matterviz 0.3.6 → 0.3.7

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 (863) 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.d.ts +13 -0
  5. package/dist/MillerIndexInput.svelte +66 -0
  6. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  7. package/dist/api/mp.d.ts +6 -0
  8. package/dist/api/mp.js +22 -0
  9. package/dist/api/optimade.d.ts +45 -0
  10. package/dist/api/optimade.js +135 -0
  11. package/dist/brillouin/BrillouinZone.svelte +549 -0
  12. package/dist/brillouin/BrillouinZone.svelte.d.ts +83 -0
  13. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  14. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  15. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  16. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  17. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  19. package/dist/brillouin/BrillouinZoneScene.svelte +476 -0
  20. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +48 -0
  21. package/dist/brillouin/BrillouinZoneTooltip.svelte +92 -0
  22. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  23. package/dist/brillouin/compute.d.ts +17 -0
  24. package/dist/brillouin/compute.js +426 -0
  25. package/dist/brillouin/index.d.ts +8 -0
  26. package/dist/brillouin/index.js +7 -0
  27. package/dist/brillouin/types.d.ts +43 -0
  28. package/dist/brillouin/types.js +1 -0
  29. package/dist/chempot-diagram/ChemPotDiagram.svelte +327 -0
  30. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  31. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  32. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  33. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  34. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  36. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  37. package/dist/chempot-diagram/async-compute.svelte.js +78 -0
  38. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  39. package/dist/chempot-diagram/chempot-worker.js +11 -0
  40. package/dist/chempot-diagram/color.d.ts +10 -0
  41. package/dist/chempot-diagram/color.js +32 -0
  42. package/dist/chempot-diagram/compute.d.ts +48 -0
  43. package/dist/chempot-diagram/compute.js +806 -0
  44. package/dist/chempot-diagram/index.d.ts +6 -0
  45. package/dist/chempot-diagram/index.js +6 -0
  46. package/dist/chempot-diagram/pointer.d.ts +16 -0
  47. package/dist/chempot-diagram/pointer.js +40 -0
  48. package/dist/chempot-diagram/temperature.d.ts +15 -0
  49. package/dist/chempot-diagram/temperature.js +34 -0
  50. package/dist/chempot-diagram/types.d.ts +81 -0
  51. package/dist/chempot-diagram/types.js +28 -0
  52. package/dist/colors/index.d.ts +47 -0
  53. package/dist/colors/index.js +203 -0
  54. package/dist/composition/BarChart.svelte +297 -0
  55. package/dist/composition/BarChart.svelte.d.ts +39 -0
  56. package/dist/composition/BubbleChart.svelte +218 -0
  57. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  58. package/dist/composition/Composition.svelte +165 -0
  59. package/dist/composition/Composition.svelte.d.ts +15 -0
  60. package/dist/composition/Formula.svelte +268 -0
  61. package/dist/composition/Formula.svelte.d.ts +19 -0
  62. package/dist/composition/FormulaFilter.svelte +1257 -0
  63. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  64. package/dist/composition/PieChart.svelte +323 -0
  65. package/dist/composition/PieChart.svelte.d.ts +37 -0
  66. package/dist/composition/format.d.ts +15 -0
  67. package/dist/composition/format.js +109 -0
  68. package/dist/composition/index.d.ts +20 -0
  69. package/dist/composition/index.js +14 -0
  70. package/dist/composition/parse.d.ts +56 -0
  71. package/dist/composition/parse.js +474 -0
  72. package/dist/constants.d.ts +29 -0
  73. package/dist/constants.js +99 -0
  74. package/dist/controls.d.ts +14 -0
  75. package/dist/controls.js +30 -0
  76. package/dist/convex-hull/ConvexHull.svelte +157 -0
  77. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  78. package/dist/convex-hull/ConvexHull2D.svelte +825 -0
  79. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  80. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  81. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  82. package/dist/convex-hull/ConvexHull4D.svelte +1398 -0
  83. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  84. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  85. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  86. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  87. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  88. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  89. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  90. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  91. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  92. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  93. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  94. package/dist/convex-hull/StructurePopup.svelte +151 -0
  95. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  96. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  97. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  98. package/dist/convex-hull/barycentric-coords.js +182 -0
  99. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  100. package/dist/convex-hull/demo-temperature.js +40 -0
  101. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  102. package/dist/convex-hull/gas-thermodynamics.js +314 -0
  103. package/dist/convex-hull/helpers.d.ts +114 -0
  104. package/dist/convex-hull/helpers.js +710 -0
  105. package/dist/convex-hull/index.d.ts +119 -0
  106. package/dist/convex-hull/index.js +58 -0
  107. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  108. package/dist/convex-hull/thermodynamics.js +1752 -0
  109. package/dist/convex-hull/types.d.ts +162 -0
  110. package/dist/convex-hull/types.js +36 -0
  111. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  112. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  113. package/dist/coordination/calc-coordination.d.ts +15 -0
  114. package/dist/coordination/calc-coordination.js +63 -0
  115. package/dist/coordination/index.d.ts +8 -0
  116. package/dist/coordination/index.js +7 -0
  117. package/dist/effects.svelte.d.ts +12 -0
  118. package/dist/effects.svelte.js +37 -0
  119. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  120. package/dist/element/ElementHeading.svelte +26 -0
  121. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  122. package/dist/element/ElementPhoto.svelte +57 -0
  123. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  124. package/dist/element/ElementStats.svelte +80 -0
  125. package/dist/element/ElementStats.svelte.d.ts +8 -0
  126. package/dist/element/ElementTile.svelte +484 -0
  127. package/dist/element/ElementTile.svelte.d.ts +29 -0
  128. package/dist/element/Nucleus.svelte.d.ts +17 -0
  129. package/dist/element/data.d.ts +2 -0
  130. package/dist/element/data.js +2 -0
  131. package/dist/element/index.d.ts +8 -0
  132. package/dist/element/index.js +7 -0
  133. package/dist/element/types.d.ts +57 -0
  134. package/dist/element/types.js +1 -0
  135. package/dist/feedback/ClickFeedback.svelte +58 -0
  136. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  137. package/dist/feedback/DragOverlay.svelte +42 -0
  138. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  139. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  140. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  141. package/dist/feedback/index.d.ts +4 -0
  142. package/dist/feedback/index.js +4 -0
  143. package/dist/fermi-surface/FermiSlice.svelte +189 -0
  144. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  145. package/dist/fermi-surface/FermiSurface.svelte +600 -0
  146. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  147. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  148. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  149. package/dist/fermi-surface/FermiSurfaceScene.svelte +794 -0
  150. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  151. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  152. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  153. package/dist/fermi-surface/compute.d.ts +5 -0
  154. package/dist/fermi-surface/compute.js +538 -0
  155. package/dist/fermi-surface/constants.d.ts +9 -0
  156. package/dist/fermi-surface/constants.js +27 -0
  157. package/dist/fermi-surface/export.d.ts +5 -0
  158. package/dist/fermi-surface/export.js +50 -0
  159. package/dist/fermi-surface/index.d.ts +12 -0
  160. package/dist/fermi-surface/index.js +13 -0
  161. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  162. package/dist/fermi-surface/marching-cubes.js +2 -0
  163. package/dist/fermi-surface/parse.d.ts +2 -0
  164. package/dist/fermi-surface/parse.js +491 -0
  165. package/dist/fermi-surface/symmetry.d.ts +3 -0
  166. package/dist/fermi-surface/symmetry.js +46 -0
  167. package/dist/fermi-surface/types.d.ts +110 -0
  168. package/dist/fermi-surface/types.js +4 -0
  169. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  170. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  171. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  172. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  173. package/dist/heatmap-matrix/index.d.ts +53 -0
  174. package/dist/heatmap-matrix/index.js +100 -0
  175. package/dist/heatmap-matrix/shared.d.ts +2 -0
  176. package/dist/heatmap-matrix/shared.js +4 -0
  177. package/dist/icons.d.ts +569 -0
  178. package/dist/icons.js +648 -0
  179. package/dist/index.d.ts +39 -0
  180. package/dist/index.js +39 -0
  181. package/dist/io/decompress.d.ts +11 -0
  182. package/dist/io/decompress.js +74 -0
  183. package/dist/io/export.d.ts +16 -0
  184. package/dist/io/export.js +316 -0
  185. package/dist/io/fetch.d.ts +5 -0
  186. package/dist/io/fetch.js +39 -0
  187. package/dist/io/file-drop.d.ts +7 -0
  188. package/dist/io/file-drop.js +43 -0
  189. package/dist/io/index.d.ts +7 -0
  190. package/dist/io/index.js +6 -0
  191. package/dist/io/is-binary.d.ts +1 -0
  192. package/dist/io/is-binary.js +20 -0
  193. package/dist/io/types.d.ts +8 -0
  194. package/dist/io/types.js +1 -0
  195. package/dist/io/url-drop.d.ts +2 -0
  196. package/dist/io/url-drop.js +123 -0
  197. package/dist/isosurface/Isosurface.svelte +285 -0
  198. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  199. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  200. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  201. package/dist/isosurface/index.d.ts +5 -0
  202. package/dist/isosurface/index.js +6 -0
  203. package/dist/isosurface/parse.d.ts +6 -0
  204. package/dist/isosurface/parse.js +553 -0
  205. package/dist/isosurface/slice.d.ts +11 -0
  206. package/dist/isosurface/slice.js +140 -0
  207. package/dist/isosurface/types.d.ts +56 -0
  208. package/dist/isosurface/types.js +227 -0
  209. package/dist/labels.d.ts +53 -0
  210. package/dist/labels.js +277 -0
  211. package/dist/layout/FullscreenToggle.svelte +50 -0
  212. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  213. package/dist/layout/InfoCard.svelte +120 -0
  214. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  215. package/dist/layout/InfoTag.svelte +185 -0
  216. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  217. package/dist/layout/PropertyFilter.svelte +246 -0
  218. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  219. package/dist/layout/SettingsSection.svelte +148 -0
  220. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  221. package/dist/layout/SubpageGrid.svelte +82 -0
  222. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  223. package/dist/layout/fullscreen.d.ts +9 -0
  224. package/dist/layout/fullscreen.js +53 -0
  225. package/dist/layout/index.d.ts +10 -0
  226. package/dist/layout/index.js +8 -0
  227. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  228. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  229. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  230. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  231. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  232. package/dist/layout/json-tree/index.d.ts +3 -0
  233. package/dist/layout/json-tree/index.js +3 -0
  234. package/dist/layout/json-tree/types.d.ts +74 -0
  235. package/dist/layout/json-tree/types.js +2 -0
  236. package/dist/layout/json-tree/utils.d.ts +29 -0
  237. package/dist/layout/json-tree/utils.js +641 -0
  238. package/dist/marching-cubes.d.ts +14 -0
  239. package/dist/marching-cubes.js +540 -0
  240. package/dist/math.d.ts +101 -0
  241. package/dist/math.js +905 -0
  242. package/dist/overlays/ContextMenu.svelte +162 -0
  243. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  244. package/dist/overlays/CopyButton.svelte +45 -0
  245. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  246. package/dist/overlays/DragControlTab.svelte +98 -0
  247. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  248. package/dist/overlays/DraggablePane.svelte +487 -0
  249. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  250. package/dist/overlays/InfoPaneCards.svelte +149 -0
  251. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  252. package/dist/overlays/index.d.ts +3 -0
  253. package/dist/overlays/index.js +3 -0
  254. package/dist/periodic-table/PeriodicTable.svelte +469 -0
  255. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  256. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  257. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  258. package/dist/periodic-table/PropertySelect.svelte +37 -0
  259. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  260. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  261. package/dist/periodic-table/index.d.ts +10 -0
  262. package/dist/periodic-table/index.js +4 -0
  263. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  264. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  265. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  266. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  267. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  268. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  269. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  270. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  271. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  272. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  273. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  274. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  275. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  276. package/dist/phase-diagram/build-diagram.js +160 -0
  277. package/dist/phase-diagram/colors.d.ts +35 -0
  278. package/dist/phase-diagram/colors.js +51 -0
  279. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  280. package/dist/phase-diagram/diagram-input.js +3 -0
  281. package/dist/phase-diagram/index.d.ts +13 -0
  282. package/dist/phase-diagram/index.js +11 -0
  283. package/dist/phase-diagram/parse.d.ts +55 -0
  284. package/dist/phase-diagram/parse.js +272 -0
  285. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  286. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  287. package/dist/phase-diagram/types.d.ts +93 -0
  288. package/dist/phase-diagram/types.js +1 -0
  289. package/dist/phase-diagram/utils.d.ts +118 -0
  290. package/dist/phase-diagram/utils.js +604 -0
  291. package/dist/plot/AxisLabel.svelte +51 -0
  292. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  293. package/dist/plot/BarPlot.svelte +2113 -0
  294. package/dist/plot/BarPlot.svelte.d.ts +84 -0
  295. package/dist/plot/BarPlotControls.svelte +66 -0
  296. package/dist/plot/BarPlotControls.svelte.d.ts +18 -0
  297. package/dist/plot/BinnedScatterPlot.svelte +1114 -0
  298. package/dist/plot/BinnedScatterPlot.svelte.d.ts +66 -0
  299. package/dist/plot/ColorBar.svelte +721 -0
  300. package/dist/plot/ColorBar.svelte.d.ts +31 -0
  301. package/dist/plot/ColorScaleSelect.svelte +54 -0
  302. package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
  303. package/dist/plot/ElementScatter.svelte +63 -0
  304. package/dist/plot/ElementScatter.svelte.d.ts +14 -0
  305. package/dist/plot/FillArea.svelte.d.ts +21 -0
  306. package/dist/plot/Histogram.svelte +1558 -0
  307. package/dist/plot/Histogram.svelte.d.ts +50 -0
  308. package/dist/plot/HistogramControls.svelte +212 -0
  309. package/dist/plot/HistogramControls.svelte.d.ts +22 -0
  310. package/dist/plot/InteractiveAxisLabel.svelte +96 -0
  311. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +14 -0
  312. package/dist/plot/Line.svelte +84 -0
  313. package/dist/plot/Line.svelte.d.ts +15 -0
  314. package/dist/plot/PlotAxis.svelte +169 -0
  315. package/dist/plot/PlotAxis.svelte.d.ts +24 -0
  316. package/dist/plot/PlotControls.svelte +537 -0
  317. package/dist/plot/PlotControls.svelte.d.ts +4 -0
  318. package/dist/plot/PlotLegend.svelte +569 -0
  319. package/dist/plot/PlotLegend.svelte.d.ts +29 -0
  320. package/dist/plot/PlotTooltip.svelte +67 -0
  321. package/dist/plot/PlotTooltip.svelte.d.ts +17 -0
  322. package/dist/plot/PortalSelect.svelte +253 -0
  323. package/dist/plot/PortalSelect.svelte.d.ts +16 -0
  324. package/dist/plot/ReferenceLine.svelte.d.ts +20 -0
  325. package/dist/plot/ReferenceLine3D.svelte +156 -0
  326. package/dist/plot/ReferenceLine3D.svelte.d.ts +14 -0
  327. package/dist/plot/ReferencePlane.svelte +175 -0
  328. package/dist/plot/ReferencePlane.svelte.d.ts +14 -0
  329. package/dist/plot/ScatterPlot.svelte +2778 -0
  330. package/dist/plot/ScatterPlot.svelte.d.ts +96 -0
  331. package/dist/plot/ScatterPlot3D.svelte +529 -0
  332. package/dist/plot/ScatterPlot3D.svelte.d.ts +95 -0
  333. package/dist/plot/ScatterPlot3DControls.svelte +437 -0
  334. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +20 -0
  335. package/dist/plot/ScatterPlot3DScene.svelte +912 -0
  336. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +74 -0
  337. package/dist/plot/ScatterPlotControls.svelte +306 -0
  338. package/dist/plot/ScatterPlotControls.svelte.d.ts +17 -0
  339. package/dist/plot/ScatterPoint.svelte +182 -0
  340. package/dist/plot/ScatterPoint.svelte.d.ts +22 -0
  341. package/dist/plot/SpacegroupBarPlot.svelte +293 -0
  342. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
  343. package/dist/plot/Surface3D.svelte +197 -0
  344. package/dist/plot/Surface3D.svelte.d.ts +13 -0
  345. package/dist/plot/ZeroLines.svelte +97 -0
  346. package/dist/plot/ZeroLines.svelte.d.ts +33 -0
  347. package/dist/plot/ZoomRect.svelte +23 -0
  348. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  349. package/dist/plot/adaptive-density.d.ts +69 -0
  350. package/dist/plot/adaptive-density.js +191 -0
  351. package/dist/plot/auto-place.d.ts +43 -0
  352. package/dist/plot/auto-place.js +122 -0
  353. package/dist/plot/axis-utils.d.ts +19 -0
  354. package/dist/plot/axis-utils.js +78 -0
  355. package/dist/plot/binned-scatter-types.d.ts +59 -0
  356. package/dist/plot/binned-scatter-types.js +1 -0
  357. package/dist/plot/data-cleaning.d.ts +37 -0
  358. package/dist/plot/data-cleaning.js +855 -0
  359. package/dist/plot/data-transform.d.ts +16 -0
  360. package/dist/plot/data-transform.js +45 -0
  361. package/dist/plot/defaults.d.ts +19 -0
  362. package/dist/plot/defaults.js +9 -0
  363. package/dist/plot/fill-utils.d.ts +46 -0
  364. package/dist/plot/fill-utils.js +322 -0
  365. package/dist/plot/hover-lock.svelte.d.ts +14 -0
  366. package/dist/plot/hover-lock.svelte.js +46 -0
  367. package/dist/plot/index.d.ts +41 -0
  368. package/dist/plot/index.js +39 -0
  369. package/dist/plot/interactions.d.ts +12 -0
  370. package/dist/plot/interactions.js +101 -0
  371. package/dist/plot/layout.d.ts +78 -0
  372. package/dist/plot/layout.js +273 -0
  373. package/dist/plot/reference-line.d.ts +60 -0
  374. package/dist/plot/reference-line.js +314 -0
  375. package/dist/plot/scales.d.ts +48 -0
  376. package/dist/plot/scales.js +481 -0
  377. package/dist/plot/svg.d.ts +1 -0
  378. package/dist/plot/svg.js +11 -0
  379. package/dist/plot/types.d.ts +831 -0
  380. package/dist/plot/types.js +99 -0
  381. package/dist/plot/utils/label-placement.d.ts +68 -0
  382. package/dist/plot/utils/label-placement.js +326 -0
  383. package/dist/plot/utils/series-visibility.d.ts +15 -0
  384. package/dist/plot/utils/series-visibility.js +85 -0
  385. package/dist/plot/utils.d.ts +1 -0
  386. package/dist/plot/utils.js +14 -0
  387. package/dist/rdf/RdfPlot.svelte +247 -0
  388. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  389. package/dist/rdf/calc-rdf.d.ts +4 -0
  390. package/dist/rdf/calc-rdf.js +111 -0
  391. package/dist/rdf/index.d.ts +23 -0
  392. package/dist/rdf/index.js +2 -0
  393. package/dist/sanitize.d.ts +6 -0
  394. package/dist/sanitize.js +116 -0
  395. package/dist/settings.d.ts +255 -0
  396. package/dist/settings.js +1132 -0
  397. package/dist/spectral/Bands.svelte +1040 -0
  398. package/dist/spectral/Bands.svelte.d.ts +40 -0
  399. package/dist/spectral/BandsAndDos.svelte +134 -0
  400. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  401. package/dist/spectral/BrillouinBandsDos.svelte +252 -0
  402. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  403. package/dist/spectral/Dos.svelte +697 -0
  404. package/dist/spectral/Dos.svelte.d.ts +29 -0
  405. package/dist/spectral/helpers.d.ts +119 -0
  406. package/dist/spectral/helpers.js +1032 -0
  407. package/dist/spectral/index.d.ts +6 -0
  408. package/dist/spectral/index.js +6 -0
  409. package/dist/spectral/types.d.ts +84 -0
  410. package/dist/spectral/types.js +2 -0
  411. package/dist/state.svelte.d.ts +25 -0
  412. package/dist/state.svelte.js +45 -0
  413. package/dist/structure/Arrow.svelte +72 -0
  414. package/dist/structure/Arrow.svelte.d.ts +15 -0
  415. package/dist/structure/AtomLegend.svelte +815 -0
  416. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  417. package/dist/structure/Bond.svelte +140 -0
  418. package/dist/structure/Bond.svelte.d.ts +9 -0
  419. package/dist/structure/CanvasTooltip.svelte +33 -0
  420. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  421. package/dist/structure/CellSelect.svelte +349 -0
  422. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  423. package/dist/structure/Cylinder.svelte +45 -0
  424. package/dist/structure/Cylinder.svelte.d.ts +10 -0
  425. package/dist/structure/Lattice.svelte +196 -0
  426. package/dist/structure/Lattice.svelte.d.ts +17 -0
  427. package/dist/structure/Structure.svelte +2248 -0
  428. package/dist/structure/Structure.svelte.d.ts +89 -0
  429. package/dist/structure/StructureControls.svelte +1273 -0
  430. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  431. package/dist/structure/StructureExportPane.svelte +252 -0
  432. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  433. package/dist/structure/StructureInfoPane.svelte +737 -0
  434. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  435. package/dist/structure/StructureScene.svelte +2255 -0
  436. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  437. package/dist/structure/atom-properties.d.ts +37 -0
  438. package/dist/structure/atom-properties.js +200 -0
  439. package/dist/structure/bond-order-perception.d.ts +13 -0
  440. package/dist/structure/bond-order-perception.js +384 -0
  441. package/dist/structure/bonding.d.ts +68 -0
  442. package/dist/structure/bonding.js +696 -0
  443. package/dist/structure/export.d.ts +20 -0
  444. package/dist/structure/export.js +727 -0
  445. package/dist/structure/index.d.ts +126 -0
  446. package/dist/structure/index.js +169 -0
  447. package/dist/structure/label-placement.d.ts +14 -0
  448. package/dist/structure/label-placement.js +72 -0
  449. package/dist/structure/measure.d.ts +6 -0
  450. package/dist/structure/measure.js +29 -0
  451. package/dist/structure/parse.d.ts +66 -0
  452. package/dist/structure/parse.js +1392 -0
  453. package/dist/structure/partial-occupancy.d.ts +25 -0
  454. package/dist/structure/partial-occupancy.js +99 -0
  455. package/dist/structure/pbc.d.ts +9 -0
  456. package/dist/structure/pbc.js +123 -0
  457. package/dist/structure/supercell.d.ts +8 -0
  458. package/dist/structure/supercell.js +170 -0
  459. package/dist/structure/validation.d.ts +2 -0
  460. package/dist/structure/validation.js +10 -0
  461. package/dist/symmetry/SymmetryStats.svelte +226 -0
  462. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  463. package/dist/symmetry/WyckoffTable.svelte +120 -0
  464. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  465. package/dist/symmetry/cell-transform.d.ts +12 -0
  466. package/dist/symmetry/cell-transform.js +91 -0
  467. package/dist/symmetry/index.d.ts +43 -0
  468. package/dist/symmetry/index.js +228 -0
  469. package/dist/symmetry/spacegroups.d.ts +9 -0
  470. package/dist/symmetry/spacegroups.js +394 -0
  471. package/dist/table/HeatmapTable.svelte +1833 -0
  472. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  473. package/dist/table/ToggleMenu.svelte +385 -0
  474. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  475. package/dist/table/index.d.ts +74 -0
  476. package/dist/table/index.js +38 -0
  477. package/dist/theme/ThemeControl.svelte +53 -0
  478. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  479. package/dist/theme/index.d.ts +29 -0
  480. package/dist/theme/index.js +79 -0
  481. package/dist/time.d.ts +4 -0
  482. package/dist/time.js +70 -0
  483. package/dist/tooltip/TooltipContent.svelte +58 -0
  484. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  485. package/dist/tooltip/index.d.ts +2 -0
  486. package/dist/tooltip/index.js +1 -0
  487. package/dist/tooltip/types.d.ts +8 -0
  488. package/dist/tooltip/types.js +1 -0
  489. package/dist/trajectory/Trajectory.svelte +1545 -0
  490. package/dist/trajectory/Trajectory.svelte.d.ts +77 -0
  491. package/dist/trajectory/TrajectoryError.svelte +128 -0
  492. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  493. package/dist/trajectory/TrajectoryExportPane.svelte +357 -0
  494. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  495. package/dist/trajectory/TrajectoryInfoPane.svelte +313 -0
  496. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  497. package/dist/trajectory/constants.d.ts +6 -0
  498. package/dist/trajectory/constants.js +7 -0
  499. package/dist/trajectory/extract.d.ts +5 -0
  500. package/dist/trajectory/extract.js +162 -0
  501. package/dist/trajectory/format-detect.d.ts +9 -0
  502. package/dist/trajectory/format-detect.js +76 -0
  503. package/dist/trajectory/frame-reader.d.ts +17 -0
  504. package/dist/trajectory/frame-reader.js +332 -0
  505. package/dist/trajectory/helpers.d.ts +15 -0
  506. package/dist/trajectory/helpers.js +164 -0
  507. package/dist/trajectory/index.d.ts +63 -0
  508. package/dist/trajectory/index.js +126 -0
  509. package/dist/trajectory/parse/ase.d.ts +2 -0
  510. package/dist/trajectory/parse/ase.js +73 -0
  511. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  512. package/dist/trajectory/parse/hdf5.js +127 -0
  513. package/dist/trajectory/parse/index.d.ts +12 -0
  514. package/dist/trajectory/parse/index.js +298 -0
  515. package/dist/trajectory/parse/lammps.d.ts +5 -0
  516. package/dist/trajectory/parse/lammps.js +179 -0
  517. package/dist/trajectory/parse/vasp.d.ts +2 -0
  518. package/dist/trajectory/parse/vasp.js +68 -0
  519. package/dist/trajectory/parse/xyz.d.ts +2 -0
  520. package/dist/trajectory/parse/xyz.js +110 -0
  521. package/dist/trajectory/plotting.d.ts +28 -0
  522. package/dist/trajectory/plotting.js +423 -0
  523. package/dist/trajectory/types.d.ts +11 -0
  524. package/dist/trajectory/types.js +1 -0
  525. package/dist/utils.d.ts +6 -0
  526. package/dist/utils.js +45 -0
  527. package/dist/xrd/XrdPlot.svelte +615 -0
  528. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  529. package/dist/xrd/broadening.d.ts +20 -0
  530. package/dist/xrd/broadening.js +97 -0
  531. package/dist/xrd/calc-xrd.d.ts +37 -0
  532. package/dist/xrd/calc-xrd.js +336 -0
  533. package/dist/xrd/index.d.ts +37 -0
  534. package/dist/xrd/index.js +4 -0
  535. package/dist/xrd/parse.d.ts +13 -0
  536. package/dist/xrd/parse.js +749 -0
  537. package/license +1 -1
  538. package/package.json +232 -1457
  539. package/readme.md +98 -171
  540. package/.vscode/launch.json +0 -13
  541. package/.vscodeignore +0 -7
  542. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  543. package/dist/assets/browser-DdDecX_W.js +0 -1
  544. package/dist/assets/export-qgn-H9y6.js +0 -2
  545. package/dist/assets/main-DiKYzti2.css +0 -1
  546. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  547. package/dist/extension.js +0 -31293
  548. package/dist/src/lib/FilePicker.svelte +0 -360
  549. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  550. package/dist/src/lib/api/mp.ts +0 -26
  551. package/dist/src/lib/api/optimade.ts +0 -204
  552. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  553. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  554. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  555. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  556. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  557. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  558. package/dist/src/lib/brillouin/compute.ts +0 -529
  559. package/dist/src/lib/brillouin/index.ts +0 -8
  560. package/dist/src/lib/brillouin/types.ts +0 -51
  561. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  562. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  563. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  564. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  565. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  566. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  567. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  568. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  569. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  570. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  571. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  572. package/dist/src/lib/colors/index.ts +0 -249
  573. package/dist/src/lib/composition/BarChart.svelte +0 -297
  574. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  575. package/dist/src/lib/composition/Composition.svelte +0 -165
  576. package/dist/src/lib/composition/Formula.svelte +0 -268
  577. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  578. package/dist/src/lib/composition/PieChart.svelte +0 -323
  579. package/dist/src/lib/composition/format.ts +0 -155
  580. package/dist/src/lib/composition/index.ts +0 -37
  581. package/dist/src/lib/composition/parse.ts +0 -605
  582. package/dist/src/lib/constants.ts +0 -134
  583. package/dist/src/lib/controls.ts +0 -42
  584. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  585. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  586. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  587. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  588. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  589. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  590. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  591. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  592. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  593. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  594. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  595. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  596. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  597. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  598. package/dist/src/lib/convex-hull/index.ts +0 -202
  599. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  600. package/dist/src/lib/convex-hull/types.ts +0 -267
  601. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  602. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  603. package/dist/src/lib/coordination/index.ts +0 -9
  604. package/dist/src/lib/effects.svelte.ts +0 -48
  605. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  606. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  607. package/dist/src/lib/element/ElementStats.svelte +0 -80
  608. package/dist/src/lib/element/ElementTile.svelte +0 -484
  609. package/dist/src/lib/element/data.ts +0 -14
  610. package/dist/src/lib/element/index.ts +0 -8
  611. package/dist/src/lib/element/types.ts +0 -62
  612. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  613. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  614. package/dist/src/lib/feedback/index.ts +0 -4
  615. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  616. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  617. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  618. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  619. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  620. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  621. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  622. package/dist/src/lib/fermi-surface/export.ts +0 -64
  623. package/dist/src/lib/fermi-surface/index.ts +0 -14
  624. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  625. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  626. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  627. package/dist/src/lib/fermi-surface/types.ts +0 -159
  628. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  629. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  630. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  631. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  632. package/dist/src/lib/icons.ts +0 -650
  633. package/dist/src/lib/index.ts +0 -61
  634. package/dist/src/lib/io/decompress.ts +0 -92
  635. package/dist/src/lib/io/export.ts +0 -385
  636. package/dist/src/lib/io/fetch.ts +0 -46
  637. package/dist/src/lib/io/file-drop.ts +0 -51
  638. package/dist/src/lib/io/index.ts +0 -7
  639. package/dist/src/lib/io/is-binary.ts +0 -24
  640. package/dist/src/lib/io/types.ts +0 -8
  641. package/dist/src/lib/io/url-drop.ts +0 -141
  642. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  643. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  644. package/dist/src/lib/isosurface/index.ts +0 -7
  645. package/dist/src/lib/isosurface/parse.ts +0 -656
  646. package/dist/src/lib/isosurface/slice.ts +0 -175
  647. package/dist/src/lib/isosurface/types.ts +0 -309
  648. package/dist/src/lib/labels.ts +0 -320
  649. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  650. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  651. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  652. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  653. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  654. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  655. package/dist/src/lib/layout/fullscreen.ts +0 -65
  656. package/dist/src/lib/layout/index.ts +0 -11
  657. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  658. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  659. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  660. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  661. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  662. package/dist/src/lib/marching-cubes.ts +0 -614
  663. package/dist/src/lib/math.ts +0 -1081
  664. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  665. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  666. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  667. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  668. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  669. package/dist/src/lib/overlays/index.ts +0 -3
  670. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  671. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  672. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  673. package/dist/src/lib/periodic-table/index.ts +0 -12
  674. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  675. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  676. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  677. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  678. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  679. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  680. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  681. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  682. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  683. package/dist/src/lib/phase-diagram/index.ts +0 -13
  684. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  685. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  686. package/dist/src/lib/phase-diagram/types.ts +0 -144
  687. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  688. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  689. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  690. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  691. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  692. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  693. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  694. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  695. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  696. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  697. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  698. package/dist/src/lib/plot/Line.svelte +0 -84
  699. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  700. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  701. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  702. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  703. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  704. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  705. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  706. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  707. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  708. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  709. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  710. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  711. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  712. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  713. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  714. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  715. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  716. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  717. package/dist/src/lib/plot/auto-place.ts +0 -184
  718. package/dist/src/lib/plot/axis-utils.ts +0 -122
  719. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  720. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  721. package/dist/src/lib/plot/data-transform.ts +0 -69
  722. package/dist/src/lib/plot/defaults.ts +0 -9
  723. package/dist/src/lib/plot/fill-utils.ts +0 -494
  724. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  725. package/dist/src/lib/plot/index.ts +0 -53
  726. package/dist/src/lib/plot/interactions.ts +0 -119
  727. package/dist/src/lib/plot/layout.ts +0 -425
  728. package/dist/src/lib/plot/reference-line.ts +0 -426
  729. package/dist/src/lib/plot/scales.ts +0 -654
  730. package/dist/src/lib/plot/svg.ts +0 -23
  731. package/dist/src/lib/plot/types.ts +0 -1144
  732. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  733. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  734. package/dist/src/lib/plot/utils.ts +0 -11
  735. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  736. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  737. package/dist/src/lib/rdf/index.ts +0 -27
  738. package/dist/src/lib/sanitize.ts +0 -126
  739. package/dist/src/lib/settings.ts +0 -1479
  740. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  741. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  742. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  743. package/dist/src/lib/spectral/Dos.svelte +0 -697
  744. package/dist/src/lib/spectral/helpers.ts +0 -1381
  745. package/dist/src/lib/spectral/index.ts +0 -8
  746. package/dist/src/lib/spectral/types.ts +0 -112
  747. package/dist/src/lib/state.svelte.ts +0 -64
  748. package/dist/src/lib/structure/Arrow.svelte +0 -72
  749. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  750. package/dist/src/lib/structure/Bond.svelte +0 -140
  751. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  752. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  753. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  754. package/dist/src/lib/structure/Lattice.svelte +0 -196
  755. package/dist/src/lib/structure/Structure.svelte +0 -2248
  756. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  757. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  758. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  759. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  760. package/dist/src/lib/structure/atom-properties.ts +0 -316
  761. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  762. package/dist/src/lib/structure/bonding.ts +0 -944
  763. package/dist/src/lib/structure/export.ts +0 -861
  764. package/dist/src/lib/structure/index.ts +0 -291
  765. package/dist/src/lib/structure/label-placement.ts +0 -130
  766. package/dist/src/lib/structure/measure.ts +0 -45
  767. package/dist/src/lib/structure/parse.ts +0 -1705
  768. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  769. package/dist/src/lib/structure/pbc.ts +0 -164
  770. package/dist/src/lib/structure/supercell.ts +0 -226
  771. package/dist/src/lib/structure/validation.ts +0 -11
  772. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  773. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  774. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  775. package/dist/src/lib/symmetry/index.ts +0 -348
  776. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  777. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  778. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  779. package/dist/src/lib/table/index.ts +0 -139
  780. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  781. package/dist/src/lib/theme/index.ts +0 -107
  782. package/dist/src/lib/time.ts +0 -71
  783. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  784. package/dist/src/lib/tooltip/index.ts +0 -2
  785. package/dist/src/lib/tooltip/types.ts +0 -13
  786. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  787. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  788. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  789. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  790. package/dist/src/lib/trajectory/constants.ts +0 -7
  791. package/dist/src/lib/trajectory/extract.ts +0 -196
  792. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  793. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  794. package/dist/src/lib/trajectory/helpers.ts +0 -217
  795. package/dist/src/lib/trajectory/index.ts +0 -218
  796. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  797. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  798. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  799. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  800. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  801. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  802. package/dist/src/lib/trajectory/plotting.ts +0 -599
  803. package/dist/src/lib/trajectory/types.ts +0 -13
  804. package/dist/src/lib/utils.ts +0 -56
  805. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  806. package/dist/src/lib/xrd/broadening.ts +0 -130
  807. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  808. package/dist/src/lib/xrd/index.ts +0 -38
  809. package/dist/src/lib/xrd/parse.ts +0 -858
  810. package/dist/webview.js +0 -29421
  811. package/icon.png +0 -0
  812. package/matterviz-0.3.2.vsix +0 -0
  813. package/matterviz-0.3.4.vsix +0 -0
  814. package/matterviz-0.3.5.vsix +0 -0
  815. package/scripts/sync-config.ts +0 -101
  816. package/src/declarations.d.ts +0 -2
  817. package/src/extension.ts +0 -972
  818. package/src/node-io.ts +0 -65
  819. package/src/types.ts +0 -17
  820. package/src/webview/JsonBrowser.svelte +0 -1079
  821. package/src/webview/PlotPanel.svelte +0 -346
  822. package/src/webview/detect.ts +0 -444
  823. package/src/webview/main.ts +0 -764
  824. package/src/webview/plot-utils.ts +0 -250
  825. package/test-fixtures/all-viz-types.json.gz +0 -0
  826. package/test-fixtures/plot-demo-data.json.gz +0 -0
  827. package/tests/detect.test.ts +0 -604
  828. package/tests/extension.test.ts +0 -2041
  829. package/tests/node-io.test.ts +0 -39
  830. package/tests/plot-utils.test.ts +0 -302
  831. package/tests/vite-plugin-json-gz.test.ts +0 -114
  832. package/tests/vscode-mock.ts +0 -18
  833. package/tests/webview.test.ts +0 -231
  834. package/tsconfig.json +0 -20
  835. package/vite-plugin-json-gz.ts +0 -29
  836. package/vite.config.ts +0 -34
  837. package/vite.extension.config.ts +0 -34
  838. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  839. /package/dist/{src/lib/Icon.svelte → Icon.svelte} +0 -0
  840. /package/dist/{src/lib/app.css → app.css} +0 -0
  841. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  842. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  843. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  844. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  845. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  846. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  847. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  848. /package/dist/{src/lib/convex-hull → convex-hull}/TemperatureSlider.svelte +0 -0
  849. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  850. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  851. /package/dist/{src/lib/element → element}/data.json +0 -0
  852. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  853. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  854. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  855. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  856. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  857. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  858. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  859. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  860. /package/dist/{src/lib/plot → plot}/FillArea.svelte +0 -0
  861. /package/dist/{src/lib/plot → plot}/ReferenceLine.svelte +0 -0
  862. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  863. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -0,0 +1,1398 @@
