@zendir/ui 0.4.1 → 0.6.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 (391) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +640 -631
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/index.js +17 -221
  5. package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
  6. package/dist/react/3d/CesiumCaptureSource.js +364 -283
  7. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  8. package/dist/react/3d/ZenSpace3D.d.ts +2 -3
  9. package/dist/react/3d/ZenSpace3D.js +1681 -1237
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -1
  11. package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
  12. package/dist/react/3d/ZenSpace3DCesium.js +513 -560
  13. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
  14. package/dist/react/3d/ZenSpace3DShaders.js +61 -66
  15. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
  16. package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
  17. package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
  18. package/dist/react/3d/ZenSpace3DUtils.js +37 -24
  19. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  20. package/dist/react/3d/capturePngAnalysis.js +42 -36
  21. package/dist/react/3d/capturePngAnalysis.js.map +1 -1
  22. package/dist/react/3d/index.d.ts +3 -3
  23. package/dist/react/3d/index.js +5 -53
  24. package/dist/react/3d/threeLoader.d.ts +1 -1
  25. package/dist/react/3d/threeLoader.js +23 -18
  26. package/dist/react/3d/threeLoader.js.map +1 -1
  27. package/dist/react/astro/ClassificationBanner.d.ts +2 -3
  28. package/dist/react/astro/ClassificationBanner.js +95 -79
  29. package/dist/react/astro/ClassificationBanner.js.map +1 -1
  30. package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
  31. package/dist/react/astro/GlobalStatusBar.js +157 -163
  32. package/dist/react/astro/GlobalStatusBar.js.map +1 -1
  33. package/dist/react/astro/MissionClock.d.ts +7 -8
  34. package/dist/react/astro/MissionClock.js +377 -400
  35. package/dist/react/astro/MissionClock.js.map +1 -1
  36. package/dist/react/astro/MonitoringIcon.d.ts +1 -2
  37. package/dist/react/astro/MonitoringIcon.js +422 -358
  38. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  39. package/dist/react/astro/Notification.d.ts +1 -2
  40. package/dist/react/astro/Notification.js +229 -126
  41. package/dist/react/astro/Notification.js.map +1 -1
  42. package/dist/react/astro/Progress.d.ts +0 -1
  43. package/dist/react/astro/Progress.js +199 -141
  44. package/dist/react/astro/Progress.js.map +1 -1
  45. package/dist/react/astro/SimulationControls.d.ts +3 -4
  46. package/dist/react/astro/SimulationControls.js +596 -650
  47. package/dist/react/astro/SimulationControls.js.map +1 -1
  48. package/dist/react/astro/StatusIndicator.d.ts +0 -1
  49. package/dist/react/astro/StatusIndicator.js +236 -170
  50. package/dist/react/astro/StatusIndicator.js.map +1 -1
  51. package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
  52. package/dist/react/astro/UnifiedTimeline.js +2345 -2392
  53. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  54. package/dist/react/astro/index.d.ts +5 -5
  55. package/dist/react/astro/index.js +1 -25
  56. package/dist/react/cards/AccessCard.d.ts +0 -1
  57. package/dist/react/cards/AccessCard.js +471 -405
  58. package/dist/react/cards/AccessCard.js.map +1 -1
  59. package/dist/react/cards/OrbitCard.d.ts +0 -1
  60. package/dist/react/cards/OrbitCard.js +487 -364
  61. package/dist/react/cards/OrbitCard.js.map +1 -1
  62. package/dist/react/cards/SpacecraftCard.d.ts +0 -1
  63. package/dist/react/cards/SpacecraftCard.js +813 -925
  64. package/dist/react/cards/SpacecraftCard.js.map +1 -1
  65. package/dist/react/cards/TelemetryCard.d.ts +0 -1
  66. package/dist/react/cards/TelemetryCard.js +1055 -732
  67. package/dist/react/cards/TelemetryCard.js.map +1 -1
  68. package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
  69. package/dist/react/cards/TelemetryStreamCard.js +323 -297
  70. package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
  71. package/dist/react/cards/index.d.ts +1 -1
  72. package/dist/react/cards/index.js +1 -8
  73. package/dist/react/charts/GroundTrackMap.d.ts +6 -7
  74. package/dist/react/charts/GroundTrackMap.js +1377 -1256
  75. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  76. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
  77. package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
  78. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
  79. package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
  80. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
  81. package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
  82. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
  83. package/dist/react/charts/index.d.ts +1 -1
  84. package/dist/react/charts/index.js +7 -100
  85. package/dist/react/charts/unified/AstroChart.d.ts +1 -2
  86. package/dist/react/charts/unified/AstroChart.js +1331 -1411
  87. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  88. package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
  89. package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
  90. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
  91. package/dist/react/charts/unified/domain.d.ts +12 -13
  92. package/dist/react/charts/unified/domain.js +3999 -3145
  93. package/dist/react/charts/unified/domain.js.map +1 -1
  94. package/dist/react/charts/unified/generators.d.ts +3 -4
  95. package/dist/react/charts/unified/generators.js +561 -498
  96. package/dist/react/charts/unified/generators.js.map +1 -1
  97. package/dist/react/charts/unified/index.d.ts +1 -1
  98. package/dist/react/charts/unified/presets.d.ts +14 -15
  99. package/dist/react/charts/unified/presets.js +857 -994
  100. package/dist/react/charts/unified/presets.js.map +1 -1
  101. package/dist/react/charts/unified/sync.d.ts +2 -3
  102. package/dist/react/charts/unified/sync.js +229 -195
  103. package/dist/react/charts/unified/sync.js.map +1 -1
  104. package/dist/react/charts/unified/theme.d.ts +11 -12
  105. package/dist/react/charts/unified/theme.js +606 -642
  106. package/dist/react/charts/unified/theme.js.map +1 -1
  107. package/dist/react/charts/unified/types.d.ts +32 -33
  108. package/dist/react/charts/unified/useChartStream.d.ts +1 -2
  109. package/dist/react/charts/unified/useChartStream.js +203 -216
  110. package/dist/react/charts/unified/useChartStream.js.map +1 -1
  111. package/dist/react/chatgpt/AppCard.d.ts +1 -2
  112. package/dist/react/chatgpt/index.d.ts +7 -7
  113. package/dist/react/chatgpt/index.js +160 -139
  114. package/dist/react/chatgpt/index.js.map +1 -1
  115. package/dist/react/context/CategoryContext.d.ts +0 -1
  116. package/dist/react/context/CategoryContext.js +78 -29
  117. package/dist/react/context/CategoryContext.js.map +1 -1
  118. package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
  119. package/dist/react/context/DisplaySettingsContext.js +205 -156
  120. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  121. package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
  122. package/dist/react/context/SpatialSelectionContext.js +36 -7
  123. package/dist/react/context/SpatialSelectionContext.js.map +1 -1
  124. package/dist/react/core/data/DataTable.d.ts +3 -4
  125. package/dist/react/core/data/DataTable.js +473 -440
  126. package/dist/react/core/data/DataTable.js.map +1 -1
  127. package/dist/react/core/data/DataValue.d.ts +4 -5
  128. package/dist/react/core/data/DataValue.js +605 -538
  129. package/dist/react/core/data/DataValue.js.map +1 -1
  130. package/dist/react/core/data/propertyConfig.d.ts +1 -2
  131. package/dist/react/core/data/propertyConfig.js +446 -382
  132. package/dist/react/core/data/propertyConfig.js.map +1 -1
  133. package/dist/react/core/display/AstroIcon.d.ts +4 -5
  134. package/dist/react/core/display/AstroIcon.js +339 -429
  135. package/dist/react/core/display/AstroIcon.js.map +1 -1
  136. package/dist/react/core/display/Badge.d.ts +2 -3
  137. package/dist/react/core/display/Badge.js +131 -131
  138. package/dist/react/core/display/Badge.js.map +1 -1
  139. package/dist/react/core/display/CardHeader.d.ts +0 -1
  140. package/dist/react/core/display/CardHeader.js +398 -311
  141. package/dist/react/core/display/CardHeader.js.map +1 -1
  142. package/dist/react/core/display/Container.d.ts +2 -3
  143. package/dist/react/core/display/Container.js +640 -668
  144. package/dist/react/core/display/Container.js.map +1 -1
  145. package/dist/react/core/display/CopyButton.d.ts +1 -2
  146. package/dist/react/core/display/CopyButton.js +158 -101
  147. package/dist/react/core/display/CopyButton.js.map +1 -1
  148. package/dist/react/core/display/GlassCard.d.ts +3 -4
  149. package/dist/react/core/display/GlassCard.js +416 -369
  150. package/dist/react/core/display/GlassCard.js.map +1 -1
  151. package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
  152. package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
  153. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
  154. package/dist/react/core/display/Icon.d.ts +2 -3
  155. package/dist/react/core/display/Icon.js +172 -143
  156. package/dist/react/core/display/Icon.js.map +1 -1
  157. package/dist/react/core/display/Typography.d.ts +24 -25
  158. package/dist/react/core/display/Typography.js +360 -178
  159. package/dist/react/core/display/Typography.js.map +1 -1
  160. package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
  161. package/dist/react/core/feedback/ConfirmDialog.js +343 -304
  162. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
  163. package/dist/react/core/feedback/Dialog.d.ts +2 -3
  164. package/dist/react/core/feedback/Dialog.js +189 -197
  165. package/dist/react/core/feedback/Dialog.js.map +1 -1
  166. package/dist/react/core/feedback/Toast.d.ts +2 -3
  167. package/dist/react/core/feedback/Toast.js +346 -207
  168. package/dist/react/core/feedback/Toast.js.map +1 -1
  169. package/dist/react/core/index.d.ts +26 -26
  170. package/dist/react/core/index.js +7 -119
  171. package/dist/react/core/inputs/Button.d.ts +2 -3
  172. package/dist/react/core/inputs/Button.js +281 -304
  173. package/dist/react/core/inputs/Button.js.map +1 -1
  174. package/dist/react/core/inputs/Checkbox.d.ts +2 -3
  175. package/dist/react/core/inputs/Checkbox.js +139 -127
  176. package/dist/react/core/inputs/Checkbox.js.map +1 -1
  177. package/dist/react/core/inputs/Input.d.ts +3 -4
  178. package/dist/react/core/inputs/Input.js +277 -285
  179. package/dist/react/core/inputs/Input.js.map +1 -1
  180. package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
  181. package/dist/react/core/inputs/LimitsBar.js +271 -196
  182. package/dist/react/core/inputs/LimitsBar.js.map +1 -1
  183. package/dist/react/core/inputs/NumberInput.d.ts +2 -3
  184. package/dist/react/core/inputs/NumberInput.js +531 -503
  185. package/dist/react/core/inputs/NumberInput.js.map +1 -1
  186. package/dist/react/core/inputs/PinInput.d.ts +2 -3
  187. package/dist/react/core/inputs/PinInput.js +224 -207
  188. package/dist/react/core/inputs/PinInput.js.map +1 -1
  189. package/dist/react/core/inputs/Select.d.ts +1 -2
  190. package/dist/react/core/inputs/Select.js +298 -299
  191. package/dist/react/core/inputs/Select.js.map +1 -1
  192. package/dist/react/core/inputs/Toggle.d.ts +2 -3
  193. package/dist/react/core/inputs/Toggle.js +142 -148
  194. package/dist/react/core/inputs/Toggle.js.map +1 -1
  195. package/dist/react/core/layout/Box.d.ts +3 -4
  196. package/dist/react/core/layout/Box.js +118 -122
  197. package/dist/react/core/layout/Box.js.map +1 -1
  198. package/dist/react/core/layout/Center.d.ts +0 -1
  199. package/dist/react/core/layout/Center.js +45 -32
  200. package/dist/react/core/layout/Center.js.map +1 -1
  201. package/dist/react/core/layout/Divider.d.ts +1 -2
  202. package/dist/react/core/layout/Divider.js +112 -106
  203. package/dist/react/core/layout/Divider.js.map +1 -1
  204. package/dist/react/core/layout/Flex.d.ts +4 -5
  205. package/dist/react/core/layout/Flex.js +120 -124
  206. package/dist/react/core/layout/Flex.js.map +1 -1
  207. package/dist/react/core/layout/Grid.d.ts +5 -6
  208. package/dist/react/core/layout/Grid.js +131 -138
  209. package/dist/react/core/layout/Grid.js.map +1 -1
  210. package/dist/react/core/layout/Spacer.d.ts +0 -1
  211. package/dist/react/core/layout/Spacer.js +36 -29
  212. package/dist/react/core/layout/Spacer.js.map +1 -1
  213. package/dist/react/core/layout/Stack.d.ts +4 -5
  214. package/dist/react/core/layout/Stack.js +127 -70
  215. package/dist/react/core/layout/Stack.js.map +1 -1
  216. package/dist/react/core/layout/responsive.d.ts +1 -2
  217. package/dist/react/core/layout/responsive.js +25 -19
  218. package/dist/react/core/layout/responsive.js.map +1 -1
  219. package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
  220. package/dist/react/core/layout/useBreakpoint.js +119 -66
  221. package/dist/react/core/layout/useBreakpoint.js.map +1 -1
  222. package/dist/react/core/navigation/AppBar.d.ts +1 -2
  223. package/dist/react/core/navigation/AppBar.js +827 -805
  224. package/dist/react/core/navigation/AppBar.js.map +1 -1
  225. package/dist/react/core/navigation/Pagination.d.ts +2 -3
  226. package/dist/react/core/navigation/Pagination.js +207 -187
  227. package/dist/react/core/navigation/Pagination.js.map +1 -1
  228. package/dist/react/core/navigation/SideNav.d.ts +11 -5
  229. package/dist/react/core/navigation/SideNav.js +857 -602
  230. package/dist/react/core/navigation/SideNav.js.map +1 -1
  231. package/dist/react/core/navigation/Tabs.d.ts +0 -1
  232. package/dist/react/core/navigation/Tabs.js +113 -119
  233. package/dist/react/core/navigation/Tabs.js.map +1 -1
  234. package/dist/react/core/overlays/Popover.d.ts +2 -3
  235. package/dist/react/core/overlays/Popover.js +303 -282
  236. package/dist/react/core/overlays/Popover.js.map +1 -1
  237. package/dist/react/core/overlays/SidePanel.d.ts +1 -2
  238. package/dist/react/core/overlays/SidePanel.js +217 -212
  239. package/dist/react/core/overlays/SidePanel.js.map +1 -1
  240. package/dist/react/core/overlays/Tooltip.d.ts +1 -2
  241. package/dist/react/core/overlays/Tooltip.js +170 -176
  242. package/dist/react/core/overlays/Tooltip.js.map +1 -1
  243. package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
  244. package/dist/react/core/widgets/ActivityPlanner.js +855 -517
  245. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
  246. package/dist/react/core/widgets/Capture.d.ts +2 -3
  247. package/dist/react/core/widgets/Capture.js +965 -779
  248. package/dist/react/core/widgets/Capture.js.map +1 -1
  249. package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
  250. package/dist/react/core/widgets/ChatPanel.js +1734 -1034
  251. package/dist/react/core/widgets/ChatPanel.js.map +1 -1
  252. package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
  253. package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
  254. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
  255. package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
  256. package/dist/react/core/widgets/CommandBuilder.js +624 -516
  257. package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
  258. package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
  259. package/dist/react/core/widgets/ConnectionForm.js +528 -492
  260. package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
  261. package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
  262. package/dist/react/core/widgets/FileExplorer.js +617 -505
  263. package/dist/react/core/widgets/FileExplorer.js.map +1 -1
  264. package/dist/react/core/widgets/HexViewer.d.ts +2 -3
  265. package/dist/react/core/widgets/HexViewer.js +1353 -1091
  266. package/dist/react/core/widgets/HexViewer.js.map +1 -1
  267. package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
  268. package/dist/react/core/widgets/ImageFrame.js +230 -193
  269. package/dist/react/core/widgets/ImageFrame.js.map +1 -1
  270. package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
  271. package/dist/react/core/widgets/ImageGallery.js +380 -314
  272. package/dist/react/core/widgets/ImageGallery.js.map +1 -1
  273. package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
  274. package/dist/react/core/widgets/ImagePanel.js +110 -101
  275. package/dist/react/core/widgets/ImagePanel.js.map +1 -1
  276. package/dist/react/core/widgets/LogViewer.d.ts +2 -3
  277. package/dist/react/core/widgets/LogViewer.js +711 -607
  278. package/dist/react/core/widgets/LogViewer.js.map +1 -1
  279. package/dist/react/core/widgets/MessageStream.d.ts +3 -4
  280. package/dist/react/core/widgets/MessageStream.js +514 -444
  281. package/dist/react/core/widgets/MessageStream.js.map +1 -1
  282. package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
  283. package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
  284. package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
  285. package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
  286. package/dist/react/core/widgets/PacketViewer.js +550 -421
  287. package/dist/react/core/widgets/PacketViewer.js.map +1 -1
  288. package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
  289. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
  290. package/dist/react/hooks/index.d.ts +5 -5
  291. package/dist/react/hooks/useAccessWindows.d.ts +0 -1
  292. package/dist/react/hooks/useCompactMode.d.ts +1 -1
  293. package/dist/react/hooks/useCompactMode.js +104 -58
  294. package/dist/react/hooks/useCompactMode.js.map +1 -1
  295. package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
  296. package/dist/react/hooks/useSimulationScene.d.ts +1 -2
  297. package/dist/react/hooks/useSimulationScene.js +481 -374
  298. package/dist/react/hooks/useSimulationScene.js.map +1 -1
  299. package/dist/react/index.d.ts +3 -3
  300. package/dist/react/panels/LayerControlPanel.d.ts +1 -2
  301. package/dist/react/panels/LayerControlPanel.js +223 -180
  302. package/dist/react/panels/LayerControlPanel.js.map +1 -1
  303. package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
  304. package/dist/react/panels/ObjectInventoryPanel.js +315 -250
  305. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
  306. package/dist/react/panels/index.d.ts +1 -1
  307. package/dist/react/panels/index.js +1 -6
  308. package/dist/react/shared/ErrorBoundary.d.ts +1 -2
  309. package/dist/react/shared/ErrorBoundary.js +170 -139
  310. package/dist/react/shared/ErrorBoundary.js.map +1 -1
  311. package/dist/react/shared/Skeleton.d.ts +1 -2
  312. package/dist/react/shared/Skeleton.js +300 -301
  313. package/dist/react/shared/Skeleton.js.map +1 -1
  314. package/dist/react/theme/ThemeProvider.d.ts +2 -321
  315. package/dist/react/theme/ThemeProvider.js +312 -939
  316. package/dist/react/theme/ThemeProvider.js.map +1 -1
  317. package/dist/react/theme/cardAccent.d.ts +1 -2
  318. package/dist/react/theme/cardAccent.js +196 -126
  319. package/dist/react/theme/cardAccent.js.map +1 -1
  320. package/dist/react/theme/config.d.ts +0 -1
  321. package/dist/react/theme/config.js +47 -25
  322. package/dist/react/theme/config.js.map +1 -1
  323. package/dist/react/theme/index.d.ts +2 -2
  324. package/dist/react/theme/index.js +1 -16
  325. package/dist/react/theme/types.d.ts +332 -0
  326. package/dist/react/theme/types.js +39 -0
  327. package/dist/react/theme/types.js.map +1 -0
  328. package/dist/react/types.d.ts +8 -8
  329. package/dist/react/types.js +147 -47
  330. package/dist/react/types.js.map +1 -1
  331. package/dist/react/utils/categoryPalette.d.ts +0 -1
  332. package/dist/react/utils/categoryPalette.js +91 -102
  333. package/dist/react/utils/categoryPalette.js.map +1 -1
  334. package/dist/react/utils/index.d.ts +5 -5
  335. package/dist/react/utils/index.js +457 -371
  336. package/dist/react/utils/index.js.map +1 -1
  337. package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
  338. package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
  339. package/dist/react/visualizations/NavBallCard.d.ts +0 -1
  340. package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
  341. package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
  342. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
  343. package/dist/react/visualizations/index.d.ts +3 -3
  344. package/dist/react.d.ts +2 -1
  345. package/dist/react.js +17 -221
  346. package/dist/shaders/atmosphere.frag.js +6 -5
  347. package/dist/shaders/atmosphere.frag.js.map +1 -1
  348. package/dist/shaders/atmosphere.vert.js +6 -5
  349. package/dist/shaders/atmosphere.vert.js.map +1 -1
  350. package/dist/shaders/stars.frag.js +6 -5
  351. package/dist/shaders/stars.frag.js.map +1 -1
  352. package/dist/shaders/stars.vert.js +6 -5
  353. package/dist/shaders/stars.vert.js.map +1 -1
  354. package/dist/style.css +217 -194
  355. package/dist/tokens/core.d.ts +159 -0
  356. package/dist/tokens/core.js +144 -0
  357. package/dist/tokens/core.js.map +1 -0
  358. package/dist/tokens/css-vars.d.ts +213 -2
  359. package/dist/tokens/css-vars.js +590 -227
  360. package/dist/tokens/css-vars.js.map +1 -1
  361. package/dist/tokens/index.d.ts +31 -228
  362. package/dist/tokens/index.js +281 -366
  363. package/dist/tokens/index.js.map +1 -1
  364. package/dist/tokens/palettes/astro.d.ts +129 -0
  365. package/dist/tokens/palettes/astro.js +112 -0
  366. package/dist/tokens/palettes/astro.js.map +1 -0
  367. package/dist/tokens/palettes/index.d.ts +288 -0
  368. package/dist/tokens/palettes/index.js +35 -0
  369. package/dist/tokens/palettes/index.js.map +1 -0
  370. package/dist/tokens/palettes/tailwind.d.ts +324 -0
  371. package/dist/tokens/palettes/tailwind.js +201 -0
  372. package/dist/tokens/palettes/tailwind.js.map +1 -0
  373. package/dist/tokens/palettes/zendir.d.ts +126 -0
  374. package/dist/tokens/palettes/zendir.js +92 -0
  375. package/dist/tokens/palettes/zendir.js.map +1 -0
  376. package/dist/tokens/themes.d.ts +30 -0
  377. package/dist/tokens/themes.js +704 -0
  378. package/dist/tokens/themes.js.map +1 -0
  379. package/dist/tokens/tokens.css +419 -41
  380. package/dist/types/index.d.ts +2 -2
  381. package/package.json +310 -313
  382. package/dist/index.js.map +0 -1
  383. package/dist/react/3d/index.js.map +0 -1
  384. package/dist/react/astro/index.js.map +0 -1
  385. package/dist/react/cards/index.js.map +0 -1
  386. package/dist/react/charts/index.js.map +0 -1
  387. package/dist/react/core/index.js.map +0 -1
  388. package/dist/react/panels/index.js.map +0 -1
  389. package/dist/react/theme/astro-tokens.d.ts +0 -153
  390. package/dist/react/theme/index.js.map +0 -1
  391. package/dist/react.js.map +0 -1
