@zendir/ui 0.2.20 → 0.3.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 (260) hide show
  1. package/CHANGELOG.md +192 -1
  2. package/README.md +70 -28
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +57 -41
  5. package/dist/index.js.map +1 -1
  6. package/dist/react/3d/CesiumCaptureSource.d.ts +119 -0
  7. package/dist/react/3d/CesiumCaptureSource.js +307 -0
  8. package/dist/react/3d/CesiumCaptureSource.js.map +1 -0
  9. package/dist/react/3d/ZenSpace3D.js +1253 -0
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  11. package/dist/react/3d/ZenSpace3DCesium.js +579 -0
  12. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3DTypes.d.ts +28 -1
  14. package/dist/react/3d/ZenSpace3DUtils.d.ts +17 -173
  15. package/dist/react/3d/ZenSpace3DUtils.js +28 -0
  16. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
  17. package/dist/react/3d/capturePngAnalysis.d.ts +16 -0
  18. package/dist/react/3d/index.d.ts +10 -12
  19. package/dist/react/3d/threeLoader.js +18 -0
  20. package/dist/react/3d/threeLoader.js.map +1 -0
  21. package/dist/react/astro/MonitoringIcon.js +1 -1
  22. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  23. package/dist/react/astro/SimulationControls.js +2 -2
  24. package/dist/react/astro/SimulationControls.js.map +1 -1
  25. package/dist/react/astro/UnifiedTimeline.js +4 -4
  26. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  27. package/dist/react/charts/GroundTrackMap.d.ts +2 -15
  28. package/dist/react/charts/GroundTrackMap.js +1 -1
  29. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  30. package/dist/react/charts/unified/AstroChart.js +34 -13
  31. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  32. package/dist/react/chatgpt/AppCard.d.ts +0 -4
  33. package/dist/react/chatgpt/index.d.ts +0 -19
  34. package/dist/react/context/SpatialSelectionContext.d.ts +40 -0
  35. package/dist/react/context/SpatialSelectionContext.js +10 -0
  36. package/dist/react/context/SpatialSelectionContext.js.map +1 -0
  37. package/dist/react/context/index.d.ts +2 -0
  38. package/dist/react/core/{DataTable.d.ts → data/DataTable.d.ts} +1 -1
  39. package/dist/react/core/{DataTable.js → data/DataTable.js} +4 -4
  40. package/dist/react/core/data/DataTable.js.map +1 -0
  41. package/dist/react/core/{DataValue.d.ts → data/DataValue.d.ts} +2 -2
  42. package/dist/react/core/{DataValue.js → data/DataValue.js} +2 -2
  43. package/dist/react/core/data/DataValue.js.map +1 -0
  44. package/dist/react/core/{propertyConfig.d.ts → data/propertyConfig.d.ts} +2 -2
  45. package/dist/react/core/data/propertyConfig.js.map +1 -0
  46. package/dist/react/core/{AstroIcon.js → display/AstroIcon.js} +1 -1
  47. package/dist/react/core/display/AstroIcon.js.map +1 -0
  48. package/dist/react/core/{Badge.d.ts → display/Badge.d.ts} +1 -1
  49. package/dist/react/core/{Badge.js → display/Badge.js} +2 -2
  50. package/dist/react/core/display/Badge.js.map +1 -0
  51. package/dist/react/core/{CardHeader.d.ts → display/CardHeader.d.ts} +1 -1
  52. package/dist/react/core/{CardHeader.js → display/CardHeader.js} +2 -2
  53. package/dist/react/core/display/CardHeader.js.map +1 -0
  54. package/dist/react/core/{Container.d.ts → display/Container.d.ts} +1 -1
  55. package/dist/react/core/{Container.js → display/Container.js} +3 -3
  56. package/dist/react/core/display/Container.js.map +1 -0
  57. package/dist/react/core/{CopyButton.js → display/CopyButton.js} +1 -1
  58. package/dist/react/core/display/CopyButton.js.map +1 -0
  59. package/dist/react/core/{GlassCard.d.ts → display/GlassCard.d.ts} +1 -1
  60. package/dist/react/core/{GlassCard.js → display/GlassCard.js} +2 -2
  61. package/dist/react/core/display/GlassCard.js.map +1 -0
  62. package/dist/react/core/{HeaderIconWithStatus.d.ts → display/HeaderIconWithStatus.d.ts} +1 -1
  63. package/dist/react/core/{HeaderIconWithStatus.js → display/HeaderIconWithStatus.js} +1 -1
  64. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -0
  65. package/dist/react/core/{Icon.d.ts → display/Icon.d.ts} +1 -1
  66. package/dist/react/core/{Icon.js → display/Icon.js} +1 -1
  67. package/dist/react/core/display/Icon.js.map +1 -0
  68. package/dist/react/core/{Typography.d.ts → display/Typography.d.ts} +13 -4
  69. package/dist/react/core/{Typography.js → display/Typography.js} +1 -1
  70. package/dist/react/core/display/Typography.js.map +1 -0
  71. package/dist/react/core/{ConfirmDialog.js → feedback/ConfirmDialog.js} +1 -1
  72. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -0
  73. package/dist/react/core/{Dialog.js → feedback/Dialog.js} +2 -2
  74. package/dist/react/core/feedback/Dialog.js.map +1 -0
  75. package/dist/react/core/{Toast.js → feedback/Toast.js} +3 -3
  76. package/dist/react/core/feedback/Toast.js.map +1 -0
  77. package/dist/react/core/index.d.ts +85 -83
  78. package/dist/react/core/{Button.js → inputs/Button.js} +2 -2
  79. package/dist/react/core/inputs/Button.js.map +1 -0
  80. package/dist/react/core/{Checkbox.js → inputs/Checkbox.js} +2 -2
  81. package/dist/react/core/inputs/Checkbox.js.map +1 -0
  82. package/dist/react/core/{Input.d.ts → inputs/Input.d.ts} +1 -1
  83. package/dist/react/core/{Input.js → inputs/Input.js} +3 -3
  84. package/dist/react/core/inputs/Input.js.map +1 -0
  85. package/dist/react/core/{LimitsBar.js → inputs/LimitsBar.js} +1 -1
  86. package/dist/react/core/inputs/LimitsBar.js.map +1 -0
  87. package/dist/react/core/{NumberInput.d.ts → inputs/NumberInput.d.ts} +2 -2
  88. package/dist/react/core/{NumberInput.js → inputs/NumberInput.js} +3 -3
  89. package/dist/react/core/inputs/NumberInput.js.map +1 -0
  90. package/dist/react/core/{PinInput.js → inputs/PinInput.js} +2 -2
  91. package/dist/react/core/inputs/PinInput.js.map +1 -0
  92. package/dist/react/core/{Select.js → inputs/Select.js} +3 -3
  93. package/dist/react/core/inputs/Select.js.map +1 -0
  94. package/dist/react/core/{Toggle.js → inputs/Toggle.js} +2 -2
  95. package/dist/react/core/inputs/Toggle.js.map +1 -0
  96. package/dist/react/core/{AppBar.d.ts → navigation/AppBar.d.ts} +1 -1
  97. package/dist/react/core/{AppBar.js → navigation/AppBar.js} +7 -7
  98. package/dist/react/core/navigation/AppBar.js.map +1 -0
  99. package/dist/react/core/{Pagination.js → navigation/Pagination.js} +2 -2
  100. package/dist/react/core/navigation/Pagination.js.map +1 -0
  101. package/dist/react/core/{SideNav.d.ts → navigation/SideNav.d.ts} +1 -1
  102. package/dist/react/core/{SideNav.js → navigation/SideNav.js} +8 -9
  103. package/dist/react/core/navigation/SideNav.js.map +1 -0
  104. package/dist/react/core/{Tabs.js → navigation/Tabs.js} +2 -2
  105. package/dist/react/core/navigation/Tabs.js.map +1 -0
  106. package/dist/react/core/{Popover.js → overlays/Popover.js} +1 -1
  107. package/dist/react/core/overlays/Popover.js.map +1 -0
  108. package/dist/react/core/{SidePanel.js → overlays/SidePanel.js} +7 -7
  109. package/dist/react/core/overlays/SidePanel.js.map +1 -0
  110. package/dist/react/core/{Tooltip.js → overlays/Tooltip.js} +2 -2
  111. package/dist/react/core/overlays/Tooltip.js.map +1 -0
  112. package/dist/react/core/{ActivityPlanner.js → widgets/ActivityPlanner.js} +1 -1
  113. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -0
  114. package/dist/react/core/widgets/Capture.d.ts +140 -0
  115. package/dist/react/core/widgets/Capture.js +804 -0
  116. package/dist/react/core/widgets/Capture.js.map +1 -0
  117. package/dist/react/core/{ChatPanel.d.ts → widgets/ChatPanel.d.ts} +1 -1
  118. package/dist/react/core/{ChatPanel.js → widgets/ChatPanel.js} +5 -4
  119. package/dist/react/core/widgets/ChatPanel.js.map +1 -0
  120. package/dist/react/core/{ColorPickerPanel.d.ts → widgets/ColorPickerPanel.d.ts} +1 -1
  121. package/dist/react/core/{ColorPickerPanel.js → widgets/ColorPickerPanel.js} +3 -3
  122. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -0
  123. package/dist/react/core/{CommandBuilder.js → widgets/CommandBuilder.js} +1 -1
  124. package/dist/react/core/widgets/CommandBuilder.js.map +1 -0
  125. package/dist/react/core/{ConnectionForm.d.ts → widgets/ConnectionForm.d.ts} +1 -1
  126. package/dist/react/core/{ConnectionForm.js → widgets/ConnectionForm.js} +2 -2
  127. package/dist/react/core/widgets/ConnectionForm.js.map +1 -0
  128. package/dist/react/core/{FileExplorer.js → widgets/FileExplorer.js} +2 -2
  129. package/dist/react/core/widgets/FileExplorer.js.map +1 -0
  130. package/dist/react/core/{HexViewer.js → widgets/HexViewer.js} +1 -1
  131. package/dist/react/core/widgets/HexViewer.js.map +1 -0
  132. package/dist/react/core/{ImageGallery.d.ts → widgets/ImageGallery.d.ts} +1 -1
  133. package/dist/react/core/{ImageGallery.js → widgets/ImageGallery.js} +3 -3
  134. package/dist/react/core/widgets/ImageGallery.js.map +1 -0
  135. package/dist/react/core/{LogViewer.d.ts → widgets/LogViewer.d.ts} +13 -3
  136. package/dist/react/core/{LogViewer.js → widgets/LogViewer.js} +28 -8
  137. package/dist/react/core/widgets/LogViewer.js.map +1 -0
  138. package/dist/react/core/{MessageStream.d.ts → widgets/MessageStream.d.ts} +2 -2
  139. package/dist/react/core/{MessageStream.js → widgets/MessageStream.js} +4 -4
  140. package/dist/react/core/widgets/MessageStream.js.map +1 -0
  141. package/dist/react/core/{MissionCalendar.js → widgets/MissionCalendar.js} +2 -2
  142. package/dist/react/core/widgets/MissionCalendar.js.map +1 -0
  143. package/dist/react/core/{PacketViewer.js → widgets/PacketViewer.js} +1 -1
  144. package/dist/react/core/widgets/PacketViewer.js.map +1 -0
  145. package/dist/react/core/widgets/capture-placeholder.png.js +5 -0
  146. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -0
  147. package/dist/react/hooks/index.d.ts +9 -11
  148. package/dist/react/hooks/useAccessWindows.d.ts +15 -19
  149. package/dist/react/hooks/useGroundTrackHistory.d.ts +34 -0
  150. package/dist/react/hooks/useSimulationScene.d.ts +141 -0
  151. package/dist/react/hooks/useSimulationScene.js +401 -0
  152. package/dist/react/hooks/useSimulationScene.js.map +1 -0
  153. package/dist/react/hooks/useZendirSession.d.ts +44 -69
  154. package/dist/react/index.d.ts +10 -5
  155. package/dist/react/panels/LayerControlPanel.d.ts +54 -0
  156. package/dist/react/panels/LayerControlPanel.js +184 -0
  157. package/dist/react/panels/LayerControlPanel.js.map +1 -0
  158. package/dist/react/panels/ObjectInventoryPanel.d.ts +57 -0
  159. package/dist/react/panels/ObjectInventoryPanel.js +261 -0
  160. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -0
  161. package/dist/react/panels/index.d.ts +15 -0
  162. package/dist/react/theme/ThemeProvider.d.ts +2 -0
  163. package/dist/react/theme/ThemeProvider.js +50 -72
  164. package/dist/react/theme/ThemeProvider.js.map +1 -1
  165. package/dist/react/types.d.ts +32 -3
  166. package/dist/react/types.js.map +1 -1
  167. package/dist/react.js +57 -41
  168. package/dist/react.js.map +1 -1
  169. package/dist/shaders/atmosphere.frag.js +5 -0
  170. package/dist/shaders/atmosphere.frag.js.map +1 -0
  171. package/dist/shaders/atmosphere.vert.js +5 -0
  172. package/dist/shaders/atmosphere.vert.js.map +1 -0
  173. package/dist/shaders/stars.frag.js +5 -0
  174. package/dist/shaders/stars.frag.js.map +1 -0
  175. package/dist/shaders/stars.vert.js +5 -0
  176. package/dist/shaders/stars.vert.js.map +1 -0
  177. package/dist/style.css +6 -4
  178. package/dist/tokens/css-vars.d.ts +91 -0
  179. package/dist/tokens/css-vars.js +228 -0
  180. package/dist/tokens/css-vars.js.map +1 -0
  181. package/dist/tokens/index.d.ts +71 -18
  182. package/dist/tokens/index.js +206 -97
  183. package/dist/tokens/index.js.map +1 -1
  184. package/dist/tokens/tokens.css +50 -50
  185. package/package.json +27 -22
  186. package/sdk-stub.js +10 -5
  187. package/dist/react/3d/EarthViewer.d.ts +0 -46
  188. package/dist/react/3d/SolarSystemViewer.d.ts +0 -43
  189. package/dist/react/chatgpt/ChatGPTCard.d.ts +0 -6
  190. package/dist/react/core/ActivityPlanner.js.map +0 -1
  191. package/dist/react/core/AppBar.js.map +0 -1
  192. package/dist/react/core/AstroIcon.js.map +0 -1
  193. package/dist/react/core/Badge.js.map +0 -1
  194. package/dist/react/core/Button.js.map +0 -1
  195. package/dist/react/core/CardHeader.js.map +0 -1
  196. package/dist/react/core/ChatPanel.js.map +0 -1
  197. package/dist/react/core/Checkbox.js.map +0 -1
  198. package/dist/react/core/ColorPickerPanel.js.map +0 -1
  199. package/dist/react/core/CommandBuilder.js.map +0 -1
  200. package/dist/react/core/ConfirmDialog.js.map +0 -1
  201. package/dist/react/core/ConnectionForm.js.map +0 -1
  202. package/dist/react/core/Container.js.map +0 -1
  203. package/dist/react/core/CopyButton.js.map +0 -1
  204. package/dist/react/core/DataTable.js.map +0 -1
  205. package/dist/react/core/DataValue.js.map +0 -1
  206. package/dist/react/core/Dialog.js.map +0 -1
  207. package/dist/react/core/FileExplorer.js.map +0 -1
  208. package/dist/react/core/GlassCard.js.map +0 -1
  209. package/dist/react/core/HeaderIconWithStatus.js.map +0 -1
  210. package/dist/react/core/HexViewer.js.map +0 -1
  211. package/dist/react/core/Icon.js.map +0 -1
  212. package/dist/react/core/ImageGallery.js.map +0 -1
  213. package/dist/react/core/Input.js.map +0 -1
  214. package/dist/react/core/LimitsBar.js.map +0 -1
  215. package/dist/react/core/LogViewer.js.map +0 -1
  216. package/dist/react/core/MessageStream.js.map +0 -1
  217. package/dist/react/core/MissionCalendar.js.map +0 -1
  218. package/dist/react/core/NumberInput.js.map +0 -1
  219. package/dist/react/core/PacketViewer.js.map +0 -1
  220. package/dist/react/core/Pagination.js.map +0 -1
  221. package/dist/react/core/PinInput.js.map +0 -1
  222. package/dist/react/core/Popover.js.map +0 -1
  223. package/dist/react/core/Select.js.map +0 -1
  224. package/dist/react/core/SideNav.js.map +0 -1
  225. package/dist/react/core/SidePanel.js.map +0 -1
  226. package/dist/react/core/Tabs.js.map +0 -1
  227. package/dist/react/core/Toast.js.map +0 -1
  228. package/dist/react/core/Toggle.js.map +0 -1
  229. package/dist/react/core/Tooltip.js.map +0 -1
  230. package/dist/react/core/Typography.js.map +0 -1
  231. package/dist/react/core/propertyConfig.js.map +0 -1
  232. package/dist/react/hooks/useSimulationTime.d.ts +0 -61
  233. package/dist/react/hooks/useSpacecraftPosition.d.ts +0 -50
  234. package/dist/react/hooks/useTelemetry.d.ts +0 -55
  235. package/dist/types.d.ts +0 -1
  236. package/dist/types.js +0 -2
  237. package/dist/types.js.map +0 -1
  238. /package/dist/react/core/{propertyConfig.js → data/propertyConfig.js} +0 -0
  239. /package/dist/react/core/{AstroIcon.d.ts → display/AstroIcon.d.ts} +0 -0
  240. /package/dist/react/core/{CopyButton.d.ts → display/CopyButton.d.ts} +0 -0
  241. /package/dist/react/core/{ConfirmDialog.d.ts → feedback/ConfirmDialog.d.ts} +0 -0
  242. /package/dist/react/core/{Dialog.d.ts → feedback/Dialog.d.ts} +0 -0
  243. /package/dist/react/core/{Toast.d.ts → feedback/Toast.d.ts} +0 -0
  244. /package/dist/react/core/{Button.d.ts → inputs/Button.d.ts} +0 -0
  245. /package/dist/react/core/{Checkbox.d.ts → inputs/Checkbox.d.ts} +0 -0
  246. /package/dist/react/core/{LimitsBar.d.ts → inputs/LimitsBar.d.ts} +0 -0
  247. /package/dist/react/core/{PinInput.d.ts → inputs/PinInput.d.ts} +0 -0
  248. /package/dist/react/core/{Select.d.ts → inputs/Select.d.ts} +0 -0
  249. /package/dist/react/core/{Toggle.d.ts → inputs/Toggle.d.ts} +0 -0
  250. /package/dist/react/core/{Pagination.d.ts → navigation/Pagination.d.ts} +0 -0
  251. /package/dist/react/core/{Tabs.d.ts → navigation/Tabs.d.ts} +0 -0
  252. /package/dist/react/core/{Popover.d.ts → overlays/Popover.d.ts} +0 -0
  253. /package/dist/react/core/{SidePanel.d.ts → overlays/SidePanel.d.ts} +0 -0
  254. /package/dist/react/core/{Tooltip.d.ts → overlays/Tooltip.d.ts} +0 -0
  255. /package/dist/react/core/{ActivityPlanner.d.ts → widgets/ActivityPlanner.d.ts} +0 -0
  256. /package/dist/react/core/{CommandBuilder.d.ts → widgets/CommandBuilder.d.ts} +0 -0
  257. /package/dist/react/core/{FileExplorer.d.ts → widgets/FileExplorer.d.ts} +0 -0
  258. /package/dist/react/core/{HexViewer.d.ts → widgets/HexViewer.d.ts} +0 -0
  259. /package/dist/react/core/{MissionCalendar.d.ts → widgets/MissionCalendar.d.ts} +0 -0
  260. /package/dist/react/core/{PacketViewer.d.ts → widgets/PacketViewer.d.ts} +0 -0
