@zendir/ui 0.1.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 (359) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +589 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +421 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/react/3d/EarthViewer.d.ts +46 -0
  8. package/dist/react/3d/EarthViewer.js +836 -0
  9. package/dist/react/3d/EarthViewer.js.map +1 -0
  10. package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
  11. package/dist/react/3d/SolarSystemViewer.js +372 -0
  12. package/dist/react/3d/SolarSystemViewer.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3D.d.ts +16 -0
  14. package/dist/react/3d/ZenSpace3D.js +1253 -0
  15. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  16. package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
  17. package/dist/react/3d/ZenSpace3DCesium.js +186 -0
  18. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  19. package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
  20. package/dist/react/3d/ZenSpace3DShaders.js +94 -0
  21. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  22. package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
  23. package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
  24. package/dist/react/3d/ZenSpace3DUtils.js +213 -0
  25. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
  26. package/dist/react/3d/index.d.ts +23 -0
  27. package/dist/react/3d/threeLoader.d.ts +22 -0
  28. package/dist/react/3d/threeLoader.js +18 -0
  29. package/dist/react/3d/threeLoader.js.map +1 -0
  30. package/dist/react/astro/ClassificationBanner.d.ts +25 -0
  31. package/dist/react/astro/ClassificationBanner.js +83 -0
  32. package/dist/react/astro/ClassificationBanner.js.map +1 -0
  33. package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
  34. package/dist/react/astro/GlobalStatusBar.js +165 -0
  35. package/dist/react/astro/GlobalStatusBar.js.map +1 -0
  36. package/dist/react/astro/MissionClock.d.ts +169 -0
  37. package/dist/react/astro/MissionClock.js +411 -0
  38. package/dist/react/astro/MissionClock.js.map +1 -0
  39. package/dist/react/astro/MonitoringIcon.d.ts +60 -0
  40. package/dist/react/astro/MonitoringIcon.js +369 -0
  41. package/dist/react/astro/MonitoringIcon.js.map +1 -0
  42. package/dist/react/astro/Notification.d.ts +42 -0
  43. package/dist/react/astro/Notification.js +156 -0
  44. package/dist/react/astro/Notification.js.map +1 -0
  45. package/dist/react/astro/Progress.d.ts +39 -0
  46. package/dist/react/astro/Progress.js +149 -0
  47. package/dist/react/astro/Progress.js.map +1 -0
  48. package/dist/react/astro/SimulationControls.d.ts +136 -0
  49. package/dist/react/astro/SimulationControls.js +668 -0
  50. package/dist/react/astro/SimulationControls.js.map +1 -0
  51. package/dist/react/astro/StatusIndicator.d.ts +34 -0
  52. package/dist/react/astro/StatusIndicator.js +189 -0
  53. package/dist/react/astro/StatusIndicator.js.map +1 -0
  54. package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
  55. package/dist/react/astro/UnifiedTimeline.js +1768 -0
  56. package/dist/react/astro/UnifiedTimeline.js.map +1 -0
  57. package/dist/react/astro/index.d.ts +63 -0
  58. package/dist/react/cards/AccessCard.d.ts +37 -0
  59. package/dist/react/cards/AccessCard.js +410 -0
  60. package/dist/react/cards/AccessCard.js.map +1 -0
  61. package/dist/react/cards/OrbitCard.d.ts +31 -0
  62. package/dist/react/cards/OrbitCard.js +372 -0
  63. package/dist/react/cards/OrbitCard.js.map +1 -0
  64. package/dist/react/cards/SpacecraftCard.d.ts +54 -0
  65. package/dist/react/cards/SpacecraftCard.js +941 -0
  66. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  67. package/dist/react/cards/TelemetryCard.d.ts +40 -0
  68. package/dist/react/cards/TelemetryCard.js +742 -0
  69. package/dist/react/cards/TelemetryCard.js.map +1 -0
  70. package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
  71. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  72. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  73. package/dist/react/cards/index.d.ts +13 -0
  74. package/dist/react/charts/GroundTrackMap.d.ts +112 -0
  75. package/dist/react/charts/GroundTrackMap.js +1123 -0
  76. package/dist/react/charts/GroundTrackMap.js.map +1 -0
  77. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
  78. package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
  79. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
  80. package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
  81. package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
  82. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
  83. package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
  84. package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
  85. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
  86. package/dist/react/charts/index.d.ts +10 -0
  87. package/dist/react/charts/unified/AstroChart.d.ts +24 -0
  88. package/dist/react/charts/unified/AstroChart.js +1405 -0
  89. package/dist/react/charts/unified/AstroChart.js.map +1 -0
  90. package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
  91. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  92. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  93. package/dist/react/charts/unified/domain.d.ts +845 -0
  94. package/dist/react/charts/unified/domain.js +3168 -0
  95. package/dist/react/charts/unified/domain.js.map +1 -0
  96. package/dist/react/charts/unified/generators.d.ts +276 -0
  97. package/dist/react/charts/unified/generators.js +518 -0
  98. package/dist/react/charts/unified/generators.js.map +1 -0
  99. package/dist/react/charts/unified/index.d.ts +55 -0
  100. package/dist/react/charts/unified/presets.d.ts +290 -0
  101. package/dist/react/charts/unified/presets.js +999 -0
  102. package/dist/react/charts/unified/presets.js.map +1 -0
  103. package/dist/react/charts/unified/sync.d.ts +69 -0
  104. package/dist/react/charts/unified/sync.js +219 -0
  105. package/dist/react/charts/unified/sync.js.map +1 -0
  106. package/dist/react/charts/unified/theme.d.ts +447 -0
  107. package/dist/react/charts/unified/theme.js +562 -0
  108. package/dist/react/charts/unified/theme.js.map +1 -0
  109. package/dist/react/charts/unified/types.d.ts +826 -0
  110. package/dist/react/charts/unified/useChartStream.d.ts +58 -0
  111. package/dist/react/charts/unified/useChartStream.js +226 -0
  112. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  113. package/dist/react/chatgpt/AppCard.d.ts +59 -0
  114. package/dist/react/chatgpt/AppCard.js +306 -0
  115. package/dist/react/chatgpt/AppCard.js.map +1 -0
  116. package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
  117. package/dist/react/chatgpt/index.d.ts +167 -0
  118. package/dist/react/chatgpt/index.js +166 -0
  119. package/dist/react/chatgpt/index.js.map +1 -0
  120. package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
  121. package/dist/react/context/DisplaySettingsContext.js +169 -0
  122. package/dist/react/context/DisplaySettingsContext.js.map +1 -0
  123. package/dist/react/context/index.d.ts +5 -0
  124. package/dist/react/core/ActivityPlanner.d.ts +45 -0
  125. package/dist/react/core/ActivityPlanner.js +532 -0
  126. package/dist/react/core/ActivityPlanner.js.map +1 -0
  127. package/dist/react/core/AppBar.d.ts +71 -0
  128. package/dist/react/core/AppBar.js +817 -0
  129. package/dist/react/core/AppBar.js.map +1 -0
  130. package/dist/react/core/AstroIcon.d.ts +84 -0
  131. package/dist/react/core/AstroIcon.js +1243 -0
  132. package/dist/react/core/AstroIcon.js.map +1 -0
  133. package/dist/react/core/Badge.d.ts +27 -0
  134. package/dist/react/core/Badge.js +134 -0
  135. package/dist/react/core/Badge.js.map +1 -0
  136. package/dist/react/core/Button.d.ts +26 -0
  137. package/dist/react/core/Button.js +306 -0
  138. package/dist/react/core/Button.js.map +1 -0
  139. package/dist/react/core/CardHeader.d.ts +34 -0
  140. package/dist/react/core/CardHeader.js +316 -0
  141. package/dist/react/core/CardHeader.js.map +1 -0
  142. package/dist/react/core/ChatPanel.d.ts +627 -0
  143. package/dist/react/core/ChatPanel.js +1144 -0
  144. package/dist/react/core/ChatPanel.js.map +1 -0
  145. package/dist/react/core/Checkbox.d.ts +26 -0
  146. package/dist/react/core/Checkbox.js +130 -0
  147. package/dist/react/core/Checkbox.js.map +1 -0
  148. package/dist/react/core/ColorPickerPanel.d.ts +25 -0
  149. package/dist/react/core/ColorPickerPanel.js +293 -0
  150. package/dist/react/core/ColorPickerPanel.js.map +1 -0
  151. package/dist/react/core/CommandBuilder.d.ts +74 -0
  152. package/dist/react/core/CommandBuilder.js +518 -0
  153. package/dist/react/core/CommandBuilder.js.map +1 -0
  154. package/dist/react/core/ConfirmDialog.d.ts +45 -0
  155. package/dist/react/core/ConfirmDialog.js +315 -0
  156. package/dist/react/core/ConfirmDialog.js.map +1 -0
  157. package/dist/react/core/ConnectionForm.d.ts +57 -0
  158. package/dist/react/core/ConnectionForm.js +496 -0
  159. package/dist/react/core/ConnectionForm.js.map +1 -0
  160. package/dist/react/core/Container.d.ts +51 -0
  161. package/dist/react/core/Container.js +670 -0
  162. package/dist/react/core/Container.js.map +1 -0
  163. package/dist/react/core/CopyButton.d.ts +39 -0
  164. package/dist/react/core/CopyButton.js +105 -0
  165. package/dist/react/core/CopyButton.js.map +1 -0
  166. package/dist/react/core/DataTable.d.ts +113 -0
  167. package/dist/react/core/DataTable.js +446 -0
  168. package/dist/react/core/DataTable.js.map +1 -0
  169. package/dist/react/core/DataValue.d.ts +64 -0
  170. package/dist/react/core/DataValue.js +545 -0
  171. package/dist/react/core/DataValue.js.map +1 -0
  172. package/dist/react/core/Dialog.d.ts +32 -0
  173. package/dist/react/core/Dialog.js +201 -0
  174. package/dist/react/core/Dialog.js.map +1 -0
  175. package/dist/react/core/FileExplorer.d.ts +65 -0
  176. package/dist/react/core/FileExplorer.js +520 -0
  177. package/dist/react/core/FileExplorer.js.map +1 -0
  178. package/dist/react/core/GlassCard.d.ts +129 -0
  179. package/dist/react/core/GlassCard.js +375 -0
  180. package/dist/react/core/GlassCard.js.map +1 -0
  181. package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
  182. package/dist/react/core/HeaderIconWithStatus.js +157 -0
  183. package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
  184. package/dist/react/core/HexViewer.d.ts +143 -0
  185. package/dist/react/core/HexViewer.js +1106 -0
  186. package/dist/react/core/HexViewer.js.map +1 -0
  187. package/dist/react/core/Icon.d.ts +32 -0
  188. package/dist/react/core/Icon.js +142 -0
  189. package/dist/react/core/Icon.js.map +1 -0
  190. package/dist/react/core/ImageGallery.d.ts +41 -0
  191. package/dist/react/core/ImageGallery.js +320 -0
  192. package/dist/react/core/ImageGallery.js.map +1 -0
  193. package/dist/react/core/Input.d.ts +38 -0
  194. package/dist/react/core/Input.js +288 -0
  195. package/dist/react/core/Input.js.map +1 -0
  196. package/dist/react/core/LimitsBar.d.ts +51 -0
  197. package/dist/react/core/LimitsBar.js +200 -0
  198. package/dist/react/core/LimitsBar.js.map +1 -0
  199. package/dist/react/core/LogViewer.d.ts +61 -0
  200. package/dist/react/core/LogViewer.js +599 -0
  201. package/dist/react/core/LogViewer.js.map +1 -0
  202. package/dist/react/core/MessageStream.d.ts +58 -0
  203. package/dist/react/core/MessageStream.js +455 -0
  204. package/dist/react/core/MessageStream.js.map +1 -0
  205. package/dist/react/core/MissionCalendar.d.ts +81 -0
  206. package/dist/react/core/MissionCalendar.js +1049 -0
  207. package/dist/react/core/MissionCalendar.js.map +1 -0
  208. package/dist/react/core/NumberInput.d.ts +85 -0
  209. package/dist/react/core/NumberInput.js +507 -0
  210. package/dist/react/core/NumberInput.js.map +1 -0
  211. package/dist/react/core/PacketViewer.d.ts +73 -0
  212. package/dist/react/core/PacketViewer.js +431 -0
  213. package/dist/react/core/PacketViewer.js.map +1 -0
  214. package/dist/react/core/Pagination.d.ts +30 -0
  215. package/dist/react/core/Pagination.js +190 -0
  216. package/dist/react/core/Pagination.js.map +1 -0
  217. package/dist/react/core/PinInput.d.ts +41 -0
  218. package/dist/react/core/PinInput.js +210 -0
  219. package/dist/react/core/PinInput.js.map +1 -0
  220. package/dist/react/core/Popover.d.ts +55 -0
  221. package/dist/react/core/Popover.js +288 -0
  222. package/dist/react/core/Popover.js.map +1 -0
  223. package/dist/react/core/Select.d.ts +42 -0
  224. package/dist/react/core/Select.js +303 -0
  225. package/dist/react/core/Select.js.map +1 -0
  226. package/dist/react/core/SideNav.d.ts +103 -0
  227. package/dist/react/core/SideNav.js +551 -0
  228. package/dist/react/core/SideNav.js.map +1 -0
  229. package/dist/react/core/SidePanel.d.ts +33 -0
  230. package/dist/react/core/SidePanel.js +199 -0
  231. package/dist/react/core/SidePanel.js.map +1 -0
  232. package/dist/react/core/Tabs.d.ts +47 -0
  233. package/dist/react/core/Tabs.js +129 -0
  234. package/dist/react/core/Tabs.js.map +1 -0
  235. package/dist/react/core/Toast.d.ts +56 -0
  236. package/dist/react/core/Toast.js +229 -0
  237. package/dist/react/core/Toast.js.map +1 -0
  238. package/dist/react/core/Toggle.d.ts +22 -0
  239. package/dist/react/core/Toggle.js +151 -0
  240. package/dist/react/core/Toggle.js.map +1 -0
  241. package/dist/react/core/Tooltip.d.ts +19 -0
  242. package/dist/react/core/Tooltip.js +179 -0
  243. package/dist/react/core/Tooltip.js.map +1 -0
  244. package/dist/react/core/Typography.d.ts +127 -0
  245. package/dist/react/core/Typography.js +187 -0
  246. package/dist/react/core/Typography.js.map +1 -0
  247. package/dist/react/core/index.d.ts +108 -0
  248. package/dist/react/core/layout/Box.d.ts +77 -0
  249. package/dist/react/core/layout/Box.js +126 -0
  250. package/dist/react/core/layout/Box.js.map +1 -0
  251. package/dist/react/core/layout/Center.d.ts +20 -0
  252. package/dist/react/core/layout/Center.js +34 -0
  253. package/dist/react/core/layout/Center.js.map +1 -0
  254. package/dist/react/core/layout/Divider.d.ts +16 -0
  255. package/dist/react/core/layout/Divider.js +108 -0
  256. package/dist/react/core/layout/Divider.js.map +1 -0
  257. package/dist/react/core/layout/Flex.d.ts +30 -0
  258. package/dist/react/core/layout/Flex.js +128 -0
  259. package/dist/react/core/layout/Flex.js.map +1 -0
  260. package/dist/react/core/layout/Grid.d.ts +36 -0
  261. package/dist/react/core/layout/Grid.js +142 -0
  262. package/dist/react/core/layout/Grid.js.map +1 -0
  263. package/dist/react/core/layout/Spacer.d.ts +8 -0
  264. package/dist/react/core/layout/Spacer.js +31 -0
  265. package/dist/react/core/layout/Spacer.js.map +1 -0
  266. package/dist/react/core/layout/Stack.d.ts +54 -0
  267. package/dist/react/core/layout/Stack.js +74 -0
  268. package/dist/react/core/layout/Stack.js.map +1 -0
  269. package/dist/react/core/layout/index.d.ts +38 -0
  270. package/dist/react/core/layout/responsive.d.ts +23 -0
  271. package/dist/react/core/layout/responsive.js +26 -0
  272. package/dist/react/core/layout/responsive.js.map +1 -0
  273. package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
  274. package/dist/react/core/layout/useBreakpoint.js +73 -0
  275. package/dist/react/core/layout/useBreakpoint.js.map +1 -0
  276. package/dist/react/core/propertyConfig.d.ts +443 -0
  277. package/dist/react/core/propertyConfig.js +399 -0
  278. package/dist/react/core/propertyConfig.js.map +1 -0
  279. package/dist/react/hooks/index.d.ts +21 -0
  280. package/dist/react/hooks/useAccessWindows.d.ts +66 -0
  281. package/dist/react/hooks/useCompactMode.d.ts +82 -0
  282. package/dist/react/hooks/useCompactMode.js +62 -0
  283. package/dist/react/hooks/useCompactMode.js.map +1 -0
  284. package/dist/react/hooks/useLiveSelection.d.ts +57 -0
  285. package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
  286. package/dist/react/hooks/useSimulationTime.d.ts +61 -0
  287. package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
  288. package/dist/react/hooks/useSpacecraftPosition.js +89 -0
  289. package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
  290. package/dist/react/hooks/useTelemetry.d.ts +55 -0
  291. package/dist/react/hooks/useTelemetry.js +73 -0
  292. package/dist/react/hooks/useTelemetry.js.map +1 -0
  293. package/dist/react/hooks/useZendirSession.d.ts +109 -0
  294. package/dist/react/hooks/useZendirSession.js +148 -0
  295. package/dist/react/hooks/useZendirSession.js.map +1 -0
  296. package/dist/react/index.d.ts +74 -0
  297. package/dist/react/shared/ErrorBoundary.d.ts +63 -0
  298. package/dist/react/shared/ErrorBoundary.js +142 -0
  299. package/dist/react/shared/ErrorBoundary.js.map +1 -0
  300. package/dist/react/shared/Skeleton.d.ts +110 -0
  301. package/dist/react/shared/Skeleton.js +324 -0
  302. package/dist/react/shared/Skeleton.js.map +1 -0
  303. package/dist/react/shared/index.d.ts +12 -0
  304. package/dist/react/theme/ThemeProvider.d.ts +385 -0
  305. package/dist/react/theme/ThemeProvider.js +1096 -0
  306. package/dist/react/theme/ThemeProvider.js.map +1 -0
  307. package/dist/react/theme/astro-tokens.d.ts +153 -0
  308. package/dist/react/theme/cardAccent.d.ts +75 -0
  309. package/dist/react/theme/cardAccent.js +137 -0
  310. package/dist/react/theme/cardAccent.js.map +1 -0
  311. package/dist/react/theme/config.d.ts +39 -0
  312. package/dist/react/theme/index.d.ts +9 -0
  313. package/dist/react/types.d.ts +360 -0
  314. package/dist/react/types.js +58 -0
  315. package/dist/react/types.js.map +1 -0
  316. package/dist/react/utils/index.d.ts +247 -0
  317. package/dist/react/utils/index.js +423 -0
  318. package/dist/react/utils/index.js.map +1 -0
  319. package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
  320. package/dist/react/visualizations/EclipseTimerCard.js +250 -0
  321. package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
  322. package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
  323. package/dist/react/visualizations/LinkBudgetCard.js +444 -0
  324. package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
  325. package/dist/react/visualizations/NavBallCard.d.ts +17 -0
  326. package/dist/react/visualizations/NavBallCard.js +243 -0
  327. package/dist/react/visualizations/NavBallCard.js.map +1 -0
  328. package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
  329. package/dist/react/visualizations/PropulsionCard.js +298 -0
  330. package/dist/react/visualizations/PropulsionCard.js.map +1 -0
  331. package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
  332. package/dist/react/visualizations/SensorFootprintCard.js +326 -0
  333. package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
  334. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
  335. package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
  336. package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
  337. package/dist/react/visualizations/index.d.ts +17 -0
  338. package/dist/react.d.ts +1 -0
  339. package/dist/react.js +421 -0
  340. package/dist/react.js.map +1 -0
  341. package/dist/shaders/atmosphere.frag.js +5 -0
  342. package/dist/shaders/atmosphere.frag.js.map +1 -0
  343. package/dist/shaders/atmosphere.vert.js +5 -0
  344. package/dist/shaders/atmosphere.vert.js.map +1 -0
  345. package/dist/shaders/stars.frag.js +5 -0
  346. package/dist/shaders/stars.frag.js.map +1 -0
  347. package/dist/shaders/stars.vert.js +5 -0
  348. package/dist/shaders/stars.vert.js.map +1 -0
  349. package/dist/style.css +143 -0
  350. package/dist/tokens/index.d.ts +296 -0
  351. package/dist/tokens/index.js +263 -0
  352. package/dist/tokens/index.js.map +1 -0
  353. package/dist/tokens/tokens.css +155 -0
  354. package/dist/types/index.d.ts +23 -0
  355. package/dist/types.d.ts +1 -0
  356. package/dist/types.js +2 -0
  357. package/dist/types.js.map +1 -0
  358. package/package.json +220 -0
  359. package/sdk-stub.js +22 -0