@@ -1,518 +1,581 @@
1
- const SPEED_OF_LIGHT = 299792458;
2
- const EARTH_RADIUS = 6371;
3
- const MU_EARTH = 398600.4418;
1
+ //#region src/react/charts/unified/generators.ts
2
+ var SPEED_OF_LIGHT = 299792458;
3
+ var EARTH_RADIUS = 6371;
4
+ var MU_EARTH = 398600.4418;
5
+ /**
6
+ * Generate realistic LEO satellite power system telemetry
7
+ *
8
+ * Models:
9
+ * - Solar array power variation with orbit phase (cosine pointing loss)
10
+ * - Eclipse periods with zero solar input
11
+ * - Battery charge/discharge with 90% round-trip efficiency
12
+ * - Load shedding during eclipse
13
+ */
4
14
  function generatePowerData(config = {}) {
5
- const {
6
- orbitPeriod = 5400,
7
- eclipseDuration = 2100,
8
- solarArrayPower = 85,
9
- loadPower = 45,
10
- batteryCapacity = 300,
11
- initialSoC = 80,
12
- eclipseLoadReduction = 0.7,
13
- orbits = 2,
14
- resolution = 60
15
- } = config;
16
- const data = [];
17
- const totalDuration = orbitPeriod * orbits;
18
- let batterySoC = initialSoC;
19
- const batteryEfficiency = 0.9;
20
- const eclipseStart = 0.4;
21
- const eclipseEnd = eclipseStart + eclipseDuration / orbitPeriod;
22
- for (let t = 0; t < totalDuration; t += resolution) {
23
- const orbitPhase = t % orbitPeriod / orbitPeriod;
24
- const inEclipse = orbitPhase >= eclipseStart && orbitPhase < eclipseEnd;
25
- const pointingFactor = 0.9 + 0.1 * Math.sin(orbitPhase * Math.PI * 2);
26
- const solarPower = inEclipse ? 0 : solarArrayPower * pointingFactor;
27
- const consumption = inEclipse ? loadPower * eclipseLoadReduction : loadPower;
28
- const netPower = solarPower - consumption;
29
- const energyDelta = netPower * resolution / 3600;
30
- const efficiencyFactor = netPower > 0 ? batteryEfficiency : 1 / batteryEfficiency;
31
- batterySoC += energyDelta * efficiencyFactor / batteryCapacity * 100;
32
- batterySoC = Math.max(0, Math.min(100, batterySoC));
33
- data.push({
34
- time: Date.now() + t * 1e3,
35
- solarPower: Math.round(solarPower * 10) / 10,
36
- consumption: Math.round(consumption * 10) / 10,
37
- netPower: Math.round(netPower * 10) / 10,
38
- batteryPercent: Math.round(batterySoC * 10) / 10,
39
- eclipse: inEclipse
40
- });
41
- }
42
- return data;
15
+ const { orbitPeriod = 5400, eclipseDuration = 2100, solarArrayPower = 85, loadPower = 45, batteryCapacity = 300, initialSoC = 80, eclipseLoadReduction = .7, orbits = 2, resolution = 60 } = config;
16
+ const data = [];
17
+ const totalDuration = orbitPeriod * orbits;
18
+ let batterySoC = initialSoC;
19
+ const batteryEfficiency = .9;
20
+ const eclipseStart = .4;
21
+ const eclipseEnd = eclipseStart + eclipseDuration / orbitPeriod;
22
+ for (let t = 0; t < totalDuration; t += resolution) {
23
+ const orbitPhase = t % orbitPeriod / orbitPeriod;
24
+ const inEclipse = orbitPhase >= eclipseStart && orbitPhase < eclipseEnd;
25
+ const pointingFactor = .9 + .1 * Math.sin(orbitPhase * Math.PI * 2);
26
+ const solarPower = inEclipse ? 0 : solarArrayPower * pointingFactor;
27
+ const consumption = inEclipse ? loadPower * eclipseLoadReduction : loadPower;
28
+ const netPower = solarPower - consumption;
29
+ const energyDelta = netPower * resolution / 3600;
30
+ batterySoC += energyDelta * (netPower > 0 ? batteryEfficiency : 1 / batteryEfficiency) / batteryCapacity * 100;
31
+ batterySoC = Math.max(0, Math.min(100, batterySoC));
32
+ data.push({
33
+ time: Date.now() + t * 1e3,
34
+ solarPower: Math.round(solarPower * 10) / 10,
35
+ consumption: Math.round(consumption * 10) / 10,
36
+ netPower: Math.round(netPower * 10) / 10,
37
+ batteryPercent: Math.round(batterySoC * 10) / 10,
38
+ eclipse: inEclipse
39
+ });
40
+ }
41
+ return data;
43
42
  }