@@ -0,0 +1,579 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useRef, useEffect, useCallback, useImperativeHandle } from "react";
3
+ const EARTH_RADIUS_KM = 6371;
4
+ function eciKmToFixedCartesian3(Cesium, positionKm, julianDate) {
5
+ if (!positionKm || !Number.isFinite(positionKm.x) || !Number.isFinite(positionKm.y) || !Number.isFinite(positionKm.z)) {
6
+ return null;
7
+ }
8
+ const eciM = new Cesium.Cartesian3(
9
+ positionKm.x * 1e3,
10
+ positionKm.y * 1e3,
11
+ positionKm.z * 1e3
12
+ );
13
+ const rot = Cesium.Transforms.computeTemeToPseudoFixedMatrix(julianDate);
14
+ if (!rot) {
15
+ return eciM;
16
+ }
17
+ return Cesium.Matrix3.multiplyByVector(rot, eciM, new Cesium.Cartesian3());
18
+ }
19
+ function eciKmToSubSatellite(Cesium, positionKm, julianDate) {
20
+ const fixed = eciKmToFixedCartesian3(Cesium, positionKm, julianDate);
21
+ if (!fixed) return null;
22
+ const carto = Cesium.Cartographic.fromCartesian(fixed);
23
+ if (!carto || !Number.isFinite(carto.height)) return null;
24
+ return {
25
+ latitude: Cesium.Math.toDegrees(carto.latitude),
26
+ longitude: Cesium.Math.toDegrees(carto.longitude),
27
+ altitude: carto.height / 1e3
28
+ // m → km
29
+ };
30
+ }
31
+ function autoFootprintRadiusM(altitudeKm, minElevDeg) {
32
+ if (altitudeKm <= 0) return 0;
33
+ const R = EARTH_RADIUS_KM;
34
+ const eps = minElevDeg * Math.PI / 180;
35
+ const sinAlpha = R * Math.cos(eps) / (R + altitudeKm);
36
+ if (sinAlpha >= 1) return 0;
37
+ const alpha = Math.asin(sinAlpha);
38
+ const lambda = Math.PI / 2 - eps - alpha;
39
+ return R * 1e3 * lambda;
40
+ }
41
+ function halfAngleFootprintRadiusM(altitudeKm, halfAngleDeg) {
42
+ return altitudeKm * 1e3 * Math.tan(halfAngleDeg * Math.PI / 180);
43
+ }
44
+ function removeFromMap(viewer, id, map) {
45
+ if (map.current.has(id)) {
46
+ try {
47
+ viewer.entities.removeById(id);
48
+ } catch (_) {
49
+ }
50
+ map.current.delete(id);
51
+ }
52
+ }
53
+ function makePointGraphics(Cesium, color, pixelSize = 8) {
54
+ return {
55
+ pixelSize,
56
+ color,
57
+ outlineColor: Cesium.Color.WHITE,
58
+ outlineWidth: 1,
59
+ scaleByDistance: new Cesium.NearFarScalar(1e6, 1.5, 5e7, 0.5),
60
+ // Always render on top so satellites hidden behind Earth are still visible
61
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
62
+ };
63
+ }
64
+ function makeLabelOpts(Cesium, text, fillColor) {
65
+ return {
66
+ text,
67
+ font: "12px monospace",
68
+ fillColor: fillColor ?? Cesium.Color.WHITE,
69
+ outlineColor: Cesium.Color.BLACK,
70
+ outlineWidth: 2,
71
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
72
+ pixelOffset: new Cesium.Cartesian2(12, 0),
73
+ scaleByDistance: new Cesium.NearFarScalar(1e6, 1, 5e7, 0.3),
74
+ // Fade out label when camera is very far away
75
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 3e7),
76
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
77
+ };
78
+ }
79
+ function upsertEllipse(viewer, Cesium, id, position, radiusM, color, map) {
80
+ const existing = map.current.get(id);
81
+ if (existing) {
82
+ existing.position = new Cesium.ConstantPositionProperty(position);
83
+ existing.ellipse.semiMajorAxis = new Cesium.ConstantProperty(radiusM);
84
+ existing.ellipse.semiMinorAxis = new Cesium.ConstantProperty(radiusM);
85
+ } else {
86
+ const entity = viewer.entities.add({
87
+ id,
88
+ position,
89
+ ellipse: {
90
+ semiMajorAxis: radiusM,
91
+ semiMinorAxis: radiusM,
92
+ material: color.withAlpha(0.08),
93
+ outline: true,
94
+ outlineColor: color.withAlpha(0.5),
95
+ outlineWidth: 1,
96
+ height: 0
97
+ }
98
+ });
99
+ map.current.set(id, entity);
100
+ }
101
+ }
102
+ function renderExplicitCoverage(viewer, Cesium, satId, satPos3, cov, julianDate, covMap, coneMap, nadirMap) {
103
+ var _a, _b;
104
+ const baseColor = cov.color ? Cesium.Color.fromCssColorString(cov.color) : Cesium.Color.CYAN;
105
+ const opacity = cov.opacity ?? 0.2;
106
+ const resolvedPos = cov.satellitePosition ?? satPos3;
107
+ const satCesPos = eciKmToFixedCartesian3(Cesium, resolvedPos, julianDate);
108
+ const subSat = eciKmToSubSatellite(Cesium, resolvedPos, julianDate);
109
+ const latitude = (subSat == null ? void 0 : subSat.latitude) ?? NaN;
110
+ const longitude = (subSat == null ? void 0 : subSat.longitude) ?? NaN;
111
+ const altitude = (subSat == null ? void 0 : subSat.altitude) ?? NaN;
112
+ const nadirLat = ((_a = cov.nadirPoint) == null ? void 0 : _a.latitude) ?? latitude;
113
+ const nadirLon = ((_b = cov.nadirPoint) == null ? void 0 : _b.longitude) ?? longitude;
114
+ const covId = `cov-${satId}`;
115
+ if (cov.showFootprint !== false && cov.footprintPolygon && cov.footprintPolygon.length >= 3) {
116
+ const positions = Cesium.Cartesian3.fromDegreesArray(
117
+ cov.footprintPolygon.flatMap((pt) => [pt.longitude, pt.latitude])
118
+ );
119
+ const existing = covMap.current.get(covId);
120
+ if (existing) {
121
+ existing.polygon.hierarchy = new Cesium.ConstantProperty(
122
+ new Cesium.PolygonHierarchy(positions)
123
+ );
124
+ } else {
125
+ const entity = viewer.entities.add({
126
+ id: covId,
127
+ polygon: {
128
+ hierarchy: new Cesium.PolygonHierarchy(positions),
129
+ material: baseColor.withAlpha(opacity),
130
+ outline: true,
131
+ outlineColor: baseColor.withAlpha(opacity * 3),
132
+ height: 0,
133
+ clampToGround: true
134
+ }
135
+ });
136
+ covMap.current.set(covId, entity);
137
+ }
138
+ } else if (cov.showFootprint !== false && cov.halfAngle != null && Number.isFinite(altitude) && altitude > 0) {
139
+ const subSatPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, 0);
140
+ const radius = halfAngleFootprintRadiusM(altitude, cov.halfAngle);
141
+ upsertEllipse(viewer, Cesium, covId, subSatPos, radius, baseColor, covMap);
142
+ } else {
143
+ removeFromMap(viewer, covId, covMap);
144
+ }
145
+ const coneId = `cone-${satId}`;
146
+ if (cov.showCone && satCesPos && Number.isFinite(altitude) && altitude > 0) {
147
+ const radius = cov.halfAngle != null ? halfAngleFootprintRadiusM(altitude, cov.halfAngle) : autoFootprintRadiusM(altitude, 5);
148
+ const coneLength = altitude * 1e3;
149
+ const midPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, coneLength / 2);
150
+ const existing = coneMap.current.get(coneId);
151
+ if (existing) {
152
+ existing.position = new Cesium.ConstantPositionProperty(midPos);
153
+ existing.cylinder.length = new Cesium.ConstantProperty(coneLength);
154
+ existing.cylinder.bottomRadius = new Cesium.ConstantProperty(radius);
155
+ } else {
156
+ const entity = viewer.entities.add({
157
+ id: coneId,
158
+ position: midPos,
159
+ cylinder: {
160
+ length: coneLength,
161
+ topRadius: 0,
162
+ bottomRadius: radius,
163
+ material: baseColor.withAlpha(0.06),
164
+ outline: true,
165
+ outlineColor: baseColor.withAlpha(0.25),
166
+ numberOfVerticalLines: 12
167
+ }
168
+ });
169
+ coneMap.current.set(coneId, entity);
170
+ }
171
+ } else {
172
+ removeFromMap(viewer, coneId, coneMap);
173
+ }
174
+ const nadirId = `nadir-${satId}`;
175
+ if (cov.showNadirLine && satCesPos) {
176
+ const groundPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, 0);
177
+ const existing = nadirMap.current.get(nadirId);
178
+ if (existing) {
179
+ existing.polyline.positions = new Cesium.ConstantProperty([satCesPos, groundPos]);
180
+ } else {
181
+ const entity = viewer.entities.add({
182
+ id: nadirId,
183
+ polyline: {
184
+ positions: [satCesPos, groundPos],
185
+ width: 1,
186
+ material: new Cesium.PolylineDashMaterialProperty({
187
+ color: baseColor.withAlpha(0.5),
188
+ dashLength: 8
189
+ })
190
+ }
191
+ });
192
+ nadirMap.current.set(nadirId, entity);
193
+ }
194
+ } else {
195
+ removeFromMap(viewer, nadirId, nadirMap);
196
+ }
197
+ }
198
+ const ZenSpace3DCesium = forwardRef(
199
+ function ZenSpace3DCesium2({
200
+ satellites = [],
201
+ stations = [],
202
+ groundStations = [],
203
+ customObjects = [],
204
+ orbitPaths = [],
205
+ satelliteCoverages = [],
206
+ view = "earth-orbit",
207
+ height = 600,
208
+ callbacks,
209
+ showTools = false,
210
+ layers,
211
+ visibility,
212
+ referenceTime,
213
+ cesium: Cesium
214
+ }, ref) {
215
+ const containerRef = useRef(null);
216
+ const viewerRef = useRef(null);
217
+ const callbacksRef = useRef(callbacks);
218
+ useEffect(() => {
219
+ callbacksRef.current = callbacks;
220
+ }, [callbacks]);
221
+ const satMapRef = useRef(/* @__PURE__ */ new Map());
222
+ const gsMapRef = useRef(/* @__PURE__ */ new Map());
223
+ const covMapRef = useRef(/* @__PURE__ */ new Map());
224
+ const coneMapRef = useRef(/* @__PURE__ */ new Map());
225
+ const nadirMapRef = useRef(/* @__PURE__ */ new Map());
226
+ const orbitMapRef = useRef(/* @__PURE__ */ new Map());
227
+ const eciPositionsRef = useRef(/* @__PURE__ */ new Map());
228
+ const showLabels = (layers == null ? void 0 : layers.labels) === true;
229
+ const showCoverage = (layers == null ? void 0 : layers.coverage) === true;
230
+ const showOrbits = (layers == null ? void 0 : layers.orbits) !== false;
231
+ const showSpacecraft = (visibility == null ? void 0 : visibility.spacecraft) !== false;
232
+ const showGroundStations = (visibility == null ? void 0 : visibility.groundStations) !== false;
233
+ const showCelestialBodies = (visibility == null ? void 0 : visibility.celestialBodies) !== false;
234
+ const focusOn = useCallback(
235
+ (objectId, options) => {
236
+ const viewer = viewerRef.current;
237
+ if (!viewer) return;
238
+ const entity = viewer.entities.getById(objectId);
239
+ if (entity) {
240
+ viewer.zoomTo(entity, { duration: (options == null ? void 0 : options.animate) !== false ? 1.5 : 0 });
241
+ }
242
+ },
243
+ []
244
+ );
245
+ const setView = useCallback(
246
+ (mode) => {
247
+ const viewer = viewerRef.current;
248
+ if (!viewer) return;
249
+ if (mode === "earth-orbit") {
250
+ viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(0, 0, 2e7) });
251
+ } else if (mode === "solar-system") {
252
+ viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(0, 0, 5e7) });
253
+ }
254
+ },
255
+ [Cesium]
256
+ );
257
+ useImperativeHandle(
258
+ ref,
259
+ () => ({
260
+ focusOn,
261
+ flyTo: focusOn,
262
+ setView,
263
+ setTime: () => {
264
+ },
265
+ setTimeScale: () => {
266
+ },
267
+ togglePlay: () => {
268
+ },
269
+ setLayerVisibility: () => {
270
+ },
271
+ getCameraState: () => ({}),
272
+ setCameraState: () => {
273
+ },
274
+ exportImage: () => "",
275
+ exportScene: () => new Blob(),
276
+ getVisibleObjects: () => [],
277
+ findObjects: () => [],
278
+ addObject: () => {
279
+ },
280
+ removeObject: () => {
281
+ },
282
+ updateObject: () => {
283
+ },
284
+ measureDistance: () => 0
285
+ }),
286
+ [focusOn, setView]
287
+ );
288
+ useEffect(() => {
289
+ if (!containerRef.current || !Cesium) return;
290
+ satMapRef.current.clear();
291
+ gsMapRef.current.clear();
292
+ covMapRef.current.clear();
293
+ coneMapRef.current.clear();
294
+ nadirMapRef.current.clear();
295
+ orbitMapRef.current.clear();
296
+ eciPositionsRef.current.clear();
297
+ const viewer = new Cesium.Viewer(containerRef.current, {
298
+ baseLayerPicker: false,
299
+ fullscreenButton: false,
300
+ vrButton: false,
301
+ geocoder: false,
302
+ homeButton: !!showTools,
303
+ sceneModePicker: false,
304
+ timeline: false,
305
+ navigationHelpButton: !!showTools,
306
+ animation: false,
307
+ scene3DOnly: true,
308
+ useDefaultRenderLoop: true,
309
+ requestRenderMode: false
310
+ });
311
+ viewer.scene.globe.enableLighting = true;
312
+ viewer.scene.backgroundColor = Cesium.Color.BLACK;
313
+ viewer.scene.renderError.addEventListener((scene, err) => {
314
+ console.error("[ZenSpace3D] Cesium render error:", err);
315
+ });
316
+ viewer.clock.currentTime = Cesium.JulianDate.now();
317
+ viewer.clock.multiplier = 1;
318
+ viewer.clock.shouldAnimate = true;
319
+ viewerRef.current = viewer;
320
+ const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
321
+ handler.setInputAction((movement) => {
322
+ var _a;
323
+ const picked = viewer.scene.pick(movement.position);
324
+ if (Cesium.defined(picked) && picked.id && ((_a = callbacksRef.current) == null ? void 0 : _a.onSelect)) {
325
+ callbacksRef.current.onSelect({
326
+ id: picked.id.id,
327
+ name: picked.id.name,
328
+ category: "satellite",
329
+ position: { x: 0, y: 0, z: 0 },
330
+ visualRadius: 0
331
+ });
332
+ }
333
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
334
+ handler.setInputAction((movement) => {
335
+ var _a, _b, _c, _d;
336
+ const picked = viewer.scene.pick(movement.endPosition);
337
+ if (Cesium.defined(picked) && picked.id) {
338
+ (_b = (_a = callbacksRef.current) == null ? void 0 : _a.onHover) == null ? void 0 : _b.call(_a, {
339
+ id: picked.id.id,
340
+ name: picked.id.name,
341
+ category: "satellite",
342
+ position: { x: 0, y: 0, z: 0 },
343
+ visualRadius: 0
344
+ });
345
+ } else {
346
+ (_d = (_c = callbacksRef.current) == null ? void 0 : _c.onHover) == null ? void 0 : _d.call(_c, null);
347
+ }
348
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
349
+ return () => {
350
+ handler.destroy();
351
+ satMapRef.current.clear();
352
+ gsMapRef.current.clear();
353
+ covMapRef.current.clear();
354
+ coneMapRef.current.clear();
355
+ nadirMapRef.current.clear();
356
+ orbitMapRef.current.clear();
357
+ eciPositionsRef.current.clear();
358
+ viewer.destroy();
359
+ viewerRef.current = null;
360
+ };
361
+ }, [Cesium, showTools]);
362
+ useEffect(() => {
363
+ const viewer = viewerRef.current;
364
+ if (!viewer || !Cesium) return;
365
+ const jd = referenceTime ? Cesium.JulianDate.fromDate(referenceTime) : Cesium.JulianDate.now();
366
+ const seenSats = /* @__PURE__ */ new Set();
367
+ const renderedSats = showSpacecraft ? [...satellites, ...stations] : [];
368
+ renderedSats.forEach((obj) => {
369
+ const id = obj.id;
370
+ const pos3 = obj.position;
371
+ if (!pos3) return;
372
+ if (!Number.isFinite(pos3.x) || !Number.isFinite(pos3.y) || !Number.isFinite(pos3.z)) return;
373
+ eciPositionsRef.current.set(id, pos3);
374
+ seenSats.add(id);
375
+ const name = obj.name ?? id;
376
+ const existing = satMapRef.current.get(id);
377
+ if (existing) {
378
+ if (existing.label) {
379
+ existing.label.show = new Cesium.ConstantProperty(showLabels);
380
+ } else if (showLabels) {
381
+ existing.label = new Cesium.LabelGraphics(makeLabelOpts(Cesium, name));
382
+ }
383
+ } else {
384
+ const capturedId = id;
385
+ const posProperty = new Cesium.CallbackPositionProperty(
386
+ (time) => {
387
+ try {
388
+ const eciKm = eciPositionsRef.current.get(capturedId);
389
+ if (!eciKm) return void 0;
390
+ const fixed = eciKmToFixedCartesian3(Cesium, eciKm, time);
391
+ if (!fixed || !Number.isFinite(fixed.x) || !Number.isFinite(fixed.y) || !Number.isFinite(fixed.z)) {
392
+ return void 0;
393
+ }
394
+ return fixed;
395
+ } catch {
396
+ return void 0;
397
+ }
398
+ },
399
+ false,
400
+ // not constant — must be re-evaluated every frame
401
+ Cesium.ReferenceFrame.FIXED
402
+ );
403
+ const entity = viewer.entities.add({
404
+ id,
405
+ name,
406
+ position: posProperty,
407
+ point: makePointGraphics(Cesium, Cesium.Color.CYAN),
408
+ label: showLabels ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, name)) : void 0
409
+ });
410
+ satMapRef.current.set(id, entity);
411
+ }
412
+ const explicitCov = (satelliteCoverages ?? []).find((c) => c.satelliteId === id);
413
+ if (explicitCov) {
414
+ renderExplicitCoverage(
415
+ viewer,
416
+ Cesium,
417
+ id,
418
+ pos3,
419
+ explicitCov,
420
+ jd,
421
+ covMapRef,
422
+ coneMapRef,
423
+ nadirMapRef
424
+ );
425
+ } else if (showCoverage) {
426
+ const subSat = eciKmToSubSatellite(Cesium, pos3, jd);
427
+ if (subSat && subSat.altitude > 0) {
428
+ const subSatPos = Cesium.Cartesian3.fromDegrees(subSat.longitude, subSat.latitude, 0);
429
+ const radius = autoFootprintRadiusM(subSat.altitude, 5);
430
+ upsertEllipse(viewer, Cesium, `cov-${id}`, subSatPos, radius, Cesium.Color.CYAN, covMapRef);
431
+ }
432
+ } else {
433
+ removeFromMap(viewer, `cov-${id}`, covMapRef);
434
+ removeFromMap(viewer, `cone-${id}`, coneMapRef);
435
+ removeFromMap(viewer, `nadir-${id}`, nadirMapRef);
436
+ }
437
+ });
438
+ satMapRef.current.forEach((_, id) => {
439
+ if (!seenSats.has(id)) {
440
+ eciPositionsRef.current.delete(id);
441
+ removeFromMap(viewer, id, satMapRef);
442
+ removeFromMap(viewer, `cov-${id}`, covMapRef);
443
+ removeFromMap(viewer, `cone-${id}`, coneMapRef);
444
+ removeFromMap(viewer, `nadir-${id}`, nadirMapRef);
445
+ }
446
+ });
447
+ const seenCustom = /* @__PURE__ */ new Set();
448
+ const renderedCustom = showCelestialBodies ? customObjects ?? [] : [];
449
+ renderedCustom.forEach((obj) => {
450
+ if (/^earth$/i.test(obj.name ?? "")) return;
451
+ const id = obj.id;
452
+ const cesPos = eciKmToFixedCartesian3(Cesium, obj.position, jd);
453
+ if (!cesPos) return;
454
+ seenCustom.add(id);
455
+ const existing = satMapRef.current.get(`custom-${id}`);
456
+ if (existing) {
457
+ existing.position = new Cesium.ConstantPositionProperty(cesPos);
458
+ if (existing.label) {
459
+ existing.label.show = new Cesium.ConstantProperty(showLabels);
460
+ } else if (showLabels) {
461
+ existing.label = new Cesium.LabelGraphics(
462
+ makeLabelOpts(Cesium, obj.name ?? id, Cesium.Color.ORANGE)
463
+ );
464
+ }
465
+ } else {
466
+ const entity = viewer.entities.add({
467
+ id: `custom-${id}`,
468
+ name: obj.name,
469
+ position: cesPos,
470
+ point: makePointGraphics(Cesium, Cesium.Color.ORANGE, 10),
471
+ label: showLabels ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, obj.name ?? id, Cesium.Color.ORANGE)) : void 0
472
+ });
473
+ satMapRef.current.set(`custom-${id}`, entity);
474
+ }
475
+ });
476
+ satMapRef.current.forEach((_, key) => {
477
+ if (key.startsWith("custom-") && !seenCustom.has(key.slice(7))) {
478
+ removeFromMap(viewer, key, satMapRef);
479
+ }
480
+ });
481
+ const seenGs = /* @__PURE__ */ new Set();
482
+ const renderedGs = showGroundStations ? groundStations ?? [] : [];
483
+ renderedGs.forEach((gs) => {
484
+ if (!Number.isFinite(gs.longitude) || !Number.isFinite(gs.latitude)) return;
485
+ seenGs.add(gs.id);
486
+ const heightM = Number.isFinite(gs.elevation) ? gs.elevation : 0;
487
+ const gsPos = Cesium.Cartesian3.fromDegrees(gs.longitude, gs.latitude, heightM);
488
+ const name = gs.name ?? gs.id;
489
+ const existing = gsMapRef.current.get(gs.id);
490
+ if (existing) {
491
+ existing.position = new Cesium.ConstantPositionProperty(gsPos);
492
+ if (existing.label) {
493
+ existing.label.show = new Cesium.ConstantProperty(showLabels);
494
+ } else if (showLabels) {
495
+ existing.label = new Cesium.LabelGraphics(
496
+ makeLabelOpts(Cesium, name, Cesium.Color.YELLOW)
497
+ );
498
+ }
499
+ } else {
500
+ const entity = viewer.entities.add({
501
+ id: gs.id,
502
+ name,
503
+ position: gsPos,
504
+ point: makePointGraphics(Cesium, Cesium.Color.YELLOW, 6),
505
+ label: showLabels ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, name, Cesium.Color.YELLOW)) : void 0
506
+ });
507
+ gsMapRef.current.set(gs.id, entity);
508
+ }
509
+ });
510
+ gsMapRef.current.forEach((_, id) => {
511
+ if (!seenGs.has(id)) removeFromMap(viewer, id, gsMapRef);
512
+ });
513
+ if (showOrbits) {
514
+ const seenOrbits = /* @__PURE__ */ new Set();
515
+ (orbitPaths ?? []).forEach((path) => {
516
+ const orbitId = `orbit-${path.objectId}`;
517
+ seenOrbits.add(orbitId);
518
+ const positions = path.points.map((p) => eciKmToFixedCartesian3(Cesium, p, jd)).filter((p) => p != null);
519
+ if (positions.length < 2) return;
520
+ const orbitColor = path.color ? Cesium.Color.fromCssColorString(path.color).withAlpha(0.65) : Cesium.Color.YELLOW.withAlpha(0.55);
521
+ const existing = orbitMapRef.current.get(orbitId);
522
+ if (existing) {
523
+ existing.polyline.positions = new Cesium.ConstantProperty(positions);
524
+ } else {
525
+ const entity = viewer.entities.add({
526
+ id: orbitId,
527
+ name: path.objectId,
528
+ polyline: {
529
+ positions,
530
+ width: 1.5,
531
+ material: new Cesium.PolylineDashMaterialProperty({
532
+ color: orbitColor,
533
+ dashLength: 16
534
+ })
535
+ }
536
+ });
537
+ orbitMapRef.current.set(orbitId, entity);
538
+ }
539
+ });
540
+ orbitMapRef.current.forEach((_, id) => {
541
+ if (!seenOrbits.has(id)) removeFromMap(viewer, id, orbitMapRef);
542
+ });
543
+ } else {
544
+ orbitMapRef.current.forEach((_, id) => removeFromMap(viewer, id, orbitMapRef));
545
+ }
546
+ }, [
547
+ Cesium,
548
+ satellites,
549
+ stations,
550
+ customObjects,
551
+ groundStations,
552
+ orbitPaths,
553
+ satelliteCoverages,
554
+ showLabels,
555
+ showCoverage,
556
+ showOrbits,
557
+ showSpacecraft,
558
+ showGroundStations,
559
+ showCelestialBodies,
560
+ referenceTime
561
+ ]);
562
+ useEffect(() => {
563
+ setView(view);
564
+ }, [view]);
565
+ const h = typeof height === "number" ? `${height}px` : height;
566
+ return /* @__PURE__ */ jsx(
567
+ "div",
568
+ {
569
+ ref: containerRef,
570
+ className: "zendir-zenspace3d-cesium",
571
+ style: { width: "100%", height: h, minHeight: 200 }
572
+ }
573
+ );
574
+ }
575
+ );
576
+ export {
577
+ ZenSpace3DCesium
578
+ };
579
+ //# sourceMappingURL=ZenSpace3DCesium.js.map