matterviz 0.3.6 → 0.4.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 (926) hide show
  1. package/dist/EmptyState.svelte.d.ts +9 -0
  2. package/dist/FilePicker.svelte +360 -0
  3. package/dist/FilePicker.svelte.d.ts +17 -0
  4. package/dist/Icon.svelte +44 -0
  5. package/dist/Icon.svelte.d.ts +13 -0
  6. package/dist/MillerIndexInput.svelte +66 -0
  7. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  8. package/dist/api/mp.d.ts +6 -0
  9. package/dist/api/mp.js +22 -0
  10. package/dist/api/optimade.d.ts +45 -0
  11. package/dist/api/optimade.js +141 -0
  12. package/dist/app.css +244 -0
  13. package/dist/brillouin/BrillouinZone.svelte +554 -0
  14. package/dist/brillouin/BrillouinZone.svelte.d.ts +84 -0
  15. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  16. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  17. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  19. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  20. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  21. package/dist/brillouin/BrillouinZoneScene.svelte +522 -0
  22. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +49 -0
  23. package/dist/brillouin/BrillouinZoneTooltip.svelte +83 -0
  24. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  25. package/dist/brillouin/compute.d.ts +17 -0
  26. package/dist/brillouin/compute.js +422 -0
  27. package/dist/brillouin/index.d.ts +8 -0
  28. package/dist/brillouin/index.js +7 -0
  29. package/dist/brillouin/types.d.ts +43 -0
  30. package/dist/brillouin/types.js +1 -0
  31. package/dist/chempot-diagram/ChemPotDiagram.svelte +328 -0
  32. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  33. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +843 -0
  34. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3191 -0
  36. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  37. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  38. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  39. package/dist/chempot-diagram/async-compute.svelte.js +80 -0
  40. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  41. package/dist/chempot-diagram/chempot-worker.js +12 -0
  42. package/dist/chempot-diagram/color.d.ts +10 -0
  43. package/dist/chempot-diagram/color.js +32 -0
  44. package/dist/chempot-diagram/compute.d.ts +48 -0
  45. package/dist/chempot-diagram/compute.js +804 -0
  46. package/dist/chempot-diagram/index.d.ts +6 -0
  47. package/dist/chempot-diagram/index.js +6 -0
  48. package/dist/chempot-diagram/pointer.d.ts +16 -0
  49. package/dist/chempot-diagram/pointer.js +40 -0
  50. package/dist/chempot-diagram/temperature.d.ts +15 -0
  51. package/dist/chempot-diagram/temperature.js +34 -0
  52. package/dist/chempot-diagram/types.d.ts +81 -0
  53. package/dist/chempot-diagram/types.js +28 -0
  54. package/dist/colors/index.d.ts +47 -0
  55. package/dist/colors/index.js +204 -0
  56. package/dist/composition/BarChart.svelte +297 -0
  57. package/dist/composition/BarChart.svelte.d.ts +39 -0
  58. package/dist/composition/BubbleChart.svelte +218 -0
  59. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  60. package/dist/composition/Composition.svelte +165 -0
  61. package/dist/composition/Composition.svelte.d.ts +15 -0
  62. package/dist/composition/Formula.svelte +268 -0
  63. package/dist/composition/Formula.svelte.d.ts +19 -0
  64. package/dist/composition/FormulaFilter.svelte +1263 -0
  65. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  66. package/dist/composition/PieChart.svelte +324 -0
  67. package/dist/composition/PieChart.svelte.d.ts +37 -0
  68. package/dist/composition/chem-sys.d.ts +8 -0
  69. package/dist/composition/chem-sys.js +85 -0
  70. package/dist/composition/format.d.ts +15 -0
  71. package/dist/composition/format.js +111 -0
  72. package/dist/composition/index.d.ts +21 -0
  73. package/dist/composition/index.js +15 -0
  74. package/dist/composition/parse.d.ts +56 -0
  75. package/dist/composition/parse.js +486 -0
  76. package/dist/constants.d.ts +29 -0
  77. package/dist/constants.js +99 -0
  78. package/dist/controls.d.ts +14 -0
  79. package/dist/controls.js +30 -0
  80. package/dist/convex-hull/ConvexHull.svelte +157 -0
  81. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  82. package/dist/convex-hull/ConvexHull2D.svelte +827 -0
  83. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  84. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  85. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  86. package/dist/convex-hull/ConvexHull4D.svelte +1394 -0
  87. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  88. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  89. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  90. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  91. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  92. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  93. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  94. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  95. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  96. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  97. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  98. package/dist/convex-hull/StructurePopup.svelte +151 -0
  99. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  100. package/dist/convex-hull/TemperatureSlider.svelte +140 -0
  101. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  102. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  103. package/dist/convex-hull/barycentric-coords.js +182 -0
  104. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  105. package/dist/convex-hull/demo-temperature.js +38 -0
  106. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  107. package/dist/convex-hull/gas-thermodynamics.js +306 -0
  108. package/dist/convex-hull/helpers.d.ts +117 -0
  109. package/dist/convex-hull/helpers.js +718 -0
  110. package/dist/convex-hull/index.d.ts +119 -0
  111. package/dist/convex-hull/index.js +58 -0
  112. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  113. package/dist/convex-hull/thermodynamics.js +1757 -0
  114. package/dist/convex-hull/types.d.ts +162 -0
  115. package/dist/convex-hull/types.js +36 -0
  116. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  117. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  118. package/dist/coordination/calc-coordination.d.ts +15 -0
  119. package/dist/coordination/calc-coordination.js +63 -0
  120. package/dist/coordination/index.d.ts +8 -0
  121. package/dist/coordination/index.js +7 -0
  122. package/dist/effects.svelte.d.ts +12 -0
  123. package/dist/effects.svelte.js +37 -0
  124. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  125. package/dist/element/ElementHeading.svelte +26 -0
  126. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  127. package/dist/element/ElementPhoto.svelte +57 -0
  128. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  129. package/dist/element/ElementStats.svelte +80 -0
  130. package/dist/element/ElementStats.svelte.d.ts +8 -0
  131. package/dist/element/ElementTile.svelte +484 -0
  132. package/dist/element/ElementTile.svelte.d.ts +29 -0
  133. package/dist/element/Nucleus.svelte.d.ts +17 -0
  134. package/dist/element/data.d.ts +2 -0
  135. package/dist/element/data.js +2 -0
  136. package/dist/element/index.d.ts +8 -0
  137. package/dist/element/index.js +7 -0
  138. package/dist/element/types.d.ts +57 -0
  139. package/dist/element/types.js +1 -0
  140. package/dist/feedback/ClickFeedback.svelte +58 -0
  141. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  142. package/dist/feedback/DragOverlay.svelte +42 -0
  143. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  144. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  145. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  146. package/dist/feedback/index.d.ts +4 -0
  147. package/dist/feedback/index.js +4 -0
  148. package/dist/fermi-surface/FermiSlice.svelte +197 -0
  149. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  150. package/dist/fermi-surface/FermiSurface.svelte +606 -0
  151. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  152. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  153. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  154. package/dist/fermi-surface/FermiSurfaceScene.svelte +797 -0
  155. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  156. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +85 -0
  157. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  158. package/dist/fermi-surface/compute.d.ts +5 -0
  159. package/dist/fermi-surface/compute.js +538 -0
  160. package/dist/fermi-surface/constants.d.ts +9 -0
  161. package/dist/fermi-surface/constants.js +27 -0
  162. package/dist/fermi-surface/export.d.ts +5 -0
  163. package/dist/fermi-surface/export.js +51 -0
  164. package/dist/fermi-surface/index.d.ts +12 -0
  165. package/dist/fermi-surface/index.js +13 -0
  166. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  167. package/dist/fermi-surface/marching-cubes.js +2 -0
  168. package/dist/fermi-surface/parse.d.ts +2 -0
  169. package/dist/fermi-surface/parse.js +494 -0
  170. package/dist/fermi-surface/symmetry.d.ts +3 -0
  171. package/dist/fermi-surface/symmetry.js +46 -0
  172. package/dist/fermi-surface/types.d.ts +111 -0
  173. package/dist/fermi-surface/types.js +4 -0
  174. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1547 -0
  175. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  176. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  177. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  178. package/dist/heatmap-matrix/index.d.ts +53 -0
  179. package/dist/heatmap-matrix/index.js +100 -0
  180. package/dist/heatmap-matrix/shared.d.ts +2 -0
  181. package/dist/heatmap-matrix/shared.js +4 -0
  182. package/dist/icons.d.ts +569 -0
  183. package/dist/icons.js +648 -0
  184. package/dist/index.d.ts +39 -0
  185. package/dist/index.js +39 -0
  186. package/dist/io/decompress.d.ts +11 -0
  187. package/dist/io/decompress.js +76 -0
  188. package/dist/io/export.d.ts +16 -0
  189. package/dist/io/export.js +338 -0
  190. package/dist/io/fetch.d.ts +5 -0
  191. package/dist/io/fetch.js +43 -0
  192. package/dist/io/file-drop.d.ts +7 -0
  193. package/dist/io/file-drop.js +42 -0
  194. package/dist/io/index.d.ts +7 -0
  195. package/dist/io/index.js +6 -0
  196. package/dist/io/is-binary.d.ts +1 -0
  197. package/dist/io/is-binary.js +20 -0
  198. package/dist/io/types.d.ts +8 -0
  199. package/dist/io/types.js +1 -0
  200. package/dist/io/url-drop.d.ts +2 -0
  201. package/dist/io/url-drop.js +154 -0
  202. package/dist/isosurface/Isosurface.svelte +285 -0
  203. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  204. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  205. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  206. package/dist/isosurface/index.d.ts +5 -0
  207. package/dist/isosurface/index.js +6 -0
  208. package/dist/isosurface/parse.d.ts +6 -0
  209. package/dist/isosurface/parse.js +552 -0
  210. package/dist/isosurface/slice.d.ts +11 -0
  211. package/dist/isosurface/slice.js +141 -0
  212. package/dist/isosurface/types.d.ts +56 -0
  213. package/dist/isosurface/types.js +227 -0
  214. package/dist/keyboard.d.ts +3 -0
  215. package/dist/keyboard.js +23 -0
  216. package/dist/labels.d.ts +53 -0
  217. package/dist/labels.js +278 -0
  218. package/dist/layout/FullscreenToggle.svelte +50 -0
  219. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  220. package/dist/layout/InfoCard.svelte +120 -0
  221. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  222. package/dist/layout/InfoTag.svelte +185 -0
  223. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  224. package/dist/layout/PropertyFilter.svelte +247 -0
  225. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  226. package/dist/layout/SettingsSection.svelte +148 -0
  227. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  228. package/dist/layout/SubpageGrid.svelte +82 -0
  229. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  230. package/dist/layout/fullscreen.d.ts +9 -0
  231. package/dist/layout/fullscreen.js +53 -0
  232. package/dist/layout/index.d.ts +10 -0
  233. package/dist/layout/index.js +8 -0
  234. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  235. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  236. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  237. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  238. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  239. package/dist/layout/json-tree/index.d.ts +3 -0
  240. package/dist/layout/json-tree/index.js +3 -0
  241. package/dist/layout/json-tree/types.d.ts +74 -0
  242. package/dist/layout/json-tree/types.js +2 -0
  243. package/dist/layout/json-tree/utils.d.ts +29 -0
  244. package/dist/layout/json-tree/utils.js +642 -0
  245. package/dist/marching-cubes.d.ts +14 -0
  246. package/dist/marching-cubes.js +535 -0
  247. package/dist/math.d.ts +105 -0
  248. package/dist/math.js +920 -0
  249. package/dist/overlays/ContextMenu.svelte +162 -0
  250. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  251. package/dist/overlays/CopyButton.svelte +45 -0
  252. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  253. package/dist/overlays/DragControlTab.svelte +98 -0
  254. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  255. package/dist/overlays/DraggablePane.svelte +487 -0
  256. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  257. package/dist/overlays/InfoPaneCards.svelte +149 -0
  258. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  259. package/dist/overlays/index.d.ts +3 -0
  260. package/dist/overlays/index.js +3 -0
  261. package/dist/periodic-table/PeriodicTable.svelte +480 -0
  262. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  263. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  264. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  265. package/dist/periodic-table/PropertySelect.svelte +38 -0
  266. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  267. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  268. package/dist/periodic-table/index.d.ts +10 -0
  269. package/dist/periodic-table/index.js +4 -0
  270. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1092 -0
  271. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  272. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  273. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  274. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +127 -0
  275. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  276. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  277. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  278. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  279. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  280. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  281. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  282. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  283. package/dist/phase-diagram/build-diagram.js +160 -0
  284. package/dist/phase-diagram/colors.d.ts +35 -0
  285. package/dist/phase-diagram/colors.js +51 -0
  286. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  287. package/dist/phase-diagram/diagram-input.js +3 -0
  288. package/dist/phase-diagram/index.d.ts +13 -0
  289. package/dist/phase-diagram/index.js +11 -0
  290. package/dist/phase-diagram/parse.d.ts +55 -0
  291. package/dist/phase-diagram/parse.js +273 -0
  292. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  293. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  294. package/dist/phase-diagram/types.d.ts +93 -0
  295. package/dist/phase-diagram/types.js +1 -0
  296. package/dist/phase-diagram/utils.d.ts +118 -0
  297. package/dist/phase-diagram/utils.js +600 -0
  298. package/dist/plot/bar/BarPlot.svelte +1755 -0
  299. package/dist/plot/bar/BarPlot.svelte.d.ts +84 -0
  300. package/dist/plot/bar/BarPlotControls.svelte +67 -0
  301. package/dist/plot/bar/BarPlotControls.svelte.d.ts +18 -0
  302. package/dist/plot/bar/SpacegroupBarPlot.svelte +293 -0
  303. package/dist/plot/bar/SpacegroupBarPlot.svelte.d.ts +9 -0
  304. package/dist/plot/bar/data.d.ts +40 -0
  305. package/dist/plot/bar/data.js +154 -0
  306. package/dist/plot/bar/geometry.d.ts +39 -0
  307. package/dist/plot/bar/geometry.js +60 -0
  308. package/dist/plot/bar/index.d.ts +3 -0
  309. package/dist/plot/bar/index.js +3 -0
  310. package/dist/plot/box/BoxPlot.svelte +1462 -0
  311. package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
  312. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  313. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  314. package/dist/plot/box/Violin.svelte +14 -0
  315. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  316. package/dist/plot/box/box-plot.d.ts +55 -0
  317. package/dist/plot/box/box-plot.js +126 -0
  318. package/dist/plot/box/index.d.ts +5 -0
  319. package/dist/plot/box/index.js +5 -0
  320. package/dist/plot/box/kde.d.ts +16 -0
  321. package/dist/plot/box/kde.js +160 -0
  322. package/dist/plot/box/quantile.d.ts +3 -0
  323. package/dist/plot/box/quantile.js +53 -0
  324. package/dist/plot/core/auto-place.d.ts +43 -0
  325. package/dist/plot/core/auto-place.js +122 -0
  326. package/dist/plot/core/axis-utils.d.ts +46 -0
  327. package/dist/plot/core/axis-utils.js +110 -0
  328. package/dist/plot/core/components/AxisLabel.svelte +51 -0
  329. package/dist/plot/core/components/AxisLabel.svelte.d.ts +16 -0
  330. package/dist/plot/core/components/ColorBar.svelte +724 -0
  331. package/dist/plot/core/components/ColorBar.svelte.d.ts +31 -0
  332. package/dist/plot/core/components/ColorScaleSelect.svelte +55 -0
  333. package/dist/plot/core/components/ColorScaleSelect.svelte.d.ts +15 -0
  334. package/dist/plot/core/components/ControlPane.svelte +46 -0
  335. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  336. package/dist/plot/core/components/FillArea.svelte +234 -0
  337. package/dist/plot/core/components/FillArea.svelte.d.ts +21 -0
  338. package/dist/plot/core/components/InteractiveAxisLabel.svelte +96 -0
  339. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +14 -0
  340. package/dist/plot/core/components/Line.svelte +101 -0
  341. package/dist/plot/core/components/Line.svelte.d.ts +15 -0
  342. package/dist/plot/core/components/PlotAxis.svelte +171 -0
  343. package/dist/plot/core/components/PlotAxis.svelte.d.ts +25 -0
  344. package/dist/plot/core/components/PlotControls.svelte +525 -0
  345. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  346. package/dist/plot/core/components/PlotLegend.svelte +580 -0
  347. package/dist/plot/core/components/PlotLegend.svelte.d.ts +30 -0
  348. package/dist/plot/core/components/PlotTooltip.svelte +83 -0
  349. package/dist/plot/core/components/PlotTooltip.svelte.d.ts +25 -0
  350. package/dist/plot/core/components/PortalSelect.svelte +257 -0
  351. package/dist/plot/core/components/PortalSelect.svelte.d.ts +16 -0
  352. package/dist/plot/core/components/ReferenceLine.svelte +204 -0
  353. package/dist/plot/core/components/ReferenceLine.svelte.d.ts +20 -0
  354. package/dist/plot/core/components/ReferenceLine3D.svelte +156 -0
  355. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +14 -0
  356. package/dist/plot/core/components/ReferencePlane.svelte +175 -0
  357. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +14 -0
  358. package/dist/plot/core/components/ZeroLines.svelte +97 -0
  359. package/dist/plot/core/components/ZeroLines.svelte.d.ts +33 -0
  360. package/dist/plot/core/components/ZoomRect.svelte +23 -0
  361. package/dist/plot/core/components/ZoomRect.svelte.d.ts +8 -0
  362. package/dist/plot/core/components/index.d.ts +17 -0
  363. package/dist/plot/core/components/index.js +17 -0
  364. package/dist/plot/core/data-cleaning.d.ts +107 -0
  365. package/dist/plot/core/data-cleaning.js +853 -0
  366. package/dist/plot/core/data-transform.d.ts +16 -0
  367. package/dist/plot/core/data-transform.js +45 -0
  368. package/dist/plot/core/fill-utils.d.ts +33 -0
  369. package/dist/plot/core/fill-utils.js +388 -0
  370. package/dist/plot/core/hover-lock.svelte.d.ts +14 -0
  371. package/dist/plot/core/hover-lock.svelte.js +45 -0
  372. package/dist/plot/core/index.d.ts +10 -0
  373. package/dist/plot/core/index.js +11 -0
  374. package/dist/plot/core/interactions.d.ts +35 -0
  375. package/dist/plot/core/interactions.js +195 -0
  376. package/dist/plot/core/layout.d.ts +79 -0
  377. package/dist/plot/core/layout.js +281 -0
  378. package/dist/plot/core/reference-line.d.ts +60 -0
  379. package/dist/plot/core/reference-line.js +301 -0
  380. package/dist/plot/core/scales.d.ts +48 -0
  381. package/dist/plot/core/scales.js +480 -0
  382. package/dist/plot/core/svg.d.ts +2 -0
  383. package/dist/plot/core/svg.js +41 -0
  384. package/dist/plot/core/types.d.ts +771 -0
  385. package/dist/plot/core/types.js +99 -0
  386. package/dist/plot/core/utils/label-placement.d.ts +68 -0
  387. package/dist/plot/core/utils/label-placement.js +326 -0
  388. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  389. package/dist/plot/core/utils/series-visibility.js +112 -0
  390. package/dist/plot/core/utils.d.ts +11 -0
  391. package/dist/plot/core/utils.js +27 -0
  392. package/dist/plot/histogram/Histogram.svelte +1418 -0
  393. package/dist/plot/histogram/Histogram.svelte.d.ts +50 -0
  394. package/dist/plot/histogram/HistogramControls.svelte +212 -0
  395. package/dist/plot/histogram/HistogramControls.svelte.d.ts +22 -0
  396. package/dist/plot/histogram/index.d.ts +2 -0
  397. package/dist/plot/histogram/index.js +2 -0
  398. package/dist/plot/index.d.ts +8 -0
  399. package/dist/plot/index.js +10 -0
  400. package/dist/plot/sankey/Sankey.svelte +700 -0
  401. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  402. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  403. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  404. package/dist/plot/sankey/index.d.ts +4 -0
  405. package/dist/plot/sankey/index.js +3 -0
  406. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  407. package/dist/plot/sankey/sankey-types.js +4 -0
  408. package/dist/plot/sankey/sankey.d.ts +52 -0
  409. package/dist/plot/sankey/sankey.js +187 -0
  410. package/dist/plot/scatter/BinnedScatterPlot.svelte +1116 -0
  411. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +66 -0
  412. package/dist/plot/scatter/ElementScatter.svelte +63 -0
  413. package/dist/plot/scatter/ElementScatter.svelte.d.ts +14 -0
  414. package/dist/plot/scatter/ScatterPlot.svelte +2357 -0
  415. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +96 -0
  416. package/dist/plot/scatter/ScatterPlotControls.svelte +307 -0
  417. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +17 -0
  418. package/dist/plot/scatter/ScatterPoint.svelte +182 -0
  419. package/dist/plot/scatter/ScatterPoint.svelte.d.ts +22 -0
  420. package/dist/plot/scatter/adaptive-density.d.ts +79 -0
  421. package/dist/plot/scatter/adaptive-density.js +217 -0
  422. package/dist/plot/scatter/binned-scatter-types.d.ts +59 -0
  423. package/dist/plot/scatter/binned-scatter-types.js +1 -0
  424. package/dist/plot/scatter/index.d.ts +7 -0
  425. package/dist/plot/scatter/index.js +5 -0
  426. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  427. package/dist/plot/scatter/scatter-data.js +212 -0
  428. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +531 -0
  429. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +95 -0
  430. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +438 -0
  431. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +20 -0
  432. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +912 -0
  433. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +74 -0
  434. package/dist/plot/scatter-3d/Surface3D.svelte +197 -0
  435. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +13 -0
  436. package/dist/plot/scatter-3d/index.d.ts +4 -0
  437. package/dist/plot/scatter-3d/index.js +4 -0
  438. package/dist/plot/sunburst/Sunburst.svelte +1045 -0
  439. package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
  440. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  441. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  442. package/dist/plot/sunburst/index.d.ts +4 -0
  443. package/dist/plot/sunburst/index.js +4 -0
  444. package/dist/plot/sunburst/render.d.ts +34 -0
  445. package/dist/plot/sunburst/render.js +122 -0
  446. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  447. package/dist/plot/sunburst/sunburst.js +266 -0
  448. package/dist/rdf/RdfPlot.svelte +248 -0
  449. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  450. package/dist/rdf/calc-rdf.d.ts +4 -0
  451. package/dist/rdf/calc-rdf.js +98 -0
  452. package/dist/rdf/index.d.ts +23 -0
  453. package/dist/rdf/index.js +2 -0
  454. package/dist/sanitize.d.ts +6 -0
  455. package/dist/sanitize.js +116 -0
  456. package/dist/settings.d.ts +319 -0
  457. package/dist/settings.js +1394 -0
  458. package/dist/spectral/Bands.svelte +1050 -0
  459. package/dist/spectral/Bands.svelte.d.ts +39 -0
  460. package/dist/spectral/BandsAndDos.svelte +134 -0
  461. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  462. package/dist/spectral/BrillouinBandsDos.svelte +264 -0
  463. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  464. package/dist/spectral/Dos.svelte +688 -0
  465. package/dist/spectral/Dos.svelte.d.ts +29 -0
  466. package/dist/spectral/helpers.d.ts +121 -0
  467. package/dist/spectral/helpers.js +1098 -0
  468. package/dist/spectral/index.d.ts +6 -0
  469. package/dist/spectral/index.js +6 -0
  470. package/dist/spectral/types.d.ts +84 -0
  471. package/dist/spectral/types.js +2 -0
  472. package/dist/state.svelte.d.ts +25 -0
  473. package/dist/state.svelte.js +45 -0
  474. package/dist/structure/Arrow.svelte +72 -0
  475. package/dist/structure/Arrow.svelte.d.ts +15 -0
  476. package/dist/structure/AtomLegend.svelte +814 -0
  477. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  478. package/dist/structure/Bond.svelte +140 -0
  479. package/dist/structure/Bond.svelte.d.ts +9 -0
  480. package/dist/structure/CanvasTooltip.svelte +33 -0
  481. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  482. package/dist/structure/CellSelect.svelte +348 -0
  483. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  484. package/dist/structure/Cylinder.svelte +49 -0
  485. package/dist/structure/Cylinder.svelte.d.ts +13 -0
  486. package/dist/structure/Lattice.svelte +196 -0
  487. package/dist/structure/Lattice.svelte.d.ts +17 -0
  488. package/dist/structure/Structure.svelte +2254 -0
  489. package/dist/structure/Structure.svelte.d.ts +89 -0
  490. package/dist/structure/StructureControls.svelte +1273 -0
  491. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  492. package/dist/structure/StructureExportPane.svelte +252 -0
  493. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  494. package/dist/structure/StructureInfoPane.svelte +736 -0
  495. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  496. package/dist/structure/StructureScene.svelte +2256 -0
  497. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  498. package/dist/structure/atom-properties.d.ts +37 -0
  499. package/dist/structure/atom-properties.js +200 -0
  500. package/dist/structure/bond-order-perception.d.ts +13 -0
  501. package/dist/structure/bond-order-perception.js +384 -0
  502. package/dist/structure/bonding.d.ts +69 -0
  503. package/dist/structure/bonding.js +724 -0
  504. package/dist/structure/export.d.ts +20 -0
  505. package/dist/structure/export.js +731 -0
  506. package/dist/structure/index.d.ts +124 -0
  507. package/dist/structure/index.js +167 -0
  508. package/dist/structure/label-placement.d.ts +14 -0
  509. package/dist/structure/label-placement.js +72 -0
  510. package/dist/structure/measure.d.ts +7 -0
  511. package/dist/structure/measure.js +30 -0
  512. package/dist/structure/parse.d.ts +66 -0
  513. package/dist/structure/parse.js +1410 -0
  514. package/dist/structure/partial-occupancy.d.ts +25 -0
  515. package/dist/structure/partial-occupancy.js +99 -0
  516. package/dist/structure/pbc.d.ts +9 -0
  517. package/dist/structure/pbc.js +127 -0
  518. package/dist/structure/supercell.d.ts +8 -0
  519. package/dist/structure/supercell.js +170 -0
  520. package/dist/structure/validation.d.ts +2 -0
  521. package/dist/structure/validation.js +10 -0
  522. package/dist/symmetry/SymmetryStats.svelte +226 -0
  523. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  524. package/dist/symmetry/WyckoffTable.svelte +120 -0
  525. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  526. package/dist/symmetry/cell-transform.d.ts +12 -0
  527. package/dist/symmetry/cell-transform.js +91 -0
  528. package/dist/symmetry/index.d.ts +43 -0
  529. package/dist/symmetry/index.js +226 -0
  530. package/dist/symmetry/spacegroups.d.ts +16 -0
  531. package/dist/symmetry/spacegroups.js +429 -0
  532. package/dist/table/HeatmapTable.svelte +1885 -0
  533. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  534. package/dist/table/ToggleMenu.svelte +385 -0
  535. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  536. package/dist/table/index.d.ts +72 -0
  537. package/dist/table/index.js +38 -0
  538. package/dist/theme/ThemeControl.svelte +53 -0
  539. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  540. package/dist/theme/index.d.ts +29 -0
  541. package/dist/theme/index.js +79 -0
  542. package/dist/time.d.ts +4 -0
  543. package/dist/time.js +70 -0
  544. package/dist/tooltip/KCoords.svelte +45 -0
  545. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  546. package/dist/tooltip/TooltipContent.svelte +58 -0
  547. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  548. package/dist/tooltip/index.d.ts +3 -0
  549. package/dist/tooltip/index.js +2 -0
  550. package/dist/tooltip/types.d.ts +8 -0
  551. package/dist/tooltip/types.js +1 -0
  552. package/dist/trajectory/Trajectory.svelte +1571 -0
  553. package/dist/trajectory/Trajectory.svelte.d.ts +78 -0
  554. package/dist/trajectory/TrajectoryError.svelte +128 -0
  555. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  556. package/dist/trajectory/TrajectoryExportPane.svelte +358 -0
  557. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  558. package/dist/trajectory/TrajectoryInfoPane.svelte +314 -0
  559. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  560. package/dist/trajectory/constants.d.ts +6 -0
  561. package/dist/trajectory/constants.js +7 -0
  562. package/dist/trajectory/extract.d.ts +5 -0
  563. package/dist/trajectory/extract.js +162 -0
  564. package/dist/trajectory/format-detect.d.ts +10 -0
  565. package/dist/trajectory/format-detect.js +90 -0
  566. package/dist/trajectory/frame-reader.d.ts +17 -0
  567. package/dist/trajectory/frame-reader.js +299 -0
  568. package/dist/trajectory/helpers.d.ts +15 -0
  569. package/dist/trajectory/helpers.js +164 -0
  570. package/dist/trajectory/index.d.ts +63 -0
  571. package/dist/trajectory/index.js +126 -0
  572. package/dist/trajectory/parse/ase.d.ts +2 -0
  573. package/dist/trajectory/parse/ase.js +73 -0
  574. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  575. package/dist/trajectory/parse/hdf5.js +127 -0
  576. package/dist/trajectory/parse/index.d.ts +12 -0
  577. package/dist/trajectory/parse/index.js +306 -0
  578. package/dist/trajectory/parse/lammps.d.ts +5 -0
  579. package/dist/trajectory/parse/lammps.js +179 -0
  580. package/dist/trajectory/parse/vasp.d.ts +2 -0
  581. package/dist/trajectory/parse/vasp.js +87 -0
  582. package/dist/trajectory/parse/xyz.d.ts +26 -0
  583. package/dist/trajectory/parse/xyz.js +123 -0
  584. package/dist/trajectory/plotting.d.ts +28 -0
  585. package/dist/trajectory/plotting.js +423 -0
  586. package/dist/trajectory/types.d.ts +11 -0
  587. package/dist/trajectory/types.js +1 -0
  588. package/dist/utils.d.ts +7 -0
  589. package/dist/utils.js +47 -0
  590. package/dist/xrd/XrdPlot.svelte +616 -0
  591. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  592. package/dist/xrd/broadening.d.ts +20 -0
  593. package/dist/xrd/broadening.js +97 -0
  594. package/dist/xrd/calc-xrd.d.ts +37 -0
  595. package/dist/xrd/calc-xrd.js +339 -0
  596. package/dist/xrd/index.d.ts +37 -0
  597. package/dist/xrd/index.js +4 -0
  598. package/dist/xrd/parse.d.ts +13 -0
  599. package/dist/xrd/parse.js +749 -0
  600. package/license +1 -1
  601. package/package.json +237 -1458
  602. package/readme.md +98 -171
  603. package/.vscode/launch.json +0 -13
  604. package/.vscodeignore +0 -7
  605. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  606. package/dist/assets/browser-DdDecX_W.js +0 -1
  607. package/dist/assets/export-qgn-H9y6.js +0 -2
  608. package/dist/assets/main-DiKYzti2.css +0 -1
  609. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  610. package/dist/extension.js +0 -31293
  611. package/dist/src/lib/FilePicker.svelte +0 -360
  612. package/dist/src/lib/Icon.svelte +0 -41
  613. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  614. package/dist/src/lib/api/mp.ts +0 -26
  615. package/dist/src/lib/api/optimade.ts +0 -204
  616. package/dist/src/lib/app.css +0 -247
  617. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  618. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  619. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  620. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  621. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  622. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  623. package/dist/src/lib/brillouin/compute.ts +0 -529
  624. package/dist/src/lib/brillouin/index.ts +0 -8
  625. package/dist/src/lib/brillouin/types.ts +0 -51
  626. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  627. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  628. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  629. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  630. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  631. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  632. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  633. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  634. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  635. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  636. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  637. package/dist/src/lib/colors/index.ts +0 -249
  638. package/dist/src/lib/composition/BarChart.svelte +0 -297
  639. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  640. package/dist/src/lib/composition/Composition.svelte +0 -165
  641. package/dist/src/lib/composition/Formula.svelte +0 -268
  642. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  643. package/dist/src/lib/composition/PieChart.svelte +0 -323
  644. package/dist/src/lib/composition/format.ts +0 -155
  645. package/dist/src/lib/composition/index.ts +0 -37
  646. package/dist/src/lib/composition/parse.ts +0 -605
  647. package/dist/src/lib/constants.ts +0 -134
  648. package/dist/src/lib/controls.ts +0 -42
  649. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  650. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  651. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  652. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  653. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  654. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  655. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  656. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  657. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  658. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  659. package/dist/src/lib/convex-hull/TemperatureSlider.svelte +0 -140
  660. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  661. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  662. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  663. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  664. package/dist/src/lib/convex-hull/index.ts +0 -202
  665. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  666. package/dist/src/lib/convex-hull/types.ts +0 -267
  667. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  668. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  669. package/dist/src/lib/coordination/index.ts +0 -9
  670. package/dist/src/lib/effects.svelte.ts +0 -48
  671. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  672. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  673. package/dist/src/lib/element/ElementStats.svelte +0 -80
  674. package/dist/src/lib/element/ElementTile.svelte +0 -484
  675. package/dist/src/lib/element/data.ts +0 -14
  676. package/dist/src/lib/element/index.ts +0 -8
  677. package/dist/src/lib/element/types.ts +0 -62
  678. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  679. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  680. package/dist/src/lib/feedback/index.ts +0 -4
  681. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  682. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  683. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  684. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  685. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  686. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  687. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  688. package/dist/src/lib/fermi-surface/export.ts +0 -64
  689. package/dist/src/lib/fermi-surface/index.ts +0 -14
  690. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  691. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  692. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  693. package/dist/src/lib/fermi-surface/types.ts +0 -159
  694. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  695. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  696. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  697. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  698. package/dist/src/lib/icons.ts +0 -650
  699. package/dist/src/lib/index.ts +0 -61
  700. package/dist/src/lib/io/decompress.ts +0 -92
  701. package/dist/src/lib/io/export.ts +0 -385
  702. package/dist/src/lib/io/fetch.ts +0 -46
  703. package/dist/src/lib/io/file-drop.ts +0 -51
  704. package/dist/src/lib/io/index.ts +0 -7
  705. package/dist/src/lib/io/is-binary.ts +0 -24
  706. package/dist/src/lib/io/types.ts +0 -8
  707. package/dist/src/lib/io/url-drop.ts +0 -141
  708. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  709. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  710. package/dist/src/lib/isosurface/index.ts +0 -7
  711. package/dist/src/lib/isosurface/parse.ts +0 -656
  712. package/dist/src/lib/isosurface/slice.ts +0 -175
  713. package/dist/src/lib/isosurface/types.ts +0 -309
  714. package/dist/src/lib/labels.ts +0 -320
  715. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  716. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  717. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  718. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  719. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  720. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  721. package/dist/src/lib/layout/fullscreen.ts +0 -65
  722. package/dist/src/lib/layout/index.ts +0 -11
  723. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  724. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  725. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  726. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  727. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  728. package/dist/src/lib/marching-cubes.ts +0 -614
  729. package/dist/src/lib/math.ts +0 -1081
  730. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  731. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  732. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  733. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  734. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  735. package/dist/src/lib/overlays/index.ts +0 -3
  736. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  737. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  738. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  739. package/dist/src/lib/periodic-table/index.ts +0 -12
  740. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  741. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  742. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  743. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  744. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  745. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  746. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  747. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  748. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  749. package/dist/src/lib/phase-diagram/index.ts +0 -13
  750. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  751. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  752. package/dist/src/lib/phase-diagram/types.ts +0 -144
  753. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  754. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  755. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  756. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  757. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  758. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  759. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  760. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  761. package/dist/src/lib/plot/FillArea.svelte +0 -223
  762. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  763. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  764. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  765. package/dist/src/lib/plot/Line.svelte +0 -84
  766. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  767. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  768. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  769. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  770. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  771. package/dist/src/lib/plot/ReferenceLine.svelte +0 -204
  772. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  773. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  774. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  775. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  776. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  777. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  778. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  779. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  780. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  781. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  782. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  783. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  784. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  785. package/dist/src/lib/plot/auto-place.ts +0 -184
  786. package/dist/src/lib/plot/axis-utils.ts +0 -122
  787. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  788. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  789. package/dist/src/lib/plot/data-transform.ts +0 -69
  790. package/dist/src/lib/plot/defaults.ts +0 -9
  791. package/dist/src/lib/plot/fill-utils.ts +0 -494
  792. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  793. package/dist/src/lib/plot/index.ts +0 -53
  794. package/dist/src/lib/plot/interactions.ts +0 -119
  795. package/dist/src/lib/plot/layout.ts +0 -425
  796. package/dist/src/lib/plot/reference-line.ts +0 -426
  797. package/dist/src/lib/plot/scales.ts +0 -654
  798. package/dist/src/lib/plot/svg.ts +0 -23
  799. package/dist/src/lib/plot/types.ts +0 -1144
  800. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  801. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  802. package/dist/src/lib/plot/utils.ts +0 -11
  803. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  804. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  805. package/dist/src/lib/rdf/index.ts +0 -27
  806. package/dist/src/lib/sanitize.ts +0 -126
  807. package/dist/src/lib/settings.ts +0 -1479
  808. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  809. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  810. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  811. package/dist/src/lib/spectral/Dos.svelte +0 -697
  812. package/dist/src/lib/spectral/helpers.ts +0 -1381
  813. package/dist/src/lib/spectral/index.ts +0 -8
  814. package/dist/src/lib/spectral/types.ts +0 -112
  815. package/dist/src/lib/state.svelte.ts +0 -64
  816. package/dist/src/lib/structure/Arrow.svelte +0 -72
  817. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  818. package/dist/src/lib/structure/Bond.svelte +0 -140
  819. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  820. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  821. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  822. package/dist/src/lib/structure/Lattice.svelte +0 -196
  823. package/dist/src/lib/structure/Structure.svelte +0 -2248
  824. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  825. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  826. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  827. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  828. package/dist/src/lib/structure/atom-properties.ts +0 -316
  829. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  830. package/dist/src/lib/structure/bonding.ts +0 -944
  831. package/dist/src/lib/structure/export.ts +0 -861
  832. package/dist/src/lib/structure/index.ts +0 -291
  833. package/dist/src/lib/structure/label-placement.ts +0 -130
  834. package/dist/src/lib/structure/measure.ts +0 -45
  835. package/dist/src/lib/structure/parse.ts +0 -1705
  836. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  837. package/dist/src/lib/structure/pbc.ts +0 -164
  838. package/dist/src/lib/structure/supercell.ts +0 -226
  839. package/dist/src/lib/structure/validation.ts +0 -11
  840. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  841. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  842. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  843. package/dist/src/lib/symmetry/index.ts +0 -348
  844. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  845. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  846. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  847. package/dist/src/lib/table/index.ts +0 -139
  848. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  849. package/dist/src/lib/theme/index.ts +0 -107
  850. package/dist/src/lib/time.ts +0 -71
  851. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  852. package/dist/src/lib/tooltip/index.ts +0 -2
  853. package/dist/src/lib/tooltip/types.ts +0 -13
  854. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  855. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  856. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  857. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  858. package/dist/src/lib/trajectory/constants.ts +0 -7
  859. package/dist/src/lib/trajectory/extract.ts +0 -196
  860. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  861. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  862. package/dist/src/lib/trajectory/helpers.ts +0 -217
  863. package/dist/src/lib/trajectory/index.ts +0 -218
  864. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  865. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  866. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  867. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  868. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  869. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  870. package/dist/src/lib/trajectory/plotting.ts +0 -599
  871. package/dist/src/lib/trajectory/types.ts +0 -13
  872. package/dist/src/lib/utils.ts +0 -56
  873. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  874. package/dist/src/lib/xrd/broadening.ts +0 -130
  875. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  876. package/dist/src/lib/xrd/index.ts +0 -38
  877. package/dist/src/lib/xrd/parse.ts +0 -858
  878. package/dist/webview.js +0 -29421
  879. package/icon.png +0 -0
  880. package/matterviz-0.3.2.vsix +0 -0
  881. package/matterviz-0.3.4.vsix +0 -0
  882. package/matterviz-0.3.5.vsix +0 -0
  883. package/scripts/sync-config.ts +0 -101
  884. package/src/declarations.d.ts +0 -2
  885. package/src/extension.ts +0 -972
  886. package/src/node-io.ts +0 -65
  887. package/src/types.ts +0 -17
  888. package/src/webview/JsonBrowser.svelte +0 -1079
  889. package/src/webview/PlotPanel.svelte +0 -346
  890. package/src/webview/detect.ts +0 -444
  891. package/src/webview/main.ts +0 -764
  892. package/src/webview/plot-utils.ts +0 -250
  893. package/test-fixtures/all-viz-types.json.gz +0 -0
  894. package/test-fixtures/plot-demo-data.json.gz +0 -0
  895. package/tests/detect.test.ts +0 -604
  896. package/tests/extension.test.ts +0 -2041
  897. package/tests/node-io.test.ts +0 -39
  898. package/tests/plot-utils.test.ts +0 -302
  899. package/tests/vite-plugin-json-gz.test.ts +0 -114
  900. package/tests/vscode-mock.ts +0 -18
  901. package/tests/webview.test.ts +0 -231
  902. package/tsconfig.json +0 -20
  903. package/vite-plugin-json-gz.ts +0 -29
  904. package/vite.config.ts +0 -34
  905. package/vite.extension.config.ts +0 -34
  906. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  907. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  908. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  909. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  910. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  911. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  912. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  913. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  914. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  915. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  916. /package/dist/{src/lib/element → element}/data.json +0 -0
  917. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  918. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  919. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  920. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  921. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  922. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  923. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  924. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  925. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  926. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -0,0 +1,1571 @@