43
+ /**
44
+ * Generate realistic spacecraft attitude telemetry
45
+ *
46
+ * Models:
47
+ * - Slew maneuver with trapezoidal velocity profile
48
+ * - Fine pointing settling with exponential decay
49
+ * - Random jitter (Gaussian distribution)
50
+ * - Angular velocity from finite differences
51
+ */
44
52
  function generateAttitudeData(config = {}) {
45
- const {
46
- initialAttitude = [0, -45, 90],
47
- targetAttitude = [0, 30, 180],
48
- slewRate = 0.5,
49
- settleTime = 30,
50
- jitter = 0.02,
51
- samplingRate = 1,
52
- duration = 300
53
- } = config;
54
- const data = [];
55
- const dt = 1 / samplingRate;
56
- const deltaAttitude = targetAttitude.map((t, i) => t - initialAttitude[i]);
57
- const totalAngle = Math.sqrt(deltaAttitude.reduce((sum, d) => sum + d * d, 0));
58
- const slewDuration = totalAngle / slewRate;
59
- deltaAttitude.map((d) => d / totalAngle);
60
- const gaussRandom = () => {
61
- const u1 = Math.random();
62
- const u2 = Math.random();
63
- return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
64
- };
65
- let prevRoll = initialAttitude[0];
66
- let prevPitch = initialAttitude[1];
67
- let prevYaw = initialAttitude[2];
68
- for (let t = 0; t < duration; t += dt) {
69
- let roll, pitch, yaw;
70
- let pointingError;
71
- if (t < slewDuration) {
72
- const progress = t / slewDuration;
73
- const smoothProgress = 0.5 - 0.5 * Math.cos(progress * Math.PI);
74
- roll = initialAttitude[0] + deltaAttitude[0] * smoothProgress;
75
- pitch = initialAttitude[1] + deltaAttitude[1] * smoothProgress;
76
- yaw = initialAttitude[2] + deltaAttitude[2] * smoothProgress;
77
- pointingError = totalAngle * (1 - progress);
78
- } else if (t < slewDuration + settleTime) {
79
- const settleProgress = (t - slewDuration) / settleTime;
80
- const decayFactor = Math.exp(-3 * settleProgress);
81
- const overshoot = 0.05 * Math.sin(settleProgress * Math.PI * 4) * decayFactor;
82
- roll = targetAttitude[0] + overshoot + jitter * gaussRandom();
83
- pitch = targetAttitude[1] + overshoot + jitter * gaussRandom();
84
- yaw = targetAttitude[2] + overshoot + jitter * gaussRandom();
85
- pointingError = Math.abs(overshoot) + jitter * Math.abs(gaussRandom());
86
- } else {
87
- roll = targetAttitude[0] + jitter * gaussRandom();
88
- pitch = targetAttitude[1] + jitter * gaussRandom();
89
- yaw = targetAttitude[2] + jitter * gaussRandom();
90
- pointingError = jitter * Math.sqrt(
91
- Math.pow(gaussRandom(), 2) + Math.pow(gaussRandom(), 2) + Math.pow(gaussRandom(), 2)
92
- );
93
- }
94
- const angularVelocity = Math.sqrt(
95
- Math.pow((roll - prevRoll) / dt, 2) + Math.pow((pitch - prevPitch) / dt, 2) + Math.pow((yaw - prevYaw) / dt, 2)
96
- );
97
- data.push({
98
- time: Date.now() + t * 1e3,
99
- roll: Math.round(roll * 100) / 100,
100
- pitch: Math.round(pitch * 100) / 100,
101
- yaw: Math.round(yaw * 100) / 100,
102
- pointingError: Math.round(pointingError * 1e3) / 1e3,
103
- angularVelocity: Math.round(angularVelocity * 1e3) / 1e3
104
- });
105
- prevRoll = roll;
106
- prevPitch = pitch;
107
- prevYaw = yaw;
108
- }
109
- return data;
53
+ const { initialAttitude = [
54
+ 0,
55
+ -45,
56
+ 90
57
+ ], targetAttitude = [
58
+ 0,
59
+ 30,
60
+ 180
61
+ ], slewRate = .5, settleTime = 30, jitter = .02, samplingRate = 1, duration = 300 } = config;
62
+ const data = [];
63
+ const dt = 1 / samplingRate;
64
+ const deltaAttitude = targetAttitude.map((t, i) => t - initialAttitude[i]);
65
+ const totalAngle = Math.sqrt(deltaAttitude.reduce((sum, d) => sum + d * d, 0));
66
+ const slewDuration = totalAngle / slewRate;
67
+ deltaAttitude.map((d) => d / totalAngle);
68
+ const gaussRandom = () => {
69
+ const u1 = Math.random();
70
+ const u2 = Math.random();
71
+ return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
72
+ };
73
+ let prevRoll = initialAttitude[0];
74
+ let prevPitch = initialAttitude[1];
75
+ let prevYaw = initialAttitude[2];
76
+ for (let t = 0; t < duration; t += dt) {
77
+ let roll, pitch, yaw;
78
+ let pointingError;
79
+ if (t < slewDuration) {
80
+ const progress = t / slewDuration;
81
+ const smoothProgress = .5 - .5 * Math.cos(progress * Math.PI);
82
+ roll = initialAttitude[0] + deltaAttitude[0] * smoothProgress;
83
+ pitch = initialAttitude[1] + deltaAttitude[1] * smoothProgress;
84
+ yaw = initialAttitude[2] + deltaAttitude[2] * smoothProgress;
85
+ pointingError = totalAngle * (1 - progress);
86
+ } else if (t < slewDuration + settleTime) {
87
+ const settleProgress = (t - slewDuration) / settleTime;
88
+ const decayFactor = Math.exp(-3 * settleProgress);
89
+ const overshoot = .05 * Math.sin(settleProgress * Math.PI * 4) * decayFactor;
90
+ roll = targetAttitude[0] + overshoot + jitter * gaussRandom();
91
+ pitch = targetAttitude[1] + overshoot + jitter * gaussRandom();
92
+ yaw = targetAttitude[2] + overshoot + jitter * gaussRandom();
93
+ pointingError = Math.abs(overshoot) + jitter * Math.abs(gaussRandom());
94
+ } else {
95
+ roll = targetAttitude[0] + jitter * gaussRandom();
96
+ pitch = targetAttitude[1] + jitter * gaussRandom();
97
+ yaw = targetAttitude[2] + jitter * gaussRandom();
98
+ pointingError = jitter * Math.sqrt(Math.pow(gaussRandom(), 2) + Math.pow(gaussRandom(), 2) + Math.pow(gaussRandom(), 2));
99
+ }
100
+ const angularVelocity = Math.sqrt(Math.pow((roll - prevRoll) / dt, 2) + Math.pow((pitch - prevPitch) / dt, 2) + Math.pow((yaw - prevYaw) / dt, 2));
101
+ data.push({
102
+ time: Date.now() + t * 1e3,
103
+ roll: Math.round(roll * 100) / 100,
104
+ pitch: Math.round(pitch * 100) / 100,
105
+ yaw: Math.round(yaw * 100) / 100,
106
+ pointingError: Math.round(pointingError * 1e3) / 1e3,
107
+ angularVelocity: Math.round(angularVelocity * 1e3) / 1e3
108
+ });
109
+ prevRoll = roll;
110
+ prevPitch = pitch;
111
+ prevYaw = yaw;
112
+ }
113
+ return data;
110
114
  }
