@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,183 @@
1
+ import { Vector3D, LatLonAlt, SphericalCoords, TLEData, Satellite, OrbitPath, CoverageHexGrid } from './ZenSpace3DTypes';
2
+
3
+ /** Earth's radius in km */
4
+ export declare const EARTH_RADIUS_KM = 6371;
5
+ /** Earth's gravitational parameter (km³/s²) */
6
+ export declare const EARTH_MU = 398600.4418;
7
+ /** Astronomical Unit in km */
8
+ export declare const AU_KM = 149597870.7;
9
+ /** Degrees to radians */
10
+ export declare const DEG_TO_RAD: number;
11
+ /** Radians to degrees */
12
+ export declare const RAD_TO_DEG: number;
13
+ /** J2000 epoch (January 1, 2000, 12:00 TT) */
14
+ export declare const J2000_EPOCH: Date;
15
+ /** Seconds per day */
16
+ export declare const SECONDS_PER_DAY = 86400;
17
+ /** Minutes per day */
18
+ export declare const MINUTES_PER_DAY = 1440;
19
+ /** Scene Earth radius (render units) */
20
+ export declare const SCENE_EARTH_RADIUS = 3000;
21
+ /** Scene scale factor (km to render units) */
22
+ export declare const KM_TO_SCENE: number;
23
+ /** Scene scale for Solar System (different scale) */
24
+ export declare const SOLAR_SYSTEM_SCALE = 1;
25
+ /**
26
+ * Convert latitude/longitude/altitude to Cartesian (ECI-like for rendering)
27
+ * @param lat Latitude in degrees
28
+ * @param lon Longitude in degrees
29
+ * @param altKm Altitude in kilometers
30
+ * @param earthRadius Scene radius for Earth
31
+ * @returns Cartesian coordinates
32
+ */
33
+ export declare function latLonAltToCartesian(lat: number, lon: number, altKm?: number, earthRadius?: number): Vector3D;
34
+ /**
35
+ * Convert Cartesian to latitude/longitude/altitude
36
+ * @param position Cartesian position
37
+ * @param earthRadius Scene radius for Earth
38
+ * @returns Lat/Lon/Alt
39
+ */
40
+ export declare function cartesianToLatLonAlt(position: Vector3D, earthRadius?: number): LatLonAlt;
41
+ /**
42
+ * Convert Cartesian to spherical coordinates
43
+ */
44
+ export declare function cartesianToSpherical(position: Vector3D): SphericalCoords;
45
+ /**
46
+ * Convert spherical to Cartesian coordinates
47
+ */
48
+ export declare function sphericalToCartesian(coords: SphericalCoords): Vector3D;
49
+ /**
50
+ * Convert ECI (Earth-Centered Inertial) to ECEF (Earth-Centered Earth-Fixed)
51
+ * @param eci ECI position (km)
52
+ * @param gmst Greenwich Mean Sidereal Time (radians)
53
+ */
54
+ export declare function eciToEcef(eci: Vector3D, gmst: number): Vector3D;
55
+ /**
56
+ * Calculate Greenwich Mean Sidereal Time
57
+ * @param date Date/time
58
+ * @returns GMST in radians
59
+ */
60
+ export declare function calculateGMST(date: Date): number;
61
+ /**
62
+ * Convert Date to Julian Date
63
+ */
64
+ export declare function dateToJulianDate(date: Date): number;
65
+ /**
66
+ * Parse Two-Line Element set
67
+ */
68
+ export declare function parseTLE(line1: string, line2: string): TLEData | null;
69
+ /**
70
+ * Simplified SGP4 propagation
71
+ * @param tle TLE data
72
+ * @param minutesFromEpoch Minutes from TLE epoch
73
+ * @returns Position in km (ECI coordinates)
74
+ */
75
+ export declare function propagateSGP4Simple(tle: TLEData, minutesFromEpoch: number): Vector3D;
76
+ /**
77
+ * Propagate satellite to specific time
78
+ * @param satellite Satellite with TLE
79
+ * @param time Target time
80
+ * @returns Position in km (ECI)
81
+ */
82
+ export declare function propagateSatellite(satellite: Satellite, time: Date): Vector3D | null;
83
+ /**
84
+ * Generate orbit path for a satellite
85
+ * @param satellite Satellite with TLE
86
+ * @param startTime Start time
87
+ * @param duration Duration in minutes
88
+ * @param steps Number of steps
89
+ */
90
+ export declare function generateOrbitPath(satellite: Satellite, startTime: Date, duration?: number, steps?: number): OrbitPath | null;
91
+ /**
92
+ * Calculate if a satellite is visible from a ground station
93
+ * @param satPos Satellite position (scene units)
94
+ * @param gsLatLon Ground station lat/lon
95
+ * @param minElevation Minimum elevation angle (degrees)
96
+ */
97
+ export declare function isVisible(satPos: Vector3D, gsLatLon: {
98
+ latitude: number;
99
+ longitude: number;
100
+ }, minElevation?: number): boolean;
101
+ /**
102
+ * Calculate visibility cone vertices for rendering
103
+ * @param gsLatLon Ground station position
104
+ * @param minElevation Minimum elevation angle
105
+ * @param altitude Altitude for cone apex (km)
106
+ * @param segments Number of segments for cone circle
107
+ */
108
+ export declare function calculateVisibilityConeGeometry(gsLatLon: {
109
+ latitude: number;
110
+ longitude: number;
111
+ }, minElevation?: number, altitude?: number, segments?: number): Vector3D[];
112
+ /**
113
+ * Generate footprint polygon for a satellite
114
+ * @param satPos Satellite position (scene units)
115
+ * @param minElevation Minimum elevation angle
116
+ * @param segments Number of segments
117
+ */
118
+ export declare function calculateFootprint(satPos: Vector3D, minElevation?: number, segments?: number): Array<{
119
+ latitude: number;
120
+ longitude: number;
121
+ }>;
122
+ /**
123
+ * Generate a hexagonal grid covering the globe
124
+ * @param resolution Grid resolution (lower = fewer hexagons)
125
+ */
126
+ export declare function generateHexGrid(resolution?: number): CoverageHexGrid;
127
+ /**
128
+ * Update hex grid coverage values based on satellite footprints
129
+ */
130
+ export declare function updateHexGridCoverage(grid: CoverageHexGrid, satellites: Satellite[], time: Date): CoverageHexGrid;
131
+ export declare function dot(a: Vector3D, b: Vector3D): number;
132
+ export declare function cross(a: Vector3D, b: Vector3D): Vector3D;
133
+ export declare function magnitude(v: Vector3D): number;
134
+ export declare function normalize(v: Vector3D): Vector3D;
135
+ export declare function subtract(a: Vector3D, b: Vector3D): Vector3D;
136
+ export declare function add(a: Vector3D, b: Vector3D): Vector3D;
137
+ export declare function scale(v: Vector3D, s: number): Vector3D;
138
+ export declare function distance(a: Vector3D, b: Vector3D): number;
139
+ export declare function lerp(a: Vector3D, b: Vector3D, t: number): Vector3D;
140
+ /**
141
+ * Ease-out cubic function
142
+ */
143
+ export declare function easeOutCubic(t: number): number;
144
+ /**
145
+ * Ease-in-out cubic function
146
+ */
147
+ export declare function easeInOutCubic(t: number): number;
148
+ /**
149
+ * Smooth step function
150
+ */
151
+ export declare function smoothstep(edge0: number, edge1: number, x: number): number;
152
+ /**
153
+ * Interpolate between two colors
154
+ */
155
+ export declare function lerpColor(color1: string, color2: string, t: number): string;
156
+ /**
157
+ * Hex to RGB
158
+ */
159
+ export declare function hexToRgb(hex: string): {
160
+ r: number;
161
+ g: number;
162
+ b: number;
163
+ } | null;
164
+ /**
165
+ * Get color from value (0-1) on a gradient scale
166
+ */
167
+ export declare function getGradientColor(value: number, colors?: string[]): string;
168
+ /**
169
+ * Format time duration as HH:MM:SS
170
+ */
171
+ export declare function formatDuration(seconds: number): string;
172
+ /**
173
+ * Format distance in appropriate units
174
+ */
175
+ export declare function formatDistance(km: number): string;
176
+ /**
177
+ * Format velocity
178
+ */
179
+ export declare function formatVelocity(kmPerSec: number): string;
180
+ /**
181
+ * Format date/time for display
182
+ */
183
+ export declare function formatDateTime(date: Date): string;
@@ -0,0 +1,213 @@
1
+ const EARTH_RADIUS_KM = 6371;
2
+ const EARTH_MU = 398600.4418;
3
+ const DEG_TO_RAD = Math.PI / 180;
4
+ const RAD_TO_DEG = 180 / Math.PI;
5
+ const SECONDS_PER_DAY = 86400;
6
+ const MINUTES_PER_DAY = 1440;
7
+ const SCENE_EARTH_RADIUS = 3e3;
8
+ const KM_TO_SCENE = SCENE_EARTH_RADIUS / EARTH_RADIUS_KM;
9
+ function latLonAltToCartesian(lat, lon, altKm = 0, earthRadius = SCENE_EARTH_RADIUS) {
10
+ const r = earthRadius + altKm * KM_TO_SCENE;
11
+ const phi = (90 - lat) * DEG_TO_RAD;
12
+ const theta = (lon + 180) * DEG_TO_RAD;
13
+ return {
14
+ x: -r * Math.sin(phi) * Math.cos(theta),
15
+ y: r * Math.cos(phi),
16
+ z: r * Math.sin(phi) * Math.sin(theta)
17
+ };
18
+ }
19
+ function cartesianToLatLonAlt(position, earthRadius = SCENE_EARTH_RADIUS) {
20
+ const r = Math.sqrt(position.x ** 2 + position.y ** 2 + position.z ** 2);
21
+ const lat = 90 - Math.acos(position.y / r) * RAD_TO_DEG;
22
+ const lon = Math.atan2(position.z, -position.x) * RAD_TO_DEG - 180;
23
+ const alt = (r - earthRadius) / KM_TO_SCENE;
24
+ return { latitude: lat, longitude: lon, altitude: alt };
25
+ }
26
+ function parseTLE(line1, line2) {
27
+ try {
28
+ const epochYear = parseInt(line1.substring(18, 20));
29
+ const epochDay = parseFloat(line1.substring(20, 32));
30
+ const bstar = parseScientificNotation(line1.substring(53, 61));
31
+ const inclination = parseFloat(line2.substring(8, 16));
32
+ const raan = parseFloat(line2.substring(17, 25));
33
+ const eccentricityStr = "0." + line2.substring(26, 33);
34
+ const eccentricity = parseFloat(eccentricityStr);
35
+ const argOfPerigee = parseFloat(line2.substring(34, 42));
36
+ const meanAnomaly = parseFloat(line2.substring(43, 51));
37
+ const meanMotion = parseFloat(line2.substring(52, 63));
38
+ const fullYear = epochYear < 57 ? 2e3 + epochYear : 1900 + epochYear;
39
+ const epoch = new Date(Date.UTC(fullYear, 0, 1));
40
+ epoch.setTime(epoch.getTime() + (epochDay - 1) * SECONDS_PER_DAY * 1e3);
41
+ return {
42
+ line1,
43
+ line2,
44
+ epoch,
45
+ meanMotion,
46
+ eccentricity,
47
+ inclination,
48
+ raan,
49
+ argOfPerigee,
50
+ meanAnomaly,
51
+ bstar
52
+ };
53
+ } catch (e) {
54
+ return null;
55
+ }
56
+ }
57
+ function parseScientificNotation(str) {
58
+ const trimmed = str.trim();
59
+ if (trimmed.length === 0) return 0;
60
+ let mantissa;
61
+ let exponent;
62
+ const lastSignPos = Math.max(trimmed.lastIndexOf("+"), trimmed.lastIndexOf("-"));
63
+ if (lastSignPos > 0) {
64
+ mantissa = "0." + trimmed.substring(0, lastSignPos).replace(/[^0-9]/g, "");
65
+ exponent = parseInt(trimmed.substring(lastSignPos));
66
+ } else {
67
+ mantissa = "0." + trimmed.replace(/[^0-9]/g, "");
68
+ exponent = 0;
69
+ }
70
+ return parseFloat(mantissa) * Math.pow(10, exponent);
71
+ }
72
+ function propagateSGP4Simple(tle, minutesFromEpoch) {
73
+ const n = tle.meanMotion * 2 * Math.PI / MINUTES_PER_DAY;
74
+ const a = Math.pow(EARTH_MU / (n * n / 60 / 60), 1 / 3);
75
+ const M = (tle.meanAnomaly + 360 * tle.meanMotion * minutesFromEpoch / MINUTES_PER_DAY) % 360;
76
+ const M_rad = M * DEG_TO_RAD;
77
+ let E = M_rad;
78
+ for (let i = 0; i < 10; i++) {
79
+ E = M_rad + tle.eccentricity * Math.sin(E);
80
+ }
81
+ const cosE = Math.cos(E);
82
+ const sinE = Math.sin(E);
83
+ const nu = Math.atan2(
84
+ Math.sqrt(1 - tle.eccentricity ** 2) * sinE,
85
+ cosE - tle.eccentricity
86
+ );
87
+ const r = a * (1 - tle.eccentricity * cosE);
88
+ const xOrb = r * Math.cos(nu);
89
+ const yOrb = r * Math.sin(nu);
90
+ const raanRad = tle.raan * DEG_TO_RAD;
91
+ const incRad = tle.inclination * DEG_TO_RAD;
92
+ const argPeriRad = tle.argOfPerigee * DEG_TO_RAD;
93
+ const cosRaan = Math.cos(raanRad);
94
+ const sinRaan = Math.sin(raanRad);
95
+ const cosInc = Math.cos(incRad);
96
+ const sinInc = Math.sin(incRad);
97
+ const cosArgPeri = Math.cos(argPeriRad);
98
+ const sinArgPeri = Math.sin(argPeriRad);
99
+ const x = (cosRaan * cosArgPeri - sinRaan * sinArgPeri * cosInc) * xOrb + (-cosRaan * sinArgPeri - sinRaan * cosArgPeri * cosInc) * yOrb;
100
+ const y = (sinRaan * cosArgPeri + cosRaan * sinArgPeri * cosInc) * xOrb + (-sinRaan * sinArgPeri + cosRaan * cosArgPeri * cosInc) * yOrb;
101
+ const z = sinArgPeri * sinInc * xOrb + cosArgPeri * sinInc * yOrb;
102
+ return { x, y, z };
103
+ }
104
+ function propagateSatellite(satellite, time) {
105
+ if (!satellite.tle) return null;
106
+ const minutesFromEpoch = (time.getTime() - satellite.tle.epoch.getTime()) / 6e4;
107
+ return propagateSGP4Simple(satellite.tle, minutesFromEpoch);
108
+ }
109
+ function generateOrbitPath(satellite, startTime, duration = 90, steps = 180) {
110
+ if (!satellite.tle) return null;
111
+ const points = [];
112
+ const startMinutes = (startTime.getTime() - satellite.tle.epoch.getTime()) / 6e4;
113
+ for (let i = 0; i <= steps; i++) {
114
+ const minutesFromEpoch = startMinutes + i / steps * duration;
115
+ const pos = propagateSGP4Simple(satellite.tle, minutesFromEpoch);
116
+ points.push({
117
+ x: pos.x * KM_TO_SCENE,
118
+ y: pos.z * KM_TO_SCENE,
119
+ // Swap Y/Z for Three.js
120
+ z: pos.y * KM_TO_SCENE
121
+ });
122
+ }
123
+ return {
124
+ objectId: satellite.id,
125
+ points,
126
+ timeSpan: duration * 60,
127
+ isFuture: true,
128
+ color: satellite.color || "#22d3ee"
129
+ };
130
+ }
131
+ function calculateVisibilityConeGeometry(gsLatLon, minElevation = 5, altitude = 2e3, segments = 32) {
132
+ const gsPos = latLonAltToCartesian(gsLatLon.latitude, gsLatLon.longitude, 0);
133
+ const vertices = [];
134
+ vertices.push(gsPos);
135
+ const coneAngle = (90 - minElevation) * DEG_TO_RAD;
136
+ const coneRadius = altitude * Math.tan(coneAngle);
137
+ const up = normalize(gsPos);
138
+ const east = normalize(cross({ x: 0, y: 1, z: 0 }, up));
139
+ const north = cross(up, east);
140
+ for (let i = 0; i <= segments; i++) {
141
+ const angle = i / segments * Math.PI * 2;
142
+ const basePoint = {
143
+ x: gsPos.x + up.x * altitude * KM_TO_SCENE + (east.x * Math.cos(angle) + north.x * Math.sin(angle)) * coneRadius * KM_TO_SCENE,
144
+ y: gsPos.y + up.y * altitude * KM_TO_SCENE + (east.y * Math.cos(angle) + north.y * Math.sin(angle)) * coneRadius * KM_TO_SCENE,
145
+ z: gsPos.z + up.z * altitude * KM_TO_SCENE + (east.z * Math.cos(angle) + north.z * Math.sin(angle)) * coneRadius * KM_TO_SCENE
146
+ };
147
+ vertices.push(basePoint);
148
+ }
149
+ return vertices;
150
+ }
151
+ function generateHexGrid(resolution = 2) {
152
+ const hexagons = [];
153
+ const latStep = 180 / (resolution * 8);
154
+ const lonStep = 360 / (resolution * 16);
155
+ let id = 0;
156
+ for (let lat = -90 + latStep / 2; lat < 90; lat += latStep) {
157
+ const adjustedLonStep = lonStep / Math.cos(lat * DEG_TO_RAD);
158
+ const offset = Math.floor((lat + 90) / latStep) % 2 * (adjustedLonStep / 2);
159
+ for (let lon = -180 + offset; lon < 180; lon += adjustedLonStep) {
160
+ hexagons.push({
161
+ id: `hex_${id++}`,
162
+ value: 0,
163
+ center: { latitude: lat, longitude: lon }
164
+ });
165
+ }
166
+ }
167
+ return {
168
+ resolution,
169
+ hexagons,
170
+ colorScale: { min: "#1a1a2e", max: "#00ff88" }
171
+ };
172
+ }
173
+ function cross(a, b) {
174
+ return {
175
+ x: a.y * b.z - a.z * b.y,
176
+ y: a.z * b.x - a.x * b.z,
177
+ z: a.x * b.y - a.y * b.x
178
+ };
179
+ }
180
+ function magnitude(v) {
181
+ return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
182
+ }
183
+ function normalize(v) {
184
+ const m = magnitude(v);
185
+ if (m === 0) return { x: 0, y: 0, z: 0 };
186
+ return { x: v.x / m, y: v.y / m, z: v.z / m };
187
+ }
188
+ function easeOutCubic(t) {
189
+ return 1 - Math.pow(1 - t, 3);
190
+ }
191
+ export {
192
+ DEG_TO_RAD,
193
+ EARTH_MU,
194
+ EARTH_RADIUS_KM,
195
+ KM_TO_SCENE,
196
+ MINUTES_PER_DAY,
197
+ RAD_TO_DEG,
198
+ SCENE_EARTH_RADIUS,
199
+ SECONDS_PER_DAY,
200
+ calculateVisibilityConeGeometry,
201
+ cartesianToLatLonAlt,
202
+ cross,
203
+ easeOutCubic,
204
+ generateHexGrid,
205
+ generateOrbitPath,
206
+ latLonAltToCartesian,
207
+ magnitude,
208
+ normalize,
209
+ parseTLE,
210
+ propagateSGP4Simple,
211
+ propagateSatellite
212
+ };
213
+ //# sourceMappingURL=ZenSpace3DUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZenSpace3DUtils.js","sources":["../../../src/react/3d/ZenSpace3DUtils.ts"],"sourcesContent":["/**\r\n * @zendir/ui - ZenSpace3D Utility Functions\r\n * \r\n * Coordinate transformations, TLE propagation, coverage calculations,\r\n * and other utilities for 3D space visualization.\r\n */\r\n\r\nimport type {\r\n Vector3D,\r\n LatLonAlt,\r\n SphericalCoords,\r\n TLEData,\r\n Satellite,\r\n OrbitPath,\r\n CoverageHexGrid,\r\n VisibilityCone as _VisibilityCone,\r\n} from './ZenSpace3DTypes';\r\n\r\n// =============================================================================\r\n// Constants\r\n// =============================================================================\r\n\r\n/** Earth's radius in km */\r\nexport const EARTH_RADIUS_KM = 6371;\r\n\r\n/** Earth's gravitational parameter (km³/s²) */\r\nexport const EARTH_MU = 398600.4418;\r\n\r\n/** Astronomical Unit in km */\r\nexport const AU_KM = 149597870.7;\r\n\r\n/** Degrees to radians */\r\nexport const DEG_TO_RAD = Math.PI / 180;\r\n\r\n/** Radians to degrees */\r\nexport const RAD_TO_DEG = 180 / Math.PI;\r\n\r\n/** J2000 epoch (January 1, 2000, 12:00 TT) */\r\nexport const J2000_EPOCH = new Date('2000-01-01T12:00:00Z');\r\n\r\n/** Seconds per day */\r\nexport const SECONDS_PER_DAY = 86400;\r\n\r\n/** Minutes per day */\r\nexport const MINUTES_PER_DAY = 1440;\r\n\r\n// =============================================================================\r\n// Scene Scale Constants\r\n// =============================================================================\r\n\r\n/** Scene Earth radius (render units) */\r\nexport const SCENE_EARTH_RADIUS = 3000;\r\n\r\n/** Scene scale factor (km to render units) */\r\nexport const KM_TO_SCENE = SCENE_EARTH_RADIUS / EARTH_RADIUS_KM;\r\n\r\n/** Scene scale for Solar System (different scale) */\r\nexport const SOLAR_SYSTEM_SCALE = 1; // 1 unit = 1 km in solar system mode\r\n\r\n// =============================================================================\r\n// Coordinate Conversions\r\n// =============================================================================\r\n\r\n/**\r\n * Convert latitude/longitude/altitude to Cartesian (ECI-like for rendering)\r\n * @param lat Latitude in degrees\r\n * @param lon Longitude in degrees\r\n * @param altKm Altitude in kilometers\r\n * @param earthRadius Scene radius for Earth\r\n * @returns Cartesian coordinates\r\n */\r\nexport function latLonAltToCartesian(\r\n lat: number,\r\n lon: number,\r\n altKm: number = 0,\r\n earthRadius: number = SCENE_EARTH_RADIUS\r\n): Vector3D {\r\n const r = earthRadius + altKm * KM_TO_SCENE;\r\n const phi = (90 - lat) * DEG_TO_RAD;\r\n const theta = (lon + 180) * DEG_TO_RAD;\r\n \r\n return {\r\n x: -r * Math.sin(phi) * Math.cos(theta),\r\n y: r * Math.cos(phi),\r\n z: r * Math.sin(phi) * Math.sin(theta),\r\n };\r\n}\r\n\r\n/**\r\n * Convert Cartesian to latitude/longitude/altitude\r\n * @param position Cartesian position\r\n * @param earthRadius Scene radius for Earth\r\n * @returns Lat/Lon/Alt\r\n */\r\nexport function cartesianToLatLonAlt(\r\n position: Vector3D,\r\n earthRadius: number = SCENE_EARTH_RADIUS\r\n): LatLonAlt {\r\n const r = Math.sqrt(position.x ** 2 + position.y ** 2 + position.z ** 2);\r\n const lat = 90 - Math.acos(position.y / r) * RAD_TO_DEG;\r\n const lon = Math.atan2(position.z, -position.x) * RAD_TO_DEG - 180;\r\n const alt = (r - earthRadius) / KM_TO_SCENE;\r\n \r\n return { latitude: lat, longitude: lon, altitude: alt };\r\n}\r\n\r\n/**\r\n * Convert Cartesian to spherical coordinates\r\n */\r\nexport function cartesianToSpherical(position: Vector3D): SphericalCoords {\r\n const radius = Math.sqrt(position.x ** 2 + position.y ** 2 + position.z ** 2);\r\n const theta = Math.atan2(position.z, position.x);\r\n const phi = Math.acos(position.y / radius);\r\n \r\n return { radius, theta, phi };\r\n}\r\n\r\n/**\r\n * Convert spherical to Cartesian coordinates\r\n */\r\nexport function sphericalToCartesian(coords: SphericalCoords): Vector3D {\r\n return {\r\n x: coords.radius * Math.sin(coords.phi) * Math.cos(coords.theta),\r\n y: coords.radius * Math.cos(coords.phi),\r\n z: coords.radius * Math.sin(coords.phi) * Math.sin(coords.theta),\r\n };\r\n}\r\n\r\n/**\r\n * Convert ECI (Earth-Centered Inertial) to ECEF (Earth-Centered Earth-Fixed)\r\n * @param eci ECI position (km)\r\n * @param gmst Greenwich Mean Sidereal Time (radians)\r\n */\r\nexport function eciToEcef(eci: Vector3D, gmst: number): Vector3D {\r\n const cosGmst = Math.cos(gmst);\r\n const sinGmst = Math.sin(gmst);\r\n \r\n return {\r\n x: eci.x * cosGmst + eci.y * sinGmst,\r\n y: -eci.x * sinGmst + eci.y * cosGmst,\r\n z: eci.z,\r\n };\r\n}\r\n\r\n/**\r\n * Calculate Greenwich Mean Sidereal Time\r\n * @param date Date/time\r\n * @returns GMST in radians\r\n */\r\nexport function calculateGMST(date: Date): number {\r\n const jd = dateToJulianDate(date);\r\n const t = (jd - 2451545.0) / 36525.0;\r\n \r\n // GMST in degrees\r\n let gmst = 280.46061837 + \r\n 360.98564736629 * (jd - 2451545.0) + \r\n 0.000387933 * t * t - \r\n t * t * t / 38710000.0;\r\n \r\n // Normalize to 0-360\r\n gmst = gmst % 360;\r\n if (gmst < 0) gmst += 360;\r\n \r\n return gmst * DEG_TO_RAD;\r\n}\r\n\r\n/**\r\n * Convert Date to Julian Date\r\n */\r\nexport function dateToJulianDate(date: Date): number {\r\n const year = date.getUTCFullYear();\r\n const month = date.getUTCMonth() + 1;\r\n const day = date.getUTCDate();\r\n const hour = date.getUTCHours();\r\n const minute = date.getUTCMinutes();\r\n const second = date.getUTCSeconds();\r\n \r\n let y = year;\r\n let m = month;\r\n \r\n if (m <= 2) {\r\n y -= 1;\r\n m += 12;\r\n }\r\n \r\n const a = Math.floor(y / 100);\r\n const b = 2 - a + Math.floor(a / 4);\r\n \r\n const jd = Math.floor(365.25 * (y + 4716)) +\r\n Math.floor(30.6001 * (m + 1)) +\r\n day + b - 1524.5 +\r\n (hour + minute / 60 + second / 3600) / 24;\r\n \r\n return jd;\r\n}\r\n\r\n// =============================================================================\r\n// TLE Parsing & Propagation (Simplified SGP4)\r\n// =============================================================================\r\n\r\n/**\r\n * Parse Two-Line Element set\r\n */\r\nexport function parseTLE(line1: string, line2: string): TLEData | null {\r\n try {\r\n // Line 1 parsing\r\n const epochYear = parseInt(line1.substring(18, 20));\r\n const epochDay = parseFloat(line1.substring(20, 32));\r\n const bstar = parseScientificNotation(line1.substring(53, 61));\r\n \r\n // Line 2 parsing\r\n const inclination = parseFloat(line2.substring(8, 16));\r\n const raan = parseFloat(line2.substring(17, 25));\r\n const eccentricityStr = '0.' + line2.substring(26, 33);\r\n const eccentricity = parseFloat(eccentricityStr);\r\n const argOfPerigee = parseFloat(line2.substring(34, 42));\r\n const meanAnomaly = parseFloat(line2.substring(43, 51));\r\n const meanMotion = parseFloat(line2.substring(52, 63));\r\n \r\n // Calculate epoch date\r\n const fullYear = epochYear < 57 ? 2000 + epochYear : 1900 + epochYear;\r\n const epoch = new Date(Date.UTC(fullYear, 0, 1));\r\n epoch.setTime(epoch.getTime() + (epochDay - 1) * SECONDS_PER_DAY * 1000);\r\n \r\n return {\r\n line1,\r\n line2,\r\n epoch,\r\n meanMotion,\r\n eccentricity,\r\n inclination,\r\n raan,\r\n argOfPerigee,\r\n meanAnomaly,\r\n bstar,\r\n };\r\n } catch (e) {\r\n if (import.meta.env.DEV) {\r\n console.error('Failed to parse TLE:', e);\r\n }\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Parse TLE scientific notation (e.g., \" 12345-4\" = 0.12345e-4)\r\n */\r\nfunction parseScientificNotation(str: string): number {\r\n const trimmed = str.trim();\r\n if (trimmed.length === 0) return 0;\r\n \r\n // Find the position of the exponent sign\r\n let mantissa: string;\r\n let exponent: number;\r\n \r\n const lastSignPos = Math.max(trimmed.lastIndexOf('+'), trimmed.lastIndexOf('-'));\r\n if (lastSignPos > 0) {\r\n mantissa = '0.' + trimmed.substring(0, lastSignPos).replace(/[^0-9]/g, '');\r\n exponent = parseInt(trimmed.substring(lastSignPos));\r\n } else {\r\n mantissa = '0.' + trimmed.replace(/[^0-9]/g, '');\r\n exponent = 0;\r\n }\r\n \r\n return parseFloat(mantissa) * Math.pow(10, exponent);\r\n}\r\n\r\n/**\r\n * Simplified SGP4 propagation\r\n * @param tle TLE data\r\n * @param minutesFromEpoch Minutes from TLE epoch\r\n * @returns Position in km (ECI coordinates)\r\n */\r\nexport function propagateSGP4Simple(tle: TLEData, minutesFromEpoch: number): Vector3D {\r\n // Semi-major axis from mean motion\r\n const n = tle.meanMotion * 2 * Math.PI / MINUTES_PER_DAY; // rad/min\r\n const a = Math.pow(EARTH_MU / (n * n / 60 / 60), 1/3); // km\r\n \r\n // Current mean anomaly\r\n const M = (tle.meanAnomaly + (360 * tle.meanMotion * minutesFromEpoch / MINUTES_PER_DAY)) % 360;\r\n const M_rad = M * DEG_TO_RAD;\r\n \r\n // Solve Kepler's equation for eccentric anomaly (simplified Newton-Raphson)\r\n let E = M_rad;\r\n for (let i = 0; i < 10; i++) {\r\n E = M_rad + tle.eccentricity * Math.sin(E);\r\n }\r\n \r\n // True anomaly\r\n const cosE = Math.cos(E);\r\n const sinE = Math.sin(E);\r\n const nu = Math.atan2(\r\n Math.sqrt(1 - tle.eccentricity ** 2) * sinE,\r\n cosE - tle.eccentricity\r\n );\r\n \r\n // Distance\r\n const r = a * (1 - tle.eccentricity * cosE);\r\n \r\n // Position in orbital plane\r\n const xOrb = r * Math.cos(nu);\r\n const yOrb = r * Math.sin(nu);\r\n \r\n // RAAN and inclination with simple precession\r\n const raanRad = tle.raan * DEG_TO_RAD;\r\n const incRad = tle.inclination * DEG_TO_RAD;\r\n const argPeriRad = tle.argOfPerigee * DEG_TO_RAD;\r\n \r\n // Rotation matrices\r\n const cosRaan = Math.cos(raanRad);\r\n const sinRaan = Math.sin(raanRad);\r\n const cosInc = Math.cos(incRad);\r\n const sinInc = Math.sin(incRad);\r\n const cosArgPeri = Math.cos(argPeriRad);\r\n const sinArgPeri = Math.sin(argPeriRad);\r\n \r\n // Transform to ECI\r\n const x = (cosRaan * cosArgPeri - sinRaan * sinArgPeri * cosInc) * xOrb +\r\n (-cosRaan * sinArgPeri - sinRaan * cosArgPeri * cosInc) * yOrb;\r\n const y = (sinRaan * cosArgPeri + cosRaan * sinArgPeri * cosInc) * xOrb +\r\n (-sinRaan * sinArgPeri + cosRaan * cosArgPeri * cosInc) * yOrb;\r\n const z = (sinArgPeri * sinInc) * xOrb + (cosArgPeri * sinInc) * yOrb;\r\n \r\n return { x, y, z };\r\n}\r\n\r\n/**\r\n * Propagate satellite to specific time\r\n * @param satellite Satellite with TLE\r\n * @param time Target time\r\n * @returns Position in km (ECI)\r\n */\r\nexport function propagateSatellite(satellite: Satellite, time: Date): Vector3D | null {\r\n if (!satellite.tle) return null;\r\n \r\n const minutesFromEpoch = (time.getTime() - satellite.tle.epoch.getTime()) / 60000;\r\n return propagateSGP4Simple(satellite.tle, minutesFromEpoch);\r\n}\r\n\r\n/**\r\n * Generate orbit path for a satellite\r\n * @param satellite Satellite with TLE\r\n * @param startTime Start time\r\n * @param duration Duration in minutes\r\n * @param steps Number of steps\r\n */\r\nexport function generateOrbitPath(\r\n satellite: Satellite,\r\n startTime: Date,\r\n duration: number = 90,\r\n steps: number = 180\r\n): OrbitPath | null {\r\n if (!satellite.tle) return null;\r\n \r\n const points: Vector3D[] = [];\r\n const startMinutes = (startTime.getTime() - satellite.tle.epoch.getTime()) / 60000;\r\n \r\n for (let i = 0; i <= steps; i++) {\r\n const minutesFromEpoch = startMinutes + (i / steps) * duration;\r\n const pos = propagateSGP4Simple(satellite.tle, minutesFromEpoch);\r\n \r\n // Convert to scene coordinates\r\n points.push({\r\n x: pos.x * KM_TO_SCENE,\r\n y: pos.z * KM_TO_SCENE, // Swap Y/Z for Three.js\r\n z: pos.y * KM_TO_SCENE,\r\n });\r\n }\r\n \r\n return {\r\n objectId: satellite.id,\r\n points,\r\n timeSpan: duration * 60,\r\n isFuture: true,\r\n color: satellite.color || '#22d3ee',\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// Coverage & Visibility Calculations\r\n// =============================================================================\r\n\r\n/**\r\n * Calculate if a satellite is visible from a ground station\r\n * @param satPos Satellite position (scene units)\r\n * @param gsLatLon Ground station lat/lon\r\n * @param minElevation Minimum elevation angle (degrees)\r\n */\r\nexport function isVisible(\r\n satPos: Vector3D,\r\n gsLatLon: { latitude: number; longitude: number },\r\n minElevation: number = 5\r\n): boolean {\r\n const gsPos = latLonAltToCartesian(gsLatLon.latitude, gsLatLon.longitude, 0);\r\n \r\n // Vector from ground station to satellite\r\n const toSat = {\r\n x: satPos.x - gsPos.x,\r\n y: satPos.y - gsPos.y,\r\n z: satPos.z - gsPos.z,\r\n };\r\n \r\n // Ground station \"up\" vector (normal to Earth surface)\r\n const up = normalize(gsPos);\r\n \r\n // Calculate elevation angle\r\n const elevation = 90 - Math.acos(dot(normalize(toSat), up)) * RAD_TO_DEG;\r\n \r\n return elevation >= minElevation;\r\n}\r\n\r\n/**\r\n * Calculate visibility cone vertices for rendering\r\n * @param gsLatLon Ground station position\r\n * @param minElevation Minimum elevation angle\r\n * @param altitude Altitude for cone apex (km)\r\n * @param segments Number of segments for cone circle\r\n */\r\nexport function calculateVisibilityConeGeometry(\r\n gsLatLon: { latitude: number; longitude: number },\r\n minElevation: number = 5,\r\n altitude: number = 2000,\r\n segments: number = 32\r\n): Vector3D[] {\r\n const gsPos = latLonAltToCartesian(gsLatLon.latitude, gsLatLon.longitude, 0);\r\n const vertices: Vector3D[] = [];\r\n \r\n // Cone apex is at ground station\r\n vertices.push(gsPos);\r\n \r\n // Calculate cone opening angle\r\n const coneAngle = (90 - minElevation) * DEG_TO_RAD;\r\n const coneRadius = altitude * Math.tan(coneAngle);\r\n \r\n // Get local tangent plane vectors\r\n const up = normalize(gsPos);\r\n const east = normalize(cross({ x: 0, y: 1, z: 0 }, up));\r\n const north = cross(up, east);\r\n \r\n // Generate cone base circle\r\n for (let i = 0; i <= segments; i++) {\r\n const angle = (i / segments) * Math.PI * 2;\r\n const basePoint = {\r\n x: gsPos.x + up.x * altitude * KM_TO_SCENE + \r\n (east.x * Math.cos(angle) + north.x * Math.sin(angle)) * coneRadius * KM_TO_SCENE,\r\n y: gsPos.y + up.y * altitude * KM_TO_SCENE + \r\n (east.y * Math.cos(angle) + north.y * Math.sin(angle)) * coneRadius * KM_TO_SCENE,\r\n z: gsPos.z + up.z * altitude * KM_TO_SCENE + \r\n (east.z * Math.cos(angle) + north.z * Math.sin(angle)) * coneRadius * KM_TO_SCENE,\r\n };\r\n vertices.push(basePoint);\r\n }\r\n \r\n return vertices;\r\n}\r\n\r\n/**\r\n * Generate footprint polygon for a satellite\r\n * @param satPos Satellite position (scene units)\r\n * @param minElevation Minimum elevation angle\r\n * @param segments Number of segments\r\n */\r\nexport function calculateFootprint(\r\n satPos: Vector3D,\r\n minElevation: number = 5,\r\n segments: number = 36\r\n): Array<{ latitude: number; longitude: number }> {\r\n const satLla = cartesianToLatLonAlt(satPos);\r\n const footprint: Array<{ latitude: number; longitude: number }> = [];\r\n \r\n // Simplified footprint calculation\r\n // Central angle of visibility circle\r\n const earthAngularRadius = Math.asin(EARTH_RADIUS_KM / (EARTH_RADIUS_KM + satLla.altitude));\r\n const elevAngle = minElevation * DEG_TO_RAD;\r\n const nadir = Math.PI / 2 - elevAngle - earthAngularRadius;\r\n const footprintRadius = nadir * RAD_TO_DEG;\r\n \r\n for (let i = 0; i < segments; i++) {\r\n const bearing = (i / segments) * 360;\r\n const point = destinationPoint(\r\n satLla.latitude,\r\n satLla.longitude,\r\n footprintRadius * 111.32, // Approximate km per degree\r\n bearing\r\n );\r\n footprint.push(point);\r\n }\r\n \r\n return footprint;\r\n}\r\n\r\n/**\r\n * Calculate destination point given start, distance, and bearing\r\n */\r\nfunction destinationPoint(\r\n lat: number,\r\n lon: number,\r\n distanceKm: number,\r\n bearing: number\r\n): { latitude: number; longitude: number } {\r\n const R = EARTH_RADIUS_KM;\r\n const d = distanceKm / R;\r\n const brng = bearing * DEG_TO_RAD;\r\n const lat1 = lat * DEG_TO_RAD;\r\n const lon1 = lon * DEG_TO_RAD;\r\n \r\n const lat2 = Math.asin(\r\n Math.sin(lat1) * Math.cos(d) +\r\n Math.cos(lat1) * Math.sin(d) * Math.cos(brng)\r\n );\r\n \r\n const lon2 = lon1 + Math.atan2(\r\n Math.sin(brng) * Math.sin(d) * Math.cos(lat1),\r\n Math.cos(d) - Math.sin(lat1) * Math.sin(lat2)\r\n );\r\n \r\n return {\r\n latitude: lat2 * RAD_TO_DEG,\r\n longitude: lon2 * RAD_TO_DEG,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// Hexagonal Grid for Coverage\r\n// =============================================================================\r\n\r\n/**\r\n * Generate a hexagonal grid covering the globe\r\n * @param resolution Grid resolution (lower = fewer hexagons)\r\n */\r\nexport function generateHexGrid(resolution: number = 2): CoverageHexGrid {\r\n const hexagons: CoverageHexGrid['hexagons'] = [];\r\n \r\n // Simplified hex grid generation (not true H3, but visually similar)\r\n const latStep = 180 / (resolution * 8);\r\n const lonStep = 360 / (resolution * 16);\r\n \r\n let id = 0;\r\n for (let lat = -90 + latStep / 2; lat < 90; lat += latStep) {\r\n // Adjust longitude step for latitude (narrower near poles)\r\n const adjustedLonStep = lonStep / Math.cos(lat * DEG_TO_RAD);\r\n const offset = (Math.floor((lat + 90) / latStep) % 2) * (adjustedLonStep / 2);\r\n \r\n for (let lon = -180 + offset; lon < 180; lon += adjustedLonStep) {\r\n hexagons.push({\r\n id: `hex_${id++}`,\r\n value: 0,\r\n center: { latitude: lat, longitude: lon },\r\n });\r\n }\r\n }\r\n \r\n return {\r\n resolution,\r\n hexagons,\r\n colorScale: { min: '#1a1a2e', max: '#00ff88' },\r\n };\r\n}\r\n\r\n/**\r\n * Update hex grid coverage values based on satellite footprints\r\n */\r\nexport function updateHexGridCoverage(\r\n grid: CoverageHexGrid,\r\n satellites: Satellite[],\r\n time: Date\r\n): CoverageHexGrid {\r\n // Clone grid\r\n const updatedGrid = {\r\n ...grid,\r\n hexagons: grid.hexagons.map(h => ({ ...h, value: 0 })),\r\n };\r\n \r\n satellites.forEach(sat => {\r\n const pos = propagateSatellite(sat, time);\r\n if (!pos) return;\r\n \r\n const scenePos = {\r\n x: pos.x * KM_TO_SCENE,\r\n y: pos.z * KM_TO_SCENE,\r\n z: pos.y * KM_TO_SCENE,\r\n };\r\n \r\n const footprint = calculateFootprint(scenePos);\r\n \r\n // Check each hexagon\r\n updatedGrid.hexagons.forEach(hex => {\r\n const inFootprint = isPointInPolygon(hex.center, footprint);\r\n if (inFootprint) {\r\n hex.value = Math.min(1, hex.value + 0.2);\r\n }\r\n });\r\n });\r\n \r\n return updatedGrid;\r\n}\r\n\r\n/**\r\n * Point-in-polygon test (simplified)\r\n */\r\nfunction isPointInPolygon(\r\n point: { latitude: number; longitude: number },\r\n polygon: Array<{ latitude: number; longitude: number }>\r\n): boolean {\r\n let inside = false;\r\n const n = polygon.length;\r\n \r\n for (let i = 0, j = n - 1; i < n; j = i++) {\r\n const xi = polygon[i].longitude;\r\n const yi = polygon[i].latitude;\r\n const xj = polygon[j].longitude;\r\n const yj = polygon[j].latitude;\r\n \r\n if (((yi > point.latitude) !== (yj > point.latitude)) &&\r\n (point.longitude < (xj - xi) * (point.latitude - yi) / (yj - yi) + xi)) {\r\n inside = !inside;\r\n }\r\n }\r\n \r\n return inside;\r\n}\r\n\r\n// =============================================================================\r\n// Vector Math Utilities\r\n// =============================================================================\r\n\r\nexport function dot(a: Vector3D, b: Vector3D): number {\r\n return a.x * b.x + a.y * b.y + a.z * b.z;\r\n}\r\n\r\nexport function cross(a: Vector3D, b: Vector3D): Vector3D {\r\n return {\r\n x: a.y * b.z - a.z * b.y,\r\n y: a.z * b.x - a.x * b.z,\r\n z: a.x * b.y - a.y * b.x,\r\n };\r\n}\r\n\r\nexport function magnitude(v: Vector3D): number {\r\n return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);\r\n}\r\n\r\nexport function normalize(v: Vector3D): Vector3D {\r\n const m = magnitude(v);\r\n if (m === 0) return { x: 0, y: 0, z: 0 };\r\n return { x: v.x / m, y: v.y / m, z: v.z / m };\r\n}\r\n\r\nexport function subtract(a: Vector3D, b: Vector3D): Vector3D {\r\n return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };\r\n}\r\n\r\nexport function add(a: Vector3D, b: Vector3D): Vector3D {\r\n return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };\r\n}\r\n\r\nexport function scale(v: Vector3D, s: number): Vector3D {\r\n return { x: v.x * s, y: v.y * s, z: v.z * s };\r\n}\r\n\r\nexport function distance(a: Vector3D, b: Vector3D): number {\r\n return magnitude(subtract(a, b));\r\n}\r\n\r\nexport function lerp(a: Vector3D, b: Vector3D, t: number): Vector3D {\r\n return {\r\n x: a.x + (b.x - a.x) * t,\r\n y: a.y + (b.y - a.y) * t,\r\n z: a.z + (b.z - a.z) * t,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// Animation Utilities\r\n// =============================================================================\r\n\r\n/**\r\n * Ease-out cubic function\r\n */\r\nexport function easeOutCubic(t: number): number {\r\n return 1 - Math.pow(1 - t, 3);\r\n}\r\n\r\n/**\r\n * Ease-in-out cubic function\r\n */\r\nexport function easeInOutCubic(t: number): number {\r\n return t < 0.5\r\n ? 4 * t * t * t\r\n : 1 - Math.pow(-2 * t + 2, 3) / 2;\r\n}\r\n\r\n/**\r\n * Smooth step function\r\n */\r\nexport function smoothstep(edge0: number, edge1: number, x: number): number {\r\n const t = Math.max(0, Math.min(1, (x - edge0) / (edge1 - edge0)));\r\n return t * t * (3 - 2 * t);\r\n}\r\n\r\n// =============================================================================\r\n// Color Utilities\r\n// =============================================================================\r\n\r\n/**\r\n * Interpolate between two colors\r\n */\r\nexport function lerpColor(color1: string, color2: string, t: number): string {\r\n const c1 = hexToRgb(color1);\r\n const c2 = hexToRgb(color2);\r\n \r\n if (!c1 || !c2) return color1;\r\n \r\n const r = Math.round(c1.r + (c2.r - c1.r) * t);\r\n const g = Math.round(c1.g + (c2.g - c1.g) * t);\r\n const b = Math.round(c1.b + (c2.b - c1.b) * t);\r\n \r\n return `rgb(${r}, ${g}, ${b})`;\r\n}\r\n\r\n/**\r\n * Hex to RGB\r\n */\r\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : null;\r\n}\r\n\r\n/**\r\n * Get color from value (0-1) on a gradient scale\r\n */\r\nexport function getGradientColor(\r\n value: number,\r\n colors: string[] = ['#1a1a2e', '#0f3460', '#16c79a', '#ff6b6b']\r\n): string {\r\n const clampedValue = Math.max(0, Math.min(1, value));\r\n const scaledValue = clampedValue * (colors.length - 1);\r\n const index = Math.floor(scaledValue);\r\n const t = scaledValue - index;\r\n \r\n if (index >= colors.length - 1) return colors[colors.length - 1];\r\n \r\n return lerpColor(colors[index], colors[index + 1], t);\r\n}\r\n\r\n// =============================================================================\r\n// Format Utilities\r\n// =============================================================================\r\n\r\n/**\r\n * Format time duration as HH:MM:SS\r\n */\r\nexport function formatDuration(seconds: number): string {\r\n const h = Math.floor(seconds / 3600);\r\n const m = Math.floor((seconds % 3600) / 60);\r\n const s = Math.floor(seconds % 60);\r\n \r\n return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;\r\n}\r\n\r\n/**\r\n * Format distance in appropriate units\r\n */\r\nexport function formatDistance(km: number): string {\r\n if (km < 1) {\r\n return `${(km * 1000).toFixed(0)} m`;\r\n } else if (km < 1000) {\r\n return `${km.toFixed(1)} km`;\r\n } else if (km < AU_KM / 100) {\r\n return `${(km / 1000).toFixed(2)} thousand km`;\r\n } else {\r\n return `${(km / AU_KM).toFixed(4)} AU`;\r\n }\r\n}\r\n\r\n/**\r\n * Format velocity\r\n */\r\nexport function formatVelocity(kmPerSec: number): string {\r\n return `${kmPerSec.toFixed(3)} km/s`;\r\n}\r\n\r\n/**\r\n * Format date/time for display\r\n */\r\nexport function formatDateTime(date: Date): string {\r\n return date.toISOString().replace('T', ' ').split('.')[0] + ' UTC';\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @zendir/ui - 3D Components
3
+ *
4
+ * ZenSpace3D uses Cesium by default when installed (optional peer); falls back to Three.js.
5
+ * Install `cesium` for the best globe/orbit experience; otherwise Three.js is used.
6
+ *
7
+ * Components:
8
+ * - ZenSpace3D: Unified 3D space visualization (Cesium default, Three.js fallback)
9
+ * - EarthViewer: Earth-focused 3D (Three.js, legacy)
10
+ * - SolarSystemViewer: Solar system (Three.js, legacy)
11
+ */
12
+ export { ZenSpace3D, default as ZenSpace3DDefault } from './ZenSpace3D';
13
+ export { ZenSpace3DCesium } from './ZenSpace3DCesium';
14
+ export type { ZenSpace3DCesiumProps } from './ZenSpace3DCesium';
15
+ export type { ZenSpace3DProps, ZenSpace3DHandle, ViewMode, CameraMode, ObjectCategory, SpaceObject, Satellite, Debris, SpaceStation, Asteroid, TLEData, OrbitPath, ManeuverNode, VisibilityCone, SatelliteCoverage, CoverageRegion, CoverageHexGrid, OverpassInfo, OrbitDesignArc, CoverageCell, TimeState, SelectionState, CameraState, LayerVisibility, ToolType, ToolState, Vector3D, LatLonAlt, SphericalCoords, SceneConfig, SceneObject, ZenSpace3DCallbacks, } from './ZenSpace3DTypes';
16
+ export { latLonAltToCartesian, cartesianToLatLonAlt, cartesianToSpherical, sphericalToCartesian, eciToEcef, calculateGMST, dateToJulianDate, parseTLE, propagateSGP4Simple, propagateSatellite, generateOrbitPath, isVisible, calculateVisibilityConeGeometry, calculateFootprint, generateHexGrid, updateHexGridCoverage, dot, cross, magnitude, normalize, subtract, add, scale, distance, lerp, easeOutCubic, easeInOutCubic, smoothstep, lerpColor, hexToRgb, getGradientColor, formatDuration, formatDistance, formatVelocity, formatDateTime, EARTH_RADIUS_KM, EARTH_MU, AU_KM, DEG_TO_RAD, RAD_TO_DEG, J2000_EPOCH, SCENE_EARTH_RADIUS, KM_TO_SCENE, } from './ZenSpace3DUtils';
17
+ export { atmosphereVertexShader, atmosphereFragmentShader, starsVertexShader, starsFragmentShader, coverageVertexShader, coverageFragmentShader, visibilityConeVertexShader, visibilityConeFragmentShader, orbitLineVertexShader, orbitLineFragmentShader, objectGlowVertexShader, objectGlowFragmentShader, selectionRingVertexShader, selectionRingFragmentShader, terminatorVertexShader, terminatorFragmentShader, gridVertexShader, gridFragmentShader, planetRingVertexShader, planetRingFragmentShader, debrisVertexShader, debrisFragmentShader, createAtmosphereUniforms, createStarsUniforms, createVisibilityConeUniforms, } from './ZenSpace3DShaders';
18
+ export { loadThree, isThreeLoaded } from './threeLoader';
19
+ export type { ThreeModule, OrbitControlsType } from './threeLoader';
20
+ export { EarthViewer } from './EarthViewer';
21
+ export type { EarthViewerProps } from './EarthViewer';
22
+ export { SolarSystemViewer } from './SolarSystemViewer';
23
+ export type { SolarSystemViewerProps, PlanetPosition } from './SolarSystemViewer';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shared Three.js loader
3
+ *
4
+ * Ensures only one instance of Three.js is loaded across all 3D components.
5
+ * This prevents the "Multiple instances of Three.js being imported" warning.
6
+ */
7
+ export type ThreeModule = typeof import('three');
8
+ export type OrbitControlsType = typeof import('three/examples/jsm/controls/OrbitControls.js').OrbitControls;
9
+ interface ThreeLoaderResult {
10
+ THREE: ThreeModule;
11
+ OrbitControls: OrbitControlsType;
12
+ }
13
+ /**
14
+ * Load Three.js and OrbitControls
15
+ * Returns cached instance if already loaded
16
+ */
17
+ export declare function loadThree(): Promise<ThreeLoaderResult>;
18
+ /**
19
+ * Check if Three.js is already loaded
20
+ */
21
+ export declare function isThreeLoaded(): boolean;
22
+ export {};
@@ -0,0 +1,18 @@
1
+ let loadPromise = null;
2
+ async function loadThree() {
3
+ if (loadPromise) {
4
+ return loadPromise;
5
+ }
6
+ loadPromise = (async () => {
7
+ const [THREE, { OrbitControls }] = await Promise.all([
8
+ import("three"),
9
+ import("three/examples/jsm/controls/OrbitControls.js")
10
+ ]);
11
+ return { THREE, OrbitControls };
12
+ })();
13
+ return loadPromise;
14
+ }
15
+ export {
16
+ loadThree
17
+ };
18
+ //# sourceMappingURL=threeLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threeLoader.js","sources":["../../../src/react/3d/threeLoader.ts"],"sourcesContent":["/**\r\n * Shared Three.js loader\r\n * \r\n * Ensures only one instance of Three.js is loaded across all 3D components.\r\n * This prevents the \"Multiple instances of Three.js being imported\" warning.\r\n */\r\n\r\nexport type ThreeModule = typeof import('three');\r\nexport type OrbitControlsType = typeof import('three/examples/jsm/controls/OrbitControls.js').OrbitControls;\r\n\r\ninterface ThreeLoaderResult {\r\n THREE: ThreeModule;\r\n OrbitControls: OrbitControlsType;\r\n}\r\n\r\n// Cached promise to ensure single load\r\nlet loadPromise: Promise<ThreeLoaderResult> | null = null;\r\n\r\n/**\r\n * Load Three.js and OrbitControls\r\n * Returns cached instance if already loaded\r\n */\r\nexport async function loadThree(): Promise<ThreeLoaderResult> {\r\n if (loadPromise) {\r\n return loadPromise;\r\n }\r\n\r\n loadPromise = (async () => {\r\n const [THREE, { OrbitControls }] = await Promise.all([\r\n import('three'),\r\n import('three/examples/jsm/controls/OrbitControls.js'),\r\n ]);\r\n \r\n return { THREE, OrbitControls };\r\n })();\r\n\r\n return loadPromise;\r\n}\r\n\r\n/**\r\n * Check if Three.js is already loaded\r\n */\r\nexport function isThreeLoaded(): boolean {\r\n return loadPromise !== null;\r\n}\r\n"],"names":[],"mappings":"AAgBA,IAAI,cAAiD;AAMrD,eAAsB,YAAwC;AAC5D,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,iBAAe,YAAY;AACzB,UAAM,CAAC,OAAO,EAAE,cAAA,CAAe,IAAI,MAAM,QAAQ,IAAI;AAAA,MACnD,OAAO,OAAO;AAAA,MACd,OAAO,8CAA8C;AAAA,IAAA,CACtD;AAED,WAAO,EAAE,OAAO,cAAA;AAAA,EAClB,GAAA;AAEA,SAAO;AACT;"}
@@ -0,0 +1,25 @@
1
+ import { default as React } from 'react';
2
+
3
+ export type ClassificationLevel = 'unclassified' | 'cui' | 'controlled' | 'confidential' | 'secret' | 'top-secret' | 'top-secret-sci';
4
+ export interface ClassificationBannerProps {
5
+ /** Classification level */
6
+ classification: ClassificationLevel;
7
+ /** Custom label (overrides default text) */
8
+ label?: string;
9
+ /** Position of the banner */
10
+ position?: 'top' | 'bottom';
11
+ /** Custom className */
12
+ className?: string;
13
+ }
14
+ /**
15
+ * ClassificationBanner - Pure React classification banner
16
+ *
17
+ * Displays security classification level. Required for U.S. Space Force applications.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <ClassificationBanner classification="unclassified" />
22
+ * <ClassificationBanner classification="secret" position="bottom" />
23
+ * ```
24
+ */
25
+ export declare const ClassificationBanner: React.NamedExoticComponent<ClassificationBannerProps>;
@@ -0,0 +1,83 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { classNames } from "../utils/index.js";
4
+ import { useTheme } from "../theme/ThemeProvider.js";
5
+ const CLASSIFICATION_STYLES = {
6
+ unclassified: {
7
+ bg: "#007a33",
8
+ text: "#ffffff",
9
+ label: "UNCLASSIFIED"
10
+ },
11
+ cui: {
12
+ bg: "#502b85",
13
+ text: "#ffffff",
14
+ label: "CUI"
15
+ },
16
+ controlled: {
17
+ bg: "#502b85",
18
+ text: "#ffffff",
19
+ label: "CONTROLLED"
20
+ },
21
+ confidential: {
22
+ bg: "#0033a0",
23
+ text: "#ffffff",
24
+ label: "CONFIDENTIAL"
25
+ },
26
+ secret: {
27
+ bg: "#c8102e",
28
+ text: "#ffffff",
29
+ label: "SECRET"
30
+ },
31
+ "top-secret": {
32
+ bg: "#ff8c00",
33
+ text: "#000000",
34
+ label: "TOP SECRET"
35
+ },
36
+ "top-secret-sci": {
37
+ bg: "#fce83a",
38
+ text: "#000000",
39
+ label: "TOP SECRET//SCI"
40
+ }
41
+ };
42
+ const ClassificationBanner = memo(function ClassificationBanner2({
43
+ classification,
44
+ label,
45
+ position = "top",
46
+ className = ""
47
+ }) {
48
+ const { tokens } = useTheme();
49
+ const style = CLASSIFICATION_STYLES[classification] ?? CLASSIFICATION_STYLES.unclassified;
50
+ const displayLabel = label ?? style.label;
51
+ return /* @__PURE__ */ jsx(
52
+ "div",
53
+ {
54
+ className: classNames("zendir-classification-banner", className),
55
+ role: "banner",
56
+ "aria-label": `Security classification: ${displayLabel}`,
57
+ style: {
58
+ position: "fixed",
59
+ left: 0,
60
+ right: 0,
61
+ [position]: 0,
62
+ zIndex: 9999,
63
+ display: "flex",
64
+ alignItems: "center",
65
+ justifyContent: "center",
66
+ height: 20,
67
+ backgroundColor: style.bg,
68
+ color: style.text,
69
+ fontSize: tokens.typography.fontSize.xs,
70
+ fontWeight: tokens.typography.fontWeight.bold,
71
+ letterSpacing: tokens.typography.letterSpacing.wide,
72
+ textTransform: "uppercase",
73
+ fontFamily: tokens.typography.fontFamily.primary,
74
+ userSelect: "none"
75
+ },
76
+ children: displayLabel
77
+ }
78
+ );
79
+ });
80
+ export {
81
+ ClassificationBanner
82
+ };
83
+ //# sourceMappingURL=ClassificationBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClassificationBanner.js","sources":["../../../src/react/astro/ClassificationBanner.tsx"],"sourcesContent":["/**\n * @zendir/ui - ClassificationBanner Component (Pure React)\n * \n * Security classification banner following Astro UX Design System.\n * Required for U.S. Space Force applications to display security classification.\n * \n * Features:\n * - Theme-integrated via useTheme()\n * - Official classification colors per DoD standards\n * - Top/bottom positioning\n * - Accessible (screen reader announces classification)\n */\n\nimport React, { memo } from 'react';\nimport { useTheme } from '../theme';\nimport { classNames } from '../utils';\n\nexport type ClassificationLevel =\n | 'unclassified'\n | 'cui'\n | 'controlled'\n | 'confidential'\n | 'secret'\n | 'top-secret'\n | 'top-secret-sci';\n\nexport interface ClassificationBannerProps {\n /** Classification level */\n classification: ClassificationLevel;\n /** Custom label (overrides default text) */\n label?: string;\n /** Position of the banner */\n position?: 'top' | 'bottom';\n /** Custom className */\n className?: string;\n}\n\n// Official DoD classification colors\nconst CLASSIFICATION_STYLES: Record<\n ClassificationLevel,\n { bg: string; text: string; label: string }\n> = {\n unclassified: {\n bg: '#007a33',\n text: '#ffffff',\n label: 'UNCLASSIFIED',\n },\n cui: {\n bg: '#502b85',\n text: '#ffffff',\n label: 'CUI',\n },\n controlled: {\n bg: '#502b85',\n text: '#ffffff',\n label: 'CONTROLLED',\n },\n confidential: {\n bg: '#0033a0',\n text: '#ffffff',\n label: 'CONFIDENTIAL',\n },\n secret: {\n bg: '#c8102e',\n text: '#ffffff',\n label: 'SECRET',\n },\n 'top-secret': {\n bg: '#ff8c00',\n text: '#000000',\n label: 'TOP SECRET',\n },\n 'top-secret-sci': {\n bg: '#fce83a',\n text: '#000000',\n label: 'TOP SECRET//SCI',\n },\n};\n\n/**\n * ClassificationBanner - Pure React classification banner\n * \n * Displays security classification level. Required for U.S. Space Force applications.\n * \n * @example\n * ```tsx\n * <ClassificationBanner classification=\"unclassified\" />\n * <ClassificationBanner classification=\"secret\" position=\"bottom\" />\n * ```\n */\nexport const ClassificationBanner = memo(function ClassificationBanner({\n classification,\n label,\n position = 'top',\n className = '',\n}: ClassificationBannerProps): React.ReactElement {\n const { tokens } = useTheme();\n const style = CLASSIFICATION_STYLES[classification] ?? CLASSIFICATION_STYLES.unclassified;\n const displayLabel = label ?? style.label;\n\n return (\n <div\n className={classNames('zendir-classification-banner', className)}\n role=\"banner\"\n aria-label={`Security classification: ${displayLabel}`}\n style={{\n position: 'fixed',\n left: 0,\n right: 0,\n [position]: 0,\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: 20,\n backgroundColor: style.bg,\n color: style.text,\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.bold,\n letterSpacing: tokens.typography.letterSpacing.wide,\n textTransform: 'uppercase',\n fontFamily: tokens.typography.fontFamily.primary,\n userSelect: 'none',\n }}\n >\n {displayLabel}\n </div>\n );\n});\n"],"names":["ClassificationBanner"],"mappings":";;;;AAsCA,MAAM,wBAGF;AAAA,EACF,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,KAAK;AAAA,IACH,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,QAAQ;AAAA,IACN,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,kBAAkB;AAAA,IAChB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAEX;AAaO,MAAM,uBAAuB,KAAK,SAASA,sBAAqB;AAAA,EACrE;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AACd,GAAkD;AAChD,QAAM,EAAE,OAAA,IAAW,SAAA;AACnB,QAAM,QAAQ,sBAAsB,cAAc,KAAK,sBAAsB;AAC7E,QAAM,eAAe,SAAS,MAAM;AAEpC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,WAAW,gCAAgC,SAAS;AAAA,MAC/D,MAAK;AAAA,MACL,cAAY,4BAA4B,YAAY;AAAA,MACpD,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,OAAO;AAAA,QACP,CAAC,QAAQ,GAAG;AAAA,QACZ,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,iBAAiB,MAAM;AAAA,QACvB,OAAO,MAAM;AAAA,QACb,UAAU,OAAO,WAAW,SAAS;AAAA,QACrC,YAAY,OAAO,WAAW,WAAW;AAAA,QACzC,eAAe,OAAO,WAAW,cAAc;AAAA,QAC/C,eAAe;AAAA,QACf,YAAY,OAAO,WAAW,WAAW;AAAA,QACzC,YAAY;AAAA,MAAA;AAAA,MAGb,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;"}