1
+ <script lang="ts">
2
+ import type { ShowControlsProp } from '../controls'
3
+ import { normalize_show_controls } from '../controls'
4
+ import type { ElementSymbol } from '../element'
5
+ import EmptyState from '../EmptyState.svelte'
6
+ import Spinner from '../feedback/Spinner.svelte'
7
+ import Icon from '../Icon.svelte'
8
+ import { handle_url_drop, load_from_url } from '../io'
9
+ import { forward_window_keydown, handle_and_prevent } from '../keyboard'
10
+ import { format_num, trajectory_property_config } from '../labels'
11
+ import { sanitize_html } from '../sanitize'
12
+ import { toggle_fullscreen } from '../layout'
13
+ import type { ControlsConfig, DataSeries, Orientation, Point } from '../plot'
14
+ import type { ScatterHandlerProps } from '../plot/core/types'
15
+ import { Histogram, ScatterPlot } from '../plot'
16
+ import { toggle_series_visibility } from '../plot/core/utils/series-visibility'
17
+ import { DEFAULTS } from '../settings'
18
+ import Structure from '../structure/Structure.svelte'
19
+ import { scaleLinear } from 'd3-scale'
20
+ import type { ComponentProps, Snippet } from 'svelte'
21
+ import { untrack } from 'svelte'
22
+ import { tooltip } from 'svelte-multiselect/attachments'
23
+ import type { HTMLAttributes } from 'svelte/elements'
24
+ import { full_data_extractor } from './extract'
25
+ import type {
26
+ ParseProgress,
27
+ TrajectoryDataExtractor,
28
+ TrajectoryFrame,
29
+ TrajectoryType,
30
+ TrajHandlerData,
31
+ } from './index'
32
+ import { TrajectoryError, TrajectoryExportPane, TrajectoryInfoPane } from './index'
33
+ import type { AtomTypeMapping, LoadingOptions } from './parse'
34
+ import {
35
+ get_unsupported_format_message,
36
+ MAX_BIN_FILE_SIZE,
37
+ MAX_TEXT_FILE_SIZE,
38
+ parse_trajectory_async,
39
+ } from './parse'
40
+ import {
41
+ generate_axis_labels,
42
+ generate_plot_series,
43
+ generate_streaming_plot_series,
44
+ should_hide_plot,
45
+ } from './plotting'
46
+
47
+ type EventHandlers = {
48
+ on_play?: (data: TrajHandlerData) => void
49
+ on_pause?: (data: TrajHandlerData) => void
50
+ on_step_change?: (data: TrajHandlerData) => void
51
+ on_end?: (data: TrajHandlerData) => void
52
+ on_loop?: (data: TrajHandlerData) => void
53
+ on_frame_rate_change?: (data: TrajHandlerData) => void
54
+ on_display_mode_change?: (data: TrajHandlerData) => void
55
+ on_fullscreen_change?: (data: TrajHandlerData) => void
56
+ on_file_load?: (data: TrajHandlerData) => void
57
+ on_error?: (data: TrajHandlerData) => void
58
+ }
59
+ type ControlsProps = {
60
+ trajectory: TrajectoryType
61
+ current_step_idx: number
62
+ total_frames: number
63
+ on_step_change: (idx: number) => void
64
+ }
65
+
66
+ let {
67
+ trajectory = $bindable(),
68
+ data_url,
69
+ current_step_idx = $bindable(0),
70
+ data_extractor = full_data_extractor,
71
+ allow_file_drop = true,
72
+ layout = `auto`,
73
+ structure_props = {},
74
+ scatter_props = {},
75
+ histogram_props = {},
76
+ spinner_props = {},
77
+ trajectory_controls,
78
+ error_snippet,
79
+ show_controls,
80
+ fullscreen_toggle = DEFAULTS.trajectory.fullscreen_toggle,
81
+ auto_play = false,
82
+ display_mode = $bindable(`structure+scatter`),
83
+ step_labels = 5,
84
+ visible_properties = $bindable(),
85
+ ELEM_PROPERTY_LABELS,
86
+ on_play,
87
+ on_pause,
88
+ on_step_change,
89
+ on_end,
90
+ on_loop,
91
+ on_frame_rate_change,
92
+ on_display_mode_change,
93
+ on_fullscreen_change,
94
+ on_file_load,
95
+ on_error,
96
+ fps_range = DEFAULTS.trajectory.fps_range,
97
+ fps = $bindable(5),
98
+ loading_options = {},
99
+ atom_type_mapping,
100
+ plot_skimming = true,
101
+ hovered = $bindable(false),
102
+ ...rest
103
+ }: EventHandlers & HTMLAttributes<HTMLDivElement> & {
104
+ // trajectory data - can be provided directly or loaded from file
105
+ trajectory?: TrajectoryType
106
+ // URL to load trajectory from (alternative to providing trajectory directly)
107
+ data_url?: string
108
+ // current step index being displayed
109
+ current_step_idx?: number
110
+ // custom function to extract plot data from trajectory frames
111
+ data_extractor?: TrajectoryDataExtractor
112
+
113
+ // file drop handlers
114
+ allow_file_drop?: boolean
115
+ // layout configuration - 'auto' (default) adapts to element size, 'horizontal'/'vertical' forces layout
116
+ layout?: `auto` | Orientation
117
+ // structure viewer props (passed to Structure component)
118
+ structure_props?: ComponentProps<typeof Structure>
119
+ // plot props (passed to ScatterPlot component)
120
+ scatter_props?: ComponentProps<typeof ScatterPlot>
121
+ // histogram props (passed to Histogram component, excluding series which is handled separately)
122
+ histogram_props?: Omit<ComponentProps<typeof Histogram>, `series`>
123
+ // spinner props (passed to Spinner component)
124
+ spinner_props?: ComponentProps<typeof Spinner>
125
+ // custom snippets for additional UI elements
126
+ trajectory_controls?: Snippet<[ControlsProps]>
127
+ // Custom error snippet for advanced error handling
128
+ error_snippet?: Snippet<[{ error_msg: string; on_dismiss: () => void }]>
129
+ // Controls visibility configuration.
130
+ // - 'always': controls always visible
131
+ // - 'hover': controls visible on component hover (default)
132
+ // - 'never': controls never visible
133
+ // - object: { mode, hidden, style } for fine-grained control
134
+ // Control names: 'filename', 'nav', 'step', 'fps', 'info-pane', 'export-pane', 'view-mode', 'fullscreen'
135
+ show_controls?: ShowControlsProp
136
+ // show/hide the fullscreen button
137
+ fullscreen_toggle?: Snippet<[{ fullscreen: boolean }]> | boolean
138
+ // automatically start playing when trajectory data is loaded
139
+ auto_play?: boolean
140
+ // display mode: 'structure+scatter' (default), 'structure' (only structure), 'scatter' (only scatter), 'histogram' (only histogram), 'structure+histogram' (structure with histogram)
141
+ display_mode?:
142
+ | `structure+scatter`
143
+ | `structure`
144
+ | `scatter`
145
+ | `histogram`
146
+ | `structure+histogram`
147
+ // step labels configuration for slider
148
+ // - positive number: number of evenly spaced ticks
149
+ // - negative number: spacing between ticks (e.g. -10 = every 10th step)
150
+ // - array: exact step indices to label
151
+ // - undefined: no labels
152
+ step_labels?: number | number[]
153
+ // visible properties - bindable array of property keys currently shown in the plot
154
+ // - controls which trajectory properties are plotted (e.g. ['energy', 'volume', 'force_max'])
155
+ // - bindable: reflects current visibility state and can be used for external control
156
+ // - if not provided, uses default visible properties (energy, force_max, stress_frobenius)
157
+ // - if specified properties don't exist in data, falls back to automatic selection
158
+ visible_properties?: string[]
159
+ // custom labels for trajectory properties - maps property keys to display labels
160
+ // - e.g. {energy: 'Total Energy', volume: 'Cell Volume', force_max: 'Max Force'}
161
+ // - merged with built-in trajectory_property_config
162
+ ELEM_PROPERTY_LABELS?: Record<string, string>
163
+ // units configuration - developers can override these (deprecated - use ELEM_PROPERTY_LABELS instead)
164
+ units?: {
165
+ energy?: string
166
+ energy_per_atom?: string
167
+ force_max?: string
168
+ force_norm?: string
169
+ stress_max?: string
170
+ volume?: string
171
+ density?: string
172
+ temperature?: string
173
+ pressure?: string
174
+ length?: string
175
+ a?: string
176
+ b?: string
177
+ c?: string
178
+ [key: string]: string | undefined
179
+ }
180
+ fps_range?: [number, number] // allowed FPS range [min_fps, max_fps]
181
+ fps?: number // frame rate for playback
182
+ // Loading options for large files
183
+ loading_options?: LoadingOptions
184
+ // Map LAMMPS atom types to element symbols (e.g. {1: 'Na', 2: 'Cl'})
185
+ atom_type_mapping?: AtomTypeMapping
186
+ // Disable plot skimming (mouse over plot doesn't update structure/step slider)
187
+ plot_skimming?: boolean
188
+ // bindable: true while the pointer is over the viewer (drives hover-scoped shortcuts)
189
+ hovered?: boolean
190
+ } = $props()
191
+
192
+ let dragover = $state(false)
193
+ let loading = $state(false)
194
+ let error_msg = $state<string | null>(null)
195
+ let is_playing = $state(false)
196
+ let play_interval: ReturnType<typeof setInterval> | undefined = $state(undefined)
197
+
198
+ // Ensure fps is within the allowed range
199
+ $effect(() => {
200
+ if (fps < fps_range[0]) {
201
+ fps = fps_range[0]
202
+ } else if (fps > fps_range[1]) {
203
+ fps = fps_range[1]
204
+ }
205
+ })
206
+ let current_filename = $state<string | undefined>(undefined)
207
+ let current_file_path = $state<string | null>(null)
208
+ let file_size = $state<number | undefined>(undefined)
209
+ let file_object = $state<File | null>(null)
210
+ let wrapper = $state<HTMLDivElement | undefined>(undefined)
211
+ let info_pane_open = $state(false)
212
+ let parsing_progress = $state<ParseProgress | null>(null)
213
+ let element_size = $state({ width: 0, height: 0 })
214
+ let filename_copied = $state(false)
215
+ let orig_data = $state<string | ArrayBuffer | null>(null)
216
+
217
+ let controls_config = $derived(normalize_show_controls(show_controls))
218
+
219
+ // Reactive layout based on element aspect ratio (for auto mode)
220
+ let actual_layout = $derived.by(() => {
221
+ if (layout === `horizontal` || layout === `vertical`) return layout
222
+ // For auto layout, use element dimensions to determine orientation
223
+ if (element_size.width > 0 && element_size.height > 0) {
224
+ return element_size.width > element_size.height ? `horizontal` : `vertical`
225
+ }
226
+ return `horizontal` // Fallback to horizontal if dimensions not available yet
227
+ })
228
+
229
+ // Get total frame count (supports both regular and indexed trajectories)
230
+ let total_frames = $derived(
231
+ trajectory?.total_frames || trajectory?.frames.length || 0,
232
+ )
233
+
234
+ // Current frame - load on demand for indexed trajectories
235
+ let current_frame = $state<TrajectoryFrame | null>(null)
236
+ let frame_load_request_id = 0
237
+
238
+ // Auto-play when trajectory changes (handles both props and file loading)
239
+ $effect(() => {
240
+ if (auto_play && trajectory && !untrack(() => is_playing) && total_frames > 1) {
241
+ start_playback()
242
+ }
243
+ })
244
+
245
+ // Update current frame when step changes
246
+ $effect(() => {
247
+ if (trajectory && current_step_idx >= 0 && current_step_idx < total_frames) {
248
+ if (trajectory.frame_loader) {
249
+ // Load frame on demand (works for both indexed files and external streaming)
250
+ load_frame_on_demand(current_step_idx)
251
+ } else {
252
+ // Use in-memory frame for regular trajectories
253
+ current_frame = trajectory.frames[current_step_idx] || null
254
+ }
255
+ } else {
256
+ current_frame = null
257
+ }
258
+ })
259
+
260
+ // Load frame on demand - works for both indexed files and external streaming
261
+ async function load_frame_on_demand(frame_idx: number) {
262
+ const load_trajectory = trajectory
263
+ const frame_loader = load_trajectory?.frame_loader
264
+ if (!load_trajectory || !frame_loader) return
265
+
266
+ const request_id = ++frame_load_request_id
267
+ const request_is_current = () =>
268
+ request_id === frame_load_request_id &&
269
+ trajectory === load_trajectory &&
270
+ current_step_idx === frame_idx
271
+
272
+ try {
273
+ const frame = await frame_loader.load_frame(
274
+ orig_data || ``, // Use original_data for indexed files, empty string for external streaming
275
+ frame_idx,
276
+ )
277
+ if (!request_is_current()) return
278
+ current_frame = frame
279
+ } catch (error) {
280
+ if (!request_is_current()) return
281
+ console.error(`Failed to load frame ${frame_idx}:`, error)
282
+ current_frame = null
283
+ on_error?.({
284
+ error_msg: `Failed to load frame ${frame_idx}: ${error}`,
285
+ filename: current_filename,
286
+ file_size,
287
+ step_idx: frame_idx,
288
+ frame_count: total_frames,
289
+ })
290
+ }
291
+ }
292
+
293
+ // Current frame structure for display
294
+ let current_structure = $derived(current_frame?.structure)
295
+
296
+ // Track hidden elements (persists across frame changes)
297
+ let hidden_elements = $state(new Set<ElementSymbol>())
298
+
299
+ let step_label_positions = $derived.by((): number[] => {
300
+ if (!step_labels || total_frames <= 1) return []
301
+
302
+ if (Array.isArray(step_labels)) {
303
+ return step_labels.filter((idx) => idx >= 0 && idx < total_frames)
304
+ }
305
+
306
+ if (typeof step_labels === `number`) {
307
+ if (step_labels > 0) {
308
+ return scaleLinear().domain([0, total_frames - 1]).nice()
309
+ .ticks(Math.min(step_labels, total_frames))
310
+ .map((tick) => Math.round(tick))
311
+ .filter((tick, idx, ticks) =>
312
+ tick >= 0 && tick < total_frames && ticks.indexOf(tick) === idx
313
+ )
314
+ }
315
+ if (step_labels < 0) {
316
+ const spacing = Math.abs(step_labels)
317
+ const positions = Array.from(
318
+ { length: Math.ceil(total_frames / spacing) },
319
+ (_, idx) => idx * spacing,
320
+ )
321
+ return positions.at(-1) === total_frames - 1
322
+ ? positions
323
+ : [...positions, total_frames - 1]
324
+ }
325
+ }
326
+ return []
327
+ })
328
+
329
+ // Build extended property config with custom labels if provided
330
+ let extended_config = $derived.by(() => {
331
+ if (!ELEM_PROPERTY_LABELS) return trajectory_property_config
332
+
333
+ const custom_config: Record<string, { label: string; unit: string }> = {}
334
+ for (const [key, label] of Object.entries(ELEM_PROPERTY_LABELS)) {
335
+ const existing = trajectory_property_config[key] ||
336
+ trajectory_property_config[key.toLowerCase()]
337
+ custom_config[key] = { label, unit: existing?.unit || `` }
338
+ }
339
+ return { ...trajectory_property_config, ...custom_config }
340
+ })
341
+
342
+ // Plot series state (not derived so we can update on legend toggle)
343
+ let plot_series = $state<DataSeries[]>([])
344
+ // Prevent circular updates when syncing legend toggles back to bindable visible_properties.
345
+ let syncing_visible_properties = false
346
+
347
+ // Regenerate plot series when trajectory, config, or visible_properties change.
348
+ // Read ALL reactive deps before the syncing guard can return: a guarded run that
349
+ // reads no dependencies leaves the effect dep-less, and Svelte permanently unlinks
350
+ // dep-less effects - trajectory changes would then never regenerate the plot.
351
+ $effect(() => {
352
+ const [traj, extractor, config, keys] = [
353
+ trajectory,
354
+ data_extractor,
355
+ extended_config,
356
+ visible_properties,
357
+ ]
358
+ if (syncing_visible_properties) return
359
+ const keys_set = keys ? new Set(keys) : undefined
360
+
361
+ if (traj?.plot_metadata) {
362
+ plot_series = generate_streaming_plot_series(traj.plot_metadata, {
363
+ property_config: config,
364
+ default_visible_properties: keys_set,
365
+ })
366
+ } else if (traj) {
367
+ plot_series = generate_plot_series(traj, extractor, {
368
+ property_config: config,
369
+ default_visible_properties: keys_set,
370
+ })
371
+ } else {
372
+ plot_series = []
373
+ }
374
+ })
375
+
376
+ // Update visible_properties binding when user toggles series visibility in legend
377
+ $effect(() => {
378
+ if (plot_series.length === 0) return
379
+
380
+ // Extract property keys from visible series metadata
381
+ const visible_keys = plot_series.flatMap((srs) => {
382
+ if (!srs.visible) return []
383
+ const metadata = Array.isArray(srs.metadata) ? srs.metadata[0] : srs.metadata
384
+ const key = metadata?.property_key
385
+ return key ? [key as string] : []
386
+ })
387
+
388
+ // Only update if changed (use untrack to avoid circular dependency)
389
+ const current = untrack(() => visible_properties) || []
390
+ const has_changed = visible_keys.length !== current.length ||
391
+ !visible_keys.every((key, idx) => key === current[idx])
392
+
393
+ if (has_changed) {
394
+ syncing_visible_properties = true
395
+ visible_properties = visible_keys
396
+ queueMicrotask(() => (syncing_visible_properties = false))
397
+ }
398
+ })
399
+
400
+ // Handler for legend toggle - updates plot_series state
401
+ function handle_legend_toggle(series_idx: number) {
402
+ plot_series = toggle_series_visibility(plot_series, series_idx)
403
+ }
404
+
405
+ let x_axis = $derived({
406
+ label: `Step`,
407
+ format: `.3~s`,
408
+ ticks: step_label_positions,
409
+ })
410
+ // Generate axis labels based on first visible series on each axis
411
+ let y_axis_labels = $derived(generate_axis_labels(plot_series))
412
+ let y_axis = $derived({
413
+ label: y_axis_labels.y1,
414
+ format: `.2~s`,
415
+ label_shift: { y: 10 },
416
+ })
417
+ let y2_axis = $derived({
418
+ label: y_axis_labels.y2,
419
+ format: `.2~s`,
420
+ label_shift: { y: 80 },
421
+ })
422
+
423
+ // hide plot if all plotted values are constant (no variation)
424
+ let show_plot = $derived(
425
+ display_mode !== `structure` && !should_hide_plot(trajectory, plot_series),
426
+ )
427
+
428
+ // Determine what to show based on display mode
429
+ let show_structure = $derived(![`scatter`, `histogram`].includes(display_mode))
430
+ let actual_show_plot = $derived(display_mode !== `structure` && show_plot)
431
+
432
+ // Check if there are any Y2 series to determine padding
433
+ let has_y2_series = $derived(
434
+ plot_series.some((srs) => srs.y_axis === `y2` && srs.visible),
435
+ )
436
+
437
+ // Step navigation functions
438
+ function next_step() {
439
+ if (current_step_idx < total_frames - 1) {
440
+ current_step_idx++
441
+ // Streaming frame loading handled by reactive effect
442
+ if (trajectory) {
443
+ on_step_change?.({
444
+ trajectory,
445
+ step_idx: current_step_idx,
446
+ frame_count: total_frames,
447
+ frame: current_frame || undefined,
448
+ })
449
+ }
450
+ }
451
+ }
452
+
453
+ function prev_step() {
454
+ if (current_step_idx > 0) {
455
+ current_step_idx--
456
+ // Streaming frame loading handled by reactive effect
457
+ if (trajectory) {
458
+ on_step_change?.({
459
+ trajectory,
460
+ step_idx: current_step_idx,
461
+ frame_count: total_frames,
462
+ frame: current_frame || undefined,
463
+ })
464
+ }
465
+ }
466
+ }
467
+
468
+ function go_to_step(idx: number) {
469
+ if (idx >= 0 && idx < total_frames) {
470
+ current_step_idx = idx
471
+ // Note: streaming frame loading is handled by reactive effect
472
+ // Handle callbacks for both traditional and streaming modes
473
+ if (trajectory) {
474
+ on_step_change?.({
475
+ trajectory,
476
+ step_idx: current_step_idx,
477
+ frame_count: total_frames,
478
+ frame: current_frame || undefined,
479
+ })
480
+ }
481
+ }
482
+ }
483
+
484
+ // Handle plot point clicks to jump to that step
485
+ function handle_plot_change(data: (Point & { series: DataSeries }) | null) {
486
+ if (data?.x !== undefined && typeof data.x === `number`) {
487
+ go_to_step(Math.round(data.x))
488
+ }
489
+ }
490
+
491
+ // Helper function to read file content
492
+ const read_file_content = (file: File): Promise<string | ArrayBuffer> =>
493
+ new Promise((resolve, reject) => {
494
+ const reader = new FileReader()
495
+ reader.addEventListener(`load`, () => resolve(reader.result as string | ArrayBuffer))
496
+ reader.addEventListener(`error`, () => reject(new Error(`Failed to read file`)))
497
+
498
+ // Read as text for text-based formats, binary for others
499
+ if (file.name.toLowerCase().match(/\.(xyz|json|extxyz|lammpstrj)$/)) {
500
+ reader.readAsText(file)
501
+ } else reader.readAsArrayBuffer(file)
502
+ })
503
+
504
+ // Play/pause functionality
505
+ function toggle_play() {
506
+ if (is_playing) pause_playback()
507
+ else start_playback()
508
+ }
509
+ function start_playback() {
510
+ if (total_frames <= 1) return
511
+ is_playing = true
512
+ if (trajectory) {
513
+ on_play?.({ trajectory, step_idx: current_step_idx, frame_count: total_frames })
514
+ }
515
+ }
516
+ function pause_playback() {
517
+ is_playing = false
518
+ if (trajectory) {
519
+ on_pause?.({
520
+ trajectory,
521
+ step_idx: current_step_idx,
522
+ frame_count: total_frames,
523
+ })
524
+ }
525
+ }
526
+ $effect(() => { // Effect to manage playback interval
527
+ // Only watch is_playing and frame_rate_ms, not play_interval itself
528
+ const playing = is_playing
529
+ const rate_ms = 1000 / fps
530
+
531
+ // Read current interval once (untrack to avoid circular dependency)
532
+ const current_interval = untrack(() => play_interval)
533
+ if (playing) {
534
+ // Clear existing interval if it exists
535
+ if (current_interval !== undefined) clearInterval(current_interval)
536
+
537
+ // Create new interval with current frame rate
538
+ play_interval = setInterval(() => {
539
+ if (current_step_idx >= total_frames - 1) {
540
+ if (trajectory) {
541
+ on_end?.({
542
+ trajectory,
543
+ step_idx: current_step_idx,
544
+ frame_count: total_frames,
545
+ frame: current_frame || undefined,
546
+ })
547
+ }
548
+ go_to_step(0) // Loop back to 1st step
549
+ if (trajectory) {
550
+ on_loop?.({ trajectory, frame_count: total_frames })
551
+ }
552
+ } else next_step()
553
+ }, rate_ms)
554
+ } else if (current_interval !== undefined) {
555
+ // Clear interval when not playing
556
+ clearInterval(current_interval)
557
+ play_interval = undefined
558
+ }
559
+ })
560
+
561
+ // Cleanup interval on component destroy
562
+ $effect(() => () => {
563
+ if (play_interval !== undefined) clearInterval(play_interval)
564
+ })
565
+
566
+ // Handle internal file format drops
567
+ async function handle_internal_file_drop(internal_data: string): Promise<boolean> {
568
+ try {
569
+ const file_info = JSON.parse(internal_data)
570
+
571
+ // Check if this is a binary file
572
+ if (file_info.is_binary) {
573
+ if (file_info.content instanceof ArrayBuffer) {
574
+ await load_trajectory_data(file_info.content, file_info.name)
575
+ } else if (file_info.content_url) {
576
+ const response = await fetch(file_info.content_url)
577
+ const array_buffer = await response.arrayBuffer()
578
+ await load_trajectory_data(array_buffer, file_info.name)
579
+ } else {
580
+ console.warn(
581
+ `Binary file without ArrayBuffer or blob URL:`,
582
+ file_info.name,
583
+ )
584
+ }
585
+ } else {
586
+ await load_trajectory_data(file_info.content, file_info.name)
587
+ }
588
+ return true
589
+ } catch (error) {
590
+ console.warn(`Failed to parse internal file data:`, error)
591
+ return false
592
+ }
593
+ }
594
+
595
+ // Handle file drop events with optimized large file support
596
+ async function handle_file_drop(event: DragEvent) {
597
+ event.preventDefault()
598
+ dragover = false
599
+ if (!allow_file_drop) return
600
+
601
+ loading = true
602
+
603
+ try {
604
+ // Check for our custom internal file format first
605
+ const internal_data = event.dataTransfer?.getData(
606
+ `application/x-matterviz-file`,
607
+ )
608
+ if (internal_data) {
609
+ const handled = await handle_internal_file_drop(internal_data)
610
+ if (handled) return
611
+ }
612
+
613
+ // Handle URL-based files (e.g. from FilePicker)
614
+ const handled = await handle_url_drop(event, async (content, filename) => {
615
+ current_filename = filename
616
+ file_size = content instanceof ArrayBuffer
617
+ ? content.byteLength
618
+ : new Blob([content]).size
619
+ await load_trajectory_data(content, filename)
620
+ }).catch(() => false)
621
+
622
+ if (handled) {
623
+ return
624
+ }
625
+
626
+ // Handle file system drops with optimized large file support
627
+ const file = event.dataTransfer?.files[0]
628
+ if (file) {
629
+ file_size = file.size
630
+ current_file_path = file.webkitRelativePath || file.name
631
+ file_object = file
632
+
633
+ // Read file content directly
634
+ const content = await read_file_content(file)
635
+ await load_trajectory_data(content, file.name)
636
+ // Don't fall through: drops from IDEs/file managers often also carry a
637
+ // text/plain payload (the file path) which would clobber the loaded data
638
+ return
639
+ }
640
+
641
+ // Check for plain text data (fallback)
642
+ const text_data = event.dataTransfer?.getData(`text/plain`)
643
+ if (text_data) {
644
+ file_size = new Blob([text_data]).size // Calculate byte size of text data
645
+ await load_trajectory_data(text_data, `trajectory.json`)
646
+ }
647
+ } catch (error) {
648
+ console.error(`File drop failed:`, error)
649
+ error_msg = `Failed to load file: ${error}`
650
+ on_error?.({ error_msg, filename: current_filename, file_size })
651
+ } finally {
652
+ loading = false
653
+ }
654
+ }
655
+
656
+ $effect(() => { // Load trajectory from URL when data_url is provided
657
+ if (data_url && !trajectory) {
658
+ loading = true
659
+ error_msg = null
660
+
661
+ load_from_url(data_url, async (content, filename) => {
662
+ current_filename = filename
663
+ file_size = content instanceof ArrayBuffer
664
+ ? content.byteLength
665
+ : new Blob([content]).size
666
+ await load_trajectory_data(content, filename)
667
+ })
668
+ .then(() => {
669
+ loading = false
670
+ })
671
+ .catch((err: Error) => {
672
+ console.error(`Failed to load trajectory from URL:`, err)
673
+ error_msg = `Failed to load trajectory: ${err.message}`
674
+ current_filename = undefined
675
+ file_size = undefined
676
+ loading = false
677
+ on_error?.({
678
+ error_msg,
679
+ filename: current_filename || undefined,
680
+ file_size: file_size || undefined,
681
+ })
682
+ })
683
+ }
684
+ })
685
+
686
+ // Watch for frame rate changes
687
+ $effect(() => {
688
+ on_frame_rate_change?.({ trajectory, fps })
689
+ })
690
+
691
+ async function load_trajectory_data(data: string | ArrayBuffer, filename: string) {
692
+ loading = true
693
+ error_msg = null
694
+ parsing_progress = null
695
+
696
+ // Reset previous loading state
697
+ orig_data = null
698
+
699
+ try {
700
+ const data_size = data instanceof ArrayBuffer ? data.byteLength : data.length
701
+
702
+ // Determine loading strategy based on file size
703
+ const bin_file_threshold = loading_options.bin_file_threshold ??
704
+ MAX_BIN_FILE_SIZE
705
+ const text_file_threshold = loading_options.text_file_threshold ??
706
+ MAX_TEXT_FILE_SIZE
707
+ if (
708
+ (data instanceof ArrayBuffer && data_size > bin_file_threshold) ||
709
+ (typeof data === `string` && data_size > text_file_threshold)
710
+ ) { // Large files: Use indexed loading
711
+ await load_with_indexing(data, filename)
712
+ } else {
713
+ // Small files: Use regular loading
714
+ const merged_options = { ...loading_options, atom_type_mapping }
715
+ trajectory = await parse_trajectory_async(data, filename, (progress) => {
716
+ parsing_progress = progress
717
+ }, merged_options)
718
+ }
719
+
720
+ current_step_idx = 0
721
+ current_filename = filename
722
+
723
+ const file_size_bytes = data instanceof ArrayBuffer
724
+ ? data.byteLength
725
+ : new Blob([data]).size
726
+ on_file_load?.({ // emit file load event
727
+ trajectory,
728
+ frame_count: trajectory?.frames.length ?? 0,
729
+ total_atoms: trajectory?.frames[0]?.structure.sites.length ?? 0,
730
+ filename,
731
+ file_size: file_size_bytes,
732
+ })
733
+ } catch (err) {
734
+ const unsupported_message = get_unsupported_format_message(
735
+ filename,
736
+ typeof data === `string` ? data : ``,
737
+ )
738
+ error_msg = unsupported_message || `Failed to parse trajectory: ${err}`
739
+ current_filename = undefined
740
+ file_size = undefined
741
+
742
+ on_error?.({ // emit error event
743
+ error_msg,
744
+ filename: current_filename || undefined,
745
+ file_size: file_size || undefined,
746
+ })
747
+ } finally {
748
+ parsing_progress = null
749
+ loading = false
750
+ }
751
+ }
752
+
753
+ // Load using indexed parsing for large files
754
+ async function load_with_indexing(data: string | ArrayBuffer, filename: string) {
755
+ try { // Use indexed parsing for efficient large file handling
756
+ const merged_options = {
757
+ use_indexing: true,
758
+ ...loading_options,
759
+ atom_type_mapping,
760
+ }
761
+ trajectory = await parse_trajectory_async(data, filename, (progress) => {
762
+ parsing_progress = progress
763
+ }, merged_options)
764
+
765
+ // Keep original data for on-demand frame loads only when indexed parsing attached a
766
+ // frame_loader. Direct-parse fallbacks (e.g. large JSON or extensionless blob:
767
+ // filenames) load all frames upfront, so retaining a full duplicate payload wastes memory.
768
+ orig_data = trajectory?.frame_loader ? data : null
769
+ } catch (error) {
770
+ console.error(`Indexed loading failed:`, error)
771
+ throw error
772
+ }
773
+ }
774
+
775
+ // Get current view mode label
776
+ let current_view_label = $derived.by(() => {
777
+ if (display_mode === `structure`) return `Structure Only`
778
+ if (display_mode === `scatter`) return `Scatter Only`
779
+ if (display_mode === `histogram`) return `Histogram Only`
780
+ if (display_mode === `structure+histogram`) return `Structure + Histogram`
781
+ if (display_mode === `structure+scatter`) return `Structure + Scatter`
782
+ throw new Error(`Unexpected display mode: ${display_mode}`)
783
+ })
784
+
785
+ let view_mode_dropdown_open = $state(false)
786
+
787
+ // Handle click outside to close dropdowns
788
+ function handle_click_outside(event: MouseEvent) {
789
+ const target = event.target
790
+ if (!(target instanceof Element)) return
791
+ if (view_mode_dropdown_open) {
792
+ const dropdown_wrapper = target.closest(`.view-mode-dropdown-wrapper`)
793
+ // Don't close if clicking on dropdown wrapper (contains both button and menu)
794
+ if (!dropdown_wrapper) view_mode_dropdown_open = false
795
+ }
796
+ }
797
+
798
+ // Handle keyboard shortcuts. Returns true if the key was handled, so the caller
799
+ // (handle_and_prevent / forward_window_keydown) can suppress the browser default.
800
+ function onkeydown(event: KeyboardEvent): boolean {
801
+ if (!trajectory) return false
802
+
803
+ // Don't handle shortcuts if user is typing in an input field (but allow if it's our step input and not focused)
804
+ const target = event.target instanceof HTMLElement ? event.target : null
805
+ const is_step_input = target?.classList.contains(`step-input`) ?? false
806
+ const is_input_focused =
807
+ target?.tagName === `INPUT` || target?.tagName === `TEXTAREA`
808
+
809
+ // Skip if typing in an input that's not our step input
810
+ if (is_input_focused && !is_step_input) return false
811
+
812
+ // If typing in step input, only handle certain navigation keys
813
+ if (is_step_input && is_input_focused) {
814
+ // Allow normal typing, but handle special navigation keys
815
+ if ([`Escape`, `Enter`].includes(event.key)) target?.blur() // Remove focus from input
816
+ return false
817
+ }
818
+
819
+ const is_cmd_or_ctrl = event.metaKey || event.ctrlKey
820
+
821
+ // Only the Arrow keys intentionally use Cmd/Ctrl (jump to first/last). For any
822
+ // other key a Cmd/Ctrl combo is a browser/OS shortcut (find, tab switch, zoom)
823
+ // — bail so we neither hijack it nor preventDefault the browser's own action.
824
+ if (is_cmd_or_ctrl && event.key !== `ArrowLeft` && event.key !== `ArrowRight`) return false
825
+
826
+ // Track whether a shortcut fired so callers suppress browser defaults (page
827
+ // scroll on Space/arrows/PageUp-Down/Home/End) only when we handled the key.
828
+ let handled = true
829
+ if (event.key === ` `) toggle_play()
830
+ else if (event.key === `ArrowLeft`) {
831
+ if (is_cmd_or_ctrl) go_to_step(0)
832
+ else prev_step()
833
+ } else if (event.key === `ArrowRight`) {
834
+ if (is_cmd_or_ctrl) go_to_step(total_frames - 1)
835
+ else next_step()
836
+ } else if (event.key === `Home`) go_to_step(0)
837
+ else if (event.key === `End`) go_to_step(total_frames - 1)
838
+ else if (event.key === `j`) {
839
+ go_to_step(Math.max(0, current_step_idx - 10))
840
+ } else if (event.key === `l`) {
841
+ go_to_step(Math.min(total_frames - 1, current_step_idx + 10))
842
+ } else if (event.key === `PageUp`) {
843
+ go_to_step(Math.max(0, current_step_idx - 25))
844
+ } else if (event.key === `PageDown`) {
845
+ go_to_step(Math.min(total_frames - 1, current_step_idx + 25))
846
+ } // Interface shortcuts
847
+ else if (event.key === `f` && fullscreen_toggle) toggle_fullscreen(wrapper)
848
+ // 'i' key handled by the TrajectoryInfoPane's built-in toggle
849
+ // Playback speed shortcuts (only when playing)
850
+ else if ((event.key === `=` || event.key === `+`) && is_playing) {
851
+ fps = Math.min(fps_range[1], fps + 0.2)
852
+ on_frame_rate_change?.({ trajectory, fps })
853
+ } else if (event.key === `-` && is_playing) {
854
+ fps = Math.max(fps_range[0], fps - 0.2)
855
+ on_frame_rate_change?.({ trajectory, fps })
856
+ } // System shortcuts
857
+ else if (event.key === `Escape`) {
858
+ if (document.fullscreenElement) document.exitFullscreen()
859
+ else if (view_mode_dropdown_open) view_mode_dropdown_open = false
860
+ // Escape key for info pane handled by DraggablePane
861
+ } // Number keys 0-9 - jump to percentage of trajectory
862
+ else if (event.key >= `0` && event.key <= `9`) {
863
+ go_to_step(Math.floor((parseInt(event.key, 10) / 10) * (total_frames - 1)))
864
+ } else handled = false
865
+
866
+ return handled
867
+ }
868
+
869
+ // Separate state variables for each pane to match component prop types
870
+ let structure_info_open = $state(false)
871
+ let structure_controls_open = $state(false)
872
+ let scatter_controls = $state<ControlsConfig>({ open: false })
873
+ let trajectory_export_open = $state(false)
874
+ let fullscreen = $state(false)
875
+ </script>
876
+
877
+ <svelte:document
878
+ onfullscreenchange={() => {
879
+ fullscreen = !!document.fullscreenElement
880
+ on_fullscreen_change?.({ trajectory, fullscreen })
881
+ }}
882
+ />
883
+
884
+ <svelte:window onkeydown={forward_window_keydown(() => hovered, onkeydown)} />
885
+
886
+ <div
887
+ class:dragover
888
+ class:active={is_playing || structure_info_open || structure_controls_open ||
889
+ scatter_controls.open || trajectory_export_open || info_pane_open}
890
+ bind:this={wrapper}
891
+ bind:clientWidth={element_size.width}
892
+ bind:clientHeight={element_size.height}
893
+ role="button"
894
+ tabindex="0"
895
+ aria-label="Drop trajectory file here to load"
896
+ onmouseenter={() => (hovered = true)}
897
+ onmouseleave={() => (hovered = false)}
898
+ ondrop={handle_file_drop}
899
+ ondragover={(event) => {
900
+ event.preventDefault()
901
+ if (!allow_file_drop) return
902
+ dragover = true
903
+ }}
904
+ ondragleave={(event) => {
905
+ event.preventDefault()
906
+ dragover = false
907
+ }}
908
+ onclick={handle_click_outside}
909
+ onkeydown={handle_and_prevent(onkeydown)}
910
+ {...rest}
911
+ class="trajectory {actual_layout} {rest.class ?? ``}"
912
+ class:show-both-views={[`structure+scatter`, `structure+histogram`].includes(display_mode) &&
913
+ actual_show_plot && show_structure}
914
+ >
915
+ {#if loading}
916
+ {@const text = parsing_progress
917
+ ? `${parsing_progress.stage} (${parsing_progress.current}%)`
918
+ : `Loading trajectory...`}
919
+ <Spinner
920
+ {text}
921
+ style="flex: 1; display: flex; align-items: center; justify-content: center"
922
+ {...spinner_props}
923
+ />
924
+ {:else if error_msg}
925
+ <TrajectoryError
926
+ {error_msg}
927
+ on_dismiss={() => (error_msg = null)}
928
+ {error_snippet}
929
+ />
930
+ {:else if trajectory}
931
+ <!-- Trajectory Controls -->
932
+ {#if controls_config.mode !== `never`}
933
+ <div
934
+ class="trajectory-controls {controls_config.class}"
935
+ style={controls_config.style}
936
+ >
937
+ {#if trajectory_controls}
938
+ {@render trajectory_controls({
939
+ trajectory,
940
+ current_step_idx,
941
+ total_frames: total_frames,
942
+ on_step_change: go_to_step,
943
+ })}
944
+ {:else}
945
+ {#if current_filename && controls_config.visible(`filename`)}
946
+ <button
947
+ class="filename"
948
+ title="Click to copy filename <code>{current_filename}</code>"
949
+ {@attach tooltip({ allow_html: true })}
950
+ onclick={() => {
951
+ if (current_filename) {
952
+ navigator.clipboard.writeText(current_filename)
953
+ filename_copied = true
954
+ setTimeout(() => filename_copied = false, 1000)
955
+ }
956
+ }}
957
+ >
958
+ {current_filename}
959
+ {#if filename_copied}
960
+ <Icon
961
+ icon="Check"
962
+ style="color: var(--success-color); position: absolute; right: 3pt; top: 50%; transform: translateY(-50%); font-size: 16px; animation: fade-in 0.1s; background: var(--surface-bg-hover); border-radius: 50%"
963
+ />
964
+ {/if}
965
+ </button>
966
+ {/if}
967
+
968
+ <!-- Navigation controls -->
969
+ {#if controls_config.visible(`nav`)}
970
+ <div class="nav-section">
971
+ <button
972
+ onclick={prev_step}
973
+ disabled={current_step_idx === 0 || is_playing}
974
+ title="Previous step"
975
+ >
976
+
977
+ </button>
978
+ <button
979
+ onclick={toggle_play}
980
+ disabled={total_frames <= 1}
981
+ title={is_playing ? `Pause playback` : `Play trajectory`}
982
+ class="play-button"
983
+ class:playing={is_playing}
984
+ >
985
+ {is_playing ? `⏸` : `▶`}
986
+ </button>
987
+ <button
988
+ onclick={next_step}
989
+ disabled={current_step_idx === total_frames - 1 || is_playing}
990
+ title="Next step"
991
+ >
992
+
993
+ </button>
994
+ </div>
995
+ {/if}
996
+
997
+ <!-- Frame slider and counter -->
998
+ {#if controls_config.visible(`step`)}
999
+ <div class="step-section">
1000
+ <input
1001
+ type="number"
1002
+ min="0"
1003
+ max={total_frames - 1}
1004
+ bind:value={current_step_idx}
1005
+ class="step-input"
1006
+ title="Enter step number to jump to"
1007
+ aria-label="Step input"
1008
+ {@attach tooltip()}
1009
+ />
1010
+ <span aria-label="total frames">/ {format_num(total_frames, `.3~s`)}</span>
1011
+ <div class="slider-container">
1012
+ <input
1013
+ type="range"
1014
+ min="0"
1015
+ max={total_frames - 1}
1016
+ bind:value={current_step_idx}
1017
+ class="step-slider"
1018
+ title="Drag to navigate steps"
1019
+ />
1020
+ {#if step_label_positions.length > 0}
1021
+ <div class="step-labels">
1022
+ {#each step_label_positions as step_idx (step_idx)}
1023
+ {@const position_percent = total_frames > 1
1024
+ ? (step_idx / (total_frames - 1)) * 100
1025
+ : 0}
1026
+ {@const adjusted_position = 1.5 + (position_percent * (100 - 2)) / 100}
1027
+ <div class="step-tick" style:left="{adjusted_position}%"></div>
1028
+ <div class="step-label" style:left="{adjusted_position}%">
1029
+ {format_num(step_idx, `.3~s`)}
1030
+ </div>
1031
+ {/each}
1032
+ </div>
1033
+ {/if}
1034
+ </div>
1035
+ </div>
1036
+ {/if}
1037
+
1038
+ <!-- Frame rate control - only shown when playing -->
1039
+ {#if is_playing && controls_config.visible(`fps`)}
1040
+ <label
1041
+ class="fps-section"
1042
+ style="font-size: 0.9em; display: flex; align-items: center; gap: 5pt; margin-inline: 6pt"
1043
+ >
1044
+ FPS
1045
+ <input
1046
+ type="range"
1047
+ min={fps_range[0]}
1048
+ max={fps_range[1]}
1049
+ bind:value={fps}
1050
+ title="Frame rate: {format_num(fps, `.2~s`)} fps"
1051
+ style="width: clamp(60px, 8cqw, 90px); accent-color: var(--accent-color)"
1052
+ />
1053
+ <input
1054
+ type="number"
1055
+ min={fps_range[0]}
1056
+ max={fps_range[1]}
1057
+ bind:value={fps}
1058
+ title="Enter precise FPS value"
1059
+ style="text-align: center; border: var(--tooltip-border)"
1060
+ />
1061
+ </label>
1062
+ {/if}
1063
+
1064
+ <!-- Frame info section -->
1065
+ <div class="info-section">
1066
+ {#if trajectory && controls_config.visible(`info-pane`)}
1067
+ <TrajectoryInfoPane
1068
+ {trajectory}
1069
+ {current_step_idx}
1070
+ {current_filename}
1071
+ {current_file_path}
1072
+ {file_size}
1073
+ {file_object}
1074
+ bind:pane_open={info_pane_open}
1075
+ pane_props={{ style: `max-height: calc(${element_size.height}px - 50px)` }}
1076
+ />
1077
+ {/if}
1078
+ <!-- Trajectory Export Pane -->
1079
+ {#if controls_config.visible(`export-pane`)}
1080
+ <TrajectoryExportPane
1081
+ bind:export_pane_open={trajectory_export_open}
1082
+ {trajectory}
1083
+ {wrapper}
1084
+ filename={current_filename || `trajectory`}
1085
+ on_step_change={go_to_step}
1086
+ pane_props={{ style: `max-height: calc(${element_size.height}px - 50px)` }}
1087
+ />
1088
+ {/if}
1089
+ <!-- Display mode dropdown -->
1090
+ {#if plot_series.length > 0 &&
1091
+ controls_config.visible(`view-mode`)}
1092
+ <div class="view-mode-dropdown-wrapper">
1093
+ <button
1094
+ onclick={() => (view_mode_dropdown_open = !view_mode_dropdown_open)}
1095
+ title={current_view_label}
1096
+ class="view-mode-button"
1097
+ class:active={view_mode_dropdown_open}
1098
+ style="background-color: transparent; padding: 0"
1099
+ >
1100
+ <Icon
1101
+ icon={({
1102
+ structure: `Atom`,
1103
+ 'structure+scatter': `TwoColumns`,
1104
+ 'structure+histogram': `TwoColumns`,
1105
+ scatter: `ScatterPlot`,
1106
+ histogram: `Histogram`,
1107
+ } as const)[display_mode]}
1108
+ />
1109
+ <Icon icon={view_mode_dropdown_open ? `ArrowUp` : `ArrowDown`} />
1110
+ </button>
1111
+ {#if view_mode_dropdown_open}
1112
+ <div class="view-mode-dropdown">
1113
+ {#each [
1114
+ { mode: `structure`, icon: `Atom`, label: `Structure-only` },
1115
+ {
1116
+ mode: `structure+scatter`,
1117
+ icon: `TwoColumns`,
1118
+ label: `Structure + Scatter`,
1119
+ },
1120
+ {
1121
+ mode: `structure+histogram`,
1122
+ icon: `TwoColumns`,
1123
+ label: `Structure + Histogram`,
1124
+ },
1125
+ { mode: `scatter`, icon: `ScatterPlot`, label: `Scatter-only` },
1126
+ {
1127
+ mode: `histogram`,
1128
+ icon: `Histogram`,
1129
+ label: `Histogram-only`,
1130
+ },
1131
+ ] as const as
1132
+ option
1133
+ (option.mode)
1134
+ }
1135
+ <button
1136
+ class="view-mode-option"
1137
+ class:selected={display_mode === option.mode}
1138
+ onclick={() => {
1139
+ display_mode = option.mode
1140
+ on_display_mode_change?.({ trajectory, mode: option.mode })
1141
+ view_mode_dropdown_open = false
1142
+ }}
1143
+ >
1144
+ <Icon icon={option.icon} />
1145
+ <span>{option.label}</span>
1146
+ </button>
1147
+ {/each}
1148
+ </div>
1149
+ {/if}
1150
+ </div>
1151
+ {/if}
1152
+ <!-- Fullscreen button - rightmost position -->
1153
+ {#if fullscreen_toggle &&
1154
+ controls_config.visible(`fullscreen`)}
1155
+ <button
1156
+ type="button"
1157
+ onclick={() => fullscreen_toggle && toggle_fullscreen(wrapper)}
1158
+ title="{fullscreen ? `Exit` : `Enter`} fullscreen"
1159
+ aria-label="{fullscreen ? `Exit` : `Enter`} fullscreen"
1160
+ aria-pressed={fullscreen}
1161
+ class="fullscreen-button"
1162
+ >
1163
+ {#if typeof fullscreen_toggle === `function`}
1164
+ {@render fullscreen_toggle({ fullscreen })}
1165
+ {:else}
1166
+ <Icon icon="{fullscreen ? `Exit` : ``}Fullscreen" />
1167
+ {/if}
1168
+ </button>
1169
+ {/if}
1170
+ </div>
1171
+ {/if}
1172
+ </div>
1173
+ {/if}
1174
+
1175
+ <div
1176
+ class="content-area"
1177
+ class:hide-plot={!actual_show_plot}
1178
+ class:hide-structure={!show_structure}
1179
+ class:show-both={[`structure+scatter`, `structure+histogram`].includes(display_mode)}
1180
+ class:show-structure-only={display_mode === `structure`}
1181
+ class:show-plot-only={[`scatter`, `histogram`].includes(display_mode)}
1182
+ >
1183
+ {#if show_structure}
1184
+ <Structure
1185
+ structure={current_structure}
1186
+ allow_file_drop={false}
1187
+ style="height: 100%; min-height: 0; z-index: 3; border-radius: 0"
1188
+ {...{
1189
+ show_image_atoms: false, // Default to false to avoid atoms popping in/out at cell edges
1190
+ ...structure_props,
1191
+ }}
1192
+ bind:controls_open={structure_controls_open}
1193
+ bind:info_pane_open={structure_info_open}
1194
+ bind:hidden_elements
1195
+ />
1196
+ {/if}
1197
+
1198
+ {#if actual_show_plot}
1199
+ {#if display_mode === `scatter` || display_mode === `structure+scatter`}
1200
+ <ScatterPlot
1201
+ series={plot_series}
1202
+ {x_axis}
1203
+ {y_axis}
1204
+ {y2_axis}
1205
+ controls={scatter_controls}
1206
+ current_x_value={current_step_idx}
1207
+ change={plot_skimming ? handle_plot_change : undefined}
1208
+ padding={{ t: 20, b: 60, l: 52, r: has_y2_series ? 100 : 20 }}
1209
+ range_padding={0}
1210
+ style="height: 100%"
1211
+ {...scatter_props}
1212
+ legend={{
1213
+ ...scatter_props.legend ?? {},
1214
+ on_toggle: (series_idx: number) => {
1215
+ handle_legend_toggle(series_idx)
1216
+ scatter_props.legend?.on_toggle?.(series_idx)
1217
+ },
1218
+ }}
1219
+ class="plot {scatter_props.class ?? ``}"
1220
+ >
1221
+ {#snippet tooltip({
1222
+ x,
1223
+ y,
1224
+ metadata,
1225
+ label,
1226
+ }: ScatterHandlerProps)}
1227
+ {@const formatted_y = typeof y === `number` ? format_num(y) : y}
1228
+ Step: {Math.round(x)}<br />
1229
+ {@html sanitize_html(metadata?.series_label || label || `Value`)}: {formatted_y}
1230
+ {/snippet}
1231
+ </ScatterPlot>
1232
+ {:else if display_mode === `histogram` || display_mode === `structure+histogram`}
1233
+ <Histogram
1234
+ {...histogram_props}
1235
+ series={plot_series}
1236
+ x_axis={{
1237
+ label: String(histogram_props.x_axis?.label ?? y_axis_labels.y1),
1238
+ format: `.3~s`,
1239
+ }}
1240
+ y_axis={{ label: histogram_props.y_axis?.label ?? `Count`, format: `.3~s` }}
1241
+ mode={histogram_props.mode ?? `overlay`}
1242
+ show_legend={histogram_props.show_legend ?? plot_series.length > 1}
1243
+ legend={histogram_props.legend}
1244
+ on_series_toggle={(series_idx: number) => {
1245
+ handle_legend_toggle(series_idx)
1246
+ histogram_props.on_series_toggle?.(series_idx)
1247
+ }}
1248
+ style="height: 100%"
1249
+ class="plot {histogram_props.class ?? ``}"
1250
+ --ctrl-btn-top="6ex"
1251
+ >
1252
+ {#snippet tooltip({
1253
+ value,
1254
+ count,
1255
+ property,
1256
+ }: {
1257
+ value: number
1258
+ count: number
1259
+ property?: string
1260
+ })}
1261
+ {#if property}<div><strong>{property}</strong></div>{/if}
1262
+ <div>Value: {format_num(value)}</div>
1263
+ <div>Count: {count}</div>
1264
+ {/snippet}
1265
+ </Histogram>
1266
+ {/if}
1267
+ {/if}
1268
+ </div>
1269
+ {:else}
1270
+ <EmptyState class="trajectory-empty-state">
1271
+ <h3 id="load-trajectory">Load Trajectory</h3>
1272
+ <p>
1273
+ Drop a trajectory file here (.xyz, .extxyz, .json, .json.gz, XDATCAR, .traj, .h5)
1274
+ or provide trajectory data via props
1275
+ </p>
1276
+ <strong style="display: block; margin-block: 1em 1ex">Supported formats:</strong>
1277
+ <ul>
1278
+ <li>Multi-frame XYZ trajectory files (.xyz, .extxyz)</li>
1279
+ <li>ASE trajectory files (.traj)</li>
1280
+ <li>Pymatgen trajectory JSON</li>
1281
+ <li>Array of structures with metadata</li>
1282
+ <li>VASP XDATCAR files</li>
1283
+ <li>HDF5 trajectory files (.h5, .hdf5)</li>
1284
+ <li>Compressed files (.gz)</li>
1285
+ </ul>
1286
+ <p>
1287
+ 💡 Force vectors will be automatically displayed when present in trajectory data
1288
+ </p>
1289
+ </EmptyState>
1290
+ {/if}
1291
+ </div>
1292
+
1293
+ <style>
1294
+ .trajectory {
1295
+ --min-height: 500px;
1296
+ display: flex;
1297
+ flex-direction: column;
1298
+ height: var(--traj-height, 100%);
1299
+ position: relative;
1300
+ min-height: var(--traj-min-height, var(--min-height));
1301
+ border-radius: var(--traj-border-radius, var(--border-radius, 3pt));
1302
+ box-sizing: border-box;
1303
+ contain: layout;
1304
+ z-index: var(--traj-z-index, 1);
1305
+ container-type: size; /* enable cqh for panes if explicit height is set */
1306
+ :global(.plot) {
1307
+ background: var(--surface-bg);
1308
+ }
1309
+ &.active {
1310
+ z-index: 2; /* needed so info/control panes from an active viewer overlay those of the next (if there is one) */
1311
+ .trajectory-controls {
1312
+ z-index: 5; /* needed so info/control panes from an active viewer its own plot when active, not sure why needed */
1313
+ }
1314
+ }
1315
+ &:fullscreen {
1316
+ height: 100vh !important;
1317
+ width: 100vw !important;
1318
+ border-radius: 0 !important;
1319
+ background: var(--surface-bg);
1320
+ overflow: hidden;
1321
+ }
1322
+ &.horizontal .content-area {
1323
+ grid-template-columns: 1fr 1fr;
1324
+ grid-template-rows: 1fr;
1325
+ }
1326
+ &.vertical .content-area {
1327
+ grid-template-columns: 1fr;
1328
+ grid-template-rows: 1fr 1fr;
1329
+ }
1330
+ /* Display mode specific layouts */
1331
+ &:is(.horizontal, .vertical) .content-area:is(.show-structure-only, .show-plot-only) {
1332
+ grid-template-columns: 1fr !important;
1333
+ grid-template-rows: 1fr !important;
1334
+ }
1335
+ &.dragover {
1336
+ background-color: var(--traj-dragover-bg, var(--dragover-bg));
1337
+ border: var(--traj-dragover-border, var(--dragover-border));
1338
+ }
1339
+ /* Mode: hover - controls visible on component hover */
1340
+ &:hover .trajectory-controls.hover-visible,
1341
+ &:focus-within .trajectory-controls.hover-visible {
1342
+ opacity: 1;
1343
+ pointer-events: auto;
1344
+ }
1345
+ }
1346
+ /* Content area - grid container for equal sizing */
1347
+ .content-area {
1348
+ display: grid;
1349
+ flex: 1;
1350
+ min-height: 0; /* important for tall structure viewers not to overflow */
1351
+ /* When plot or structure is hidden, the other takes full space */
1352
+ &:is(.hide-plot, .hide-structure) {
1353
+ grid-template-columns: 1fr !important;
1354
+ grid-template-rows: 1fr !important;
1355
+ }
1356
+ }
1357
+ .trajectory-controls {
1358
+ display: flex;
1359
+ align-items: center;
1360
+ gap: clamp(2pt, 1cqw, 1ex);
1361
+ padding: clamp(2pt, 0.5cqw, 1ex) clamp(4pt, 1cqw, 1.2ex);
1362
+ background: var(--surface-bg-hover);
1363
+ backdrop-filter: blur(4px);
1364
+ position: relative;
1365
+ border-radius: var(--border-radius, 3pt) var(--border-radius, 3pt) 0 0;
1366
+ opacity: 0;
1367
+ pointer-events: none;
1368
+ transition: opacity 0.2s ease;
1369
+ /* Mode: always - controls always visible */
1370
+ &.always-visible {
1371
+ opacity: 1;
1372
+ pointer-events: auto;
1373
+ }
1374
+ /* Mode: never - stays hidden (default state, no additional CSS needed) */
1375
+ &:focus-within {
1376
+ z-index: var(--traj-controls-z-index, 999999999);
1377
+ }
1378
+ button {
1379
+ background: var(--btn-bg);
1380
+ font-size: clamp(0.8rem, 2cqw, 1rem);
1381
+ &:hover:not(:disabled) {
1382
+ background: var(--btn-bg-hover);
1383
+ }
1384
+ }
1385
+ input[type='number'] {
1386
+ &::-webkit-outer-spin-button,
1387
+ &::-webkit-inner-spin-button {
1388
+ -webkit-appearance: none;
1389
+ margin: 0;
1390
+ }
1391
+ }
1392
+ }
1393
+ .nav-section {
1394
+ display: flex;
1395
+ align-items: center;
1396
+ gap: clamp(1pt, 0.5cqw, 5pt);
1397
+ }
1398
+ .step-section {
1399
+ display: flex;
1400
+ align-items: center;
1401
+ gap: clamp(0.25rem, 1.5cqw, 0.5rem);
1402
+ flex: 1;
1403
+ min-width: 0;
1404
+ }
1405
+ .step-input {
1406
+ border: 1px solid rgba(99, 179, 237, 0.3);
1407
+ text-align: center;
1408
+ margin: 0 -5px 0 0;
1409
+ padding: 2px;
1410
+ }
1411
+ .slider-container {
1412
+ position: relative;
1413
+ flex: 1;
1414
+ min-width: var(--trajectory-slider-min-width, 100px);
1415
+ }
1416
+ .step-slider {
1417
+ width: 100%;
1418
+ accent-color: var(--accent-color);
1419
+ }
1420
+ .step-labels {
1421
+ position: absolute;
1422
+ left: 0;
1423
+ right: 0;
1424
+ }
1425
+ .step-tick {
1426
+ position: absolute;
1427
+ transform: translateX(-50%);
1428
+ width: var(--trajectory-step-tick-width, 1px);
1429
+ height: var(--trajectory-step-tick-height, 4px);
1430
+ background: var(--text-color-muted);
1431
+ top: -9pt;
1432
+ }
1433
+ .step-label {
1434
+ position: absolute;
1435
+ transform: translateX(-50%);
1436
+ font-size: clamp(0.5em, 1.2cqw, 0.65em);
1437
+ color: var(--text-color-muted);
1438
+ white-space: nowrap;
1439
+ text-align: center;
1440
+ top: -1.7ex;
1441
+ }
1442
+ button.filename {
1443
+ align-items: center;
1444
+ white-space: nowrap;
1445
+ padding: var(--trajectory-filename-padding, 3pt 4pt);
1446
+ border-radius: var(--trajectory-filename-border-radius, var(--border-radius, 3pt));
1447
+ max-width: clamp(150px, 20cqw, 250px);
1448
+ overflow: hidden;
1449
+ text-overflow: ellipsis;
1450
+ display: inline-block;
1451
+ position: relative;
1452
+ font-family: monospace;
1453
+ font-size: 0.9em;
1454
+ background: var(--code-bg, rgba(0, 0, 0, 0.1));
1455
+ }
1456
+ @keyframes fade-in {
1457
+ from {
1458
+ opacity: 0;
1459
+ }
1460
+ }
1461
+ .fullscreen-button {
1462
+ background: transparent !important;
1463
+ padding: 0;
1464
+ &:hover:not(:disabled) {
1465
+ background: var(--border-color);
1466
+ }
1467
+ }
1468
+ .info-section {
1469
+ display: flex;
1470
+ align-items: center;
1471
+ gap: clamp(3pt, 0.6cqw, 1ex);
1472
+ position: relative;
1473
+ }
1474
+ .info-section :global(:is(.trajectory-info-toggle, .trajectory-export-toggle)) {
1475
+ font-size: clamp(1rem, 2.2cqw, 1.1rem);
1476
+ }
1477
+ .play-button {
1478
+ min-width: clamp(32px, 4cqw, 36px);
1479
+ &:hover:not(:disabled) {
1480
+ background: var(--traj-play-btn-bg-hover, var(--btn-bg-hover, rgba(0, 0, 0, 0.2)));
1481
+ }
1482
+ &.playing {
1483
+ background: var(--traj-pause-btn-bg, var(--btn-bg, rgba(0, 0, 0, 0.1)));
1484
+ &:hover:not(:disabled) {
1485
+ background: var(
1486
+ --traj-pause-btn-bg-hover,
1487
+ var(--btn-bg-hover, rgba(0, 0, 0, 0.1))
1488
+ );
1489
+ }
1490
+ }
1491
+ }
1492
+ :global(.trajectory-empty-state) {
1493
+ padding: 2rem;
1494
+ border-radius: var(--border-radius, 3pt);
1495
+ background: var(--dropzone-bg);
1496
+ :where(p, ul) {
1497
+ color: var(--text-color-muted);
1498
+ }
1499
+ :where(ul, li, strong) {
1500
+ max-width: var(--trajectory-empty-state-max-width, 500px);
1501
+ margin-inline: auto;
1502
+ }
1503
+ }
1504
+ button {
1505
+ &:hover:not(:disabled) {
1506
+ background: var(--border-color);
1507
+ }
1508
+ &:disabled {
1509
+ background: var(--btn-disabled-bg);
1510
+ color: var(--text-color-muted);
1511
+ cursor: not-allowed;
1512
+ }
1513
+ }
1514
+ /* Responsive design */
1515
+ @media (orientation: portrait) {
1516
+ .trajectory {
1517
+ /* Fallback class for browsers without :has() support */
1518
+ &.show-both-views {
1519
+ min-height: calc(var(--min-height) * 2);
1520
+ }
1521
+ /* Modern browsers: use :has() for same effect */
1522
+ @supports selector(:has(.content-area)) {
1523
+ &:has(.content-area.show-both:not(.hide-plot):not(.hide-structure)) {
1524
+ min-height: calc(var(--min-height) * 2);
1525
+ }
1526
+ }
1527
+ .content-area.show-both:not(.hide-plot):not(.hide-structure) {
1528
+ grid-template-columns: 1fr !important;
1529
+ grid-template-rows: 1fr 1fr !important;
1530
+ }
1531
+ }
1532
+ }
1533
+ .view-mode-dropdown-wrapper {
1534
+ display: flex;
1535
+ position: relative;
1536
+ }
1537
+ .view-mode-dropdown {
1538
+ position: absolute;
1539
+ top: 115%;
1540
+ right: 0;
1541
+ background: var(--surface-bg);
1542
+ border-radius: 4px;
1543
+ box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.3), 0 4px 8px -2px rgba(0, 0, 0, 0.1);
1544
+ }
1545
+ .view-mode-option {
1546
+ display: flex;
1547
+ align-items: center;
1548
+ gap: 1ex;
1549
+ width: 100%;
1550
+ padding: var(--trajectory-view-mode-option-padding, 5pt);
1551
+ box-sizing: border-box;
1552
+ background: transparent;
1553
+ border-radius: 0;
1554
+ text-align: left;
1555
+ transition: background-color 0.15s ease;
1556
+ &:first-child {
1557
+ border-top-left-radius: 3px;
1558
+ border-top-right-radius: 3px;
1559
+ }
1560
+ &.selected {
1561
+ color: var(--accent-color);
1562
+ }
1563
+ span {
1564
+ font-weight: 500;
1565
+ white-space: nowrap;
1566
+ overflow: hidden;
1567
+ text-overflow: ellipsis;
1568
+ flex: 1;
1569
+ }
1570
+ }
1571
+ </style>