115
+ /**
116
+ * Generate realistic Doppler tracking data for a satellite pass
117
+ *
118
+ * Uses simplified orbital mechanics:
119
+ * - Circular orbit at specified altitude
120
+ * - Pass geometry from maximum elevation
121
+ * - Doppler shift from velocity projection
122
+ */
111
123
  function generateDopplerData(config = {}) {
112
- const {
113
- carrierFrequency = 437e6,
114
- // 437 MHz (UHF amateur)
115
- altitude = 400,
116
- // km (ISS altitude)
117
- maxElevation = 75,
118
- passDuration = 600,
119
- // 10 minutes
120
- resolution = 1,
121
- measurementNoise = 50,
122
- // Hz
123
- satelliteName = "ISS",
124
- groundStation: _groundStation = "Home Station"
125
- } = config;
126
- const predicted = [];
127
- const measured = [];
128
- const orbitRadius = EARTH_RADIUS + altitude;
129
- const orbitalVelocity = Math.sqrt(MU_EARTH / orbitRadius);
130
- const maxDoppler = carrierFrequency * (orbitalVelocity * 1e3 / SPEED_OF_LIGHT);
131
- const elevationRad = maxElevation * Math.PI / 180;
132
- const passHalfAngle = Math.PI / 2 - elevationRad;
133
- const now = Date.now();
134
- const aos = now;
135
- const los = now + passDuration * 1e3;
136
- const tca = now + passDuration / 2 * 1e3;
137
- const gaussRandom = () => {
138
- const u1 = Math.random();
139
- const u2 = Math.random();
140
- return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
141
- };
142
- for (let t = 0; t <= passDuration; t += resolution) {
143
- const time = now + t * 1e3;
144
- const passPhase = t / passDuration;
145
- const angle = (passPhase - 0.5) * 2 * passHalfAngle;
146
- const dopplerShift = maxDoppler * Math.sin(angle);
147
- const elevation = maxElevation * Math.cos(angle);
148
- predicted.push({
149
- time,
150
- dopplerShift: Math.round(dopplerShift),
151
- elevation: Math.round(elevation * 10) / 10
152
- });
153
- const measuredShift = dopplerShift + measurementNoise * gaussRandom();
154
- measured.push({
155
- time,
156
- dopplerShift: Math.round(measuredShift),
157
- elevation: Math.round(elevation * 10) / 10
158
- });
159
- }
160
- const passInfo = {
161
- name: satelliteName,
162
- aos: new Date(aos),
163
- los: new Date(los),
164
- tca: new Date(tca),
165
- maxElevation
166
- };
167
- return { predicted, measured, passInfo };
124
+ const { carrierFrequency = 437e6, altitude = 400, maxElevation = 75, passDuration = 600, resolution = 1, measurementNoise = 50, satelliteName = "ISS", groundStation: _groundStation = "Home Station" } = config;
125
+ const predicted = [];
126
+ const measured = [];
127
+ const orbitRadius = EARTH_RADIUS + altitude;
128
+ const maxDoppler = carrierFrequency * (Math.sqrt(MU_EARTH / orbitRadius) * 1e3 / SPEED_OF_LIGHT);
129
+ const elevationRad = maxElevation * Math.PI / 180;
130
+ const passHalfAngle = Math.PI / 2 - elevationRad;
131
+ const now = Date.now();
132
+ const aos = now;
133
+ const los = now + passDuration * 1e3;
134
+ const tca = now + passDuration / 2 * 1e3;
135
+ const gaussRandom = () => {
136
+ const u1 = Math.random();
137
+ const u2 = Math.random();
138
+ return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
139
+ };
140
+ for (let t = 0; t <= passDuration; t += resolution) {
141
+ const time = now + t * 1e3;
142
+ const angle = (t / passDuration - .5) * 2 * passHalfAngle;
143
+ const dopplerShift = maxDoppler * Math.sin(angle);
144
+ const elevation = maxElevation * Math.cos(angle);
145
+ predicted.push({
146
+ time,
147
+ dopplerShift: Math.round(dopplerShift),
148
+ elevation: Math.round(elevation * 10) / 10
149
+ });
150
+ const measuredShift = dopplerShift + measurementNoise * gaussRandom();
151
+ measured.push({
152
+ time,
153
+ dopplerShift: Math.round(measuredShift),
154
+ elevation: Math.round(elevation * 10) / 10
155
+ });
156
+ }
157
+ return {
158
+ predicted,
159
+ measured,
160
+ passInfo: {
161
+ name: satelliteName,
162
+ aos: new Date(aos),
163
+ los: new Date(los),
164
+ tca: new Date(tca),
165
+ maxElevation
166
+ }
167
+ };
168
168
  }
