@tak-ps/cloudtak 12.54.0

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 (483) hide show
  1. package/README.md +34 -0
  2. package/dist/types/plugin.d.ts +99 -0
  3. package/dist/types/src/App.vue.d.ts +5 -0
  4. package/dist/types/src/base/chatroom-chats.d.ts +17 -0
  5. package/dist/types/src/base/chatroom.d.ts +47 -0
  6. package/dist/types/src/base/cot.d.ts +94 -0
  7. package/dist/types/src/base/database.d.ts +115 -0
  8. package/dist/types/src/base/events.d.ts +30 -0
  9. package/dist/types/src/base/filter.d.ts +41 -0
  10. package/dist/types/src/base/handler.d.ts +11 -0
  11. package/dist/types/src/base/icon.d.ts +4 -0
  12. package/dist/types/src/base/notification.d.ts +37 -0
  13. package/dist/types/src/base/overlay.d.ts +94 -0
  14. package/dist/types/src/base/subscription-feature.d.ts +49 -0
  15. package/dist/types/src/base/subscription-log.d.ts +32 -0
  16. package/dist/types/src/base/subscription.d.ts +115 -0
  17. package/dist/types/src/base/utils/styles.d.ts +11 -0
  18. package/dist/types/src/base/validators.d.ts +9 -0
  19. package/dist/types/src/components/Admin/AdminImports.vue.d.ts +3 -0
  20. package/dist/types/src/components/Admin/AdminLayers.vue.d.ts +3 -0
  21. package/dist/types/src/components/Admin/AdminMissionTemplate.vue.d.ts +3 -0
  22. package/dist/types/src/components/Admin/AdminMissionTemplateLog.vue.d.ts +3 -0
  23. package/dist/types/src/components/Admin/AdminMissionTemplates.vue.d.ts +3 -0
  24. package/dist/types/src/components/Admin/AdminOverlays.vue.d.ts +3 -0
  25. package/dist/types/src/components/Admin/AdminPalette.vue.d.ts +3 -0
  26. package/dist/types/src/components/Admin/AdminPaletteFeature.vue.d.ts +3 -0
  27. package/dist/types/src/components/Admin/AdminPalettes.vue.d.ts +3 -0
  28. package/dist/types/src/components/Admin/AdminServer.vue.d.ts +3 -0
  29. package/dist/types/src/components/Admin/AdminTasks.vue.d.ts +3 -0
  30. package/dist/types/src/components/Admin/AdminUser.vue.d.ts +3 -0
  31. package/dist/types/src/components/Admin/AdminUsers.vue.d.ts +3 -0
  32. package/dist/types/src/components/Admin/AdminVideos.vue.d.ts +3 -0
  33. package/dist/types/src/components/Admin/Server/ServerConnection.vue.d.ts +3 -0
  34. package/dist/types/src/components/Admin/Server/ServerInjectorModal.vue.d.ts +11 -0
  35. package/dist/types/src/components/Admin/Server/ServerInjectors.vue.d.ts +3 -0
  36. package/dist/types/src/components/Admin/Server/ServerPackages.vue.d.ts +3 -0
  37. package/dist/types/src/components/Admin/Server/ServerRepeaters.vue.d.ts +3 -0
  38. package/dist/types/src/components/Admin/Server/ServerVideos.vue.d.ts +3 -0
  39. package/dist/types/src/components/Admin/Tasks/AdminRawTasks.vue.d.ts +3 -0
  40. package/dist/types/src/components/Admin/Videos/AdminVideoLeases.vue.d.ts +3 -0
  41. package/dist/types/src/components/Admin/Videos/AdminVideoService.vue.d.ts +3 -0
  42. package/dist/types/src/components/Admin/Videos/VideoConfig.vue.d.ts +7 -0
  43. package/dist/types/src/components/Admin/Videos/VideoConfigPort.vue.d.ts +8 -0
  44. package/dist/types/src/components/CloudTAK/CoTView.vue.d.ts +3 -0
  45. package/dist/types/src/components/CloudTAK/CoordInput.vue.d.ts +7 -0
  46. package/dist/types/src/components/CloudTAK/DrawTools.vue.d.ts +3 -0
  47. package/dist/types/src/components/CloudTAK/FeatView.vue.d.ts +8 -0
  48. package/dist/types/src/components/CloudTAK/GeoJSONInput.vue.d.ts +24 -0
  49. package/dist/types/src/components/CloudTAK/MainMenu.vue.d.ts +9 -0
  50. package/dist/types/src/components/CloudTAK/MainMenuContents.vue.d.ts +16 -0
  51. package/dist/types/src/components/CloudTAK/Map.vue.d.ts +8 -0
  52. package/dist/types/src/components/CloudTAK/MapLoading.vue.d.ts +3 -0
  53. package/dist/types/src/components/CloudTAK/Menu/Debugger.vue.d.ts +3 -0
  54. package/dist/types/src/components/CloudTAK/Menu/MenuBasemaps.vue.d.ts +3 -0
  55. package/dist/types/src/components/CloudTAK/Menu/MenuChannels.vue.d.ts +3 -0
  56. package/dist/types/src/components/CloudTAK/Menu/MenuChats.vue.d.ts +3 -0
  57. package/dist/types/src/components/CloudTAK/Menu/MenuConnections.vue.d.ts +3 -0
  58. package/dist/types/src/components/CloudTAK/Menu/MenuContacts.vue.d.ts +3 -0
  59. package/dist/types/src/components/CloudTAK/Menu/MenuFeatures.vue.d.ts +3 -0
  60. package/dist/types/src/components/CloudTAK/Menu/MenuFeaturesDeleted.vue.d.ts +3 -0
  61. package/dist/types/src/components/CloudTAK/Menu/MenuFiles.vue.d.ts +3 -0
  62. package/dist/types/src/components/CloudTAK/Menu/MenuImport.vue.d.ts +3 -0
  63. package/dist/types/src/components/CloudTAK/Menu/MenuImports.vue.d.ts +3 -0
  64. package/dist/types/src/components/CloudTAK/Menu/MenuItemCard.vue.d.ts +101 -0
  65. package/dist/types/src/components/CloudTAK/Menu/MenuMission.vue.d.ts +3 -0
  66. package/dist/types/src/components/CloudTAK/Menu/MenuMissions.vue.d.ts +3 -0
  67. package/dist/types/src/components/CloudTAK/Menu/MenuOverlayExplorer.vue.d.ts +3 -0
  68. package/dist/types/src/components/CloudTAK/Menu/MenuOverlays.vue.d.ts +3 -0
  69. package/dist/types/src/components/CloudTAK/Menu/MenuPackage.vue.d.ts +3 -0
  70. package/dist/types/src/components/CloudTAK/Menu/MenuPackages.vue.d.ts +3 -0
  71. package/dist/types/src/components/CloudTAK/Menu/MenuRoutes.vue.d.ts +3 -0
  72. package/dist/types/src/components/CloudTAK/Menu/MenuRoutesNew.vue.d.ts +3 -0
  73. package/dist/types/src/components/CloudTAK/Menu/MenuSettings.vue.d.ts +3 -0
  74. package/dist/types/src/components/CloudTAK/Menu/MenuSettingsCallsign.vue.d.ts +3 -0
  75. package/dist/types/src/components/CloudTAK/Menu/MenuSettingsDisplay.vue.d.ts +3 -0
  76. package/dist/types/src/components/CloudTAK/Menu/MenuVideos.vue.d.ts +3 -0
  77. package/dist/types/src/components/CloudTAK/Menu/MenuVideosRemote.vue.d.ts +3 -0
  78. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionContents.vue.d.ts +11 -0
  79. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionCreate.vue.d.ts +7 -0
  80. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionInfo.vue.d.ts +11 -0
  81. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionInviteModal.vue.d.ts +17 -0
  82. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionLayerCreate.vue.d.ts +13 -0
  83. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionLayerEdit.vue.d.ts +15 -0
  84. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionLayerTree.vue.d.ts +15 -0
  85. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionLayers.vue.d.ts +8 -0
  86. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionLog.vue.d.ts +9 -0
  87. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionLogs.vue.d.ts +7 -0
  88. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionTimeline.vue.d.ts +7 -0
  89. package/dist/types/src/components/CloudTAK/Menu/Mission/MissionUsers.vue.d.ts +7 -0
  90. package/dist/types/src/components/CloudTAK/Menu/Mission/PendingInvites.vue.d.ts +11 -0
  91. package/dist/types/src/components/CloudTAK/Menu/Overlays/TreeMission.vue.d.ts +7 -0
  92. package/dist/types/src/components/CloudTAK/Menu/Overlays/TreeVector.vue.d.ts +13 -0
  93. package/dist/types/src/components/CloudTAK/Menu/Videos/VideoLeaseModal.vue.d.ts +16 -0
  94. package/dist/types/src/components/CloudTAK/Menu/Videos/VideosRemoteFeed.vue.d.ts +13 -0
  95. package/dist/types/src/components/CloudTAK/Notifications.vue.d.ts +3 -0
  96. package/dist/types/src/components/CloudTAK/Query/Magnetic.vue.d.ts +7 -0
  97. package/dist/types/src/components/CloudTAK/Query/Reverse.vue.d.ts +8 -0
  98. package/dist/types/src/components/CloudTAK/Query/Sun.vue.d.ts +7 -0
  99. package/dist/types/src/components/CloudTAK/Query/Weather.vue.d.ts +7 -0
  100. package/dist/types/src/components/CloudTAK/QueryView.vue.d.ts +3 -0
  101. package/dist/types/src/components/CloudTAK/RangeInput.vue.d.ts +7 -0
  102. package/dist/types/src/components/CloudTAK/RangeRingsInput.vue.d.ts +7 -0
  103. package/dist/types/src/components/CloudTAK/util/Breadcrumb.vue.d.ts +6 -0
  104. package/dist/types/src/components/CloudTAK/util/ChannelInfo.vue.d.ts +15 -0
  105. package/dist/types/src/components/CloudTAK/util/ContactPuck.vue.d.ts +7 -0
  106. package/dist/types/src/components/CloudTAK/util/Coordinate.vue.d.ts +67 -0
  107. package/dist/types/src/components/CloudTAK/util/CoordinateType.vue.d.ts +27 -0
  108. package/dist/types/src/components/CloudTAK/util/CopyButton.vue.d.ts +32 -0
  109. package/dist/types/src/components/CloudTAK/util/CopyField.vue.d.ts +122 -0
  110. package/dist/types/src/components/CloudTAK/util/DrawOverlay.vue.d.ts +3 -0
  111. package/dist/types/src/components/CloudTAK/util/EmptyInfo.vue.d.ts +24 -0
  112. package/dist/types/src/components/CloudTAK/util/FeatureIcon.vue.d.ts +23 -0
  113. package/dist/types/src/components/CloudTAK/util/FeatureRow.vue.d.ts +81 -0
  114. package/dist/types/src/components/CloudTAK/util/FloatingAttachment.vue.d.ts +17 -0
  115. package/dist/types/src/components/CloudTAK/util/FloatingVideo.vue.d.ts +27 -0
  116. package/dist/types/src/components/CloudTAK/util/GroupSelect.vue.d.ts +14 -0
  117. package/dist/types/src/components/CloudTAK/util/JSONModal.vue.d.ts +27 -0
  118. package/dist/types/src/components/CloudTAK/util/Keywords.vue.d.ts +6 -0
  119. package/dist/types/src/components/CloudTAK/util/LineLength.vue.d.ts +24 -0
  120. package/dist/types/src/components/CloudTAK/util/MenuTemplate.vue.d.ts +71 -0
  121. package/dist/types/src/components/CloudTAK/util/MultipleSelect.vue.d.ts +7 -0
  122. package/dist/types/src/components/CloudTAK/util/NotificationIcon.vue.d.ts +10 -0
  123. package/dist/types/src/components/CloudTAK/util/NotificationToast.vue.d.ts +13 -0
  124. package/dist/types/src/components/CloudTAK/util/PolygonArea.vue.d.ts +24 -0
  125. package/dist/types/src/components/CloudTAK/util/PropertyBattery.vue.d.ts +13 -0
  126. package/dist/types/src/components/CloudTAK/util/PropertyBearing.vue.d.ts +58 -0
  127. package/dist/types/src/components/CloudTAK/util/PropertyCreator.vue.d.ts +7 -0
  128. package/dist/types/src/components/CloudTAK/util/PropertyDistance.vue.d.ts +54 -0
  129. package/dist/types/src/components/CloudTAK/util/PropertyElevation.vue.d.ts +32 -0
  130. package/dist/types/src/components/CloudTAK/util/PropertyEmail.vue.d.ts +13 -0
  131. package/dist/types/src/components/CloudTAK/util/PropertyLinks.vue.d.ts +14 -0
  132. package/dist/types/src/components/CloudTAK/util/PropertyMetadata.vue.d.ts +7 -0
  133. package/dist/types/src/components/CloudTAK/util/PropertyMilSym.vue.d.ts +25 -0
  134. package/dist/types/src/components/CloudTAK/util/PropertyPhone.vue.d.ts +13 -0
  135. package/dist/types/src/components/CloudTAK/util/PropertySpeed.vue.d.ts +23 -0
  136. package/dist/types/src/components/CloudTAK/util/PropertyStyle.vue.d.ts +7 -0
  137. package/dist/types/src/components/CloudTAK/util/PropertyTimes.vue.d.ts +7 -0
  138. package/dist/types/src/components/CloudTAK/util/PropertyType.vue.d.ts +27 -0
  139. package/dist/types/src/components/CloudTAK/util/SearchBox.vue.d.ts +37 -0
  140. package/dist/types/src/components/CloudTAK/util/SelectFeats.vue.d.ts +7 -0
  141. package/dist/types/src/components/CloudTAK/util/SettingsCallsign.vue.d.ts +28 -0
  142. package/dist/types/src/components/CloudTAK/util/Share.vue.d.ts +14 -0
  143. package/dist/types/src/components/CloudTAK/util/ShareToMission.vue.d.ts +53 -0
  144. package/dist/types/src/components/CloudTAK/util/ShareToPackage.vue.d.ts +62 -0
  145. package/dist/types/src/components/CloudTAK/util/SlideDownHeader.vue.d.ts +41 -0
  146. package/dist/types/src/components/CloudTAK/util/StandardItem.vue.d.ts +18 -0
  147. package/dist/types/src/components/CloudTAK/util/Subscriptions.vue.d.ts +7 -0
  148. package/dist/types/src/components/CloudTAK/util/VideoLeaseSourceType.vue.d.ts +6 -0
  149. package/dist/types/src/components/CloudTAK/util/WarnChannels.vue.d.ts +7 -0
  150. package/dist/types/src/components/CloudTAK/util/WarnConfiguration.vue.d.ts +7 -0
  151. package/dist/types/src/components/Configure.vue.d.ts +3 -0
  152. package/dist/types/src/components/ETL/Connection/AgencyBadge.vue.d.ts +8 -0
  153. package/dist/types/src/components/ETL/Connection/ConnectionFiles.vue.d.ts +3 -0
  154. package/dist/types/src/components/ETL/Connection/ConnectionTokens.vue.d.ts +3 -0
  155. package/dist/types/src/components/ETL/Connection/ConnectionVideos.vue.d.ts +3 -0
  156. package/dist/types/src/components/ETL/Connection/StatusDot.vue.d.ts +13 -0
  157. package/dist/types/src/components/ETL/Connection/TokenModal.vue.d.ts +16 -0
  158. package/dist/types/src/components/ETL/Connection.vue.d.ts +3 -0
  159. package/dist/types/src/components/ETL/ConnectionCard.vue.d.ts +16 -0
  160. package/dist/types/src/components/ETL/Connections.vue.d.ts +3 -0
  161. package/dist/types/src/components/ETL/Data.vue.d.ts +3 -0
  162. package/dist/types/src/components/ETL/Layer/LayerIncomingConfig.vue.d.ts +27 -0
  163. package/dist/types/src/components/ETL/Layer/LayerOutgoingConfig.vue.d.ts +27 -0
  164. package/dist/types/src/components/ETL/Layer/utils/QueryInput.vue.d.ts +56 -0
  165. package/dist/types/src/components/ETL/Layer/utils/StatusDot.vue.d.ts +7 -0
  166. package/dist/types/src/components/ETL/Layer.vue.d.ts +3 -0
  167. package/dist/types/src/components/Home.vue.d.ts +13 -0
  168. package/dist/types/src/components/Loading.vue.d.ts +3 -0
  169. package/dist/types/src/components/Login.vue.d.ts +7 -0
  170. package/dist/types/src/components/LostUser.vue.d.ts +3 -0
  171. package/dist/types/src/components/PageFooter.vue.d.ts +3 -0
  172. package/dist/types/src/components/ServerAdmin.vue.d.ts +3 -0
  173. package/dist/types/src/components/VideoWall/Main.vue.d.ts +3 -0
  174. package/dist/types/src/components/VideoWall.vue.d.ts +13 -0
  175. package/dist/types/src/components/util/GroupSelect.vue.d.ts +14 -0
  176. package/dist/types/src/components/util/InitialAuthor.vue.d.ts +6 -0
  177. package/dist/types/src/components/util/StatusDot.vue.d.ts +8 -0
  178. package/dist/types/src/components/util/Upload.vue.d.ts +46 -0
  179. package/dist/types/src/components/util/UploadLogo.vue.d.ts +14 -0
  180. package/dist/types/src/main.d.ts +1 -0
  181. package/dist/types/src/pages/admin/main.d.ts +1 -0
  182. package/dist/types/src/pages/connection/main.d.ts +1 -0
  183. package/dist/types/src/pages/docs/App.vue.d.ts +4 -0
  184. package/dist/types/src/pages/docs/main.d.ts +1 -0
  185. package/dist/types/src/pages/video/main.d.ts +1 -0
  186. package/dist/types/src/std.d.ts +19 -0
  187. package/dist/types/src/stores/brand.d.ts +7 -0
  188. package/dist/types/src/stores/float.d.ts +42 -0
  189. package/dist/types/src/stores/map.d.ts +115 -0
  190. package/dist/types/src/stores/modules/draw.d.ts +35 -0
  191. package/dist/types/src/stores/modules/icons.d.ts +38 -0
  192. package/dist/types/src/stores/modules/menu.d.ts +34 -0
  193. package/dist/types/src/test/setup.d.ts +1 -0
  194. package/dist/types/src/timediff.d.ts +1 -0
  195. package/dist/types/src/types.d.ts +158 -0
  196. package/dist/types/src/video.d.ts +1 -0
  197. package/dist/types/src/workers/atlas-connection.d.ts +12 -0
  198. package/dist/types/src/workers/atlas-database.d.ts +134 -0
  199. package/dist/types/src/workers/atlas-profile.d.ts +39 -0
  200. package/dist/types/src/workers/atlas-team.d.ts +13 -0
  201. package/dist/types/src/workers/atlas.d.ts +19 -0
  202. package/package.json +97 -0
  203. package/src/App.vue +341 -0
  204. package/src/base/chatroom-chats.ts +124 -0
  205. package/src/base/chatroom.ts +202 -0
  206. package/src/base/cot.ts +625 -0
  207. package/src/base/database.ts +150 -0
  208. package/src/base/events.ts +43 -0
  209. package/src/base/filter.ts +163 -0
  210. package/src/base/handler.ts +67 -0
  211. package/src/base/icon.ts +16 -0
  212. package/src/base/notification.ts +163 -0
  213. package/src/base/overlay.ts +558 -0
  214. package/src/base/subscription-feature.ts +224 -0
  215. package/src/base/subscription-log.ts +174 -0
  216. package/src/base/subscription.ts +489 -0
  217. package/src/base/utils/styles.ts +430 -0
  218. package/src/base/validators.ts +66 -0
  219. package/src/components/Admin/AdminConfig.vue +487 -0
  220. package/src/components/Admin/AdminConnections.vue +195 -0
  221. package/src/components/Admin/AdminDatas.vue +165 -0
  222. package/src/components/Admin/AdminExport.vue +121 -0
  223. package/src/components/Admin/AdminImports.vue +222 -0
  224. package/src/components/Admin/AdminLayerTemplate.vue +91 -0
  225. package/src/components/Admin/AdminLayers.vue +301 -0
  226. package/src/components/Admin/AdminMissionTemplate.vue +259 -0
  227. package/src/components/Admin/AdminMissionTemplateLog.vue +273 -0
  228. package/src/components/Admin/AdminMissionTemplates.vue +189 -0
  229. package/src/components/Admin/AdminOverlays.vue +232 -0
  230. package/src/components/Admin/AdminOverlaysEdit.vue +355 -0
  231. package/src/components/Admin/AdminPalette.vue +214 -0
  232. package/src/components/Admin/AdminPaletteFeature.vue +208 -0
  233. package/src/components/Admin/AdminPalettes.vue +189 -0
  234. package/src/components/Admin/AdminServer.vue +143 -0
  235. package/src/components/Admin/AdminTasks.vue +60 -0
  236. package/src/components/Admin/AdminUser.vue +263 -0
  237. package/src/components/Admin/AdminUsers.vue +183 -0
  238. package/src/components/Admin/AdminVideos.vue +60 -0
  239. package/src/components/Admin/Server/ServerConnection.vue +322 -0
  240. package/src/components/Admin/Server/ServerInjectorModal.vue +125 -0
  241. package/src/components/Admin/Server/ServerInjectors.vue +104 -0
  242. package/src/components/Admin/Server/ServerPackages.vue +159 -0
  243. package/src/components/Admin/Server/ServerRepeaters.vue +105 -0
  244. package/src/components/Admin/Server/ServerVideos.vue +83 -0
  245. package/src/components/Admin/Tasks/AdminRawTasks.vue +148 -0
  246. package/src/components/Admin/Tasks/AdminTasks.vue +286 -0
  247. package/src/components/Admin/Videos/AdminVideoLeases.vue +198 -0
  248. package/src/components/Admin/Videos/AdminVideoService.vue +67 -0
  249. package/src/components/Admin/Videos/VideoConfig.vue +132 -0
  250. package/src/components/Admin/Videos/VideoConfigPath.vue +58 -0
  251. package/src/components/Admin/Videos/VideoConfigPort.vue +40 -0
  252. package/src/components/CloudTAK/CoTView.vue +915 -0
  253. package/src/components/CloudTAK/CoordInput.vue +110 -0
  254. package/src/components/CloudTAK/DrawTools.vue +200 -0
  255. package/src/components/CloudTAK/FeatView.vue +242 -0
  256. package/src/components/CloudTAK/GeoJSONInput.vue +226 -0
  257. package/src/components/CloudTAK/MainMenu.vue +190 -0
  258. package/src/components/CloudTAK/MainMenuContents.vue +360 -0
  259. package/src/components/CloudTAK/Map.vue +972 -0
  260. package/src/components/CloudTAK/MapLoading.vue +31 -0
  261. package/src/components/CloudTAK/Menu/Basemaps/EditModal.vue +427 -0
  262. package/src/components/CloudTAK/Menu/Debugger.vue +118 -0
  263. package/src/components/CloudTAK/Menu/Iconset/EditModal.vue +118 -0
  264. package/src/components/CloudTAK/Menu/MenuBasemaps.vue +410 -0
  265. package/src/components/CloudTAK/Menu/MenuChannels.vue +206 -0
  266. package/src/components/CloudTAK/Menu/MenuChat.vue +222 -0
  267. package/src/components/CloudTAK/Menu/MenuChats.vue +167 -0
  268. package/src/components/CloudTAK/Menu/MenuConnections.vue +166 -0
  269. package/src/components/CloudTAK/Menu/MenuContacts.vue +245 -0
  270. package/src/components/CloudTAK/Menu/MenuFeatures.vue +718 -0
  271. package/src/components/CloudTAK/Menu/MenuFeaturesDeleted.vue +217 -0
  272. package/src/components/CloudTAK/Menu/MenuFiles.vue +433 -0
  273. package/src/components/CloudTAK/Menu/MenuIcon.vue +236 -0
  274. package/src/components/CloudTAK/Menu/MenuIconset.vue +128 -0
  275. package/src/components/CloudTAK/Menu/MenuIconsets.vue +266 -0
  276. package/src/components/CloudTAK/Menu/MenuImport.vue +198 -0
  277. package/src/components/CloudTAK/Menu/MenuImports.vue +199 -0
  278. package/src/components/CloudTAK/Menu/MenuItemCard.vue +240 -0
  279. package/src/components/CloudTAK/Menu/MenuMission.vue +324 -0
  280. package/src/components/CloudTAK/Menu/MenuMissions.vue +334 -0
  281. package/src/components/CloudTAK/Menu/MenuOverlayExplorer.vue +434 -0
  282. package/src/components/CloudTAK/Menu/MenuOverlays.vue +560 -0
  283. package/src/components/CloudTAK/Menu/MenuPackage.vue +340 -0
  284. package/src/components/CloudTAK/Menu/MenuPackages.vue +193 -0
  285. package/src/components/CloudTAK/Menu/MenuRoutes.vue +186 -0
  286. package/src/components/CloudTAK/Menu/MenuRoutesNew.vue +193 -0
  287. package/src/components/CloudTAK/Menu/MenuSettings.vue +95 -0
  288. package/src/components/CloudTAK/Menu/MenuSettingsCallsign.vue +12 -0
  289. package/src/components/CloudTAK/Menu/MenuSettingsDisplay.vue +144 -0
  290. package/src/components/CloudTAK/Menu/MenuSettingsTokens.vue +83 -0
  291. package/src/components/CloudTAK/Menu/MenuVideos.vue +436 -0
  292. package/src/components/CloudTAK/Menu/MenuVideosRemote.vue +203 -0
  293. package/src/components/CloudTAK/Menu/Mission/MissionContents.vue +211 -0
  294. package/src/components/CloudTAK/Menu/Mission/MissionCreate.vue +372 -0
  295. package/src/components/CloudTAK/Menu/Mission/MissionInfo.vue +331 -0
  296. package/src/components/CloudTAK/Menu/Mission/MissionInviteModal.vue +107 -0
  297. package/src/components/CloudTAK/Menu/Mission/MissionLayerCreate.vue +77 -0
  298. package/src/components/CloudTAK/Menu/Mission/MissionLayerEdit.vue +77 -0
  299. package/src/components/CloudTAK/Menu/Mission/MissionLayerTree.vue +194 -0
  300. package/src/components/CloudTAK/Menu/Mission/MissionLayers.vue +157 -0
  301. package/src/components/CloudTAK/Menu/Mission/MissionLog.vue +170 -0
  302. package/src/components/CloudTAK/Menu/Mission/MissionLogs.vue +194 -0
  303. package/src/components/CloudTAK/Menu/Mission/MissionTimeline.vue +142 -0
  304. package/src/components/CloudTAK/Menu/Mission/MissionUsers.vue +74 -0
  305. package/src/components/CloudTAK/Menu/Mission/PendingInvites.vue +130 -0
  306. package/src/components/CloudTAK/Menu/Overlays/DeleteModal.vue +57 -0
  307. package/src/components/CloudTAK/Menu/Overlays/TreeCots.vue +497 -0
  308. package/src/components/CloudTAK/Menu/Overlays/TreeMission.vue +32 -0
  309. package/src/components/CloudTAK/Menu/Overlays/TreeVector.vue +113 -0
  310. package/src/components/CloudTAK/Menu/Settings/TokenModal.vue +110 -0
  311. package/src/components/CloudTAK/Menu/Videos/VideoLeaseModal.vue +753 -0
  312. package/src/components/CloudTAK/Menu/Videos/VideosRemoteFeed.vue +75 -0
  313. package/src/components/CloudTAK/Notifications.vue +195 -0
  314. package/src/components/CloudTAK/Query/Magnetic.vue +80 -0
  315. package/src/components/CloudTAK/Query/Reverse.vue +65 -0
  316. package/src/components/CloudTAK/Query/Sun.vue +178 -0
  317. package/src/components/CloudTAK/Query/Weather.vue +195 -0
  318. package/src/components/CloudTAK/QueryView.vue +134 -0
  319. package/src/components/CloudTAK/RadialMenu/LICENSE +21 -0
  320. package/src/components/CloudTAK/RadialMenu/README.md +63 -0
  321. package/src/components/CloudTAK/RadialMenu/RadialMenu.css +85 -0
  322. package/src/components/CloudTAK/RadialMenu/RadialMenu.js +534 -0
  323. package/src/components/CloudTAK/RadialMenu/RadialMenu.vue +257 -0
  324. package/src/components/CloudTAK/RangeInput.vue +155 -0
  325. package/src/components/CloudTAK/RangeRingsInput.vue +269 -0
  326. package/src/components/CloudTAK/util/Breadcrumb.vue +85 -0
  327. package/src/components/CloudTAK/util/ChannelInfo.vue +25 -0
  328. package/src/components/CloudTAK/util/Contact.vue +131 -0
  329. package/src/components/CloudTAK/util/ContactPuck.vue +40 -0
  330. package/src/components/CloudTAK/util/Coordinate.vue +313 -0
  331. package/src/components/CloudTAK/util/CoordinateType.vue +134 -0
  332. package/src/components/CloudTAK/util/CopyButton.vue +67 -0
  333. package/src/components/CloudTAK/util/CopyField.vue +286 -0
  334. package/src/components/CloudTAK/util/DrawOverlay.vue +254 -0
  335. package/src/components/CloudTAK/util/EmptyInfo.vue +71 -0
  336. package/src/components/CloudTAK/util/FeatureIcon.vue +134 -0
  337. package/src/components/CloudTAK/util/FeatureRow.vue +206 -0
  338. package/src/components/CloudTAK/util/FloatingAttachment.vue +191 -0
  339. package/src/components/CloudTAK/util/FloatingVideo.vue +654 -0
  340. package/src/components/CloudTAK/util/GenericSelect.vue +125 -0
  341. package/src/components/CloudTAK/util/GroupSelect.vue +129 -0
  342. package/src/components/CloudTAK/util/Icons.vue +146 -0
  343. package/src/components/CloudTAK/util/JSONModal.vue +57 -0
  344. package/src/components/CloudTAK/util/Keywords.vue +31 -0
  345. package/src/components/CloudTAK/util/LineLength.vue +121 -0
  346. package/src/components/CloudTAK/util/MenuItem.vue +21 -0
  347. package/src/components/CloudTAK/util/MenuTemplate.vue +137 -0
  348. package/src/components/CloudTAK/util/MultipleSelect.vue +103 -0
  349. package/src/components/CloudTAK/util/NotificationIcon.vue +50 -0
  350. package/src/components/CloudTAK/util/NotificationToast.vue +125 -0
  351. package/src/components/CloudTAK/util/PolygonArea.vue +109 -0
  352. package/src/components/CloudTAK/util/PropertyAttachments.vue +224 -0
  353. package/src/components/CloudTAK/util/PropertyBattery.vue +44 -0
  354. package/src/components/CloudTAK/util/PropertyBearing.vue +148 -0
  355. package/src/components/CloudTAK/util/PropertyCreator.vue +61 -0
  356. package/src/components/CloudTAK/util/PropertyDistance.vue +182 -0
  357. package/src/components/CloudTAK/util/PropertyElevation.vue +84 -0
  358. package/src/components/CloudTAK/util/PropertyEmail.vue +44 -0
  359. package/src/components/CloudTAK/util/PropertyLinks.vue +148 -0
  360. package/src/components/CloudTAK/util/PropertyMetadata.vue +53 -0
  361. package/src/components/CloudTAK/util/PropertyMilSym.vue +62 -0
  362. package/src/components/CloudTAK/util/PropertyPhone.vue +61 -0
  363. package/src/components/CloudTAK/util/PropertySensor.vue +129 -0
  364. package/src/components/CloudTAK/util/PropertySpeed.vue +91 -0
  365. package/src/components/CloudTAK/util/PropertyStyle.vue +202 -0
  366. package/src/components/CloudTAK/util/PropertyTimes.vue +95 -0
  367. package/src/components/CloudTAK/util/PropertyType.vue +274 -0
  368. package/src/components/CloudTAK/util/SearchBox.vue +314 -0
  369. package/src/components/CloudTAK/util/SelectFeats.vue +190 -0
  370. package/src/components/CloudTAK/util/SettingsCallsign.vue +151 -0
  371. package/src/components/CloudTAK/util/Share.vue +496 -0
  372. package/src/components/CloudTAK/util/ShareToMission.vue +223 -0
  373. package/src/components/CloudTAK/util/ShareToPackage.vue +250 -0
  374. package/src/components/CloudTAK/util/SlideDownHeader.vue +92 -0
  375. package/src/components/CloudTAK/util/StandardItem.vue +42 -0
  376. package/src/components/CloudTAK/util/Subscriptions.vue +151 -0
  377. package/src/components/CloudTAK/util/TagEntry.vue +301 -0
  378. package/src/components/CloudTAK/util/UploadImport.vue +195 -0
  379. package/src/components/CloudTAK/util/VideoLeaseSourceType.vue +66 -0
  380. package/src/components/CloudTAK/util/WarnChannels.vue +56 -0
  381. package/src/components/CloudTAK/util/WarnConfiguration.vue +34 -0
  382. package/src/components/Configure.vue +259 -0
  383. package/src/components/ETL/Connection/AgencyBadge.vue +102 -0
  384. package/src/components/ETL/Connection/AgencySelect.vue +185 -0
  385. package/src/components/ETL/Connection/CertificateLogin.vue +75 -0
  386. package/src/components/ETL/Connection/CertificateMachineUser.vue +228 -0
  387. package/src/components/ETL/Connection/CertificateP12.vue +104 -0
  388. package/src/components/ETL/Connection/CertificateRaw.vue +50 -0
  389. package/src/components/ETL/Connection/ConnectionData.vue +174 -0
  390. package/src/components/ETL/Connection/ConnectionFiles.vue +182 -0
  391. package/src/components/ETL/Connection/ConnectionGroups.vue +181 -0
  392. package/src/components/ETL/Connection/ConnectionLayer.vue +180 -0
  393. package/src/components/ETL/Connection/ConnectionTokens.vue +147 -0
  394. package/src/components/ETL/Connection/ConnectionVideos.vue +151 -0
  395. package/src/components/ETL/Connection/Events.vue +88 -0
  396. package/src/components/ETL/Connection/StatusDot.vue +48 -0
  397. package/src/components/ETL/Connection/TokenModal.vue +136 -0
  398. package/src/components/ETL/Connection.vue +194 -0
  399. package/src/components/ETL/ConnectionCard.vue +265 -0
  400. package/src/components/ETL/ConnectionEdit.vue +448 -0
  401. package/src/components/ETL/Connections.vue +148 -0
  402. package/src/components/ETL/Data/DataFiles.vue +245 -0
  403. package/src/components/ETL/Data/DataGroups.vue +45 -0
  404. package/src/components/ETL/Data/DataLayer.vue +144 -0
  405. package/src/components/ETL/Data/Location.vue +238 -0
  406. package/src/components/ETL/Data.vue +259 -0
  407. package/src/components/ETL/DataEdit.vue +212 -0
  408. package/src/components/ETL/Layer/LayerAlarm.vue +307 -0
  409. package/src/components/ETL/Layer/LayerDeployment.vue +388 -0
  410. package/src/components/ETL/Layer/LayerEnvironment.vue +259 -0
  411. package/src/components/ETL/Layer/LayerIncomingConfig.vue +401 -0
  412. package/src/components/ETL/Layer/LayerIncomingEnvironmentArcGIS.vue +354 -0
  413. package/src/components/ETL/Layer/LayerIncomingSchema.vue +138 -0
  414. package/src/components/ETL/Layer/LayerIncomingStyles.vue +349 -0
  415. package/src/components/ETL/Layer/LayerOutgoingConfig.vue +204 -0
  416. package/src/components/ETL/Layer/LayerOutgoingEnvironmentArcGIS.vue +279 -0
  417. package/src/components/ETL/Layer/utils/QueryInput.vue +52 -0
  418. package/src/components/ETL/Layer/utils/Schema.vue +322 -0
  419. package/src/components/ETL/Layer/utils/SchemaModal.vue +77 -0
  420. package/src/components/ETL/Layer/utils/StatusDot.vue +38 -0
  421. package/src/components/ETL/Layer/utils/StyleLinkModal.vue +83 -0
  422. package/src/components/ETL/Layer/utils/StyleLinks.vue +139 -0
  423. package/src/components/ETL/Layer/utils/StyleSingle.vue +885 -0
  424. package/src/components/ETL/Layer/utils/StyleTemplate.vue +97 -0
  425. package/src/components/ETL/Layer/utils/TaskModal.vue +217 -0
  426. package/src/components/ETL/Layer.vue +560 -0
  427. package/src/components/ETL/LayerEdit.vue +276 -0
  428. package/src/components/ETL/Styling/Layer.vue +311 -0
  429. package/src/components/ETL/Styling/ObjectInput.vue +46 -0
  430. package/src/components/ETL/Styling/Style.vue +233 -0
  431. package/src/components/Home.vue +17 -0
  432. package/src/components/Loading.vue +42 -0
  433. package/src/components/Login.vue +198 -0
  434. package/src/components/LostUser.vue +31 -0
  435. package/src/components/PageFooter.vue +41 -0
  436. package/src/components/ServerAdmin.vue +408 -0
  437. package/src/components/VideoWall/Main.vue +79 -0
  438. package/src/components/VideoWall.vue +17 -0
  439. package/src/components/util/DataSelect.vue +148 -0
  440. package/src/components/util/EsriFilter.vue +140 -0
  441. package/src/components/util/EsriPortal.vue +422 -0
  442. package/src/components/util/EsriPortalCreate.vue +72 -0
  443. package/src/components/util/EsriServer.vue +368 -0
  444. package/src/components/util/GroupSelect.vue +166 -0
  445. package/src/components/util/IconSelect.vue +302 -0
  446. package/src/components/util/InitialAuthor.vue +28 -0
  447. package/src/components/util/LayerSelect.vue +162 -0
  448. package/src/components/util/LayerTaskSelect.vue +311 -0
  449. package/src/components/util/LayerTemplateSelect.vue +173 -0
  450. package/src/components/util/LoginModal.vue +110 -0
  451. package/src/components/util/PublicTilesSelect.vue +171 -0
  452. package/src/components/util/StatusDot.vue +31 -0
  453. package/src/components/util/TableFooter.vue +64 -0
  454. package/src/components/util/TableHeader.vue +127 -0
  455. package/src/components/util/Upload.vue +220 -0
  456. package/src/components/util/UploadCSV.vue +46 -0
  457. package/src/components/util/UploadLogo.vue +83 -0
  458. package/src/components/util/UploadP12.vue +93 -0
  459. package/src/components/util/UserSelect.vue +151 -0
  460. package/src/derived-types.d.ts +35243 -0
  461. package/src/main.ts +264 -0
  462. package/src/pages/admin/main.ts +208 -0
  463. package/src/pages/connection/main.ts +158 -0
  464. package/src/pages/docs/App.vue +19 -0
  465. package/src/pages/docs/main.ts +6 -0
  466. package/src/pages/video/main.ts +27 -0
  467. package/src/std.ts +152 -0
  468. package/src/stores/brand.ts +28 -0
  469. package/src/stores/float.ts +113 -0
  470. package/src/stores/map.ts +931 -0
  471. package/src/stores/modules/draw.ts +413 -0
  472. package/src/stores/modules/icons.ts +185 -0
  473. package/src/stores/modules/menu.ts +281 -0
  474. package/src/test/setup.ts +43 -0
  475. package/src/timediff.ts +33 -0
  476. package/src/types.ts +226 -0
  477. package/src/video.ts +27 -0
  478. package/src/vite-env.d.ts +9 -0
  479. package/src/workers/atlas-connection.ts +236 -0
  480. package/src/workers/atlas-database.ts +764 -0
  481. package/src/workers/atlas-profile.ts +374 -0
  482. package/src/workers/atlas-team.ts +90 -0
  483. package/src/workers/atlas.ts +81 -0