1
+ <script lang="ts">
2
+ import type { D3InterpolateName } from '../colors'
3
+ import {
4
+ add_alpha,
5
+ is_dark_mode,
6
+ PLOT_COLORS,
7
+ vesta_hex,
8
+ watch_dark_mode,
9
+ } from '../colors'
10
+ import { normalize_show_controls } from '../controls'
11
+ import { sanitize_html } from '../sanitize'
12
+ import { ClickFeedback, DragOverlay, Spinner } from '../feedback'
13
+ import Icon from '../Icon.svelte'
14
+ import {
15
+ set_fullscreen_bg,
16
+ setup_fullscreen_effect,
17
+ toggle_fullscreen,
18
+ } from '../layout'
19
+ import { ColorBar, PlotTooltip } from '../plot'
20
+ import { create_pulse_animation } from '../effects.svelte'
21
+ import { DEFAULTS } from '../settings'
22
+ import type { AnyStructure } from '../structure'
23
+ import {
24
+ barycentric_to_tetrahedral,
25
+ compute_4d_coords,
26
+ TETRAHEDRON_VERTICES,
27
+ } from './barycentric-coords'
28
+ import ConvexHullControls from './ConvexHullControls.svelte'
29
+ import ConvexHullInfoPane from './ConvexHullInfoPane.svelte'
30
+ import ConvexHullTooltip from './ConvexHullTooltip.svelte'
31
+ import GasPressureControls from './GasPressureControls.svelte'
32
+ import * as helpers from './helpers'
33
+ import type { BaseConvexHullProps, Hull3DProps } from './index'
34
+ import { CONVEX_HULL_STYLE, default_controls, default_hull_config } from './index'
35
+ import StructurePopup from './StructurePopup.svelte'
36
+ import TemperatureSlider from './TemperatureSlider.svelte'
37
+ import type { Point4D } from './thermodynamics'
38
+ import * as thermo from './thermodynamics'
39
+ import type {
40
+ ConvexHullEntry,
41
+ HighlightStyle,
42
+ HoverData3D,
43
+ HullFaceColorMode,
44
+ } from './types'
45
+ import { compute_hull_stability } from './helpers'
46
+
47
+ let {
48
+ entries = [],
49
+ controls = {},
50
+ config = {},
51
+ on_point_click,
52
+ on_point_hover,
53
+ fullscreen = $bindable(DEFAULTS.convex_hull.quaternary.fullscreen),
54
+ enable_fullscreen = true,
55
+ enable_info_pane = true,
56
+ wrapper = $bindable(),
57
+ label_threshold = 50,
58
+ show_stable = $bindable(DEFAULTS.convex_hull.quaternary.show_stable),
59
+ show_unstable = $bindable(DEFAULTS.convex_hull.quaternary.show_unstable),
60
+ show_hull_faces = $bindable(DEFAULTS.convex_hull.quaternary.show_hull_faces),
61
+ hull_face_opacity = $bindable(DEFAULTS.convex_hull.quaternary.hull_face_opacity),
62
+ hull_face_color_mode = $bindable(
63
+ DEFAULTS.convex_hull.quaternary.hull_face_color_mode as HullFaceColorMode,
64
+ ),
65
+ element_colors = vesta_hex,
66
+ color_mode = $bindable(DEFAULTS.convex_hull.quaternary.color_mode),
67
+ color_scale = $bindable(
68
+ DEFAULTS.convex_hull.quaternary.color_scale as D3InterpolateName,
69
+ ),
70
+ info_pane_open = $bindable(DEFAULTS.convex_hull.quaternary.info_pane_open),
71
+ legend_pane_open = $bindable(DEFAULTS.convex_hull.quaternary.legend_pane_open),
72
+ max_hull_dist_show_phases = $bindable(
73
+ DEFAULTS.convex_hull.quaternary.max_hull_dist_show_phases,
74
+ ),
75
+ max_hull_dist_show_labels = $bindable(
76
+ DEFAULTS.convex_hull.quaternary.max_hull_dist_show_labels,
77
+ ),
78
+ show_stable_labels = $bindable(
79
+ DEFAULTS.convex_hull.quaternary.show_stable_labels,
80
+ ),
81
+ show_unstable_labels = $bindable(
82
+ DEFAULTS.convex_hull.quaternary.show_unstable_labels,
83
+ ),
84
+ on_file_drop,
85
+ enable_click_selection = true,
86
+ enable_structure_preview = true,
87
+ energy_source_mode = $bindable(`precomputed`),
88
+ phase_stats = $bindable(null),
89
+ stable_entries = $bindable([]),
90
+ unstable_entries = $bindable([]),
91
+ highlighted_entries = $bindable([]),
92
+ highlight_style = {},
93
+ selected_entry = $bindable(null),
94
+ temperature = $bindable(),
95
+ interpolate_temperature = true,
96
+ max_interpolation_gap = 500,
97
+ gas_config,
98
+ gas_pressures = $bindable({}),
99
+ children,
100
+ tooltip,
101
+ ...rest
102
+ }: BaseConvexHullProps<ConvexHullEntry> & Hull3DProps & {
103
+ highlight_style?: HighlightStyle
104
+ } = $props()
105
+
106
+ const merged_controls = $derived({ ...default_controls, ...controls })
107
+ const controls_config = $derived(normalize_show_controls(merged_controls.show))
108
+ const merged_config = $derived({
109
+ ...default_hull_config,
110
+ ...config,
111
+ colors: { ...default_hull_config.colors, ...config.colors },
112
+ margin: { t: 60, r: 60, b: 60, l: 60, ...config.margin },
113
+ })
114
+
115
+ // Reactive dark mode detection for canvas text color
116
+ let dark_mode = $state(is_dark_mode())
117
+ $effect(() => watch_dark_mode((dark) => dark_mode = dark))
118
+ const text_color = $derived(helpers.get_canvas_text_color(dark_mode))
119
+
120
+ // Temperature-dependent free energy support
121
+ const { has_temp_data, available_temperatures } = $derived(
122
+ helpers.analyze_temperature_data(entries),
123
+ )
124
+
125
+ // Initialize or reset temperature when it's undefined or no longer valid
126
+ $effect(() => {
127
+ if (
128
+ has_temp_data &&
129
+ available_temperatures.length > 0 &&
130
+ (temperature === undefined || !available_temperatures.includes(temperature))
131
+ ) temperature = available_temperatures[0]
132
+ })
133
+
134
+ // Filter entries by temperature when in temperature mode
135
+ const temp_filtered_entries = $derived(
136
+ has_temp_data && temperature !== undefined
137
+ ? helpers.filter_entries_at_temperature(entries, temperature, {
138
+ interpolate: interpolate_temperature,
139
+ max_interpolation_gap,
140
+ })
141
+ : entries,
142
+ )
143
+
144
+ // Gas-dependent chemical potential support (corrections based on T, P)
145
+ const {
146
+ entries: gas_corrected_entries,
147
+ analysis: gas_analysis,
148
+ merged_config: merged_gas_config,
149
+ } = $derived(
150
+ helpers.get_gas_corrected_entries(
151
+ temp_filtered_entries,
152
+ gas_config,
153
+ gas_pressures,
154
+ temperature ?? helpers.DEFAULT_GAS_TEMP,
155
+ ),
156
+ )
157
+
158
+ let { // Compute energy mode information
159
+ has_precomputed_e_form,
160
+ has_precomputed_hull,
161
+ can_compute_e_form,
162
+ can_compute_hull,
163
+ energy_mode,
164
+ unary_refs,
165
+ } = $derived(
166
+ helpers.compute_energy_mode_info(
167
+ gas_corrected_entries,
168
+ thermo.find_lowest_energy_unary_refs,
169
+ energy_source_mode,
170
+ ),
171
+ )
172
+
173
+ const effective_entries = $derived(
174
+ helpers.get_effective_entries(
175
+ gas_corrected_entries,
176
+ energy_mode,
177
+ unary_refs,
178
+ thermo.compute_e_form_per_atom,
179
+ ),
180
+ )
181
+
182
+ // Process convex hull data with unified PhaseData interface using effective entries
183
+ const pd_data = $derived(thermo.process_hull_entries(effective_entries))
184
+
185
+ // Pre-compute polymorph stats once for O(1) tooltip lookups
186
+ const polymorph_stats_map = $derived(
187
+ helpers.compute_all_polymorph_stats(effective_entries),
188
+ )
189
+
190
+ const elements = $derived.by(() => {
191
+ if (pd_data.elements.length > 4) {
192
+ console.error(
193
+ `ConvexHull4D: Dataset contains ${pd_data.elements.length} elements, but quaternary diagrams require exactly 4. Found: [${
194
+ pd_data.elements.join(`, `)
195
+ }]`,
196
+ )
197
+ return []
198
+ }
199
+ return pd_data.elements
200
+ })
201
+
202
+ // Compute 4D hull for visualization (always compute when we have formation energies)
203
+ const hull_4d = $derived.by(() => {
204
+ if (elements.length !== 4) return []
205
+
206
+ try {
207
+ // Get coords with formation energies, excluding entries that don't participate in hull
208
+ const coords = compute_4d_coords(pd_data.entries, elements)
209
+ .filter((ent) => !ent.exclude_from_hull)
210
+
211
+ // Convert to 4D points for hull computation using barycentric coordinates (composition fractions)
212
+ const points_4d: Point4D[] = coords
213
+ .filter(
214
+ (ent) =>
215
+ Number.isFinite(ent.e_form_per_atom) &&
216
+ [ent.x, ent.y, ent.z].every(Number.isFinite),
217
+ )
218
+ .map((ent) => {
219
+ const amounts = elements.map((el) => ent.composition[el] || 0)
220
+ const total = amounts.reduce((sum, amt) => sum + amt, 0)
221
+ if (!(total > 0)) return { x: NaN, y: NaN, z: NaN, w: NaN }
222
+ const [x, y, z] = amounts.map((amt) => amt / total)
223
+ return { x, y, z, w: ent.e_form_per_atom ?? NaN }
224
+ })
225
+ .filter((point) => [point.x, point.y, point.z, point.w].every(Number.isFinite))
226
+
227
+ if (points_4d.length < 5) return [] // Need at least 5 points for 4D hull
228
+
229
+ return thermo.compute_lower_hull_4d(points_4d)
230
+ } catch (error) {
231
+ console.error(`Error computing 4D hull:`, error)
232
+ return []
233
+ }
234
+ })
235
+
236
+ // Enrich coords with e_above_hull (before filtering)
237
+ const all_enriched_entries = $derived.by(() => {
238
+ if (elements.length !== 4) return []
239
+ try {
240
+ const coords = compute_4d_coords(pd_data.entries, elements)
241
+ if (energy_mode !== `on-the-fly` || hull_4d.length === 0) return coords
242
+
243
+ // Build 4D points, tracking original indices for mapping hull distances back
244
+ const valid = coords.flatMap((entry, idx) => {
245
+ if (
246
+ !Number.isFinite(entry.e_form_per_atom) ||
247
+ ![entry.x, entry.y, entry.z].every(Number.isFinite)
248
+ ) return []
249
+ const amounts = elements.map((el) => entry.composition[el] || 0)
250
+ const total = amounts.reduce((sum, amt) => sum + amt, 0)
251
+ if (!(total > 0)) return []
252
+ const [x, y, z] = amounts.map((amt) => amt / total)
253
+ return [x, y, z].every(Number.isFinite)
254
+ ? [{ idx, pt: { x, y, z, w: entry.e_form_per_atom ?? NaN } }]
255
+ : []
256
+ })
257
+ const raw_dists = thermo.compute_e_above_hull_4d(valid.map((item) => item.pt), hull_4d)
258
+ const hull_map = new Map(valid.map((item, hull_idx) => [item.idx, raw_dists[hull_idx]]))
259
+ return coords.map((entry, idx) => {
260
+ const raw = hull_map.get(idx)
261
+ if (raw === undefined) return { ...entry, e_above_hull: raw, is_stable: false }
262
+ return { ...entry, ...compute_hull_stability(raw, entry.exclude_from_hull) }
263
+ })
264
+ } catch (err) {
265
+ console.error(`Error computing quaternary coordinates:`, err)
266
+ return []
267
+ }
268
+ })
269
+
270
+ // Auto threshold: show all for few entries, use default for many, interpolate between
271
+ const max_hull_dist_in_data = $derived(
272
+ helpers.calc_max_hull_dist_in_data(all_enriched_entries),
273
+ )
274
+ const auto_default_threshold = $derived(helpers.compute_auto_hull_dist_threshold(
275
+ all_enriched_entries.length,
276
+ max_hull_dist_in_data,
277
+ DEFAULTS.convex_hull.quaternary.max_hull_dist_show_phases,
278
+ ))
279
+
280
+ const next_auto_threshold = helpers.auto_threshold_reset(
281
+ DEFAULTS.convex_hull.quaternary.max_hull_dist_show_phases,
282
+ )
283
+ $effect(() => {
284
+ max_hull_dist_show_phases = next_auto_threshold(
285
+ entries,
286
+ max_hull_dist_show_phases,
287
+ auto_default_threshold,
288
+ ) ?? max_hull_dist_show_phases
289
+ })
290
+
291
+ // Filter by threshold; visibility is a view predicate, not entry state.
292
+ const plot_entries = $derived(
293
+ all_enriched_entries.filter((entry) => {
294
+ // Always include stable entries and elemental reference points
295
+ if (helpers.entry_is_stable(entry)) return true
296
+ return typeof entry.e_above_hull === `number` &&
297
+ entry.e_above_hull <= max_hull_dist_show_phases
298
+ }),
299
+ )
300
+ const visible_entries = $derived(helpers.visible_entries(
301
+ plot_entries,
302
+ show_stable,
303
+ show_unstable,
304
+ ))
305
+
306
+ // Stable and unstable entries exposed as bindable props
307
+ $effect(() => {
308
+ stable_entries = plot_entries.filter(helpers.entry_is_stable)
309
+ unstable_entries = plot_entries.filter(helpers.entry_is_unstable)
310
+ })
311
+
312
+ let canvas: HTMLCanvasElement | undefined = undefined
313
+ let ctx: CanvasRenderingContext2D | null = null
314
+ let frame_id = 0 // Performance optimization
315
+
316
+ // Camera state - following Materials Project's 3D camera setup
317
+ let camera = $state({
318
+ rotation_x: DEFAULTS.convex_hull.quaternary.camera_rotation_x,
319
+ rotation_y: DEFAULTS.convex_hull.quaternary.camera_rotation_y,
320
+ zoom: DEFAULTS.convex_hull.quaternary.camera_zoom,
321
+ center_x: 0,
322
+ center_y: 20, // Slight offset to avoid legend overlap
323
+ })
324
+
325
+ // Interaction state
326
+ let is_dragging = $state(false)
327
+ let drag_started = $state(false)
328
+ let last_mouse = $state({ x: 0, y: 0 })
329
+ let hover_data = $state<HoverData3D<ConvexHullEntry> | null>(null)
330
+ let copy_feedback = $state({ visible: false, position: { x: 0, y: 0 } })
331
+
332
+ // Drag and drop state
333
+ let drag_over = $state(false)
334
+
335
+ // Structure popup state
336
+ let modal_open = $state(false)
337
+ let selected_structure = $state<AnyStructure | null>(null)
338
+ let modal_place_right = $state(true)
339
+ $effect(() => {
340
+ const current_selection = helpers.current_entry(selected_entry, plot_entries)
341
+ const stale_selection = selected_entry && !current_selection
342
+ if (stale_selection) selected_entry = null
343
+ else if (current_selection && current_selection !== selected_entry) {
344
+ selected_entry = current_selection
345
+ }
346
+ const current_hover = helpers.current_entry(hover_data?.entry, plot_entries)
347
+ if (hover_data?.entry && !current_hover) {
348
+ hover_data = null
349
+ on_point_hover?.(null)
350
+ } else if (hover_data && current_hover && current_hover !== hover_data.entry) {
351
+ hover_data = { ...hover_data, entry: current_hover }
352
+ }
353
+ if (modal_open) {
354
+ const structure = current_selection && extract_structure_from_entry(current_selection)
355
+ if (structure) selected_structure = structure
356
+ else {
357
+ modal_open = false
358
+ selected_structure = null
359
+ }
360
+ }
361
+ })
362
+
363
+ // Hull face color (customizable via controls)
364
+ let hull_face_color = $state(`#4caf50`)
365
+
366
+ // Pulsating highlight for selected point and highlighted entries
367
+ const pulse = create_pulse_animation(
368
+ () => selected_entry !== null || highlighted_entries.length > 0,
369
+ { on_tick: render_once },
370
+ )
371
+ let pulse_opacity = $derived(0.3 + 0.4 * pulse.unit)
372
+
373
+ // Merge highlight style with defaults
374
+ const merged_highlight_style = $derived(
375
+ helpers.merge_highlight_style(highlight_style),
376
+ )
377
+
378
+ // Helper to check if entry is highlighted
379
+ const is_highlighted = (entry: ConvexHullEntry): boolean =>
380
+ helpers.is_entry_highlighted(entry, highlighted_entries)
381
+
382
+ // Re-render when important state changes
383
+ $effect(() => {
384
+ // oxfmt-ignore
385
+ void [show_hull_faces, color_mode, color_scale, camera.rotation_x, camera.rotation_y, camera.zoom, camera.center_x, camera.center_y, plot_entries, hull_face_color, hull_face_opacity, hull_face_color_mode, element_colors, text_color, elements] // track reactively
386
+
387
+ render_once()
388
+ })
389
+
390
+ // Visibility toggles are now bindable props
391
+
392
+ // Smart label defaults - hide labels if too many entries
393
+ $effect(() => {
394
+ const total_entries = effective_entries.length
395
+ if (total_entries > label_threshold) {
396
+ show_stable_labels = false
397
+ show_unstable_labels = false
398
+ } else {
399
+ // For smaller datasets, show stable labels by default
400
+ show_stable_labels = true
401
+ show_unstable_labels = false
402
+ }
403
+ })
404
+
405
+ // Function to extract structure data from a convex hull entry
406
+ function extract_structure_from_entry(
407
+ entry: ConvexHullEntry,
408
+ ): AnyStructure | null {
409
+ const orig_entry = entries.find((ent) => ent.entry_id === entry.entry_id)
410
+ return orig_entry?.structure as AnyStructure || null
411
+ }
412
+
413
+ const reset_camera = () => {
414
+ camera.rotation_x = DEFAULTS.convex_hull.quaternary.camera_rotation_x
415
+ camera.rotation_y = DEFAULTS.convex_hull.quaternary.camera_rotation_y
416
+ camera.zoom = DEFAULTS.convex_hull.quaternary.camera_zoom
417
+ camera.center_x = 0
418
+ camera.center_y = 20 // Slight offset to avoid legend overlap
419
+ }
420
+ function reset_all() {
421
+ reset_camera()
422
+ fullscreen = DEFAULTS.convex_hull.quaternary.fullscreen
423
+ info_pane_open = DEFAULTS.convex_hull.quaternary.info_pane_open
424
+ legend_pane_open = DEFAULTS.convex_hull.quaternary.legend_pane_open
425
+ color_mode = DEFAULTS.convex_hull.quaternary.color_mode
426
+ color_scale = DEFAULTS.convex_hull.quaternary.color_scale as D3InterpolateName
427
+ show_stable = DEFAULTS.convex_hull.quaternary.show_stable
428
+ show_unstable = DEFAULTS.convex_hull.quaternary.show_unstable
429
+ show_stable_labels = DEFAULTS.convex_hull.quaternary.show_stable_labels
430
+ show_unstable_labels = DEFAULTS.convex_hull.quaternary.show_unstable_labels
431
+ // Use auto-computed threshold based on entry count instead of static default
432
+ max_hull_dist_show_phases = auto_default_threshold
433
+ max_hull_dist_show_labels =
434
+ DEFAULTS.convex_hull.quaternary.max_hull_dist_show_labels
435
+ show_hull_faces = DEFAULTS.convex_hull.quaternary.show_hull_faces
436
+ hull_face_color = DEFAULTS.convex_hull.quaternary.hull_face_color
437
+ hull_face_opacity = DEFAULTS.convex_hull.quaternary.hull_face_opacity
438
+ hull_face_color_mode = DEFAULTS.convex_hull.quaternary
439
+ .hull_face_color_mode as HullFaceColorMode
440
+ }
441
+
442
+ const handle_keydown = (event: KeyboardEvent) => {
443
+ const target = event.target
444
+ // Skip if focus is on an interactive element that handles Enter natively
445
+ const interactive_selector =
446
+ `input,textarea,select,button,a,[contenteditable="true"],[role="button"],[tabindex]:not([tabindex="-1"])`
447
+ if (
448
+ target instanceof HTMLElement &&
449
+ target.matches(interactive_selector) &&
450
+ target !== canvas
451
+ ) return
452
+
453
+ // Prevent double handling from canvas + wrapper bubbling
454
+ if (event.target !== event.currentTarget && event.currentTarget !== canvas) return
455
+
456
+ // Handle Enter for keyboard accessibility - select hovered entry
457
+ if (event.key === `Enter`) {
458
+ const entry = hover_data?.entry
459
+ if (entry) {
460
+ on_point_click?.(entry)
461
+ if (enable_click_selection) {
462
+ selected_entry = entry
463
+ if (enable_structure_preview) {
464
+ const structure = extract_structure_from_entry(entry)
465
+ if (structure) {
466
+ selected_structure = structure
467
+ modal_place_right = helpers.calculate_modal_side(wrapper)
468
+ modal_open = true
469
+ }
470
+ }
471
+ }
472
+ } else if (modal_open) {
473
+ close_structure_popup()
474
+ }
475
+ return
476
+ }
477
+
478
+ const actions: Record<string, () => void> = {
479
+ r: reset_camera,
480
+ b: () => color_mode = color_mode === `stability` ? `energy` : `stability`,
481
+ s: () => show_stable = !show_stable,
482
+ u: () => show_unstable = !show_unstable,
483
+ h: () => show_hull_faces = !show_hull_faces,
484
+ l: () => show_stable_labels = !show_stable_labels,
485
+ }
486
+ actions[event.key.toLowerCase()]?.()
487
+ }
488
+
489
+ async function handle_file_drop(event: DragEvent): Promise<void> {
490
+ drag_over = false
491
+ const data = await helpers.parse_hull_entries_from_drop(event)
492
+ if (data) on_file_drop?.(data)
493
+ }
494
+
495
+ async function copy_entry_data(
496
+ entry: ConvexHullEntry,
497
+ position: { x: number; y: number },
498
+ ) {
499
+ await helpers.copy_entry_to_clipboard(entry, position, (visible, pos) => {
500
+ copy_feedback.visible = visible
501
+ copy_feedback.position = pos
502
+ })
503
+ }
504
+
505
+ const get_point_color = (entry: ConvexHullEntry): string =>
506
+ helpers.get_point_color_for_entry(
507
+ entry,
508
+ color_mode,
509
+ merged_config.colors,
510
+ energy_color_scale,
511
+ )
512
+
513
+ // Cache energy color scale per frame/setting
514
+ const energy_color_scale = $derived.by(() =>
515
+ helpers.get_energy_color_scale(color_mode, color_scale, plot_entries)
516
+ )
517
+
518
+ // Convex hull statistics - compute internally and expose via bindable prop
519
+ $effect(() => {
520
+ phase_stats = thermo.get_convex_hull_stats(plot_entries, elements, 4)
521
+ })
522
+
523
+ // 3D to 2D projection following Materials Project approach
524
+ function project_3d_point(
525
+ x: number,
526
+ y: number,
527
+ z: number,
528
+ ): { x: number; y: number; depth: number } {
529
+ if (!canvas) return { x: 0, y: 0, depth: 0 }
530
+
531
+ // Center coordinates around tetrahedron/triangle centroid
532
+ let [centered_x, centered_y, centered_z] = [x, y, z]
533
+
534
+ // Tetrahedron centroid: average of vertices (1,0,0), (0.5,√3/2,0), (0.5,√3/6,√6/3), (0,0,0)
535
+ const centroid_x = (1 + 0.5 + 0.5 + 0) / 4 // = 0.5
536
+ const centroid_y = (0 + Math.sqrt(3) / 2 + Math.sqrt(3) / 6 + 0) / 4 // = √3/6
537
+ const centroid_z = (0 + 0 + Math.sqrt(6) / 3 + 0) / 4 // = √6/12
538
+ centered_x = x - centroid_x
539
+ centered_y = y - centroid_y
540
+ centered_z = z - centroid_z
541
+
542
+ // Apply 3D transformations around the centered coordinates
543
+ const cos_x = Math.cos(camera.rotation_x)
544
+ const sin_x = Math.sin(camera.rotation_x)
545
+ const cos_y = Math.cos(camera.rotation_y)
546
+ const sin_y = Math.sin(camera.rotation_y)
547
+
548
+ // Rotate around Y axis first
549
+ const x1 = centered_x * cos_y - centered_z * sin_y
550
+ const z1 = centered_x * sin_y + centered_z * cos_y
551
+
552
+ // Then rotate around X axis
553
+ const y2 = centered_y * cos_x - z1 * sin_x
554
+ const z2 = centered_y * sin_x + z1 * cos_x
555
+
556
+ // Apply perspective projection using cached canvas dimensions for consistency
557
+ const scale = Math.min(canvas_dims.width, canvas_dims.height) * 0.6 * camera.zoom
558
+ const center_x = canvas_dims.width / 2 + camera.center_x
559
+ const center_y = canvas_dims.height / 2 + camera.center_y
560
+
561
+ return {
562
+ x: center_x + x1 * scale,
563
+ y: center_y - y2 * scale, // Flip Y for canvas coordinates
564
+ depth: z2, // For depth sorting
565
+ }
566
+ }
567
+
568
+ function draw_structure_outline(): void {
569
+ if (!ctx || !canvas) return
570
+
571
+ const styles = getComputedStyle(canvas)
572
+ // Match gray dashed structure lines used in 3D
573
+ ctx.strokeStyle = CONVEX_HULL_STYLE.structure_line.color
574
+ ctx.lineWidth = CONVEX_HULL_STYLE.structure_line.line_width
575
+ ctx.setLineDash(CONVEX_HULL_STYLE.structure_line.dash)
576
+
577
+ // Draw tetrahedron edges
578
+ draw_tetrahedron()
579
+
580
+ // Reset dash and stroke for subsequent drawings
581
+ ctx.setLineDash([])
582
+ ctx.strokeStyle = styles.getPropertyValue(`--hull-edge-color`) || `#212121`
583
+ }
584
+
585
+ function draw_tetrahedron(): void {
586
+ if (!ctx) return
587
+
588
+ // Convert vertices to Point3D objects
589
+ const vertices = TETRAHEDRON_VERTICES.map(([x, y, z]) => ({ x, y, z }))
590
+
591
+ // Tetrahedron edges (connecting vertices)
592
+ const edges = [
593
+ [0, 1],
594
+ [0, 2],
595
+ [0, 3], // From vertex 0
596
+ [1, 2],
597
+ [1, 3], // From vertex 1
598
+ [2, 3], // From vertex 2
599
+ ]
600
+
601
+ // Draw edges
602
+ ctx.beginPath()
603
+ for (const [start, end] of edges) {
604
+ const v1 = vertices[start]
605
+ const v2 = vertices[end]
606
+
607
+ const proj1 = project_3d_point(v1.x, v1.y, v1.z)
608
+ const proj2 = project_3d_point(v2.x, v2.y, v2.z)
609
+
610
+ ctx.moveTo(proj1.x, proj1.y)
611
+ ctx.lineTo(proj2.x, proj2.y)
612
+ }
613
+ ctx.stroke()
614
+
615
+ // Corner element labels: place just outside along line towards tetrahedron centroid
616
+ if (elements.length === 4) {
617
+ // Tetrahedron centroid in barycentric space maps to average of vertices
618
+ const centroid = {
619
+ x: (vertices[0].x + vertices[1].x + vertices[2].x + vertices[3].x) / 4,
620
+ y: (vertices[0].y + vertices[1].y + vertices[2].y + vertices[3].y) / 4,
621
+ z: (vertices[0].z + vertices[1].z + vertices[2].z + vertices[3].z) / 4,
622
+ }
623
+
624
+ ctx.fillStyle = text_color
625
+ ctx.font = `bold 18px Arial`
626
+ ctx.textAlign = `center`
627
+ ctx.textBaseline = `middle`
628
+
629
+ const distance = 0.06
630
+ for (let idx = 0; idx < 4; idx++) {
631
+ const vx = vertices[idx]
632
+ // Direction from centroid to vertex
633
+ const dir = {
634
+ x: vx.x - centroid.x,
635
+ y: vx.y - centroid.y,
636
+ z: vx.z - centroid.z,
637
+ }
638
+ const len = Math.hypot(dir.x, dir.y, dir.z) || 1
639
+ const label_pos = {
640
+ x: vx.x + (dir.x / len) * distance,
641
+ y: vx.y + (dir.y / len) * distance,
642
+ z: vx.z + (dir.z / len) * distance,
643
+ }
644
+ const proj = project_3d_point(label_pos.x, label_pos.y, label_pos.z)
645
+ ctx.fillText(elements[idx], proj.x, proj.y)
646
+ }
647
+ }
648
+ }
649
+
650
+ // Draw convex hull faces connecting stable points
651
+ function draw_convex_hull_faces(): void {
652
+ if (!ctx || !show_hull_faces || hull_4d.length === 0) return
653
+
654
+ // Get stable points to determine which hull facets to draw
655
+ const stable_points = plot_entries.filter(helpers.entry_is_stable)
656
+ if (stable_points.length === 0) return
657
+
658
+ // Each tetrahedral facet has 4 triangular faces - we need to draw these
659
+ // Collect all triangular faces with depth for sorting
660
+ type TriangleFace = {
661
+ vertices: [
662
+ { x: number; y: number; depth: number },
663
+ { x: number; y: number; depth: number },
664
+ { x: number; y: number; depth: number },
665
+ ]
666
+ avg_depth: number
667
+ avg_w: number // Average formation energy for coloring
668
+ tet_idx: number // Tetrahedron index for facet_index mode
669
+ centroid_bary: number[] // Barycentric centroid [el0, el1, el2, el3] for dominant_element mode
670
+ }
671
+
672
+ const triangles: TriangleFace[] = []
673
+
674
+ for (let tet_idx = 0; tet_idx < hull_4d.length; tet_idx++) {
675
+ const tet = hull_4d[tet_idx]
676
+ const [p0, p1, p2, p3] = tet.vertices
677
+
678
+ // Convert barycentric coordinates to tetrahedral 3D coordinates
679
+ const tet0 = barycentric_to_tetrahedral([
680
+ p0.x,
681
+ p0.y,
682
+ p0.z,
683
+ 1 - p0.x - p0.y - p0.z,
684
+ ])
685
+ const tet1 = barycentric_to_tetrahedral([
686
+ p1.x,
687
+ p1.y,
688
+ p1.z,
689
+ 1 - p1.x - p1.y - p1.z,
690
+ ])
691
+ const tet2 = barycentric_to_tetrahedral([
692
+ p2.x,
693
+ p2.y,
694
+ p2.z,
695
+ 1 - p2.x - p2.y - p2.z,
696
+ ])
697
+ const tet3 = barycentric_to_tetrahedral([
698
+ p3.x,
699
+ p3.y,
700
+ p3.z,
701
+ 1 - p3.x - p3.y - p3.z,
702
+ ])
703
+
704
+ // Project to 2D screen space
705
+ const proj0 = project_3d_point(tet0.x, tet0.y, tet0.z)
706
+ const proj1 = project_3d_point(tet1.x, tet1.y, tet1.z)
707
+ const proj2 = project_3d_point(tet2.x, tet2.y, tet2.z)
708
+ const proj3 = project_3d_point(tet3.x, tet3.y, tet3.z)
709
+
710
+ // Compute tetrahedron centroid in barycentric coords (for dominant_element mode)
711
+ // All 4 faces share the same tetrahedron, so they get the same color for facet_index
712
+ const tet_centroid_bary = [
713
+ (p0.x + p1.x + p2.x + p3.x) / 4,
714
+ (p0.y + p1.y + p2.y + p3.y) / 4,
715
+ (p0.z + p1.z + p2.z + p3.z) / 4,
716
+ ((1 - p0.x - p0.y - p0.z) + (1 - p1.x - p1.y - p1.z) +
717
+ (1 - p2.x - p2.y - p2.z) + (1 - p3.x - p3.y - p3.z)) / 4,
718
+ ]
719
+
720
+ // Each tetrahedron has 4 triangular faces
721
+ const faces: [typeof proj0, typeof proj1, typeof proj2, number][] = [
722
+ [proj0, proj1, proj2, (p0.w + p1.w + p2.w) / 3],
723
+ [proj0, proj1, proj3, (p0.w + p1.w + p3.w) / 3],
724
+ [proj0, proj2, proj3, (p0.w + p2.w + p3.w) / 3],
725
+ [proj1, proj2, proj3, (p1.w + p2.w + p3.w) / 3],
726
+ ]
727
+
728
+ for (const [v0, v1, v2, avg_w] of faces) {
729
+ triangles.push({
730
+ vertices: [v0, v1, v2],
731
+ avg_depth: (v0.depth + v1.depth + v2.depth) / 3,
732
+ avg_w,
733
+ tet_idx,
734
+ centroid_bary: tet_centroid_bary,
735
+ })
736
+ }
737
+ }
738
+
739
+ // Sort by depth (back to front)
740
+ triangles.sort((a, b) => a.avg_depth - b.avg_depth)
741
+
742
+ // Lazy computation for uniform mode: normalize alpha by formation energy
743
+ let norm_alpha: ((w: number) => number) | null = null
744
+ if (hull_face_color_mode === `uniform`) {
745
+ norm_alpha = (energy: number) => {
746
+ const t = Math.max(
747
+ 0,
748
+ Math.min(1, (0 - energy) / Math.max(1e-6, 0 - formation_energy_min)),
749
+ )
750
+ return t * hull_face_opacity
751
+ }
752
+ }
753
+
754
+ // Lazy computation for formation_energy mode
755
+ let energy_face_scale: ((val: number) => string) | null = null
756
+ let min_w = 0
757
+ if (hull_face_color_mode === `formation_energy`) {
758
+ const all_avg_w = triangles.map((tri) => tri.avg_w)
759
+ min_w = Math.min(...all_avg_w)
760
+ energy_face_scale = helpers.get_energy_color_scale(
761
+ `energy`,
762
+ color_scale,
763
+ all_avg_w.map((energy) => ({ e_above_hull: energy - min_w })), // Normalize to 0-based
764
+ )
765
+ }
766
+
767
+ // Helper to get face color based on mode
768
+ const get_face_color = (tri: TriangleFace): string => {
769
+ if (hull_face_color_mode === `uniform`) {
770
+ return hull_face_color
771
+ }
772
+ if (hull_face_color_mode === `formation_energy`) {
773
+ return energy_face_scale?.(tri.avg_w - min_w) ?? hull_face_color
774
+ }
775
+ if (hull_face_color_mode === `dominant_element`) {
776
+ // Find element with highest fraction
777
+ const max_idx = tri.centroid_bary.indexOf(Math.max(...tri.centroid_bary))
778
+ const el = elements[max_idx]
779
+ return element_colors[el] ?? `#888888`
780
+ }
781
+ if (hull_face_color_mode === `facet_index`) {
782
+ return PLOT_COLORS[tri.tet_idx % PLOT_COLORS.length]
783
+ }
784
+ return hull_face_color
785
+ }
786
+
787
+ // Draw each triangle
788
+ for (const tri of triangles) {
789
+ const [v0, v1, v2] = tri.vertices
790
+ // Uniform mode uses variable opacity; other modes use fixed opacity
791
+ const alpha = hull_face_color_mode === `uniform`
792
+ ? (norm_alpha?.(tri.avg_w) ?? hull_face_opacity)
793
+ : hull_face_opacity
794
+ const face_color = get_face_color(tri)
795
+
796
+ ctx.save()
797
+ ctx.beginPath()
798
+ ctx.moveTo(v0.x, v0.y)
799
+ ctx.lineTo(v1.x, v1.y)
800
+ ctx.lineTo(v2.x, v2.y)
801
+ ctx.closePath()
802
+
803
+ ctx.fillStyle = add_alpha(face_color, alpha)
804
+ ctx.fill()
805
+
806
+ // Edge lines more pronounced with higher opacity
807
+ ctx.strokeStyle = add_alpha(face_color, Math.min(0.4, alpha * 4))
808
+ ctx.lineWidth = 1
809
+ ctx.stroke()
810
+ ctx.restore()
811
+ }
812
+ }
813
+
814
+ function draw_data_points(): void {
815
+ if (!ctx || sorted_points_cache.length === 0) return
816
+
817
+ for (const { entry, projected } of sorted_points_cache) {
818
+ const is_stable = helpers.entry_is_stable(entry)
819
+ const is_entry_highlighted = is_highlighted(entry)
820
+ const color = get_point_color(entry)
821
+ const size = (entry.size || (is_stable ? 6 : 4)) * canvas_dims.scale
822
+ const marker = entry.marker || `circle`
823
+
824
+ // Shadow
825
+ const shadow_offset = Math.abs(entry.z) * 2 * canvas_dims.scale
826
+ ctx.fillStyle = `rgba(0, 0, 0, 0.2)`
827
+ const shadow_path = helpers.create_marker_path(size * 0.8, marker)
828
+ ctx.save()
829
+ ctx.translate(projected.x + shadow_offset, projected.y + shadow_offset)
830
+ ctx.fill(shadow_path)
831
+ ctx.restore()
832
+
833
+ // Highlights
834
+ if (selected_entry && entry.entry_id === selected_entry.entry_id) {
835
+ helpers.draw_selection_highlight(
836
+ ctx,
837
+ projected,
838
+ size,
839
+ canvas_dims.scale,
840
+ pulse.time,
841
+ pulse_opacity,
842
+ )
843
+ }
844
+ if (is_entry_highlighted) {
845
+ helpers.draw_highlight_effect(
846
+ ctx,
847
+ projected,
848
+ size,
849
+ canvas_dims.scale,
850
+ pulse.time,
851
+ merged_highlight_style,
852
+ )
853
+ }
854
+
855
+ // Main point with marker symbol
856
+ ctx.fillStyle =
857
+ is_entry_highlighted && merged_highlight_style.effect === `color`
858
+ ? merged_highlight_style.color
859
+ : color
860
+ ctx.strokeStyle = is_stable ? `#ffffff` : `#000000`
861
+ ctx.lineWidth = 0.5 * canvas_dims.scale
862
+ const marker_path = helpers.create_marker_path(size, marker)
863
+ ctx.save()
864
+ ctx.translate(projected.x, projected.y)
865
+ ctx.fill(marker_path)
866
+ ctx.stroke(marker_path)
867
+ ctx.restore()
868
+ }
869
+
870
+ if (!merged_config.show_labels) return
871
+
872
+ const label_entries = helpers.get_composition_label_entries(
873
+ sorted_points_cache
874
+ .map(({ entry }) => entry)
875
+ .filter((entry) => {
876
+ if (entry.is_element) return false
877
+ const is_stable = helpers.entry_is_stable(entry)
878
+ return (is_stable && show_stable_labels) ||
879
+ (!is_stable && show_unstable_labels &&
880
+ (entry.e_above_hull ?? 0) <= max_hull_dist_show_labels)
881
+ }),
882
+ )
883
+
884
+ ctx.fillStyle = text_color
885
+ ctx.font = `${Math.round(12 * canvas_dims.scale)}px Arial`
886
+ ctx.textAlign = `center`
887
+ ctx.textBaseline = `middle`
888
+
889
+ for (const entry of label_entries) {
890
+ const is_stable = helpers.entry_is_stable(entry)
891
+ const size = (entry.size || (is_stable ? 6 : 4)) * canvas_dims.scale
892
+ const projected = project_3d_point(entry.x, entry.y, entry.z)
893
+ const label = helpers.get_entry_label(entry, elements)
894
+ ctx.fillText(label, projected.x, projected.y + size + 6 * canvas_dims.scale)
895
+ }
896
+ }
897
+
898
+ function render_frame(): void {
899
+ if (!ctx || !canvas) return
900
+
901
+ // Use CSS dimensions for rendering (already scaled by DPR in context)
902
+ const display_width = canvas.clientWidth || 600
903
+ const display_height = canvas.clientHeight || 600
904
+
905
+ ctx.clearRect(0, 0, display_width, display_height) // Clear canvas
906
+
907
+ ctx.fillStyle = `transparent` // Set background - use transparent to inherit from container
908
+ ctx.fillRect(0, 0, display_width, display_height)
909
+
910
+ if (elements.length !== 4) {
911
+ if (elements.length > 0) {
912
+ ctx.fillStyle = text_color
913
+ ctx.font = `16px Arial`
914
+ ctx.textAlign = `center`
915
+ ctx.textBaseline = `middle`
916
+ ctx.fillText(
917
+ `Quaternary convex hull requires exactly 4 elements (got ${elements.length})`,
918
+ display_width / 2,
919
+ display_height / 2,
920
+ )
921
+ }
922
+ return
923
+ }
924
+
925
+ draw_structure_outline() // Draw tetrahedron outline
926
+
927
+ draw_convex_hull_faces() // Draw convex hull faces (before points so they appear behind)
928
+
929
+ draw_data_points() // Draw data points (on top)
930
+ }
931
+
932
+ function handle_mouse_down(event: MouseEvent) {
933
+ is_dragging = true
934
+ drag_started = false
935
+ hover_data = null
936
+ on_point_hover?.(null)
937
+ last_mouse = { x: event.clientX, y: event.clientY }
938
+ }
939
+
940
+ const handle_mouse_move = (event: MouseEvent) => {
941
+ if (!is_dragging) return
942
+ const [dx, dy] = [event.clientX - last_mouse.x, event.clientY - last_mouse.y]
943
+
944
+ // Mark as drag if any movement occurred
945
+ if (dx !== 0 || dy !== 0) drag_started = true
946
+
947
+ // With Cmd/Ctrl held: pan the view instead of rotating
948
+ if (event.metaKey || event.ctrlKey) {
949
+ camera.center_x += dx
950
+ camera.center_y += dy
951
+ } else {
952
+ camera.rotation_y += dx * 0.005
953
+ camera.rotation_x = Math.max(
954
+ -Math.PI / 3,
955
+ Math.min(Math.PI / 3, camera.rotation_x - dy * 0.005),
956
+ )
957
+ }
958
+ last_mouse = { x: event.clientX, y: event.clientY }
959
+ }
960
+
961
+ const handle_wheel = (event: WheelEvent) => {
962
+ event.preventDefault()
963
+ camera.zoom = Math.max(
964
+ 1.0,
965
+ Math.min(15, camera.zoom * (event.deltaY > 0 ? 0.98 : 1.02)),
966
+ )
967
+ }
968
+
969
+ const handle_hover = (event: MouseEvent) => {
970
+ if (is_dragging) return
971
+ const entry = find_entry_at_mouse(event)
972
+ hover_data = entry
973
+ ? { entry, position: { x: event.clientX, y: event.clientY } }
974
+ : null
975
+ on_point_hover?.(hover_data)
976
+ }
977
+
978
+ const find_entry_at_mouse = (event: MouseEvent): ConvexHullEntry | null =>
979
+ helpers.find_hull_entry_at_mouse(
980
+ canvas,
981
+ event,
982
+ visible_entries,
983
+ (x: number, y: number, z: number) => {
984
+ const projected = project_3d_point(x, y, z)
985
+ return { x: projected.x, y: projected.y }
986
+ },
987
+ )
988
+
989
+ const handle_click = (event: MouseEvent) => {
990
+ event.stopPropagation()
991
+
992
+ // Check if this was a drag operation (any mouse movement during drag)
993
+ const was_drag = drag_started
994
+ drag_started = false // Reset for next interaction
995
+ if (was_drag) return // Don't trigger click if this was a drag
996
+
997
+ const entry = find_entry_at_mouse(event)
998
+ if (entry) {
999
+ on_point_click?.(entry)
1000
+ if (enable_click_selection) {
1001
+ selected_entry = entry
1002
+ if (enable_structure_preview) {
1003
+ const structure = extract_structure_from_entry(entry)
1004
+ if (structure) {
1005
+ selected_structure = structure
1006
+ modal_place_right = helpers.calculate_modal_side(wrapper)
1007
+ modal_open = true
1008
+ }
1009
+ }
1010
+ }
1011
+ } else if (modal_open) close_structure_popup()
1012
+ }
1013
+
1014
+ function close_structure_popup() {
1015
+ modal_open = false
1016
+ selected_structure = null
1017
+ selected_entry = null
1018
+ }
1019
+
1020
+ const handle_double_click = (event: MouseEvent) => {
1021
+ const entry = find_entry_at_mouse(event)
1022
+ if (entry) {
1023
+ copy_entry_data(entry, {
1024
+ x: event.clientX,
1025
+ y: event.clientY,
1026
+ })
1027
+ }
1028
+ }
1029
+
1030
+ function render_once() {
1031
+ if (!frame_id) {
1032
+ frame_id = requestAnimationFrame(() => {
1033
+ render_frame()
1034
+ frame_id = 0
1035
+ })
1036
+ }
1037
+ }
1038
+
1039
+ function update_canvas_size() {
1040
+ if (!canvas) return
1041
+ const dpr = globalThis.devicePixelRatio || 1
1042
+ const container = canvas.parentElement
1043
+ const rect = container?.getBoundingClientRect()
1044
+ const [width, height] = rect ? [rect.width, rect.height] : [400, 400]
1045
+
1046
+ const new_width = Math.max(0, Math.round(width * dpr))
1047
+ const new_height = Math.max(0, Math.round(height * dpr))
1048
+ canvas_dims = { width, height, scale: Math.min(width, height) / 600 }
1049
+
1050
+ if (!ctx || canvas.width !== new_width || canvas.height !== new_height) {
1051
+ canvas.width = new_width
1052
+ canvas.height = new_height
1053
+ ctx = canvas.getContext(`2d`)
1054
+ if (ctx) {
1055
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
1056
+ ctx.imageSmoothingEnabled = true
1057
+ ctx.imageSmoothingQuality = `high`
1058
+ }
1059
+ }
1060
+ render_once()
1061
+ }
1062
+
1063
+ $effect(() => {
1064
+ if (!canvas) return
1065
+
1066
+ // Initial setup
1067
+ update_canvas_size()
1068
+
1069
+ // Watch for resize events - only update canvas, don't reset camera
1070
+ const resize_observer = new ResizeObserver(update_canvas_size)
1071
+
1072
+ const container = canvas.parentElement
1073
+ if (container) resize_observer.observe(container)
1074
+
1075
+ return () => { // Cleanup on unmount
1076
+ if (frame_id) cancelAnimationFrame(frame_id)
1077
+ resize_observer.disconnect()
1078
+ }
1079
+ })
1080
+
1081
+ // Fullscreen handling with camera reset
1082
+ let was_fullscreen = $state(fullscreen)
1083
+ $effect(() => {
1084
+ setup_fullscreen_effect(fullscreen, wrapper, (entering_fullscreen) => {
1085
+ if (entering_fullscreen !== was_fullscreen) {
1086
+ camera.center_x = 0
1087
+ camera.center_y = 20
1088
+ was_fullscreen = entering_fullscreen
1089
+ }
1090
+ })
1091
+ set_fullscreen_bg(wrapper, fullscreen, `--hull-4d-bg-fullscreen`)
1092
+ })
1093
+
1094
+ // Performance: Cache canvas dimensions and pre-compute sorted point projections
1095
+ let canvas_dims = $state({ width: 600, height: 600, scale: 1 })
1096
+ const formation_energy_min = $derived.by(() => {
1097
+ let min_energy = 0
1098
+ for (const entry of all_enriched_entries) {
1099
+ min_energy = Math.min(min_energy, entry.e_form_per_atom ?? 0)
1100
+ }
1101
+ return min_energy
1102
+ })
1103
+ const sorted_points_cache = $derived.by(() => {
1104
+ if (!canvas || visible_entries.length === 0) return []
1105
+ return visible_entries
1106
+ .map((entry) => ({
1107
+ entry,
1108
+ projected: project_3d_point(entry.x, entry.y, entry.z),
1109
+ }))
1110
+ .sort((a, b) => a.projected.depth - b.projected.depth)
1111
+ })
1112
+
1113
+ let style = $derived(
1114
+ `--hull-stable-color:${merged_config.colors?.stable || `#0072B2`};
1115
+ --hull-unstable-color:${merged_config.colors?.unstable || `#E69F00`};
1116
+ --hull-edge-color:${merged_config.colors?.edge || `var(--text-color, #212121)`};
1117
+ --hull-text-color:${
1118
+ merged_config.colors?.annotation || `var(--text-color, #212121)`
1119
+ }`,
1120
+ )
1121
+ </script>
1122
+
1123
+ <svelte:document
1124
+ onfullscreenchange={() => {
1125
+ fullscreen = Boolean(document.fullscreenElement)
1126
+ }}
1127
+ onmousemove={handle_mouse_move}
1128
+ onmouseup={() => [is_dragging, drag_started] = [false, false]}
1129
+ />
1130
+
1131
+ <div
1132
+ {...rest}
1133
+ class="convex-hull-4d {rest.class ?? ``}"
1134
+ class:dragover={drag_over}
1135
+ style={`${style}; ${rest.style ?? ``}`}
1136
+ data-has-selection={selected_entry !== null}
1137
+ data-has-hover={hover_data !== null}
1138
+ data-is-dragging={is_dragging}
1139
+ data-rotation-x={camera.rotation_x.toFixed(4)}
1140
+ data-rotation-y={camera.rotation_y.toFixed(4)}
1141
+ bind:this={wrapper}
1142
+ role="application"
1143
+ tabindex="-1"
1144
+ onkeydown={handle_keydown}
1145
+ ondrop={handle_file_drop}
1146
+ ondragover={(event) => {
1147
+ event.preventDefault()
1148
+ drag_over = true
1149
+ }}
1150
+ ondragleave={(event) => {
1151
+ event.preventDefault()
1152
+ drag_over = false
1153
+ }}
1154
+ aria-label="Convex hull visualization"
1155
+ >
1156
+ {@render children?.({
1157
+ stable_entries,
1158
+ unstable_entries,
1159
+ highlighted_entries,
1160
+ selected_entry,
1161
+ })}
1162
+ <h3 style="position: absolute; left: 1em; top: 1ex; margin: 0">
1163
+ {@html sanitize_html(merged_controls.title || phase_stats?.chemical_system || ``)}
1164
+ </h3>
1165
+
1166
+ <canvas
1167
+ bind:this={canvas}
1168
+ tabindex="0"
1169
+ aria-label={merged_controls.title || phase_stats?.chemical_system || `4D Convex Hull`}
1170
+ onmousedown={handle_mouse_down}
1171
+ onmousemove={handle_hover}
1172
+ onclick={handle_click}
1173
+ onkeydown={handle_keydown}
1174
+ ondblclick={handle_double_click}
1175
+ onwheel={handle_wheel}
1176
+ ></canvas>
1177
+
1178
+ {#if entries.length === 0}
1179
+ <Spinner
1180
+ text="Loading data..."
1181
+ style="position: absolute; inset: 0; display: flex; align-items: center; justify-content: center"
1182
+ />
1183
+ {/if}
1184
+
1185
+ <!-- Energy above hull Color Bar -->
1186
+ {#if color_mode === `energy` && plot_entries.length > 0}
1187
+ {@const hull_distances = plot_entries
1188
+ .map((entry) => entry.e_above_hull)
1189
+ .filter((val): val is number => typeof val === `number`)}
1190
+ {@const min_energy = hull_distances.length > 0 ? Math.min(...hull_distances) : 0}
1191
+ {@const max_energy = hull_distances.length > 0 ? Math.max(...hull_distances, 0.1) : 0.1}
1192
+ <ColorBar
1193
+ title="Energy above hull (eV/atom)"
1194
+ range={[min_energy, max_energy]}
1195
+ {color_scale}
1196
+ wrapper_style="position: absolute; bottom: 2em; left: 1em; width: 200px;"
1197
+ bar_style="height: 12px;"
1198
+ title_style="margin-bottom: 4px;"
1199
+ />
1200
+ {/if}
1201
+
1202
+ <!-- Control buttons (top-right corner like Structure.svelte) -->
1203
+ {#if controls_config.mode !== `never`}
1204
+ <section class="control-buttons {controls_config.class}">
1205
+ {#if controls_config.visible(`reset`)}
1206
+ <button
1207
+ type="button"
1208
+ onclick={reset_all}
1209
+ title="Reset camera view (R key)"
1210
+ class="reset-camera-btn"
1211
+ >
1212
+ <Icon icon="Reset" />
1213
+ </button>
1214
+ {/if}
1215
+
1216
+ {#if enable_info_pane && phase_stats && controls_config.visible(`info-pane`)}
1217
+ <ConvexHullInfoPane
1218
+ bind:pane_open={info_pane_open}
1219
+ {phase_stats}
1220
+ {stable_entries}
1221
+ {unstable_entries}
1222
+ {show_stable}
1223
+ {show_unstable}
1224
+ {max_hull_dist_show_phases}
1225
+ {max_hull_dist_show_labels}
1226
+ {label_threshold}
1227
+ toggle_props={{ class: `info-btn` }}
1228
+ />
1229
+ {/if}
1230
+
1231
+ {#if enable_fullscreen && controls_config.visible(`fullscreen`)}
1232
+ <button
1233
+ type="button"
1234
+ onclick={() => toggle_fullscreen(wrapper)}
1235
+ title="{fullscreen ? `Exit` : `Enter`} fullscreen"
1236
+ class="fullscreen-btn"
1237
+ >
1238
+ <Icon icon="{fullscreen ? `Exit` : ``}Fullscreen" />
1239
+ </button>
1240
+ {/if}
1241
+
1242
+ <!-- Legend controls pane -->
1243
+ {#if controls_config.visible(`controls`)}
1244
+ <ConvexHullControls
1245
+ bind:controls_open={legend_pane_open}
1246
+ bind:color_mode
1247
+ bind:color_scale
1248
+ bind:show_stable
1249
+ bind:show_unstable
1250
+ bind:show_stable_labels
1251
+ bind:show_unstable_labels
1252
+ bind:max_hull_dist_show_phases
1253
+ bind:max_hull_dist_show_labels
1254
+ {max_hull_dist_in_data}
1255
+ {stable_entries}
1256
+ {unstable_entries}
1257
+ {camera}
1258
+ {merged_controls}
1259
+ toggle_props={{ class: `legend-controls-btn` }}
1260
+ {show_hull_faces}
1261
+ on_hull_faces_change={(value: boolean) => show_hull_faces = value}
1262
+ {hull_face_color}
1263
+ on_hull_face_color_change={(value: string) => hull_face_color = value}
1264
+ {hull_face_opacity}
1265
+ on_hull_face_opacity_change={(value: number) => hull_face_opacity = value}
1266
+ {hull_face_color_mode}
1267
+ on_hull_face_color_mode_change={(value: HullFaceColorMode) =>
1268
+ hull_face_color_mode = value}
1269
+ bind:energy_source_mode
1270
+ {has_precomputed_e_form}
1271
+ {can_compute_e_form}
1272
+ {has_precomputed_hull}
1273
+ {can_compute_hull}
1274
+ />
1275
+ {/if}
1276
+ </section>
1277
+ {/if}
1278
+
1279
+ {#if has_temp_data && temperature !== undefined}
1280
+ <TemperatureSlider {available_temperatures} bind:temperature />
1281
+ {/if}
1282
+
1283
+ {#if gas_analysis.has_gas_dependent_elements && merged_gas_config}
1284
+ <GasPressureControls
1285
+ config={merged_gas_config}
1286
+ bind:pressures={gas_pressures}
1287
+ temperature={temperature ?? 300}
1288
+ />
1289
+ {/if}
1290
+
1291
+ <!-- Hover tooltip -->
1292
+ {#if hover_data}
1293
+ {@const { entry, position } = hover_data}
1294
+ {@const entry_highlight = is_highlighted(entry) ? merged_highlight_style : undefined}
1295
+ {@const tooltip_style =
1296
+ `z-index: ${CONVEX_HULL_STYLE.z_index.tooltip}; backdrop-filter: blur(4px);
1297
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);`}
1298
+ <PlotTooltip
1299
+ x={position.x}
1300
+ y={position.y}
1301
+ offset={{ x: 10, y: -10 }}
1302
+ bg_color={get_point_color(entry)}
1303
+ fixed
1304
+ style={tooltip_style}
1305
+ >
1306
+ <ConvexHullTooltip
1307
+ {entry}
1308
+ {polymorph_stats_map}
1309
+ highlight_style={entry_highlight}
1310
+ {tooltip}
1311
+ />
1312
+ </PlotTooltip>
1313
+ {/if}
1314
+
1315
+ <!-- Copy-to-clipboard feedback (double-click on point) -->
1316
+ <ClickFeedback bind:visible={copy_feedback.visible} position={copy_feedback.position} />
1317
+
1318
+ <!-- Drag over overlay -->
1319
+ <DragOverlay visible={drag_over} />
1320
+
1321
+ {#if modal_open && selected_structure}
1322
+ <StructurePopup
1323
+ structure={selected_structure}
1324
+ place_right={modal_place_right}
1325
+ stats={{
1326
+ id: selected_entry?.entry_id,
1327
+ e_above_hull: selected_entry?.e_above_hull,
1328
+ e_form: selected_entry?.e_form_per_atom,
1329
+ }}
1330
+ onclose={close_structure_popup}
1331
+ />
1332
+ {/if}
1333
+ </div>
1334
+
1335
+ <style>
1336
+ .convex-hull-4d {
1337
+ position: relative;
1338
+ container-type: size; /* enable cqh/cqw for responsive sizing */
1339
+ width: 100%;
1340
+ height: var(--hull-height, 500px);
1341
+ background: var(--hull-4d-bg, var(--hull-bg));
1342
+ border-radius: var(--hull-border-radius, var(--border-radius, 3pt));
1343
+ }
1344
+ .convex-hull-4d:fullscreen {
1345
+ border-radius: 0;
1346
+ background: var(--hull-4d-bg-fullscreen, var(--hull-4d-bg, var(--hull-bg)));
1347
+ overflow: hidden;
1348
+ }
1349
+ .convex-hull-4d.dragover {
1350
+ border: 2px dashed var(--accent-color, #1976d2);
1351
+ }
1352
+ canvas {
1353
+ width: 100%;
1354
+ height: 100%;
1355
+ cursor: grab;
1356
+ }
1357
+ canvas:active {
1358
+ cursor: grabbing;
1359
+ }
1360
+ .control-buttons {
1361
+ position: absolute;
1362
+ top: 1ex;
1363
+ right: 1ex;
1364
+ display: flex;
1365
+ gap: 8px;
1366
+ transition: opacity 0.2s ease-in-out;
1367
+ }
1368
+ .control-buttons.hover-visible {
1369
+ opacity: 0;
1370
+ pointer-events: none;
1371
+ }
1372
+ .convex-hull-4d:hover .control-buttons.hover-visible,
1373
+ .convex-hull-4d:focus-within .control-buttons.hover-visible {
1374
+ opacity: 1;
1375
+ pointer-events: auto;
1376
+ }
1377
+ .control-buttons.always-visible {
1378
+ opacity: 1;
1379
+ pointer-events: auto;
1380
+ }
1381
+ .control-buttons :global(.draggable-pane) {
1382
+ z-index: 1001 !important;
1383
+ }
1384
+ .control-buttons :global(button) {
1385
+ background: transparent;
1386
+ border: none;
1387
+ padding: 4px;
1388
+ cursor: pointer;
1389
+ border-radius: 3px;
1390
+ color: var(--text-color, currentColor);
1391
+ transition: background-color 0.2s;
1392
+ display: flex;
1393
+ font-size: clamp(0.85em, 2cqmin, 1.3em);
1394
+ }
1395
+ .control-buttons :global(button):hover {
1396
+ background-color: color-mix(in srgb, currentColor 8%, transparent);
1397
+ }
1398
+ </style>