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
@@ -1,1381 +0,0 @@
1
- // Helper utilities for band structure and DOS data processing
2
- import { SUBSCRIPT_MAP } from '$lib/labels'
3
- import { centered_frac, euclidean_dist } from '$lib/math'
4
- import type { Matrix3x3, Vec2, Vec3 } from '$lib/math'
5
- import type { AxisConfig } from '$lib/plot/types'
6
- import type * as types from './types'
7
- import type { RibbonConfig } from './types'
8
-
9
- const is_subscript_key = (key: string): key is keyof typeof SUBSCRIPT_MAP =>
10
- key in SUBSCRIPT_MAP
11
-
12
- // Check if range is a valid [min, max] tuple (strict 2-element array of finite numbers)
13
- export const is_valid_range = (range: unknown): range is Vec2 =>
14
- Array.isArray(range) &&
15
- range.length === 2 &&
16
- Number.isFinite(range[0]) &&
17
- Number.isFinite(range[1])
18
-
19
- // Check if two ranges are approximately equal (within tolerance)
20
- // Returns false if either range is invalid (null, undefined, or fails is_valid_range)
21
- // Negative tol is clamped to 0; tol=0 checks exact equality
22
- export const ranges_equal = (
23
- a: Vec2 | undefined | null,
24
- b: Vec2 | undefined | null,
25
- tol = 0.001,
26
- ): boolean => {
27
- const safe_tol = Math.max(0, tol)
28
- return (
29
- is_valid_range(a) &&
30
- is_valid_range(b) &&
31
- Math.abs(a[0] - b[0]) <= safe_tol &&
32
- Math.abs(a[1] - b[1]) <= safe_tol
33
- )
34
- }
35
-
36
- export const axis_with_range = (
37
- axis: AxisConfig | undefined,
38
- range: Vec2 | undefined,
39
- label?: string,
40
- ): AxisConfig => ({
41
- ...axis,
42
- ...(label !== undefined && { label }),
43
- ...(is_valid_range(range) && { range }),
44
- })
45
-
46
- // Detect which plot triggered a zoom change and return the new synced range.
47
- // Returns null to reset to shared range, undefined for no change, or Vec2 for new zoom.
48
- export function detect_zoom_change(
49
- bands_range: unknown,
50
- dos_range: unknown,
51
- shared_range: Vec2,
52
- current_synced: Vec2 | null,
53
- dos_enabled = true,
54
- ): Vec2 | null | undefined {
55
- const bands_valid = is_valid_range(bands_range)
56
- const dos_valid = dos_enabled && is_valid_range(dos_range)
57
-
58
- // Reset if either becomes invalid (auto-range reset) or returns to shared range
59
- if (current_synced !== null) {
60
- const bands_at_shared = bands_valid && ranges_equal(bands_range, shared_range)
61
- const dos_at_shared = dos_valid && ranges_equal(dos_range, shared_range)
62
- if (bands_at_shared || dos_at_shared || !bands_valid || (dos_enabled && !dos_valid)) {
63
- return null
64
- }
65
- }
66
-
67
- // Check for new zoom from either plot
68
- const bands_is_new =
69
- bands_valid &&
70
- !ranges_equal(bands_range, shared_range) &&
71
- !ranges_equal(bands_range, current_synced)
72
- const dos_is_new =
73
- dos_valid &&
74
- !ranges_equal(dos_range, shared_range) &&
75
- !ranges_equal(dos_range, current_synced)
76
-
77
- if (bands_is_new && !dos_is_new) return bands_range
78
- if (dos_is_new && !bands_is_new) return dos_range
79
- return undefined // no change
80
- }
81
-
82
- // Physical constants for unit conversions (SI units)
83
- const PLANCK = 6.62607015e-34 // J⋅s
84
- const EV_TO_J = 1.602176634e-19 // J
85
- const C_LIGHT = 299792458 // m/s
86
- const THz_TO_HZ = 1e12
87
- const THz_TO_EV = (PLANCK * THz_TO_HZ) / EV_TO_J
88
- const THz_TO_MEV = THz_TO_EV * 1000
89
- const THz_TO_HA = THz_TO_EV / 27.211386245988 // Hartree
90
- const THz_TO_CM = THz_TO_HZ / (C_LIGHT * 100) // cm^-1 (c in cm/s)
91
-
92
- // Band structure constants
93
- export const IMAGINARY_MODE_NOISE_THRESHOLD = 0.005 // Clamp negatives < 0.5% as noise
94
-
95
- // Convert symmetry point symbols to pretty-printed versions.
96
- // Handles Greek letters (both plain and LaTeX backslash-prefixed) and subscripts.
97
- export function pretty_sym_point(symbol: string): string {
98
- if (!symbol) return ``
99
-
100
- // Remove underscores (htmlify maps S0 → S<sub>0</sub> but leaves S_0 as is)
101
- // Replace common symmetry point names with Greek letters
102
- // Handle both plain names (GAMMA) and LaTeX notation (\Gamma) from pymatgen
103
- // Handle subscripts: convert S0 to S₀, K1 to K₁, Γ1 to Γ₁, etc.
104
- // Use \p{L} to match any Unicode letter (not just ASCII A-Z)
105
- return symbol
106
- .replace(/_/g, ``)
107
- .replace(/\\?GAMMA/gi, `Γ`)
108
- .replace(/\\?DELTA/gi, `Δ`)
109
- .replace(/\\?SIGMA/gi, `Σ`)
110
- .replace(/\\?LAMBDA/gi, `Λ`)
111
- .replace(
112
- /(\p{L})(\d+)/gu,
113
- (_, letter, num) =>
114
- letter +
115
- num
116
- .split(``)
117
- .map((digit: string) => (is_subscript_key(digit) ? SUBSCRIPT_MAP[digit] : digit))
118
- .join(``),
119
- )
120
- }
121
-
122
- // Create segment key from start and end labels
123
- export const get_segment_key = (start_label?: string, end_label?: string) =>
124
- `${start_label ?? `null`}_${end_label ?? `null`}`
125
-
126
- // Get ordered segment keys from a band structure, preserving physical path order.
127
- export const get_ordered_segments = (
128
- band_struct: types.BaseBandStructure | null,
129
- segments: Set<string>,
130
- ) => {
131
- if (!band_struct) return Array.from(segments)
132
-
133
- const ordered = band_struct.branches.map((branch) =>
134
- get_segment_key(
135
- band_struct.qpoints[branch.start_index]?.label ?? undefined,
136
- band_struct.qpoints[branch.end_index]?.label ?? undefined,
137
- ),
138
- )
139
- const remaining = Array.from(segments).filter((seg) => !ordered.includes(seg))
140
- return [...ordered, ...remaining]
141
- }
142
-
143
- // Scale segment distances to a target x-axis range [x_start, x_end].
144
- // Used by both band line series and fat band ribbons for consistent x-axis positioning.
145
- export function scale_segment_distances(
146
- segment_distances: number[],
147
- x_start: number,
148
- x_end: number,
149
- ): number[] {
150
- if (segment_distances.length === 0) return []
151
-
152
- const dist_min = segment_distances[0]
153
- const dist_range = (segment_distances.at(-1) ?? dist_min) - dist_min
154
-
155
- if (dist_range === 0) {
156
- // All points at same distance - place at midpoint
157
- return segment_distances.map(() => (x_start + x_end) / 2)
158
- }
159
-
160
- return segment_distances.map(
161
- (dist) => x_start + ((dist - dist_min) / dist_range) * (x_end - x_start),
162
- )
163
- }
164
-
165
- // Get ribbon config for a specific band structure label.
166
- // Supports both single global config (with primitive keys like opacity, max_width, scale, color)
167
- // and per-structure config (keyed by structure label).
168
- // Distinguishes between a global config and a per-structure config by checking if any
169
- // primitive-typed keys (opacity, max_width, scale, color) exist at the top level.
170
- export function get_ribbon_config(
171
- ribbon_config: RibbonConfig | Record<string, RibbonConfig>,
172
- label: string,
173
- ): RibbonConfig {
174
- const defaults: RibbonConfig = { opacity: 0.3, max_width: 6, scale: 1 }
175
- const config_record = ribbon_config as Record<string, unknown>
176
-
177
- // Check for primitive config values (not objects) to distinguish single vs per-structure config
178
- const has_primitive = [`opacity`, `max_width`, `scale`, `color`].some((key) => {
179
- const value = config_record[key]
180
- return value !== undefined && typeof value !== `object`
181
- })
182
-
183
- if (has_primitive) {
184
- // Single global config with primitive values - apply to all structures
185
- return { ...defaults, ...ribbon_config }
186
- }
187
-
188
- // Otherwise, treat as Record<string, RibbonConfig> and look up by label
189
- // Empty label skips lookup and uses defaults only
190
- const label_config = label ? config_record[label] : undefined
191
- return {
192
- ...defaults,
193
- ...(label_config && typeof label_config === `object` ? label_config : {}),
194
- }
195
- }
196
-
197
- // Extract tick positions and labels for a band structure plot.
198
- export function get_band_xaxis_ticks(
199
- band_struct: types.BaseBandStructure,
200
- branches: string[] | Set<string> = [],
201
- ): [number[], string[]] {
202
- const ticks_x_pos: number[] = []
203
- const tick_labels: string[] = []
204
- let prev_label = band_struct.qpoints[0]?.label || null
205
- let prev_branch = band_struct.branches[0]?.name || null
206
-
207
- // Convert branches to Set for consistent handling
208
- const branches_set = Array.isArray(branches) ? new Set(branches) : branches
209
-
210
- for (let idx = 0; idx < band_struct.qpoints.length; idx++) {
211
- const point = band_struct.qpoints[idx]
212
- if (point.label === null) continue
213
-
214
- // Find which branch this point belongs to
215
- const branch_names = band_struct.branches
216
- .filter((branch) => branch.start_index <= idx && idx <= branch.end_index)
217
- .map((branch) => branch.name)
218
- const this_branch = branch_names[0] || null
219
-
220
- if (point.label !== prev_label && prev_branch !== this_branch) {
221
- // Branch transition - combine labels
222
- tick_labels[tick_labels.length - 1] = `${prev_label || ``}|${point.label}`
223
- ticks_x_pos[ticks_x_pos.length - 1] = band_struct.distance[idx]
224
- } else if (branches_set.size === 0 || (this_branch && branches_set.has(this_branch))) {
225
- tick_labels.push(point.label)
226
- ticks_x_pos.push(band_struct.distance[idx])
227
- }
228
-
229
- prev_label = point.label
230
- prev_branch = this_branch
231
- }
232
-
233
- return [ticks_x_pos, tick_labels.map(pretty_sym_point)]
234
- }
235
-
236
- // Convert frequencies from THz to specified units.
237
- export function convert_frequencies(
238
- frequencies: number[],
239
- unit: types.FrequencyUnit = `THz`,
240
- ): number[] {
241
- const conversion_factors: Record<types.FrequencyUnit, number> = {
242
- THz: 1,
243
- eV: THz_TO_EV,
244
- meV: THz_TO_MEV,
245
- Ha: THz_TO_HA,
246
- 'cm-1': THz_TO_CM,
247
- }
248
-
249
- const factor = conversion_factors[unit]
250
- if (!factor) {
251
- const valid_units = Object.keys(conversion_factors).join(`, `)
252
- throw new Error(`Invalid unit: ${unit}. Must be one of ${valid_units}`)
253
- }
254
-
255
- return frequencies.map((freq) => freq * factor)
256
- }
257
-
258
- // Normalize DOS densities according to specified mode.
259
- export function normalize_densities(
260
- densities: number[],
261
- freqs_or_energies: number[],
262
- mode: types.NormalizationMode,
263
- ): number[] {
264
- if (!mode) return densities
265
-
266
- const normalized = [...densities]
267
-
268
- if (mode === `max`) {
269
- const max_val = Math.max(...normalized)
270
- if (max_val === 0) return normalized
271
- return normalized.map((dens) => dens / max_val)
272
- } else if (mode === `sum`) {
273
- const sum = normalized.reduce((acc, d) => acc + d, 0)
274
- if (sum === 0) return normalized
275
- return normalized.map((dens) => dens / sum)
276
- } else if (mode === `integral`) {
277
- if (freqs_or_energies.length < 2) return normalized
278
- const bin_width = freqs_or_energies[1] - freqs_or_energies[0]
279
- if (bin_width === 0) return normalized
280
- const sum = normalized.reduce((acc, d) => acc + d, 0)
281
- if (sum === 0) return normalized
282
- return normalized.map((dens) => dens / (sum * bin_width))
283
- }
284
-
285
- return normalized
286
- }
287
-
288
- // Simple LRU cache for Gaussian smearing results
289
- // Key: hash of (frequencies, densities, sigma), Value: smeared densities
290
- const SMEARING_CACHE_MAX_SIZE = 10
291
- const smearing_cache = new Map<string, number[]>()
292
-
293
- // FNV-1a hash for number arrays (fast, good distribution, O(n))
294
- function fnv1a_hash(arr: number[]): number {
295
- let hash = 2166136261 // FNV offset basis
296
- for (const val of arr) {
297
- // Convert float to int32 bits for consistent hashing
298
- const bits = new Float64Array([val])
299
- const int_view = new Uint32Array(bits.buffer)
300
- hash ^= int_view[0]
301
- hash = Math.imul(hash, 16777619) // FNV prime
302
- hash ^= int_view[1]
303
- hash = Math.imul(hash, 16777619)
304
- }
305
- return hash >>> 0 // Ensure unsigned
306
- }
307
-
308
- // Generate cache key using FNV-1a hash over full arrays (O(n), low collision risk)
309
- function generate_smearing_cache_key(
310
- freqs_or_energies: number[],
311
- densities: number[],
312
- sigma: number,
313
- ): string {
314
- const len = freqs_or_energies.length
315
- if (len === 0) return `0:${sigma.toFixed(6)}:0:0`
316
- return `${len}:${sigma.toFixed(6)}:${fnv1a_hash(freqs_or_energies).toString(16)}:${fnv1a_hash(
317
- densities,
318
- ).toString(16)}`
319
- }
320
-
321
- // Core Gaussian smearing computation (unmemoized)
322
- function apply_gaussian_smearing_core(
323
- freqs_or_energies: number[],
324
- densities: number[],
325
- sigma: number,
326
- ): number[] {
327
- const orig_sum = densities.reduce((acc, d) => acc + d, 0)
328
- if (sigma <= 0 || orig_sum === 0) return densities
329
-
330
- const smeared = Array(densities.length).fill(0)
331
- const truncation_width = 4 // Truncate Gaussian at ±4σ (contribution < 0.01%)
332
-
333
- for (let idx = 0; idx < freqs_or_energies.length; idx++) {
334
- const energy = freqs_or_energies[idx]
335
- const cutoff = truncation_width * sigma
336
-
337
- for (let jdx = 0; jdx < freqs_or_energies.length; jdx++) {
338
- const e_j = freqs_or_energies[jdx]
339
- const delta = Math.abs(energy - e_j)
340
-
341
- // Skip points beyond truncation width
342
- if (delta > cutoff) continue
343
-
344
- const gaussian = Math.exp(-((energy - e_j) ** 2) / (2 * sigma ** 2))
345
- smeared[idx] += densities[jdx] * gaussian
346
- }
347
- }
348
-
349
- // Normalize to preserve integral
350
- const smeared_sum = smeared.reduce((acc, d) => acc + d, 0)
351
- if (smeared_sum === 0) return densities
352
- const normalization = orig_sum / smeared_sum
353
- return smeared.map((dens) => dens * normalization)
354
- }
355
-
356
- // Apply Gaussian smearing to DOS densities with memoization.
357
- // Uses truncated Gaussian (±4σ) for O(n·w) complexity instead of O(n²).
358
- // Results are cached using an LRU cache to avoid recomputation on reactive updates.
359
- export function apply_gaussian_smearing(
360
- freqs_or_energies: number[],
361
- densities: number[],
362
- sigma: number,
363
- ): number[] {
364
- // Fast path: no smearing needed
365
- if (sigma <= 0) return densities
366
-
367
- const cache_key = generate_smearing_cache_key(freqs_or_energies, densities, sigma)
368
-
369
- // Check cache
370
- const cached = smearing_cache.get(cache_key)
371
- if (cached) {
372
- // Move to end (LRU behavior: most recently used last)
373
- smearing_cache.delete(cache_key)
374
- smearing_cache.set(cache_key, cached)
375
- return cached
376
- }
377
-
378
- // Compute and cache
379
- const result = apply_gaussian_smearing_core(freqs_or_energies, densities, sigma)
380
-
381
- // Evict oldest entry if cache is full (LRU: first entry is oldest)
382
- if (smearing_cache.size >= SMEARING_CACHE_MAX_SIZE) {
383
- const oldest_key = smearing_cache.keys().next().value
384
- if (oldest_key !== undefined) smearing_cache.delete(oldest_key)
385
- }
386
-
387
- smearing_cache.set(cache_key, result)
388
- return result
389
- }
390
-
391
- // Clear the smearing cache (useful for testing or memory management)
392
- export function clear_smearing_cache(): void {
393
- smearing_cache.clear()
394
- }
395
-
396
- // Type guards for pymatgen qpoint formats
397
- const is_vec3 = (val: unknown): val is Vec3 =>
398
- Array.isArray(val) && val.length >= 3 && val.slice(0, 3).every(Number.isFinite)
399
-
400
- interface PymatgenKpoint {
401
- frac_coords: Vec3
402
- label?: string | null
403
- }
404
- const is_kpoint = (val: unknown): val is PymatgenKpoint =>
405
- !!val && typeof val === `object` && `frac_coords` in val && is_vec3(val.frac_coords)
406
-
407
- const is_pymatgen_format = (obj: Record<string, unknown>): boolean => {
408
- // Check for explicit pymatgen markers
409
- if (typeof obj[`@class`] === `string` || typeof obj[`@module`] === `string`) {
410
- return true
411
- }
412
- // Check for pymatgen-style qpoints (phonon) or kpoints (electronic) without branches
413
- const points = obj.qpoints ?? obj.kpoints
414
- if (Array.isArray(points) && points.length > 0 && !Array.isArray(obj.branches)) {
415
- return is_vec3(points[0]) || is_kpoint(points[0])
416
- }
417
- return false
418
- }
419
-
420
- // Extract frac_coords/label from pymatgen qpoint, matching label from labels_dict if needed
421
- const parse_qpoint = (
422
- qpt: unknown,
423
- labels_dict?: Record<string, Vec3>,
424
- ): types.QPoint | null => {
425
- const frac_coords = is_vec3(qpt)
426
- ? ([qpt[0], qpt[1], qpt[2]] as Vec3)
427
- : is_kpoint(qpt)
428
- ? qpt.frac_coords
429
- : null
430
- if (!frac_coords) return null
431
-
432
- const label =
433
- (is_kpoint(qpt) && typeof qpt.label === `string` && qpt.label) ||
434
- Object.entries(labels_dict ?? {}).find(
435
- ([, c]) => euclidean_dist(frac_coords, c) < 1e-4,
436
- )?.[0] ||
437
- null
438
- return { label, frac_coords }
439
- }
440
-
441
- // Inverse conversion factors (derived from THz_TO_* for consistency)
442
- const EV_TO_THZ = 1 / THz_TO_EV
443
- const CM_TO_THZ = 1 / THz_TO_CM
444
-
445
- // Spin key constants for pymatgen spin-polarized data
446
- const SPIN_UP_KEYS = [`1`, `Spin.up`]
447
- const SPIN_DOWN_KEYS = [`-1`, `Spin.down`]
448
-
449
- // Extract both spin channels from pymatgen spin-keyed data.
450
- // Returns { up: T, down: T | null } where down is null for non-spin-polarized data.
451
- export function extract_spin_channels<T>(data: unknown): { up: T; down: T | null } | null {
452
- if (Array.isArray(data)) return { up: data as T, down: null }
453
- if (data && typeof data === `object`) {
454
- const record = data as Record<string, T>
455
- let spin_up: T | null = null
456
- let spin_down: T | null = null
457
-
458
- // Extract spin-up channel
459
- for (const key of SPIN_UP_KEYS) {
460
- if (key in record) {
461
- spin_up = record[key]
462
- break
463
- }
464
- }
465
- // Extract spin-down channel
466
- for (const key of SPIN_DOWN_KEYS) {
467
- if (key in record) {
468
- spin_down = record[key]
469
- break
470
- }
471
- }
472
-
473
- // Fall back to first key if no spin-up key found
474
- if (spin_up === null) {
475
- const keys = Object.keys(record)
476
- if (keys.length > 0) spin_up = record[keys[0]]
477
- }
478
-
479
- if (spin_up === null) return null
480
- return { up: spin_up, down: spin_down }
481
- }
482
- return null
483
- }
484
-
485
- // Convert pymatgen PhononBandStructureSymmLine or BandStructure to matterviz format
486
- function convert_pymatgen_band_structure(
487
- pmg: Record<string, unknown>,
488
- ): types.BaseBandStructure | null {
489
- // Support both qpoints (phonon) and kpoints (electronic)
490
- const raw_qpts = (pmg.qpoints ?? pmg.kpoints) as unknown[] | undefined
491
-
492
- // Handle bands in multiple formats:
493
- // 1. Standard pymatgen: bands as dict with spin keys {1: [[...], ...]}
494
- // 2. Custom phonon format: frequencies_cm as 2D array [[...], ...]
495
- // 3. Already normalized: bands as 2D array [[...], ...]
496
- const spin_channels = extract_spin_channels<number[][]>(pmg.bands)
497
- let raw_bands = spin_channels?.up ?? null
498
- let raw_spin_down_bands = spin_channels?.down ?? null
499
- const has_frequencies_cm = Array.isArray(pmg.frequencies_cm)
500
- if (!raw_bands && has_frequencies_cm) {
501
- // Phonon format: frequencies_cm is [n_qpoints x n_branches] - needs transpose
502
- const freqs = pmg.frequencies_cm as number[][]
503
- if (freqs.length > 0 && Array.isArray(freqs[0])) {
504
- // Transpose: [n_qpoints x n_branches] -> [n_branches x n_qpoints]
505
- raw_bands = Array.from({ length: freqs[0].length }, (_, band_idx) =>
506
- freqs.map((qpt_freqs) => qpt_freqs[band_idx]),
507
- )
508
- raw_spin_down_bands = null
509
- }
510
- }
511
-
512
- const labels_dict = pmg.labels_dict as Record<string, Vec3> | undefined
513
- const lattice_rec = pmg.lattice_rec as { matrix?: Matrix3x3 } | undefined
514
- // Determine unit: cm-1 if frequencies_cm present, else check explicit unit or default to THz
515
- const unit =
516
- (pmg.unit as string | undefined)?.toLowerCase() ?? (has_frequencies_cm ? `cm-1` : `thz`)
517
-
518
- if (
519
- !Array.isArray(raw_qpts) ||
520
- !Array.isArray(raw_bands) ||
521
- !raw_qpts.length ||
522
- !raw_bands.length
523
- )
524
- return null
525
-
526
- const qpoints = raw_qpts
527
- .map((qpoint) => parse_qpoint(qpoint, labels_dict))
528
- .filter((qpoint): qpoint is types.QPoint => qpoint !== null)
529
- if (!qpoints.length) return null
530
-
531
- // Step distances and discontinuity detection (5x median threshold)
532
- const steps = qpoints
533
- .slice(1)
534
- .map((qpoint, idx) => euclidean_dist(qpoints[idx].frac_coords, qpoint.frac_coords))
535
- const sorted = steps.slice().sort((a, b) => a - b)
536
- const threshold = (sorted[Math.floor(sorted.length / 2)] ?? 0) * 5
537
- const disc_set = new Set(
538
- steps
539
- .map((step, idx) => (step > threshold ? idx + 1 : -1))
540
- .filter((disc_idx) => disc_idx >= 0),
541
- )
542
-
543
- // Cumulative distance (skip discontinuities)
544
- const distance = steps.reduce(
545
- (acc, step, idx) => [...acc, disc_set.has(idx + 1) ? acc[idx] : acc[idx] + step],
546
- [0],
547
- )
548
-
549
- // Use pymatgen's branches if available - they correctly handle discontinuities
550
- // Otherwise, infer branches from discontinuities (robust fallback covering all qpoints)
551
- const pmg_branches = pmg.branches as types.Branch[] | undefined
552
- let branches: types.Branch[] = []
553
-
554
- if (Array.isArray(pmg_branches) && pmg_branches.length > 0) {
555
- // Validate and use pymatgen branches directly
556
- branches = pmg_branches.filter(
557
- (branch) =>
558
- typeof branch.start_index === `number` &&
559
- typeof branch.end_index === `number` &&
560
- branch.start_index >= 0 &&
561
- branch.end_index < qpoints.length &&
562
- branch.start_index <= branch.end_index,
563
- )
564
- }
565
-
566
- // Fallback: infer branches from discontinuities when none provided or all invalid
567
- if (branches.length === 0) {
568
- console.warn(
569
- `Band structure missing 'branches' field - inferring from path discontinuities`,
570
- )
571
- // Discontinuity indices mark points where the path jumps (disc before that index)
572
- // Create continuous segments between discontinuities
573
- const disc_indices = [...disc_set].sort((a, b) => a - b)
574
- // Segment boundaries: [0, first_disc), [first_disc, second_disc), ..., [last_disc, end]
575
- const segment_starts = [0, ...disc_indices]
576
- const segment_ends = [...disc_indices.map((idx) => idx - 1), qpoints.length - 1]
577
-
578
- branches = segment_starts
579
- .map((start, idx) => {
580
- const end = segment_ends[idx]
581
- const start_label = qpoints[start]?.label ?? `?`
582
- const end_label = qpoints[end]?.label ?? `?`
583
- return {
584
- start_index: start,
585
- end_index: end,
586
- name: `${start_label}-${end_label}`,
587
- }
588
- })
589
- .filter((branch) => branch.start_index <= branch.end_index)
590
- }
591
-
592
- if (!branches.length) {
593
- branches.push({ start_index: 0, end_index: qpoints.length - 1, name: `path` })
594
- }
595
-
596
- // Convert bands to THz based on input unit
597
- const convert_to_thz = (val: number): number => {
598
- if (unit === `ev`) return val * EV_TO_THZ
599
- if (unit === `cm-1`) return val * CM_TO_THZ
600
- return val // THz (default) - no conversion
601
- }
602
-
603
- const converted_bands = raw_bands.map((band) => band.map(convert_to_thz))
604
- const valid_spin_down_bands =
605
- Array.isArray(raw_spin_down_bands) &&
606
- raw_spin_down_bands.length === raw_bands.length &&
607
- raw_spin_down_bands.every(
608
- (band, band_idx) => Array.isArray(band) && band.length === raw_bands[band_idx]?.length,
609
- )
610
- ? raw_spin_down_bands
611
- : null
612
- const converted_spin_down_bands = valid_spin_down_bands?.map((band) =>
613
- band.map(convert_to_thz),
614
- )
615
-
616
- return {
617
- qpoints,
618
- branches,
619
- distance,
620
- bands: converted_bands,
621
- spin_down_bands: converted_spin_down_bands,
622
- nb_bands: raw_bands.length,
623
- labels_dict: labels_dict ?? {},
624
- recip_lattice: {
625
- matrix: lattice_rec?.matrix ?? [
626
- [1, 0, 0],
627
- [0, 1, 0],
628
- [0, 0, 1],
629
- ],
630
- },
631
- }
632
- }
633
-
634
- export function normalize_band_structure(bs: unknown): types.BaseBandStructure | null {
635
- if (!bs || typeof bs !== `object`) return null
636
-
637
- const band_struct = bs as Record<string, unknown>
638
-
639
- // Check if this is pymatgen format and convert if so
640
- if (is_pymatgen_format(band_struct)) {
641
- return convert_pymatgen_band_structure(band_struct)
642
- }
643
-
644
- // Standard matterviz format validation
645
- const { qpoints, branches, bands, distance } =
646
- band_struct as Partial<types.BaseBandStructure>
647
- if (
648
- !Array.isArray(qpoints) ||
649
- !Array.isArray(branches) ||
650
- !Array.isArray(bands) ||
651
- !Array.isArray(distance)
652
- )
653
- return null
654
-
655
- // Validate array lengths and branch indices
656
- const n_qpts = qpoints.length
657
- if (
658
- distance.length !== n_qpts ||
659
- bands.some((band) => !Array.isArray(band) || band.length !== n_qpts) ||
660
- branches.some(
661
- (branch) =>
662
- typeof branch.start_index !== `number` ||
663
- typeof branch.end_index !== `number` ||
664
- branch.start_index < 0 ||
665
- branch.end_index >= n_qpts ||
666
- branch.start_index > branch.end_index,
667
- )
668
- )
669
- return null
670
-
671
- return band_struct as unknown as types.BaseBandStructure
672
- }
673
-
674
- // Validate and normalize a DOS object.
675
- // Supports both matterviz and pymatgen formats.
676
- // Also auto-detects and converts cm⁻¹ to THz for legacy data (disable with auto_convert_units: false).
677
- export function normalize_dos(
678
- dos: unknown,
679
- options: { auto_convert_units?: boolean } = {},
680
- ): types.DosData | null {
681
- const { auto_convert_units = true } = options
682
- if (!dos || typeof dos !== `object`) return null
683
-
684
- const dos_obj = dos as Record<string, unknown>
685
-
686
- // Check for pymatgen format (has @class or @module)
687
- const is_pymatgen =
688
- typeof dos_obj[`@class`] === `string` || typeof dos_obj[`@module`] === `string`
689
-
690
- const { frequencies, energies, spin_polarized } = dos_obj
691
-
692
- // Handle densities as either array or dict with spin keys (pymatgen format)
693
- // Pymatgen stores densities as {1: [...], -1: [...]} or {"Spin.up": [...], ...}
694
- const spin_channels = extract_spin_channels<number[]>(dos_obj.densities)
695
- if (!spin_channels) return null
696
-
697
- const densities = spin_channels.up
698
- // Use extracted spin-down or fallback to explicit field (for already-normalized DosData)
699
- const spin_down_densities =
700
- spin_channels.down ?? (dos_obj.spin_down_densities as number[] | undefined) ?? null
701
-
702
- if (!Array.isArray(densities)) return null
703
-
704
- // Phonon DOS: has frequencies
705
- if (Array.isArray(frequencies)) {
706
- if (frequencies.length !== densities.length) return null
707
-
708
- // Auto-detect if frequencies are in cm⁻¹ instead of THz (unless disabled)
709
- // Typical phonon frequencies are < 50 THz for most materials
710
- // If max frequency > 100, it's almost certainly in cm⁻¹
711
- const max_freq = Math.max(...(frequencies as number[]))
712
- let final_frequencies = frequencies as number[]
713
-
714
- if (auto_convert_units && max_freq > 100) {
715
- // Likely in cm⁻¹, convert to THz
716
- final_frequencies = (frequencies as number[]).map((frequency) => frequency * CM_TO_THZ)
717
- console.warn(
718
- `Phonon DOS frequencies appear to be in cm⁻¹ (max: ${max_freq.toFixed(1)}). ` +
719
- `Converting to THz (max: ${(max_freq * CM_TO_THZ).toFixed(1)} THz).`,
720
- )
721
- }
722
-
723
- return { type: `phonon`, frequencies: final_frequencies, densities }
724
- }
725
-
726
- // Electronic DOS: has energies
727
- if (Array.isArray(energies)) {
728
- if (energies.length !== densities.length) return null
729
- // Detect spin-polarized from data if not explicitly set
730
- const is_spin_polarized =
731
- (spin_polarized as boolean | undefined) ??
732
- (spin_down_densities !== null && spin_down_densities.length === densities.length)
733
- return {
734
- type: `electronic`,
735
- energies,
736
- densities,
737
- spin_down_densities: is_spin_polarized ? (spin_down_densities ?? undefined) : undefined,
738
- spin_polarized: is_spin_polarized,
739
- }
740
- }
741
-
742
- // For pymatgen format, log a helpful message if format wasn't recognized
743
- if (is_pymatgen) {
744
- console.warn(
745
- `Pymatgen DOS format detected but missing required fields. ` +
746
- `Expected 'frequencies' (phonon) or 'energies' (electronic) arrays.`,
747
- )
748
- }
749
-
750
- return null
751
- }
752
-
753
- // Extract k-path points from band structure and convert to reciprocal space coordinates
754
- // Accepts a reciprocal lattice matrix (should include 2π factor for consistency with BZ)
755
- // Handles both matterviz format (qpoints as objects) and normalized pymatgen format
756
- // Optionally wraps fractional coordinates to first BZ (default: true)
757
- export function extract_k_path_points(
758
- band_struct: types.BaseBandStructure,
759
- recip_lattice_matrix: Matrix3x3,
760
- options: { wrap_to_bz?: boolean } = {},
761
- ): Vec3[] {
762
- const { wrap_to_bz = true } = options
763
- if (!band_struct?.qpoints || !recip_lattice_matrix) return []
764
-
765
- if (
766
- recip_lattice_matrix.length !== 3 ||
767
- recip_lattice_matrix.some((row) => row?.length !== 3)
768
- )
769
- throw new Error(`reciprocal_lattice_matrix must be a 3×3 matrix`)
770
-
771
- const [[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]] = recip_lattice_matrix
772
-
773
- return band_struct.qpoints.map((qpoint): Vec3 => {
774
- let [x, y, z] = qpoint.frac_coords
775
- // Wrap to first BZ if enabled (handles [0,1] vs [-0.5,0.5] convention difference)
776
- if (wrap_to_bz) {
777
- x = centered_frac(x)
778
- y = centered_frac(y)
779
- z = centered_frac(z)
780
- }
781
- const kx = x * m00 + y * m10 + z * m20
782
- const ky = x * m01 + y * m11 + z * m21
783
- const kz = x * m02 + y * m12 + z * m22
784
- return [kx, ky, kz]
785
- })
786
- }
787
-
788
- // Find the q-point index closest to a given distance along the band structure path
789
- export function find_qpoint_at_distance(
790
- band_struct: types.BaseBandStructure,
791
- target: number,
792
- ): number | null {
793
- const { distance } = band_struct
794
- if (!distance?.length) return null
795
-
796
- return distance.reduce(
797
- (closest: number, dist: number, idx: number) =>
798
- Math.abs(dist - target) < Math.abs(distance[closest] - target) ? idx : closest,
799
- 0,
800
- )
801
- }
802
-
803
- // Find q-point index from rescaled x-coordinate (used in band structure plots)
804
- // This handles the case where the plot uses custom x-axis scaling per segment
805
- export function find_qpoint_at_rescaled_x(
806
- band_struct: types.BaseBandStructure,
807
- rescaled_x: number,
808
- x_positions: Record<string, [number, number]>,
809
- ): number | null {
810
- if (!band_struct?.branches?.length || !x_positions) return null
811
-
812
- // Find which segment contains this x coordinate
813
- for (const branch of band_struct.branches) {
814
- const start_idx = branch.start_index
815
- const end_idx = branch.end_index
816
- const start_label = band_struct.qpoints[start_idx]?.label ?? undefined
817
- const end_label = band_struct.qpoints[end_idx]?.label ?? undefined
818
- const segment_key = get_segment_key(start_label, end_label)
819
-
820
- const segment_range = x_positions[segment_key]
821
- if (!segment_range) continue
822
-
823
- const [x_start, x_end] = segment_range
824
-
825
- // Check if discontinuity (zero-length segment)
826
- const is_discontinuity = Math.abs(x_end - x_start) < 1e-6
827
- if (is_discontinuity) {
828
- // For discontinuities, check if x is exactly at this point
829
- if (Math.abs(rescaled_x - x_start) < 1e-6) {
830
- return start_idx
831
- }
832
- continue
833
- }
834
-
835
- // Check if x is within this segment (with small tolerance for edges)
836
- if (rescaled_x >= x_start - 1e-6 && rescaled_x <= x_end + 1e-6) {
837
- // Map from rescaled x back to original distance
838
- const segment_distances = band_struct.distance.slice(start_idx, end_idx + 1)
839
- const dist_min = segment_distances[0]
840
- const dist_max = segment_distances.at(-1) ?? dist_min
841
- const dist_range = dist_max - dist_min
842
-
843
- // Handle zero-length segments
844
- if (dist_range === 0) {
845
- return start_idx
846
- }
847
-
848
- // Inverse of the scaling: x = x_start + ((dist - dist_min) / dist_range) * (x_end - x_start)
849
- // Solving for dist: dist = dist_min + ((x - x_start) / (x_end - x_start)) * dist_range
850
- const normalized_x = (rescaled_x - x_start) / (x_end - x_start)
851
- const target_dist = dist_min + normalized_x * dist_range
852
-
853
- // Find closest qpoint in this branch to the target distance
854
- let closest_idx = start_idx
855
- let min_diff = Math.abs(band_struct.distance[start_idx] - target_dist)
856
-
857
- for (let idx = start_idx; idx <= end_idx; idx++) {
858
- const diff = Math.abs(band_struct.distance[idx] - target_dist)
859
- if (diff < min_diff) {
860
- min_diff = diff
861
- closest_idx = idx
862
- }
863
- }
864
-
865
- return closest_idx
866
- }
867
- }
868
-
869
- // Fallback: find closest labeled point
870
- let closest_idx = 0
871
- let min_dist = Infinity
872
-
873
- for (const branch of band_struct.branches) {
874
- const start_idx = branch.start_index
875
- const end_idx = branch.end_index
876
- const start_label = band_struct.qpoints[start_idx]?.label ?? undefined
877
- const end_label = band_struct.qpoints[end_idx]?.label ?? undefined
878
- const segment_key = get_segment_key(start_label, end_label)
879
- const segment_range = x_positions[segment_key]
880
-
881
- if (!segment_range) continue
882
-
883
- const [x_start, x_end] = segment_range
884
-
885
- for (const [x_pos, idx] of [
886
- [x_start, start_idx],
887
- [x_end, end_idx],
888
- ] as const) {
889
- const dist = Math.abs(rescaled_x - x_pos)
890
- if (dist < min_dist) {
891
- min_dist = dist
892
- closest_idx = idx
893
- }
894
- }
895
- }
896
-
897
- return closest_idx
898
- }
899
-
900
- // Type definitions for pymatgen DOS formats
901
- // Densities can be spin-keyed: {1: number[], -1: number[]} or {"Spin.up": number[], ...}
902
- type SpinDensities = Record<string, number[]>
903
-
904
- // Pymatgen Dos base class format
905
- export interface PymatgenDos {
906
- '@class': string
907
- '@module': string
908
- energies: number[]
909
- densities: SpinDensities | number[]
910
- efermi: number
911
- }
912
-
913
- // Pymatgen CompleteDos format (includes projected DOS)
914
- export interface PymatgenCompleteDos extends PymatgenDos {
915
- '@class': `CompleteDos` | `LobsterCompleteDos`
916
- structure?: Record<string, unknown>
917
- pdos?: Record<string, SpinDensities>[]
918
- atom_dos?: Record<string, PymatgenDos>
919
- spd_dos?: Record<string, PymatgenDos>
920
- }
921
-
922
- // Extract projected DOS from pymatgen CompleteDos format.
923
- // Returns a dict of label → DosData for each atom or orbital.
924
- // filter_keys: optional list of keys to include (e.g., ["Fe", "O"] for atoms or ["s", "p", "d"] for orbitals)
925
- export function extract_pdos(
926
- dos: unknown,
927
- pdos_type: types.PdosType,
928
- filter_keys?: string[],
929
- ): Record<string, types.ElectronicDos> | null {
930
- if (!dos || typeof dos !== `object`) return null
931
-
932
- const dos_obj = dos as Record<string, unknown>
933
-
934
- // Get the appropriate projected DOS dict
935
- const pdos_dict =
936
- pdos_type === `atom`
937
- ? (dos_obj.atom_dos as Record<string, PymatgenDos> | undefined)
938
- : (dos_obj.spd_dos as Record<string, PymatgenDos> | undefined)
939
-
940
- if (!pdos_dict || typeof pdos_dict !== `object`) return null
941
-
942
- const result: Record<string, types.ElectronicDos> = {}
943
-
944
- for (const [key, nested_dos] of Object.entries(pdos_dict)) {
945
- // Apply filter if provided
946
- if (filter_keys && filter_keys.length > 0 && !filter_keys.includes(key)) continue
947
-
948
- if (!nested_dos || typeof nested_dos !== `object`) continue
949
-
950
- const energies = nested_dos.energies
951
- const spin_channels = extract_spin_channels<number[]>(nested_dos.densities)
952
-
953
- if (!Array.isArray(energies) || !spin_channels) continue
954
-
955
- const densities = spin_channels.up
956
- if (!Array.isArray(densities) || energies.length !== densities.length) continue
957
-
958
- const is_spin_polarized =
959
- spin_channels.down !== null && spin_channels.down.length === densities.length
960
-
961
- result[key] = {
962
- type: `electronic`,
963
- energies,
964
- densities,
965
- spin_down_densities: is_spin_polarized ? (spin_channels.down ?? undefined) : undefined,
966
- spin_polarized: is_spin_polarized,
967
- efermi: nested_dos.efermi,
968
- }
969
- }
970
-
971
- return Object.keys(result).length > 0 ? result : null
972
- }
973
-
974
- // Shift a single DOS object's energies by the given amount
975
- const shift_dos_energies = <T extends PymatgenDos>(dos: T, shift: number): T => ({
976
- ...dos,
977
- efermi: dos.efermi - shift,
978
- energies: dos.energies.map((energy) => energy - shift),
979
- })
980
-
981
- // Shift DOS energies relative to Fermi energy so E_F = 0
982
- // Recursively shifts nested DOS in atom_dos and spd_dos for consistency
983
- export function shift_to_fermi(dos: PymatgenCompleteDos): PymatgenCompleteDos {
984
- const shift = dos.efermi
985
-
986
- // Shift root DOS energies using the shared helper
987
- const shifted_root = shift_dos_energies(dos, shift)
988
-
989
- // Shift nested atom_dos if present
990
- const atom_dos = dos.atom_dos
991
- ? Object.fromEntries(
992
- Object.entries(dos.atom_dos).map(([key, nested_dos]) => [
993
- key,
994
- shift_dos_energies(nested_dos, shift),
995
- ]),
996
- )
997
- : undefined
998
-
999
- // Shift nested spd_dos if present
1000
- const spd_dos = dos.spd_dos
1001
- ? Object.fromEntries(
1002
- Object.entries(dos.spd_dos).map(([key, nested_dos]) => [
1003
- key,
1004
- shift_dos_energies(nested_dos, shift),
1005
- ]),
1006
- )
1007
- : undefined
1008
-
1009
- return {
1010
- ...shifted_root,
1011
- efermi: 0, // Explicitly set to 0 (shift_dos_energies would give efermi - shift)
1012
- ...(atom_dos && { atom_dos }),
1013
- ...(spd_dos && { spd_dos }),
1014
- }
1015
- }
1016
-
1017
- // Generate an SVG path for a fat band ribbon.
1018
- // Creates a closed polygon by tracing the upper edge (y - half_width) forward,
1019
- // then tracing the lower edge (y + half_width) backward.
1020
- // Non-finite or non-positive widths are clamped to 0.
1021
- export function generate_ribbon_path(
1022
- x_values: number[],
1023
- y_values: number[],
1024
- width_values: number[],
1025
- x_scale_fn: (x: number) => number,
1026
- y_scale_fn: (y: number) => number,
1027
- max_width_px: number,
1028
- scale: number = 1,
1029
- ): string {
1030
- const len = x_values.length
1031
- if (len < 2 || len !== y_values.length || len !== width_values.length) return ``
1032
-
1033
- // Normalize width values to [0, 1] range based on the max positive finite value
1034
- const finite_positive_widths = width_values.filter(
1035
- (width) => Number.isFinite(width) && width > 0,
1036
- )
1037
- if (finite_positive_widths.length === 0) return ``
1038
- const max_width_val = Math.max(...finite_positive_widths)
1039
-
1040
- // Build upper edge path (forward direction)
1041
- const upper_points: string[] = []
1042
- const lower_points: string[] = []
1043
-
1044
- for (let idx = 0; idx < x_values.length; idx++) {
1045
- const x_px = x_scale_fn(x_values[idx])
1046
- const y_data = y_values[idx]
1047
- const raw_width = width_values[idx] ?? 0
1048
- const width_normalized =
1049
- Number.isFinite(raw_width) && raw_width > 0 ? raw_width / max_width_val : 0
1050
- const half_width_px = width_normalized * max_width_px * scale
1051
-
1052
- // In SVG, y increases downward, so upper edge has smaller y value
1053
- const y_upper_px = y_scale_fn(y_data) - half_width_px
1054
- const y_lower_px = y_scale_fn(y_data) + half_width_px
1055
-
1056
- upper_points.push(`${x_px.toFixed(2)},${y_upper_px.toFixed(2)}`)
1057
- lower_points.push(`${x_px.toFixed(2)},${y_lower_px.toFixed(2)}`)
1058
- }
1059
-
1060
- // Combine: upper edge forward, lower edge backward, close path
1061
- const path_parts = [
1062
- `M${upper_points[0]}`,
1063
- ...upper_points.slice(1).map((pt) => `L${pt}`),
1064
- ...lower_points.toReversed().map((pt) => `L${pt}`),
1065
- `Z`,
1066
- ]
1067
-
1068
- return path_parts.join(` `)
1069
- }
1070
-
1071
- // Extract efermi from a data source (band structure or DOS).
1072
- // Handles both single objects with an efermi field and dicts of objects.
1073
- // Returns undefined if no valid efermi is found or if the source is empty.
1074
- export function extract_efermi(data: unknown): number | undefined {
1075
- if (!data || typeof data !== `object`) return undefined
1076
- const obj = data as Record<string, unknown>
1077
-
1078
- // Direct efermi field on the object
1079
- if (`efermi` in obj && typeof obj.efermi === `number`) return obj.efermi
1080
-
1081
- // Dict of objects - try to get efermi from first value
1082
- const values = Object.values(obj)
1083
- if (values.length === 0) return undefined
1084
-
1085
- const first_val = values[0]
1086
- if (first_val && typeof first_val === `object`) {
1087
- const efermi = (first_val as Record<string, unknown>).efermi
1088
- if (typeof efermi === `number`) return efermi
1089
- }
1090
-
1091
- return undefined
1092
- }
1093
-
1094
- // Calculate fraction of |values| that are negative. Used to detect imaginary phonon modes.
1095
- export function negative_fraction(values: number[]): number {
1096
- let [neg, total] = [0, 0]
1097
- for (const val of values) {
1098
- if (!Number.isFinite(val)) continue
1099
- const abs_val = Math.abs(val)
1100
- total += abs_val
1101
- if (val < 0) neg += abs_val
1102
- }
1103
- return total > 0 ? neg / total : 0
1104
- }
1105
-
1106
- // Check if raw band structure input has electronic markers (efermi, kpoints, or electronic @class).
1107
- // Must be called on raw input before normalization since these fields aren't preserved.
1108
- function is_electronic_band_struct(bs: unknown): boolean {
1109
- if (!bs || typeof bs !== `object`) return false
1110
- const obj = bs as Record<string, unknown>
1111
- // Electronic band structures have efermi field
1112
- if (`efermi` in obj && typeof obj.efermi === `number`) return true
1113
- // Pymatgen electronic format uses kpoints (not qpoints)
1114
- if (`kpoints` in obj && Array.isArray(obj.kpoints) && obj.kpoints.length > 0) {
1115
- return true
1116
- }
1117
- // Pymatgen @class: BandStructure* but not Phonon*
1118
- const raw_class = obj[`@class`]
1119
- const py_class_name = typeof raw_class === `string` ? raw_class : ``
1120
- if (py_class_name.startsWith(`BandStructure`) && !py_class_name.includes(`Phonon`)) {
1121
- return true
1122
- }
1123
- return false
1124
- }
1125
-
1126
- // Compute frequency/energy range from bands and DOS. Clamps phonon min to 0 if noise < 0.5%.
1127
- export function compute_frequency_range(
1128
- band_structs: unknown,
1129
- doses: unknown,
1130
- padding_factor = 0.02,
1131
- ): [number, number] | undefined {
1132
- let [min_val, max_val, is_phonon] = [Infinity, -Infinity, false]
1133
- const all_freqs: number[] = []
1134
-
1135
- // Check raw band_structs for electronic markers before normalization
1136
- // (normalized structures always have qpoints, so we can't detect from them)
1137
- let has_electronic_bs = false
1138
- // Support both qpoints (phonon) and kpoints (electronic) to detect single vs dict
1139
- const is_single_bs =
1140
- band_structs &&
1141
- typeof band_structs === `object` &&
1142
- (`qpoints` in band_structs || `kpoints` in band_structs)
1143
- if (band_structs && typeof band_structs === `object`) {
1144
- // Single structure check
1145
- if (is_electronic_band_struct(band_structs)) {
1146
- has_electronic_bs = true
1147
- } else if (!is_single_bs) {
1148
- // Dict of band structures - check each value
1149
- for (const bs_val of Object.values(band_structs)) {
1150
- if (is_electronic_band_struct(bs_val)) {
1151
- has_electronic_bs = true
1152
- break
1153
- }
1154
- }
1155
- }
1156
- }
1157
-
1158
- const bs_list = band_structs
1159
- ? is_single_bs
1160
- ? [normalize_band_structure(band_structs)]
1161
- : Object.values(band_structs as object).map(normalize_band_structure)
1162
- : []
1163
-
1164
- // If band structures exist and aren't electronic, mark as phonon
1165
- const has_band_structs = bs_list.some(Boolean)
1166
- if (has_band_structs && !has_electronic_bs) is_phonon = true
1167
-
1168
- for (const bs of bs_list) {
1169
- if (!bs) continue
1170
- for (const band of bs.bands) {
1171
- for (const val of band) {
1172
- if (!Number.isFinite(val)) continue
1173
- all_freqs.push(val)
1174
- min_val = Math.min(min_val, val)
1175
- max_val = Math.max(max_val, val)
1176
- }
1177
- }
1178
- }
1179
-
1180
- const dos_list = doses
1181
- ? `densities` in (doses as object)
1182
- ? [normalize_dos(doses)]
1183
- : Object.values(doses as object).map((dos) => normalize_dos(dos))
1184
- : []
1185
- for (const dos of dos_list) {
1186
- if (!dos) continue
1187
- // DOS type detection: explicit type field is authoritative
1188
- if (dos.type === `phonon`) is_phonon = true
1189
- if (dos.type === `electronic`) is_phonon = false
1190
- for (const val of dos.type === `phonon` ? dos.frequencies : dos.energies) {
1191
- if (!Number.isFinite(val)) continue
1192
- all_freqs.push(val)
1193
- min_val = Math.min(min_val, val)
1194
- max_val = Math.max(max_val, val)
1195
- }
1196
- }
1197
-
1198
- if (!Number.isFinite(min_val) || !Number.isFinite(max_val)) return undefined
1199
- const clamp_min =
1200
- is_phonon &&
1201
- min_val < 0 && // clamp phonon noise to 0
1202
- negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD
1203
- if (clamp_min) min_val = 0
1204
- // Calculate padding from (possibly clamped) range for consistency with Bands.svelte
1205
- const padding = (max_val - min_val) * padding_factor
1206
- return [min_val === 0 ? 0 : min_val - padding, max_val + padding]
1207
- }
1208
-
1209
- // Parse axis label: "Frequency (THz)" → { name: "Frequency", unit: "THz" }
1210
- function parse_axis_label(label: string): { name: string; unit?: string } {
1211
- const match = /^(.+?)\s*\(([^)]+)\)$/.exec(label)
1212
- return match ? { name: match[1], unit: match[2] } : { name: label }
1213
- }
1214
-
1215
- const format_tooltip_line = (name: string, value: string, unit?: string) =>
1216
- `${name}: ${value}${unit ? ` ${unit}` : ``}`
1217
-
1218
- // Format DOS tooltip content from axis labels and values
1219
- export function format_dos_tooltip(
1220
- x_formatted: string,
1221
- y_formatted: string,
1222
- label: string | null,
1223
- is_horizontal: boolean,
1224
- is_phonon: boolean,
1225
- units: types.FrequencyUnit,
1226
- x_axis_label: string,
1227
- y_axis_label: string,
1228
- num_series: number,
1229
- ): { title?: string; lines: string[] } {
1230
- const x_parsed = parse_axis_label(x_axis_label)
1231
- const y_parsed = parse_axis_label(y_axis_label)
1232
- const freq_defaults = {
1233
- name: is_phonon ? `Frequency` : `Energy`,
1234
- unit: is_phonon ? units : `eV`,
1235
- }
1236
-
1237
- const lines = is_horizontal
1238
- ? [
1239
- format_tooltip_line(
1240
- y_parsed.name || freq_defaults.name,
1241
- y_formatted,
1242
- y_parsed.unit || freq_defaults.unit,
1243
- ),
1244
- format_tooltip_line(x_parsed.name || `Density`, x_formatted),
1245
- ]
1246
- : [
1247
- format_tooltip_line(y_parsed.name || `Density`, y_formatted),
1248
- format_tooltip_line(
1249
- x_parsed.name || freq_defaults.name,
1250
- x_formatted,
1251
- x_parsed.unit || freq_defaults.unit,
1252
- ),
1253
- ]
1254
-
1255
- return { title: num_series > 1 && label ? label : undefined, lines }
1256
- }
1257
-
1258
- // Spin mode options for DOS visualization
1259
- export const SPIN_MODES = [
1260
- { value: `mirror`, label: `↕`, title: `Mirror: spin-up above, spin-down below zero` },
1261
- { value: `overlay`, label: `≡`, title: `Overlay: both spins on same axis` },
1262
- { value: `up_only`, label: `↑`, title: `Show spin-up only` },
1263
- { value: `down_only`, label: `↓`, title: `Show spin-down only` },
1264
- ] as const satisfies readonly { value: types.SpinMode; label: string; title: string }[]
1265
-
1266
- // Normalization mode options
1267
- export const NORMALIZATION_MODES = [
1268
- { value: null, label: `None` },
1269
- { value: `max`, label: `Max=1` },
1270
- { value: `sum`, label: `Sum=1` },
1271
- { value: `integral`, label: `∫=1` },
1272
- ] as const satisfies readonly { value: types.NormalizationMode; label: string }[]
1273
-
1274
- // Available frequency units for phonon DOS
1275
- export const FREQUENCY_UNITS: types.FrequencyUnit[] = [`THz`, `eV`, `meV`, `cm-1`, `Ha`]
1276
-
1277
- // Default values for DOS controls
1278
- export const DEFAULT_SPIN_MODE: types.SpinMode = `mirror`
1279
- export const DEFAULT_SIGMA = 0
1280
- export const DEFAULT_NORMALIZE: types.NormalizationMode = null
1281
- export const DEFAULT_UNITS: types.FrequencyUnit = `THz`
1282
-
1283
- // Format sigma with adaptive precision: 0→"0", <0.01→exp, <1→3dp, else→2dp
1284
- export function format_sigma(val: number): string {
1285
- if (val === 0) return `0`
1286
- if (val < 0.01) return val.toExponential(1)
1287
- return val.toFixed(val < 1 ? 3 : 2)
1288
- }
1289
-
1290
- // Validate sigma_range: ensures min < max, returns [0, 1] if invalid
1291
- export const validate_sigma_range = ([min, max]: [number, number]): [number, number] =>
1292
- Number.isFinite(min) && Number.isFinite(max) && min < max ? [min, max] : [0, 1]
1293
-
1294
- // Calculate slider step: 1/100th of range, or 0.01 fallback
1295
- export function calculate_sigma_step(range: [number, number]): number {
1296
- const [min, max] = validate_sigma_range(range)
1297
- return (max - min) / 100 || 0.01
1298
- }
1299
-
1300
- // === Band Tooltip Helpers ===
1301
-
1302
- // Per-point metadata for band tooltip display
1303
- export interface BandPointMeta extends Record<string, unknown> {
1304
- band_idx: number
1305
- spin: `up` | `down`
1306
- is_acoustic: boolean | null
1307
- nb_bands: number
1308
- frac_coords: Vec3 | null
1309
- qpoint_label: string | null
1310
- band_width: number | null
1311
- slope: number | null
1312
- }
1313
-
1314
- // Central difference for local slope (dω/dk or dE/dk).
1315
- // Uses forward/backward difference at endpoints, central difference for interior points.
1316
- export function compute_slope(x_vals: number[], y_vals: number[], idx: number): number | null {
1317
- const len = Math.min(x_vals.length, y_vals.length)
1318
- if (len < 2 || idx < 0 || idx >= len) return null
1319
- const lo = idx === 0 ? 0 : idx - 1
1320
- const hi = idx >= len - 1 ? len - 1 : idx + 1
1321
- const dx = x_vals[hi] - x_vals[lo]
1322
- return dx ? (y_vals[hi] - y_vals[lo]) / dx : null
1323
- }
1324
-
1325
- // Find Gamma-point indices (q ≈ integer lattice point) in a band structure.
1326
- // Returns indices of q-points whose fractional coordinates are all within 0.01 of integers.
1327
- export function find_gamma_indices(bs: types.BaseBandStructure): number[] {
1328
- const indices: number[] = []
1329
- for (let q_idx = 0; q_idx < bs.qpoints.length; q_idx++) {
1330
- const coords = bs.qpoints[q_idx]?.frac_coords
1331
- if (coords?.every((coord) => Math.abs(coord - Math.round(coord)) < 0.01)) {
1332
- indices.push(q_idx)
1333
- }
1334
- }
1335
- return indices
1336
- }
1337
-
1338
- // Threshold below which a band's frequency at Gamma is considered acoustic (THz).
1339
- // Assumes bands are stored in THz (normalize_band_structure converts to THz).
1340
- export const ACOUSTIC_FREQ_THRESHOLD = 0.5
1341
-
1342
- // Classify a band as acoustic based on near-zero frequency at Gamma points.
1343
- // Returns true (acoustic), false (optical), or null (no Gamma points → can't determine).
1344
- export function classify_acoustic(
1345
- bs: types.BaseBandStructure,
1346
- band_idx: number,
1347
- gamma_indices: number[],
1348
- threshold = ACOUSTIC_FREQ_THRESHOLD,
1349
- ): boolean | null {
1350
- if (gamma_indices.length === 0) return null
1351
- return gamma_indices.some(
1352
- (gamma_idx) => Math.abs(bs.bands[band_idx]?.[gamma_idx] ?? Infinity) < threshold,
1353
- )
1354
- }
1355
-
1356
- // Build per-point metadata array for a band series in the tooltip.
1357
- export function build_point_metadata(opts: {
1358
- x_vals: number[]
1359
- y_vals: number[]
1360
- band_idx: number
1361
- spin: `up` | `down`
1362
- is_acoustic: boolean | null
1363
- bs: types.BaseBandStructure
1364
- start_idx: number
1365
- }): BandPointMeta[] {
1366
- const { x_vals, y_vals, band_idx, spin, is_acoustic, bs, start_idx } = opts
1367
- return x_vals.map((_, pt_idx) => {
1368
- const global_idx = start_idx + pt_idx
1369
- const qpoint = bs.qpoints[global_idx]
1370
- return {
1371
- band_idx,
1372
- spin,
1373
- is_acoustic,
1374
- nb_bands: bs.nb_bands,
1375
- frac_coords: qpoint?.frac_coords ?? null,
1376
- qpoint_label: qpoint?.label ?? null,
1377
- band_width: bs.band_widths?.[band_idx]?.[global_idx] ?? null,
1378
- slope: compute_slope(x_vals, y_vals, pt_idx),
1379
- }
1380
- })
1381
- }