169
+ /**
170
+ * Generate realistic RF waterfall data
171
+ *
172
+ * Models:
173
+ * - Gaussian noise floor
174
+ * - CW signals (narrow spikes)
175
+ * - SSB signals (offset sideband with modulation)
176
+ * - Digital signals (wider, flatter spectrum)
177
+ * - Time-varying Doppler drift
178
+ */
169
179
  function generateWaterfallData(config = {}) {
170
- const {
171
- centerFrequency = 437e6,
172
- bandwidth = 1e5,
173
- fftBins = 512,
174
- noiseFloor = -120,
175
- timeSamples = 100,
176
- signals = [
177
- { offset: -3e4, power: -80, bandwidth: 500, type: "cw" },
178
- { offset: 0, power: -75, bandwidth: 2e4, type: "digital" },
179
- { offset: 25e3, power: -90, bandwidth: 3e3, type: "ssb" }
180
- ]
181
- } = config;
182
- const data = [];
183
- const freqStep = bandwidth / fftBins;
184
- const noiseStdDev = 3;
185
- const gaussRandom = () => {
186
- const u1 = Math.random();
187
- const u2 = Math.random();
188
- return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
189
- };
190
- const frequencies = [];
191
- for (let f = 0; f < fftBins; f++) {
192
- frequencies.push(centerFrequency + (f - fftBins / 2) * freqStep);
193
- }
194
- for (let t = 0; t < timeSamples; t++) {
195
- const powers = [];
196
- const time = Date.now() - (timeSamples - t) * 100;
197
- for (let f = 0; f < fftBins; f++) {
198
- const freqOffset = (f - fftBins / 2) * freqStep;
199
- let power = noiseFloor + noiseStdDev * gaussRandom();
200
- for (const signal of signals) {
201
- const signalOffset = signal.offset + (signal.dopplerDrift || 0) * (t / 10);
202
- const distance = Math.abs(freqOffset - signalOffset);
203
- if (signal.type === "cw") {
204
- if (distance < signal.bandwidth * 2) {
205
- const shape = Math.pow(Math.sin(Math.PI * distance / signal.bandwidth) / (Math.PI * distance / signal.bandwidth + 1e-3), 2);
206
- power = Math.max(power, signal.power + 10 * Math.log10(shape + 1e-3) + gaussRandom());
207
- }
208
- } else if (signal.type === "ssb") {
209
- if (freqOffset >= signalOffset && freqOffset <= signalOffset + signal.bandwidth) {
210
- const modulation = 0.5 + 0.5 * Math.sin(t * 0.3 + f * 0.1);
211
- power = Math.max(power, signal.power - 3 + 6 * modulation + 2 * gaussRandom());
212
- }
213
- } else if (signal.type === "digital") {
214
- if (distance < signal.bandwidth / 2) {
215
- power = Math.max(power, signal.power + gaussRandom());
216
- } else if (distance < signal.bandwidth) {
217
- const rolloff = 1 - (distance - signal.bandwidth / 2) / (signal.bandwidth / 2);
218
- power = Math.max(power, signal.power - 20 * (1 - rolloff) + gaussRandom());
219
- }
220
- } else if (signal.type === "beacon") {
221
- if (distance < signal.bandwidth) {
222
- power = Math.max(power, signal.power);
223
- }
224
- }
225
- }
226
- powers.push(Math.round(power * 10) / 10);
227
- }
228
- data.push({ time, frequencies: [...frequencies], powers });
229
- }
230
- return data;
180
+ const { centerFrequency = 437e6, bandwidth = 1e5, fftBins = 512, noiseFloor = -120, timeSamples = 100, signals = [
181
+ {
182
+ offset: -3e4,
183
+ power: -80,
184
+ bandwidth: 500,
185
+ type: "cw"
186
+ },
187
+ {
188
+ offset: 0,
189
+ power: -75,
190
+ bandwidth: 2e4,
191
+ type: "digital"
192
+ },
193
+ {
194
+ offset: 25e3,
195
+ power: -90,
196
+ bandwidth: 3e3,
197
+ type: "ssb"
198
+ }
199
+ ] } = config;
200
+ const data = [];
201
+ const freqStep = bandwidth / fftBins;
202
+ const noiseStdDev = 3;
203
+ const gaussRandom = () => {
204
+ const u1 = Math.random();
205
+ const u2 = Math.random();
206
+ return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
207
+ };
208
+ const frequencies = [];
209
+ for (let f = 0; f < fftBins; f++) frequencies.push(centerFrequency + (f - fftBins / 2) * freqStep);
210
+ for (let t = 0; t < timeSamples; t++) {
211
+ const powers = [];
212
+ const time = Date.now() - (timeSamples - t) * 100;
213
+ for (let f = 0; f < fftBins; f++) {
214
+ const freqOffset = (f - fftBins / 2) * freqStep;
215
+ let power = noiseFloor + noiseStdDev * gaussRandom();
216
+ for (const signal of signals) {
217
+ const signalOffset = signal.offset + (signal.dopplerDrift || 0) * (t / 10);
218
+ const distance = Math.abs(freqOffset - signalOffset);
219
+ if (signal.type === "cw") {
220
+ if (distance < signal.bandwidth * 2) {
221
+ const shape = Math.pow(Math.sin(Math.PI * distance / signal.bandwidth) / (Math.PI * distance / signal.bandwidth + .001), 2);
222
+ power = Math.max(power, signal.power + 10 * Math.log10(shape + .001) + gaussRandom());
223
+ }
224
+ } else if (signal.type === "ssb") {
225
+ if (freqOffset >= signalOffset && freqOffset <= signalOffset + signal.bandwidth) {
226
+ const modulation = .5 + .5 * Math.sin(t * .3 + f * .1);
227
+ power = Math.max(power, signal.power - 3 + 6 * modulation + 2 * gaussRandom());
228
+ }
229
+ } else if (signal.type === "digital") {
230
+ if (distance < signal.bandwidth / 2) power = Math.max(power, signal.power + gaussRandom());
231
+ else if (distance < signal.bandwidth) {
232
+ const rolloff = 1 - (distance - signal.bandwidth / 2) / (signal.bandwidth / 2);
233
+ power = Math.max(power, signal.power - 20 * (1 - rolloff) + gaussRandom());
234
+ }
235
+ } else if (signal.type === "beacon") {
236
+ if (distance < signal.bandwidth) power = Math.max(power, signal.power);
237
+ }
238
+ }
239
+ powers.push(Math.round(power * 10) / 10);
240
+ }
241
+ data.push({
242
+ time,
243
+ frequencies: [...frequencies],
244
+ powers
245
+ });
246
+ }
247
+ return data;
231
248
  }