@@ -0,0 +1,571 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useState, useCallback, useEffect } from "react";
3
+ import L from "leaflet";
4
+ import "leaflet/dist/leaflet.css";
5
+ /* empty css */
6
+ import { geodesicCirclePoints, splitRingAtAntimeridian, segmentsWithWorldCopies, splitPolylineAtAntimeridian } from "./groundTrackMapLeafletUtils.js";
7
+ import { DEFAULT_TILE, CARTO_ATTRIBUTION, OSM_ATTRIBUTION, FALLBACK_TILE } from "./groundTrackMapLeafletTiles.js";
8
+ import { useTheme } from "../theme/ThemeProvider.js";
9
+ const STATUS_COLOR_MAP = {
10
+ normal: "#56f000",
11
+ standby: "#2dccff",
12
+ caution: "#fce83a",
13
+ serious: "#ffb302",
14
+ critical: "#ff3838",
15
+ off: "#a4abb6"
16
+ };
17
+ const DEFAULT_TRACK_COLORS = [
18
+ "#2dccff",
19
+ "#3E3CFF",
20
+ "#9D70FF",
21
+ "#56f000",
22
+ "#fce83a",
23
+ "#ff7849",
24
+ "#2dd4bf",
25
+ "#ff3838"
26
+ ];
27
+ function createSatDivIcon(statusColor, trackColor) {
28
+ const badge = statusColor === "#56f000" ? `<circle cx="7" cy="7" r="3" fill="${statusColor}"/>` : statusColor === "#2dccff" ? `<circle cx="7" cy="7" r="2.5" fill="none" stroke="${statusColor}" stroke-width="1.5"/>` : statusColor === "#fce83a" ? `<rect x="4.5" y="4.5" width="5" height="5" fill="${statusColor}"/>` : statusColor === "#ffb302" ? `<polygon points="7,3.5 10.5,7 7,10.5 3.5,7" fill="${statusColor}"/>` : statusColor === "#ff3838" ? `<polygon points="7,10 4,4 10,4" fill="${statusColor}"/>` : `<circle cx="7" cy="7" r="2" fill="${statusColor}"/>`;
29
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 34 34">
30
+ <!-- Glow ring -->
31
+ <circle cx="17" cy="17" r="15" fill="${statusColor}" fill-opacity="0.12"/>
32
+ <!-- Main body circle -->
33
+ <circle cx="17" cy="17" r="11" fill="#0d1323" stroke="${trackColor}" stroke-width="1.5"/>
34
+ <!-- Left solar panel -->
35
+ <rect x="2" y="15" width="9" height="4" rx="0.5" fill="${trackColor}" fill-opacity="0.75"/>
36
+ <line x1="5.5" y1="15" x2="5.5" y2="19" stroke="${trackColor}" stroke-width="0.5" stroke-opacity="0.45"/>
37
+ <!-- Connector left -->
38
+ <line x1="11" y1="17" x2="13" y2="17" stroke="${trackColor}" stroke-width="1.2"/>
39
+ <!-- Satellite bus body -->
40
+ <rect x="13" y="14.5" width="8" height="5" rx="1" fill="${statusColor}"/>
41
+ <!-- Connector right -->
42
+ <line x1="21" y1="17" x2="23" y2="17" stroke="${trackColor}" stroke-width="1.2"/>
43
+ <!-- Right solar panel -->
44
+ <rect x="23" y="15" width="9" height="4" rx="0.5" fill="${trackColor}" fill-opacity="0.75"/>
45
+ <line x1="26.5" y1="15" x2="26.5" y2="19" stroke="${trackColor}" stroke-width="0.5" stroke-opacity="0.45"/>
46
+ <!-- Status badge (top-left) -->
47
+ <circle cx="7" cy="7" r="5.5" fill="#0d1323"/>
48
+ ${badge}
49
+ </svg>`;
50
+ return L.divIcon({
51
+ html: svg,
52
+ className: "zendir-sat-icon",
53
+ iconSize: [34, 34],
54
+ iconAnchor: [17, 17],
55
+ tooltipAnchor: [0, -18]
56
+ });
57
+ }
58
+ function createStationDivIcon(statusColor, type, status) {
59
+ const badge = status === "normal" ? `<circle cx="5" cy="5" r="2.5" fill="${statusColor}"/>` : status === "standby" ? `<circle cx="5" cy="5" r="2" fill="none" stroke="${statusColor}" stroke-width="1.2"/>` : status === "caution" ? `<rect x="3" y="3" width="4" height="4" fill="${statusColor}"/>` : status === "serious" ? `<polygon points="5,2.5 7.5,5 5,7.5 2.5,5" fill="${statusColor}"/>` : status === "critical" ? `<polygon points="5,7.5 2.5,2.5 7.5,2.5" fill="${statusColor}"/>` : `<circle cx="5" cy="5" r="1.5" fill="${statusColor}"/>`;
60
+ let iconInner = "";
61
+ if (type === "phased-array") {
62
+ iconInner = `
63
+ <rect x="9" y="7" width="10" height="8" rx="0.5" fill="none" stroke="${statusColor}" stroke-width="1.2"/>
64
+ <line x1="12" y1="7" x2="12" y2="15" stroke="${statusColor}" stroke-width="0.7"/>
65
+ <line x1="15" y1="7" x2="15" y2="15" stroke="${statusColor}" stroke-width="0.7"/>
66
+ <line x1="9" y1="10" x2="19" y2="10" stroke="${statusColor}" stroke-width="0.7"/>
67
+ <line x1="9" y1="13" x2="19" y2="13" stroke="${statusColor}" stroke-width="0.7"/>
68
+ <line x1="14" y1="15" x2="14" y2="20" stroke="${statusColor}" stroke-width="1.2"/>
69
+ <line x1="11" y1="20" x2="17" y2="20" stroke="${statusColor}" stroke-width="1.2"/>`;
70
+ } else if (type === "relay") {
71
+ iconInner = `
72
+ <path d="M 8 16 a 7 7 0 0 1 7 -7" fill="none" stroke="${statusColor}" stroke-width="1.5" stroke-linecap="round"/>
73
+ <path d="M 8 16 m 2 -2 a 5 5 0 0 1 5 -5" fill="none" stroke="${statusColor}" stroke-width="1.2" stroke-linecap="round"/>
74
+ <line x1="14" y1="16" x2="14" y2="21" stroke="${statusColor}" stroke-width="1.2"/>
75
+ <line x1="11" y1="21" x2="17" y2="21" stroke="${statusColor}" stroke-width="1.2"/>
76
+ <path d="M 16 8 a 3 3 0 0 1 0 4" fill="none" stroke="${statusColor}" stroke-width="1.2" stroke-linecap="round"/>
77
+ <path d="M 17.5 6.5 a 5 5 0 0 1 0 7" fill="none" stroke="${statusColor}" stroke-width="1" stroke-linecap="round"/>`;
78
+ } else {
79
+ iconInner = `
80
+ <path d="M 14 14 m -7 0 a 7 7 0 0 1 7 -7" fill="none" stroke="${statusColor}" stroke-width="1.5" stroke-linecap="round"/>
81
+ <path d="M 14 14 m -5 0 a 5 5 0 0 1 5 -5" fill="none" stroke="${statusColor}" stroke-width="1.5" stroke-linecap="round"/>
82
+ <path d="M 14 14 m -3 0 a 3 3 0 0 1 3 -3" fill="none" stroke="${statusColor}" stroke-width="1.5" stroke-linecap="round"/>
83
+ <circle cx="14" cy="14" r="1.5" fill="${statusColor}"/>
84
+ <line x1="14" y1="15" x2="14" y2="21" stroke="${statusColor}" stroke-width="1.2"/>
85
+ <line x1="11" y1="21" x2="17" y2="21" stroke="${statusColor}" stroke-width="1.2"/>`;
86
+ }
87
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28">
88
+ <!-- Glow ring -->
89
+ <circle cx="14" cy="14" r="13" fill="${statusColor}" fill-opacity="0.1"/>
90
+ <!-- Background -->
91
+ <circle cx="14" cy="14" r="11" fill="#0d1323" stroke="${statusColor}" stroke-width="1.2" stroke-opacity="0.7"/>
92
+ ${iconInner}
93
+ <!-- Status badge (top-left) -->
94
+ <circle cx="5" cy="5" r="5" fill="#0d1323"/>
95
+ ${badge}
96
+ </svg>`;
97
+ return L.divIcon({
98
+ html: svg,
99
+ className: "zendir-station-icon",
100
+ iconSize: [28, 28],
101
+ iconAnchor: [14, 14],
102
+ tooltipAnchor: [0, -14]
103
+ });
104
+ }
105
+ function calculateTerminatorContinuous(date, numPoints = 72) {
106
+ const dayOfYear = Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 864e5);
107
+ const declination = -23.44 * Math.cos(2 * Math.PI / 365 * (dayOfYear + 10));
108
+ const decRad = declination * Math.PI / 180;
109
+ const hourAngle = (date.getUTCHours() + date.getUTCMinutes() / 60) / 24 * 360 - 180;
110
+ const points = [];
111
+ let prevLon = null;
112
+ for (let i = 0; i <= numPoints; i++) {
113
+ const latRad = (i / numPoints * 180 - 90) * (Math.PI / 180);
114
+ const cosH = -Math.tan(latRad) * Math.tan(decRad);
115
+ let lon;
116
+ if (cosH < -1) lon = hourAngle + 180;
117
+ else if (cosH > 1) lon = hourAngle;
118
+ else lon = hourAngle + Math.acos(cosH) * 180 / Math.PI;
119
+ if (prevLon != null) {
120
+ while (lon - prevLon > 180) lon -= 360;
121
+ while (lon - prevLon < -180) lon += 360;
122
+ }
123
+ prevLon = lon;
124
+ points.push([i / numPoints * 180 - 90, lon]);
125
+ }
126
+ return points;
127
+ }
128
+ function buildNightPolygon(sunsetTerminator) {
129
+ if (!sunsetTerminator.length) return [];
130
+ const sunrise = sunsetTerminator.map(([lat, lon]) => [lat, lon - 180]);
131
+ return [...sunsetTerminator, ...[...sunrise].reverse()];
132
+ }
133
+ function GroundTrackMapLeaflet({
134
+ allSatellites,
135
+ groundStations,
136
+ showTerminator = true,
137
+ showGrid = false,
138
+ showLegend = true,
139
+ showEquator = false,
140
+ showRecenterButton = true,
141
+ defaultCenter = [20, 0],
142
+ defaultZoom = 2,
143
+ height = "100%",
144
+ width = "100%",
145
+ minHeight = "400px",
146
+ emptyMessage = "No orbital data available",
147
+ tileUrl = DEFAULT_TILE,
148
+ className = "",
149
+ onSatelliteClick,
150
+ onStationClick
151
+ }) {
152
+ const { tokens } = useTheme();
153
+ const containerRef = useRef(null);
154
+ const mapRef = useRef(null);
155
+ const tileLayerRef = useRef(null);
156
+ const overlayGroupRef = useRef(null);
157
+ const controlsRef = useRef([]);
158
+ const [ready, setReady] = useState(false);
159
+ const clearLayers = useCallback(() => {
160
+ var _a;
161
+ const map = mapRef.current;
162
+ if (!map) return;
163
+ (_a = overlayGroupRef.current) == null ? void 0 : _a.clearLayers();
164
+ controlsRef.current.forEach((ctrl) => map.removeControl(ctrl));
165
+ controlsRef.current = [];
166
+ }, []);
167
+ const addLayer = useCallback((layer) => {
168
+ var _a;
169
+ (_a = overlayGroupRef.current) == null ? void 0 : _a.addLayer(layer);
170
+ }, []);
171
+ useEffect(() => {
172
+ const el = containerRef.current;
173
+ if (!el) return;
174
+ const center = defaultCenter ?? [20, 0];
175
+ const zoom = defaultZoom ?? 2;
176
+ const map = L.map(el, {
177
+ center,
178
+ zoom,
179
+ zoomControl: false,
180
+ scrollWheelZoom: true,
181
+ doubleClickZoom: true,
182
+ touchZoom: true,
183
+ boxZoom: true,
184
+ keyboard: true,
185
+ dragging: true,
186
+ attributionControl: true,
187
+ maxBounds: [[-90, -540], [90, 540]],
188
+ maxBoundsViscosity: 1
189
+ });
190
+ L.control.zoom({ position: "topright" }).addTo(map);
191
+ map.attributionControl.setPrefix("");
192
+ const isCartoTiles = tileUrl.includes("cartocdn");
193
+ if (isCartoTiles) {
194
+ map.attributionControl.addAttribution(CARTO_ATTRIBUTION);
195
+ }
196
+ const tileOptions = {
197
+ maxZoom: 19,
198
+ subdomains: isCartoTiles ? "abcd" : "abc",
199
+ // crossOrigin avoids tainted-canvas errors when Leaflet tries to read tile pixels
200
+ crossOrigin: true
201
+ };
202
+ const tile = L.tileLayer(tileUrl, tileOptions);
203
+ tile.addTo(map);
204
+ tileLayerRef.current = tile;
205
+ let hasSwitchedToFallback = false;
206
+ const onTileError = () => {
207
+ if (hasSwitchedToFallback) return;
208
+ hasSwitchedToFallback = true;
209
+ tile.off("tileerror", onTileError);
210
+ tile.remove();
211
+ if (isCartoTiles) {
212
+ map.attributionControl.removeAttribution(CARTO_ATTRIBUTION);
213
+ map.attributionControl.addAttribution(OSM_ATTRIBUTION);
214
+ }
215
+ const fallback = L.tileLayer(FALLBACK_TILE, {
216
+ maxZoom: 19,
217
+ subdomains: "abc",
218
+ crossOrigin: true
219
+ });
220
+ fallback.addTo(map);
221
+ tileLayerRef.current = fallback;
222
+ };
223
+ tile.on("tileerror", onTileError);
224
+ const overlayGroup = L.layerGroup();
225
+ overlayGroup.addTo(map);
226
+ overlayGroupRef.current = overlayGroup;
227
+ mapRef.current = map;
228
+ setReady(true);
229
+ const onSize = () => {
230
+ map.invalidateSize({ animate: false });
231
+ };
232
+ const raf = requestAnimationFrame(onSize);
233
+ const t1 = setTimeout(onSize, 150);
234
+ const t2 = setTimeout(onSize, 500);
235
+ return () => {
236
+ clearTimeout(t1);
237
+ clearTimeout(t2);
238
+ cancelAnimationFrame(raf);
239
+ clearLayers();
240
+ tileLayerRef.current = null;
241
+ map.remove();
242
+ mapRef.current = null;
243
+ overlayGroupRef.current = null;
244
+ };
245
+ }, [tileUrl, clearLayers]);
246
+ useEffect(() => {
247
+ if (!ready || !mapRef.current) return;
248
+ const map = mapRef.current;
249
+ clearLayers();
250
+ if (showTerminator) {
251
+ const sunsetTerminator = calculateTerminatorContinuous(/* @__PURE__ */ new Date());
252
+ const nightPoly = buildNightPolygon(sunsetTerminator);
253
+ if (nightPoly.length > 2) {
254
+ [0, 360, -360].forEach((offset) => {
255
+ const shifted = nightPoly.map(([lat, lon]) => [lat, lon + offset]);
256
+ addLayer(L.polygon(shifted, {
257
+ color: "transparent",
258
+ fillColor: "#00060f",
259
+ fillOpacity: 0.35,
260
+ interactive: false
261
+ }));
262
+ });
263
+ }
264
+ const sunriseTerminator = sunsetTerminator.map(([lat, lon]) => [lat, lon - 180]);
265
+ [sunsetTerminator, sunriseTerminator].forEach((line) => {
266
+ [0, 360, -360].forEach((offset) => {
267
+ const shifted = line.map(([lat, lon]) => [lat, lon + offset]);
268
+ addLayer(L.polyline(shifted, {
269
+ color: "rgba(88, 166, 255, 0.22)",
270
+ weight: 1,
271
+ interactive: false
272
+ }));
273
+ });
274
+ });
275
+ }
276
+ if (showGrid) {
277
+ const gridStyle = { color: "rgba(157, 112, 255, 0.12)", weight: 0.5, interactive: false };
278
+ [-360, 0, 360].forEach((offset) => {
279
+ for (let lon = -180; lon <= 180; lon += 30) {
280
+ const l = lon + offset;
281
+ addLayer(L.polyline([[90, l], [-90, l]], gridStyle));
282
+ }
283
+ for (let lat = -90; lat <= 90; lat += 30) {
284
+ addLayer(L.polyline([[lat, -180 + offset], [lat, 180 + offset]], gridStyle));
285
+ }
286
+ });
287
+ }
288
+ if (showEquator) {
289
+ [-360, 0, 360].forEach((offset) => {
290
+ addLayer(L.polyline([[0, -180 + offset], [0, 180 + offset]], {
291
+ color: "rgba(88, 166, 255, 0.25)",
292
+ weight: 1,
293
+ dashArray: "6, 4",
294
+ interactive: false
295
+ }));
296
+ });
297
+ }
298
+ groundStations.forEach((gs) => {
299
+ const status = ("status" in gs ? gs.status : void 0) ?? "standby";
300
+ const statusColor = STATUS_COLOR_MAP[status] || STATUS_COLOR_MAP.standby;
301
+ const stationType = ("type" in gs ? gs.type : void 0) ?? "dish";
302
+ const radius = "coverageRadius" in gs ? gs.coverageRadius : void 0;
303
+ const showCoverage = "showCoverage" in gs ? gs.showCoverage : false;
304
+ if (radius != null && radius > 0 && showCoverage) {
305
+ const ring = geodesicCirclePoints(gs.latitude, gs.longitude, radius, 64);
306
+ const rings = splitRingAtAntimeridian(ring);
307
+ [0, 360, -360].forEach((offset) => {
308
+ rings.forEach((r) => {
309
+ const shifted = r.map(([lat, lon]) => [lat, lon + offset]);
310
+ addLayer(L.polygon(shifted, {
311
+ color: `${statusColor}55`,
312
+ fillColor: statusColor,
313
+ fillOpacity: 0.1,
314
+ weight: 1,
315
+ dashArray: "4, 3",
316
+ interactive: false
317
+ }));
318
+ });
319
+ });
320
+ }
321
+ const gsIcon = createStationDivIcon(statusColor, stationType, status);
322
+ const marker = L.marker([gs.latitude, gs.longitude], { icon: gsIcon });
323
+ addLayer(marker);
324
+ const statusLabel = status !== "standby" ? ` · ${status}` : "";
325
+ marker.bindTooltip(
326
+ `<strong>${gs.name}</strong>${statusLabel}${"network" in gs && gs.network ? `<br/><span style="opacity:0.7">${gs.network}</span>` : ""}`,
327
+ { permanent: false, direction: "top", className: "zendir-leaflet-tooltip" }
328
+ );
329
+ marker.on("click", () => {
330
+ onStationClick == null ? void 0 : onStationClick("id" in gs ? String(gs.id) : gs.name);
331
+ });
332
+ });
333
+ allSatellites.forEach((sat, satIdx) => {
334
+ const track = sat.groundTrack;
335
+ if (!track || track.length === 0) return;
336
+ const color = sat.color || DEFAULT_TRACK_COLORS[satIdx % DEFAULT_TRACK_COLORS.length];
337
+ const futureIdx = sat.futureTrackIndex ?? track.length;
338
+ const pastLatLngs = track.slice(0, futureIdx).map((p) => [p.latitude, p.longitude]);
339
+ segmentsWithWorldCopies(splitPolylineAtAntimeridian(pastLatLngs)).forEach((seg) => {
340
+ if (seg.length >= 2) {
341
+ addLayer(L.polyline(seg, { color, weight: 2.5, opacity: 1 }));
342
+ }
343
+ });
344
+ if (futureIdx < track.length) {
345
+ const futureLatLngs = track.slice(futureIdx).map((p) => [p.latitude, p.longitude]);
346
+ segmentsWithWorldCopies(splitPolylineAtAntimeridian(futureLatLngs)).forEach((seg) => {
347
+ if (seg.length >= 2) {
348
+ addLayer(L.polyline(seg, { color, weight: 1.5, opacity: 0.5, dashArray: "6, 4" }));
349
+ }
350
+ });
351
+ }
352
+ if (sat.accessMask && sat.accessMask.some(Boolean)) {
353
+ let segment = [];
354
+ for (let i = 0; i < track.length; i++) {
355
+ if (sat.accessMask[i]) {
356
+ segment.push([track[i].latitude, track[i].longitude]);
357
+ } else if (segment.length >= 2) {
358
+ segmentsWithWorldCopies(splitPolylineAtAntimeridian(segment)).forEach((seg) => {
359
+ if (seg.length >= 2) {
360
+ addLayer(L.polyline(seg, { color: STATUS_COLOR_MAP.normal, weight: 4, opacity: 0.9 }));
361
+ }
362
+ });
363
+ segment = [];
364
+ } else {
365
+ segment = [];
366
+ }
367
+ }
368
+ if (segment.length >= 2) {
369
+ segmentsWithWorldCopies(splitPolylineAtAntimeridian(segment)).forEach((seg) => {
370
+ if (seg.length >= 2) {
371
+ addLayer(L.polyline(seg, { color: STATUS_COLOR_MAP.normal, weight: 4, opacity: 0.9 }));
372
+ }
373
+ });
374
+ }
375
+ }
376
+ if (sat.passMarkers && sat.passMarkers.length > 0) {
377
+ sat.passMarkers.forEach((pm) => {
378
+ const isAos = pm.type === "aos";
379
+ const pmColor = isAos ? "#56f000" : "#ff3838";
380
+ const pmMarker = L.circleMarker([pm.latitude, pm.longitude], {
381
+ radius: 5,
382
+ fillColor: pmColor,
383
+ color: `${pmColor}cc`,
384
+ weight: 1.5,
385
+ fillOpacity: 0.9
386
+ });
387
+ addLayer(pmMarker);
388
+ pmMarker.bindTooltip(`${pm.type.toUpperCase()}${pm.label ? ` – ${pm.label}` : ""}`, {
389
+ permanent: false,
390
+ direction: "top",
391
+ className: "zendir-leaflet-tooltip"
392
+ });
393
+ });
394
+ }
395
+ if (sat.showFootprint && sat.footprintRadius) {
396
+ const lastIdx = futureIdx > 0 ? Math.min(futureIdx - 1, track.length - 1) : track.length - 1;
397
+ const last = track[lastIdx];
398
+ const ring = geodesicCirclePoints(last.latitude, last.longitude, sat.footprintRadius, 64);
399
+ const rings = splitRingAtAntimeridian(ring);
400
+ [0, 360, -360].forEach((offset) => {
401
+ rings.forEach((r) => {
402
+ const shifted = r.map(([lat, lon]) => [lat, lon + offset]);
403
+ addLayer(L.polygon(shifted, {
404
+ color: `${color}70`,
405
+ fillColor: color,
406
+ fillOpacity: 0.1,
407
+ weight: 1,
408
+ dashArray: "3, 3",
409
+ interactive: false
410
+ }));
411
+ });
412
+ });
413
+ }
414
+ const currentIdx = futureIdx > 0 ? Math.min(futureIdx - 1, track.length - 1) : track.length - 1;
415
+ const current = track[currentIdx];
416
+ const statusColor = STATUS_COLOR_MAP[sat.status || "normal"] || STATUS_COLOR_MAP.normal;
417
+ const satIcon = createSatDivIcon(statusColor, color);
418
+ const satMarker = L.marker([current.latitude, current.longitude], { icon: satIcon });
419
+ addLayer(satMarker);
420
+ satMarker.bindTooltip(
421
+ `<strong style="color:${color}">${sat.name}</strong><br/>Lat ${current.latitude.toFixed(3)}° &nbsp; Lon ${current.longitude.toFixed(3)}°` + (current.altitude != null ? `<br/>Alt ${current.altitude.toFixed(1)} km` : "") + (sat.status ? `<br/><span style="color:${statusColor}">${sat.status.toUpperCase()}</span>` : ""),
422
+ { permanent: false, direction: "top", className: "zendir-leaflet-tooltip" }
423
+ );
424
+ satMarker.on("click", () => onSatelliteClick == null ? void 0 : onSatelliteClick(sat.id));
425
+ });
426
+ if (showLegend && (allSatellites.length > 0 || groundStations.length > 0)) {
427
+ const Legend = L.Control.extend({
428
+ onAdd() {
429
+ const div = L.DomUtil.create("div", "leaflet-legend-zendir");
430
+ div.style.cssText = `
431
+ padding: 8px 12px; background: rgba(15,21,32,0.9); border: 1px solid rgba(157,112,255,0.2);
432
+ border-radius: 8px; color: #e4e0f0; font-size: 11px; font-family: Roboto, sans-serif;
433
+ `;
434
+ allSatellites.forEach((s, i) => {
435
+ const c = s.color || DEFAULT_TRACK_COLORS[i % DEFAULT_TRACK_COLORS.length];
436
+ const row = document.createElement("div");
437
+ row.style.cssText = "display: flex; align-items: center; gap: 6px; margin: 2px 0;";
438
+ const swatch = document.createElement("span");
439
+ swatch.style.cssText = `width:8px;height:8px;border-radius:50%;background:${c};`;
440
+ const label = document.createElement("span");
441
+ label.textContent = s.name;
442
+ row.appendChild(swatch);
443
+ row.appendChild(label);
444
+ div.appendChild(row);
445
+ });
446
+ if (groundStations.length > 0) {
447
+ const row = document.createElement("div");
448
+ row.style.cssText = "display: flex; align-items: center; gap: 6px; margin: 2px 0; margin-top: 6px;";
449
+ const swatch = document.createElement("span");
450
+ swatch.style.cssText = "width:8px;height:8px;border-radius:50%;background:#2dccff;";
451
+ const label = document.createElement("span");
452
+ label.textContent = `${groundStations.length} Ground Station${groundStations.length > 1 ? "s" : ""}`;
453
+ row.appendChild(swatch);
454
+ row.appendChild(label);
455
+ div.appendChild(row);
456
+ }
457
+ return div;
458
+ }
459
+ });
460
+ const legend = new Legend({ position: "topleft" });
461
+ legend.addTo(map);
462
+ controlsRef.current.push(legend);
463
+ }
464
+ }, [
465
+ ready,
466
+ allSatellites,
467
+ groundStations,
468
+ showTerminator,
469
+ showGrid,
470
+ showEquator,
471
+ showLegend,
472
+ tokens.colors.text.secondary,
473
+ addLayer,
474
+ clearLayers,
475
+ onSatelliteClick,
476
+ onStationClick
477
+ ]);
478
+ const handleRecenter = useCallback(() => {
479
+ const map = mapRef.current;
480
+ if (!map) return;
481
+ const points = [];
482
+ allSatellites.forEach((s) => {
483
+ s.groundTrack.forEach((p) => points.push([p.latitude, p.longitude]));
484
+ });
485
+ groundStations.forEach((gs) => points.push([gs.latitude, gs.longitude]));
486
+ if (points.length > 0) {
487
+ const bounds = L.latLngBounds(points);
488
+ map.fitBounds(bounds, { padding: [40, 40], maxZoom: 8 });
489
+ } else {
490
+ map.setView(defaultCenter, defaultZoom);
491
+ }
492
+ }, [allSatellites, groundStations, defaultCenter, defaultZoom]);
493
+ const resolvedMinHeight = minHeight || (typeof height === "number" ? `${height}px` : "400px");
494
+ const isEmpty = allSatellites.length === 0 && groundStations.length === 0;
495
+ return /* @__PURE__ */ jsxs(
496
+ "div",
497
+ {
498
+ className: `zendir-ground-track-map zendir-ground-track-map-leaflet ${className}`,
499
+ "data-map-backend": "leaflet",
500
+ style: {
501
+ width,
502
+ height,
503
+ minHeight: resolvedMinHeight,
504
+ backgroundColor: tokens.colors.background.base,
505
+ borderRadius: 8,
506
+ overflow: "hidden",
507
+ position: "relative"
508
+ },
509
+ children: [
510
+ /* @__PURE__ */ jsx(
511
+ "div",
512
+ {
513
+ ref: containerRef,
514
+ style: { width: "100%", height: "100%", minHeight: resolvedMinHeight }
515
+ }
516
+ ),
517
+ isEmpty && /* @__PURE__ */ jsx(
518
+ "div",
519
+ {
520
+ style: {
521
+ position: "absolute",
522
+ left: "50%",
523
+ top: "50%",
524
+ transform: "translate(-50%, -50%)",
525
+ color: tokens.colors.text.secondary,
526
+ fontSize: 14,
527
+ pointerEvents: "none"
528
+ },
529
+ children: emptyMessage
530
+ }
531
+ ),
532
+ showRecenterButton && /* @__PURE__ */ jsxs(
533
+ "button",
534
+ {
535
+ type: "button",
536
+ onClick: handleRecenter,
537
+ title: "Recenter map",
538
+ "aria-label": "Recenter map",
539
+ style: {
540
+ position: "absolute",
541
+ top: 8,
542
+ right: 50,
543
+ zIndex: 1e3,
544
+ background: "rgba(24, 29, 46, 0.9)",
545
+ border: "1px solid rgba(157, 112, 255, 0.25)",
546
+ borderRadius: 6,
547
+ color: "#e4e0f0",
548
+ cursor: "pointer",
549
+ padding: "6px 10px",
550
+ fontSize: 12,
551
+ display: "flex",
552
+ alignItems: "center",
553
+ gap: 4
554
+ },
555
+ children: [
556
+ /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
557
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
558
+ /* @__PURE__ */ jsx("path", { d: "M12 2v4M12 18v4M2 12h4M18 12h4" })
559
+ ] }),
560
+ "Recenter"
561
+ ]
562
+ }
563
+ )
564
+ ]
565
+ }
566
+ );
567
+ }
568
+ export {
569
+ GroundTrackMapLeaflet
570
+ };
571
+ //# sourceMappingURL=GroundTrackMapLeaflet.js.map