@camera.ui/server 2.2.7 → 2.2.8

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 (528) hide show
  1. package/dist/interface/assets/{404-C8EoOtBl.js → 404-BYV0u5qE.js} +1 -1
  2. package/dist/interface/assets/{About-Q7ZmOGgl.js → About-DBOS1rfw.js} +1 -1
  3. package/dist/interface/assets/{Assistant-DFLgklVe.js → Assistant-BRcHj8hq.js} +1 -1
  4. package/dist/interface/assets/Automation-C0Emde7z.js +3 -0
  5. package/dist/interface/assets/{AutomationImport-CLQSdqg9.js → AutomationImport-Iu-K82Os.js} +2 -2
  6. package/dist/interface/assets/{AutomationStore-Dt6yTQDb.js → AutomationStore-C2G0Bk8c.js} +2 -2
  7. package/dist/interface/assets/{AutomationStoreDetail-DqBrBhUI.js → AutomationStoreDetail-BbvLRJ5u.js} +2 -2
  8. package/dist/interface/assets/Automations-D-vfqRnZ.js +2 -0
  9. package/dist/interface/assets/Camera-BpurrgAr.js +2 -0
  10. package/dist/interface/assets/Camera-D0B7yyVD.css +1 -0
  11. package/dist/interface/assets/{CameraConsole-rhle_cfW.js → CameraConsole-JBD3ZmJ6.js} +2 -2
  12. package/dist/interface/assets/{Cameras-Bzy3P0xN.js → Cameras-R5mJGMK9.js} +2 -2
  13. package/dist/interface/assets/{Camview-Bri_T7Tq.css → Camview-DH6_8CxH.css} +1 -1
  14. package/dist/interface/assets/Camview-IbOVRx20.js +1 -0
  15. package/dist/interface/assets/{CertificateUpload-CWVu_52v.js → CertificateUpload-B9S4EOQs.js} +1 -1
  16. package/dist/interface/assets/Config-CbFl5Wcp.js +2 -0
  17. package/dist/interface/assets/{ConfigActionAssistant-AfQfSqHZ.js → ConfigActionAssistant-DIOh6-np.js} +1 -1
  18. package/dist/interface/assets/{ConfigActionCameraControl-BKQdHxqe.js → ConfigActionCameraControl-Bw_egtpP.js} +1 -1
  19. package/dist/interface/assets/{ConfigActionDelay-B52HeJGb.js → ConfigActionDelay-B9i4YZjy.js} +1 -1
  20. package/dist/interface/assets/{ConfigActionHttp-BP5gvpQc.js → ConfigActionHttp-DFtxAa3U.js} +1 -1
  21. package/dist/interface/assets/{ConfigActionImageInput-DE2mSost.js → ConfigActionImageInput-CuTH4Nw2.js} +1 -1
  22. package/dist/interface/assets/{ConfigActionMqtt-CYgnZjAE.js → ConfigActionMqtt-B9SfWP-G.js} +1 -1
  23. package/dist/interface/assets/{ConfigActionNotification-C3q53I4n.js → ConfigActionNotification-BGMIByJT.js} +1 -1
  24. package/dist/interface/assets/{ConfigActionNotificationControl-eDJ8r5ao.js → ConfigActionNotificationControl-Cz72szMd.js} +1 -1
  25. package/dist/interface/assets/{ConfigActionOutput-DgYSYvy-.js → ConfigActionOutput-BG6DoIRe.js} +1 -1
  26. package/dist/interface/assets/{ConfigActionPlugin-utolgAXk.js → ConfigActionPlugin-B5oRSE9n.js} +1 -1
  27. package/dist/interface/assets/{ConfigActionSensor-CmEKQPqs.js → ConfigActionSensor-BErRRYfl.js} +1 -1
  28. package/dist/interface/assets/{ConfigActionSnapshot-D7XucxVV.js → ConfigActionSnapshot-Di-uxMrg.js} +1 -1
  29. package/dist/interface/assets/{ConfigActionVariable-C-Mjm3gr.js → ConfigActionVariable-BBpUti5A.js} +1 -1
  30. package/dist/interface/assets/{ConfigConditionIfElse-B24Rqb8y.js → ConfigConditionIfElse-DjOKPXQw.js} +1 -1
  31. package/dist/interface/assets/{ConfigConditionSensorState-42-yFDmK.js → ConfigConditionSensorState-BzvvZvD0.js} +1 -1
  32. package/dist/interface/assets/{ConfigConditionSwitch-DezH_nwm.js → ConfigConditionSwitch-DQvdfUxR.js} +1 -1
  33. package/dist/interface/assets/{ConfigConditionTime-Cg2Lwznd.js → ConfigConditionTime-BqOElX5C.js} +1 -1
  34. package/dist/interface/assets/{ConfigSensorValueInput-YHBDCTZm.js → ConfigSensorValueInput-BT-0LhSH.js} +1 -1
  35. package/dist/interface/assets/{ConfigTriggerDetection-DxEpodjG.js → ConfigTriggerDetection-1OkudUah.js} +1 -1
  36. package/dist/interface/assets/{ConfigTriggerGeofence-Bye8syxc.js → ConfigTriggerGeofence-HGatk3C5.js} +1 -1
  37. package/dist/interface/assets/{ConfigTriggerManual-s_lEDTV9.js → ConfigTriggerManual-DpRr_vVq.js} +1 -1
  38. package/dist/interface/assets/{ConfigTriggerMqtt-DqdZj7TU.js → ConfigTriggerMqtt-C_MId3BY.js} +1 -1
  39. package/dist/interface/assets/{ConfigTriggerSchedule-Q559hn6g.js → ConfigTriggerSchedule-BmwDqd6N.js} +1 -1
  40. package/dist/interface/assets/{ConfigTriggerSensor-DIKkdbTF.js → ConfigTriggerSensor-Rgx8q4g8.js} +1 -1
  41. package/dist/interface/assets/{ConfigTriggerSystem-CwNZ4xEg.js → ConfigTriggerSystem-4VsHPmbn.js} +1 -1
  42. package/dist/interface/assets/{ConfigTriggerWebhook-9ZC6X4mK.js → ConfigTriggerWebhook-Bs7zEfY0.js} +1 -1
  43. package/dist/interface/assets/{Console-BqIDZ5vq.js → Console-oCuuVKET.js} +1 -1
  44. package/dist/interface/assets/CuiAssistantConversation-Bsyxau9v.js +5 -0
  45. package/dist/interface/assets/{CuiAutomationRunsDialog-CVjCLiVW.js → CuiAutomationRunsDialog-sRh_K6JI.js} +1 -1
  46. package/dist/interface/assets/CuiBottomSheet-DWoSHzC7.js +1 -0
  47. package/dist/interface/assets/{CuiBottomSheet-D75L0Zny.js → CuiBottomSheet-Dd3uOtnC.js} +1 -1
  48. package/dist/interface/assets/CuiCameraPipCard-D6REm8uT.js +1 -0
  49. package/dist/interface/assets/CuiCameraPipCard-TYTCfwXf.css +1 -0
  50. package/dist/interface/assets/{CuiCameraRecordings-DdEWkJrO.js → CuiCameraRecordings-C2tvrbbw.js} +1 -1
  51. package/dist/interface/assets/{CuiCameraShares-8mtgFsQ_.js → CuiCameraShares-jrrUEHoZ.js} +1 -1
  52. package/dist/interface/assets/CuiCameraTable-BOzTWLwd.js +1 -0
  53. package/dist/interface/assets/{CuiCameraTable-CmCT-XQF.js → CuiCameraTable-C7WLZ2pA.js} +2 -2
  54. package/dist/interface/assets/{CuiChartTable-v8sGY6PD.js → CuiChartTable-BYrIX7LV.js} +1 -1
  55. package/dist/interface/assets/{CuiConsole-DYV-FUE0.js → CuiConsole-CkZML0iY.js} +2 -2
  56. package/dist/interface/assets/CuiDataTable-BFIhx1D3.js +1 -0
  57. package/dist/interface/assets/{CuiLightControl-CFIwBj3C.js → CuiLightControl-DitIWqUr.js} +1 -1
  58. package/dist/interface/assets/{CuiList-9TVV8SB6.js → CuiList-BewTNr2X.js} +1 -1
  59. package/dist/interface/assets/CuiMarkdownContent-Do04YgHe.js +1 -0
  60. package/dist/interface/assets/{CuiMarkdownContent-BYBQX_aF.js → CuiMarkdownContent-qOPm3VEi.js} +1 -1
  61. package/dist/interface/assets/CuiPluginCard-Bd2HFduI.js +2 -0
  62. package/dist/interface/assets/{CuiPluginCategoryChip-DhnIBJHa.js → CuiPluginCategoryChip-DlzOwRgc.js} +1 -1
  63. package/dist/interface/assets/{CuiPluginOAuthButton-DAuzNRAA.js → CuiPluginOAuthButton-BQZkTcgo.js} +2 -2
  64. package/dist/interface/assets/{CuiPluginTrustBadge-Bz710WwC.js → CuiPluginTrustBadge-DbqdfdaL.js} +1 -1
  65. package/dist/interface/assets/{CuiQRCode-B8-4GHSY.js → CuiQRCode-2WsWJQFi.js} +1 -1
  66. package/dist/interface/assets/{CuiSchema-C_CHuKuf.js → CuiSchema-BL0QZmP2.js} +1 -1
  67. package/dist/interface/assets/{CuiTopNavbarItem-CNEnOPSh.js → CuiTopNavbarItem-Ti2TueU1.js} +1 -1
  68. package/dist/interface/assets/Faces-DARrGLXf.js +1 -0
  69. package/dist/interface/assets/{FirstSteps-Ci2Iqbe2.js → FirstSteps-DBYPBvGr.js} +1 -1
  70. package/dist/interface/assets/Floorplan-BaZvzoyv.js +1 -0
  71. package/dist/interface/assets/{Instances-gzKFKB1l.js → Instances-r0xReURi.js} +1 -1
  72. package/dist/interface/assets/{Logs-DL1yw_Pe.js → Logs-DMehPk0t.js} +2 -2
  73. package/dist/interface/assets/{Menu-C0GQ63aj.js → Menu-C34RRyLd.js} +1 -1
  74. package/dist/interface/assets/Metrics-BjoC71_O.js +12 -0
  75. package/dist/interface/assets/{OAuthDeviceFlow-Zd6r9IHU.js → OAuthDeviceFlow-CdZxelf2.js} +1 -1
  76. package/dist/interface/assets/Plugin-npx7CnwV.js +1 -0
  77. package/dist/interface/assets/{PluginConsole-ag0jPZQ_.js → PluginConsole-D1BRQCO9.js} +2 -2
  78. package/dist/interface/assets/PluginDetail-nwTrJmO6.js +2 -0
  79. package/dist/interface/assets/{PluginSchema-CxUujnVs.js → PluginSchema-B9VsBHOU.js} +1 -1
  80. package/dist/interface/assets/PluginSearch-CP2kQWKf.js +1 -0
  81. package/dist/interface/assets/{PluginSearch-BqzngVRL.js → PluginSearch-WEvbKMRs.js} +2 -2
  82. package/dist/interface/assets/{PluginUpdateProgress-CFut0RAe.js → PluginUpdateProgress-uj0XPV-_.js} +1 -1
  83. package/dist/interface/assets/Plugins-CPx9Hszm.js +1 -0
  84. package/dist/interface/assets/{RecentEventsFilter-CqeHhECT.js → RecentEventsFilter-D5VSH2K1.js} +1 -1
  85. package/dist/interface/assets/Recordings-De6Zcv0M.js +1 -0
  86. package/dist/interface/assets/{SensorEdit-Bi0gg-CL.js → SensorEdit-SD_oHBRo.js} +1 -1
  87. package/dist/interface/assets/{SensorHistory-q0UR3qMG.js → SensorHistory-SxiLOloa.js} +1 -1
  88. package/dist/interface/assets/Sensors-Djl64M-W.js +2 -0
  89. package/dist/interface/assets/{Settings-Cv38rGWn.js → Settings-CAf2reGs.js} +1 -1
  90. package/dist/interface/assets/SettingsAccount-BGj5Ni91.js +1 -0
  91. package/dist/interface/assets/SettingsAccount-Dy6WC8ql.js +1 -0
  92. package/dist/interface/assets/SettingsAppearance-BGFhMlRk.js +1 -0
  93. package/dist/interface/assets/{SettingsAppearance-DdyYUgmV.js → SettingsAppearance-DQzQmVzE.js} +1 -1
  94. package/dist/interface/assets/SettingsAssistant-BwYVyuN3.js +1 -0
  95. package/dist/interface/assets/{SettingsBackup-DKwlPQhD.js → SettingsBackup-CVExGnOo.js} +1 -1
  96. package/dist/interface/assets/{SettingsList-D6hqnvUo.js → SettingsList-vo7sz_MY.js} +1 -1
  97. package/dist/interface/assets/{SettingsMqtt-C01fgLY0.js → SettingsMqtt-B1CuOcML.js} +1 -1
  98. package/dist/interface/assets/{SettingsNotifications-D47cIquQ.js → SettingsNotifications-CCQ6eiq8.js} +1 -1
  99. package/dist/interface/assets/{SettingsPermissions-BeTCTrAf.js → SettingsPermissions-BlOf6HEy.js} +1 -1
  100. package/dist/interface/assets/{SettingsRecordings-mwL6Dalr.js → SettingsRecordings-7tTBg6m1.js} +1 -1
  101. package/dist/interface/assets/SettingsRemote-CsIGx-LU.css +1 -0
  102. package/dist/interface/assets/SettingsRemote-DBgKmIdv.js +2 -0
  103. package/dist/interface/assets/{SettingsSystem-BXnzXgqm.js → SettingsSystem-DaFMsZpN.js} +2 -2
  104. package/dist/interface/assets/{SettingsUsers-D2mVlJin.js → SettingsUsers-DXACwVPi.js} +1 -1
  105. package/dist/interface/assets/{Terminal-C1UoXDRK.js → Terminal-DtGqlHbk.js} +2 -2
  106. package/dist/interface/assets/Training-Ca11D1Vj.js +1 -0
  107. package/dist/interface/assets/{Updates-kS_Tm8HD.js → Updates-yenwuqnD.js} +2 -2
  108. package/dist/interface/assets/{VariableInput-D9PfI8Ut.js → VariableInput-CcILik4M.js} +1 -1
  109. package/dist/interface/assets/{VariableSuggestions-DArWzQuE.js → VariableSuggestions-Bj0HdrYW.js} +1 -1
  110. package/dist/interface/assets/{VersionsHandler-BZVMpB2v.js → VersionsHandler-BA8Lcysg.js} +1 -1
  111. package/dist/interface/assets/{VirtualSensorCreate-Cz-QFo4R.js → VirtualSensorCreate-DvHyw7I2.js} +1 -1
  112. package/dist/interface/assets/{Workers-DH59zE1C.css → Workers-Dey1snI4.css} +1 -1
  113. package/dist/interface/assets/Workers-Dyo44zxe.js +2 -0
  114. package/dist/interface/assets/{account-DwW7pBOb.js → account-DjBQulDn.js} +1 -1
  115. package/dist/interface/assets/ace-BPAekgyf.js +1 -0
  116. package/dist/interface/assets/{ace.config-CCyX_Ohk.js → ace.config-CvKE-yp1.js} +1 -1
  117. package/dist/interface/assets/{alert-circle-BdUVAt1B.js → alert-circle-B-JCMbb9.js} +1 -1
  118. package/dist/interface/assets/{alert-outline-IRxYbw0j.js → alert-outline-B4ZZowEj.js} +1 -1
  119. package/dist/interface/assets/{api-CGfJbsTz.css → api-CHQlxVtZ.css} +1 -1
  120. package/dist/interface/assets/{api-CzwdnGAH.js → api-CKbL5jC7.js} +1 -1
  121. package/dist/interface/assets/api-CLazgL-g.js +4 -0
  122. package/dist/interface/assets/{arrow-left-Bk-ZrOVr.js → arrow-left-PeaVwpHd.js} +1 -1
  123. package/dist/interface/assets/{assistant-hGCAgv-f.js → assistant-CwmHp5bB.js} +1 -1
  124. package/dist/interface/assets/{assistantModels-BsSgRsws.js → assistantModels-D3ncWWu0.js} +1 -1
  125. package/dist/interface/assets/{auth-By-S-WEr.js → auth-AfZrkJ2f.js} +1 -1
  126. package/dist/interface/assets/automations-DOCG0q8-.js +1 -0
  127. package/dist/interface/assets/{back-filled-D-X19YMO.js → back-filled-CJoz7Gkl.js} +1 -1
  128. package/dist/interface/assets/{bell-ring-DreEHgoT.js → bell-ring-CBf0Yn3H.js} +1 -1
  129. package/dist/interface/assets/{brain-DuDAg544.js → brain-uZ03n3LW.js} +1 -1
  130. package/dist/interface/assets/cameraSources-mHEz9ROa.js +1 -0
  131. package/dist/interface/assets/{cctv-DM-C_8_6.js → cctv-VgKQ-dBV.js} +1 -1
  132. package/dist/interface/assets/{check-circle-Bevuw8-0.js → check-circle-BU-KNgPB.js} +1 -1
  133. package/dist/interface/assets/{check-circle-outline-aMxkvksr.js → check-circle-outline-BsxzAMed.js} +1 -1
  134. package/dist/interface/assets/{chevron-down-CCFn9Z56.js → chevron-down-CxK4Sfjs.js} +1 -1
  135. package/dist/interface/assets/{chevron-up-CSImUM3_.js → chevron-up-DWfNH8va.js} +1 -1
  136. package/dist/interface/assets/{clock-outline-DH3WIEJt.js → clock-outline-BtWx4GaF.js} +1 -1
  137. package/dist/interface/assets/{close-CMxyM4v9.js → close-Be7oB7d_.js} +1 -1
  138. package/dist/interface/assets/{close-circle-CfgJCZ9A.js → close-circle-D7Jmhp_7.js} +1 -1
  139. package/dist/interface/assets/{cloud-check-CbdFLIdR.js → cloud-check-zCGJxpWI.js} +1 -1
  140. package/dist/interface/assets/cloudHandoff-zJCrDmwk.js +1 -0
  141. package/dist/interface/assets/{config-BQxEwrK6.js → config-AG0SnOiY.js} +1 -1
  142. package/dist/interface/assets/{content-copy-Bz49QPOI.js → content-copy-BcYlfuFc.js} +1 -1
  143. package/dist/interface/assets/{copy-DA6QQHRt.js → copy-DuY-M96E.js} +1 -1
  144. package/dist/interface/assets/{cube-scan-IiH8zwm2.js → cube-scan-Cae03i_N.js} +1 -1
  145. package/dist/interface/assets/{database-refresh-outline-CIUDpcuq.js → database-refresh-outline-B3OEQFF7.js} +1 -1
  146. package/dist/interface/assets/{delete-Btu-UVx9.js → delete-BWgOAzKl.js} +1 -1
  147. package/dist/interface/assets/{dist-D_qWDAKp.js → dist-DmpuuM9s.js} +1 -1
  148. package/dist/interface/assets/{dots-vertical-D496SIss.js → dots-vertical-Kby1GY8_.js} +1 -1
  149. package/dist/interface/assets/{download-BSC7lwq_.js → download-C291Yq7I.js} +1 -1
  150. package/dist/interface/assets/esm-B2TVBF3B.js +1 -0
  151. package/dist/interface/assets/esm-BEntuCG7.js +1 -0
  152. package/dist/interface/assets/esm-BRnyrFH8.js +1 -0
  153. package/dist/interface/assets/esm-CCwXzd_8.js +1 -0
  154. package/dist/interface/assets/esm-CEjwTsuD.js +1 -0
  155. package/dist/interface/assets/esm-CGGV9tC4.js +1 -0
  156. package/dist/interface/assets/esm-CI2tTOc5.js +1 -0
  157. package/dist/interface/assets/esm-CgxZmMYv.js +1 -0
  158. package/dist/interface/assets/esm-Csc6f5Fy.js +1 -0
  159. package/dist/interface/assets/esm-Qzx3d-Ie.js +1 -0
  160. package/dist/interface/assets/esm-a_w7mTdx.js +1 -0
  161. package/dist/interface/assets/esm-iKfsu7-H.js +1 -0
  162. package/dist/interface/assets/esm-ks5kvk_e.js +1 -0
  163. package/dist/interface/assets/esm-nJfTguKF.js +1 -0
  164. package/dist/interface/assets/{eventIcons-UQutPG3p.js → eventIcons-C3JWChgS.js} +1 -1
  165. package/dist/interface/assets/{eye-off-CSU0U8g7.js → eye-off-zGCIHKOK.js} +1 -1
  166. package/dist/interface/assets/{flowSchema-BPq6iHks.js → flowSchema-B0d3VjU7.js} +1 -1
  167. package/dist/interface/assets/{help-circle-outline-Cr_yNhPi.js → help-circle-outline-DXFepDAG.js} +1 -1
  168. package/dist/interface/assets/{history-anuCbp1T.js → history-D-FlZdKD.js} +1 -1
  169. package/dist/interface/assets/{home-N3bDR1vX.js → home-DPdzRxcM.js} +1 -1
  170. package/dist/interface/assets/{information-outline-CMWIvLNB.js → information-outline-ChOM9qgI.js} +1 -1
  171. package/dist/interface/assets/{intercomService-CXcjcPa9.js → intercomService-DG3EeZ6s.js} +1 -1
  172. package/dist/interface/assets/{lan-CYXjdk7L.js → lan-DvYEO83l.js} +1 -1
  173. package/dist/interface/assets/{main-DVa5U7UB.css → main-CGY9cVyi.css} +1 -1
  174. package/dist/interface/assets/main-DkHV6YgB.js +3 -0
  175. package/dist/interface/assets/{microphone-BB2pATI_.js → microphone-D-T9xga4.js} +1 -1
  176. package/dist/interface/assets/{minus-BCp3ZNKO.js → minus-4T4INuO4.js} +1 -1
  177. package/dist/interface/assets/mqtt-DE2VbNdt.js +1 -0
  178. package/dist/interface/assets/native-CtfXrwj5.js +1 -0
  179. package/dist/interface/assets/native-JMtkOkIV.js +1 -0
  180. package/dist/interface/assets/{nodeDefinitions-ByrqsENY.js → nodeDefinitions-Dp8cnne1.js} +1 -1
  181. package/dist/interface/assets/{notifications-BCyiD-TP.js → notifications-8FH4ApEz.js} +1 -1
  182. package/dist/interface/assets/{pause-BQlxwAW2.js → pause-DHqHYA3V.js} +1 -1
  183. package/dist/interface/assets/{pencil-outline-CIQL5Kui.js → pencil-outline-D-GmPf8M.js} +1 -1
  184. package/dist/interface/assets/{pencil-CDsNnEXi.js → pencil-vACi-JzY.js} +1 -1
  185. package/dist/interface/assets/plugin-Dt5Xetfz.js +1 -0
  186. package/dist/interface/assets/plugins-2JLUEMYc.js +1 -0
  187. package/dist/interface/assets/{plus-Bp4q9G7S.js → plus-BBUb8_uL.js} +1 -1
  188. package/dist/interface/assets/{plus-CySoovdr.js → plus-BJb7U4bN.js} +1 -1
  189. package/dist/interface/assets/{power-WmBLDR0-.js → power-Dm_aNIz-.js} +1 -1
  190. package/dist/interface/assets/{radar-CyYAmume.js → radar-Dcvdz--e.js} +1 -1
  191. package/dist/interface/assets/{refresh-CHTA3jVN.js → refresh-CO4F18Je.js} +1 -1
  192. package/dist/interface/assets/{restore-C8RNM5yX.js → restore-xRBt3Grb.js} +1 -1
  193. package/dist/interface/assets/rooms-DoAfzA8W.js +1 -0
  194. package/dist/interface/assets/{round-alt-arrow-left-bold-Gh5mi_yR.js → round-alt-arrow-left-bold-CZHXzGS5.js} +1 -1
  195. package/dist/interface/assets/{search-BajCVmOI.js → search-D75YW08B.js} +1 -1
  196. package/dist/interface/assets/{sensorIcons-DofElQ3w.js → sensorIcons-BntiOPX7.js} +1 -1
  197. package/dist/interface/assets/{sensorSlots-D2KJGvPw.js → sensorSlots-biaL-O8E.js} +1 -1
  198. package/dist/interface/assets/sensors-DyAMdS-H.js +1 -0
  199. package/dist/interface/assets/{server-Dw5DD473.js → server-BDRUGj61.js} +1 -1
  200. package/dist/interface/assets/{settings-DnksaK7m.js → settings-DDOgc5BX.js} +1 -1
  201. package/dist/interface/assets/{source-branch-CzqIPffP.js → source-branch-DVHuYlkZ.js} +1 -1
  202. package/dist/interface/assets/{theme-C85LJhOY.js → theme-CLxrnR60.js} +1 -1
  203. package/dist/interface/assets/{trash-2-DJeEhHf4.js → trash-2-DDKPtl2x.js} +1 -1
  204. package/dist/interface/assets/{trash-can-outline-DrT6iw7I.js → trash-can-outline-DVH3zgo0.js} +1 -1
  205. package/dist/interface/assets/{trash-fill-Bb_-UicM.js → trash-fill-C_IJ4Vu2.js} +1 -1
  206. package/dist/interface/assets/{trash2-Dsl8gfxq.js → trash2-DY0XTaJD.js} +1 -1
  207. package/dist/interface/assets/{types-CPhy0Ovw.js → types-8JXzkoC8.js} +1 -1
  208. package/dist/interface/assets/{types-DYKmSGl4.js → types-B4LLKzDW.js} +1 -1
  209. package/dist/interface/assets/types-a7Nw-P-m.js +1 -0
  210. package/dist/interface/assets/{undo-DoqJW-k7.js → undo-YRkBYCnf.js} +1 -1
  211. package/dist/interface/assets/ungrouped-BoAbb9w3.js +1 -0
  212. package/dist/interface/assets/ungrouped-ChmBvcXp.css +1 -0
  213. package/dist/interface/assets/updates-F-veEP1I.js +1 -0
  214. package/dist/interface/assets/{upload-DtIcwiNC.js → upload-2WcHRjTq.js} +1 -1
  215. package/dist/interface/assets/{upload-C3w1XH-o.js → upload-BiE7VzTj.js} +1 -1
  216. package/dist/interface/assets/{useAppVersion-DkazK9Vu.js → useAppVersion-BjUQmB7M.js} +1 -1
  217. package/dist/interface/assets/{useAssistantActions-BZP6NL18.js → useAssistantActions-CNEJol4o.js} +1 -1
  218. package/dist/interface/assets/useBackupRestore-Biqn_lhh.js +1 -0
  219. package/dist/interface/assets/{useCameraOptions-DnI0xLrX.js → useCameraOptions-D_oduve2.js} +1 -1
  220. package/dist/interface/assets/{useKeyboardInset-Cr7SxKGN.js → useKeyboardInset-CPWSVYlA.js} +1 -1
  221. package/dist/interface/assets/{useLogsSocket-C3Y8S0Ar.js → useLogsSocket-B_jXUqv8.js} +1 -1
  222. package/dist/interface/assets/{useNavLayout-C9pcDuVP.js → useNavLayout-DEngIIeU.js} +1 -1
  223. package/dist/interface/assets/{usePermissions-CCTxwXF0.js → usePermissions-DAO92InI.js} +1 -1
  224. package/dist/interface/assets/{usePluginUpdates-DBhLWAua.js → usePluginUpdates-CJi8Y_wl.js} +1 -1
  225. package/dist/interface/assets/{usePushRegistration-CPRVdLAx.js → usePushRegistration-j9WCeFbv.js} +2 -2
  226. package/dist/interface/assets/{useServerRestart-bScBLJ9r.js → useServerRestart-BVks5tuC.js} +1 -1
  227. package/dist/interface/assets/{useStreamStatus-Bfh-WmLH.js → useStreamStatus-DQ0NSyU8.js} +1 -1
  228. package/dist/interface/assets/{useTabSwipe-C_QOrvSW.js → useTabSwipe-CVq7EcIY.js} +1 -1
  229. package/dist/interface/assets/{useUpdateChannel-g0h_4c55.js → useUpdateChannel-C0fjDvNP.js} +1 -1
  230. package/dist/interface/assets/{useUpdatesSocket-CxrLRETs.js → useUpdatesSocket-DXKF9hzc.js} +1 -1
  231. package/dist/interface/assets/useUserOptions-UjMeAL5n.js +1 -0
  232. package/dist/interface/assets/{variable-ywTlRfo5.js → variable-Cp8o-q8t.js} +1 -1
  233. package/dist/interface/assets/vendor-Df81FCJz.js +29 -0
  234. package/dist/interface/assets/{vendor-ace-CvEoip98.js → vendor-ace-QSsGUspX.js} +1 -1
  235. package/dist/interface/assets/{vendor-cameraui-B28aGJJD.js → vendor-cameraui-GmMRyJ2R.js} +3 -3
  236. package/dist/interface/assets/{vendor-capacitor-Bs_WzL0Q.js → vendor-capacitor-t5EIN1GG.js} +2 -2
  237. package/dist/interface/assets/{vendor-chart-DBK083Hu.js → vendor-chart-BiJYkx5_.js} +1 -1
  238. package/dist/interface/assets/{vendor-core-DIa0tPNH.js → vendor-core-BeAannbA.js} +1 -1
  239. package/dist/interface/assets/{vendor-dnd-DGQLvX6Y.js → vendor-dnd-C1kMh9_t.js} +1 -1
  240. package/dist/interface/assets/{vendor-draggabilly-D8CK6M-y.js → vendor-draggabilly-Cw1oJ6qc.js} +1 -1
  241. package/dist/interface/assets/vendor-leaflet-OSZlONe5.js +1 -0
  242. package/dist/interface/assets/{vendor-markdown-qHIinIUE.js → vendor-markdown-DTWiWKBj.js} +1 -1
  243. package/dist/interface/assets/{vendor-primevue-CZKUAkMA.js → vendor-primevue-Zx6t06A4.js} +1 -1
  244. package/dist/interface/assets/{vendor-vueflow-bSwRZ9X8.js → vendor-vueflow-DWU_IzGe.js} +1 -1
  245. package/dist/interface/assets/web-B98ahwoP.js +1 -0
  246. package/dist/interface/assets/web-BSsSrRZf.js +1 -0
  247. package/dist/interface/assets/web-BiNRDta4.js +1 -0
  248. package/dist/interface/assets/web-BjKL51lK-CZKmYhby.js +1 -0
  249. package/dist/interface/assets/web-BjtOcquy.js +1 -0
  250. package/dist/interface/assets/web-CkTE9nCG.js +1 -0
  251. package/dist/interface/assets/web-Cvogq5S5.js +1 -0
  252. package/dist/interface/assets/web-D-A4EBKj.js +1 -0
  253. package/dist/interface/assets/web-DVGMBduz.js +1 -0
  254. package/dist/interface/assets/web-SpWB7I6X.js +1 -0
  255. package/dist/interface/assets/web-k0ihT_qK.js +1 -0
  256. package/dist/interface/assets/web-ovBpm7Dl.js +1 -0
  257. package/dist/interface/assets/web-z5Xz9tOQ.js +1 -0
  258. package/dist/interface/assets/web-zfhkFevT.js +1 -0
  259. package/dist/interface/assets/{webhook-CWKf2Qxu.js → webhook-DIjChTrs.js} +1 -1
  260. package/dist/interface/assets/workbox-window.prod.es5-DRKojI0e.js +1 -0
  261. package/dist/interface/assets/{zoom-in-CHkXAWHy.js → zoom-in-rMB152Uz.js} +1 -1
  262. package/dist/interface/ha/{404-tl2VQ3qy.js → 404-D5gfy0Cd.js} +1 -1
  263. package/dist/interface/ha/{About-Cn7KOblU.js → About-JzlpCzBN.js} +3 -3
  264. package/dist/interface/ha/{Assistant-DG2GGda0.js → Assistant-DgOfGesf.js} +2409 -1917
  265. package/dist/interface/ha/{Automation-D0_WpXx4.js → Automation-BDaWYiBu.js} +146 -146
  266. package/dist/interface/ha/{AutomationImport-DdC3dEaC.js → AutomationImport-BNB_PJ9R.js} +6 -6
  267. package/dist/interface/ha/{AutomationStore-BrLn4oBx.js → AutomationStore-_TeOt1wz.js} +73 -73
  268. package/dist/interface/ha/{AutomationStoreDetail-DoppNsNc.js → AutomationStoreDetail-jjIEZoRi.js} +20 -20
  269. package/dist/interface/ha/{Automations-BaUJ9pVq.js → Automations-DM6FEVOw.js} +110 -110
  270. package/dist/interface/ha/Camera-sH9fRv18.js +670 -0
  271. package/dist/interface/ha/{CameraConsole-7MhlS2VK.js → CameraConsole-BoVql05l.js} +4 -4
  272. package/dist/interface/ha/{Cameras-vHYz8uSO.js → Cameras-cQBGvXq7.js} +349 -347
  273. package/dist/interface/ha/{Camview-BEglAx26.js → Camview-mkG5FXZM.js} +357 -353
  274. package/dist/interface/ha/{Config-CHiK--zP.js → Config-BNPDzo_h.js} +11 -11
  275. package/dist/interface/ha/{ConfigActionAssistant-DynduZYV.js → ConfigActionAssistant-C-8P3DYz.js} +4 -4
  276. package/dist/interface/ha/{ConfigActionCameraControl-BEYePssz.js → ConfigActionCameraControl-x1ksGL7m.js} +3 -3
  277. package/dist/interface/ha/{ConfigActionHttp-h0vRWqZ5.js → ConfigActionHttp-DzCJp85z.js} +2 -2
  278. package/dist/interface/ha/{ConfigActionImageInput-B9GMZYAR.js → ConfigActionImageInput-C5C5U_2z.js} +1 -1
  279. package/dist/interface/ha/{ConfigActionMqtt-BEQpHBgf.js → ConfigActionMqtt-T29xb75r.js} +4 -4
  280. package/dist/interface/ha/{ConfigActionNotification-BYsz8_aS.js → ConfigActionNotification-BcnyilF9.js} +3 -3
  281. package/dist/interface/ha/{ConfigActionNotificationControl-BxmIWVE8.js → ConfigActionNotificationControl-D3wIVKuU.js} +2 -2
  282. package/dist/interface/ha/{ConfigActionOutput-DTOQSa1S.js → ConfigActionOutput-hD-yVczw.js} +1 -1
  283. package/dist/interface/ha/{ConfigActionPlugin-NOsUs3QI.js → ConfigActionPlugin-Bz1O-O4Q.js} +5 -5
  284. package/dist/interface/ha/{ConfigActionSensor-YWnsH_LV.js → ConfigActionSensor-FOz-PYl_.js} +5 -5
  285. package/dist/interface/ha/{ConfigActionSnapshot-DHJnTvin.js → ConfigActionSnapshot-CmxEOuK1.js} +2 -2
  286. package/dist/interface/ha/{ConfigActionVariable-C7UFnvW0.js → ConfigActionVariable-BCvkrdCh.js} +1 -1
  287. package/dist/interface/ha/{ConfigConditionIfElse-CAHbuhH3.js → ConfigConditionIfElse-icfTG9OA.js} +3 -3
  288. package/dist/interface/ha/{ConfigConditionSensorState-CE6okUeb.js → ConfigConditionSensorState-ClUAsm0d.js} +4 -4
  289. package/dist/interface/ha/{ConfigConditionSwitch-D5FULaTy.js → ConfigConditionSwitch-C8AMCkn6.js} +5 -5
  290. package/dist/interface/ha/{ConfigSensorValueInput-mo6Gs_aZ.js → ConfigSensorValueInput-ChvDQzGd.js} +4 -4
  291. package/dist/interface/ha/{ConfigTriggerDetection-Bt-OhHtM.js → ConfigTriggerDetection-aUSyaClu.js} +11 -11
  292. package/dist/interface/ha/{ConfigTriggerGeofence-Cw3jV5qD.js → ConfigTriggerGeofence-DsJeJWP4.js} +7 -7
  293. package/dist/interface/ha/{ConfigTriggerMqtt-BXeV82UG.js → ConfigTriggerMqtt-CsAxA7QZ.js} +1 -1
  294. package/dist/interface/ha/{ConfigTriggerSensor-Baqq--nJ.js → ConfigTriggerSensor-CTxr9cfU.js} +1 -1
  295. package/dist/interface/ha/{ConfigTriggerSystem-braUVGzW.js → ConfigTriggerSystem-C8UEfpfs.js} +2 -2
  296. package/dist/interface/ha/{ConfigTriggerWebhook-Dm45r-1C.js → ConfigTriggerWebhook-frEE-SCB.js} +1 -1
  297. package/dist/interface/ha/{Console-q3TCsxYo.js → Console-A3VtbsLg.js} +12 -12
  298. package/dist/interface/ha/{CuiAutomationRunsDialog-DO6h5Tc4.js → CuiAutomationRunsDialog-BlJvhBiX.js} +2 -2
  299. package/dist/interface/ha/{CuiBottomSheet-B7ldz0xi.js → CuiBottomSheet-Cu-t3H0Z.js} +1 -1
  300. package/dist/interface/ha/{CuiCameraRecordings-Dq1Vh3qA.js → CuiCameraRecordings-R5ArEmqJ.js} +11 -11
  301. package/dist/interface/ha/{CuiCameraShares-DBqcpevG.js → CuiCameraShares-B9pfRkM4.js} +5 -5
  302. package/dist/interface/ha/{CuiCameraTable-kL8rK-Uv.js → CuiCameraTable-CKjGKaMC.js} +9 -9
  303. package/dist/interface/ha/{CuiChartTable-BrFyiSt_.js → CuiChartTable-BxWjRe-k.js} +16 -16
  304. package/dist/interface/ha/{CuiConsole-DpeXZmJd.js → CuiConsole-C5fzsR7t.js} +4 -4
  305. package/dist/interface/ha/{CuiDataTable-BtqzIz0o.js → CuiDataTable-BOdQDY8J.js} +5 -5
  306. package/dist/interface/ha/{CuiPluginCard-lBLypaN4.js → CuiPluginCard-BT71RRAD.js} +33 -33
  307. package/dist/interface/ha/{CuiPluginOAuthButton-CuGauZJA.js → CuiPluginOAuthButton-moh9uS7G.js} +7 -7
  308. package/dist/interface/ha/{CuiPluginTrustBadge-BofBmRYc.js → CuiPluginTrustBadge-F_pVWkPJ.js} +1 -1
  309. package/dist/interface/ha/{CuiQRCode-CdK9bwKb.js → CuiQRCode-BNuj-nJ4.js} +6 -6
  310. package/dist/interface/ha/{CuiSchema-DqkCLv9Y.js → CuiSchema-Cb_8Ks-I.js} +125 -125
  311. package/dist/interface/ha/{CuiTopNavbarItem-C2VZB7WV.js → CuiTopNavbarItem-BGzrrTls.js} +1 -1
  312. package/dist/interface/ha/{Faces-Crfi-75Z.js → Faces-CsM5VO8Q.js} +142 -142
  313. package/dist/interface/ha/{FirstSteps-CKVG86pf.js → FirstSteps-BFX0-EEi.js} +12 -12
  314. package/dist/interface/ha/{Floorplan-CH9_-6hk.js → Floorplan-D6MGqSJT.js} +198 -199
  315. package/dist/interface/ha/{Instances-5gZdPPDA.js → Instances-CHzIUyyA.js} +72 -72
  316. package/dist/interface/ha/{Logs-BkzEM70F.js → Logs-DZKM3dWv.js} +10 -10
  317. package/dist/interface/ha/{Menu-BuT3_Ggx.js → Menu-BQz4dfQi.js} +8 -8
  318. package/dist/interface/ha/{Metrics-BGrzu0bu.js → Metrics-CdpWJ1mm.js} +89 -89
  319. package/dist/interface/ha/{OAuthDeviceFlow-BEJtegqy.js → OAuthDeviceFlow-DUELtx3X.js} +9 -9
  320. package/dist/interface/ha/{Plugin-Bnp2jiC2.js → Plugin-5bbTF0Rv.js} +92 -92
  321. package/dist/interface/ha/{PluginConsole-CmsuPVMz.js → PluginConsole-C__0lzsS.js} +4 -4
  322. package/dist/interface/ha/{PluginDetail-BCNx7vHr.js → PluginDetail-Blrktk9W.js} +9 -9
  323. package/dist/interface/ha/{PluginSearch-DOdhuxgM.js → PluginSearch-BKbdwHQ1.js} +121 -121
  324. package/dist/interface/ha/{PluginUpdateProgress-CwkKc8Tr.js → PluginUpdateProgress-IsNiecu3.js} +3 -3
  325. package/dist/interface/ha/{Plugins-BrFowCdC.js → Plugins-CC2Dwlx5.js} +53 -53
  326. package/dist/interface/ha/{Recordings-BZhf39pJ.js → Recordings-B1XsJrzs.js} +318 -318
  327. package/dist/interface/ha/{SensorEdit-Ds6WbN4A.js → SensorEdit-Bi2Yx_ji.js} +46 -46
  328. package/dist/interface/ha/{SensorHistory-CoTIYTJx.js → SensorHistory-sqG_6eav.js} +2 -2
  329. package/dist/interface/ha/{Sensors-DZ2MKdlh.js → Sensors-DLtOh1p4.js} +509 -510
  330. package/dist/interface/ha/{Settings-D3JKr430.js → Settings-DI3_zenm.js} +38 -38
  331. package/dist/interface/ha/{SettingsAccount-cvtlSKZw.js → SettingsAccount-pS86Qyr-.js} +251 -251
  332. package/dist/interface/ha/{SettingsAppearance-CaKuOHRu.js → SettingsAppearance-tS3bubKQ.js} +4 -4
  333. package/dist/interface/ha/{SettingsAssistant-vWVjAUqQ.js → SettingsAssistant-LejCRXsF.js} +501 -501
  334. package/dist/interface/ha/{SettingsBackup-CvzL_bVf.js → SettingsBackup-CkhD1Kze.js} +23 -23
  335. package/dist/interface/ha/{SettingsList-C0Ec8x-H.js → SettingsList-bibwvPSM.js} +2 -2
  336. package/dist/interface/ha/{SettingsMqtt-COnq-QM5.js → SettingsMqtt-DSt0B4Qg.js} +18 -18
  337. package/dist/interface/ha/{SettingsNotifications-BZ68bQzO.js → SettingsNotifications-BF7ajNwE.js} +118 -118
  338. package/dist/interface/ha/{SettingsRecordings-BPtNNpDa.js → SettingsRecordings-BTIdncxg.js} +9 -9
  339. package/dist/interface/ha/{SettingsRemote-BXG8IYjf.js → SettingsRemote-Cba4P1-O.js} +347 -344
  340. package/dist/interface/ha/{SettingsSystem-_jHBUhws.js → SettingsSystem-_Nnh2ZF5.js} +9 -9
  341. package/dist/interface/ha/{SettingsUsers-CzGj_RJN.js → SettingsUsers-BfHFoxJi.js} +83 -83
  342. package/dist/interface/ha/{Terminal-BP3b8IBP.js → Terminal-Dv_7oWmS.js} +11 -11
  343. package/dist/interface/ha/{Training-C2-6DgY0.js → Training-CaSFA5oH.js} +184 -184
  344. package/dist/interface/ha/{Updates-BMZsEhmy.js → Updates-BHl5H7zE.js} +15 -15
  345. package/dist/interface/ha/{VariableInput-DmI7skCD.js → VariableInput-DtLo7-Nw.js} +1 -1
  346. package/dist/interface/ha/{VersionsHandler-DJd4NqtD.js → VersionsHandler-CF0DSeol.js} +10 -10
  347. package/dist/interface/ha/{VirtualSensorCreate-DmtGYvAn.js → VirtualSensorCreate-C907EgIz.js} +2 -2
  348. package/dist/interface/ha/Workers-Dz1d9gEQ.js +814 -0
  349. package/dist/interface/ha/{ace-B3bPzJu9.js → ace-C9MtBQVV.js} +1 -1
  350. package/dist/interface/ha/{ace.config-Dt55Nqby.js → ace.config-CSXnaIzV.js} +1 -1
  351. package/dist/interface/ha/{api-BelbnLQO.js → api-DUqpDJ2N.js} +13766 -13527
  352. package/dist/interface/ha/{api-sy4rqV2N.js → api-gId1nlMj.js} +4 -4
  353. package/dist/interface/ha/{assistant-C6KYXJfi.js → assistant-BaR65gIY.js} +50 -50
  354. package/dist/interface/ha/{auth-Da66mVEd.js → auth-Btsz_KxO.js} +38 -38
  355. package/dist/interface/ha/{automationBlueprint-hlqqM17r.js → automationBlueprint-CuO3iOiM.js} +3 -3
  356. package/dist/interface/ha/cameraui-cards.js +1 -1
  357. package/dist/interface/ha/{cards-BFRRfuM7.js → cards-DWhezIPP.js} +1449 -1409
  358. package/dist/interface/ha/{config-Cd7JNMpD.js → config-BKStpoEQ.js} +12 -12
  359. package/dist/interface/ha/{dist-BybVYMVs.js → dist-CM7R4_Gj.js} +15 -6
  360. package/dist/interface/ha/{mqtt-UZfptWJl.js → mqtt-ajcSmTB-.js} +14 -14
  361. package/dist/interface/ha/{notifications-DTHM8fS-.js → notifications-Cf9dXHEO.js} +18 -18
  362. package/dist/interface/ha/{pinia-BokSpDzj.js → pinia-DIKO5lnE.js} +267 -259
  363. package/dist/interface/ha/{plugins-Bwp_GfaX.js → plugins-ml823dJV.js} +61 -61
  364. package/dist/interface/ha/{rooms-BvaD0r0q.js → rooms-C5gUErBi.js} +9 -9
  365. package/dist/interface/ha/{server-OWdtITVa.js → server-dArenpJI.js} +26 -26
  366. package/dist/interface/ha/{types-BFJjyMZe.js → types-DYymuACA.js} +25 -25
  367. package/dist/interface/ha/{ungrouped-x00DHNHO.js → ungrouped-BHLAySWP.js} +39 -38
  368. package/dist/interface/ha/{updates-C03Qf3Il.js → updates-D5sFzGtC.js} +33 -33
  369. package/dist/interface/ha/{useAppVersion-CrMd9CC9.js → useAppVersion-C5x3Ap4_.js} +1 -1
  370. package/dist/interface/ha/{useKeyboardInset-DwUQCWHC.js → useKeyboardInset-Cj0T2AFX.js} +1 -1
  371. package/dist/interface/ha/{useLogsSocket-C6k217mW.js → useLogsSocket-DtvfQlPh.js} +1 -1
  372. package/dist/interface/ha/{useNavLayout-DhuQE024.js → useNavLayout-HSFBA4JV.js} +13 -13
  373. package/dist/interface/ha/{useServerRestart-CYaen2r6.js → useServerRestart-Ci0SppGW.js} +1 -1
  374. package/dist/interface/ha/{useTabSwipe-DAmCFlgg.js → useTabSwipe-CPKkRmaH.js} +1 -1
  375. package/dist/interface/ha/{useUpdateChannel-Dr1EoU2X.js → useUpdateChannel-CXHHovK3.js} +2 -2
  376. package/dist/interface/ha/{useUpdatesSocket-C8Gmhemh.js → useUpdatesSocket-DVST2YXV.js} +1 -1
  377. package/dist/interface/ha/{useUserOptions-BB5wk3Bq.js → useUserOptions-BYcYI6QA.js} +1 -1
  378. package/dist/interface/index.html +69 -69
  379. package/dist/interface/sw.js +1 -1
  380. package/dist/server/package.json +15 -15
  381. package/dist/server/requirements.txt +2 -2
  382. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/config.py +8 -0
  383. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/device.py +5 -1
  384. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/camera_config_internal.py +5 -1
  385. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/manager/__init__.py +2 -1
  386. package/dist/server/src/api/controllers/plugins.controller.js +1 -0
  387. package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
  388. package/dist/server/src/api/controllers/workers.controller.d.ts +2 -2
  389. package/dist/server/src/api/controllers/workers.controller.js +8 -2
  390. package/dist/server/src/api/controllers/workers.controller.js.map +1 -1
  391. package/dist/server/src/api/database/record-schemas.d.ts +3 -0
  392. package/dist/server/src/api/database/record-schemas.js +1 -0
  393. package/dist/server/src/api/database/record-schemas.js.map +1 -1
  394. package/dist/server/src/api/database/types.d.ts +4 -0
  395. package/dist/server/src/api/routes/workers.routes.js +4 -4
  396. package/dist/server/src/api/routes/workers.routes.js.map +1 -1
  397. package/dist/server/src/api/schemas/cameras.schema.d.ts +38 -0
  398. package/dist/server/src/api/schemas/cameras.schema.js +22 -0
  399. package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
  400. package/dist/server/src/api/schemas/users.schema.d.ts +12 -0
  401. package/dist/server/src/api/schemas/users.schema.js +4 -0
  402. package/dist/server/src/api/schemas/users.schema.js.map +1 -1
  403. package/dist/server/src/api/schemas/workers.schema.d.ts +5 -4
  404. package/dist/server/src/api/schemas/workers.schema.js +6 -3
  405. package/dist/server/src/api/schemas/workers.schema.js.map +1 -1
  406. package/dist/server/src/api/services/cameras.service.d.ts +3 -0
  407. package/dist/server/src/api/services/cameras.service.js +47 -2
  408. package/dist/server/src/api/services/cameras.service.js.map +1 -1
  409. package/dist/server/src/api/services/plugins.service.d.ts +1 -0
  410. package/dist/server/src/api/services/plugins.service.js +5 -1
  411. package/dist/server/src/api/services/plugins.service.js.map +1 -1
  412. package/dist/server/src/api/services/workers.service.d.ts +2 -0
  413. package/dist/server/src/api/services/workers.service.js +15 -0
  414. package/dist/server/src/api/services/workers.service.js.map +1 -1
  415. package/dist/server/src/api/types/index.d.ts +3 -2
  416. package/dist/server/src/assistant/pricing.js +39 -10
  417. package/dist/server/src/assistant/pricing.js.map +1 -1
  418. package/dist/server/src/assistant/providers.js +9 -1
  419. package/dist/server/src/assistant/providers.js.map +1 -1
  420. package/dist/server/src/camera/decoder/event-manager.d.ts +1 -2
  421. package/dist/server/src/camera/decoder/event-manager.js +37 -59
  422. package/dist/server/src/camera/decoder/event-manager.js.map +1 -1
  423. package/dist/server/src/manager/coreManager.d.ts +2 -1
  424. package/dist/server/src/manager/coreManager.js +9 -2
  425. package/dist/server/src/manager/coreManager.js.map +1 -1
  426. package/dist/server/src/plugins/runtime/node/proxy/coreManager.js +1 -1
  427. package/dist/server/src/plugins/runtime/node/proxy/coreManager.js.map +1 -1
  428. package/dist/server/src/plugins/runtime/python/proxy/camera_device.py +3 -0
  429. package/dist/server/src/plugins/runtime/python/proxy/core_manager.py +1 -1
  430. package/dist/server/src/plugins/runtime/python/rpc/typings.py +1 -1
  431. package/dist/server/src/rpc/interfaces/core.d.ts +1 -1
  432. package/dist/server/src/sensors/registry.d.ts +2 -0
  433. package/dist/server/src/sensors/registry.js +24 -0
  434. package/dist/server/src/sensors/registry.js.map +1 -1
  435. package/dist/server/src/workers/agent.js +2 -0
  436. package/dist/server/src/workers/agent.js.map +1 -1
  437. package/dist/server/src/workers/manager.d.ts +1 -0
  438. package/dist/server/src/workers/manager.js +22 -0
  439. package/dist/server/src/workers/manager.js.map +1 -1
  440. package/dist/server/src/workers/types.d.ts +5 -0
  441. package/dist/server/src/workers/types.js.map +1 -1
  442. package/npm-shrinkwrap.json +107 -107
  443. package/package.json +15 -15
  444. package/dist/interface/assets/Automation-D__qvx8c.js +0 -3
  445. package/dist/interface/assets/Automations-BH_7lYR7.js +0 -2
  446. package/dist/interface/assets/Camera-BW9ikKqh.css +0 -1
  447. package/dist/interface/assets/Camera-aquPHFwb.js +0 -2
  448. package/dist/interface/assets/Camview-CjcQbtTl.js +0 -1
  449. package/dist/interface/assets/Config-Dc1zKIPq.js +0 -2
  450. package/dist/interface/assets/CuiAssistantConversation-CM7KdaX2.js +0 -5
  451. package/dist/interface/assets/CuiBottomSheet-CFohFiO2.js +0 -1
  452. package/dist/interface/assets/CuiCameraPipCard-BQKk4fxY.css +0 -1
  453. package/dist/interface/assets/CuiCameraPipCard-eiJjYZ5W.js +0 -1
  454. package/dist/interface/assets/CuiCameraTable-DHrKoD9s.js +0 -1
  455. package/dist/interface/assets/CuiDataTable-C0gsYYpg.js +0 -1
  456. package/dist/interface/assets/CuiMarkdownContent-DTAm-EDR.js +0 -1
  457. package/dist/interface/assets/CuiPluginCard-DEfqwUhQ.js +0 -2
  458. package/dist/interface/assets/Faces-DRHMrrxh.js +0 -1
  459. package/dist/interface/assets/Floorplan-CqWIbDbh.js +0 -1
  460. package/dist/interface/assets/Metrics-BYnnb7M0.js +0 -12
  461. package/dist/interface/assets/Plugin-DJIrYUnZ.js +0 -1
  462. package/dist/interface/assets/PluginDetail-DmElwUuV.js +0 -2
  463. package/dist/interface/assets/PluginSearch-B-2zH2Xy.js +0 -1
  464. package/dist/interface/assets/Plugins-ZFcB_j6v.js +0 -1
  465. package/dist/interface/assets/Recordings-BJrtW9eG.js +0 -1
  466. package/dist/interface/assets/Sensors-C_InhcHA.js +0 -2
  467. package/dist/interface/assets/SettingsAccount-B05739dn.js +0 -1
  468. package/dist/interface/assets/SettingsAccount-gm28wtbl.js +0 -1
  469. package/dist/interface/assets/SettingsAppearance-DwUknDPV.js +0 -1
  470. package/dist/interface/assets/SettingsAssistant-ChHfkUKk.js +0 -1
  471. package/dist/interface/assets/SettingsRemote-CtP6Gz9C.css +0 -1
  472. package/dist/interface/assets/SettingsRemote-MhaShPIf.js +0 -2
  473. package/dist/interface/assets/Training-A5ynOv_l.js +0 -1
  474. package/dist/interface/assets/Workers-2sc4VMi9.js +0 -2
  475. package/dist/interface/assets/ace-DzzM-RlW.js +0 -1
  476. package/dist/interface/assets/api-DOpXVpef.js +0 -4
  477. package/dist/interface/assets/automations-vwIwb2PQ.js +0 -1
  478. package/dist/interface/assets/cameraSources-BMhXvtFt.js +0 -1
  479. package/dist/interface/assets/cloudHandoff-BnzjCpJ2.js +0 -1
  480. package/dist/interface/assets/esm-Bn9gXwX4.js +0 -1
  481. package/dist/interface/assets/esm-BzM6y2-F.js +0 -1
  482. package/dist/interface/assets/esm-CP3JWrtj.js +0 -1
  483. package/dist/interface/assets/esm-CjAXkqCf.js +0 -1
  484. package/dist/interface/assets/esm-Cqxk-j1S.js +0 -1
  485. package/dist/interface/assets/esm-DFHd3JNU.js +0 -1
  486. package/dist/interface/assets/esm-DfMLJtug.js +0 -1
  487. package/dist/interface/assets/esm-DhDrpq7a.js +0 -1
  488. package/dist/interface/assets/esm-DvhM-SOd.js +0 -1
  489. package/dist/interface/assets/esm-G63bqygQ.js +0 -1
  490. package/dist/interface/assets/esm-Gn-Y59hU.js +0 -1
  491. package/dist/interface/assets/esm-KJSOz2vj.js +0 -1
  492. package/dist/interface/assets/esm-Ryfc94Tm.js +0 -1
  493. package/dist/interface/assets/esm-rSfI5Poy.js +0 -1
  494. package/dist/interface/assets/eye-off-outline-DCxLRGo_.js +0 -1
  495. package/dist/interface/assets/main-By4L33Im.js +0 -3
  496. package/dist/interface/assets/mqtt-DE1KQ8Td.js +0 -1
  497. package/dist/interface/assets/native-CZJE8bTs.js +0 -1
  498. package/dist/interface/assets/native-DKZwialB.js +0 -1
  499. package/dist/interface/assets/plugin-DSEMkqaK.js +0 -1
  500. package/dist/interface/assets/plugins-BJPCV1YL.js +0 -1
  501. package/dist/interface/assets/rooms-Dr4yiakO.js +0 -1
  502. package/dist/interface/assets/sensors-3llrL7s3.js +0 -1
  503. package/dist/interface/assets/types-i1kTodPP.js +0 -1
  504. package/dist/interface/assets/ungrouped-BlheTJCh.css +0 -1
  505. package/dist/interface/assets/ungrouped-C2CWO39a.js +0 -1
  506. package/dist/interface/assets/updates-C2LhMkNR.js +0 -1
  507. package/dist/interface/assets/useBackupRestore-DMQW_CVC.js +0 -1
  508. package/dist/interface/assets/useUserOptions-DN0t3gBr.js +0 -1
  509. package/dist/interface/assets/vendor-gFkr2qsZ.js +0 -23
  510. package/dist/interface/assets/vendor-leaflet-DkAk6mAj.js +0 -1
  511. package/dist/interface/assets/web-BDNQnMmA.js +0 -1
  512. package/dist/interface/assets/web-B_9Qyt8E.js +0 -1
  513. package/dist/interface/assets/web-BhJykCtq.js +0 -1
  514. package/dist/interface/assets/web-BjKL51lK-wWFeZlLg.js +0 -1
  515. package/dist/interface/assets/web-C7nJwIOa.js +0 -1
  516. package/dist/interface/assets/web-CGJsJQDb.js +0 -1
  517. package/dist/interface/assets/web-CJwASxrl.js +0 -1
  518. package/dist/interface/assets/web-CLe0L31Y.js +0 -1
  519. package/dist/interface/assets/web-DEv1hAn1.js +0 -1
  520. package/dist/interface/assets/web-DaeQvsXT.js +0 -1
  521. package/dist/interface/assets/web-H3-wNunW.js +0 -1
  522. package/dist/interface/assets/web-LCdyqJq1.js +0 -1
  523. package/dist/interface/assets/web-XZWYTK65.js +0 -1
  524. package/dist/interface/assets/web-rU5hlxxW.js +0 -1
  525. package/dist/interface/assets/workbox-window.prod.es5-BEYAF-e-.js +0 -1
  526. package/dist/interface/ha/Camera-Cj5ImvZG.js +0 -657
  527. package/dist/interface/ha/Workers-2HTPHgKV.js +0 -765
  528. package/dist/interface/ha/eye-off-outline-ACbzsGuK.js +0 -19