249
+ /**
250
+ * Generate realistic ground station contact windows
251
+ *
252
+ * Uses simplified visibility calculation based on:
253
+ * - Orbital period from altitude
254
+ * - Swath width from elevation angle
255
+ * - Ground track precession
256
+ */
232
257
  function generateContactWindows(config = {}) {
233
- const {
234
- groundStations = [
235
- { name: "Svalbard (SG)", latitude: 78.2, longitude: 15.4 },
236
- { name: "McMurdo (MCM)", latitude: -77.8, longitude: 166.7 },
237
- { name: "Hawaii (HBK)", latitude: 21.5, longitude: -158 },
238
- { name: "Kiruna (KIR)", latitude: 67.9, longitude: 20.9 }
239
- ],
240
- altitude = 400,
241
- inclination = 51.6,
242
- duration = 24,
243
- minElevation = 5
244
- } = config;
245
- const result = [];
246
- const now = Date.now();
247
- const orbitPeriod = 2 * Math.PI * Math.sqrt(Math.pow(EARTH_RADIUS + altitude, 3) / MU_EARTH);
248
- const passesPerDay = Math.floor(duration * 3600 / orbitPeriod);
249
- for (const gs of groundStations) {
250
- const windows = [];
251
- const isVisible = Math.abs(gs.latitude) <= inclination + 15;
252
- if (!isVisible) continue;
253
- const passesForStation = Math.floor(passesPerDay * (0.3 + 0.7 * Math.cos(gs.latitude * Math.PI / 180)));
254
- for (let i = 0; i < passesForStation; i++) {
255
- const passStart = now + i * duration * 3600 * 1e3 / passesForStation;
256
- const passStart2 = passStart + (Math.random() - 0.5) * orbitPeriod * 500;
257
- const maxEl = minElevation + Math.random() * (85 - minElevation);
258
- const passDuration = 10 * 60 * 1e3 * (1 - maxEl / 180);
259
- const signalQuality = maxEl > 45 ? "good" : maxEl > 20 ? "marginal" : "poor";
260
- windows.push({
261
- start: passStart2,
262
- end: passStart2 + passDuration,
263
- label: `Pass ${i + 1}`,
264
- signalQuality,
265
- elevation: Math.round(maxEl)
266
- });
267
- }
268
- result.push({ id: gs.name, name: gs.name, windows });
269
- }
270
- return result;
258
+ const { groundStations = [
259
+ {
260
+ name: "Svalbard (SG)",
261
+ latitude: 78.2,
262
+ longitude: 15.4
263
+ },
264
+ {
265
+ name: "McMurdo (MCM)",
266
+ latitude: -77.8,
267
+ longitude: 166.7
268
+ },
269
+ {
270
+ name: "Hawaii (HBK)",
271
+ latitude: 21.5,
272
+ longitude: -158
273
+ },
274
+ {
275
+ name: "Kiruna (KIR)",
276
+ latitude: 67.9,
277
+ longitude: 20.9
278
+ }
279
+ ], altitude = 400, inclination = 51.6, duration = 24, minElevation = 5 } = config;
280
+ const result = [];
281
+ const now = Date.now();
282
+ const orbitPeriod = 2 * Math.PI * Math.sqrt(Math.pow(EARTH_RADIUS + altitude, 3) / MU_EARTH);
283
+ const passesPerDay = Math.floor(duration * 3600 / orbitPeriod);
284
+ for (const gs of groundStations) {
285
+ const windows = [];
286
+ if (!(Math.abs(gs.latitude) <= inclination + 15)) continue;
287
+ const passesForStation = Math.floor(passesPerDay * (.3 + .7 * Math.cos(gs.latitude * Math.PI / 180)));
288
+ for (let i = 0; i < passesForStation; i++) {
289
+ const passStart2 = now + i * duration * 3600 * 1e3 / passesForStation + (Math.random() - .5) * orbitPeriod * 500;
290
+ const maxEl = minElevation + Math.random() * (85 - minElevation);
291
+ const passDuration = 600 * 1e3 * (1 - maxEl / 180);
292
+ const signalQuality = maxEl > 45 ? "good" : maxEl > 20 ? "marginal" : "poor";
293
+ windows.push({
294
+ start: passStart2,
295
+ end: passStart2 + passDuration,
296
+ label: `Pass ${i + 1}`,
297
+ signalQuality,
298
+ elevation: Math.round(maxEl)
299
+ });
300
+ }
301
+ result.push({
302
+ id: gs.name,
303
+ name: gs.name,
304
+ windows
305
+ });
306
+ }
307
+ return result;
271
308
  }
309
+ /**
310
+ * Generate heliocentric orbit visualization data
311
+ */
272
312
  function generateHeliocentricOrbits(config = {}) {
273
- const {
274
- bodies = [
275
- { name: "Earth", type: "planet", semiMajorAxis: 1, eccentricity: 0.017, inclination: 0, argumentOfPerihelion: 102, trueAnomaly: 0, color: "#3498db" },
276
- { name: "Mars", type: "planet", semiMajorAxis: 1.52, eccentricity: 0.093, inclination: 1.85, argumentOfPerihelion: 286, trueAnomaly: 45, color: "#e74c3c" },
277
- { name: "Voyager 1", type: "spacecraft", semiMajorAxis: 40, eccentricity: 0.99, inclination: 35, argumentOfPerihelion: 0, trueAnomaly: 170, color: "#3E3CFF" }
278
- ],
279
- orbitPoints = 72
280
- } = config;
281
- return bodies.map((body) => {
282
- const { semiMajorAxis: a, eccentricity: e, inclination: i, argumentOfPerihelion: omega, trueAnomaly: nu } = body;
283
- const orbitPath = [];
284
- for (let j = 0; j <= orbitPoints; j++) {
285
- const angle = j / orbitPoints * 2 * Math.PI;
286
- const r2 = a * (1 - e * e) / (1 + e * Math.cos(angle));
287
- const xOrbit2 = r2 * Math.cos(angle);
288
- const yOrbit2 = r2 * Math.sin(angle);
289
- const omegaRad2 = omega * Math.PI / 180;
290
- const iRad2 = i * Math.PI / 180;
291
- const x2 = xOrbit2 * Math.cos(omegaRad2) - yOrbit2 * Math.cos(iRad2) * Math.sin(omegaRad2);
292
- const y2 = xOrbit2 * Math.sin(omegaRad2) + yOrbit2 * Math.cos(iRad2) * Math.cos(omegaRad2);
293
- const z2 = yOrbit2 * Math.sin(iRad2);
294
- orbitPath.push({ x: x2, y: y2, z: z2 });
295
- }
296
- const nuRad = nu * Math.PI / 180;
297
- const r = a * (1 - e * e) / (1 + e * Math.cos(nuRad));
298
- const xOrbit = r * Math.cos(nuRad);
299
- const yOrbit = r * Math.sin(nuRad);
300
- const omegaRad = omega * Math.PI / 180;
301
- const iRad = i * Math.PI / 180;
302
- const x = xOrbit * Math.cos(omegaRad) - yOrbit * Math.cos(iRad) * Math.sin(omegaRad);
303
- const y = xOrbit * Math.sin(omegaRad) + yOrbit * Math.cos(iRad) * Math.cos(omegaRad);
304
- const z = yOrbit * Math.sin(iRad);
305
- const period = 365.25 * Math.pow(a, 1.5);
306
- return {
307
- name: body.name,
308
- type: body.type,
309
- x,
310
- y,
311
- z,
312
- orbitPath,
313
- color: body.color,
314
- semiMajorAxis: a,
315
- period,
316
- inclination: i,
317
- size: body.type === "planet" ? 20 : 12
318
- };
319
- });
313
+ const { bodies = [
314
+ {
315
+ name: "Earth",
316
+ type: "planet",
317
+ semiMajorAxis: 1,
318
+ eccentricity: .017,
319
+ inclination: 0,
320
+ argumentOfPerihelion: 102,
321
+ trueAnomaly: 0,
322
+ color: "#3498db"
323
+ },
324
+ {
325
+ name: "Mars",
326
+ type: "planet",
327
+ semiMajorAxis: 1.52,
328
+ eccentricity: .093,
329
+ inclination: 1.85,
330
+ argumentOfPerihelion: 286,
331
+ trueAnomaly: 45,
332
+ color: "#e74c3c"
333
+ },
334
+ {
335
+ name: "Voyager 1",
336
+ type: "spacecraft",
337
+ semiMajorAxis: 40,
338
+ eccentricity: .99,
339
+ inclination: 35,
340
+ argumentOfPerihelion: 0,
341
+ trueAnomaly: 170,
342
+ color: "#3E3CFF"
343
+ }
344
+ ], orbitPoints = 72 } = config;
345
+ return bodies.map((body) => {
346
+ const { semiMajorAxis: a, eccentricity: e, inclination: i, argumentOfPerihelion: omega, trueAnomaly: nu } = body;
347
+ const orbitPath = [];
348
+ for (let j = 0; j <= orbitPoints; j++) {
349
+ const angle = j / orbitPoints * 2 * Math.PI;
350
+ const r = a * (1 - e * e) / (1 + e * Math.cos(angle));
351
+ const xOrbit = r * Math.cos(angle);
352
+ const yOrbit = r * Math.sin(angle);
353
+ const omegaRad = omega * Math.PI / 180;
354
+ const iRad = i * Math.PI / 180;
355
+ const x = xOrbit * Math.cos(omegaRad) - yOrbit * Math.cos(iRad) * Math.sin(omegaRad);
356
+ const y = xOrbit * Math.sin(omegaRad) + yOrbit * Math.cos(iRad) * Math.cos(omegaRad);
357
+ const z = yOrbit * Math.sin(iRad);
358
+ orbitPath.push({
359
+ x,
360
+ y,
361
+ z
362
+ });
363
+ }
364
+ const nuRad = nu * Math.PI / 180;
365
+ const r = a * (1 - e * e) / (1 + e * Math.cos(nuRad));
366
+ const xOrbit = r * Math.cos(nuRad);
367
+ const yOrbit = r * Math.sin(nuRad);
368
+ const omegaRad = omega * Math.PI / 180;
369
+ const iRad = i * Math.PI / 180;
370
+ const x = xOrbit * Math.cos(omegaRad) - yOrbit * Math.cos(iRad) * Math.sin(omegaRad);
371
+ const y = xOrbit * Math.sin(omegaRad) + yOrbit * Math.cos(iRad) * Math.cos(omegaRad);
372
+ const z = yOrbit * Math.sin(iRad);
373
+ const period = 365.25 * Math.pow(a, 1.5);
374
+ return {
375
+ name: body.name,
376
+ type: body.type,
377
+ x,
378
+ y,
379
+ z,
380
+ orbitPath,
381
+ color: body.color,
382
+ semiMajorAxis: a,
383
+ period,
384
+ inclination: i,
385
+ size: body.type === "planet" ? 20 : 12
386
+ };
387
+ });
320
388
  }