@@ -0,0 +1,654 @@
1
+ <template>
2
+ <div
3
+ ref='container'
4
+ class='position-absolute bg-dark rounded border resizable-content text-white video-container'
5
+ >
6
+ <div
7
+ style='height: 50px;'
8
+ class='d-flex align-items-center px-2 py-2 border-bottom border-secondary'
9
+ >
10
+ <div
11
+ ref='drag-handle'
12
+ class='cursor-pointer'
13
+ >
14
+ <IconGripVertical
15
+ :size='24'
16
+ stroke='1'
17
+ />
18
+ </div>
19
+
20
+ <StatusDot
21
+ v-if='active && active.metadata'
22
+ :status='active.metadata.active ? "success" : "unknown"'
23
+ :dark='true'
24
+ :title='active.metadata.active ? "Streaming" : "Unknown"'
25
+ :size='24'
26
+ />
27
+
28
+ <VideoLeaseSourceType
29
+ v-if='active && active.metadata'
30
+ :source-type='active.metadata.source_type'
31
+ :size='24'
32
+ />
33
+
34
+ <div
35
+ class='mx-2'
36
+ style='max-width: calc(100% - 100px);'
37
+ >
38
+ <div
39
+ class='text-sm text-truncate'
40
+ v-text='title'
41
+ />
42
+ <div
43
+ v-if='active && active.metadata && active.metadata.source_model'
44
+ class='subheader'
45
+ v-text='active.metadata.source_model'
46
+ />
47
+ </div>
48
+
49
+ <div class='btn-list ms-auto'>
50
+ <span
51
+ v-if='active && active.metadata'
52
+ class='watchers-info'
53
+ >
54
+ <IconUsersGroup
55
+ :size='24'
56
+ stroke='1'
57
+ />
58
+ <span v-text='active.metadata.watchers + 1' />
59
+ <span
60
+ class='ms-1 watcher-text'
61
+ v-text='active.metadata.watchers + 1 > 1 ? "Watchers" : "Watcher"'
62
+ />
63
+ </span>
64
+
65
+ <TablerIconButton
66
+ title='Close Video Player'
67
+ @click='emit("close")'
68
+ >
69
+ <IconX
70
+ :size='24'
71
+ stroke='1'
72
+ />
73
+ </TablerIconButton>
74
+ </div>
75
+ </div>
76
+ <div
77
+ class='modal-body'
78
+ :class='{ "modal-body--error": !!error }'
79
+ :style='`height: calc(100% - 50px)`'
80
+ >
81
+ <div
82
+ v-if='loading'
83
+ class='col-12 d-flex align-items-center justify-content-center'
84
+ >
85
+ <TablerLoading label='Loading Stream' />
86
+ </div>
87
+ <template v-else-if='error'>
88
+ <div class='error-state d-flex flex-column align-items-center justify-content-center text-center gap-3 h-100 w-100'>
89
+ <div class='row g-2 w-100'>
90
+ <TablerAlert
91
+ class='error-alert w-100'
92
+ title='Video Error'
93
+ :compact='true'
94
+ :err='error'
95
+ />
96
+ </div>
97
+
98
+ <div class='row g-2 w-100 error-actions'>
99
+ <div class='col-md-6'>
100
+ <TablerButton
101
+ class='w-100'
102
+ @click='$emit("close")'
103
+ >
104
+ Close Player
105
+ </TablerButton>
106
+ </div>
107
+ <div class='col-md-6'>
108
+ <TablerButton
109
+ class='w-100'
110
+ @click='requestLease'
111
+ >
112
+ Retry
113
+ </TablerButton>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ </template>
118
+ <template v-else-if='!video || !videoProtocols || !videoProtocols.hls'>
119
+ <TablerNone
120
+ label='HLS Streaming Protocol'
121
+ :create='false'
122
+ />
123
+ </template>
124
+ <template v-else>
125
+ <video
126
+ ref='videoTag'
127
+ class='w-100 h-100 live-video'
128
+ controls
129
+ autoplay
130
+ muted
131
+ />
132
+ </template>
133
+ </div>
134
+ </div>
135
+ </template>
136
+
137
+ <script setup lang='ts'>
138
+ /**
139
+ * FloatingVideo Component
140
+ *
141
+ * A draggable, resizable video player component for HLS live streaming.
142
+ * Features resilient error handling, automatic retry logic, and MediaMTX muxer restart recovery.
143
+ */
144
+
145
+ import { ref, computed, onMounted, onUnmounted, nextTick, useTemplateRef } from 'vue'
146
+ import { std, stdurl } from '../../../../src/std.ts';
147
+ import StatusDot from './../../util/StatusDot.vue';
148
+ import VideoLeaseSourceType from './VideoLeaseSourceType.vue';
149
+ import type { VideoLeaseResponse, VideoLeaseMetadata } from '../../../types.ts';
150
+ import Hls from 'hls.js'
151
+ import { useFloatStore } from '../../../stores/float.ts';
152
+ import type { VideoPane } from '../../../stores/float.ts';
153
+ import {
154
+ IconX,
155
+ IconUsersGroup,
156
+ IconGripVertical
157
+ } from '@tabler/icons-vue';
158
+ import {
159
+ TablerNone,
160
+ TablerAlert,
161
+ TablerLoading,
162
+ TablerButton,
163
+ TablerIconButton,
164
+ } from '@tak-ps/vue-tabler';
165
+
166
+ // Store for managing floating panes
167
+ const floatStore = useFloatStore();
168
+
169
+ // Component props
170
+ const props = defineProps({
171
+ title: {
172
+ type: String,
173
+ default: 'Video Stream'
174
+ },
175
+ uid: {
176
+ type: String,
177
+ required: true // Unique identifier for this video pane
178
+ }
179
+ });
180
+
181
+ // Template refs for DOM elements
182
+ const videoTag = useTemplateRef<HTMLVideoElement>('videoTag');
183
+ const container = useTemplateRef<HTMLElement>('container');
184
+ const dragHandle = useTemplateRef<HTMLElement>('drag-handle');
185
+
186
+ // Component events
187
+ const emit = defineEmits(['close']);
188
+
189
+ // UI state management
190
+ const loading = ref(true);
191
+ const error = ref<Error | undefined>();
192
+
193
+ // HLS retry logic state
194
+ const retryCount = ref(0);
195
+ const maxRetries = ref(3); // Maximum retry attempts before giving up
196
+
197
+ // HLS player instance
198
+ const player = ref<Hls | undefined>()
199
+
200
+ // Video streaming data
201
+ const video = ref(floatStore.panes.get(props.uid) as VideoPane);
202
+ const videoLease = ref<VideoLeaseResponse | undefined>(); // CloudTAK video lease
203
+ const videoProtocols = ref<VideoLeaseMetadata["protocols"] | undefined>(); // Available streaming protocols
204
+
205
+ // Drag and resize functionality
206
+ const observer = ref<ResizeObserver | undefined>(); // Watches for container resize events
207
+ const lastPosition = ref({ top: 0, left: 0 }) // Last mouse position during drag
208
+
209
+ // Active stream metadata
210
+ const active = ref();
211
+
212
+ // Computed title - uses stream metadata name if available, falls back to prop
213
+ const title = computed(() => {
214
+ if (active.value && active.value.metadata) {
215
+ return active.value.metadata.name;
216
+ } else {
217
+ return props.title;
218
+ }
219
+ });
220
+
221
+ // Cleanup when component is unmounted
222
+ onUnmounted(async () => {
223
+ // Stop observing resize events
224
+ if (observer.value) {
225
+ observer.value.disconnect();
226
+ }
227
+
228
+ // Destroy HLS player instance
229
+ if (player.value) {
230
+ player.value.destroy();
231
+ }
232
+
233
+ // Clean up video lease from server
234
+ await deleteLease();
235
+ });
236
+
237
+ // Initialize component when mounted
238
+ onMounted(async () => {
239
+ // Set up resize observer to sync container size with store
240
+ observer.value = new ResizeObserver((entries) => {
241
+ if (!entries.length) return;
242
+
243
+ // Use requestAnimationFrame for smooth resize updates
244
+ window.requestAnimationFrame(() => {
245
+ if (video.value && video.value && container.value) {
246
+ video.value.config.height = entries[0].contentRect.height;
247
+ video.value.config.width = entries[0].contentRect.width;
248
+ }
249
+ });
250
+ })
251
+
252
+ // Initialize container position and size from stored config
253
+ if (container.value && video.value) {
254
+ container.value.style.top = video.value.config.y + 'px';
255
+ container.value.style.left = video.value.config.x + 'px';
256
+
257
+ container.value.style.height = video.value.config.height + 'px';
258
+ container.value.style.width = video.value.config.width + 'px';
259
+
260
+ // Start observing container for resize events
261
+ observer.value.observe(container.value);
262
+ }
263
+
264
+ // Set up drag functionality
265
+ if (dragHandle.value) {
266
+ dragHandle.value.addEventListener('mousedown', dragStart);
267
+ dragHandle.value.addEventListener('touchstart', touchStart, { passive: false });
268
+ }
269
+
270
+ // Start the video lease request process
271
+ await requestLease();
272
+ });
273
+
274
+ /**
275
+ * Drag functionality - allows user to move the video player around the screen
276
+ */
277
+ function dragStart(event: MouseEvent) {
278
+ if (!container.value || !dragHandle.value) return;
279
+
280
+ // Store initial mouse position
281
+ lastPosition.value.left = event.clientX;
282
+ lastPosition.value.top = event.clientY;
283
+
284
+ // Add visual feedback for dragging state
285
+ dragHandle.value.classList.add('dragging');
286
+
287
+ // Attach drag event listeners
288
+ container.value.addEventListener('mousemove', dragMove);
289
+ container.value.addEventListener('mouseleave', dragEnd);
290
+ container.value.addEventListener('mouseup', dragEnd);
291
+ }
292
+
293
+ function dragMove(event: MouseEvent) {
294
+ if (!container.value || !dragHandle.value || !video.value) return;
295
+
296
+ // Calculate new position based on mouse movement
297
+ const dragElRect = container.value.getBoundingClientRect();
298
+
299
+ // Update stored position in video config
300
+ video.value.config.x = dragElRect.left + event.clientX - lastPosition.value.left;
301
+ video.value.config.y = dragElRect.top + event.clientY - lastPosition.value.top;
302
+
303
+ // Update last position for next move calculation
304
+ lastPosition.value.left = event.clientX;
305
+ lastPosition.value.top = event.clientY;
306
+
307
+ // Apply new position to DOM element
308
+ container.value.style.top = video.value.config.y + 'px';
309
+ container.value.style.left = video.value.config.x + 'px';
310
+ }
311
+
312
+ function dragEnd() {
313
+ if (!container.value || !dragHandle.value) return;
314
+
315
+ // Remove drag event listeners
316
+ container.value.removeEventListener('mousemove', dragMove);
317
+ container.value.removeEventListener('mouseleave', dragEnd);
318
+ container.value.removeEventListener('mouseup', dragEnd);
319
+
320
+ // Remove visual feedback for dragging state
321
+ dragHandle.value.classList.remove('dragging');
322
+ }
323
+
324
+ function touchStart(event: TouchEvent) {
325
+ if (!container.value || !dragHandle.value) return;
326
+ event.preventDefault();
327
+
328
+ const touch = event.touches[0];
329
+ lastPosition.value.left = touch.clientX;
330
+ lastPosition.value.top = touch.clientY;
331
+
332
+ dragHandle.value.classList.add('dragging');
333
+
334
+ container.value.addEventListener('touchmove', touchMove, { passive: false });
335
+ container.value.addEventListener('touchend', touchEnd);
336
+ container.value.addEventListener('touchcancel', touchEnd);
337
+ }
338
+
339
+ function touchMove(event: TouchEvent) {
340
+ if (!container.value || !dragHandle.value || !video.value) return;
341
+ event.preventDefault();
342
+
343
+ const touch = event.touches[0];
344
+ const dragElRect = container.value.getBoundingClientRect();
345
+
346
+ video.value.config.x = dragElRect.left + touch.clientX - lastPosition.value.left;
347
+ video.value.config.y = dragElRect.top + touch.clientY - lastPosition.value.top;
348
+
349
+ lastPosition.value.left = touch.clientX;
350
+ lastPosition.value.top = touch.clientY;
351
+
352
+ container.value.style.top = video.value.config.y + 'px';
353
+ container.value.style.left = video.value.config.x + 'px';
354
+ }
355
+
356
+ function touchEnd() {
357
+ if (!container.value || !dragHandle.value) return;
358
+
359
+ container.value.removeEventListener('touchmove', touchMove);
360
+ container.value.removeEventListener('touchend', touchEnd);
361
+ container.value.removeEventListener('touchcancel', touchEnd);
362
+
363
+ dragHandle.value.classList.remove('dragging');
364
+ }
365
+
366
+ /**
367
+ * Clean up video lease from CloudTAK server when component is destroyed
368
+ */
369
+ async function deleteLease(): Promise<void> {
370
+ if (!videoLease.value) return;
371
+
372
+ try {
373
+ // Delete the temporary video lease from server
374
+ await std(`/api/video/lease/${videoLease.value.id}`, {
375
+ method: 'DELETE',
376
+ });
377
+
378
+ loading.value = false;
379
+ } catch (err) {
380
+ loading.value = false;
381
+ error.value = err instanceof Error ? err : new Error(String(err));
382
+ }
383
+ }
384
+
385
+ /**
386
+ * Create and configure HLS.js player with resilient settings for live streaming
387
+ */
388
+ async function createPlayer(): Promise<void> {
389
+ try {
390
+ const url = new URL(videoProtocols.value!.hls!.url);
391
+
392
+ player.value = new Hls({
393
+ enableWorker: true,
394
+ lowLatencyMode: false, // More forgiving for stream restarts
395
+ debug: false,
396
+ backBufferLength: 90, // Keep more buffer for smoother playback
397
+ maxBufferLength: 30, // Larger buffer for resilience
398
+ maxMaxBufferLength: 600,
399
+ liveSyncDurationCount: 3, // More tolerant of discontinuities
400
+ liveMaxLatencyDurationCount: 10,
401
+ xhrSetup: (xhr: XMLHttpRequest) => {
402
+ // Add authentication if stream requires it
403
+ if (url.username && url.password) {
404
+ xhr.setRequestHeader('Authorization', 'Basic ' + btoa(`${url.username}:${url.password}`));
405
+ }
406
+ }
407
+ });
408
+
409
+ player.value.attachMedia(videoTag.value!);
410
+
411
+ player.value.on(Hls.Events.MEDIA_ATTACHED, async () => {
412
+ if (player.value) player.value.loadSource(url.toString());
413
+ });
414
+
415
+ // Auto-play when manifest is loaded and parsed
416
+ player.value.on(Hls.Events.MANIFEST_PARSED, async () => {
417
+ try {
418
+ if (videoTag.value) await videoTag.value.play();
419
+ } catch (err) {
420
+ console.error("Error playing video:", err);
421
+ }
422
+ });
423
+
424
+ // Enhanced error handling for MediaMTX muxer restarts and network issues
425
+ player.value.on(Hls.Events.ERROR, (event, data) => {
426
+ console.log("HLS Error:", data);
427
+
428
+ switch (data.type) {
429
+ case Hls.ErrorTypes.NETWORK_ERROR:
430
+ if (!data.fatal) {
431
+ handleStreamRestart(); // Handle muxer restart scenario
432
+ break;
433
+ } else {
434
+ console.log("Fatal network error:", data);
435
+ handleStreamError(data.error);
436
+ break;
437
+ }
438
+ case Hls.ErrorTypes.MEDIA_ERROR:
439
+ if (!data.fatal) {
440
+ handleStreamRestart(); // Handle muxer restart scenario
441
+ break;
442
+ } else {
443
+ console.log("Fatal media error:", data);
444
+
445
+ if (data.details === 'bufferAddCodecError' && data.error instanceof Error && data.error.name === 'NotSupportedError') {
446
+ error.value = new Error(`Your browser does not support the required video codec for this stream (${data.mimeType}`);
447
+ } else if (player.value) {
448
+ try {
449
+ player.value.recoverMediaError();
450
+ } catch {
451
+ handleStreamError(data.error);
452
+ }
453
+ } else {
454
+ handleStreamError(data.error);
455
+ }
456
+
457
+ break;
458
+ }
459
+ default:
460
+ if (!data.fatal) return;
461
+
462
+ // Handle other fatal errors with retry logic
463
+ handleStreamError(data.error);
464
+ break;
465
+ }
466
+ })
467
+ } catch (err) {
468
+ error.value = err instanceof Error ? err : new Error(String(err));
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Handle MediaMTX muxer restarts gracefully
474
+ * This occurs when MediaMTX creates new segment naming due to source hiccups
475
+ */
476
+ function handleStreamRestart(): void {
477
+ const hls = player.value;
478
+ if (!hls || !videoProtocols.value?.hls) return;
479
+
480
+ console.log('Handling HLS stream restart (muxer restart detected)');
481
+
482
+ try {
483
+ hls.recoverMediaError();
484
+ hls.stopLoad();
485
+ hls.loadSource(hls.url!);
486
+
487
+ const videoElement = hls.media;
488
+ if (videoElement) {
489
+ hls.once(Hls.Events.LEVEL_LOADED, () => {
490
+ // Seek to the end (live edge) to bypass the stalled gap
491
+ videoElement.currentTime = videoElement.duration;
492
+ hls.startLoad();
493
+ videoElement.play().catch(e => console.error("Play failed", e));
494
+ });
495
+ }
496
+ } catch (err) {
497
+ console.error('Error handling stream restart:', err);
498
+ handleStreamError(err instanceof Error ? err : new Error(String(err)));
499
+ }
500
+ }
501
+
502
+ /**
503
+ * Handle stream errors with exponential backoff retry logic
504
+ * Implements 3-attempt retry system with increasing delays: 1s, 2s, 4s
505
+ */
506
+ function handleStreamError(streamError: Error): void {
507
+ if (retryCount.value < maxRetries.value) {
508
+ // Calculate exponential backoff delay
509
+ const delay = 1000 * Math.pow(2, retryCount.value); // 1s, 2s, 4s
510
+ console.log(`Retrying stream in ${delay}ms (attempt ${retryCount.value + 1}/${maxRetries.value})`);
511
+
512
+ retryCount.value++;
513
+
514
+ // Retry after delay
515
+ setTimeout(() => {
516
+ if (player.value) {
517
+ player.value.destroy();
518
+ player.value = undefined;
519
+ }
520
+
521
+ createPlayer();
522
+ }, delay);
523
+ } else {
524
+ // Max retries reached - give up and show error to user
525
+ console.error('Max retries reached, giving up');
526
+
527
+ if (player.value) {
528
+ player.value.destroy();
529
+ player.value = undefined;
530
+ }
531
+
532
+ error.value = streamError;
533
+ retryCount.value = 0;
534
+ }
535
+ }
536
+
537
+ /**
538
+ * Request video lease from CloudTAK server and initialize streaming
539
+ * Handles both existing active streams and creation of new temporary leases
540
+ */
541
+ async function requestLease(): Promise<void> {
542
+ if (!video.value) {
543
+ error.value = new Error('Video URL could not be loaded');
544
+ return;
545
+ } else if (!Hls.isSupported()) {
546
+ error.value = new Error('HLS.js is not supported in this browser.');
547
+ return;
548
+ } else {
549
+ error.value = undefined;
550
+ }
551
+
552
+ try {
553
+ // Check if stream is already active on the server
554
+ const url = stdurl('/api/video/active');
555
+ url.searchParams.append('url', video.value.config.url)
556
+ active.value = await std(url);
557
+
558
+ if (active.value.metadata) {
559
+ // Stream is already active - use existing protocols
560
+ videoProtocols.value = active.value.metadata.protocols;
561
+ loading.value = false;
562
+ } else if (active.value.leasable) {
563
+ // Stream can be leased - create temporary lease
564
+ const lease = await std('/api/video/lease', {
565
+ method: 'POST',
566
+ body: {
567
+ name: 'Temporary Lease',
568
+ ephemeral: true, // Hidden from streaming list
569
+ duration: 1 * 60 * 60, // 1 hour lease
570
+ proxy: video.value.config.url // Proxy the external stream
571
+ }
572
+ }) as VideoLeaseResponse
573
+
574
+ const { protocols } = await std(`/api/video/lease/${lease.path}/metadata`) as VideoLeaseMetadata;
575
+
576
+ videoLease.value = lease;
577
+ videoProtocols.value = protocols;
578
+
579
+ loading.value = false;
580
+ } else if (!active.value.leasable) {
581
+ // Stream cannot be leased
582
+ error.value = new Error(active.value.message || 'Could not start stream');
583
+ }
584
+
585
+ // Initialize HLS player if we have protocols available
586
+ if (!error.value && videoProtocols.value && videoProtocols.value.hls) {
587
+ retryCount.value = 0; // Reset retry count for new lease
588
+ nextTick(() => {
589
+ createPlayer();
590
+ });
591
+ }
592
+ } catch (err) {
593
+ loading.value = false;
594
+ error.value = err instanceof Error ? err : new Error(String(err));
595
+ }
596
+ }
597
+ </script>
598
+
599
+ <style>
600
+ .dragging {
601
+ cursor: move !important;
602
+ }
603
+
604
+ .resizable-content {
605
+ min-height: 300px;
606
+ min-width: 400px;
607
+ resize: both;
608
+ overflow: hidden;
609
+ }
610
+
611
+ .video-container {
612
+ container-type: inline-size;
613
+ }
614
+
615
+ .modal-body--error {
616
+ display: flex;
617
+ align-items: center;
618
+ justify-content: center;
619
+ }
620
+
621
+ .error-state {
622
+ padding: 1rem;
623
+ max-width: 520px;
624
+ }
625
+
626
+ .error-alert,
627
+ .error-actions {
628
+ max-width: 480px;
629
+ }
630
+
631
+ @container (max-width: 500px) {
632
+ .watchers-info .watcher-text {
633
+ display: none;
634
+ }
635
+ }
636
+
637
+ @container (max-width: 450px) {
638
+ .watchers-info {
639
+ display: none !important;
640
+ }
641
+ }
642
+
643
+ .live-video::-webkit-media-controls-timeline {
644
+ display: none;
645
+ }
646
+
647
+ .live-video::-webkit-media-controls-current-time-display {
648
+ display: none;
649
+ }
650
+
651
+ .live-video::-webkit-media-controls-time-remaining-display {
652
+ display: none;
653
+ }
654
+ </style>