@@ -2,69 +2,69 @@ import { c as e, m as t } from "./ripple-ZDATPc2w.js";
2
2
  import { B as n, D as r, Dt as i, G as a, H as o, Jt as s, K as c, M as l, Wt as u, _t as d, bt as f, d as p, f as m, ft as h, gt as g, kt as _, l as v, lt as y, ot as b, p as x, qt as S, r as C, rt as w, u as T, ut as E, v as D, x as O, xt as k, y as A, yt as j, z as M } from "./runtime-core.esm-bundler-_TfE0DWz.js";
3
3
  import { t as ee } from "./tooltip-BDrlgLof.js";
4
4
  import { t as te } from "./message-D6dIy_hz.js";
5
- import { An as N, Ar as P, D as F, Dr as ne, Dt as re, E as I, Er as ie, F as L, I as R, Jt as z, O as B, Ot as V, P as H, Si as U, a as W, et as ae, fi as oe, gr as se, gt as G, k as K, m as q, si as ce, wr as le, xt as ue } from "./api-BelbnLQO.js";
6
- import { M as de } from "./protocol-BB4jdtUC-DW3jl2tV.js";
7
- import { i as fe, o as pe } from "./intercomService-B7HkLs6z.js";
8
- import { $ as me, et as he, nt as ge, rt as _e, tt as ve } from "./pinia-BokSpDzj.js";
9
- import { n as J } from "./vue-i18n-D5EAy78K.js";
10
- import { n as ye, t as be } from "./button-BouAFgf5.js";
11
- import { t as Y } from "./inputtext-C_ygnPrC.js";
12
- import { t as xe } from "./close-CxFbonhd.js";
13
- import { t as Se } from "./select-DV7p2EDj.js";
14
- import { i as Ce, n as we, r as Te, t as Ee } from "./accordion-BylV-jUK.js";
15
- import { t as De } from "./chip-BTHURsTF.js";
16
- import { i as Oe, t as ke } from "./CuiDataTable-BtqzIz0o.js";
17
- import { n as Ae, r as je, t as Me } from "./CuiSchema-DqkCLv9Y.js";
18
- import { t as Ne } from "./CuiCameraTable-kL8rK-Uv.js";
19
- import { u as Pe } from "./cards-BFRRfuM7.js";
20
- import { t as Fe } from "./plus-CgxY7W0L.js";
21
- import { t as Ie } from "./radar-BG-Tcwg_.js";
22
- import { n as Le, t as Re } from "./eye-off-UG_p9nl8.js";
23
- import { t as ze } from "./rooms-BvaD0r0q.js";
5
+ import { An as N, D as P, Dt as ne, E as F, Er as re, F as I, I as L, Jt as R, Mr as ie, O as z, Or as ae, Ot as B, P as V, _r as oe, a as H, et as se, gt as U, k as W, kr as ce, li as le, m as G, mi as ue, wi as K, xt as de } from "./api-DUqpDJ2N.js";
6
+ import { M as fe } from "./protocol-BB4jdtUC-DW3jl2tV.js";
7
+ import { i as pe, o as me } from "./intercomService-B7HkLs6z.js";
8
+ import { $ as he, et as ge, it as _e, nt as ve, rt as ye, tt as be } from "./pinia-DIKO5lnE.js";
9
+ import { n as q } from "./vue-i18n-D5EAy78K.js";
10
+ import { n as xe, t as Se } from "./button-BouAFgf5.js";
11
+ import { t as J } from "./inputtext-C_ygnPrC.js";
12
+ import { t as Ce } from "./close-CxFbonhd.js";
13
+ import { t as we } from "./select-DV7p2EDj.js";
14
+ import { i as Te, n as Ee, r as De, t as Oe } from "./accordion-BylV-jUK.js";
15
+ import { t as ke } from "./chip-BTHURsTF.js";
16
+ import { i as Ae, t as je } from "./CuiDataTable-BOdQDY8J.js";
17
+ import { n as Me, r as Ne, t as Pe } from "./CuiSchema-Cb_8Ks-I.js";
18
+ import { t as Fe } from "./CuiCameraTable-CKjGKaMC.js";
19
+ import { u as Ie } from "./cards-DWhezIPP.js";
20
+ import { t as Le } from "./plus-CgxY7W0L.js";
21
+ import { t as Re } from "./radar-BG-Tcwg_.js";
22
+ import { n as ze, t as Be } from "./eye-off-UG_p9nl8.js";
23
+ import { t as Ve } from "./rooms-C5gUErBi.js";
24
24
  //#region ~icons/material-symbols/camera-rounded