389
+ /**
390
+ * Generate a single RF spectrum snapshot
391
+ */
321
392
  function generateSpectrum(config = {}) {
322
- const {
323
- centerFrequency = 22e8,
324
- bandwidth = 1e7,
325
- points = 256,
326
- noiseFloor = -120,
327
- signals = [
328
- { frequency: 22e8, power: -75, bandwidth: 1e5 },
329
- { frequency: 21975e5, power: -80, bandwidth: 1e4 },
330
- { frequency: 22025e5, power: -95, bandwidth: 5e4 }
331
- ]
332
- } = config;
333
- const data = [];
334
- const freqMin = centerFrequency - bandwidth / 2;
335
- const freqStep = bandwidth / points;
336
- for (let i = 0; i < points; i++) {
337
- const freq = freqMin + i * freqStep;
338
- let power = noiseFloor + 3 * (Math.random() - 0.5);
339
- for (const signal of signals) {
340
- const distance = Math.abs(freq - signal.frequency);
341
- if (distance < signal.bandwidth * 2) {
342
- const attenuation = 20 * Math.log10(1 + distance / (signal.bandwidth / 2));
343
- power = Math.max(power, signal.power - attenuation);
344
- }
345
- }
346
- data.push({ frequency: freq, power: Math.round(power * 10) / 10 });
347
- }
348
- return data;
393
+ const { centerFrequency = 22e8, bandwidth = 1e7, points = 256, noiseFloor = -120, signals = [
394
+ {
395
+ frequency: 22e8,
396
+ power: -75,
397
+ bandwidth: 1e5
398
+ },
399
+ {
400
+ frequency: 21975e5,
401
+ power: -80,
402
+ bandwidth: 1e4
403
+ },
404
+ {
405
+ frequency: 22025e5,
406
+ power: -95,
407
+ bandwidth: 5e4
408
+ }
409
+ ] } = config;
410
+ const data = [];
411
+ const freqMin = centerFrequency - bandwidth / 2;
412
+ const freqStep = bandwidth / points;
413
+ for (let i = 0; i < points; i++) {
414
+ const freq = freqMin + i * freqStep;
415
+ let power = noiseFloor + 3 * (Math.random() - .5);
416
+ for (const signal of signals) {
417
+ const distance = Math.abs(freq - signal.frequency);
418
+ if (distance < signal.bandwidth * 2) {
419
+ const attenuation = 20 * Math.log10(1 + distance / (signal.bandwidth / 2));
420
+ power = Math.max(power, signal.power - attenuation);
421
+ }
422
+ }
423
+ data.push({
424
+ frequency: freq,
425
+ power: Math.round(power * 10) / 10
426
+ });
427
+ }
428
+ return data;
349
429
  }
430
+ /**
431
+ * Generate eclipse timeline data
432
+ */
350
433
  function generateEclipseTimeline(config = {}) {
351
- const {
352
- orbitPeriod = 5400,
353
- eclipseFraction = 0.38,
354
- orbits = 5,
355
- includePenumbra = true
356
- } = config;
357
- const data = [];
358
- const now = Date.now();
359
- const penumbraDuration = includePenumbra ? 60 : 0;
360
- for (let orbit = 0; orbit < orbits; orbit++) {
361
- const orbitStart = now + orbit * orbitPeriod * 1e3;
362
- const eclipseStart = orbitStart + orbitPeriod * 0.4 * 1e3;
363
- const eclipseEnd = eclipseStart + orbitPeriod * eclipseFraction * 1e3;
364
- data.push({
365
- start: orbitStart,
366
- end: eclipseStart - penumbraDuration * 1e3,
367
- type: "sunlight",
368
- orbitNumber: orbit + 1
369
- });
370
- if (includePenumbra) {
371
- data.push({
372
- start: eclipseStart - penumbraDuration * 1e3,
373
- end: eclipseStart,
374
- type: "penumbra",
375
- orbitNumber: orbit + 1
376
- });
377
- }
378
- data.push({
379
- start: eclipseStart,
380
- end: eclipseEnd,
381
- type: "umbra",
382
- orbitNumber: orbit + 1
383
- });
384
- if (includePenumbra) {
385
- data.push({
386
- start: eclipseEnd,
387
- end: eclipseEnd + penumbraDuration * 1e3,
388
- type: "penumbra",
389
- orbitNumber: orbit + 1
390
- });
391
- }
392
- data.push({
393
- start: eclipseEnd + penumbraDuration * 1e3,
394
- end: orbitStart + orbitPeriod * 1e3,
395
- type: "sunlight",
396
- orbitNumber: orbit + 1
397
- });
398
- }
399
- return data;
434
+ const { orbitPeriod = 5400, eclipseFraction = .38, orbits = 5, includePenumbra = true } = config;
435
+ const data = [];
436
+ const now = Date.now();
437
+ const penumbraDuration = includePenumbra ? 60 : 0;
438
+ for (let orbit = 0; orbit < orbits; orbit++) {
439
+ const orbitStart = now + orbit * orbitPeriod * 1e3;
440
+ const eclipseStart = orbitStart + orbitPeriod * .4 * 1e3;
441
+ const eclipseEnd = eclipseStart + orbitPeriod * eclipseFraction * 1e3;
442
+ data.push({
443
+ start: orbitStart,
444
+ end: eclipseStart - penumbraDuration * 1e3,
445
+ type: "sunlight",
446
+ orbitNumber: orbit + 1
447
+ });
448
+ if (includePenumbra) data.push({
449
+ start: eclipseStart - penumbraDuration * 1e3,
450
+ end: eclipseStart,
451
+ type: "penumbra",
452
+ orbitNumber: orbit + 1
453
+ });
454
+ data.push({
455
+ start: eclipseStart,
456
+ end: eclipseEnd,
457
+ type: "umbra",
458
+ orbitNumber: orbit + 1
459
+ });
460
+ if (includePenumbra) data.push({
461
+ start: eclipseEnd,
462
+ end: eclipseEnd + penumbraDuration * 1e3,
463
+ type: "penumbra",
464
+ orbitNumber: orbit + 1
465
+ });
466
+ data.push({
467
+ start: eclipseEnd + penumbraDuration * 1e3,
468
+ end: orbitStart + orbitPeriod * 1e3,
469
+ type: "sunlight",
470
+ orbitNumber: orbit + 1
471
+ });
472
+ }
473
+ return data;
400
474
  }