25
- var Be = {
25
+ var He = {
26
26
  viewBox: "0 0 24 24",
27
27
  width: "1.2em",
28
28
  height: "1.2em"
29
29
  };
30
- function Ve(e, t) {
31
- return o(), x("svg", Be, [...t[0] ||= [T("path", {
30
+ function Ue(e, t) {
31
+ return o(), x("svg", He, [...t[0] ||= [T("path", {
32
32
  fill: "currentColor",
33
33
  d: "M12.5 9q-.275 0-.425-.25t0-.5L15 3.175q.2-.325.5-.387t.65.112q1.725.775 3.05 2.162T21.25 8.2q.125.325-.038.563T20.7 9zm-3.575 1.225l-3-5.2q-.2-.325-.1-.65t.4-.525Q7.425 3 8.888 2.5T12 2q.375 0 .825.038t.75.087q.35.05.463.3t-.063.55L9.8 10.225q-.15.25-.437.25t-.438-.25M2.85 14q-.275 0-.5-.187t-.275-.463t-.062-.6T2 12q0-1.575.513-3.137T4.1 5.9q.275-.35.638-.35t.562.375l4.2 7.325q.15.25-.012.5T9.05 14zm5 7.1q-1.65-.8-3.025-2.175T2.75 15.8q-.125-.325.05-.562T3.325 15h8.15q.275 0 .425.25t0 .5l-2.875 5.025q-.2.325-.5.425t-.675-.1M12 22q-.35 0-.788-.038t-.762-.087q-.35-.05-.475-.3t.05-.55l4.125-7.2q.15-.25.5-.25t.5.25l2.95 5.125q.175.275.113.6t-.413.6q-1.15.85-2.687 1.35T12 22m6.775-3.875l-4.25-7.375q-.15-.25.013-.5t.437-.25h6.175q.275 0 .5.188t.275.462t.062.6T22 12q0 1.575-.513 3.163T19.9 18.125q-.2.275-.575.288t-.55-.288"
34
34
  }, null, -1)]]);
35
35
  }
36
- var He = d({
36
+ var We = d({
37
37
  name: "material-symbols-camera-rounded",
38
- render: Ve
39
- }), Ue = "#### Source: Bubble\n\nOther names: [ESeeCloud](http://www.eseecloud.com/), [dvr163](http://help.dvr163.com/).\n\n- you can skip `username`, `password`, `port`, `ch` and `stream` if they are default\n- setup separate streams for different channels and streams\n\n```yaml\nstreams:\n camera1: bubble://username:password@192.168.1.123:34567/bubble/live?ch=0&stream=0\n```\n\n_Source: [Go2Rtc Bubble](https://github.com/seydx/go2rtc#source-bubble)_\n", We = "#### Source: CUI\n\nThis source can be used to stream dynamically generated, go2rtc compatible, URLs. The source is just a placeholder for a `https://` URL.\n\n```yaml\nstreams:\n camera1: cui://192.168.1.123:34567/some-identifier-if-you-want\n```\n\nThe URL will be changed to `https://192.168.1.123:34567/some-identifier-if-you-want` and the response must be like this:\n\n```json\n{\n {\n \"streamUrl\": \"rtsp://192.168.1.1:554/stream\",\n }\n}\n```\n\nGo2rtc will then use the `streamUrl` to stream the video. The `streamUrl` can be any URL that is compatible with go2rtc. The response must be a valid JSON object with the `streamUrl` key.\n", Ge = "#### Source: Doorbird\n\n[Doorbird](https://www.doorbird.com/) proprietary camera protocol with **two way audio** support.\n\n```yaml\nstreams:\n video-audio:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n two-way:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n - doorbird://user:pass@123.123.123.123\n mjpeg-video:\n - doorbird://user:pass@123.123.123.123?media=video\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-doorbird)_\n", Ke = "#### Source: DVRIP\n\nOther names: DVR-IP, NetSurveillance, Sofia protocol (NETsurveillance ActiveX plugin XMeye SDK).\n\n- you can skip `username`, `password`, `port`, `channel` and `subtype` if they are default\n- setup separate streams for different channels\n- use `subtype=0` for Main stream, and `subtype=1` for Extra1 stream\n- only the TCP protocol is supported\n\n```yaml\nstreams:\n only_stream: dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n only_tts: dvrip://username:password@192.168.1.123:34567?backchannel=1\n two_way_audio:\n - dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n - dvrip://username:password@192.168.1.123:34567?backchannel=1\n```\n\n_Source: [Go2Rtc DVRIP](https://github.com/seydx/go2rtc#source-dvrip)_\n", qe = "#### Source: Echo\n\nSome sources may have a dynamic link. And you will need to get it using a bash or python script. Your script should echo a link to the source. RTSP, FFmpeg or any of the [supported sources](https://github.com/seydx/go2rtc#module-streams).\n\n**Docker** and **Hass Add-on** users has preinstalled `python3`, `curl`, `jq`.\nCheck examples in [wiki](https://github.com/seydx/go2rtc/wiki/Source-Echo-examples).\n\n```yaml\nstreams:\n apple_hls: echo:python3 hls.py https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\n```\n\n_Source: [Go2Rtc Echo](https://github.com/seydx/go2rtc#source-echo)_\n", Je = "#### Source: Exec\n\nExec source can run any external application and expect data from it. Two transports are supported - **pipe** and **RTSP**.\n\nIf you want to use **RTSP** transport - the command must contain the `{output}` argument in any place. On launch, it will be replaced by the local address of the RTSP server.\n\n**pipe** reads data from app stdout in different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**. Also pipe can write data to app stdin in two formats: **PCMA** and **PCM/48000**.\n\nThe source can be used with:\n\n- [FFmpeg](https://ffmpeg.org/) - go2rtc ffmpeg source just a shortcut to exec source\n- [FFplay](https://ffmpeg.org/ffplay.html) - play audio on your server\n- [GStreamer](https://gstreamer.freedesktop.org/)\n- [Raspberry Pi Cameras](https://www.raspberrypi.com/documentation/computers/camera_software.html)\n- any your own software\n\n```yaml\nstreams:\n stream: exec:ffmpeg -re -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {output}\n picam_h264: exec:libcamera-vid -t 0 --inline -o -\n picam_mjpeg: exec:libcamera-vid -t 0 --codec mjpeg -o -\n pi5cam_h264: exec:libcamera-vid -t 0 --libav-format h264 -o -\n canon: exec:gphoto2 --capture-movie --stdout#killsignal=2#killtimeout=5\n play_pcma: exec:ffplay -fflags nobuffer -f alaw -ar 8000 -i -#backchannel=1\n play_pcm48k: exec:ffplay -fflags nobuffer -f s16be -ar 48000 -i -#backchannel=1\n```\n\n_Source: [Go2Rtc Exec](https://github.com/seydx/go2rtc#source-exec)_\n", Ye = "#### Source: Expr\n\n[Expr](https://github.com/antonmedv/expr) - expression language and expression evaluation for Go.\n\n- [language definition](https://expr.medv.io/docs/Language-Definition) - takes best from JS, Python, Jinja2 syntax\n- your expression should return a link of any supported source\n- expression supports multiple operation, but:\n - all operations must be separated by a semicolon\n - all operations, except the last one, must declare a new variable (`let s = \"abc\";`)\n - the last operation should return a string\n- go2rtc supports additional functions:\n - `fetch` - JS-like HTTP requests\n - `match` - JS-like RegExp queries\n\n## Examples\n\n**Two way audio for Dahua VTO**\n\n```yaml\nstreams:\n dahua_vto: |\n expr: let host = \"admin:password@192.168.1.123\";\n fetch(\"http://\"+host+\"/cgi-bin/configManager.cgi?action=setConfig&Encode[0].MainFormat[0].Audio.Compression=G.711A&Encode[0].MainFormat[0].Audio.Frequency=8000\").ok\n ? \"rtsp://\"+host+\"/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\" : \"\"\n```\n\n**dom.ru**\n\nYou can get credentials via:\n\n- https://github.com/alexmorbo/domru (file `/share/domru/accounts`)\n- https://github.com/ad/domru\n\n```yaml\nstreams:\n dom_ru: |\n expr: let camera = \"99999999\"; let token = \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"; let operator = 99;\n fetch(\"https://myhome.novotelecom.ru/rest/v1/forpost/cameras/\"+camera+\"/video\", {\n headers: {Authorization: \"Bearer \"+token, Operator: operator}\n }).json().data.URL\n```\n\n**Parse HLS files from Apple**\n\nSame example in two languages - python and expr.\n\n```yaml\nstreams:\n example_python: |\n echo:python -c 'from urllib.request import urlopen; import re\n\n # url1 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8\"\n html1 = urlopen(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").read().decode(\"utf-8\")\n url1 = re.search(r\"https.+?m3u8\", html1)[0]\n\n # url2 = \"gear1/prog_index.m3u8\"\n html2 = urlopen(url1).read().decode(\"utf-8\")\n url2 = re.search(r\"^[a-z0-1/_]+\\.m3u8$\", html2, flags=re.MULTILINE)[0]\n\n # url3 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear1/prog_index.m3u8\"\n url3 = url1[:url1.rindex(\"/\")+1] + url2\n\n print(\"ffmpeg:\" + url3 + \"#video=copy\")'\n\n example_expr: |\n expr:\n\n let html1 = fetch(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").text;\n let url1 = match(html1, \"https.+?m3u8\")[0];\n\n let html2 = fetch(url1).text;\n let url2 = match(html2, \"^[a-z0-1/_]+\\\\.m3u8$\", \"m\")[0];\n\n let url3 = url1[:lastIndexOf(url1, \"/\")+1] + url2;\n\n \"ffmpeg:\" + url3 + \"#video=copy\"\n```\n\n## Comparsion\n\n| expr | python | js |\n| ---------------------------- | -------------------------- | ------------------------------ |\n| let x = 1; | x = 1 | let x = 1 |\n| {a: 1, b: 2} | {\"a\": 1, \"b\": 2} | {a: 1, b: 2} |\n| let r = fetch(url, {method}) | r = request(method, url) | r = await fetch(url, {method}) |\n| r.ok | r.ok | r.ok |\n| r.status | r.status_code | r.status |\n| r.text | r.text | await r.text() |\n| r.json() | r.json() | await r.json() |\n| r.headers | r.headers | r.headers |\n| let m = match(text, \"abc\") | m = re.search(\"abc\", text) | let m = text.match(/abc/) |\n\n_Source: [Go2Rtc Expr](https://github.com/seydx/go2rtc#source-expr)_\n", Xe = "#### Source: FFmpeg\n\nYou can get any stream or file or device via FFmpeg and push it to go2rtc. The app will automatically start FFmpeg with the proper arguments when someone starts watching the stream.\n\n- FFmpeg preistalled for **Docker** and **Hass Add-on** users\n- **Hass Add-on** users can target files from [/media](https://www.home-assistant.io/more-info/local-media/setup-media/) folder\n\nFormat: `ffmpeg:{input}#{param1}#{param2}#{param3}`. Examples:\n\n```yaml\nstreams:\n # [FILE] all tracks will be copied without transcoding codecs\n file1: ffmpeg:/media/BigBuckBunny.mp4\n\n # [FILE] video will be transcoded to H264, audio will be skipped\n file2: ffmpeg:/media/BigBuckBunny.mp4#video=h264\n\n # [FILE] video will be copied, audio will be transcoded to pcmu\n file3: ffmpeg:/media/BigBuckBunny.mp4#video=copy#audio=pcmu\n\n # [HLS] video will be copied, audio will be skipped\n hls: ffmpeg:https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear5/prog_index.m3u8#video=copy\n\n # [MJPEG] video will be transcoded to H264\n mjpeg: ffmpeg:http://185.97.122.128/cgi-bin/faststream.jpg#video=h264\n\n # [RTSP] video with rotation, should be transcoded, so select H264\n rotate: ffmpeg:rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0#video=h264#rotate=90\n```\n\nAll trascoding formats has [built-in templates](https://github.com/seydx/go2rtc/blob/master/internal/ffmpeg/ffmpeg.go): `h264`, `h265`, `opus`, `pcmu`, `pcmu/16000`, `pcmu/48000`, `pcma`, `pcma/16000`, `pcma/48000`, `aac`, `aac/16000`.\n\nBut you can override them via YAML config. You can also add your own formats to config and use them with source params.\n\n```yaml\nffmpeg:\n bin: ffmpeg # path to ffmpeg binary\n h264: '-codec:v libx264 -g:v 30 -preset:v superfast -tune:v zerolatency -profile:v main -level:v 4.1'\n mycodec: '-any args that supported by ffmpeg...'\n myinput: '-fflags nobuffer -flags low_delay -timeout 5000000 -i {input}'\n myraw: '-ss 00:00:20'\n```\n\n- You can use go2rtc stream name as ffmpeg input (ex. `ffmpeg:camera1#video=h264`)\n- You can use `video` and `audio` params multiple times (ex. `#video=copy#audio=copy#audio=pcmu`)\n- You can use `rotate` param with `90`, `180`, `270` or `-90` values, important with transcoding (ex. `#video=h264#rotate=90`)\n- You can use `width` and/or `height` params, important with transcoding (ex. `#video=h264#width=1280`)\n- You can use `drawtext` to add a timestamp (ex. `drawtext=x=2:y=2:fontsize=12:fontcolor=white:box=1:boxcolor=black`)\n - This will greatly increase the CPU of the server, even with hardware acceleration\n- You can use `raw` param for any additional FFmpeg arguments (ex. `#raw=-vf transpose=1`)\n- You can use `input` param to override default input template (ex. `#input=rtsp/udp` will change RTSP transport from TCP to UDP+TCP)\n - You can use raw input value (ex. `#input=-timeout 5000000 -i {input}`)\n - You can add your own input templates\n\nRead more about [hardware acceleration](https://github.com/seydx/go2rtc/wiki/Hardware-acceleration).\n\n**PS.** It is recommended to check the available hardware in the WebUI add page.\n\n<hr>\n\n#### Source: FFmpeg Device\n\nYou can get video from any USB-camera or Webcam as RTSP or WebRTC stream. This is part of FFmpeg integration.\n\n- check available devices in Web interface\n- `video_size` and `framerate` must be supported by your camera!\n- for Linux supported only video for now\n- for macOS you can stream Facetime camera or whole Desktop!\n- for macOS important to set right framerate\n\nFormat: `ffmpeg:device?{input-params}#{param1}#{param2}#{param3}`\n\n```yaml\nstreams:\n linux_usbcam: ffmpeg:device?video=0&video_size=1280x720#video=h264\n windows_webcam: ffmpeg:device?video=0#video=h264\n macos_facetime: ffmpeg:device?video=0&audio=1&video_size=1280x720&framerate=30#video=h264#audio=pcma\n```\n\n**PS.** It is recommended to check the available devices in the WebUI add page.\n\n_Source: [Go2Rtc FFmpeg](https://github.com/seydx/go2rtc#source-ffmpeg) & [Go2Rtc FFmpeg Device](https://github.com/seydx/go2rtc#source-ffmpeg-device)_\n", Ze = "#### Source: GoPro\n\nSupported models: HERO9, HERO10, HERO11, HERO12. \nSupported OS: Linux, Mac, Windows, [HassOS](https://www.home-assistant.io/installation/)\n\nThe other camera models have different APIs. I will try to add them in the next versions.\n\n## Config\n\n- USB-connected cameras create a new network interface in the system\n- Linux users do not need to install anything\n- Windows users should install the [network driver](https://community.gopro.com/s/article/GoPro-Webcam)\n- if the camera is detected but the stream does not start - you need to disable firewall\n\n1. Discover camera address: WebUI > Add > GoPro\n2. Add camera to config\n\n```yaml\nstreams:\n hero12: gopro://172.20.100.51\n```\n\n## Useful links\n\n- https://gopro.github.io/OpenGoPro/\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", Qe = "#### Source: Hass\n\nSupport import camera links from [Home Assistant](https://www.home-assistant.io/) config files:\n\n- [Generic Camera](https://www.home-assistant.io/integrations/generic/), setup via GUI\n- [HomeKit Camera](https://www.home-assistant.io/integrations/homekit_controller/)\n- [ONVIF](https://www.home-assistant.io/integrations/onvif/)\n- [Roborock](https://github.com/humbertogontijo/homeassistant-roborock) vacuums with camera\n\n```yaml\nhass:\n config: '/config' # skip this setting if you Hass Add-on user\n\nstreams:\n generic_camera: hass:Camera1 # Settings > Integrations > Integration Name\n aqara_g3: hass:Camera-Hub-G3-AB12\n```\n\n**WebRTC Cameras**\n\nAny cameras in WebRTC format are supported. But at the moment Home Assistant only supports some [Nest](https://www.home-assistant.io/integrations/nest/) cameras in this fomat.\n\nThe Nest API only allows you to get a link to a stream for 5 minutes. So every 5 minutes the stream will be reconnected.\n\n```yaml\nstreams:\n # link to Home Assistant Supervised\n hass-webrtc1: hass://supervisor?entity_id=camera.nest_doorbell\n # link to external Hass with Long-Lived Access Tokens\n hass-webrtc2: hass://192.168.1.123:8123?entity_id=camera.nest_doorbell&token=eyXYZ...\n```\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", $e = "#### Source: HomeKit\n\n**Important:**\n\n- You can use HomeKit Cameras **without Apple devices** (iPhone, iPad, etc.), it's just a yet another protocol\n- HomeKit device can be paired with only one ecosystem. So, if you have paired it to an iPhone (Apple Home) - you can't pair it with Home Assistant or go2rtc. Or if you have paired it to go2rtc - you can't pair it with iPhone\n- HomeKit device should be in same network with working [mDNS](https://en.wikipedia.org/wiki/Multicast_DNS) between device and go2rtc\n\ngo2rtc support import paired HomeKit devices from [Home Assistant](#source-hass). So you can use HomeKit camera with Hass and go2rtc simultaneously. If you using Hass, I recommend pairing devices with it, it will give you more options.\n\nYou can pair device with go2rtc on the HomeKit page. If you can't see your devices - reload the page. Also try reboot your HomeKit device (power off). If you still can't see it - you have a problems with mDNS.\n\nIf you see a device but it does not have a pair button - it is paired to some ecosystem (Apple Home, Home Assistant etc). You need to delete device from that ecosystem, and it will be available for pairing. If you cannot unpair device, you will have to reset it.\n\n**Important:**\n\n- HomeKit audio uses very non-standard **AAC-ELD** codec with very non-standard params and specification violation\n- Audio can't be played in `VLC` and probably any other player\n- Audio should be transcoded for using with MSE, WebRTC, etc.\n\nRecommended settings for using HomeKit Camera with WebRTC, MSE, MP4, RTSP:\n\n```\nstreams:\n aqara_g3:\n - hass:Camera-Hub-G3-AB12\n - ffmpeg:aqara_g3#audio=aac#audio=opus\n```\n\nRTSP link with \"normal\" audio for any player: `rtsp://192.168.1.123:8554/aqara_g3?video&audio=aac`\n\n**This source is in active development!** Tested only with [Aqara Camera Hub G3](https://www.aqara.com/eu/product/camera-hub-g3) (both EU and CN versions).\n\n_Source: [Go2Rtc HomeKit](https://github.com/seydx/go2rtc#source-homekit)_\n", et = "#### Source: HTTP\n\nSupport Content-Type:\n\n- **HTTP-FLV** (`video/x-flv`) - same as RTMP, but over HTTP\n- **HTTP-JPEG** (`image/jpeg`) - camera snapshot link, can be converted by go2rtc to MJPEG stream\n- **HTTP-MJPEG** (`multipart/x`) - simple MJPEG stream over HTTP\n- **MPEG-TS** (`video/mpeg`) - legacy [streaming format](https://en.wikipedia.org/wiki/MPEG_transport_stream)\n\nSource also support HTTP and TCP streams with autodetection for different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**.\n\n```yaml\nstreams:\n # [HTTP-FLV] stream in video/x-flv format\n http_flv: http://192.168.1.123:20880/api/camera/stream/780900131155/657617\n\n # [JPEG] snapshots from Dahua camera, will be converted to MJPEG stream\n dahua_snap: http://admin:password@192.168.1.123/cgi-bin/snapshot.cgi?channel=1\n\n # [MJPEG] stream will be proxied without modification\n http_mjpeg: https://mjpeg.sanford.io/count.mjpeg\n\n # [MJPEG or H.264/H.265 bitstream or MPEG-TS]\n tcp_magic: tcp://192.168.1.123:12345\n\n # Add custom header\n custom_header: 'https://mjpeg.sanford.io/count.mjpeg#header=Authorization: Bearer XXX'\n```\n\n**PS.** Dahua camera has bug: if you select MJPEG codec for RTSP second stream - snapshot won't work.\n\n_Source: [Go2Rtc Http](https://github.com/seydx/go2rtc#source-http)_\n", tt = "#### Source: ISAPI\n\nThis source type support only backchannel audio for Hikvision ISAPI protocol. So it should be used as second source in addition to the RTSP protocol.\n\n```yaml\nstreams:\n hikvision1:\n - rtsp://admin:password@192.168.1.123:554/Streaming/Channels/101\n - isapi://admin:password@192.168.1.123:80/\n```\n\n_Source: [Go2Rtc Isapi](https://github.com/seydx/go2rtc#source-isapi)_\n", nt = "#### Source: Ivideon\n\nSupport public cameras from service [Ivideon](https://tv.ivideon.com/).\n\n```yaml\nstreams:\n quailcam: ivideon:100-tu5dkUPct39cTp9oNEN2B6/0\n```\n\n_Source: [Go2Rtc Ivideon](https://github.com/seydx/go2rtc#source-ivideon)_\n", rt = "#### Source: Kasa\n\n[TP-Link Kasa](https://www.kasasmart.com/) non-standard protocol [more info](https://medium.com/@hu3vjeen/reverse-engineering-tp-link-kc100-bac4641bf1cd).\n\n- `username` - urlsafe email, `alex@gmail.com` -> `alex%40gmail.com`\n- `password` - base64password, `secret1` -> `c2VjcmV0MQ==`\n\n```yaml\nstreams:\n kc401: kasa://username:password@192.168.1.123:19443/https/stream/mixed\n```\n\nTested: KD110, KC200, KC401, KC420WS, EC71.\n\n_Source: [Go2Rtc Kasa](https://github.com/seydx/go2rtc#source-kasa)_\n", it = "#### Source: Nest\n\nCurrently only WebRTC cameras are supported.\n\nFor simplicity, it is recommended to connect the Nest/WebRTC camera to the [Home Assistant](#source-hass). But if you can somehow get the below parameters - Nest/WebRTC source will work without Hass.\n\n```yaml\nstreams:\n nest-doorbell: nest:?client_id=***&client_secret=***&refresh_token=***&project_id=***&device_id=***\n```\n\n_Source: [Go2Rtc Nest](https://github.com/seydx/go2rtc#source-nest)_\n", at = "#### Source: ONVIF\n\nThe source is not very useful if you already know RTSP and snapshot links for your camera. But it can be useful if you don't.\n\n**WebUI > Add** webpage support ONVIF autodiscovery. Your server must be on the same subnet as the camera. If you use docker, you must use \"network host\".\n\n```yaml\nstreams:\n dahua1: onvif://admin:password@192.168.1.123\n reolink1: onvif://admin:password@192.168.1.123:8000\n tapo1: onvif://admin:password@192.168.1.123:2020\n```\n\n_Source: [Go2Rtc Onvif](https://github.com/seydx/go2rtc#source-onvif)_\n", ot = "#### Source: Ring\n\nThis source type support Ring cameras with [two way audio](#two-way-audio) support. If you have a `refresh_token` and `device_id` - you can use it in `go2rtc.yaml` config file. Otherwise, you can use the go2rtc interface and add your ring account (WebUI > Add > Ring). Once added, it will list all your Ring cameras.\n\n```yaml\nstreams:\n ring: ring:?device_id=XXX&refresh_token=XXX\n ring_snapshot: ring:?device_id=XXX&refresh_token=XXX&snapshot\n```\n\n_Source: [Go2Rtc Ring](https://github.com/seydx/go2rtc#source-ring)_\n", st = "#### Source: Roborock\n\nThis source type support Roborock vacuums with cameras. Known working models:\n\n- Roborock S6 MaxV - only video (the vacuum has no microphone)\n- Roborock S7 MaxV - video and two way audio\n- Roborock Qrevo MaxV - video and two way audio\n\nSource support load Roborock credentials from Home Assistant [custom integration](https://github.com/humbertogontijo/homeassistant-roborock) or the [core integration](https://www.home-assistant.io/integrations/roborock). Otherwise, you need to log in to your Roborock account (MiHome account is not supported). Go to: go2rtc WebUI > Add webpage. Copy `roborock://...` source for your vacuum and paste it to `go2rtc.yaml` config.\n\nIf you have graphic pin for your vacuum - add it as numeric pin (lines: 123, 456, 789) to the end of the roborock-link.\n\n_Source: [Go2Rtc Roborock](https://github.com/seydx/go2rtc#source-roborock)_\n", ct = "#### Source: RTMP\n\nYou can get stream from RTMP server, for example [Nginx with nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module).\n\n```yaml\nstreams:\n rtmp_stream: rtmp://192.168.1.123/live/camera1\n```\n\n_Source: [Go2Rtc RTMP](https://github.com/seydx/go2rtc#source-rtmp)_\n", lt = "#### Source: RTSP\n\n```yaml\nstreams:\n sonoff_camera: rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0\n dahua_camera:\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=1\n amcrest_doorbell:\n - rtsp://username:password@192.168.1.123:554/cam/realmonitor?channel=1&subtype=0#backchannel=0\n unifi_camera: rtspx://192.168.1.123:7441/fD6ouM72bWoFijxK\n glichy_camera: ffmpeg:rtsp://username:password@192.168.1.123/live/ch00_1\n```\n\n**Recommendations**\n\n- **Amcrest Doorbell** users may want to disable two way audio, because with an active stream you won't have a call button working. You need to add `#backchannel=0` to the end of your RTSP link in YAML config file\n- **Dahua Doorbell** users may want to change backchannel [audio codec](https://github.com/AlexxIT/go2rtc/issues/52)\n- **Reolink** users may want NOT to use RTSP protocol at all, some camera models have a very awful unusable stream implementation\n- **Ubiquiti UniFi** users may want to disable HTTPS verification. Use `rtspx://` prefix instead of `rtsps://`. And don't use `?enableSrtp` [suffix](https://github.com/AlexxIT/go2rtc/issues/81)\n- **TP-Link Tapo** users may skip login and password, because go2rtc support login [without them](https://drmnsamoliu.github.io/video.html)\n- If your camera has two RTSP links - you can add both of them as sources. This is useful when streams has different codecs, as example AAC audio with main stream and PCMU/PCMA audio with second stream\n- If the stream from your camera is glitchy, try using [ffmpeg source](#source-ffmpeg). It will not add CPU load if you won't use transcoding\n- If the stream from your camera is very glitchy, try to use transcoding with [ffmpeg source](#source-ffmpeg)\n\n**Other options**\n\nFormat: `rtsp...#{param1}#{param2}#{param3}`\n\n- Ignore audio - `#media=video` or ignore video - `#media=audio`\n- Ignore two way audio API `#backchannel=0` - important for some glitchy cameras\n- Use WebSocket transport `#transport=ws...`\n\n**RTSP over WebSocket**\n\n```yaml\nstreams:\n # WebSocket with authorization, RTSP - without\n axis-rtsp-ws: rtsp://192.168.1.123:4567/axis-media/media.amp?overview=0&camera=1&resolution=1280x720&videoframeskipmode=empty&Axis-Orig-Sw=true#transport=ws://user:pass@192.168.1.123:4567/rtsp-over-websocket\n # WebSocket without authorization, RTSP - with\n dahua-rtsp-ws: rtsp://user:pass@192.168.1.123/cam/realmonitor?channel=1&subtype=1&proto=Private3#transport=ws://192.168.1.123/rtspoverwebsocket\n```\n\n_Source: [Go2Rtc RTSP](https://github.com/seydx/go2rtc#source-rtsp)_\n", ut = "#### Source: Tapo\n\n[TP-Link Tapo](https://www.tapo.com/) proprietary camera protocol with **two way audio** support.\n\n- stream quality is the same as [RTSP protocol](https://www.tapo.com/en/faq/34/)\n- use the **cloud password**, this is not the RTSP password! you do not need to add a login!\n- you can also use UPPERCASE MD5 hash from your cloud password with `admin` username\n- some new camera firmwares requires SHA256 instead of MD5\n\n```yaml\nstreams:\n # cloud password without username\n camera1: tapo://cloud-password@192.168.1.123\n # admin username and UPPERCASE MD5 cloud-password hash\n camera2: tapo://admin:UPPERCASE-MD5@192.168.1.123\n # admin username and UPPERCASE SHA256 cloud-password hash\n camera3: tapo://admin:UPPERCASE-SHA256@192.168.1.123\n```\n\n```bash\necho -n \"cloud password\" | md5 | awk '{print toupper($0)}'\necho -n \"cloud password\" | shasum -a 256 | awk '{print toupper($0)}'\n```\n\n_Source: [Go2Rtc Tapo](https://github.com/seydx/go2rtc#source-tapo)_\n", dt = "#### Source: Tuya\n\n[Tuya](https://www.tuya.com/) proprietary camera protocol with **two way audio** support. Go2rtc supports `Tuya Smart API` and `Tuya Cloud API`.\n\n**Tuya Smart API (recommended)**:\n\n- Cameras can be discovered through the go2rtc web interface via Tuya Smart account (Add > Tuya > Select region and fill in email and password > Login).\n- **Smart Life accounts are not supported**, you need to create a Tuya Smart account. If the cameras are already added to the Smart Life app, you need to remove them and add them again to the Tuya Smart app.\n\n**Tuya Cloud API**:\n\n- Requires setting up a cloud project in the Tuya Developer Platform.\n- Obtain `device_id`, `client_id`, `client_secret`, and `uid` from [Tuya IoT Platform](https://iot.tuya.com/). [Here's a guide](https://xzetsubou.github.io/hass-localtuya/cloud_api/).\n- Please ensure that you have subscribed to the `IoT Video Live Stream` service (Free Trial) in the Tuya Developer Platform, otherwise the stream will not work (Tuya Developer Platform > Service API > Authorize > IoT Video Live Stream).\n\n**Configuring the stream:**\n\n- Use `resolution` parameter to select the stream (not all cameras support `hd` stream through WebRTC even if the camera has it):\n - `hd` - HD stream (default)\n - `sd` - SD stream\n\n```yaml\nstreams:\n # Tuya Smart API: WebRTC main stream (use Add > Tuya to discover the URL)\n tuya_main:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX\n\n # Tuya Smart API: WebRTC sub stream (use Add > Tuya to discover the URL)\n tuya_sub:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX&resolution=sd\n\n # Tuya Cloud API: WebRTC main stream\n tuya_webrtc:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX\n\n # Tuya Cloud API: WebRTC sub stream\n tuya_webrtc_sd:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX&resolution=sd\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-tuya)_\n", ft = "#### Source: WebRTC\n\nThis source type support four connection formats.\n\n**whep**\n\n[WebRTC/WHEP](https://datatracker.ietf.org/doc/draft-murillo-whep/) - is replaced by [WebRTC/WISH](https://datatracker.ietf.org/doc/charter-ietf-wish/02/) standard for WebRTC video/audio viewers. But it may already be supported in some third-party software. It is supported in go2rtc.\n\n**go2rtc**\n\nThis format is only supported in go2rtc. Unlike WHEP it supports asynchronous WebRTC connection and two way audio.\n\n**openipc**\n\nSupport connection to [OpenIPC](https://openipc.org/) cameras.\n\n**wyze**\n\nSupports connection to [Wyze](https://www.wyze.com/) cameras, using WebRTC protocol. You can use [docker-wyze-bridge](https://github.com/mrlt8/docker-wyze-bridge) project to get connection credentials.\n\n**kinesis**\n\nSupports [Amazon Kinesis Video Streams](https://aws.amazon.com/kinesis/video-streams/), using WebRTC protocol. You need to specify signalling WebSocket URL with all credentials in query params, `client_id` and `ice_servers` list in [JSON format](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer).\n\n```yaml\nstreams:\n webrtc-whep: webrtc:http://192.168.1.123:1984/api/webrtc?src=camera1\n webrtc-go2rtc: webrtc:ws://192.168.1.123:1984/api/ws?src=camera1\n webrtc-openipc: webrtc:ws://192.168.1.123/webrtc_ws#format=openipc#ice_servers=[{\"urls\":\"stun:stun.kinesisvideo.eu-north-1.amazonaws.com:443\"}]\n webrtc-wyze: webrtc:http://192.168.1.123:5000/signaling/camera1?kvs#format=wyze\n webrtc-kinesis: webrtc:wss://...amazonaws.com/?...#format=kinesis#client_id=...#ice_servers=[{...},{...}]\n```\n\n**PS.** For `kinesis` sources you can use [echo](#source-echo) to get connection params using `bash`/`python` or any other script language.\n\n_Source: [Go2Rtc WebRTC](https://github.com/seydx/go2rtc#source-webrtc)_\n", pt = "#### Source: WebTorrent\n\nThis source can get a stream from another go2rtc via [WebTorrent](#module-webtorrent) protocol.\n\n```yaml\nstreams:\n webtorrent1: webtorrent:?share=huofssuxaty00izc&pwd=k3l2j9djeg8v8r7e\n```\n\n_Source: [Go2Rtc Webtorrent](https://github.com/seydx/go2rtc#source-webtorrent)_\n", mt = "#### Source: Wyze\n\nThis source allows you to stream from [Wyze](https://wyze.com/) cameras using native P2P protocol without the Wyze app or SDK.\n\n**Important:**\n\n1. **Requires Wyze account**. You need to login once via the WebUI to load your cameras.\n2. **Requires firmware with DTLS**. Only cameras with DTLS-enabled firmware are supported.\n3. Internet access is only needed when loading cameras from your account. After that, all streaming is local P2P.\n4. Connection to the camera is local only (direct P2P to camera IP).\n\n**Features:**\n\n- H.264 and H.265 video codec support\n- AAC, G.711, PCM, and Opus audio codec support\n- Two-way audio (intercom) support\n- Resolution switching (HD/SD)\n\n## Setup\n\n1. Get your API Key from [Wyze Developer Portal](https://support.wyze.com/hc/en-us/articles/16129834216731)\n2. Go to go2rtc WebUI > Add > Wyze\n3. Enter your API ID, API Key, email, and password\n4. Select cameras to add - stream URLs are generated automatically\n\n**Example Config**\n\n```yaml\nwyze:\n user@email.com:\n api_id: 'your-api-id'\n api_key: 'your-api-key'\n password: 'yourpassword' # or MD5 triple-hash with \"md5:\" prefix\n\nstreams:\n wyze_cam: wyze://192.168.1.123?uid=WYZEUID1234567890AB&enr=xxx&mac=AABBCCDDEEFF&model=HL_CAM4&dtls=true\n```\n\n## Stream URL Format\n\nThe stream URL is automatically generated when you add cameras via the WebUI:\n\n```\nwyze://[IP]?uid=[P2P_ID]&enr=[ENR]&mac=[MAC]&model=[MODEL]&subtype=[hd|sd]&dtls=true\n```\n\n| Parameter | Description |\n| --------- | ----------------------------------------------- |\n| `IP` | Camera's local IP address |\n| `uid` | P2P identifier (20 chars) |\n| `enr` | Encryption key for DTLS |\n| `mac` | Device MAC address |\n| `model` | Camera model (e.g., HL_CAM4) |\n| `dtls` | Enable DTLS encryption (default: true) |\n| `subtype` | Camera resolution: `hd` or `sd` (default: `hd`) |\n\n## Configuration\n\n### Resolution\n\nYou can change the camera's resolution using the `subtype` parameter:\n\n```yaml\nstreams:\n wyze_hd: wyze://...&subtype=hd\n wyze_sd: wyze://...&subtype=sd\n```\n\n### Two-Way Audio\n\nTwo-way audio (intercom) is supported automatically. When a consumer sends audio to the stream, it will be transmitted to the camera's speaker.\n", ht = "#### Source: Xiaomi\n\nThis source allows you to view cameras from the [Xiaomi Mi Home](https://home.mi.com/) ecosystem.\n\n**Important:**\n\n1. **Not all cameras are supported**. There are several P2P protocol vendors in the Xiaomi ecosystem.\n Currently, the **CS2** vendor is supported. However, the **TUTK** vendor is not supported.\n2. Each time you connect to the camera, you need internet access to obtain encryption keys.\n3. Connection to the camera is local only.\n\n**Features:**\n\n- Multiple Xiaomi accounts supported\n- Cameras from multiple regions are supported for a single account\n- Two-way audio is supported\n- Cameras with multiple lenses are supported\n\n## Setup\n\n1. Goto go2rtc WebUI > Add > Xiaomi > Login with username and password\n2. Receive verification code by email or phone if required.\n3. Complete the captcha if required.\n4. If everything is OK, your account will be added and you can load cameras from it.\n\n**Example**\n\n```yaml\nxiaomi:\n 1234567890: V1:***\n\nstreams:\n xiaomi1: xiaomi://1234567890:cn@192.168.1.123?did=9876543210&model=isa.camera.hlc7\n```\n\n## Configuration\n\nYou can change camera's quality: `subtype=hd/sd/auto`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&subtype=sd\n```\n\nYou can use second channel for Dual cameras: `channel=1`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&channel=1\n```\n", gt = "# Yandex\n\nSource for receiving stream from new [Yandex IP camera](https://alice.yandex.ru/smart-home/security/ipcamera).\n\n## Get Yandex token\n\n1. Install HomeAssistant integration [YandexStation](https://github.com/AlexxIT/YandexStation).\n2. Copy token from HomeAssistant config folder: `/config/.storage/core.config_entries`, key: `\"x_token\"`.\n\n## Get device ID\n\n1. Open this link in any browser: https://iot.quasar.yandex.ru/m/v3/user/devices\n2. Copy ID of your camera, key: `\"id\"`.\n\n## Config examples\n\n```yaml\nstreams:\n yandex_stream: yandex:?x_token=XXXX&device_id=XXXX\n yandex_snapshot: yandex:?x_token=XXXX&device_id=XXXX&snapshot\n yandex_snapshot_custom_size: yandex:?x_token=XXXX&device_id=XXXX&snapshot=h=540\n```\n\n_Source: [Go2Rtc Yandex](https://github.com/AlexxIT/go2rtc/tree/master/internal/yandex)_\n", _t = [
38
+ render: Ue
39
+ }), Ge = "#### Source: Bubble\n\nOther names: [ESeeCloud](http://www.eseecloud.com/), [dvr163](http://help.dvr163.com/).\n\n- you can skip `username`, `password`, `port`, `ch` and `stream` if they are default\n- setup separate streams for different channels and streams\n\n```yaml\nstreams:\n camera1: bubble://username:password@192.168.1.123:34567/bubble/live?ch=0&stream=0\n```\n\n_Source: [Go2Rtc Bubble](https://github.com/seydx/go2rtc#source-bubble)_\n", Ke = "#### Source: CUI\n\nThis source can be used to stream dynamically generated, go2rtc compatible, URLs. The source is just a placeholder for a `https://` URL.\n\n```yaml\nstreams:\n camera1: cui://192.168.1.123:34567/some-identifier-if-you-want\n```\n\nThe URL will be changed to `https://192.168.1.123:34567/some-identifier-if-you-want` and the response must be like this:\n\n```json\n{\n {\n \"streamUrl\": \"rtsp://192.168.1.1:554/stream\",\n }\n}\n```\n\nGo2rtc will then use the `streamUrl` to stream the video. The `streamUrl` can be any URL that is compatible with go2rtc. The response must be a valid JSON object with the `streamUrl` key.\n", qe = "#### Source: Doorbird\n\n[Doorbird](https://www.doorbird.com/) proprietary camera protocol with **two way audio** support.\n\n```yaml\nstreams:\n video-audio:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n two-way:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n - doorbird://user:pass@123.123.123.123\n mjpeg-video:\n - doorbird://user:pass@123.123.123.123?media=video\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-doorbird)_\n", Je = "#### Source: DVRIP\n\nOther names: DVR-IP, NetSurveillance, Sofia protocol (NETsurveillance ActiveX plugin XMeye SDK).\n\n- you can skip `username`, `password`, `port`, `channel` and `subtype` if they are default\n- setup separate streams for different channels\n- use `subtype=0` for Main stream, and `subtype=1` for Extra1 stream\n- only the TCP protocol is supported\n\n```yaml\nstreams:\n only_stream: dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n only_tts: dvrip://username:password@192.168.1.123:34567?backchannel=1\n two_way_audio:\n - dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n - dvrip://username:password@192.168.1.123:34567?backchannel=1\n```\n\n_Source: [Go2Rtc DVRIP](https://github.com/seydx/go2rtc#source-dvrip)_\n", Ye = "#### Source: Echo\n\nSome sources may have a dynamic link. And you will need to get it using a bash or python script. Your script should echo a link to the source. RTSP, FFmpeg or any of the [supported sources](https://github.com/seydx/go2rtc#module-streams).\n\n**Docker** and **Hass Add-on** users has preinstalled `python3`, `curl`, `jq`.\nCheck examples in [wiki](https://github.com/seydx/go2rtc/wiki/Source-Echo-examples).\n\n```yaml\nstreams:\n apple_hls: echo:python3 hls.py https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\n```\n\n_Source: [Go2Rtc Echo](https://github.com/seydx/go2rtc#source-echo)_\n", Xe = "#### Source: Exec\n\nExec source can run any external application and expect data from it. Two transports are supported - **pipe** and **RTSP**.\n\nIf you want to use **RTSP** transport - the command must contain the `{output}` argument in any place. On launch, it will be replaced by the local address of the RTSP server.\n\n**pipe** reads data from app stdout in different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**. Also pipe can write data to app stdin in two formats: **PCMA** and **PCM/48000**.\n\nThe source can be used with:\n\n- [FFmpeg](https://ffmpeg.org/) - go2rtc ffmpeg source just a shortcut to exec source\n- [FFplay](https://ffmpeg.org/ffplay.html) - play audio on your server\n- [GStreamer](https://gstreamer.freedesktop.org/)\n- [Raspberry Pi Cameras](https://www.raspberrypi.com/documentation/computers/camera_software.html)\n- any your own software\n\n```yaml\nstreams:\n stream: exec:ffmpeg -re -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {output}\n picam_h264: exec:libcamera-vid -t 0 --inline -o -\n picam_mjpeg: exec:libcamera-vid -t 0 --codec mjpeg -o -\n pi5cam_h264: exec:libcamera-vid -t 0 --libav-format h264 -o -\n canon: exec:gphoto2 --capture-movie --stdout#killsignal=2#killtimeout=5\n play_pcma: exec:ffplay -fflags nobuffer -f alaw -ar 8000 -i -#backchannel=1\n play_pcm48k: exec:ffplay -fflags nobuffer -f s16be -ar 48000 -i -#backchannel=1\n```\n\n_Source: [Go2Rtc Exec](https://github.com/seydx/go2rtc#source-exec)_\n", Ze = "#### Source: Expr\n\n[Expr](https://github.com/antonmedv/expr) - expression language and expression evaluation for Go.\n\n- [language definition](https://expr.medv.io/docs/Language-Definition) - takes best from JS, Python, Jinja2 syntax\n- your expression should return a link of any supported source\n- expression supports multiple operation, but:\n - all operations must be separated by a semicolon\n - all operations, except the last one, must declare a new variable (`let s = \"abc\";`)\n - the last operation should return a string\n- go2rtc supports additional functions:\n - `fetch` - JS-like HTTP requests\n - `match` - JS-like RegExp queries\n\n## Examples\n\n**Two way audio for Dahua VTO**\n\n```yaml\nstreams:\n dahua_vto: |\n expr: let host = \"admin:password@192.168.1.123\";\n fetch(\"http://\"+host+\"/cgi-bin/configManager.cgi?action=setConfig&Encode[0].MainFormat[0].Audio.Compression=G.711A&Encode[0].MainFormat[0].Audio.Frequency=8000\").ok\n ? \"rtsp://\"+host+\"/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\" : \"\"\n```\n\n**dom.ru**\n\nYou can get credentials via:\n\n- https://github.com/alexmorbo/domru (file `/share/domru/accounts`)\n- https://github.com/ad/domru\n\n```yaml\nstreams:\n dom_ru: |\n expr: let camera = \"99999999\"; let token = \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"; let operator = 99;\n fetch(\"https://myhome.novotelecom.ru/rest/v1/forpost/cameras/\"+camera+\"/video\", {\n headers: {Authorization: \"Bearer \"+token, Operator: operator}\n }).json().data.URL\n```\n\n**Parse HLS files from Apple**\n\nSame example in two languages - python and expr.\n\n```yaml\nstreams:\n example_python: |\n echo:python -c 'from urllib.request import urlopen; import re\n\n # url1 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8\"\n html1 = urlopen(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").read().decode(\"utf-8\")\n url1 = re.search(r\"https.+?m3u8\", html1)[0]\n\n # url2 = \"gear1/prog_index.m3u8\"\n html2 = urlopen(url1).read().decode(\"utf-8\")\n url2 = re.search(r\"^[a-z0-1/_]+\\.m3u8$\", html2, flags=re.MULTILINE)[0]\n\n # url3 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear1/prog_index.m3u8\"\n url3 = url1[:url1.rindex(\"/\")+1] + url2\n\n print(\"ffmpeg:\" + url3 + \"#video=copy\")'\n\n example_expr: |\n expr:\n\n let html1 = fetch(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").text;\n let url1 = match(html1, \"https.+?m3u8\")[0];\n\n let html2 = fetch(url1).text;\n let url2 = match(html2, \"^[a-z0-1/_]+\\\\.m3u8$\", \"m\")[0];\n\n let url3 = url1[:lastIndexOf(url1, \"/\")+1] + url2;\n\n \"ffmpeg:\" + url3 + \"#video=copy\"\n```\n\n## Comparsion\n\n| expr | python | js |\n| ---------------------------- | -------------------------- | ------------------------------ |\n| let x = 1; | x = 1 | let x = 1 |\n| {a: 1, b: 2} | {\"a\": 1, \"b\": 2} | {a: 1, b: 2} |\n| let r = fetch(url, {method}) | r = request(method, url) | r = await fetch(url, {method}) |\n| r.ok | r.ok | r.ok |\n| r.status | r.status_code | r.status |\n| r.text | r.text | await r.text() |\n| r.json() | r.json() | await r.json() |\n| r.headers | r.headers | r.headers |\n| let m = match(text, \"abc\") | m = re.search(\"abc\", text) | let m = text.match(/abc/) |\n\n_Source: [Go2Rtc Expr](https://github.com/seydx/go2rtc#source-expr)_\n", Qe = "#### Source: FFmpeg\n\nYou can get any stream or file or device via FFmpeg and push it to go2rtc. The app will automatically start FFmpeg with the proper arguments when someone starts watching the stream.\n\n- FFmpeg preistalled for **Docker** and **Hass Add-on** users\n- **Hass Add-on** users can target files from [/media](https://www.home-assistant.io/more-info/local-media/setup-media/) folder\n\nFormat: `ffmpeg:{input}#{param1}#{param2}#{param3}`. Examples:\n\n```yaml\nstreams:\n # [FILE] all tracks will be copied without transcoding codecs\n file1: ffmpeg:/media/BigBuckBunny.mp4\n\n # [FILE] video will be transcoded to H264, audio will be skipped\n file2: ffmpeg:/media/BigBuckBunny.mp4#video=h264\n\n # [FILE] video will be copied, audio will be transcoded to pcmu\n file3: ffmpeg:/media/BigBuckBunny.mp4#video=copy#audio=pcmu\n\n # [HLS] video will be copied, audio will be skipped\n hls: ffmpeg:https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear5/prog_index.m3u8#video=copy\n\n # [MJPEG] video will be transcoded to H264\n mjpeg: ffmpeg:http://185.97.122.128/cgi-bin/faststream.jpg#video=h264\n\n # [RTSP] video with rotation, should be transcoded, so select H264\n rotate: ffmpeg:rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0#video=h264#rotate=90\n```\n\nAll trascoding formats has [built-in templates](https://github.com/seydx/go2rtc/blob/master/internal/ffmpeg/ffmpeg.go): `h264`, `h265`, `opus`, `pcmu`, `pcmu/16000`, `pcmu/48000`, `pcma`, `pcma/16000`, `pcma/48000`, `aac`, `aac/16000`.\n\nBut you can override them via YAML config. You can also add your own formats to config and use them with source params.\n\n```yaml\nffmpeg:\n bin: ffmpeg # path to ffmpeg binary\n h264: '-codec:v libx264 -g:v 30 -preset:v superfast -tune:v zerolatency -profile:v main -level:v 4.1'\n mycodec: '-any args that supported by ffmpeg...'\n myinput: '-fflags nobuffer -flags low_delay -timeout 5000000 -i {input}'\n myraw: '-ss 00:00:20'\n```\n\n- You can use go2rtc stream name as ffmpeg input (ex. `ffmpeg:camera1#video=h264`)\n- You can use `video` and `audio` params multiple times (ex. `#video=copy#audio=copy#audio=pcmu`)\n- You can use `rotate` param with `90`, `180`, `270` or `-90` values, important with transcoding (ex. `#video=h264#rotate=90`)\n- You can use `width` and/or `height` params, important with transcoding (ex. `#video=h264#width=1280`)\n- You can use `drawtext` to add a timestamp (ex. `drawtext=x=2:y=2:fontsize=12:fontcolor=white:box=1:boxcolor=black`)\n - This will greatly increase the CPU of the server, even with hardware acceleration\n- You can use `raw` param for any additional FFmpeg arguments (ex. `#raw=-vf transpose=1`)\n- You can use `input` param to override default input template (ex. `#input=rtsp/udp` will change RTSP transport from TCP to UDP+TCP)\n - You can use raw input value (ex. `#input=-timeout 5000000 -i {input}`)\n - You can add your own input templates\n\nRead more about [hardware acceleration](https://github.com/seydx/go2rtc/wiki/Hardware-acceleration).\n\n**PS.** It is recommended to check the available hardware in the WebUI add page.\n\n<hr>\n\n#### Source: FFmpeg Device\n\nYou can get video from any USB-camera or Webcam as RTSP or WebRTC stream. This is part of FFmpeg integration.\n\n- check available devices in Web interface\n- `video_size` and `framerate` must be supported by your camera!\n- for Linux supported only video for now\n- for macOS you can stream Facetime camera or whole Desktop!\n- for macOS important to set right framerate\n\nFormat: `ffmpeg:device?{input-params}#{param1}#{param2}#{param3}`\n\n```yaml\nstreams:\n linux_usbcam: ffmpeg:device?video=0&video_size=1280x720#video=h264\n windows_webcam: ffmpeg:device?video=0#video=h264\n macos_facetime: ffmpeg:device?video=0&audio=1&video_size=1280x720&framerate=30#video=h264#audio=pcma\n```\n\n**PS.** It is recommended to check the available devices in the WebUI add page.\n\n_Source: [Go2Rtc FFmpeg](https://github.com/seydx/go2rtc#source-ffmpeg) & [Go2Rtc FFmpeg Device](https://github.com/seydx/go2rtc#source-ffmpeg-device)_\n", $e = "#### Source: GoPro\n\nSupported models: HERO9, HERO10, HERO11, HERO12. \nSupported OS: Linux, Mac, Windows, [HassOS](https://www.home-assistant.io/installation/)\n\nThe other camera models have different APIs. I will try to add them in the next versions.\n\n## Config\n\n- USB-connected cameras create a new network interface in the system\n- Linux users do not need to install anything\n- Windows users should install the [network driver](https://community.gopro.com/s/article/GoPro-Webcam)\n- if the camera is detected but the stream does not start - you need to disable firewall\n\n1. Discover camera address: WebUI > Add > GoPro\n2. Add camera to config\n\n```yaml\nstreams:\n hero12: gopro://172.20.100.51\n```\n\n## Useful links\n\n- https://gopro.github.io/OpenGoPro/\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", et = "#### Source: Hass\n\nSupport import camera links from [Home Assistant](https://www.home-assistant.io/) config files:\n\n- [Generic Camera](https://www.home-assistant.io/integrations/generic/), setup via GUI\n- [HomeKit Camera](https://www.home-assistant.io/integrations/homekit_controller/)\n- [ONVIF](https://www.home-assistant.io/integrations/onvif/)\n- [Roborock](https://github.com/humbertogontijo/homeassistant-roborock) vacuums with camera\n\n```yaml\nhass:\n config: '/config' # skip this setting if you Hass Add-on user\n\nstreams:\n generic_camera: hass:Camera1 # Settings > Integrations > Integration Name\n aqara_g3: hass:Camera-Hub-G3-AB12\n```\n\n**WebRTC Cameras**\n\nAny cameras in WebRTC format are supported. But at the moment Home Assistant only supports some [Nest](https://www.home-assistant.io/integrations/nest/) cameras in this fomat.\n\nThe Nest API only allows you to get a link to a stream for 5 minutes. So every 5 minutes the stream will be reconnected.\n\n```yaml\nstreams:\n # link to Home Assistant Supervised\n hass-webrtc1: hass://supervisor?entity_id=camera.nest_doorbell\n # link to external Hass with Long-Lived Access Tokens\n hass-webrtc2: hass://192.168.1.123:8123?entity_id=camera.nest_doorbell&token=eyXYZ...\n```\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", tt = "#### Source: HomeKit\n\n**Important:**\n\n- You can use HomeKit Cameras **without Apple devices** (iPhone, iPad, etc.), it's just a yet another protocol\n- HomeKit device can be paired with only one ecosystem. So, if you have paired it to an iPhone (Apple Home) - you can't pair it with Home Assistant or go2rtc. Or if you have paired it to go2rtc - you can't pair it with iPhone\n- HomeKit device should be in same network with working [mDNS](https://en.wikipedia.org/wiki/Multicast_DNS) between device and go2rtc\n\ngo2rtc support import paired HomeKit devices from [Home Assistant](#source-hass). So you can use HomeKit camera with Hass and go2rtc simultaneously. If you using Hass, I recommend pairing devices with it, it will give you more options.\n\nYou can pair device with go2rtc on the HomeKit page. If you can't see your devices - reload the page. Also try reboot your HomeKit device (power off). If you still can't see it - you have a problems with mDNS.\n\nIf you see a device but it does not have a pair button - it is paired to some ecosystem (Apple Home, Home Assistant etc). You need to delete device from that ecosystem, and it will be available for pairing. If you cannot unpair device, you will have to reset it.\n\n**Important:**\n\n- HomeKit audio uses very non-standard **AAC-ELD** codec with very non-standard params and specification violation\n- Audio can't be played in `VLC` and probably any other player\n- Audio should be transcoded for using with MSE, WebRTC, etc.\n\nRecommended settings for using HomeKit Camera with WebRTC, MSE, MP4, RTSP:\n\n```\nstreams:\n aqara_g3:\n - hass:Camera-Hub-G3-AB12\n - ffmpeg:aqara_g3#audio=aac#audio=opus\n```\n\nRTSP link with \"normal\" audio for any player: `rtsp://192.168.1.123:8554/aqara_g3?video&audio=aac`\n\n**This source is in active development!** Tested only with [Aqara Camera Hub G3](https://www.aqara.com/eu/product/camera-hub-g3) (both EU and CN versions).\n\n_Source: [Go2Rtc HomeKit](https://github.com/seydx/go2rtc#source-homekit)_\n", nt = "#### Source: HTTP\n\nSupport Content-Type:\n\n- **HTTP-FLV** (`video/x-flv`) - same as RTMP, but over HTTP\n- **HTTP-JPEG** (`image/jpeg`) - camera snapshot link, can be converted by go2rtc to MJPEG stream\n- **HTTP-MJPEG** (`multipart/x`) - simple MJPEG stream over HTTP\n- **MPEG-TS** (`video/mpeg`) - legacy [streaming format](https://en.wikipedia.org/wiki/MPEG_transport_stream)\n\nSource also support HTTP and TCP streams with autodetection for different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**.\n\n```yaml\nstreams:\n # [HTTP-FLV] stream in video/x-flv format\n http_flv: http://192.168.1.123:20880/api/camera/stream/780900131155/657617\n\n # [JPEG] snapshots from Dahua camera, will be converted to MJPEG stream\n dahua_snap: http://admin:password@192.168.1.123/cgi-bin/snapshot.cgi?channel=1\n\n # [MJPEG] stream will be proxied without modification\n http_mjpeg: https://mjpeg.sanford.io/count.mjpeg\n\n # [MJPEG or H.264/H.265 bitstream or MPEG-TS]\n tcp_magic: tcp://192.168.1.123:12345\n\n # Add custom header\n custom_header: 'https://mjpeg.sanford.io/count.mjpeg#header=Authorization: Bearer XXX'\n```\n\n**PS.** Dahua camera has bug: if you select MJPEG codec for RTSP second stream - snapshot won't work.\n\n_Source: [Go2Rtc Http](https://github.com/seydx/go2rtc#source-http)_\n", rt = "#### Source: ISAPI\n\nThis source type support only backchannel audio for Hikvision ISAPI protocol. So it should be used as second source in addition to the RTSP protocol.\n\n```yaml\nstreams:\n hikvision1:\n - rtsp://admin:password@192.168.1.123:554/Streaming/Channels/101\n - isapi://admin:password@192.168.1.123:80/\n```\n\n_Source: [Go2Rtc Isapi](https://github.com/seydx/go2rtc#source-isapi)_\n", it = "#### Source: Ivideon\n\nSupport public cameras from service [Ivideon](https://tv.ivideon.com/).\n\n```yaml\nstreams:\n quailcam: ivideon:100-tu5dkUPct39cTp9oNEN2B6/0\n```\n\n_Source: [Go2Rtc Ivideon](https://github.com/seydx/go2rtc#source-ivideon)_\n", at = "#### Source: Kasa\n\n[TP-Link Kasa](https://www.kasasmart.com/) non-standard protocol [more info](https://medium.com/@hu3vjeen/reverse-engineering-tp-link-kc100-bac4641bf1cd).\n\n- `username` - urlsafe email, `alex@gmail.com` -> `alex%40gmail.com`\n- `password` - base64password, `secret1` -> `c2VjcmV0MQ==`\n\n```yaml\nstreams:\n kc401: kasa://username:password@192.168.1.123:19443/https/stream/mixed\n```\n\nTested: KD110, KC200, KC401, KC420WS, EC71.\n\n_Source: [Go2Rtc Kasa](https://github.com/seydx/go2rtc#source-kasa)_\n", ot = "#### Source: Nest\n\nCurrently only WebRTC cameras are supported.\n\nFor simplicity, it is recommended to connect the Nest/WebRTC camera to the [Home Assistant](#source-hass). But if you can somehow get the below parameters - Nest/WebRTC source will work without Hass.\n\n```yaml\nstreams:\n nest-doorbell: nest:?client_id=***&client_secret=***&refresh_token=***&project_id=***&device_id=***\n```\n\n_Source: [Go2Rtc Nest](https://github.com/seydx/go2rtc#source-nest)_\n", st = "#### Source: ONVIF\n\nThe source is not very useful if you already know RTSP and snapshot links for your camera. But it can be useful if you don't.\n\n**WebUI > Add** webpage support ONVIF autodiscovery. Your server must be on the same subnet as the camera. If you use docker, you must use \"network host\".\n\n```yaml\nstreams:\n dahua1: onvif://admin:password@192.168.1.123\n reolink1: onvif://admin:password@192.168.1.123:8000\n tapo1: onvif://admin:password@192.168.1.123:2020\n```\n\n_Source: [Go2Rtc Onvif](https://github.com/seydx/go2rtc#source-onvif)_\n", ct = "#### Source: Ring\n\nThis source type support Ring cameras with [two way audio](#two-way-audio) support. If you have a `refresh_token` and `device_id` - you can use it in `go2rtc.yaml` config file. Otherwise, you can use the go2rtc interface and add your ring account (WebUI > Add > Ring). Once added, it will list all your Ring cameras.\n\n```yaml\nstreams:\n ring: ring:?device_id=XXX&refresh_token=XXX\n ring_snapshot: ring:?device_id=XXX&refresh_token=XXX&snapshot\n```\n\n_Source: [Go2Rtc Ring](https://github.com/seydx/go2rtc#source-ring)_\n", lt = "#### Source: Roborock\n\nThis source type support Roborock vacuums with cameras. Known working models:\n\n- Roborock S6 MaxV - only video (the vacuum has no microphone)\n- Roborock S7 MaxV - video and two way audio\n- Roborock Qrevo MaxV - video and two way audio\n\nSource support load Roborock credentials from Home Assistant [custom integration](https://github.com/humbertogontijo/homeassistant-roborock) or the [core integration](https://www.home-assistant.io/integrations/roborock). Otherwise, you need to log in to your Roborock account (MiHome account is not supported). Go to: go2rtc WebUI > Add webpage. Copy `roborock://...` source for your vacuum and paste it to `go2rtc.yaml` config.\n\nIf you have graphic pin for your vacuum - add it as numeric pin (lines: 123, 456, 789) to the end of the roborock-link.\n\n_Source: [Go2Rtc Roborock](https://github.com/seydx/go2rtc#source-roborock)_\n", ut = "#### Source: RTMP\n\nYou can get stream from RTMP server, for example [Nginx with nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module).\n\n```yaml\nstreams:\n rtmp_stream: rtmp://192.168.1.123/live/camera1\n```\n\n_Source: [Go2Rtc RTMP](https://github.com/seydx/go2rtc#source-rtmp)_\n", dt = "#### Source: RTSP\n\n```yaml\nstreams:\n sonoff_camera: rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0\n dahua_camera:\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=1\n amcrest_doorbell:\n - rtsp://username:password@192.168.1.123:554/cam/realmonitor?channel=1&subtype=0#backchannel=0\n unifi_camera: rtspx://192.168.1.123:7441/fD6ouM72bWoFijxK\n glichy_camera: ffmpeg:rtsp://username:password@192.168.1.123/live/ch00_1\n```\n\n**Recommendations**\n\n- **Amcrest Doorbell** users may want to disable two way audio, because with an active stream you won't have a call button working. You need to add `#backchannel=0` to the end of your RTSP link in YAML config file\n- **Dahua Doorbell** users may want to change backchannel [audio codec](https://github.com/AlexxIT/go2rtc/issues/52)\n- **Reolink** users may want NOT to use RTSP protocol at all, some camera models have a very awful unusable stream implementation\n- **Ubiquiti UniFi** users may want to disable HTTPS verification. Use `rtspx://` prefix instead of `rtsps://`. And don't use `?enableSrtp` [suffix](https://github.com/AlexxIT/go2rtc/issues/81)\n- **TP-Link Tapo** users may skip login and password, because go2rtc support login [without them](https://drmnsamoliu.github.io/video.html)\n- If your camera has two RTSP links - you can add both of them as sources. This is useful when streams has different codecs, as example AAC audio with main stream and PCMU/PCMA audio with second stream\n- If the stream from your camera is glitchy, try using [ffmpeg source](#source-ffmpeg). It will not add CPU load if you won't use transcoding\n- If the stream from your camera is very glitchy, try to use transcoding with [ffmpeg source](#source-ffmpeg)\n\n**Other options**\n\nFormat: `rtsp...#{param1}#{param2}#{param3}`\n\n- Ignore audio - `#media=video` or ignore video - `#media=audio`\n- Ignore two way audio API `#backchannel=0` - important for some glitchy cameras\n- Use WebSocket transport `#transport=ws...`\n\n**RTSP over WebSocket**\n\n```yaml\nstreams:\n # WebSocket with authorization, RTSP - without\n axis-rtsp-ws: rtsp://192.168.1.123:4567/axis-media/media.amp?overview=0&camera=1&resolution=1280x720&videoframeskipmode=empty&Axis-Orig-Sw=true#transport=ws://user:pass@192.168.1.123:4567/rtsp-over-websocket\n # WebSocket without authorization, RTSP - with\n dahua-rtsp-ws: rtsp://user:pass@192.168.1.123/cam/realmonitor?channel=1&subtype=1&proto=Private3#transport=ws://192.168.1.123/rtspoverwebsocket\n```\n\n_Source: [Go2Rtc RTSP](https://github.com/seydx/go2rtc#source-rtsp)_\n", ft = "#### Source: Tapo\n\n[TP-Link Tapo](https://www.tapo.com/) proprietary camera protocol with **two way audio** support.\n\n- stream quality is the same as [RTSP protocol](https://www.tapo.com/en/faq/34/)\n- use the **cloud password**, this is not the RTSP password! you do not need to add a login!\n- you can also use UPPERCASE MD5 hash from your cloud password with `admin` username\n- some new camera firmwares requires SHA256 instead of MD5\n\n```yaml\nstreams:\n # cloud password without username\n camera1: tapo://cloud-password@192.168.1.123\n # admin username and UPPERCASE MD5 cloud-password hash\n camera2: tapo://admin:UPPERCASE-MD5@192.168.1.123\n # admin username and UPPERCASE SHA256 cloud-password hash\n camera3: tapo://admin:UPPERCASE-SHA256@192.168.1.123\n```\n\n```bash\necho -n \"cloud password\" | md5 | awk '{print toupper($0)}'\necho -n \"cloud password\" | shasum -a 256 | awk '{print toupper($0)}'\n```\n\n_Source: [Go2Rtc Tapo](https://github.com/seydx/go2rtc#source-tapo)_\n", pt = "#### Source: Tuya\n\n[Tuya](https://www.tuya.com/) proprietary camera protocol with **two way audio** support. Go2rtc supports `Tuya Smart API` and `Tuya Cloud API`.\n\n**Tuya Smart API (recommended)**:\n\n- Cameras can be discovered through the go2rtc web interface via Tuya Smart account (Add > Tuya > Select region and fill in email and password > Login).\n- **Smart Life accounts are not supported**, you need to create a Tuya Smart account. If the cameras are already added to the Smart Life app, you need to remove them and add them again to the Tuya Smart app.\n\n**Tuya Cloud API**:\n\n- Requires setting up a cloud project in the Tuya Developer Platform.\n- Obtain `device_id`, `client_id`, `client_secret`, and `uid` from [Tuya IoT Platform](https://iot.tuya.com/). [Here's a guide](https://xzetsubou.github.io/hass-localtuya/cloud_api/).\n- Please ensure that you have subscribed to the `IoT Video Live Stream` service (Free Trial) in the Tuya Developer Platform, otherwise the stream will not work (Tuya Developer Platform > Service API > Authorize > IoT Video Live Stream).\n\n**Configuring the stream:**\n\n- Use `resolution` parameter to select the stream (not all cameras support `hd` stream through WebRTC even if the camera has it):\n - `hd` - HD stream (default)\n - `sd` - SD stream\n\n```yaml\nstreams:\n # Tuya Smart API: WebRTC main stream (use Add > Tuya to discover the URL)\n tuya_main:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX\n\n # Tuya Smart API: WebRTC sub stream (use Add > Tuya to discover the URL)\n tuya_sub:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX&resolution=sd\n\n # Tuya Cloud API: WebRTC main stream\n tuya_webrtc:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX\n\n # Tuya Cloud API: WebRTC sub stream\n tuya_webrtc_sd:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX&resolution=sd\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-tuya)_\n", mt = "#### Source: WebRTC\n\nThis source type support four connection formats.\n\n**whep**\n\n[WebRTC/WHEP](https://datatracker.ietf.org/doc/draft-murillo-whep/) - is replaced by [WebRTC/WISH](https://datatracker.ietf.org/doc/charter-ietf-wish/02/) standard for WebRTC video/audio viewers. But it may already be supported in some third-party software. It is supported in go2rtc.\n\n**go2rtc**\n\nThis format is only supported in go2rtc. Unlike WHEP it supports asynchronous WebRTC connection and two way audio.\n\n**openipc**\n\nSupport connection to [OpenIPC](https://openipc.org/) cameras.\n\n**wyze**\n\nSupports connection to [Wyze](https://www.wyze.com/) cameras, using WebRTC protocol. You can use [docker-wyze-bridge](https://github.com/mrlt8/docker-wyze-bridge) project to get connection credentials.\n\n**kinesis**\n\nSupports [Amazon Kinesis Video Streams](https://aws.amazon.com/kinesis/video-streams/), using WebRTC protocol. You need to specify signalling WebSocket URL with all credentials in query params, `client_id` and `ice_servers` list in [JSON format](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer).\n\n```yaml\nstreams:\n webrtc-whep: webrtc:http://192.168.1.123:1984/api/webrtc?src=camera1\n webrtc-go2rtc: webrtc:ws://192.168.1.123:1984/api/ws?src=camera1\n webrtc-openipc: webrtc:ws://192.168.1.123/webrtc_ws#format=openipc#ice_servers=[{\"urls\":\"stun:stun.kinesisvideo.eu-north-1.amazonaws.com:443\"}]\n webrtc-wyze: webrtc:http://192.168.1.123:5000/signaling/camera1?kvs#format=wyze\n webrtc-kinesis: webrtc:wss://...amazonaws.com/?...#format=kinesis#client_id=...#ice_servers=[{...},{...}]\n```\n\n**PS.** For `kinesis` sources you can use [echo](#source-echo) to get connection params using `bash`/`python` or any other script language.\n\n_Source: [Go2Rtc WebRTC](https://github.com/seydx/go2rtc#source-webrtc)_\n", ht = "#### Source: WebTorrent\n\nThis source can get a stream from another go2rtc via [WebTorrent](#module-webtorrent) protocol.\n\n```yaml\nstreams:\n webtorrent1: webtorrent:?share=huofssuxaty00izc&pwd=k3l2j9djeg8v8r7e\n```\n\n_Source: [Go2Rtc Webtorrent](https://github.com/seydx/go2rtc#source-webtorrent)_\n", gt = "#### Source: Wyze\n\nThis source allows you to stream from [Wyze](https://wyze.com/) cameras using native P2P protocol without the Wyze app or SDK.\n\n**Important:**\n\n1. **Requires Wyze account**. You need to login once via the WebUI to load your cameras.\n2. **Requires firmware with DTLS**. Only cameras with DTLS-enabled firmware are supported.\n3. Internet access is only needed when loading cameras from your account. After that, all streaming is local P2P.\n4. Connection to the camera is local only (direct P2P to camera IP).\n\n**Features:**\n\n- H.264 and H.265 video codec support\n- AAC, G.711, PCM, and Opus audio codec support\n- Two-way audio (intercom) support\n- Resolution switching (HD/SD)\n\n## Setup\n\n1. Get your API Key from [Wyze Developer Portal](https://support.wyze.com/hc/en-us/articles/16129834216731)\n2. Go to go2rtc WebUI > Add > Wyze\n3. Enter your API ID, API Key, email, and password\n4. Select cameras to add - stream URLs are generated automatically\n\n**Example Config**\n\n```yaml\nwyze:\n user@email.com:\n api_id: 'your-api-id'\n api_key: 'your-api-key'\n password: 'yourpassword' # or MD5 triple-hash with \"md5:\" prefix\n\nstreams:\n wyze_cam: wyze://192.168.1.123?uid=WYZEUID1234567890AB&enr=xxx&mac=AABBCCDDEEFF&model=HL_CAM4&dtls=true\n```\n\n## Stream URL Format\n\nThe stream URL is automatically generated when you add cameras via the WebUI:\n\n```\nwyze://[IP]?uid=[P2P_ID]&enr=[ENR]&mac=[MAC]&model=[MODEL]&subtype=[hd|sd]&dtls=true\n```\n\n| Parameter | Description |\n| --------- | ----------------------------------------------- |\n| `IP` | Camera's local IP address |\n| `uid` | P2P identifier (20 chars) |\n| `enr` | Encryption key for DTLS |\n| `mac` | Device MAC address |\n| `model` | Camera model (e.g., HL_CAM4) |\n| `dtls` | Enable DTLS encryption (default: true) |\n| `subtype` | Camera resolution: `hd` or `sd` (default: `hd`) |\n\n## Configuration\n\n### Resolution\n\nYou can change the camera's resolution using the `subtype` parameter:\n\n```yaml\nstreams:\n wyze_hd: wyze://...&subtype=hd\n wyze_sd: wyze://...&subtype=sd\n```\n\n### Two-Way Audio\n\nTwo-way audio (intercom) is supported automatically. When a consumer sends audio to the stream, it will be transmitted to the camera's speaker.\n", _t = "#### Source: Xiaomi\n\nThis source allows you to view cameras from the [Xiaomi Mi Home](https://home.mi.com/) ecosystem.\n\n**Important:**\n\n1. **Not all cameras are supported**. There are several P2P protocol vendors in the Xiaomi ecosystem.\n Currently, the **CS2** vendor is supported. However, the **TUTK** vendor is not supported.\n2. Each time you connect to the camera, you need internet access to obtain encryption keys.\n3. Connection to the camera is local only.\n\n**Features:**\n\n- Multiple Xiaomi accounts supported\n- Cameras from multiple regions are supported for a single account\n- Two-way audio is supported\n- Cameras with multiple lenses are supported\n\n## Setup\n\n1. Goto go2rtc WebUI > Add > Xiaomi > Login with username and password\n2. Receive verification code by email or phone if required.\n3. Complete the captcha if required.\n4. If everything is OK, your account will be added and you can load cameras from it.\n\n**Example**\n\n```yaml\nxiaomi:\n 1234567890: V1:***\n\nstreams:\n xiaomi1: xiaomi://1234567890:cn@192.168.1.123?did=9876543210&model=isa.camera.hlc7\n```\n\n## Configuration\n\nYou can change camera's quality: `subtype=hd/sd/auto`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&subtype=sd\n```\n\nYou can use second channel for Dual cameras: `channel=1`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&channel=1\n```\n", vt = "# Yandex\n\nSource for receiving stream from new [Yandex IP camera](https://alice.yandex.ru/smart-home/security/ipcamera).\n\n## Get Yandex token\n\n1. Install HomeAssistant integration [YandexStation](https://github.com/AlexxIT/YandexStation).\n2. Copy token from HomeAssistant config folder: `/config/.storage/core.config_entries`, key: `\"x_token\"`.\n\n## Get device ID\n\n1. Open this link in any browser: https://iot.quasar.yandex.ru/m/v3/user/devices\n2. Copy ID of your camera, key: `\"id\"`.\n\n## Config examples\n\n```yaml\nstreams:\n yandex_stream: yandex:?x_token=XXXX&device_id=XXXX\n yandex_snapshot: yandex:?x_token=XXXX&device_id=XXXX&snapshot\n yandex_snapshot_custom_size: yandex:?x_token=XXXX&device_id=XXXX&snapshot=h=540\n```\n\n_Source: [Go2Rtc Yandex](https://github.com/AlexxIT/go2rtc/tree/master/internal/yandex)_\n", yt = [
40
40
  "nest:",
41
41
  "ring:",
42
42
  "yandex:",
43
43
  "webtorrent:"
44
44
  ];
45
- function vt(e) {
45
+ function bt(e) {
46
46
  let t = e.trim(), n;
47
- for (let e of me) t.startsWith(e) && (!n || e.length > n.length) && (n = e);
47
+ for (let e of he) t.startsWith(e) && (!n || e.length > n.length) && (n = e);
48
48
  return n;
49
49
  }
50
- function yt(e) {
50
+ function xt(e) {
51
51
  let t = e.trim();
52
52
  if (!t) return "";
53
- for (let e of _t) if (t.startsWith(e)) {
53
+ for (let e of yt) if (t.startsWith(e)) {
54
54
  let n = t.slice(e.length);
55
55
  return n && !n.startsWith("?") ? `${e}?${n}` : t;
56
56
  }
57
57
  return t;
58
58
  }
59
- function bt(e) {
59
+ function St(e) {
60
60
  return e.startsWith("cui://") && e.includes("/api/cameras/streams/");
61
61
  }
62
62
  //#endregion
63
63
  //#region src/components/CuiCameraSources/CuiCameraSources.vue?vue&type=script&setup=true&lang.ts
64
- var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-center w-full" }, Ct = { class: "flex gap-2 items-center w-full" }, wt = { class: "text-color text-sm" }, Tt = { class: "flex flex-col gap-6" }, Et = ["for"], Dt = ["for"], Ot = { class: "w-full flex flex-col gap-2" }, kt = { class: "flex items-center gap-4" }, At = { class: "flex flex-col field-switch-gap" }, jt = ["for"], Mt = { class: "flex items-center gap-4" }, Nt = { class: "flex flex-col field-switch-gap" }, Pt = ["for"], Ft = { class: "flex items-center gap-4" }, It = { class: "flex flex-col field-switch-gap" }, Lt = ["for"], Rt = { class: "flex items-center gap-4" }, zt = { class: "flex flex-col field-switch-gap" }, Bt = ["for"], Vt = { class: "flex flex-col gap-6" }, Ht = { class: "flex flex-col field-gap" }, Ut = ["for"], Wt = {
64
+ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-center w-full" }, Tt = { class: "flex gap-2 items-center w-full" }, Et = { class: "text-color text-sm" }, Dt = { class: "flex flex-col gap-6" }, Ot = ["for"], kt = ["for"], At = { class: "w-full flex flex-col gap-2" }, jt = { class: "flex items-center gap-4" }, Mt = { class: "flex flex-col field-switch-gap" }, Nt = ["for"], Pt = { class: "flex items-center gap-4" }, Ft = { class: "flex flex-col field-switch-gap" }, It = ["for"], Lt = { class: "flex items-center gap-4" }, Rt = { class: "flex flex-col field-switch-gap" }, zt = ["for"], Bt = { class: "flex items-center gap-4" }, Vt = { class: "flex flex-col field-switch-gap" }, Ht = ["for"], Ut = { class: "flex flex-col gap-6" }, Wt = { class: "flex flex-col field-gap" }, Gt = ["for"], Kt = {
65
65
  key: 0,
66
66
  class: "w-full flex flex-row gap-2"
67
- }, Gt = "rtsp://user:pass@192.168.1.50:554/stream", Kt = /* @__PURE__ */ O({
67
+ }, qt = "rtsp://user:pass@192.168.1.50:554/stream", Jt = /* @__PURE__ */ O({
68
68
  __name: "CuiCameraSources",
69
69
  props: {
70
70
  sources: {},
@@ -75,35 +75,35 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
75
75
  }
76
76
  },
77
77
  setup(n, { expose: r }) {
78
- let i = new z(), c = n, d = G(), { t: f } = J(), { mutateAsync: h, isPending: b } = i.previewCameraQuery(), S = /* #__PURE__ */ Object.assign({
79
- "../../markdowns/bubble.md": Ue,
80
- "../../markdowns/cui.md": We,
81
- "../../markdowns/doorbird.md": Ge,
82
- "../../markdowns/dvrip.md": Ke,
83
- "../../markdowns/echo.md": qe,
84
- "../../markdowns/exec.md": Je,
85
- "../../markdowns/expr.md": Ye,
86
- "../../markdowns/ffmpeg.md": Xe,
87
- "../../markdowns/gopro.md": Ze,
88
- "../../markdowns/hass.md": Qe,
89
- "../../markdowns/homekit.md": $e,
90
- "../../markdowns/http.md": et,
91
- "../../markdowns/isapi.md": tt,
92
- "../../markdowns/ivideon.md": nt,
93
- "../../markdowns/kasa.md": rt,
94
- "../../markdowns/nest.md": it,
95
- "../../markdowns/onvif.md": at,
96
- "../../markdowns/ring.md": ot,
97
- "../../markdowns/roborock.md": st,
98
- "../../markdowns/rtmp.md": ct,
99
- "../../markdowns/rtsp.md": lt,
100
- "../../markdowns/tapo.md": ut,
101
- "../../markdowns/tuya.md": dt,
102
- "../../markdowns/webrtc.md": ft,
103
- "../../markdowns/webtorrent.md": pt,
104
- "../../markdowns/wyze.md": mt,
105
- "../../markdowns/xiaomi.md": ht,
106
- "../../markdowns/yandex.md": gt
78
+ let i = new R(), c = n, d = U(), { t: f } = q(), { mutateAsync: h, isPending: b } = i.previewCameraQuery(), S = /* #__PURE__ */ Object.assign({
79
+ "../../markdowns/bubble.md": Ge,
80
+ "../../markdowns/cui.md": Ke,
81
+ "../../markdowns/doorbird.md": qe,
82
+ "../../markdowns/dvrip.md": Je,
83
+ "../../markdowns/echo.md": Ye,
84
+ "../../markdowns/exec.md": Xe,
85
+ "../../markdowns/expr.md": Ze,
86
+ "../../markdowns/ffmpeg.md": Qe,
87
+ "../../markdowns/gopro.md": $e,
88
+ "../../markdowns/hass.md": et,
89
+ "../../markdowns/homekit.md": tt,
90
+ "../../markdowns/http.md": nt,
91
+ "../../markdowns/isapi.md": rt,
92
+ "../../markdowns/ivideon.md": it,
93
+ "../../markdowns/kasa.md": at,
94
+ "../../markdowns/nest.md": ot,
95
+ "../../markdowns/onvif.md": st,
96
+ "../../markdowns/ring.md": ct,
97
+ "../../markdowns/roborock.md": lt,
98
+ "../../markdowns/rtmp.md": ut,
99
+ "../../markdowns/rtsp.md": dt,
100
+ "../../markdowns/tapo.md": ft,
101
+ "../../markdowns/tuya.md": pt,
102
+ "../../markdowns/webrtc.md": mt,
103
+ "../../markdowns/webtorrent.md": ht,
104
+ "../../markdowns/wyze.md": gt,
105
+ "../../markdowns/xiaomi.md": _t,
106
+ "../../markdowns/yandex.md": vt
107
107
  }), w = k([
108
108
  "high-resolution",
109
109
  "mid-resolution",
@@ -111,10 +111,10 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
111
111
  "snapshot"
112
112
  ]), O = k(c.sources.map((e, t) => t)), j = v(() => c.isLoading || b.value);
113
113
  function M(e) {
114
- return e.urls.some(bt);
114
+ return e.urls.some(St);
115
115
  }
116
116
  function P(e) {
117
- let t = vt(e);
117
+ let t = bt(e);
118
118
  if (!t) return;
119
119
  let n = t.replace(/[:/]+$/, "");
120
120
  return S[`../../markdowns/${n}.md`];
@@ -122,21 +122,21 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
122
122
  function F(e) {
123
123
  return !!P(e);
124
124
  }
125
- function ne(e) {
125
+ function re(e) {
126
126
  c.sources[e].urls.push("");
127
127
  }
128
- function I(e, t) {
128
+ function L(e, t) {
129
129
  c.sources[e].urls.splice(t, 1);
130
130
  }
131
131
  function ie(e, t, n) {
132
132
  c.sources[e].urls[t] = n;
133
133
  }
134
- function R(e, t) {
134
+ function z(e, t) {
135
135
  e.role = t, t === "snapshot" && (e.useForSnapshot = !1, e.hotMode = !1, e.preload = !1);
136
136
  }
137
- function B() {
137
+ function ae() {
138
138
  c.sources.push({
139
- _id: q(8),
139
+ _id: G(8),
140
140
  name: "",
141
141
  role: null,
142
142
  urls: [""],
@@ -146,10 +146,10 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
146
146
  muted: !1
147
147
  }), O.value = [c.sources.length];
148
148
  }
149
- function U(e) {
149
+ function oe(e) {
150
150
  c.sources.splice(e, 1);
151
151
  }
152
- function W(e) {
152
+ function H(e) {
153
153
  let t = P(e);
154
154
  t && d.openTextDialog({ data: {
155
155
  title: f("components.dialog.title.information"),
@@ -158,8 +158,8 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
158
158
  markdown: !0
159
159
  } });
160
160
  }
161
- async function ae(e) {
162
- let t = yt(e);
161
+ async function se(e) {
162
+ let t = xt(e);
163
163
  if (t) try {
164
164
  let e = await h({ cameraData: { url: t } });
165
165
  d.openImageDialog({ data: {
@@ -169,14 +169,14 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
169
169
  } });
170
170
  } catch {}
171
171
  }
172
- return r({ newSource: B }), (r, i) => {
173
- let c = De, d = xe, f = be, h = Te, v = Y, b = V, S = te, k = Se, P = N, z = Ae, B = He, oe = re, se = Ce, G = we, K = Ee, q = ee;
174
- return o(), x("div", xt, [A(K, {
172
+ return r({ newSource: ae }), (r, i) => {
173
+ let c = ke, d = Ce, f = Se, h = De, v = J, b = B, S = te, k = we, P = N, R = Me, ae = We, U = ne, W = Te, ce = Ee, le = Oe, G = ee;
174
+ return o(), x("div", Ct, [A(le, {
175
175
  value: _(O),
176
176
  "onUpdate:value": i[0] ||= (e) => g(O) ? O.value = e : null,
177
177
  multiple: ""
178
178
  }, {
179
- default: y(() => [(o(!0), x(C, null, a(n.sources, (i, g) => (o(), p(G, {
179
+ default: y(() => [(o(!0), x(C, null, a(n.sources, (i, g) => (o(), p(ce, {
180
180
  key: i._id,
181
181
  value: g,
182
182
  class: u({ "border-b-0": g === n.sources.length - 1 })
@@ -186,7 +186,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
186
186
  "px-0": g !== 0,
187
187
  "pb-5": g === n.sources.length - 1
188
188
  }) }, {
189
- default: y(() => [T("div", St, [T("div", Ct, [T("span", wt, s(r.$t("components.dialog.components.new_camera.source") + ": "), 1), A(c, {
189
+ default: y(() => [T("div", wt, [T("div", Tt, [T("span", Et, s(r.$t("components.dialog.components.new_camera.source") + ": "), 1), A(c, {
190
190
  class: "text-color text-xs border-[1px] bg-primary-500/20 border-primary-500/30 py-2 px-3 rounded-full overflow-hidden",
191
191
  label: i.name === "" ? r.$t("components.dialog.components.new_camera.unknown") : i.name
192
192
  }, null, 8, ["label"])]), n.allowAddRemoveSources && n.sources.length > 1 ? (o(), p(f, {
@@ -196,7 +196,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
196
196
  severity: "danger",
197
197
  class: "cui-icon-md ml-auto mr-2",
198
198
  loading: _(j),
199
- onClick: (e) => U(g)
199
+ onClick: (e) => oe(g)
200
200
  }, {
201
201
  icon: y(() => [A(d, {
202
202
  width: "100%",
@@ -205,12 +205,12 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
205
205
  _: 1
206
206
  }, 8, ["loading", "onClick"])) : m("", !0)])]),
207
207
  _: 2
208
- }, 1032, ["class"]), A(se, { pt: { content: { class: {
208
+ }, 1032, ["class"]), A(W, { pt: { content: { class: {
209
209
  "px-0": !0,
210
210
  "pb-5": g === n.sources.length - 1
211
211
  } } } }, {
212
- default: y(() => [T("div", Tt, [
213
- A(_(L), {
212
+ default: y(() => [T("div", Dt, [
213
+ A(_(I), {
214
214
  modelValue: i.name,
215
215
  "onUpdate:modelValue": (e) => i.name = e,
216
216
  modelModifiers: { trim: !0 },
@@ -222,7 +222,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
222
222
  T("label", {
223
223
  for: `sources[${g}].name`,
224
224
  class: "cui-label"
225
- }, s(r.$t("components.form.label.source_name")), 9, Et),
225
+ }, s(r.$t("components.form.label.source_name")), 9, Ot),
226
226
  A(b, null, {
227
227
  default: y(() => [A(v, l({ ref_for: !0 }, t, {
228
228
  invalid: n.length > 0,
@@ -232,7 +232,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
232
232
  _: 2
233
233
  }, 1024),
234
234
  A(e, { name: "fade" }, {
235
- default: y(() => [A(_(H), {
235
+ default: y(() => [A(_(V), {
236
236
  name: `sources[${g}].name`,
237
237
  class: "cui-input-error"
238
238
  }, null, 8, ["name"])]),
@@ -255,7 +255,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
255
255
  "onUpdate:modelValue",
256
256
  "name"
257
257
  ]),
258
- A(_(L), {
258
+ A(_(I), {
259
259
  "model-value": i.role,
260
260
  name: `sources[${g}].role`,
261
261
  as: "div",
@@ -265,14 +265,14 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
265
265
  T("label", {
266
266
  for: `sources[${g}].role`,
267
267
  class: "cui-label"
268
- }, s(r.$t("components.form.label.source_role")), 9, Dt),
268
+ }, s(r.$t("components.form.label.source_role")), 9, kt),
269
269
  A(b, null, {
270
270
  default: y(() => [A(k, {
271
271
  "model-value": i.role,
272
272
  options: _(w).filter((e) => !n.sources.some((t) => t.role === e && t._id !== i._id)),
273
273
  invalid: t.length > 0,
274
274
  loading: _(j),
275
- onValueChange: (e) => R(i, e)
275
+ onValueChange: (e) => z(i, e)
276
276
  }, null, 8, [
277
277
  "model-value",
278
278
  "options",
@@ -283,7 +283,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
283
283
  _: 2
284
284
  }, 1024),
285
285
  A(e, { name: "fade" }, {
286
- default: y(() => [A(_(H), {
286
+ default: y(() => [A(_(V), {
287
287
  name: `sources[${g}].role`,
288
288
  class: "cui-input-error"
289
289
  }, null, 8, ["name"])]),
@@ -302,8 +302,8 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
302
302
  ]),
303
303
  _: 2
304
304
  }, 1032, ["model-value", "name"]),
305
- T("div", Ot, [
306
- i.role !== "snapshot" && n.sources.length > 1 ? (o(), p(_(L), {
305
+ T("div", At, [
306
+ i.role !== "snapshot" && n.sources.length > 1 ? (o(), p(_(I), {
307
307
  key: 0,
308
308
  "model-value": i.useForSnapshot,
309
309
  value: !0,
@@ -313,11 +313,11 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
313
313
  as: "div",
314
314
  class: "flex flex-col field-gap cui-toggle-switch"
315
315
  }, {
316
- default: y(({ field: t, errors: a }) => [T("div", kt, [T("div", At, [
316
+ default: y(({ field: t, errors: a }) => [T("div", jt, [T("div", Mt, [
317
317
  T("label", {
318
318
  for: `sources[${g}].useForSnapshot`,
319
319
  class: "cui-label-switch"
320
- }, s(r.$t("components.form.label.use_for_snapshot")), 9, jt),
320
+ }, s(r.$t("components.form.label.use_for_snapshot")), 9, Nt),
321
321
  A(S, {
322
322
  severity: "secondary",
323
323
  variant: "simple",
@@ -328,7 +328,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
328
328
  _: 1
329
329
  }),
330
330
  A(e, { name: "fade" }, {
331
- default: y(() => [A(_(H), {
331
+ default: y(() => [A(_(V), {
332
332
  name: `sources[${g}].useForSnapshot`,
333
333
  class: "cui-input-switch-error"
334
334
  }, null, 8, ["name"])]),
@@ -349,7 +349,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
349
349
  ])])]),
350
350
  _: 2
351
351
  }, 1032, ["model-value", "name"])) : m("", !0),
352
- i.role === "snapshot" ? m("", !0) : (o(), p(_(L), {
352
+ i.role === "snapshot" ? m("", !0) : (o(), p(_(I), {
353
353
  key: 1,
354
354
  "model-value": i.hotMode,
355
355
  value: !0,
@@ -359,11 +359,11 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
359
359
  as: "div",
360
360
  class: "flex flex-col field-gap cui-toggle-switch"
361
361
  }, {
362
- default: y(({ field: t, errors: n }) => [T("div", Mt, [T("div", Nt, [
362
+ default: y(({ field: t, errors: n }) => [T("div", Pt, [T("div", Ft, [
363
363
  T("label", {
364
364
  for: `sources[${g}].hotMode`,
365
365
  class: "cui-label-switch"
366
- }, s(r.$t("components.form.label.hot_mode")), 9, Pt),
366
+ }, s(r.$t("components.form.label.hot_mode")), 9, It),
367
367
  A(S, {
368
368
  severity: "secondary",
369
369
  variant: "simple",
@@ -374,7 +374,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
374
374
  _: 1
375
375
  }),
376
376
  A(e, { name: "fade" }, {
377
- default: y(() => [A(_(H), {
377
+ default: y(() => [A(_(V), {
378
378
  name: `sources[${g}].hotMode`,
379
379
  class: "cui-input-switch-error"
380
380
  }, null, 8, ["name"])]),
@@ -393,7 +393,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
393
393
  ])])]),
394
394
  _: 2
395
395
  }, 1032, ["model-value", "name"])),
396
- i.role === "snapshot" ? m("", !0) : (o(), p(_(L), {
396
+ i.role === "snapshot" ? m("", !0) : (o(), p(_(I), {
397
397
  key: 2,
398
398
  "model-value": i.preload,
399
399
  value: !0,
@@ -403,11 +403,11 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
403
403
  as: "div",
404
404
  class: "flex flex-col field-gap cui-toggle-switch"
405
405
  }, {
406
- default: y(({ field: t, errors: n }) => [T("div", Ft, [T("div", It, [
406
+ default: y(({ field: t, errors: n }) => [T("div", Lt, [T("div", Rt, [
407
407
  T("label", {
408
408
  for: `sources[${g}].preload`,
409
409
  class: "cui-label-switch"
410
- }, s(r.$t("components.form.label.preload")), 9, Lt),
410
+ }, s(r.$t("components.form.label.preload")), 9, zt),
411
411
  A(S, {
412
412
  severity: "secondary",
413
413
  variant: "simple",
@@ -418,7 +418,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
418
418
  _: 1
419
419
  }),
420
420
  A(e, { name: "fade" }, {
421
- default: y(() => [A(_(H), {
421
+ default: y(() => [A(_(V), {
422
422
  name: `sources[${g}].preload`,
423
423
  class: "cui-input-switch-error"
424
424
  }, null, 8, ["name"])]),
@@ -437,7 +437,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
437
437
  ])])]),
438
438
  _: 2
439
439
  }, 1032, ["model-value", "name"])),
440
- i.role === "snapshot" ? m("", !0) : (o(), p(_(L), {
440
+ i.role === "snapshot" ? m("", !0) : (o(), p(_(I), {
441
441
  key: 3,
442
442
  "model-value": i.muted,
443
443
  value: !0,
@@ -447,11 +447,11 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
447
447
  as: "div",
448
448
  class: "flex flex-col field-gap cui-toggle-switch"
449
449
  }, {
450
- default: y(({ field: t, errors: n }) => [T("div", Rt, [T("div", zt, [
450
+ default: y(({ field: t, errors: n }) => [T("div", Bt, [T("div", Vt, [
451
451
  T("label", {
452
452
  for: `sources[${g}].muted`,
453
453
  class: "cui-label-switch"
454
- }, s(r.$t("components.form.label.muted")), 9, Bt),
454
+ }, s(r.$t("components.form.label.muted")), 9, Ht),
455
455
  A(S, {
456
456
  severity: "secondary",
457
457
  variant: "simple",
@@ -462,7 +462,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
462
462
  _: 1
463
463
  }),
464
464
  A(e, { name: "fade" }, {
465
- default: y(() => [A(_(H), {
465
+ default: y(() => [A(_(V), {
466
466
  name: `sources[${g}].muted`,
467
467
  class: "cui-input-switch-error"
468
468
  }, null, 8, ["name"])]),
@@ -482,11 +482,11 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
482
482
  _: 2
483
483
  }, 1032, ["model-value", "name"]))
484
484
  ]),
485
- T("div", Vt, [
486
- T("div", Ht, [T("label", {
485
+ T("div", Ut, [
486
+ T("div", Wt, [T("label", {
487
487
  for: `sources[${g}].urls[]`,
488
488
  class: "cui-label"
489
- }, s(r.$t("components.form.label.sources")), 9, Ut), A(S, {
489
+ }, s(r.$t("components.form.label.sources")), 9, Gt), A(S, {
490
490
  severity: "secondary",
491
491
  variant: "simple",
492
492
  size: "small",
@@ -495,7 +495,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
495
495
  default: y(() => [D(s(M(i) ? r.$t("views.devices.managed_source_hint") : r.$t("components.form.hint.source_urls")), 1)]),
496
496
  _: 2
497
497
  }, 1024)]),
498
- (o(!0), x(C, null, a(i.urls, (n, a) => (o(), x(C, { key: a }, [_(bt)(n) ? (o(), x("div", Wt, [A(b, null, {
498
+ (o(!0), x(C, null, a(i.urls, (n, a) => (o(), x(C, { key: a }, [_(St)(n) ? (o(), x("div", Kt, [A(b, null, {
499
499
  default: y(() => [A(v, {
500
500
  "model-value": n,
501
501
  readonly: "",
@@ -503,7 +503,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
503
503
  type: "text"
504
504
  }, null, 8, ["model-value", "loading"])]),
505
505
  _: 2
506
- }, 1024)])) : (o(), p(_(L), {
506
+ }, 1024)])) : (o(), p(_(I), {
507
507
  key: 1,
508
508
  "model-value": n,
509
509
  name: `sources[${g}].urls[${a}]`,
@@ -517,14 +517,14 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
517
517
  invalid: c.length > 0,
518
518
  loading: _(j),
519
519
  type: "text",
520
- placeholder: Gt,
520
+ placeholder: qt,
521
521
  "onUpdate:modelValue": (e) => ie(g, a, e ?? "")
522
522
  }, null, 8, [
523
523
  "model-value",
524
524
  "invalid",
525
525
  "loading",
526
526
  "onUpdate:modelValue"
527
- ]), A(oe, null, {
527
+ ]), A(U, null, {
528
528
  default: y(() => [
529
529
  E((o(), p(f, {
530
530
  text: "",
@@ -532,15 +532,15 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
532
532
  severity: "secondary",
533
533
  disabled: _(j) || !F(n),
534
534
  class: "border-right-color",
535
- onClick: (e) => W(n)
535
+ onClick: (e) => H(n)
536
536
  }, {
537
- icon: y(() => [A(z, {
537
+ icon: y(() => [A(R, {
538
538
  width: "100%",
539
539
  height: "100%"
540
540
  })]),
541
541
  _: 1
542
542
  }, 8, ["disabled", "onClick"])), [[
543
- q,
543
+ G,
544
544
  { value: r.$t("components.dialog.components.new_camera.protocol_info") },
545
545
  void 0,
546
546
  { top: !0 }
@@ -549,17 +549,17 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
549
549
  text: "",
550
550
  rounded: "",
551
551
  severity: "secondary",
552
- disabled: _(j) || !_(vt)(n),
552
+ disabled: _(j) || !_(bt)(n),
553
553
  class: "border-right-color",
554
- onClick: (e) => ae(n)
554
+ onClick: (e) => se(n)
555
555
  }, {
556
- icon: y(() => [A(B, {
556
+ icon: y(() => [A(ae, {
557
557
  width: "100%",
558
558
  height: "100%"
559
559
  })]),
560
560
  _: 1
561
561
  }, 8, ["disabled", "onClick"])), [[
562
- q,
562
+ G,
563
563
  { value: r.$t("components.dialog.components.new_camera.test_source") },
564
564
  void 0,
565
565
  { top: !0 }
@@ -570,7 +570,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
570
570
  rounded: "",
571
571
  severity: "danger",
572
572
  disabled: _(j),
573
- onClick: t((e) => I(g, a), ["prevent"])
573
+ onClick: t((e) => L(g, a), ["prevent"])
574
574
  }, {
575
575
  icon: y(() => [A(d, {
576
576
  width: "100%",
@@ -584,7 +584,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
584
584
  _: 2
585
585
  }, 1024),
586
586
  A(e, { name: "fade" }, {
587
- default: y(() => [A(_(H), {
587
+ default: y(() => [A(_(V), {
588
588
  name: `sources[${g}].urls[${a}]`,
589
589
  class: "cui-input-error"
590
590
  }, null, 8, ["name"])]),
@@ -596,7 +596,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
596
596
  size: "small",
597
597
  class: "cui-input-hint"
598
598
  }, {
599
- default: y(() => [D(s(_(vt)(n) ? r.$t("components.form.hint.source_detected_protocol", { protocol: _(vt)(n) }) : r.$t("components.form.hint.source_url")), 1)]),
599
+ default: y(() => [D(s(_(bt)(n) ? r.$t("components.form.hint.source_detected_protocol", { protocol: _(bt)(n) }) : r.$t("components.form.hint.source_url")), 1)]),
600
600
  _: 2
601
601
  }, 1024)
602
602
  ]),
@@ -607,7 +607,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
607
607
  loading: _(j),
608
608
  label: r.$t("components.form.button.add_source"),
609
609
  class: "ml-auto cui-button-medium",
610
- onClick: (e) => ne(g)
610
+ onClick: (e) => re(g)
611
611
  }, null, 8, [
612
612
  "loading",
613
613
  "label",
@@ -623,16 +623,16 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
623
623
  }, 8, ["value"])]);
624
624
  };
625
625
  }
626
- }), qt = { class: "flex flex-col gap-2 w-full" }, Jt = {
626
+ }), Yt = { class: "flex flex-col gap-2 w-full" }, Xt = {
627
627
  for: "roomName",
628
628
  class: "cui-label"
629
- }, Yt = /* @__PURE__ */ O({
629
+ }, Zt = /* @__PURE__ */ O({
630
630
  __name: "CreateRoom",
631
631
  setup(e, { expose: t }) {
632
632
  let n = k("");
633
633
  return t({ onConfirm: async () => n.value.trim() || null }), (e, t) => {
634
- let r = Y;
635
- return o(), x("div", qt, [T("label", Jt, s(e.$t("components.form.label.name")), 1), A(r, {
634
+ let r = J;
635
+ return o(), x("div", Yt, [T("label", Xt, s(e.$t("components.form.label.name")), 1), A(r, {
636
636
  id: "roomName",
637
637
  modelValue: _(n),
638
638
  "onUpdate:modelValue": t[0] ||= (e) => g(n) ? n.value = e : null,
@@ -645,7 +645,7 @@ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-cente
645
645
  });
646
646
  //#endregion
647
647
  //#region src/components/CuiCameraDetailsFields/rooms.ts
648
- function Xt(e, t) {
648
+ function Qt(e, t) {
649
649
  let n = e?.rooms ?? [], r = [...e?.levels ?? []].sort((e, t) => e.order - t.order), i = (e) => ({
650
650
  label: e.name === "Default" ? t("components.form.label.room_default") : e.name,
651
651
  value: e.id
@@ -667,46 +667,46 @@ function Xt(e, t) {
667
667
  }
668
668
  //#endregion
669
669
  //#region src/components/CuiCameraDetailsFields/CuiCameraDetailsFields.vue?vue&type=script&setup=true&lang.ts
670
- var Zt = { class: "flex flex-col gap-6" }, Qt = {
670
+ var $t = { class: "flex flex-col gap-6" }, en = {
671
671
  for: "name",
672
672
  class: "cui-label"
673
- }, $t = { class: "flex flex-col field-gap" }, en = {
673
+ }, tn = { class: "flex flex-col field-gap" }, nn = {
674
674
  for: "type",
675
675
  class: "cui-label"
676
- }, tn = { class: "flex flex-col field-gap" }, nn = {
676
+ }, rn = { class: "flex flex-col field-gap" }, an = {
677
677
  for: "room",
678
678
  class: "cui-label"
679
- }, rn = { class: "flex gap-2" }, an = { class: "text-color font-normal" }, on = { class: "flex flex-col gap-6" }, sn = {
679
+ }, on = { class: "flex gap-2" }, sn = { class: "text-color font-normal" }, cn = { class: "flex flex-col gap-6" }, ln = {
680
680
  for: "info.manufacturer",
681
681
  class: "cui-label"
682
- }, cn = {
682
+ }, un = {
683
683
  for: "info.model",
684
684
  class: "cui-label"
685
- }, ln = {
685
+ }, dn = {
686
686
  for: "info.hardware",
687
687
  class: "cui-label"
688
- }, un = {
688
+ }, fn = {
689
689
  for: "info.serialNumber",
690
690
  class: "cui-label"
691
- }, dn = {
691
+ }, pn = {
692
692
  for: "info.firmwareVersion",
693
693
  class: "cui-label"
694
- }, fn = {
694
+ }, mn = {
695
695
  for: "info.supportUrl",
696
696
  class: "cui-label"
697
- }, pn = /* @__PURE__ */ O({
697
+ }, hn = /* @__PURE__ */ O({
698
698
  __name: "CuiCameraDetailsFields",
699
699
  props: {
700
700
  form: {},
701
701
  isLoading: { type: Boolean }
702
702
  },
703
703
  setup(t) {
704
- let n = new ze(), r = t, i = G(), { t: a } = J(), { data: u, isBusy: d } = n.getRoomsQuery(), { mutateAsync: f } = n.createRoomMutation(), h = k(["camera", "doorbell"]), g = v(() => (u.value?.levels.length ?? 0) > 0), b = v(() => Xt(u.value, a));
704
+ let n = new Ve(), r = t, i = U(), { t: a } = q(), { data: u, isBusy: d } = n.getRoomsQuery(), { mutateAsync: f } = n.createRoomMutation(), h = k(["camera", "doorbell"]), g = v(() => (u.value?.levels.length ?? 0) > 0), b = v(() => Qt(u.value, a));
705
705
  function S(e) {
706
706
  r.form.roomId = e;
707
707
  }
708
708
  function C() {
709
- i.openComponentDialog(Yt, {
709
+ i.openComponentDialog(Zt, {
710
710
  data: {
711
711
  title: a("components.dialog.title.create_room"),
712
712
  confirmText: a("components.form.button.add"),
@@ -724,9 +724,9 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
724
724
  });
725
725
  }
726
726
  return (n, r) => {
727
- let i = Y, a = V, u = te, f = Se, v = Pe, w = be, O = Te, k = Ce, j = we, M = Ee, N = ee;
728
- return o(), x("div", Zt, [
729
- A(_(L), {
727
+ let i = J, a = B, u = te, f = we, v = Ie, w = Se, O = De, k = Te, j = Ee, M = Oe, N = ee;
728
+ return o(), x("div", $t, [
729
+ A(_(I), {
730
730
  modelValue: t.form.name,
731
731
  "onUpdate:modelValue": r[0] ||= (e) => t.form.name = e,
732
732
  modelModifiers: { trim: !0 },
@@ -735,7 +735,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
735
735
  class: "flex flex-col field-gap"
736
736
  }, {
737
737
  default: y(({ field: r, errors: c }) => [
738
- T("label", Qt, s(n.$t("components.form.label.name")), 1),
738
+ T("label", en, s(n.$t("components.form.label.name")), 1),
739
739
  A(a, null, {
740
740
  default: y(() => [A(i, l(r, {
741
741
  invalid: c.length > 0,
@@ -745,7 +745,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
745
745
  _: 2
746
746
  }, 1024),
747
747
  A(e, { name: "fade" }, {
748
- default: y(() => [A(_(H), {
748
+ default: y(() => [A(_(V), {
749
749
  name: "name",
750
750
  class: "cui-input-error"
751
751
  })]),
@@ -764,7 +764,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
764
764
  ]),
765
765
  _: 1
766
766
  }, 8, ["modelValue"]),
767
- T("div", $t, [T("label", en, s(n.$t("components.form.label.type")), 1), A(a, null, {
767
+ T("div", tn, [T("label", nn, s(n.$t("components.form.label.type")), 1), A(a, null, {
768
768
  default: y(() => [A(f, {
769
769
  "model-value": t.form.type,
770
770
  options: _(h),
@@ -778,9 +778,9 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
778
778
  ])]),
779
779
  _: 1
780
780
  })]),
781
- T("div", tn, [
782
- T("label", nn, s(n.$t("components.form.label.room")), 1),
783
- T("div", rn, [A(f, {
781
+ T("div", rn, [
782
+ T("label", an, s(n.$t("components.form.label.room")), 1),
783
+ T("div", on, [A(f, {
784
784
  "model-value": t.form.roomId,
785
785
  options: _(b),
786
786
  "option-label": "label",
@@ -824,11 +824,11 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
824
824
  A(M, null, {
825
825
  default: y(() => [A(j, { value: "branding" }, {
826
826
  default: y(() => [A(O, { class: "px-0 pt-0" }, {
827
- default: y(() => [T("span", an, s(n.$t("components.camera_options.branding")), 1)]),
827
+ default: y(() => [T("span", sn, s(n.$t("components.camera_options.branding")), 1)]),
828
828
  _: 1
829
829
  }), A(k, { pt: { content: { class: "px-0" } } }, {
830
- default: y(() => [T("div", on, [
831
- A(_(L), {
830
+ default: y(() => [T("div", cn, [
831
+ A(_(I), {
832
832
  modelValue: t.form.info.manufacturer,
833
833
  "onUpdate:modelValue": r[3] ||= (e) => t.form.info.manufacturer = e,
834
834
  modelModifiers: { trim: !0 },
@@ -837,7 +837,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
837
837
  class: "flex flex-col field-gap"
838
838
  }, {
839
839
  default: y(({ field: r, errors: o }) => [
840
- T("label", sn, s(n.$t("components.form.label.manufacturer")), 1),
840
+ T("label", ln, s(n.$t("components.form.label.manufacturer")), 1),
841
841
  A(a, null, {
842
842
  default: y(() => [A(i, l(r, {
843
843
  invalid: o.length > 0,
@@ -847,7 +847,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
847
847
  _: 2
848
848
  }, 1024),
849
849
  A(e, { name: "fade" }, {
850
- default: y(() => [A(_(H), {
850
+ default: y(() => [A(_(V), {
851
851
  name: "info.manufacturer",
852
852
  class: "cui-input-error"
853
853
  })]),
@@ -856,7 +856,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
856
856
  ]),
857
857
  _: 1
858
858
  }, 8, ["modelValue"]),
859
- A(_(L), {
859
+ A(_(I), {
860
860
  modelValue: t.form.info.model,
861
861
  "onUpdate:modelValue": r[4] ||= (e) => t.form.info.model = e,
862
862
  modelModifiers: { trim: !0 },
@@ -865,7 +865,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
865
865
  class: "flex flex-col field-gap"
866
866
  }, {
867
867
  default: y(({ field: r, errors: o }) => [
868
- T("label", cn, s(n.$t("components.form.label.model")), 1),
868
+ T("label", un, s(n.$t("components.form.label.model")), 1),
869
869
  A(a, null, {
870
870
  default: y(() => [A(i, l(r, {
871
871
  invalid: o.length > 0,
@@ -875,7 +875,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
875
875
  _: 2
876
876
  }, 1024),
877
877
  A(e, { name: "fade" }, {
878
- default: y(() => [A(_(H), {
878
+ default: y(() => [A(_(V), {
879
879
  name: "info.model",
880
880
  class: "cui-input-error"
881
881
  })]),
@@ -884,7 +884,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
884
884
  ]),
885
885
  _: 1
886
886
  }, 8, ["modelValue"]),
887
- A(_(L), {
887
+ A(_(I), {
888
888
  modelValue: t.form.info.hardware,
889
889
  "onUpdate:modelValue": r[5] ||= (e) => t.form.info.hardware = e,
890
890
  modelModifiers: { trim: !0 },
@@ -893,7 +893,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
893
893
  class: "flex flex-col field-gap"
894
894
  }, {
895
895
  default: y(({ field: r, errors: o }) => [
896
- T("label", ln, s(n.$t("components.form.label.hardware_version")), 1),
896
+ T("label", dn, s(n.$t("components.form.label.hardware_version")), 1),
897
897
  A(a, null, {
898
898
  default: y(() => [A(i, l(r, {
899
899
  invalid: o.length > 0,
@@ -903,7 +903,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
903
903
  _: 2
904
904
  }, 1024),
905
905
  A(e, { name: "fade" }, {
906
- default: y(() => [A(_(H), {
906
+ default: y(() => [A(_(V), {
907
907
  name: "info.hardware",
908
908
  class: "cui-input-error"
909
909
  })]),
@@ -912,7 +912,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
912
912
  ]),
913
913
  _: 1
914
914
  }, 8, ["modelValue"]),
915
- A(_(L), {
915
+ A(_(I), {
916
916
  modelValue: t.form.info.serialNumber,
917
917
  "onUpdate:modelValue": r[6] ||= (e) => t.form.info.serialNumber = e,
918
918
  modelModifiers: { trim: !0 },
@@ -921,7 +921,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
921
921
  class: "flex flex-col field-gap"
922
922
  }, {
923
923
  default: y(({ field: r, errors: o }) => [
924
- T("label", un, s(n.$t("components.form.label.serial_number")), 1),
924
+ T("label", fn, s(n.$t("components.form.label.serial_number")), 1),
925
925
  A(a, null, {
926
926
  default: y(() => [A(i, l(r, {
927
927
  invalid: o.length > 0,
@@ -931,7 +931,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
931
931
  _: 2
932
932
  }, 1024),
933
933
  A(e, { name: "fade" }, {
934
- default: y(() => [A(_(H), {
934
+ default: y(() => [A(_(V), {
935
935
  name: "info.serialNumber",
936
936
  class: "cui-input-error"
937
937
  })]),
@@ -940,7 +940,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
940
940
  ]),
941
941
  _: 1
942
942
  }, 8, ["modelValue"]),
943
- A(_(L), {
943
+ A(_(I), {
944
944
  modelValue: t.form.info.firmwareVersion,
945
945
  "onUpdate:modelValue": r[7] ||= (e) => t.form.info.firmwareVersion = e,
946
946
  modelModifiers: { trim: !0 },
@@ -949,7 +949,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
949
949
  class: "flex flex-col field-gap"
950
950
  }, {
951
951
  default: y(({ field: r, errors: o }) => [
952
- T("label", dn, s(n.$t("components.form.label.firmware_version")), 1),
952
+ T("label", pn, s(n.$t("components.form.label.firmware_version")), 1),
953
953
  A(a, null, {
954
954
  default: y(() => [A(i, l(r, {
955
955
  invalid: o.length > 0,
@@ -959,7 +959,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
959
959
  _: 2
960
960
  }, 1024),
961
961
  A(e, { name: "fade" }, {
962
- default: y(() => [A(_(H), {
962
+ default: y(() => [A(_(V), {
963
963
  name: "info.firmwareVersion",
964
964
  class: "cui-input-error"
965
965
  })]),
@@ -968,7 +968,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
968
968
  ]),
969
969
  _: 1
970
970
  }, 8, ["modelValue"]),
971
- A(_(L), {
971
+ A(_(I), {
972
972
  modelValue: t.form.info.supportUrl,
973
973
  "onUpdate:modelValue": r[8] ||= (e) => t.form.info.supportUrl = e,
974
974
  modelModifiers: { trim: !0 },
@@ -977,7 +977,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
977
977
  class: "flex flex-col field-gap"
978
978
  }, {
979
979
  default: y(({ field: r, errors: o }) => [
980
- T("label", fn, s(n.$t("components.form.label.support_url")), 1),
980
+ T("label", mn, s(n.$t("components.form.label.support_url")), 1),
981
981
  A(a, null, {
982
982
  default: y(() => [A(i, l(r, {
983
983
  invalid: o.length > 0,
@@ -987,7 +987,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
987
987
  _: 2
988
988
  }, 1024),
989
989
  A(e, { name: "fade" }, {
990
- default: y(() => [A(_(H), {
990
+ default: y(() => [A(_(V), {
991
991
  name: "info.supportUrl",
992
992
  class: "cui-input-error"
993
993
  })]),
@@ -1006,26 +1006,28 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1006
1006
  ]);
1007
1007
  };
1008
1008
  }
1009
- }), mn = RegExp(`^(${me.join("|")})`), hn = K().trim().min(1, "Camera Source is required").regex(mn, "Unsupported protocol — start the URL with a supported one (e.g. rtsp://)"), gn = B({
1010
- name: K().trim().min(1, "Camera Source Name is required"),
1011
- urls: hn.array(),
1012
- role: ge,
1013
- useForSnapshot: I().default(!1),
1014
- hotMode: I().default(!0),
1015
- preload: I().default(!0),
1016
- muted: I().default(!1),
1017
- backchannelDisabled: I().default(!1),
1018
- timeout: F().int().min(5).max(120).nullish(),
1019
- handshakeTimeout: F().int().min(1).max(60).nullish(),
1020
- childSourceId: K().trim().nullish()
1009
+ }), gn = RegExp(`^(${he.join("|")})`), _n = W().trim().min(1, "Camera Source is required").regex(gn, "Unsupported protocol — start the URL with a supported one (e.g. rtsp://)"), vn = z({
1010
+ name: W().trim().min(1, "Camera Source Name is required"),
1011
+ urls: _n.array(),
1012
+ role: ve,
1013
+ useForSnapshot: F().default(!1),
1014
+ hotMode: F().default(!0),
1015
+ preload: F().default(!0),
1016
+ muted: F().default(!1),
1017
+ backchannelDisabled: F().default(!1),
1018
+ timeout: P().int().min(5).max(120).nullish(),
1019
+ handshakeTimeout: P().int().min(1).max(60).nullish(),
1020
+ childSourceId: W().trim().nullish(),
1021
+ childCameraId: W().trim().nullish(),
1022
+ childCameraRole: _e.nullish()
1021
1023
  }).strict().transform((e) => e.role === "snapshot" ? {
1022
1024
  ...e,
1023
1025
  useForSnapshot: !1,
1024
1026
  hotMode: !1,
1025
1027
  preload: !1
1026
- } : e), _n = B({
1027
- ...he.shape,
1028
- sources: gn.array().refine((e) => e.some((e) => e.role === "high-resolution" || e.role === "mid-resolution" || e.role === "low-resolution"), {
1028
+ } : e), yn = z({
1029
+ ...ge.shape,
1030
+ sources: vn.array().refine((e) => e.some((e) => e.role === "high-resolution" || e.role === "mid-resolution" || e.role === "low-resolution"), {
1029
1031
  path: ["sources[].role"],
1030
1032
  message: "One of the roles \"high-resolution\", \"mid-resolution\" or \"low-resolution\" is required"
1031
1033
  }).refine((e) => e.filter((e) => e.useForSnapshot).length <= 1, {
@@ -1037,8 +1039,8 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1037
1039
  }, {
1038
1040
  message: "Each source role can be assigned to only one source",
1039
1041
  path: ["sources"]
1040
- }).superRefine(_e)
1041
- }).strict(), vn = {
1042
+ }).superRefine(ye)
1043
+ }).strict(), bn = {
1042
1044
  disabled: !1,
1043
1045
  name: "",
1044
1046
  type: "camera",
@@ -1053,7 +1055,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1053
1055
  supportUrl: ""
1054
1056
  },
1055
1057
  sources: [{
1056
- _id: q(8),
1058
+ _id: G(8),
1057
1059
  name: "",
1058
1060
  role: "high-resolution",
1059
1061
  urls: [""],
@@ -1072,25 +1074,25 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1072
1074
  },
1073
1075
  plugins: [],
1074
1076
  assignments: {}
1075
- }, yn = { class: "card-title" }, bn = { class: "card-title" }, xn = { class: "w-full flex items-center justify-center mt-4" }, Sn = /* @__PURE__ */ O({
1077
+ }, xn = { class: "card-title" }, Sn = { class: "card-title" }, Cn = { class: "w-full flex items-center justify-center mt-4" }, wn = /* @__PURE__ */ O({
1076
1078
  __name: "AddCamera",
1077
- props: { camera: { default: () => vn } },
1079
+ props: { camera: { default: () => bn } },
1078
1080
  setup(e, { expose: t }) {
1079
- let n = new z(), r = e, a = U(), { t: c } = J(), { mutateAsync: l, isPending: u } = n.createCameraQuery(), { camera: d } = i(r), f = w("formRef"), p = w("sourcesRef"), m = k(W(d.value)), h = v(() => u.value);
1081
+ let n = new R(), r = e, a = K(), { t: c } = q(), { mutateAsync: l, isPending: u } = n.createCameraQuery(), { camera: d } = i(r), f = w("formRef"), p = w("sourcesRef"), m = k(H(d.value)), h = v(() => u.value);
1080
1082
  async function g() {
1081
1083
  if (!(await f.value?.validate())?.valid) return a.add({
1082
1084
  severity: "error",
1083
1085
  detail: c("components.toast.validation_failed"),
1084
1086
  life: 3e3
1085
1087
  }), null;
1086
- let e = W(m.value), t = {
1087
- ...ve(),
1088
+ let e = H(m.value), t = {
1089
+ ...be(),
1088
1090
  ...e,
1089
1091
  sources: e.sources.map((e) => ({
1090
1092
  ...e,
1091
1093
  muted: e.muted ?? !1,
1092
1094
  backchannelDisabled: e.backchannelDisabled ?? !1,
1093
- urls: e.urls.map(yt).filter(Boolean)
1095
+ urls: e.urls.map(xt).filter(Boolean)
1094
1096
  }))
1095
1097
  };
1096
1098
  await l({ cameraData: t });
@@ -1100,21 +1102,21 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1100
1102
  onSave: g,
1101
1103
  onConfirm: g
1102
1104
  }), (e, t) => {
1103
- let n = pn, r = fe, i = Kt, a = je, c = be;
1104
- return o(), x("div", null, [A(_(R), {
1105
+ let n = hn, r = pe, i = Jt, a = Ne, c = Se;
1106
+ return o(), x("div", null, [A(_(L), {
1105
1107
  ref_key: "formRef",
1106
1108
  ref: f,
1107
1109
  class: "flex flex-col w-full gap-6",
1108
- "validation-schema": _(_n)
1110
+ "validation-schema": _(yn)
1109
1111
  }, {
1110
- default: y(() => [T("div", null, [T("span", yn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(r, { class: "cui-card" }, {
1112
+ default: y(() => [T("div", null, [T("span", xn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(r, { class: "cui-card" }, {
1111
1113
  content: y(() => [A(n, {
1112
1114
  form: _(m),
1113
1115
  "is-loading": _(h)
1114
1116
  }, null, 8, ["form", "is-loading"])]),
1115
1117
  _: 1
1116
1118
  })]), T("div", null, [
1117
- T("span", bn, s(e.$t("components.form.label.sources")), 1),
1119
+ T("span", Sn, s(e.$t("components.form.label.sources")), 1),
1118
1120
  A(r, {
1119
1121
  class: "cui-card border-color-inner",
1120
1122
  pt: { body: { class: "pb-0" } }
@@ -1128,7 +1130,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1128
1130
  }, null, 8, ["sources", "is-loading"])]),
1129
1131
  _: 1
1130
1132
  }),
1131
- T("div", xn, [A(c, {
1133
+ T("div", Cn, [A(c, {
1132
1134
  text: "",
1133
1135
  rounded: "",
1134
1136
  loading: _(h),
@@ -1146,17 +1148,17 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1146
1148
  }, 8, ["validation-schema"])]);
1147
1149
  };
1148
1150
  }
1149
- }), Cn = { class: "card-title" }, wn = {
1151
+ }), Tn = { class: "card-title" }, En = {
1150
1152
  key: 0,
1151
1153
  class: "flex flex-col gap-6"
1152
- }, Tn = { class: "cui-label" }, En = { class: "card-title" }, Dn = /* @__PURE__ */ O({
1154
+ }, Dn = { class: "cui-label" }, On = { class: "card-title" }, kn = /* @__PURE__ */ O({
1153
1155
  __name: "ConfirmCamera",
1154
1156
  props: {
1155
1157
  draft: {},
1156
1158
  onConfirm: { type: Function }
1157
1159
  },
1158
1160
  setup(e, { expose: t }) {
1159
- let n = B({ name: K().trim().min(1) }).passthrough(), r = e, i = U(), { t: c } = J(), l = w("formRef"), u = k(W(r.draft)), d = k({
1161
+ let n = z({ name: W().trim().min(1) }).passthrough(), r = e, i = K(), { t: c } = q(), l = w("formRef"), u = k(H(r.draft)), d = k({
1160
1162
  name: u.value.name,
1161
1163
  type: u.value.type,
1162
1164
  room: u.value.room,
@@ -1193,7 +1195,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1193
1195
  info: d.value.info,
1194
1196
  sources: d.value.sources.map((e) => ({
1195
1197
  ...e,
1196
- urls: e.urls.map(yt).filter(Boolean)
1198
+ urls: e.urls.map(xt).filter(Boolean)
1197
1199
  }))
1198
1200
  };
1199
1201
  await r.onConfirm(e);
@@ -1212,22 +1214,22 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1212
1214
  isLoading: h,
1213
1215
  onConfirm: g
1214
1216
  }), (e, t) => {
1215
- let r = Y, i = V, c = pn, u = fe, f = Kt;
1216
- return o(), x("div", null, [A(_(R), {
1217
+ let r = J, i = B, c = hn, u = pe, f = Jt;
1218
+ return o(), x("div", null, [A(_(L), {
1217
1219
  ref_key: "formRef",
1218
1220
  ref: l,
1219
1221
  class: "flex flex-col w-full gap-6",
1220
1222
  "validation-schema": _(n)
1221
1223
  }, {
1222
- default: y(() => [T("div", null, [T("span", Cn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(u, { class: "cui-card" }, {
1224
+ default: y(() => [T("div", null, [T("span", Tn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(u, { class: "cui-card" }, {
1223
1225
  content: y(() => [A(c, {
1224
1226
  form: _(d),
1225
1227
  "is-loading": _(h)
1226
1228
  }, {
1227
- default: y(() => [_(p).length ? (o(), x("div", wn, [(o(!0), x(C, null, a(_(p), (e) => (o(), x("div", {
1229
+ default: y(() => [_(p).length ? (o(), x("div", En, [(o(!0), x(C, null, a(_(p), (e) => (o(), x("div", {
1228
1230
  key: e.label,
1229
1231
  class: "flex flex-col field-gap"
1230
- }, [T("label", Tn, s(e.label), 1), A(i, null, {
1232
+ }, [T("label", Dn, s(e.label), 1), A(i, null, {
1231
1233
  default: y(() => [A(r, {
1232
1234
  "model-value": e.value,
1233
1235
  readonly: "",
@@ -1238,7 +1240,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1238
1240
  _: 1
1239
1241
  }, 8, ["form", "is-loading"])]),
1240
1242
  _: 1
1241
- })]), T("div", null, [T("span", En, s(e.$t("components.form.label.sources")), 1), A(u, {
1243
+ })]), T("div", null, [T("span", On, s(e.$t("components.form.label.sources")), 1), A(u, {
1242
1244
  class: "cui-card border-color-inner",
1243
1245
  pt: { body: { class: "pb-0" } }
1244
1246
  }, {
@@ -1253,13 +1255,13 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1253
1255
  }, 8, ["validation-schema"])]);
1254
1256
  };
1255
1257
  }
1256
- }), On = { class: "flex flex-col gap-6" }, kn = {
1258
+ }), An = { class: "flex flex-col gap-6" }, jn = {
1257
1259
  key: 0,
1258
1260
  class: "flex flex-col field-gap"
1259
- }, An = { class: "cui-label" }, jn = {
1261
+ }, Mn = { class: "cui-label" }, Nn = {
1260
1262
  key: 1,
1261
1263
  class: "text-center py-4"
1262
- }, Mn = { class: "text-muted" }, Nn = /* @__PURE__ */ O({
1264
+ }, Pn = { class: "text-muted" }, Fn = /* @__PURE__ */ O({
1263
1265
  __name: "ConnectionSchema",
1264
1266
  props: {
1265
1267
  camera: {},
@@ -1267,7 +1269,7 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1267
1269
  onConnect: { type: Function }
1268
1270
  },
1269
1271
  setup(e, { expose: t }) {
1270
- let n = e, a = pe(), c = U(), { t: l } = J(), u = r("dialogRefProps"), { schema: d } = i(n), f = w("schemaFormRef"), h = k(!1), g = v(() => ({
1272
+ let n = e, a = me(), c = K(), { t: l } = q(), u = r("dialogRefProps"), { schema: d } = i(n), f = w("schemaFormRef"), h = k(!1), g = v(() => ({
1271
1273
  schema: d.value,
1272
1274
  config: {}
1273
1275
  })), y = v(() => !!(u.loading?.value || h.value));
@@ -1300,11 +1302,11 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1300
1302
  isLoading: y,
1301
1303
  onConfirm: b
1302
1304
  }), (t, n) => {
1303
- let r = Y, i = Me;
1304
- return o(), x("div", On, [e.camera.address ? (o(), x("div", kn, [T("label", An, s(t.$t("views.devices.address")), 1), A(r, {
1305
+ let r = J, i = Pe;
1306
+ return o(), x("div", An, [e.camera.address ? (o(), x("div", jn, [T("label", Mn, s(t.$t("views.devices.address")), 1), A(r, {
1305
1307
  "model-value": e.camera.address,
1306
1308
  readonly: ""
1307
- }, null, 8, ["model-value"])])) : m("", !0), _(d).length === 0 ? (o(), x("div", jn, [T("p", Mn, s(t.$t("views.devices.no_settings_required")), 1)])) : (o(), p(i, {
1309
+ }, null, 8, ["model-value"])])) : m("", !0), _(d).length === 0 ? (o(), x("div", Nn, [T("p", Pn, s(t.$t("views.devices.no_settings_required")), 1)])) : (o(), p(i, {
1308
1310
  key: 2,
1309
1311
  ref_key: "schemaFormRef",
1310
1312
  ref: f,
@@ -1313,98 +1315,98 @@ var Zt = { class: "flex flex-col gap-6" }, Qt = {
1313
1315
  }, null, 8, ["schema-form", "loading"]))]);
1314
1316
  };
1315
1317
  }
1316
- }), Pn = 5e3, X = j({
1318
+ }), In = 5e3, Y = j({
1317
1319
  isLoading: !0,
1318
1320
  devices: [],
1319
1321
  isScanning: !1,
1320
1322
  hiddenDevices: [],
1321
1323
  showHidden: !1,
1322
1324
  error: null
1323
- }), Fn = null, Z = null, Q = !1, $ = 0, In = null;
1324
- function Ln() {
1325
- X.isLoading = !0, X.devices = [], X.isScanning = !1, X.hiddenDevices = [], X.showHidden = !1, X.error = null;
1326
- }
1325
+ }), Ln = null, X = null, Z = !1, Q = 0, $ = null;
1327
1326
  function Rn() {
1328
- return Z || (Fn = h(!0), Fn.run(() => {
1329
- let e = oe("/cameras");
1330
- Z = e, e.onReady(() => {
1331
- zn();
1327
+ Y.isLoading = !0, Y.devices = [], Y.isScanning = !1, Y.hiddenDevices = [], Y.showHidden = !1, Y.error = null;
1328
+ }
1329
+ function zn() {
1330
+ return X || (Ln = h(!0), Ln.run(() => {
1331
+ let e = ue("/cameras");
1332
+ X = e, e.onReady(() => {
1333
+ Bn();
1332
1334
  }), b(e.connected, (e, t) => {
1333
- !e && t && (Q = !1);
1335
+ !e && t && (Z = !1);
1334
1336
  }), e.on("cameras:discovered", (e) => {
1335
1337
  for (let t of e.devices) {
1336
- let e = X.devices.findIndex((e) => e.id === t.id);
1337
- e >= 0 ? X.devices[e] = t : X.devices.push(t);
1338
+ let e = Y.devices.findIndex((e) => e.id === t.id);
1339
+ e >= 0 ? Y.devices[e] = t : Y.devices.push(t);
1338
1340
  }
1339
1341
  }), e.on("cameras:scanning", (e) => {
1340
- X.isScanning = e.isScanning;
1342
+ Y.isScanning = e.isScanning;
1341
1343
  }), e.on("cameras:connection-status", (e) => {
1342
- let t = X.devices.find((t) => t.discoveredId === e.discoveredId);
1343
- t && (e.status === "connecting" ? t.status = "adopting" : e.status === "error" ? (t.status = "error", t.errorMessage = e.errorMessage) : e.status === "connected" && (X.devices = X.devices.filter((t) => t.discoveredId !== e.discoveredId)));
1344
+ let t = Y.devices.find((t) => t.discoveredId === e.discoveredId);
1345
+ t && (e.status === "connecting" ? t.status = "adopting" : e.status === "error" ? (t.status = "error", t.errorMessage = e.errorMessage) : e.status === "connected" && (Y.devices = Y.devices.filter((t) => t.discoveredId !== e.discoveredId)));
1344
1346
  }), e.on("cameras:camera-connected", (e) => {
1345
- X.devices = X.devices.filter((t) => t.discoveredId !== e.discoveredId);
1347
+ Y.devices = Y.devices.filter((t) => t.discoveredId !== e.discoveredId);
1346
1348
  }), e.on("cameras:deleted", (e) => {
1347
- X.devices = X.devices.filter((t) => t.cameraId !== e.cameraId);
1349
+ Y.devices = Y.devices.filter((t) => t.cameraId !== e.cameraId);
1348
1350
  });
1349
- }), Z);
1351
+ }), X);
1350
1352
  }
1351
- async function zn() {
1352
- if (!Z || Q) return {
1353
- success: Q,
1354
- devices: X.devices,
1355
- isScanning: X.isScanning,
1356
- hiddenDevices: X.hiddenDevices
1353
+ async function Bn() {
1354
+ if (!X || Z) return {
1355
+ success: Z,
1356
+ devices: Y.devices,
1357
+ isScanning: Y.isScanning,
1358
+ hiddenDevices: Y.hiddenDevices
1357
1359
  };
1358
1360
  try {
1359
- let e = await Z.request("cameras:subscribe", {});
1360
- return Q = e.success, e.devices && (X.devices = e.devices), e.isScanning !== void 0 && (X.isScanning = e.isScanning), e.hiddenDevices && (X.hiddenDevices = e.hiddenDevices), X.isLoading = !1, e;
1361
+ let e = await X.request("cameras:subscribe", {});
1362
+ return Z = e.success, e.devices && (Y.devices = e.devices), e.isScanning !== void 0 && (Y.isScanning = e.isScanning), e.hiddenDevices && (Y.hiddenDevices = e.hiddenDevices), Y.isLoading = !1, e;
1361
1363
  } catch (e) {
1362
- return X.isLoading = !1, X.error = e instanceof Error ? e.message : "subscribe failed", { success: !1 };
1364
+ return Y.isLoading = !1, Y.error = e instanceof Error ? e.message : "subscribe failed", { success: !1 };
1363
1365
  }
1364
1366
  }
1365
- async function Bn() {
1366
- if (!Z || !Q) return { success: !0 };
1367
+ async function Vn() {
1368
+ if (!X || !Z) return { success: !0 };
1367
1369
  try {
1368
- let e = await Z.request("cameras:unsubscribe", {});
1369
- return Q = !e.success, e;
1370
+ let e = await X.request("cameras:unsubscribe", {});
1371
+ return Z = !e.success, e;
1370
1372
  } catch {
1371
1373
  return { success: !1 };
1372
1374
  }
1373
1375
  }
1374
- function Vn() {
1375
- Q && Bn(), Fn?.stop(), Fn = null, Z = null, Q = !1, Ln();
1376
- }
1377
1376
  function Hn() {
1378
- In &&= (clearTimeout(In), null), $++;
1377
+ Z && Vn(), Ln?.stop(), Ln = null, X = null, Z = !1, Rn();
1378
+ }
1379
+ function Un() {
1380
+ $ &&= (clearTimeout($), null), Q++;
1379
1381
  function e() {
1380
- Rn(), Z?.connected.value && !Q && zn();
1382
+ zn(), X?.connected.value && !Z && Bn();
1381
1383
  }
1382
1384
  function t() {
1383
- Q && Bn();
1385
+ Z && Vn();
1384
1386
  }
1385
1387
  async function n() {
1386
- if (!Z?.ready.value) return {
1388
+ if (!X?.ready.value) return {
1387
1389
  success: !1,
1388
1390
  error: "Not connected"
1389
1391
  };
1390
- X.devices = [], X.isScanning = !0;
1392
+ Y.devices = [], Y.isScanning = !0;
1391
1393
  try {
1392
- let e = await Z.request("cameras:rescan", {});
1393
- return e.success || (X.isScanning = !1), e;
1394
+ let e = await X.request("cameras:rescan", {});
1395
+ return e.success || (Y.isScanning = !1), e;
1394
1396
  } catch (e) {
1395
- return X.isScanning = !1, {
1397
+ return Y.isScanning = !1, {
1396
1398
  success: !1,
1397
1399
  error: e instanceof Error ? e.message : "rescan failed"
1398
1400
  };
1399
1401
  }
1400
1402
  }
1401
1403
  async function r(e) {
1402
- if (!Z?.ready.value) return {
1404
+ if (!X?.ready.value) return {
1403
1405
  success: !1,
1404
1406
  error: "Not connected"
1405
1407
  };
1406
1408
  try {
1407
- return await Z.request("cameras:get-schema", { discoveredId: e });
1409
+ return await X.request("cameras:get-schema", { discoveredId: e });
1408
1410
  } catch (e) {
1409
1411
  return {
1410
1412
  success: !1,
@@ -1413,12 +1415,12 @@ function Hn() {
1413
1415
  }
1414
1416
  }
1415
1417
  async function i(e, t) {
1416
- if (!Z?.ready.value) return {
1418
+ if (!X?.ready.value) return {
1417
1419
  success: !1,
1418
1420
  error: "Not connected"
1419
1421
  };
1420
1422
  try {
1421
- return await Z.request("cameras:connect", {
1423
+ return await X.request("cameras:connect", {
1422
1424
  discoveredId: e,
1423
1425
  credentials: t
1424
1426
  });
@@ -1430,8 +1432,8 @@ function Hn() {
1430
1432
  }
1431
1433
  }
1432
1434
  async function a(e, t) {
1433
- if (!Z?.ready.value) throw Error("Not connected");
1434
- let n = await Z.request("cameras:prepare", {
1435
+ if (!X?.ready.value) throw Error("Not connected");
1436
+ let n = await X.request("cameras:prepare", {
1435
1437
  discoveredId: e,
1436
1438
  credentials: t
1437
1439
  });
@@ -1439,8 +1441,8 @@ function Hn() {
1439
1441
  return n.draft;
1440
1442
  }
1441
1443
  async function o(e, t) {
1442
- if (!Z?.ready.value) throw Error("Not connected");
1443
- let n = await Z.request("cameras:confirm", {
1444
+ if (!X?.ready.value) throw Error("Not connected");
1445
+ let n = await X.request("cameras:confirm", {
1444
1446
  draft: e,
1445
1447
  discoveredId: t
1446
1448
  });
@@ -1451,7 +1453,7 @@ function Hn() {
1451
1453
  };
1452
1454
  }
1453
1455
  async function s(e) {
1454
- if (!Z?.ready.value) return {
1456
+ if (!X?.ready.value) return {
1455
1457
  success: !1,
1456
1458
  error: "Not connected"
1457
1459
  };
@@ -1461,8 +1463,8 @@ function Hn() {
1461
1463
  model: e.model
1462
1464
  };
1463
1465
  try {
1464
- let e = await Z.request("cameras:hide-device", { device: t });
1465
- return e.success && e.hiddenDevices && (X.hiddenDevices = e.hiddenDevices), e;
1466
+ let e = await X.request("cameras:hide-device", { device: t });
1467
+ return e.success && e.hiddenDevices && (Y.hiddenDevices = e.hiddenDevices), e;
1466
1468
  } catch (e) {
1467
1469
  return {
1468
1470
  success: !1,
@@ -1471,13 +1473,13 @@ function Hn() {
1471
1473
  }
1472
1474
  }
1473
1475
  async function c(e) {
1474
- if (!Z?.ready.value) return {
1476
+ if (!X?.ready.value) return {
1475
1477
  success: !1,
1476
1478
  error: "Not connected"
1477
1479
  };
1478
1480
  try {
1479
- let t = await Z.request("cameras:unhide-device", { deviceId: e });
1480
- return t.success && t.hiddenDevices && (X.hiddenDevices = t.hiddenDevices), t;
1481
+ let t = await X.request("cameras:unhide-device", { deviceId: e });
1482
+ return t.success && t.hiddenDevices && (Y.hiddenDevices = t.hiddenDevices), t;
1481
1483
  } catch (e) {
1482
1484
  return {
1483
1485
  success: !1,
@@ -1486,37 +1488,37 @@ function Hn() {
1486
1488
  }
1487
1489
  }
1488
1490
  function l() {
1489
- X.showHidden = !X.showHidden;
1491
+ Y.showHidden = !Y.showHidden;
1490
1492
  }
1491
1493
  function u(e) {
1492
- return e.type !== "discovered" || !e.discoveredId ? !1 : X.hiddenDevices.some((t) => t.id === e.discoveredId);
1494
+ return e.type !== "discovered" || !e.discoveredId ? !1 : Y.hiddenDevices.some((t) => t.id === e.discoveredId);
1493
1495
  }
1494
1496
  let d = v(() => {
1495
- let e = new Set(X.hiddenDevices.map((e) => e.id)), t = (e, t) => e.name.localeCompare(t.name), n = X.devices.filter((e) => e.type === "camera").sort(t), r = X.devices.filter((t) => t.type === "discovered" && !e.has(t.discoveredId)).sort(t), i = X.showHidden ? X.devices.filter((t) => t.type === "discovered" && e.has(t.discoveredId)).sort(t) : [];
1497
+ let e = new Set(Y.hiddenDevices.map((e) => e.id)), t = (e, t) => e.name.localeCompare(t.name), n = Y.devices.filter((e) => e.type === "camera").sort(t), r = Y.devices.filter((t) => t.type === "discovered" && !e.has(t.discoveredId)).sort(t), i = Y.showHidden ? Y.devices.filter((t) => t.type === "discovered" && e.has(t.discoveredId)).sort(t) : [];
1496
1498
  return [
1497
1499
  ...n,
1498
1500
  ...r,
1499
1501
  ...i
1500
1502
  ];
1501
1503
  });
1502
- return de(() => {
1503
- $--, !($ > 0) && ($ = 0, In = setTimeout(() => {
1504
- $ <= 0 && (Vn(), In = null);
1505
- }, Pn));
1504
+ return fe(() => {
1505
+ Q--, !(Q > 0) && (Q = 0, $ = setTimeout(() => {
1506
+ Q <= 0 && (Hn(), $ = null);
1507
+ }, In));
1506
1508
  }), {
1507
- state: f(X),
1508
- isConnected: v(() => Z?.connected.value ?? !1),
1509
- isLoading: v(() => X.isLoading),
1510
- devices: v(() => X.devices),
1511
- isScanning: v(() => X.isScanning),
1512
- hiddenDevices: v(() => X.hiddenDevices),
1513
- showHidden: v(() => X.showHidden),
1514
- error: v(() => X.error),
1509
+ state: f(Y),
1510
+ isConnected: v(() => X?.connected.value ?? !1),
1511
+ isLoading: v(() => Y.isLoading),
1512
+ devices: v(() => Y.devices),
1513
+ isScanning: v(() => Y.isScanning),
1514
+ hiddenDevices: v(() => Y.hiddenDevices),
1515
+ showHidden: v(() => Y.showHidden),
1516
+ error: v(() => Y.error),
1515
1517
  sortedDevices: d,
1516
1518
  connect: e,
1517
1519
  disconnect: t,
1518
- subscribe: zn,
1519
- unsubscribe: Bn,
1520
+ subscribe: Bn,
1521
+ unsubscribe: Vn,
1520
1522
  forceRescan: n,
1521
1523
  getConnectionSchema: r,
1522
1524
  connectDevice: i,
@@ -1530,38 +1532,38 @@ function Hn() {
1530
1532
  }
1531
1533
  //#endregion
1532
1534
  //#region src/views/Cameras.vue?vue&type=script&setup=true&lang.ts
1533
- var Un = { class: "flex flex-col" }, Wn = {
1535
+ var Wn = { class: "flex flex-col" }, Gn = {
1534
1536
  key: 0,
1535
1537
  class: "page-title"
1536
- }, Gn = {
1538
+ }, Kn = {
1537
1539
  key: 1,
1538
1540
  class: "flex min-h-0 flex-col"
1539
- }, Kn = {
1541
+ }, qn = {
1540
1542
  key: 0,
1541
1543
  class: "flex flex-1 min-h-0 flex-col items-center justify-center w-full gap-4"
1542
- }, qn = {
1544
+ }, Jn = {
1543
1545
  key: 1,
1544
1546
  class: "flex flex-1 min-h-0 flex-col items-center justify-center w-full gap-4 py-16"
1545
- }, Jn = { class: "w-16 h-16 rounded-full bg-primary-500/10 flex items-center justify-center" }, Yn = { class: "flex flex-col items-center gap-1 max-w-[400px] text-center" }, Xn = { class: "text-color font-semibold text-base" }, Zn = { class: "text-muted text-sm" }, Qn = {
1547
+ }, Yn = { class: "w-16 h-16 rounded-full bg-primary-500/10 flex items-center justify-center" }, Xn = { class: "flex flex-col items-center gap-1 max-w-[400px] text-center" }, Zn = { class: "text-color font-semibold text-base" }, Qn = { class: "text-muted text-sm" }, $n = {
1546
1548
  key: 2,
1547
1549
  class: "flex min-h-0 flex-col"
1548
- }, $n = { class: "card-title" }, er = { class: "flex items-center justify-center" }, tr = { class: "font-bold text-color truncate" }, nr = { class: "text-xs text-muted truncate" }, rr = {
1550
+ }, er = { class: "card-title" }, tr = { class: "flex items-center justify-center" }, nr = { class: "font-bold text-color truncate" }, rr = { class: "text-xs text-muted truncate" }, ir = {
1549
1551
  key: 0,
1550
1552
  class: "text-xs text-red-500 truncate"
1551
- }, ir = { class: "card-title" }, ar = {
1553
+ }, ar = { class: "card-title" }, or = {
1552
1554
  key: 0,
1553
1555
  class: "flex flex-col gap-6"
1554
- }, or = { class: "flex items-center justify-center" }, sr = { class: "flex items-center justify-center" }, cr = {
1556
+ }, sr = { class: "flex items-center justify-center" }, cr = { class: "flex items-center justify-center" }, lr = {
1555
1557
  key: 1,
1556
1558
  class: "flex flex-col items-center justify-center py-6 gap-2"
1557
- }, lr = { class: "text-muted text-sm" }, ur = { class: "flex flex-wrap items-center gap-2 mt-4" }, dr = /*#__PURE__*/ ie(/* @__PURE__ */ O({
1559
+ }, ur = { class: "text-muted text-sm" }, dr = { class: "flex flex-wrap items-center gap-2 mt-4" }, fr = /*#__PURE__*/ ae(/* @__PURE__ */ O({
1558
1560
  __name: "Cameras",
1559
1561
  setup(e) {
1560
- let { t } = J(), r = U(), i = G(), a = ue(), { smBreakpoint: c } = P(), l = Hn(), d = {
1562
+ let { t } = q(), r = K(), i = U(), a = de(), { smBreakpoint: c } = ie(), l = Un(), d = {
1561
1563
  bodyRow: { class: "text-sm text-secondary" },
1562
1564
  column: { columnTitle: { class: "text-sm" } },
1563
1565
  datatable: { class: "z-0" }
1564
- }, f = v(() => se(void 0, "admin")), h = v(() => l.sortedDevices.value), g = v(() => h.value.filter((e) => e.type === "camera")), b = v(() => h.value.filter((e) => e.type === "discovered")), w = v(() => l.isLoading.value), D = v(() => l.isScanning.value), O = v(() => l.hiddenDevices.value), k = v(() => l.showHidden.value), j = v(() => O.value.length);
1566
+ }, f = v(() => oe(void 0, "admin")), h = v(() => l.sortedDevices.value), g = v(() => h.value.filter((e) => e.type === "camera")), b = v(() => h.value.filter((e) => e.type === "discovered")), w = v(() => l.isLoading.value), D = v(() => l.isScanning.value), O = v(() => l.hiddenDevices.value), k = v(() => l.showHidden.value), j = v(() => O.value.length);
1565
1567
  function te(e) {
1566
1568
  switch (e) {
1567
1569
  case "added": return "green";
@@ -1580,11 +1582,11 @@ var Un = { class: "flex flex-col" }, Wn = {
1580
1582
  default: return t("views.devices.status_unknown");
1581
1583
  }
1582
1584
  }
1583
- function F(e) {
1585
+ function P(e) {
1584
1586
  return l.isHidden(e);
1585
1587
  }
1586
- async function re(e) {
1587
- if (!F(e)) {
1588
+ async function ne(e) {
1589
+ if (!P(e)) {
1588
1590
  if (e.type === "camera") {
1589
1591
  a.open({ cameraName: e.name });
1590
1592
  return;
@@ -1602,7 +1604,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1602
1604
  });
1603
1605
  return;
1604
1606
  }
1605
- i.openComponentDialog(Nn, { data: {
1607
+ i.openComponentDialog(Fn, { data: {
1606
1608
  title: `${t("views.devices.connect")}: ${e.name}`,
1607
1609
  confirmText: t("views.devices.connect"),
1608
1610
  contentProps: {
@@ -1616,7 +1618,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1616
1618
  },
1617
1619
  schema: n.schema ?? [],
1618
1620
  onConnect: async (t) => {
1619
- I(await l.prepareDevice(e.discoveredId, t), e.discoveredId);
1621
+ F(await l.prepareDevice(e.discoveredId, t), e.discoveredId);
1620
1622
  }
1621
1623
  }
1622
1624
  } });
@@ -1631,8 +1633,8 @@ var Un = { class: "flex flex-col" }, Wn = {
1631
1633
  }
1632
1634
  }
1633
1635
  }
1634
- function I(e, n) {
1635
- i.openComponentDialog(Dn, { data: {
1636
+ function F(e, n) {
1637
+ i.openComponentDialog(kn, { data: {
1636
1638
  title: t("views.devices.confirm_title"),
1637
1639
  confirmText: t("views.devices.confirm"),
1638
1640
  fullscreen: !0,
@@ -1649,7 +1651,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1649
1651
  }
1650
1652
  } });
1651
1653
  }
1652
- async function ie() {
1654
+ async function I() {
1653
1655
  try {
1654
1656
  let e = await l.forceRescan();
1655
1657
  e.success ? r.add({
@@ -1673,7 +1675,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1673
1675
  }
1674
1676
  }
1675
1677
  function L() {
1676
- i.openComponentDialog(Sn, { data: {
1678
+ i.openComponentDialog(wn, { data: {
1677
1679
  title: t("components.dialog.components.new_camera.add_camera"),
1678
1680
  fullscreen: !0,
1679
1681
  contentProps: {}
@@ -1727,43 +1729,43 @@ var Un = { class: "flex flex-col" }, Wn = {
1727
1729
  });
1728
1730
  }
1729
1731
  }
1730
- function B() {
1732
+ function ae() {
1731
1733
  l.toggleShowHidden();
1732
1734
  }
1733
- function V(e) {
1734
- return F(e) ? "opacity-50 cursor-not-allowed" : "";
1735
+ function B(e) {
1736
+ return P(e) ? "opacity-50 cursor-not-allowed" : "";
1735
1737
  }
1736
1738
  return M(() => {
1737
1739
  f.value && l.connect();
1738
1740
  }), n(() => {
1739
1741
  f.value && l.unsubscribe();
1740
1742
  }), (e, t) => {
1741
- let n = Ne, r = fe, i = le, a = ce, l = be, v = ye, O = Oe, M = De, P = ke, I = ae, H = Ie, U = ne, W = ee;
1742
- return o(), x("div", Un, [
1743
- _(c) ? m("", !0) : (o(), x("h1", Wn, s(e.$t(`views.${String(e.$route.name).toLowerCase()}.title`)), 1)),
1743
+ let n = Fe, r = pe, i = re, a = le, l = Se, v = xe, O = Ae, M = ke, F = je, ie = se, V = Re, H = ce, U = ee;
1744
+ return o(), x("div", Wn, [
1745
+ _(c) ? m("", !0) : (o(), x("h1", Gn, s(e.$t(`views.${String(e.$route.name).toLowerCase()}.title`)), 1)),
1744
1746
  _(f) ? (o(), x(C, { key: 2 }, [
1745
- _(w) ? (o(), x("div", Kn, [A(i, {
1747
+ _(w) ? (o(), x("div", qn, [A(i, {
1746
1748
  "stroke-width": "5",
1747
1749
  class: "w-[30px] h-[30px]"
1748
1750
  })])) : m("", !0),
1749
- !_(w) && !_(h).length ? (o(), x("div", qn, [
1750
- T("div", Jn, [A(a, { class: "w-8 h-8 text-primary-500" })]),
1751
- T("div", Yn, [T("span", Xn, s(_(D) ? e.$t("views.devices.scanning") : e.$t("views.devices.no_devices")), 1), T("span", Zn, s(_(D) ? e.$t("views.devices.scanning_hint") : e.$t("views.devices.no_devices_hint")), 1)]),
1751
+ !_(w) && !_(h).length ? (o(), x("div", Jn, [
1752
+ T("div", Yn, [A(a, { class: "w-8 h-8 text-primary-500" })]),
1753
+ T("div", Xn, [T("span", Zn, s(_(D) ? e.$t("views.devices.scanning") : e.$t("views.devices.no_devices")), 1), T("span", Qn, s(_(D) ? e.$t("views.devices.scanning_hint") : e.$t("views.devices.no_devices_hint")), 1)]),
1752
1754
  A(l, {
1753
1755
  class: "cui-button-medium mt-2",
1754
1756
  severity: "secondary",
1755
1757
  label: e.$t("views.devices.rescan"),
1756
1758
  loading: _(D),
1757
- onClick: ie
1759
+ onClick: I
1758
1760
  }, null, 8, ["label", "loading"])
1759
1761
  ])) : m("", !0),
1760
- !_(w) && _(g).length ? (o(), x("div", Qn, [T("span", $n, s(e.$t("views.devices.status_adopted_cameras")), 1), A(r, { class: "cui-card" }, {
1761
- content: y(() => [A(P, {
1762
+ !_(w) && _(g).length ? (o(), x("div", $n, [T("span", er, s(e.$t("views.devices.status_adopted_cameras")), 1), A(r, { class: "cui-card" }, {
1763
+ content: y(() => [A(F, {
1762
1764
  value: _(g),
1763
1765
  "striped-rows": "",
1764
1766
  pt: d,
1765
1767
  class: "w-full",
1766
- onRowClick: t[0] ||= (e) => re(e.data)
1768
+ onRowClick: t[0] ||= (e) => ne(e.data)
1767
1769
  }, {
1768
1770
  default: y(() => [
1769
1771
  A(O, {
@@ -1771,7 +1773,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1771
1773
  "header-class": "p-2 pl-4 w-5 max-w-5",
1772
1774
  class: "p-2 pl-4 w-5 max-w-5"
1773
1775
  }, {
1774
- body: y(({ data: e }) => [T("div", er, [E(A(v, { style: S({ background: te(e.status) }) }, null, 8, ["style"]), [[W, { value: N(e.status) }]])])]),
1776
+ body: y(({ data: e }) => [T("div", tr, [E(A(v, { style: S({ background: te(e.status) }) }, null, 8, ["style"]), [[U, { value: N(e.status) }]])])]),
1775
1777
  _: 1
1776
1778
  }),
1777
1779
  A(O, {
@@ -1781,9 +1783,9 @@ var Un = { class: "flex flex-col" }, Wn = {
1781
1783
  class: "p-2 w-full min-w-[200px] max-w-0"
1782
1784
  }, {
1783
1785
  body: y(({ data: t }) => [
1784
- T("div", tr, s(t.name), 1),
1785
- T("div", nr, s(t.manufacturer || e.$t("views.devices.unknown")) + " · " + s(t.model || e.$t("views.devices.unknown")), 1),
1786
- t.errorMessage ? (o(), x("div", rr, s(t.errorMessage), 1)) : m("", !0)
1786
+ T("div", nr, s(t.name), 1),
1787
+ T("div", rr, s(t.manufacturer || e.$t("views.devices.unknown")) + " · " + s(t.model || e.$t("views.devices.unknown")), 1),
1788
+ t.errorMessage ? (o(), x("div", ir, s(t.errorMessage), 1)) : m("", !0)
1787
1789
  ]),
1788
1790
  _: 1
1789
1791
  }, 8, ["header"]),
@@ -1820,13 +1822,13 @@ var Un = { class: "flex flex-col" }, Wn = {
1820
1822
  !_(w) && _(h).length ? (o(), x("div", {
1821
1823
  key: 3,
1822
1824
  class: u(["flex min-h-0 flex-col", { "mt-6": _(g).length }])
1823
- }, [T("span", ir, s(e.$t("views.devices.status_discovered")), 1), A(r, { class: "cui-card" }, {
1824
- content: y(() => [_(b).length ? (o(), x("div", ar, [A(P, {
1825
+ }, [T("span", ar, s(e.$t("views.devices.status_discovered")), 1), A(r, { class: "cui-card" }, {
1826
+ content: y(() => [_(b).length ? (o(), x("div", or, [A(F, {
1825
1827
  value: _(b),
1826
1828
  "striped-rows": "",
1827
1829
  pt: d,
1828
1830
  class: "w-full",
1829
- onRowClick: t[1] ||= (e) => re(e.data)
1831
+ onRowClick: t[1] ||= (e) => ne(e.data)
1830
1832
  }, {
1831
1833
  default: y(() => [
1832
1834
  A(O, {
@@ -1834,7 +1836,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1834
1836
  "header-class": "p-2 pl-4 w-5 max-w-5",
1835
1837
  class: "p-2 pl-4 w-5 max-w-5"
1836
1838
  }, {
1837
- body: y(({ data: e }) => [T("div", or, [E(A(v, { style: S({ background: te(e.status) }) }, null, 8, ["style"]), [[W, { value: N(e.status) }]])])]),
1839
+ body: y(({ data: e }) => [T("div", sr, [E(A(v, { style: S({ background: te(e.status) }) }, null, 8, ["style"]), [[U, { value: N(e.status) }]])])]),
1838
1840
  _: 1
1839
1841
  }),
1840
1842
  A(O, {
@@ -1843,7 +1845,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1843
1845
  "header-class": "p-2",
1844
1846
  class: "p-2 w-full min-w-[200px] max-w-0"
1845
1847
  }, {
1846
- body: y(({ data: t }) => [T("div", { class: u(["font-bold text-color truncate", V(t)]) }, s(t.name), 3), T("div", { class: u(["text-xs text-muted truncate", V(t)]) }, s(t.manufacturer || e.$t("views.devices.unknown")) + " · " + s(t.model || e.$t("views.devices.unknown")), 3)]),
1848
+ body: y(({ data: t }) => [T("div", { class: u(["font-bold text-color truncate", B(t)]) }, s(t.name), 3), T("div", { class: u(["text-xs text-muted truncate", B(t)]) }, s(t.manufacturer || e.$t("views.devices.unknown")) + " · " + s(t.model || e.$t("views.devices.unknown")), 3)]),
1847
1849
  _: 1
1848
1850
  }, 8, ["header"]),
1849
1851
  A(O, {
@@ -1854,7 +1856,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1854
1856
  }, {
1855
1857
  body: y(({ data: e }) => [e.address ? (o(), x("span", {
1856
1858
  key: 0,
1857
- class: u(["text-xs text-muted whitespace-nowrap", V(e)])
1859
+ class: u(["text-xs text-muted whitespace-nowrap", B(e)])
1858
1860
  }, s(e.address), 3)) : m("", !0)]),
1859
1861
  _: 1
1860
1862
  }, 8, ["header"]),
@@ -1866,7 +1868,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1866
1868
  }, {
1867
1869
  body: y(({ data: e }) => [A(M, {
1868
1870
  label: e.provider,
1869
- class: u(["text-xs whitespace-nowrap", V(e)])
1871
+ class: u(["text-xs whitespace-nowrap", B(e)])
1870
1872
  }, null, 8, ["label", "class"])]),
1871
1873
  _: 1
1872
1874
  }, 8, ["header"]),
@@ -1875,21 +1877,21 @@ var Un = { class: "flex flex-col" }, Wn = {
1875
1877
  "header-class": "p-2 pr-4 w-12",
1876
1878
  class: "p-2 pr-4 w-12"
1877
1879
  }, {
1878
- body: y(({ data: t }) => [T("div", sr, [F(t) ? E((o(), p(l, {
1880
+ body: y(({ data: t }) => [T("div", cr, [P(t) ? E((o(), p(l, {
1879
1881
  key: 1,
1880
1882
  text: "",
1881
1883
  rounded: "",
1882
1884
  class: "cui-icon-md",
1883
1885
  onClick: (e) => z(e, t)
1884
1886
  }, {
1885
- icon: y(() => [A(_(Le), {
1887
+ icon: y(() => [A(_(ze), {
1886
1888
  width: "100%",
1887
1889
  height: "100%",
1888
1890
  class: "text-muted"
1889
1891
  })]),
1890
1892
  _: 1
1891
1893
  }, 8, ["onClick"])), [[
1892
- W,
1894
+ U,
1893
1895
  { value: e.$t("views.devices.unhide") },
1894
1896
  void 0,
1895
1897
  { left: !0 }
@@ -1901,14 +1903,14 @@ var Un = { class: "flex flex-col" }, Wn = {
1901
1903
  class: "cui-icon-md",
1902
1904
  onClick: (e) => R(e, t)
1903
1905
  }, {
1904
- icon: y(() => [A(_(Re), {
1906
+ icon: y(() => [A(_(Be), {
1905
1907
  width: "100%",
1906
1908
  height: "100%",
1907
1909
  class: "text-muted"
1908
1910
  })]),
1909
1911
  _: 1
1910
1912
  }, 8, ["onClick"])), [[
1911
- W,
1913
+ U,
1912
1914
  { value: e.$t("views.devices.hide") },
1913
1915
  void 0,
1914
1916
  { left: !0 }
@@ -1917,44 +1919,44 @@ var Un = { class: "flex flex-col" }, Wn = {
1917
1919
  })
1918
1920
  ]),
1919
1921
  _: 1
1920
- }, 8, ["value"])])) : (o(), x("div", cr, [_(D) ? (o(), p(I, {
1922
+ }, 8, ["value"])])) : (o(), x("div", lr, [_(D) ? (o(), p(ie, {
1921
1923
  key: 0,
1922
1924
  width: "24px",
1923
1925
  height: "24px",
1924
1926
  class: "text-muted"
1925
- })) : (o(), p(H, {
1927
+ })) : (o(), p(V, {
1926
1928
  key: 1,
1927
1929
  width: "32px",
1928
1930
  height: "32px",
1929
1931
  class: "text-muted"
1930
- })), T("span", lr, s(_(D) ? e.$t("views.devices.scanning") : e.$t("views.devices.no_discovered")), 1)])), T("div", ur, [
1932
+ })), T("span", ur, s(_(D) ? e.$t("views.devices.scanning") : e.$t("views.devices.no_discovered")), 1)])), T("div", dr, [
1931
1933
  t[2] ||= T("div", { class: "ml-auto" }, null, -1),
1932
1934
  _(j) > 0 ? (o(), p(l, {
1933
1935
  key: 0,
1934
1936
  severity: "secondary",
1935
1937
  class: "cui-button-medium",
1936
1938
  label: _(k) ? e.$t("views.devices.hide_hidden") : `${e.$t("views.devices.show_hidden")} (${_(j)})`,
1937
- onClick: B
1939
+ onClick: ae
1938
1940
  }, null, 8, ["label"])) : m("", !0),
1939
1941
  A(l, {
1940
1942
  severity: "secondary",
1941
1943
  class: "cui-button-medium",
1942
1944
  label: e.$t("views.devices.rescan"),
1943
1945
  loading: _(D),
1944
- onClick: ie
1946
+ onClick: I
1945
1947
  }, null, 8, ["label", "loading"])
1946
1948
  ])]),
1947
1949
  _: 1
1948
1950
  })], 2)) : m("", !0)
1949
- ], 64)) : (o(), x("div", Gn, [A(r, { class: "cui-card" }, {
1951
+ ], 64)) : (o(), x("div", Kn, [A(r, { class: "cui-card" }, {
1950
1952
  content: y(() => [A(n)]),
1951
1953
  _: 1
1952
1954
  })])),
1953
- ("hasPermission" in e ? e.hasPermission : _(se))(void 0, "admin") ? (o(), p(U, {
1955
+ ("hasPermission" in e ? e.hasPermission : _(oe))(void 0, "admin") ? (o(), p(H, {
1954
1956
  key: 3,
1955
1957
  "tooltip-props": { value: e.$t("views.cameras.add_camera") },
1956
1958
  "button-props": { class: "text-white" },
1957
- icon: _(Fe),
1959
+ icon: _(Le),
1958
1960
  "icon-props": {
1959
1961
  width: "30px",
1960
1962
  height: "30px"
@@ -1966,4 +1968,4 @@ var Un = { class: "flex flex-col" }, Wn = {
1966
1968
  }
1967
1969
  }), [["__scopeId", "data-v-e79311c0"]]);
1968
1970
  //#endregion
1969
- export { dr as default };
1971
+ export { fr as default };