475
+ /**
476
+ * Generate constellation coverage grid data
477
+ *
478
+ * Models simplified visibility based on satellite altitude
479
+ * and ground footprint overlap from Walker constellation geometry.
480
+ */
401
481
  function generateConstellationCoverage(config = {}) {
402
- const {
403
- latResolution = 5,
404
- lonResolution = 5,
405
- planes = 6,
406
- satsPerPlane = 22,
407
- altitude = 550,
408
- inclination = 53,
409
- metric = "visibility"
410
- } = config;
411
- const latitudes = [];
412
- const longitudes = [];
413
- const coverage = [];
414
- for (let lat = -90; lat <= 90; lat += latResolution) latitudes.push(lat);
415
- for (let lon = -180; lon < 180; lon += lonResolution) longitudes.push(lon);
416
- const earthRadius = 6371;
417
- const footprintAngle = Math.acos(earthRadius / (earthRadius + altitude)) * (180 / Math.PI);
418
- const totalSats = planes * satsPerPlane;
419
- for (let li = 0; li < latitudes.length; li++) {
420
- const row = [];
421
- const lat = latitudes[li];
422
- for (let lj = 0; lj < longitudes.length; lj++) {
423
- let value;
424
- const latFactor = Math.abs(lat) <= inclination ? 1 : Math.max(0, 1 - (Math.abs(lat) - inclination) / 20);
425
- const densityFactor = totalSats / 100;
426
- const footprintOverlap = Math.min(1, densityFactor * (footprintAngle / 30));
427
- if (metric === "visibility") {
428
- value = Math.min(100, footprintOverlap * latFactor * 100);
429
- if (Math.abs(lat) > 60) value = Math.min(100, value * 1.2);
430
- value += (Math.random() - 0.5) * 5;
431
- value = Math.max(0, Math.min(100, value));
432
- } else if (metric === "revisitTime") {
433
- const baseRevisit = 90 / (footprintOverlap * latFactor + 0.01);
434
- value = Math.max(1, Math.min(120, baseRevisit + (Math.random() - 0.5) * 10));
435
- } else {
436
- const slantRange = altitude / Math.sin(Math.max(0.1, latFactor * Math.PI / 4));
437
- value = slantRange / 300 + 2 + Math.random() * 2;
438
- }
439
- row.push(Math.round(value * 10) / 10);
440
- }
441
- coverage.push(row);
442
- }
443
- const units = { visibility: "%", revisitTime: "min", latency: "ms" };
444
- return { latitudes, longitudes, coverage, unit: units[metric] || "%" };
482
+ const { latResolution = 5, lonResolution = 5, planes = 6, satsPerPlane = 22, altitude = 550, inclination = 53, metric = "visibility" } = config;
483
+ const latitudes = [];
484
+ const longitudes = [];
485
+ const coverage = [];
486
+ for (let lat = -90; lat <= 90; lat += latResolution) latitudes.push(lat);
487
+ for (let lon = -180; lon < 180; lon += lonResolution) longitudes.push(lon);
488
+ const earthRadius = 6371;
489
+ const footprintAngle = Math.acos(earthRadius / (earthRadius + altitude)) * (180 / Math.PI);
490
+ const totalSats = planes * satsPerPlane;
491
+ for (let li = 0; li < latitudes.length; li++) {
492
+ const row = [];
493
+ const lat = latitudes[li];
494
+ lat * Math.PI / 180;
495
+ for (let lj = 0; lj < longitudes.length; lj++) {
496
+ let value;
497
+ const latFactor = Math.abs(lat) <= inclination ? 1 : Math.max(0, 1 - (Math.abs(lat) - inclination) / 20);
498
+ const densityFactor = totalSats / 100;
499
+ const footprintOverlap = Math.min(1, densityFactor * (footprintAngle / 30));
500
+ if (metric === "visibility") {
501
+ value = Math.min(100, footprintOverlap * latFactor * 100);
502
+ if (Math.abs(lat) > 60) value = Math.min(100, value * 1.2);
503
+ value += (Math.random() - .5) * 5;
504
+ value = Math.max(0, Math.min(100, value));
505
+ } else if (metric === "revisitTime") {
506
+ const baseRevisit = 90 / (footprintOverlap * latFactor + .01);
507
+ value = Math.max(1, Math.min(120, baseRevisit + (Math.random() - .5) * 10));
508
+ } else value = altitude / Math.sin(Math.max(.1, latFactor * Math.PI / 4)) / 300 + 2 + Math.random() * 2;
509
+ row.push(Math.round(value * 10) / 10);
510
+ }
511
+ coverage.push(row);
512
+ }
513
+ return {
514
+ latitudes,
515
+ longitudes,
516
+ coverage,
517
+ unit: {
518
+ visibility: "%",
519
+ revisitTime: "min",
520
+ latency: "ms"
521
+ }[metric] || "%"
522
+ };
445
523
  }
524
+ /**
525
+ * Generate realistic conjunction/close approach events
526
+ */
446
527
  function generateConjunctionEvents(config = {}) {
447
- const {
448
- primaryName = "SAT-ALPHA",
449
- eventCount = 12,
450
- timeRangeHours = 72,
451
- includeHighRisk = true
452
- } = config;
453
- const secondaries = [
454
- "COSMOS-2251 DEB",
455
- "FENGYUN-1C DEB",
456
- "SL-16 R/B",
457
- "IRIDIUM 33 DEB",
458
- "NOAA 17 DEB",
459
- "ATLAS 5 CENTAUR R/B",
460
- "BREEZE-M DEB",
461
- "CZ-3B R/B",
462
- "UNKNOWN DEB",
463
- "MICROSAT-R DEB",
464
- "DELTA 2 R/B",
465
- "H-2A R/B"
466
- ];
467
- const now = Date.now();
468
- const events = [];
469
- for (let i = 0; i < eventCount; i++) {
470
- const tca = now + Math.random() * timeRangeHours * 36e5;
471
- let missDistance;
472
- if (includeHighRisk && i < 2) {
473
- missDistance = 0.1 + Math.random() * 0.9;
474
- } else if (i < 5) {
475
- missDistance = 1 + Math.random() * 4;
476
- } else {
477
- missDistance = 5 + Math.random() * 15;
478
- }
479
- const probability = Math.pow(10, -3 - missDistance * 1.5 + Math.random());
480
- const relativeVelocity = 5 + Math.random() * 12;
481
- const angle = Math.random() * 2 * Math.PI;
482
- const incAngle = (Math.random() - 0.5) * Math.PI;
483
- const radius = 6800 + Math.random() * 600;
484
- events.push({
485
- id: `CDM-${String(i + 1).padStart(3, "0")}`,
486
- primary: primaryName,
487
- secondary: secondaries[i % secondaries.length],
488
- tca,
489
- missDistance: Math.round(missDistance * 1e3) / 1e3,
490
- probability: Math.max(1e-10, probability),
491
- relativeVelocity: Math.round(relativeVelocity * 100) / 100,
492
- position: {
493
- x: Math.round(radius * Math.cos(angle) * Math.cos(incAngle)),
494
- y: Math.round(radius * Math.sin(angle) * Math.cos(incAngle)),
495
- z: Math.round(radius * Math.sin(incAngle))
496
- },
497
- uncertainty: {
498
- rx: 20 + Math.random() * 100,
499
- ry: 50 + Math.random() * 300,
500
- rz: 10 + Math.random() * 60
501
- }
502
- });
503
- }
504
- return events.sort((a, b) => a.tca - b.tca);
528
+ const { primaryName = "SAT-ALPHA", eventCount = 12, timeRangeHours = 72, includeHighRisk = true } = config;
529
+ const secondaries = [
530
+ "COSMOS-2251 DEB",
531
+ "FENGYUN-1C DEB",
532
+ "SL-16 R/B",
533
+ "IRIDIUM 33 DEB",
534
+ "NOAA 17 DEB",
535
+ "ATLAS 5 CENTAUR R/B",
536
+ "BREEZE-M DEB",
537
+ "CZ-3B R/B",
538
+ "UNKNOWN DEB",
539
+ "MICROSAT-R DEB",
540
+ "DELTA 2 R/B",
541
+ "H-2A R/B"
542
+ ];
543
+ const now = Date.now();
544
+ const events = [];
545
+ for (let i = 0; i < eventCount; i++) {
546
+ const tca = now + Math.random() * timeRangeHours * 36e5;
547
+ let missDistance;
548
+ if (includeHighRisk && i < 2) missDistance = .1 + Math.random() * .9;
549
+ else if (i < 5) missDistance = 1 + Math.random() * 4;
550
+ else missDistance = 5 + Math.random() * 15;
551
+ const probability = Math.pow(10, -3 - missDistance * 1.5 + Math.random());
552
+ const relativeVelocity = 5 + Math.random() * 12;
553
+ const angle = Math.random() * 2 * Math.PI;
554
+ const incAngle = (Math.random() - .5) * Math.PI;
555
+ const radius = 6800 + Math.random() * 600;
556
+ events.push({
557
+ id: `CDM-${String(i + 1).padStart(3, "0")}`,
558
+ primary: primaryName,
559
+ secondary: secondaries[i % secondaries.length],
560
+ tca,
561
+ missDistance: Math.round(missDistance * 1e3) / 1e3,
562
+ probability: Math.max(1e-10, probability),
563
+ relativeVelocity: Math.round(relativeVelocity * 100) / 100,
564
+ position: {
565
+ x: Math.round(radius * Math.cos(angle) * Math.cos(incAngle)),
566
+ y: Math.round(radius * Math.sin(angle) * Math.cos(incAngle)),
567
+ z: Math.round(radius * Math.sin(incAngle))
568
+ },
569
+ uncertainty: {
570
+ rx: 20 + Math.random() * 100,
571
+ ry: 50 + Math.random() * 300,
572
+ rz: 10 + Math.random() * 60
573
+ }
574
+ });
575
+ }
576
+ return events.sort((a, b) => a.tca - b.tca);
505
577
  }
506
- export {
507
- generateAttitudeData,
508
- generateConjunctionEvents,
509
- generateConstellationCoverage,
510
- generateContactWindows,
511
- generateDopplerData,
512
- generateEclipseTimeline,
513
- generateHeliocentricOrbits,
514
- generatePowerData,
515
- generateSpectrum,
516
- generateWaterfallData
517
- };
518
- //# sourceMappingURL=generators.js.map
578
+ //#endregion
579
+ export { generateAttitudeData, generateConjunctionEvents, generateConstellationCoverage, generateContactWindows, generateDopplerData, generateEclipseTimeline, generateHeliocentricOrbits, generatePowerData, generateSpectrum, generateWaterfallData };
580
+
581
+ //# sourceMappingURL=generators.js.map