matterviz 0.3.6 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (863) hide show
  1. package/dist/EmptyState.svelte.d.ts +9 -0
  2. package/dist/FilePicker.svelte +360 -0
  3. package/dist/FilePicker.svelte.d.ts +17 -0
  4. package/dist/Icon.svelte.d.ts +13 -0
  5. package/dist/MillerIndexInput.svelte +66 -0
  6. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  7. package/dist/api/mp.d.ts +6 -0
  8. package/dist/api/mp.js +22 -0
  9. package/dist/api/optimade.d.ts +45 -0
  10. package/dist/api/optimade.js +135 -0
  11. package/dist/brillouin/BrillouinZone.svelte +549 -0
  12. package/dist/brillouin/BrillouinZone.svelte.d.ts +83 -0
  13. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  14. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  15. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  16. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  17. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  19. package/dist/brillouin/BrillouinZoneScene.svelte +476 -0
  20. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +48 -0
  21. package/dist/brillouin/BrillouinZoneTooltip.svelte +92 -0
  22. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  23. package/dist/brillouin/compute.d.ts +17 -0
  24. package/dist/brillouin/compute.js +426 -0
  25. package/dist/brillouin/index.d.ts +8 -0
  26. package/dist/brillouin/index.js +7 -0
  27. package/dist/brillouin/types.d.ts +43 -0
  28. package/dist/brillouin/types.js +1 -0
  29. package/dist/chempot-diagram/ChemPotDiagram.svelte +327 -0
  30. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  31. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  32. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  33. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  34. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  36. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  37. package/dist/chempot-diagram/async-compute.svelte.js +78 -0
  38. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  39. package/dist/chempot-diagram/chempot-worker.js +11 -0
  40. package/dist/chempot-diagram/color.d.ts +10 -0
  41. package/dist/chempot-diagram/color.js +32 -0
  42. package/dist/chempot-diagram/compute.d.ts +48 -0
  43. package/dist/chempot-diagram/compute.js +806 -0
  44. package/dist/chempot-diagram/index.d.ts +6 -0
  45. package/dist/chempot-diagram/index.js +6 -0
  46. package/dist/chempot-diagram/pointer.d.ts +16 -0
  47. package/dist/chempot-diagram/pointer.js +40 -0
  48. package/dist/chempot-diagram/temperature.d.ts +15 -0
  49. package/dist/chempot-diagram/temperature.js +34 -0
  50. package/dist/chempot-diagram/types.d.ts +81 -0
  51. package/dist/chempot-diagram/types.js +28 -0
  52. package/dist/colors/index.d.ts +47 -0
  53. package/dist/colors/index.js +203 -0
  54. package/dist/composition/BarChart.svelte +297 -0
  55. package/dist/composition/BarChart.svelte.d.ts +39 -0
  56. package/dist/composition/BubbleChart.svelte +218 -0
  57. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  58. package/dist/composition/Composition.svelte +165 -0
  59. package/dist/composition/Composition.svelte.d.ts +15 -0
  60. package/dist/composition/Formula.svelte +268 -0
  61. package/dist/composition/Formula.svelte.d.ts +19 -0
  62. package/dist/composition/FormulaFilter.svelte +1257 -0
  63. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  64. package/dist/composition/PieChart.svelte +323 -0
  65. package/dist/composition/PieChart.svelte.d.ts +37 -0
  66. package/dist/composition/format.d.ts +15 -0
  67. package/dist/composition/format.js +109 -0
  68. package/dist/composition/index.d.ts +20 -0
  69. package/dist/composition/index.js +14 -0
  70. package/dist/composition/parse.d.ts +56 -0
  71. package/dist/composition/parse.js +474 -0
  72. package/dist/constants.d.ts +29 -0
  73. package/dist/constants.js +99 -0
  74. package/dist/controls.d.ts +14 -0
  75. package/dist/controls.js +30 -0
  76. package/dist/convex-hull/ConvexHull.svelte +157 -0
  77. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  78. package/dist/convex-hull/ConvexHull2D.svelte +825 -0
  79. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  80. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  81. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  82. package/dist/convex-hull/ConvexHull4D.svelte +1398 -0
  83. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  84. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  85. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  86. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  87. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  88. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  89. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  90. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  91. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  92. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  93. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  94. package/dist/convex-hull/StructurePopup.svelte +151 -0
  95. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  96. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  97. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  98. package/dist/convex-hull/barycentric-coords.js +182 -0
  99. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  100. package/dist/convex-hull/demo-temperature.js +40 -0
  101. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  102. package/dist/convex-hull/gas-thermodynamics.js +314 -0
  103. package/dist/convex-hull/helpers.d.ts +114 -0
  104. package/dist/convex-hull/helpers.js +710 -0
  105. package/dist/convex-hull/index.d.ts +119 -0
  106. package/dist/convex-hull/index.js +58 -0
  107. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  108. package/dist/convex-hull/thermodynamics.js +1752 -0
  109. package/dist/convex-hull/types.d.ts +162 -0
  110. package/dist/convex-hull/types.js +36 -0
  111. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  112. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  113. package/dist/coordination/calc-coordination.d.ts +15 -0
  114. package/dist/coordination/calc-coordination.js +63 -0
  115. package/dist/coordination/index.d.ts +8 -0
  116. package/dist/coordination/index.js +7 -0
  117. package/dist/effects.svelte.d.ts +12 -0
  118. package/dist/effects.svelte.js +37 -0
  119. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  120. package/dist/element/ElementHeading.svelte +26 -0
  121. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  122. package/dist/element/ElementPhoto.svelte +57 -0
  123. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  124. package/dist/element/ElementStats.svelte +80 -0
  125. package/dist/element/ElementStats.svelte.d.ts +8 -0
  126. package/dist/element/ElementTile.svelte +484 -0
  127. package/dist/element/ElementTile.svelte.d.ts +29 -0
  128. package/dist/element/Nucleus.svelte.d.ts +17 -0
  129. package/dist/element/data.d.ts +2 -0
  130. package/dist/element/data.js +2 -0
  131. package/dist/element/index.d.ts +8 -0
  132. package/dist/element/index.js +7 -0
  133. package/dist/element/types.d.ts +57 -0
  134. package/dist/element/types.js +1 -0
  135. package/dist/feedback/ClickFeedback.svelte +58 -0
  136. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  137. package/dist/feedback/DragOverlay.svelte +42 -0
  138. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  139. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  140. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  141. package/dist/feedback/index.d.ts +4 -0
  142. package/dist/feedback/index.js +4 -0
  143. package/dist/fermi-surface/FermiSlice.svelte +189 -0
  144. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  145. package/dist/fermi-surface/FermiSurface.svelte +600 -0
  146. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  147. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  148. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  149. package/dist/fermi-surface/FermiSurfaceScene.svelte +794 -0
  150. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  151. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  152. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  153. package/dist/fermi-surface/compute.d.ts +5 -0
  154. package/dist/fermi-surface/compute.js +538 -0
  155. package/dist/fermi-surface/constants.d.ts +9 -0
  156. package/dist/fermi-surface/constants.js +27 -0
  157. package/dist/fermi-surface/export.d.ts +5 -0
  158. package/dist/fermi-surface/export.js +50 -0
  159. package/dist/fermi-surface/index.d.ts +12 -0
  160. package/dist/fermi-surface/index.js +13 -0
  161. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  162. package/dist/fermi-surface/marching-cubes.js +2 -0
  163. package/dist/fermi-surface/parse.d.ts +2 -0
  164. package/dist/fermi-surface/parse.js +491 -0
  165. package/dist/fermi-surface/symmetry.d.ts +3 -0
  166. package/dist/fermi-surface/symmetry.js +46 -0
  167. package/dist/fermi-surface/types.d.ts +110 -0
  168. package/dist/fermi-surface/types.js +4 -0
  169. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  170. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  171. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  172. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  173. package/dist/heatmap-matrix/index.d.ts +53 -0
  174. package/dist/heatmap-matrix/index.js +100 -0
  175. package/dist/heatmap-matrix/shared.d.ts +2 -0
  176. package/dist/heatmap-matrix/shared.js +4 -0
  177. package/dist/icons.d.ts +569 -0
  178. package/dist/icons.js +648 -0
  179. package/dist/index.d.ts +39 -0
  180. package/dist/index.js +39 -0
  181. package/dist/io/decompress.d.ts +11 -0
  182. package/dist/io/decompress.js +74 -0
  183. package/dist/io/export.d.ts +16 -0
  184. package/dist/io/export.js +316 -0
  185. package/dist/io/fetch.d.ts +5 -0
  186. package/dist/io/fetch.js +39 -0
  187. package/dist/io/file-drop.d.ts +7 -0
  188. package/dist/io/file-drop.js +43 -0
  189. package/dist/io/index.d.ts +7 -0
  190. package/dist/io/index.js +6 -0
  191. package/dist/io/is-binary.d.ts +1 -0
  192. package/dist/io/is-binary.js +20 -0
  193. package/dist/io/types.d.ts +8 -0
  194. package/dist/io/types.js +1 -0
  195. package/dist/io/url-drop.d.ts +2 -0
  196. package/dist/io/url-drop.js +123 -0
  197. package/dist/isosurface/Isosurface.svelte +285 -0
  198. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  199. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  200. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  201. package/dist/isosurface/index.d.ts +5 -0
  202. package/dist/isosurface/index.js +6 -0
  203. package/dist/isosurface/parse.d.ts +6 -0
  204. package/dist/isosurface/parse.js +553 -0
  205. package/dist/isosurface/slice.d.ts +11 -0
  206. package/dist/isosurface/slice.js +140 -0
  207. package/dist/isosurface/types.d.ts +56 -0
  208. package/dist/isosurface/types.js +227 -0
  209. package/dist/labels.d.ts +53 -0
  210. package/dist/labels.js +277 -0
  211. package/dist/layout/FullscreenToggle.svelte +50 -0
  212. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  213. package/dist/layout/InfoCard.svelte +120 -0
  214. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  215. package/dist/layout/InfoTag.svelte +185 -0
  216. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  217. package/dist/layout/PropertyFilter.svelte +246 -0
  218. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  219. package/dist/layout/SettingsSection.svelte +148 -0
  220. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  221. package/dist/layout/SubpageGrid.svelte +82 -0
  222. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  223. package/dist/layout/fullscreen.d.ts +9 -0
  224. package/dist/layout/fullscreen.js +53 -0
  225. package/dist/layout/index.d.ts +10 -0
  226. package/dist/layout/index.js +8 -0
  227. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  228. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  229. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  230. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  231. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  232. package/dist/layout/json-tree/index.d.ts +3 -0
  233. package/dist/layout/json-tree/index.js +3 -0
  234. package/dist/layout/json-tree/types.d.ts +74 -0
  235. package/dist/layout/json-tree/types.js +2 -0
  236. package/dist/layout/json-tree/utils.d.ts +29 -0
  237. package/dist/layout/json-tree/utils.js +641 -0
  238. package/dist/marching-cubes.d.ts +14 -0
  239. package/dist/marching-cubes.js +540 -0
  240. package/dist/math.d.ts +101 -0
  241. package/dist/math.js +905 -0
  242. package/dist/overlays/ContextMenu.svelte +162 -0
  243. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  244. package/dist/overlays/CopyButton.svelte +45 -0
  245. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  246. package/dist/overlays/DragControlTab.svelte +98 -0
  247. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  248. package/dist/overlays/DraggablePane.svelte +487 -0
  249. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  250. package/dist/overlays/InfoPaneCards.svelte +149 -0
  251. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  252. package/dist/overlays/index.d.ts +3 -0
  253. package/dist/overlays/index.js +3 -0
  254. package/dist/periodic-table/PeriodicTable.svelte +469 -0
  255. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  256. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  257. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  258. package/dist/periodic-table/PropertySelect.svelte +37 -0
  259. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  260. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  261. package/dist/periodic-table/index.d.ts +10 -0
  262. package/dist/periodic-table/index.js +4 -0
  263. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  264. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  265. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  266. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  267. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  268. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  269. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  270. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  271. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  272. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  273. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  274. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  275. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  276. package/dist/phase-diagram/build-diagram.js +160 -0
  277. package/dist/phase-diagram/colors.d.ts +35 -0
  278. package/dist/phase-diagram/colors.js +51 -0
  279. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  280. package/dist/phase-diagram/diagram-input.js +3 -0
  281. package/dist/phase-diagram/index.d.ts +13 -0
  282. package/dist/phase-diagram/index.js +11 -0
  283. package/dist/phase-diagram/parse.d.ts +55 -0
  284. package/dist/phase-diagram/parse.js +272 -0
  285. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  286. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  287. package/dist/phase-diagram/types.d.ts +93 -0
  288. package/dist/phase-diagram/types.js +1 -0
  289. package/dist/phase-diagram/utils.d.ts +118 -0
  290. package/dist/phase-diagram/utils.js +604 -0
  291. package/dist/plot/AxisLabel.svelte +51 -0
  292. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  293. package/dist/plot/BarPlot.svelte +2113 -0
  294. package/dist/plot/BarPlot.svelte.d.ts +84 -0
  295. package/dist/plot/BarPlotControls.svelte +66 -0
  296. package/dist/plot/BarPlotControls.svelte.d.ts +18 -0
  297. package/dist/plot/BinnedScatterPlot.svelte +1114 -0
  298. package/dist/plot/BinnedScatterPlot.svelte.d.ts +66 -0
  299. package/dist/plot/ColorBar.svelte +721 -0
  300. package/dist/plot/ColorBar.svelte.d.ts +31 -0
  301. package/dist/plot/ColorScaleSelect.svelte +54 -0
  302. package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
  303. package/dist/plot/ElementScatter.svelte +63 -0
  304. package/dist/plot/ElementScatter.svelte.d.ts +14 -0
  305. package/dist/plot/FillArea.svelte.d.ts +21 -0
  306. package/dist/plot/Histogram.svelte +1558 -0
  307. package/dist/plot/Histogram.svelte.d.ts +50 -0
  308. package/dist/plot/HistogramControls.svelte +212 -0
  309. package/dist/plot/HistogramControls.svelte.d.ts +22 -0
  310. package/dist/plot/InteractiveAxisLabel.svelte +96 -0
  311. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +14 -0
  312. package/dist/plot/Line.svelte +84 -0
  313. package/dist/plot/Line.svelte.d.ts +15 -0
  314. package/dist/plot/PlotAxis.svelte +169 -0
  315. package/dist/plot/PlotAxis.svelte.d.ts +24 -0
  316. package/dist/plot/PlotControls.svelte +537 -0
  317. package/dist/plot/PlotControls.svelte.d.ts +4 -0
  318. package/dist/plot/PlotLegend.svelte +569 -0
  319. package/dist/plot/PlotLegend.svelte.d.ts +29 -0
  320. package/dist/plot/PlotTooltip.svelte +67 -0
  321. package/dist/plot/PlotTooltip.svelte.d.ts +17 -0
  322. package/dist/plot/PortalSelect.svelte +253 -0
  323. package/dist/plot/PortalSelect.svelte.d.ts +16 -0
  324. package/dist/plot/ReferenceLine.svelte.d.ts +20 -0
  325. package/dist/plot/ReferenceLine3D.svelte +156 -0
  326. package/dist/plot/ReferenceLine3D.svelte.d.ts +14 -0
  327. package/dist/plot/ReferencePlane.svelte +175 -0
  328. package/dist/plot/ReferencePlane.svelte.d.ts +14 -0
  329. package/dist/plot/ScatterPlot.svelte +2778 -0
  330. package/dist/plot/ScatterPlot.svelte.d.ts +96 -0
  331. package/dist/plot/ScatterPlot3D.svelte +529 -0
  332. package/dist/plot/ScatterPlot3D.svelte.d.ts +95 -0
  333. package/dist/plot/ScatterPlot3DControls.svelte +437 -0
  334. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +20 -0
  335. package/dist/plot/ScatterPlot3DScene.svelte +912 -0
  336. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +74 -0
  337. package/dist/plot/ScatterPlotControls.svelte +306 -0
  338. package/dist/plot/ScatterPlotControls.svelte.d.ts +17 -0
  339. package/dist/plot/ScatterPoint.svelte +182 -0
  340. package/dist/plot/ScatterPoint.svelte.d.ts +22 -0
  341. package/dist/plot/SpacegroupBarPlot.svelte +293 -0
  342. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
  343. package/dist/plot/Surface3D.svelte +197 -0
  344. package/dist/plot/Surface3D.svelte.d.ts +13 -0
  345. package/dist/plot/ZeroLines.svelte +97 -0
  346. package/dist/plot/ZeroLines.svelte.d.ts +33 -0
  347. package/dist/plot/ZoomRect.svelte +23 -0
  348. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  349. package/dist/plot/adaptive-density.d.ts +69 -0
  350. package/dist/plot/adaptive-density.js +191 -0
  351. package/dist/plot/auto-place.d.ts +43 -0
  352. package/dist/plot/auto-place.js +122 -0
  353. package/dist/plot/axis-utils.d.ts +19 -0
  354. package/dist/plot/axis-utils.js +78 -0
  355. package/dist/plot/binned-scatter-types.d.ts +59 -0
  356. package/dist/plot/binned-scatter-types.js +1 -0
  357. package/dist/plot/data-cleaning.d.ts +37 -0
  358. package/dist/plot/data-cleaning.js +855 -0
  359. package/dist/plot/data-transform.d.ts +16 -0
  360. package/dist/plot/data-transform.js +45 -0
  361. package/dist/plot/defaults.d.ts +19 -0
  362. package/dist/plot/defaults.js +9 -0
  363. package/dist/plot/fill-utils.d.ts +46 -0
  364. package/dist/plot/fill-utils.js +322 -0
  365. package/dist/plot/hover-lock.svelte.d.ts +14 -0
  366. package/dist/plot/hover-lock.svelte.js +46 -0
  367. package/dist/plot/index.d.ts +41 -0
  368. package/dist/plot/index.js +39 -0
  369. package/dist/plot/interactions.d.ts +12 -0
  370. package/dist/plot/interactions.js +101 -0
  371. package/dist/plot/layout.d.ts +78 -0
  372. package/dist/plot/layout.js +273 -0
  373. package/dist/plot/reference-line.d.ts +60 -0
  374. package/dist/plot/reference-line.js +314 -0
  375. package/dist/plot/scales.d.ts +48 -0
  376. package/dist/plot/scales.js +481 -0
  377. package/dist/plot/svg.d.ts +1 -0
  378. package/dist/plot/svg.js +11 -0
  379. package/dist/plot/types.d.ts +831 -0
  380. package/dist/plot/types.js +99 -0
  381. package/dist/plot/utils/label-placement.d.ts +68 -0
  382. package/dist/plot/utils/label-placement.js +326 -0
  383. package/dist/plot/utils/series-visibility.d.ts +15 -0
  384. package/dist/plot/utils/series-visibility.js +85 -0
  385. package/dist/plot/utils.d.ts +1 -0
  386. package/dist/plot/utils.js +14 -0
  387. package/dist/rdf/RdfPlot.svelte +247 -0
  388. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  389. package/dist/rdf/calc-rdf.d.ts +4 -0
  390. package/dist/rdf/calc-rdf.js +111 -0
  391. package/dist/rdf/index.d.ts +23 -0
  392. package/dist/rdf/index.js +2 -0
  393. package/dist/sanitize.d.ts +6 -0
  394. package/dist/sanitize.js +116 -0
  395. package/dist/settings.d.ts +255 -0
  396. package/dist/settings.js +1132 -0
  397. package/dist/spectral/Bands.svelte +1040 -0
  398. package/dist/spectral/Bands.svelte.d.ts +40 -0
  399. package/dist/spectral/BandsAndDos.svelte +134 -0
  400. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  401. package/dist/spectral/BrillouinBandsDos.svelte +252 -0
  402. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  403. package/dist/spectral/Dos.svelte +697 -0
  404. package/dist/spectral/Dos.svelte.d.ts +29 -0
  405. package/dist/spectral/helpers.d.ts +119 -0
  406. package/dist/spectral/helpers.js +1032 -0
  407. package/dist/spectral/index.d.ts +6 -0
  408. package/dist/spectral/index.js +6 -0
  409. package/dist/spectral/types.d.ts +84 -0
  410. package/dist/spectral/types.js +2 -0
  411. package/dist/state.svelte.d.ts +25 -0
  412. package/dist/state.svelte.js +45 -0
  413. package/dist/structure/Arrow.svelte +72 -0
  414. package/dist/structure/Arrow.svelte.d.ts +15 -0
  415. package/dist/structure/AtomLegend.svelte +815 -0
  416. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  417. package/dist/structure/Bond.svelte +140 -0
  418. package/dist/structure/Bond.svelte.d.ts +9 -0
  419. package/dist/structure/CanvasTooltip.svelte +33 -0
  420. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  421. package/dist/structure/CellSelect.svelte +349 -0
  422. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  423. package/dist/structure/Cylinder.svelte +45 -0
  424. package/dist/structure/Cylinder.svelte.d.ts +10 -0
  425. package/dist/structure/Lattice.svelte +196 -0
  426. package/dist/structure/Lattice.svelte.d.ts +17 -0
  427. package/dist/structure/Structure.svelte +2248 -0
  428. package/dist/structure/Structure.svelte.d.ts +89 -0
  429. package/dist/structure/StructureControls.svelte +1273 -0
  430. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  431. package/dist/structure/StructureExportPane.svelte +252 -0
  432. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  433. package/dist/structure/StructureInfoPane.svelte +737 -0
  434. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  435. package/dist/structure/StructureScene.svelte +2255 -0
  436. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  437. package/dist/structure/atom-properties.d.ts +37 -0
  438. package/dist/structure/atom-properties.js +200 -0
  439. package/dist/structure/bond-order-perception.d.ts +13 -0
  440. package/dist/structure/bond-order-perception.js +384 -0
  441. package/dist/structure/bonding.d.ts +68 -0
  442. package/dist/structure/bonding.js +696 -0
  443. package/dist/structure/export.d.ts +20 -0
  444. package/dist/structure/export.js +727 -0
  445. package/dist/structure/index.d.ts +126 -0
  446. package/dist/structure/index.js +169 -0
  447. package/dist/structure/label-placement.d.ts +14 -0
  448. package/dist/structure/label-placement.js +72 -0
  449. package/dist/structure/measure.d.ts +6 -0
  450. package/dist/structure/measure.js +29 -0
  451. package/dist/structure/parse.d.ts +66 -0
  452. package/dist/structure/parse.js +1392 -0
  453. package/dist/structure/partial-occupancy.d.ts +25 -0
  454. package/dist/structure/partial-occupancy.js +99 -0
  455. package/dist/structure/pbc.d.ts +9 -0
  456. package/dist/structure/pbc.js +123 -0
  457. package/dist/structure/supercell.d.ts +8 -0
  458. package/dist/structure/supercell.js +170 -0
  459. package/dist/structure/validation.d.ts +2 -0
  460. package/dist/structure/validation.js +10 -0
  461. package/dist/symmetry/SymmetryStats.svelte +226 -0
  462. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  463. package/dist/symmetry/WyckoffTable.svelte +120 -0
  464. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  465. package/dist/symmetry/cell-transform.d.ts +12 -0
  466. package/dist/symmetry/cell-transform.js +91 -0
  467. package/dist/symmetry/index.d.ts +43 -0
  468. package/dist/symmetry/index.js +228 -0
  469. package/dist/symmetry/spacegroups.d.ts +9 -0
  470. package/dist/symmetry/spacegroups.js +394 -0
  471. package/dist/table/HeatmapTable.svelte +1833 -0
  472. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  473. package/dist/table/ToggleMenu.svelte +385 -0
  474. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  475. package/dist/table/index.d.ts +74 -0
  476. package/dist/table/index.js +38 -0
  477. package/dist/theme/ThemeControl.svelte +53 -0
  478. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  479. package/dist/theme/index.d.ts +29 -0
  480. package/dist/theme/index.js +79 -0
  481. package/dist/time.d.ts +4 -0
  482. package/dist/time.js +70 -0
  483. package/dist/tooltip/TooltipContent.svelte +58 -0
  484. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  485. package/dist/tooltip/index.d.ts +2 -0
  486. package/dist/tooltip/index.js +1 -0
  487. package/dist/tooltip/types.d.ts +8 -0
  488. package/dist/tooltip/types.js +1 -0
  489. package/dist/trajectory/Trajectory.svelte +1545 -0
  490. package/dist/trajectory/Trajectory.svelte.d.ts +77 -0
  491. package/dist/trajectory/TrajectoryError.svelte +128 -0
  492. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  493. package/dist/trajectory/TrajectoryExportPane.svelte +357 -0
  494. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  495. package/dist/trajectory/TrajectoryInfoPane.svelte +313 -0
  496. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  497. package/dist/trajectory/constants.d.ts +6 -0
  498. package/dist/trajectory/constants.js +7 -0
  499. package/dist/trajectory/extract.d.ts +5 -0
  500. package/dist/trajectory/extract.js +162 -0
  501. package/dist/trajectory/format-detect.d.ts +9 -0
  502. package/dist/trajectory/format-detect.js +76 -0
  503. package/dist/trajectory/frame-reader.d.ts +17 -0
  504. package/dist/trajectory/frame-reader.js +332 -0
  505. package/dist/trajectory/helpers.d.ts +15 -0
  506. package/dist/trajectory/helpers.js +164 -0
  507. package/dist/trajectory/index.d.ts +63 -0
  508. package/dist/trajectory/index.js +126 -0
  509. package/dist/trajectory/parse/ase.d.ts +2 -0
  510. package/dist/trajectory/parse/ase.js +73 -0
  511. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  512. package/dist/trajectory/parse/hdf5.js +127 -0
  513. package/dist/trajectory/parse/index.d.ts +12 -0
  514. package/dist/trajectory/parse/index.js +298 -0
  515. package/dist/trajectory/parse/lammps.d.ts +5 -0
  516. package/dist/trajectory/parse/lammps.js +179 -0
  517. package/dist/trajectory/parse/vasp.d.ts +2 -0
  518. package/dist/trajectory/parse/vasp.js +68 -0
  519. package/dist/trajectory/parse/xyz.d.ts +2 -0
  520. package/dist/trajectory/parse/xyz.js +110 -0
  521. package/dist/trajectory/plotting.d.ts +28 -0
  522. package/dist/trajectory/plotting.js +423 -0
  523. package/dist/trajectory/types.d.ts +11 -0
  524. package/dist/trajectory/types.js +1 -0
  525. package/dist/utils.d.ts +6 -0
  526. package/dist/utils.js +45 -0
  527. package/dist/xrd/XrdPlot.svelte +615 -0
  528. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  529. package/dist/xrd/broadening.d.ts +20 -0
  530. package/dist/xrd/broadening.js +97 -0
  531. package/dist/xrd/calc-xrd.d.ts +37 -0
  532. package/dist/xrd/calc-xrd.js +336 -0
  533. package/dist/xrd/index.d.ts +37 -0
  534. package/dist/xrd/index.js +4 -0
  535. package/dist/xrd/parse.d.ts +13 -0
  536. package/dist/xrd/parse.js +749 -0
  537. package/license +1 -1
  538. package/package.json +232 -1457
  539. package/readme.md +98 -171
  540. package/.vscode/launch.json +0 -13
  541. package/.vscodeignore +0 -7
  542. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  543. package/dist/assets/browser-DdDecX_W.js +0 -1
  544. package/dist/assets/export-qgn-H9y6.js +0 -2
  545. package/dist/assets/main-DiKYzti2.css +0 -1
  546. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  547. package/dist/extension.js +0 -31293
  548. package/dist/src/lib/FilePicker.svelte +0 -360
  549. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  550. package/dist/src/lib/api/mp.ts +0 -26
  551. package/dist/src/lib/api/optimade.ts +0 -204
  552. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  553. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  554. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  555. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  556. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  557. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  558. package/dist/src/lib/brillouin/compute.ts +0 -529
  559. package/dist/src/lib/brillouin/index.ts +0 -8
  560. package/dist/src/lib/brillouin/types.ts +0 -51
  561. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  562. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  563. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  564. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  565. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  566. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  567. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  568. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  569. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  570. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  571. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  572. package/dist/src/lib/colors/index.ts +0 -249
  573. package/dist/src/lib/composition/BarChart.svelte +0 -297
  574. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  575. package/dist/src/lib/composition/Composition.svelte +0 -165
  576. package/dist/src/lib/composition/Formula.svelte +0 -268
  577. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  578. package/dist/src/lib/composition/PieChart.svelte +0 -323
  579. package/dist/src/lib/composition/format.ts +0 -155
  580. package/dist/src/lib/composition/index.ts +0 -37
  581. package/dist/src/lib/composition/parse.ts +0 -605
  582. package/dist/src/lib/constants.ts +0 -134
  583. package/dist/src/lib/controls.ts +0 -42
  584. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  585. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  586. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  587. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  588. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  589. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  590. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  591. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  592. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  593. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  594. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  595. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  596. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  597. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  598. package/dist/src/lib/convex-hull/index.ts +0 -202
  599. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  600. package/dist/src/lib/convex-hull/types.ts +0 -267
  601. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  602. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  603. package/dist/src/lib/coordination/index.ts +0 -9
  604. package/dist/src/lib/effects.svelte.ts +0 -48
  605. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  606. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  607. package/dist/src/lib/element/ElementStats.svelte +0 -80
  608. package/dist/src/lib/element/ElementTile.svelte +0 -484
  609. package/dist/src/lib/element/data.ts +0 -14
  610. package/dist/src/lib/element/index.ts +0 -8
  611. package/dist/src/lib/element/types.ts +0 -62
  612. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  613. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  614. package/dist/src/lib/feedback/index.ts +0 -4
  615. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  616. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  617. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  618. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  619. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  620. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  621. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  622. package/dist/src/lib/fermi-surface/export.ts +0 -64
  623. package/dist/src/lib/fermi-surface/index.ts +0 -14
  624. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  625. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  626. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  627. package/dist/src/lib/fermi-surface/types.ts +0 -159
  628. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  629. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  630. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  631. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  632. package/dist/src/lib/icons.ts +0 -650
  633. package/dist/src/lib/index.ts +0 -61
  634. package/dist/src/lib/io/decompress.ts +0 -92
  635. package/dist/src/lib/io/export.ts +0 -385
  636. package/dist/src/lib/io/fetch.ts +0 -46
  637. package/dist/src/lib/io/file-drop.ts +0 -51
  638. package/dist/src/lib/io/index.ts +0 -7
  639. package/dist/src/lib/io/is-binary.ts +0 -24
  640. package/dist/src/lib/io/types.ts +0 -8
  641. package/dist/src/lib/io/url-drop.ts +0 -141
  642. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  643. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  644. package/dist/src/lib/isosurface/index.ts +0 -7
  645. package/dist/src/lib/isosurface/parse.ts +0 -656
  646. package/dist/src/lib/isosurface/slice.ts +0 -175
  647. package/dist/src/lib/isosurface/types.ts +0 -309
  648. package/dist/src/lib/labels.ts +0 -320
  649. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  650. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  651. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  652. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  653. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  654. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  655. package/dist/src/lib/layout/fullscreen.ts +0 -65
  656. package/dist/src/lib/layout/index.ts +0 -11
  657. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  658. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  659. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  660. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  661. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  662. package/dist/src/lib/marching-cubes.ts +0 -614
  663. package/dist/src/lib/math.ts +0 -1081
  664. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  665. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  666. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  667. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  668. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  669. package/dist/src/lib/overlays/index.ts +0 -3
  670. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  671. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  672. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  673. package/dist/src/lib/periodic-table/index.ts +0 -12
  674. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  675. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  676. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  677. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  678. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  679. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  680. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  681. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  682. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  683. package/dist/src/lib/phase-diagram/index.ts +0 -13
  684. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  685. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  686. package/dist/src/lib/phase-diagram/types.ts +0 -144
  687. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  688. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  689. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  690. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  691. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  692. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  693. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  694. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  695. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  696. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  697. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  698. package/dist/src/lib/plot/Line.svelte +0 -84
  699. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  700. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  701. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  702. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  703. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  704. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  705. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  706. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  707. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  708. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  709. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  710. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  711. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  712. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  713. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  714. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  715. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  716. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  717. package/dist/src/lib/plot/auto-place.ts +0 -184
  718. package/dist/src/lib/plot/axis-utils.ts +0 -122
  719. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  720. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  721. package/dist/src/lib/plot/data-transform.ts +0 -69
  722. package/dist/src/lib/plot/defaults.ts +0 -9
  723. package/dist/src/lib/plot/fill-utils.ts +0 -494
  724. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  725. package/dist/src/lib/plot/index.ts +0 -53
  726. package/dist/src/lib/plot/interactions.ts +0 -119
  727. package/dist/src/lib/plot/layout.ts +0 -425
  728. package/dist/src/lib/plot/reference-line.ts +0 -426
  729. package/dist/src/lib/plot/scales.ts +0 -654
  730. package/dist/src/lib/plot/svg.ts +0 -23
  731. package/dist/src/lib/plot/types.ts +0 -1144
  732. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  733. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  734. package/dist/src/lib/plot/utils.ts +0 -11
  735. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  736. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  737. package/dist/src/lib/rdf/index.ts +0 -27
  738. package/dist/src/lib/sanitize.ts +0 -126
  739. package/dist/src/lib/settings.ts +0 -1479
  740. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  741. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  742. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  743. package/dist/src/lib/spectral/Dos.svelte +0 -697
  744. package/dist/src/lib/spectral/helpers.ts +0 -1381
  745. package/dist/src/lib/spectral/index.ts +0 -8
  746. package/dist/src/lib/spectral/types.ts +0 -112
  747. package/dist/src/lib/state.svelte.ts +0 -64
  748. package/dist/src/lib/structure/Arrow.svelte +0 -72
  749. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  750. package/dist/src/lib/structure/Bond.svelte +0 -140
  751. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  752. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  753. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  754. package/dist/src/lib/structure/Lattice.svelte +0 -196
  755. package/dist/src/lib/structure/Structure.svelte +0 -2248
  756. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  757. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  758. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  759. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  760. package/dist/src/lib/structure/atom-properties.ts +0 -316
  761. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  762. package/dist/src/lib/structure/bonding.ts +0 -944
  763. package/dist/src/lib/structure/export.ts +0 -861
  764. package/dist/src/lib/structure/index.ts +0 -291
  765. package/dist/src/lib/structure/label-placement.ts +0 -130
  766. package/dist/src/lib/structure/measure.ts +0 -45
  767. package/dist/src/lib/structure/parse.ts +0 -1705
  768. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  769. package/dist/src/lib/structure/pbc.ts +0 -164
  770. package/dist/src/lib/structure/supercell.ts +0 -226
  771. package/dist/src/lib/structure/validation.ts +0 -11
  772. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  773. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  774. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  775. package/dist/src/lib/symmetry/index.ts +0 -348
  776. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  777. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  778. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  779. package/dist/src/lib/table/index.ts +0 -139
  780. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  781. package/dist/src/lib/theme/index.ts +0 -107
  782. package/dist/src/lib/time.ts +0 -71
  783. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  784. package/dist/src/lib/tooltip/index.ts +0 -2
  785. package/dist/src/lib/tooltip/types.ts +0 -13
  786. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  787. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  788. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  789. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  790. package/dist/src/lib/trajectory/constants.ts +0 -7
  791. package/dist/src/lib/trajectory/extract.ts +0 -196
  792. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  793. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  794. package/dist/src/lib/trajectory/helpers.ts +0 -217
  795. package/dist/src/lib/trajectory/index.ts +0 -218
  796. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  797. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  798. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  799. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  800. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  801. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  802. package/dist/src/lib/trajectory/plotting.ts +0 -599
  803. package/dist/src/lib/trajectory/types.ts +0 -13
  804. package/dist/src/lib/utils.ts +0 -56
  805. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  806. package/dist/src/lib/xrd/broadening.ts +0 -130
  807. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  808. package/dist/src/lib/xrd/index.ts +0 -38
  809. package/dist/src/lib/xrd/parse.ts +0 -858
  810. package/dist/webview.js +0 -29421
  811. package/icon.png +0 -0
  812. package/matterviz-0.3.2.vsix +0 -0
  813. package/matterviz-0.3.4.vsix +0 -0
  814. package/matterviz-0.3.5.vsix +0 -0
  815. package/scripts/sync-config.ts +0 -101
  816. package/src/declarations.d.ts +0 -2
  817. package/src/extension.ts +0 -972
  818. package/src/node-io.ts +0 -65
  819. package/src/types.ts +0 -17
  820. package/src/webview/JsonBrowser.svelte +0 -1079
  821. package/src/webview/PlotPanel.svelte +0 -346
  822. package/src/webview/detect.ts +0 -444
  823. package/src/webview/main.ts +0 -764
  824. package/src/webview/plot-utils.ts +0 -250
  825. package/test-fixtures/all-viz-types.json.gz +0 -0
  826. package/test-fixtures/plot-demo-data.json.gz +0 -0
  827. package/tests/detect.test.ts +0 -604
  828. package/tests/extension.test.ts +0 -2041
  829. package/tests/node-io.test.ts +0 -39
  830. package/tests/plot-utils.test.ts +0 -302
  831. package/tests/vite-plugin-json-gz.test.ts +0 -114
  832. package/tests/vscode-mock.ts +0 -18
  833. package/tests/webview.test.ts +0 -231
  834. package/tsconfig.json +0 -20
  835. package/vite-plugin-json-gz.ts +0 -29
  836. package/vite.config.ts +0 -34
  837. package/vite.extension.config.ts +0 -34
  838. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  839. /package/dist/{src/lib/Icon.svelte → Icon.svelte} +0 -0
  840. /package/dist/{src/lib/app.css → app.css} +0 -0
  841. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  842. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  843. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  844. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  845. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  846. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  847. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  848. /package/dist/{src/lib/convex-hull → convex-hull}/TemperatureSlider.svelte +0 -0
  849. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  850. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  851. /package/dist/{src/lib/element → element}/data.json +0 -0
  852. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  853. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  854. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  855. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  856. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  857. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  858. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  859. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  860. /package/dist/{src/lib/plot → plot}/FillArea.svelte +0 -0
  861. /package/dist/{src/lib/plot → plot}/ReferenceLine.svelte +0 -0
  862. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  863. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -0,0 +1,1032 @@
1
+ // Helper utilities for band structure and DOS data processing
2
+ import { SUBSCRIPT_MAP } from '../labels';
3
+ import { centered_frac, euclidean_dist } from '../math';
4
+ const is_subscript_key = (key) => key in SUBSCRIPT_MAP;
5
+ // Check if range is a valid [min, max] tuple (strict 2-element array of finite numbers)
6
+ export const is_valid_range = (range) => Array.isArray(range) &&
7
+ range.length === 2 &&
8
+ Number.isFinite(range[0]) &&
9
+ Number.isFinite(range[1]);
10
+ // Check if two ranges are approximately equal (within tolerance)
11
+ // Returns false if either range is invalid (null, undefined, or fails is_valid_range)
12
+ // Negative tol is clamped to 0; tol=0 checks exact equality
13
+ export const ranges_equal = (a, b, tol = 0.001) => {
14
+ const safe_tol = Math.max(0, tol);
15
+ return (is_valid_range(a) &&
16
+ is_valid_range(b) &&
17
+ Math.abs(a[0] - b[0]) <= safe_tol &&
18
+ Math.abs(a[1] - b[1]) <= safe_tol);
19
+ };
20
+ export const axis_with_range = (axis, range, label) => ({
21
+ ...axis,
22
+ ...(label !== undefined && { label }),
23
+ ...(is_valid_range(range) && { range }),
24
+ });
25
+ // Detect which plot triggered a zoom change and return the new synced range.
26
+ // Returns null to reset to shared range, undefined for no change, or Vec2 for new zoom.
27
+ export function detect_zoom_change(bands_range, dos_range, shared_range, current_synced, dos_enabled = true) {
28
+ const bands_valid = is_valid_range(bands_range);
29
+ const dos_valid = dos_enabled && is_valid_range(dos_range);
30
+ // Reset if either becomes invalid (auto-range reset) or returns to shared range
31
+ if (current_synced !== null) {
32
+ const bands_at_shared = bands_valid && ranges_equal(bands_range, shared_range);
33
+ const dos_at_shared = dos_valid && ranges_equal(dos_range, shared_range);
34
+ if (bands_at_shared || dos_at_shared || !bands_valid || (dos_enabled && !dos_valid)) {
35
+ return null;
36
+ }
37
+ }
38
+ // Check for new zoom from either plot
39
+ const bands_is_new = bands_valid &&
40
+ !ranges_equal(bands_range, shared_range) &&
41
+ !ranges_equal(bands_range, current_synced);
42
+ const dos_is_new = dos_valid &&
43
+ !ranges_equal(dos_range, shared_range) &&
44
+ !ranges_equal(dos_range, current_synced);
45
+ if (bands_is_new && !dos_is_new)
46
+ return bands_range;
47
+ if (dos_is_new && !bands_is_new)
48
+ return dos_range;
49
+ return undefined; // no change
50
+ }
51
+ // Physical constants for unit conversions (SI units)
52
+ const PLANCK = 6.62607015e-34; // J⋅s
53
+ const EV_TO_J = 1.602176634e-19; // J
54
+ const C_LIGHT = 299792458; // m/s
55
+ const THz_TO_HZ = 1e12;
56
+ const THz_TO_EV = (PLANCK * THz_TO_HZ) / EV_TO_J;
57
+ const THz_TO_MEV = THz_TO_EV * 1000;
58
+ const THz_TO_HA = THz_TO_EV / 27.211386245988; // Hartree
59
+ const THz_TO_CM = THz_TO_HZ / (C_LIGHT * 100); // cm^-1 (c in cm/s)
60
+ // Band structure constants
61
+ export const IMAGINARY_MODE_NOISE_THRESHOLD = 0.005; // Clamp negatives < 0.5% as noise
62
+ // Convert symmetry point symbols to pretty-printed versions.
63
+ // Handles Greek letters (both plain and LaTeX backslash-prefixed) and subscripts.
64
+ export function pretty_sym_point(symbol) {
65
+ if (!symbol)
66
+ return ``;
67
+ // Remove underscores (htmlify maps S0 → S<sub>0</sub> but leaves S_0 as is)
68
+ // Replace common symmetry point names with Greek letters
69
+ // Handle both plain names (GAMMA) and LaTeX notation (\Gamma) from pymatgen
70
+ // Handle subscripts: convert S0 to S₀, K1 to K₁, Γ1 to Γ₁, etc.
71
+ // Use \p{L} to match any Unicode letter (not just ASCII A-Z)
72
+ return symbol
73
+ .replace(/_/g, ``)
74
+ .replace(/\\?GAMMA/gi, `Γ`)
75
+ .replace(/\\?DELTA/gi, `Δ`)
76
+ .replace(/\\?SIGMA/gi, `Σ`)
77
+ .replace(/\\?LAMBDA/gi, `Λ`)
78
+ .replace(/(\p{L})(\d+)/gu, (_, letter, num) => letter +
79
+ num
80
+ .split(``)
81
+ .map((digit) => (is_subscript_key(digit) ? SUBSCRIPT_MAP[digit] : digit))
82
+ .join(``));
83
+ }
84
+ // Create segment key from start and end labels
85
+ export const get_segment_key = (start_label, end_label) => `${start_label ?? `null`}_${end_label ?? `null`}`;
86
+ // Get ordered segment keys from a band structure, preserving physical path order.
87
+ export const get_ordered_segments = (band_struct, segments) => {
88
+ if (!band_struct)
89
+ return Array.from(segments);
90
+ const ordered = band_struct.branches.map((branch) => get_segment_key(band_struct.qpoints[branch.start_index]?.label ?? undefined, band_struct.qpoints[branch.end_index]?.label ?? undefined));
91
+ const remaining = Array.from(segments).filter((seg) => !ordered.includes(seg));
92
+ return [...ordered, ...remaining];
93
+ };
94
+ // Scale segment distances to a target x-axis range [x_start, x_end].
95
+ // Used by both band line series and fat band ribbons for consistent x-axis positioning.
96
+ export function scale_segment_distances(segment_distances, x_start, x_end) {
97
+ if (segment_distances.length === 0)
98
+ return [];
99
+ const dist_min = segment_distances[0];
100
+ const dist_range = (segment_distances.at(-1) ?? dist_min) - dist_min;
101
+ if (dist_range === 0) {
102
+ // All points at same distance - place at midpoint
103
+ return segment_distances.map(() => (x_start + x_end) / 2);
104
+ }
105
+ return segment_distances.map((dist) => x_start + ((dist - dist_min) / dist_range) * (x_end - x_start));
106
+ }
107
+ // Get ribbon config for a specific band structure label.
108
+ // Supports both single global config (with primitive keys like opacity, max_width, scale, color)
109
+ // and per-structure config (keyed by structure label).
110
+ // Distinguishes between a global config and a per-structure config by checking if any
111
+ // primitive-typed keys (opacity, max_width, scale, color) exist at the top level.
112
+ export function get_ribbon_config(ribbon_config, label) {
113
+ const defaults = { opacity: 0.3, max_width: 6, scale: 1 };
114
+ const config_record = ribbon_config;
115
+ // Check for primitive config values (not objects) to distinguish single vs per-structure config
116
+ const has_primitive = [`opacity`, `max_width`, `scale`, `color`].some((key) => {
117
+ const value = config_record[key];
118
+ return value !== undefined && typeof value !== `object`;
119
+ });
120
+ if (has_primitive) {
121
+ // Single global config with primitive values - apply to all structures
122
+ return { ...defaults, ...ribbon_config };
123
+ }
124
+ // Otherwise, treat as Record<string, RibbonConfig> and look up by label
125
+ // Empty label skips lookup and uses defaults only
126
+ const label_config = label ? config_record[label] : undefined;
127
+ return {
128
+ ...defaults,
129
+ ...(label_config && typeof label_config === `object` ? label_config : {}),
130
+ };
131
+ }
132
+ // Extract tick positions and labels for a band structure plot.
133
+ export function get_band_xaxis_ticks(band_struct, branches = []) {
134
+ const ticks_x_pos = [];
135
+ const tick_labels = [];
136
+ let prev_label = band_struct.qpoints[0]?.label || null;
137
+ let prev_branch = band_struct.branches[0]?.name || null;
138
+ // Convert branches to Set for consistent handling
139
+ const branches_set = Array.isArray(branches) ? new Set(branches) : branches;
140
+ for (let idx = 0; idx < band_struct.qpoints.length; idx++) {
141
+ const point = band_struct.qpoints[idx];
142
+ if (point.label === null)
143
+ continue;
144
+ // Find which branch this point belongs to
145
+ const branch_names = band_struct.branches
146
+ .filter((branch) => branch.start_index <= idx && idx <= branch.end_index)
147
+ .map((branch) => branch.name);
148
+ const this_branch = branch_names[0] || null;
149
+ if (point.label !== prev_label && prev_branch !== this_branch) {
150
+ // Branch transition - combine labels
151
+ tick_labels[tick_labels.length - 1] = `${prev_label || ``}|${point.label}`;
152
+ ticks_x_pos[ticks_x_pos.length - 1] = band_struct.distance[idx];
153
+ }
154
+ else if (branches_set.size === 0 || (this_branch && branches_set.has(this_branch))) {
155
+ tick_labels.push(point.label);
156
+ ticks_x_pos.push(band_struct.distance[idx]);
157
+ }
158
+ prev_label = point.label;
159
+ prev_branch = this_branch;
160
+ }
161
+ return [ticks_x_pos, tick_labels.map(pretty_sym_point)];
162
+ }
163
+ // Convert frequencies from THz to specified units.
164
+ export function convert_frequencies(frequencies, unit = `THz`) {
165
+ const conversion_factors = {
166
+ THz: 1,
167
+ eV: THz_TO_EV,
168
+ meV: THz_TO_MEV,
169
+ Ha: THz_TO_HA,
170
+ 'cm-1': THz_TO_CM,
171
+ };
172
+ const factor = conversion_factors[unit];
173
+ if (!factor) {
174
+ const valid_units = Object.keys(conversion_factors).join(`, `);
175
+ throw new Error(`Invalid unit: ${unit}. Must be one of ${valid_units}`);
176
+ }
177
+ return frequencies.map((freq) => freq * factor);
178
+ }
179
+ // Normalize DOS densities according to specified mode.
180
+ export function normalize_densities(densities, freqs_or_energies, mode) {
181
+ if (!mode)
182
+ return densities;
183
+ const normalized = [...densities];
184
+ if (mode === `max`) {
185
+ const max_val = Math.max(...normalized);
186
+ if (max_val === 0)
187
+ return normalized;
188
+ return normalized.map((dens) => dens / max_val);
189
+ }
190
+ else if (mode === `sum`) {
191
+ const sum = normalized.reduce((acc, d) => acc + d, 0);
192
+ if (sum === 0)
193
+ return normalized;
194
+ return normalized.map((dens) => dens / sum);
195
+ }
196
+ else if (mode === `integral`) {
197
+ if (freqs_or_energies.length < 2)
198
+ return normalized;
199
+ const bin_width = freqs_or_energies[1] - freqs_or_energies[0];
200
+ if (bin_width === 0)
201
+ return normalized;
202
+ const sum = normalized.reduce((acc, d) => acc + d, 0);
203
+ if (sum === 0)
204
+ return normalized;
205
+ return normalized.map((dens) => dens / (sum * bin_width));
206
+ }
207
+ return normalized;
208
+ }
209
+ // Simple LRU cache for Gaussian smearing results
210
+ // Key: hash of (frequencies, densities, sigma), Value: smeared densities
211
+ const SMEARING_CACHE_MAX_SIZE = 10;
212
+ const smearing_cache = new Map();
213
+ // FNV-1a hash for number arrays (fast, good distribution, O(n))
214
+ function fnv1a_hash(arr) {
215
+ let hash = 2166136261; // FNV offset basis
216
+ for (const val of arr) {
217
+ // Convert float to int32 bits for consistent hashing
218
+ const bits = new Float64Array([val]);
219
+ const int_view = new Uint32Array(bits.buffer);
220
+ hash ^= int_view[0];
221
+ hash = Math.imul(hash, 16777619); // FNV prime
222
+ hash ^= int_view[1];
223
+ hash = Math.imul(hash, 16777619);
224
+ }
225
+ return hash >>> 0; // Ensure unsigned
226
+ }
227
+ // Generate cache key using FNV-1a hash over full arrays (O(n), low collision risk)
228
+ function generate_smearing_cache_key(freqs_or_energies, densities, sigma) {
229
+ const len = freqs_or_energies.length;
230
+ if (len === 0)
231
+ return `0:${sigma.toFixed(6)}:0:0`;
232
+ return `${len}:${sigma.toFixed(6)}:${fnv1a_hash(freqs_or_energies).toString(16)}:${fnv1a_hash(densities).toString(16)}`;
233
+ }
234
+ // Core Gaussian smearing computation (unmemoized)
235
+ function apply_gaussian_smearing_core(freqs_or_energies, densities, sigma) {
236
+ const orig_sum = densities.reduce((acc, d) => acc + d, 0);
237
+ if (sigma <= 0 || orig_sum === 0)
238
+ return densities;
239
+ const smeared = Array(densities.length).fill(0);
240
+ const truncation_width = 4; // Truncate Gaussian at ±4σ (contribution < 0.01%)
241
+ for (let idx = 0; idx < freqs_or_energies.length; idx++) {
242
+ const energy = freqs_or_energies[idx];
243
+ const cutoff = truncation_width * sigma;
244
+ for (let jdx = 0; jdx < freqs_or_energies.length; jdx++) {
245
+ const e_j = freqs_or_energies[jdx];
246
+ const delta = Math.abs(energy - e_j);
247
+ // Skip points beyond truncation width
248
+ if (delta > cutoff)
249
+ continue;
250
+ const gaussian = Math.exp(-((energy - e_j) ** 2) / (2 * sigma ** 2));
251
+ smeared[idx] += densities[jdx] * gaussian;
252
+ }
253
+ }
254
+ // Normalize to preserve integral
255
+ const smeared_sum = smeared.reduce((acc, d) => acc + d, 0);
256
+ if (smeared_sum === 0)
257
+ return densities;
258
+ const normalization = orig_sum / smeared_sum;
259
+ return smeared.map((dens) => dens * normalization);
260
+ }
261
+ // Apply Gaussian smearing to DOS densities with memoization.
262
+ // Uses truncated Gaussian (±4σ) for O(n·w) complexity instead of O(n²).
263
+ // Results are cached using an LRU cache to avoid recomputation on reactive updates.
264
+ export function apply_gaussian_smearing(freqs_or_energies, densities, sigma) {
265
+ // Fast path: no smearing needed
266
+ if (sigma <= 0)
267
+ return densities;
268
+ const cache_key = generate_smearing_cache_key(freqs_or_energies, densities, sigma);
269
+ // Check cache
270
+ const cached = smearing_cache.get(cache_key);
271
+ if (cached) {
272
+ // Move to end (LRU behavior: most recently used last)
273
+ smearing_cache.delete(cache_key);
274
+ smearing_cache.set(cache_key, cached);
275
+ return cached;
276
+ }
277
+ // Compute and cache
278
+ const result = apply_gaussian_smearing_core(freqs_or_energies, densities, sigma);
279
+ // Evict oldest entry if cache is full (LRU: first entry is oldest)
280
+ if (smearing_cache.size >= SMEARING_CACHE_MAX_SIZE) {
281
+ const oldest_key = smearing_cache.keys().next().value;
282
+ if (oldest_key !== undefined)
283
+ smearing_cache.delete(oldest_key);
284
+ }
285
+ smearing_cache.set(cache_key, result);
286
+ return result;
287
+ }
288
+ // Clear the smearing cache (useful for testing or memory management)
289
+ export function clear_smearing_cache() {
290
+ smearing_cache.clear();
291
+ }
292
+ // Type guards for pymatgen qpoint formats
293
+ const is_vec3 = (val) => Array.isArray(val) && val.length >= 3 && val.slice(0, 3).every(Number.isFinite);
294
+ const is_kpoint = (val) => !!val && typeof val === `object` && `frac_coords` in val && is_vec3(val.frac_coords);
295
+ const is_pymatgen_format = (obj) => {
296
+ // Check for explicit pymatgen markers
297
+ if (typeof obj[`@class`] === `string` || typeof obj[`@module`] === `string`) {
298
+ return true;
299
+ }
300
+ // Check for pymatgen-style qpoints (phonon) or kpoints (electronic) without branches
301
+ const points = obj.qpoints ?? obj.kpoints;
302
+ if (Array.isArray(points) && points.length > 0 && !Array.isArray(obj.branches)) {
303
+ return is_vec3(points[0]) || is_kpoint(points[0]);
304
+ }
305
+ return false;
306
+ };
307
+ // Extract frac_coords/label from pymatgen qpoint, matching label from labels_dict if needed
308
+ const parse_qpoint = (qpt, labels_dict) => {
309
+ const frac_coords = is_vec3(qpt)
310
+ ? [qpt[0], qpt[1], qpt[2]]
311
+ : is_kpoint(qpt)
312
+ ? qpt.frac_coords
313
+ : null;
314
+ if (!frac_coords)
315
+ return null;
316
+ const label = (is_kpoint(qpt) && typeof qpt.label === `string` && qpt.label) ||
317
+ Object.entries(labels_dict ?? {}).find(([, c]) => euclidean_dist(frac_coords, c) < 1e-4)?.[0] ||
318
+ null;
319
+ return { label, frac_coords };
320
+ };
321
+ // Inverse conversion factors (derived from THz_TO_* for consistency)
322
+ const EV_TO_THZ = 1 / THz_TO_EV;
323
+ const CM_TO_THZ = 1 / THz_TO_CM;
324
+ // Spin key constants for pymatgen spin-polarized data
325
+ const SPIN_UP_KEYS = [`1`, `Spin.up`];
326
+ const SPIN_DOWN_KEYS = [`-1`, `Spin.down`];
327
+ // Extract both spin channels from pymatgen spin-keyed data.
328
+ // Returns { up: T, down: T | null } where down is null for non-spin-polarized data.
329
+ export function extract_spin_channels(data) {
330
+ if (Array.isArray(data))
331
+ return { up: data, down: null };
332
+ if (data && typeof data === `object`) {
333
+ const record = data;
334
+ let spin_up = null;
335
+ let spin_down = null;
336
+ // Extract spin-up channel
337
+ for (const key of SPIN_UP_KEYS) {
338
+ if (key in record) {
339
+ spin_up = record[key];
340
+ break;
341
+ }
342
+ }
343
+ // Extract spin-down channel
344
+ for (const key of SPIN_DOWN_KEYS) {
345
+ if (key in record) {
346
+ spin_down = record[key];
347
+ break;
348
+ }
349
+ }
350
+ // Fall back to first key if no spin-up key found
351
+ if (spin_up === null) {
352
+ const keys = Object.keys(record);
353
+ if (keys.length > 0)
354
+ spin_up = record[keys[0]];
355
+ }
356
+ if (spin_up === null)
357
+ return null;
358
+ return { up: spin_up, down: spin_down };
359
+ }
360
+ return null;
361
+ }
362
+ // Convert pymatgen PhononBandStructureSymmLine or BandStructure to matterviz format
363
+ function convert_pymatgen_band_structure(pmg) {
364
+ // Support both qpoints (phonon) and kpoints (electronic)
365
+ const raw_qpts = (pmg.qpoints ?? pmg.kpoints);
366
+ // Handle bands in multiple formats:
367
+ // 1. Standard pymatgen: bands as dict with spin keys {1: [[...], ...]}
368
+ // 2. Custom phonon format: frequencies_cm as 2D array [[...], ...]
369
+ // 3. Already normalized: bands as 2D array [[...], ...]
370
+ const spin_channels = extract_spin_channels(pmg.bands);
371
+ let raw_bands = spin_channels?.up ?? null;
372
+ let raw_spin_down_bands = spin_channels?.down ?? null;
373
+ const has_frequencies_cm = Array.isArray(pmg.frequencies_cm);
374
+ if (!raw_bands && has_frequencies_cm) {
375
+ // Phonon format: frequencies_cm is [n_qpoints x n_branches] - needs transpose
376
+ const freqs = pmg.frequencies_cm;
377
+ if (freqs.length > 0 && Array.isArray(freqs[0])) {
378
+ // Transpose: [n_qpoints x n_branches] -> [n_branches x n_qpoints]
379
+ raw_bands = Array.from({ length: freqs[0].length }, (_, band_idx) => freqs.map((qpt_freqs) => qpt_freqs[band_idx]));
380
+ raw_spin_down_bands = null;
381
+ }
382
+ }
383
+ const labels_dict = pmg.labels_dict;
384
+ const lattice_rec = pmg.lattice_rec;
385
+ // Determine unit: cm-1 if frequencies_cm present, else check explicit unit or default to THz
386
+ const unit = pmg.unit?.toLowerCase() ?? (has_frequencies_cm ? `cm-1` : `thz`);
387
+ if (!Array.isArray(raw_qpts) ||
388
+ !Array.isArray(raw_bands) ||
389
+ !raw_qpts.length ||
390
+ !raw_bands.length)
391
+ return null;
392
+ const qpoints = raw_qpts
393
+ .map((qpoint) => parse_qpoint(qpoint, labels_dict))
394
+ .filter((qpoint) => qpoint !== null);
395
+ if (!qpoints.length)
396
+ return null;
397
+ // Step distances and discontinuity detection (5x median threshold)
398
+ const steps = qpoints
399
+ .slice(1)
400
+ .map((qpoint, idx) => euclidean_dist(qpoints[idx].frac_coords, qpoint.frac_coords));
401
+ const sorted = steps.slice().sort((a, b) => a - b);
402
+ const threshold = (sorted[Math.floor(sorted.length / 2)] ?? 0) * 5;
403
+ const disc_set = new Set(steps
404
+ .map((step, idx) => (step > threshold ? idx + 1 : -1))
405
+ .filter((disc_idx) => disc_idx >= 0));
406
+ // Cumulative distance (skip discontinuities)
407
+ const distance = steps.reduce((acc, step, idx) => [...acc, disc_set.has(idx + 1) ? acc[idx] : acc[idx] + step], [0]);
408
+ // Use pymatgen's branches if available - they correctly handle discontinuities
409
+ // Otherwise, infer branches from discontinuities (robust fallback covering all qpoints)
410
+ const pmg_branches = pmg.branches;
411
+ let branches = [];
412
+ if (Array.isArray(pmg_branches) && pmg_branches.length > 0) {
413
+ // Validate and use pymatgen branches directly
414
+ branches = pmg_branches.filter((branch) => typeof branch.start_index === `number` &&
415
+ typeof branch.end_index === `number` &&
416
+ branch.start_index >= 0 &&
417
+ branch.end_index < qpoints.length &&
418
+ branch.start_index <= branch.end_index);
419
+ }
420
+ // Fallback: infer branches from discontinuities when none provided or all invalid
421
+ if (branches.length === 0) {
422
+ console.warn(`Band structure missing 'branches' field - inferring from path discontinuities`);
423
+ // Discontinuity indices mark points where the path jumps (disc before that index)
424
+ // Create continuous segments between discontinuities
425
+ const disc_indices = [...disc_set].sort((a, b) => a - b);
426
+ // Segment boundaries: [0, first_disc), [first_disc, second_disc), ..., [last_disc, end]
427
+ const segment_starts = [0, ...disc_indices];
428
+ const segment_ends = [...disc_indices.map((idx) => idx - 1), qpoints.length - 1];
429
+ branches = segment_starts
430
+ .map((start, idx) => {
431
+ const end = segment_ends[idx];
432
+ const start_label = qpoints[start]?.label ?? `?`;
433
+ const end_label = qpoints[end]?.label ?? `?`;
434
+ return {
435
+ start_index: start,
436
+ end_index: end,
437
+ name: `${start_label}-${end_label}`,
438
+ };
439
+ })
440
+ .filter((branch) => branch.start_index <= branch.end_index);
441
+ }
442
+ if (!branches.length) {
443
+ branches.push({ start_index: 0, end_index: qpoints.length - 1, name: `path` });
444
+ }
445
+ // Convert bands to THz based on input unit
446
+ const convert_to_thz = (val) => {
447
+ if (unit === `ev`)
448
+ return val * EV_TO_THZ;
449
+ if (unit === `cm-1`)
450
+ return val * CM_TO_THZ;
451
+ return val; // THz (default) - no conversion
452
+ };
453
+ const converted_bands = raw_bands.map((band) => band.map(convert_to_thz));
454
+ const valid_spin_down_bands = Array.isArray(raw_spin_down_bands) &&
455
+ raw_spin_down_bands.length === raw_bands.length &&
456
+ raw_spin_down_bands.every((band, band_idx) => Array.isArray(band) && band.length === raw_bands[band_idx]?.length)
457
+ ? raw_spin_down_bands
458
+ : null;
459
+ const converted_spin_down_bands = valid_spin_down_bands?.map((band) => band.map(convert_to_thz));
460
+ return {
461
+ qpoints,
462
+ branches,
463
+ distance,
464
+ bands: converted_bands,
465
+ spin_down_bands: converted_spin_down_bands,
466
+ nb_bands: raw_bands.length,
467
+ labels_dict: labels_dict ?? {},
468
+ recip_lattice: {
469
+ matrix: lattice_rec?.matrix ?? [
470
+ [1, 0, 0],
471
+ [0, 1, 0],
472
+ [0, 0, 1],
473
+ ],
474
+ },
475
+ };
476
+ }
477
+ export function normalize_band_structure(bs) {
478
+ if (!bs || typeof bs !== `object`)
479
+ return null;
480
+ const band_struct = bs;
481
+ // Check if this is pymatgen format and convert if so
482
+ if (is_pymatgen_format(band_struct)) {
483
+ return convert_pymatgen_band_structure(band_struct);
484
+ }
485
+ // Standard matterviz format validation
486
+ const { qpoints, branches, bands, distance } = band_struct;
487
+ if (!Array.isArray(qpoints) ||
488
+ !Array.isArray(branches) ||
489
+ !Array.isArray(bands) ||
490
+ !Array.isArray(distance))
491
+ return null;
492
+ // Validate array lengths and branch indices
493
+ const n_qpts = qpoints.length;
494
+ if (distance.length !== n_qpts ||
495
+ bands.some((band) => !Array.isArray(band) || band.length !== n_qpts) ||
496
+ branches.some((branch) => typeof branch.start_index !== `number` ||
497
+ typeof branch.end_index !== `number` ||
498
+ branch.start_index < 0 ||
499
+ branch.end_index >= n_qpts ||
500
+ branch.start_index > branch.end_index))
501
+ return null;
502
+ return band_struct;
503
+ }
504
+ // Validate and normalize a DOS object.
505
+ // Supports both matterviz and pymatgen formats.
506
+ // Also auto-detects and converts cm⁻¹ to THz for legacy data (disable with auto_convert_units: false).
507
+ export function normalize_dos(dos, options = {}) {
508
+ const { auto_convert_units = true } = options;
509
+ if (!dos || typeof dos !== `object`)
510
+ return null;
511
+ const dos_obj = dos;
512
+ // Check for pymatgen format (has @class or @module)
513
+ const is_pymatgen = typeof dos_obj[`@class`] === `string` || typeof dos_obj[`@module`] === `string`;
514
+ const { frequencies, energies, spin_polarized } = dos_obj;
515
+ // Handle densities as either array or dict with spin keys (pymatgen format)
516
+ // Pymatgen stores densities as {1: [...], -1: [...]} or {"Spin.up": [...], ...}
517
+ const spin_channels = extract_spin_channels(dos_obj.densities);
518
+ if (!spin_channels)
519
+ return null;
520
+ const densities = spin_channels.up;
521
+ // Use extracted spin-down or fallback to explicit field (for already-normalized DosData)
522
+ const spin_down_densities = spin_channels.down ?? dos_obj.spin_down_densities ?? null;
523
+ if (!Array.isArray(densities))
524
+ return null;
525
+ // Phonon DOS: has frequencies
526
+ if (Array.isArray(frequencies)) {
527
+ if (frequencies.length !== densities.length)
528
+ return null;
529
+ // Auto-detect if frequencies are in cm⁻¹ instead of THz (unless disabled)
530
+ // Typical phonon frequencies are < 50 THz for most materials
531
+ // If max frequency > 100, it's almost certainly in cm⁻¹
532
+ const max_freq = Math.max(...frequencies);
533
+ let final_frequencies = frequencies;
534
+ if (auto_convert_units && max_freq > 100) {
535
+ // Likely in cm⁻¹, convert to THz
536
+ final_frequencies = frequencies.map((frequency) => frequency * CM_TO_THZ);
537
+ console.warn(`Phonon DOS frequencies appear to be in cm⁻¹ (max: ${max_freq.toFixed(1)}). ` +
538
+ `Converting to THz (max: ${(max_freq * CM_TO_THZ).toFixed(1)} THz).`);
539
+ }
540
+ return { type: `phonon`, frequencies: final_frequencies, densities };
541
+ }
542
+ // Electronic DOS: has energies
543
+ if (Array.isArray(energies)) {
544
+ if (energies.length !== densities.length)
545
+ return null;
546
+ // Detect spin-polarized from data if not explicitly set
547
+ const is_spin_polarized = spin_polarized ??
548
+ (spin_down_densities !== null && spin_down_densities.length === densities.length);
549
+ return {
550
+ type: `electronic`,
551
+ energies,
552
+ densities,
553
+ spin_down_densities: is_spin_polarized ? (spin_down_densities ?? undefined) : undefined,
554
+ spin_polarized: is_spin_polarized,
555
+ };
556
+ }
557
+ // For pymatgen format, log a helpful message if format wasn't recognized
558
+ if (is_pymatgen) {
559
+ console.warn(`Pymatgen DOS format detected but missing required fields. ` +
560
+ `Expected 'frequencies' (phonon) or 'energies' (electronic) arrays.`);
561
+ }
562
+ return null;
563
+ }
564
+ // Extract k-path points from band structure and convert to reciprocal space coordinates
565
+ // Accepts a reciprocal lattice matrix (should include 2π factor for consistency with BZ)
566
+ // Handles both matterviz format (qpoints as objects) and normalized pymatgen format
567
+ // Optionally wraps fractional coordinates to first BZ (default: true)
568
+ export function extract_k_path_points(band_struct, recip_lattice_matrix, options = {}) {
569
+ const { wrap_to_bz = true } = options;
570
+ if (!band_struct?.qpoints || !recip_lattice_matrix)
571
+ return [];
572
+ if (recip_lattice_matrix.length !== 3 ||
573
+ recip_lattice_matrix.some((row) => row?.length !== 3))
574
+ throw new Error(`reciprocal_lattice_matrix must be a 3×3 matrix`);
575
+ const [[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]] = recip_lattice_matrix;
576
+ return band_struct.qpoints.map((qpoint) => {
577
+ let [x, y, z] = qpoint.frac_coords;
578
+ // Wrap to first BZ if enabled (handles [0,1] vs [-0.5,0.5] convention difference)
579
+ if (wrap_to_bz) {
580
+ x = centered_frac(x);
581
+ y = centered_frac(y);
582
+ z = centered_frac(z);
583
+ }
584
+ const kx = x * m00 + y * m10 + z * m20;
585
+ const ky = x * m01 + y * m11 + z * m21;
586
+ const kz = x * m02 + y * m12 + z * m22;
587
+ return [kx, ky, kz];
588
+ });
589
+ }
590
+ // Find the q-point index closest to a given distance along the band structure path
591
+ export function find_qpoint_at_distance(band_struct, target) {
592
+ const { distance } = band_struct;
593
+ if (!distance?.length)
594
+ return null;
595
+ return distance.reduce((closest, dist, idx) => Math.abs(dist - target) < Math.abs(distance[closest] - target) ? idx : closest, 0);
596
+ }
597
+ // Find q-point index from rescaled x-coordinate (used in band structure plots)
598
+ // This handles the case where the plot uses custom x-axis scaling per segment
599
+ export function find_qpoint_at_rescaled_x(band_struct, rescaled_x, x_positions) {
600
+ if (!band_struct?.branches?.length || !x_positions)
601
+ return null;
602
+ // Find which segment contains this x coordinate
603
+ for (const branch of band_struct.branches) {
604
+ const start_idx = branch.start_index;
605
+ const end_idx = branch.end_index;
606
+ const start_label = band_struct.qpoints[start_idx]?.label ?? undefined;
607
+ const end_label = band_struct.qpoints[end_idx]?.label ?? undefined;
608
+ const segment_key = get_segment_key(start_label, end_label);
609
+ const segment_range = x_positions[segment_key];
610
+ if (!segment_range)
611
+ continue;
612
+ const [x_start, x_end] = segment_range;
613
+ // Check if discontinuity (zero-length segment)
614
+ const is_discontinuity = Math.abs(x_end - x_start) < 1e-6;
615
+ if (is_discontinuity) {
616
+ // For discontinuities, check if x is exactly at this point
617
+ if (Math.abs(rescaled_x - x_start) < 1e-6) {
618
+ return start_idx;
619
+ }
620
+ continue;
621
+ }
622
+ // Check if x is within this segment (with small tolerance for edges)
623
+ if (rescaled_x >= x_start - 1e-6 && rescaled_x <= x_end + 1e-6) {
624
+ // Map from rescaled x back to original distance
625
+ const segment_distances = band_struct.distance.slice(start_idx, end_idx + 1);
626
+ const dist_min = segment_distances[0];
627
+ const dist_max = segment_distances.at(-1) ?? dist_min;
628
+ const dist_range = dist_max - dist_min;
629
+ // Handle zero-length segments
630
+ if (dist_range === 0) {
631
+ return start_idx;
632
+ }
633
+ // Inverse of the scaling: x = x_start + ((dist - dist_min) / dist_range) * (x_end - x_start)
634
+ // Solving for dist: dist = dist_min + ((x - x_start) / (x_end - x_start)) * dist_range
635
+ const normalized_x = (rescaled_x - x_start) / (x_end - x_start);
636
+ const target_dist = dist_min + normalized_x * dist_range;
637
+ // Find closest qpoint in this branch to the target distance
638
+ let closest_idx = start_idx;
639
+ let min_diff = Math.abs(band_struct.distance[start_idx] - target_dist);
640
+ for (let idx = start_idx; idx <= end_idx; idx++) {
641
+ const diff = Math.abs(band_struct.distance[idx] - target_dist);
642
+ if (diff < min_diff) {
643
+ min_diff = diff;
644
+ closest_idx = idx;
645
+ }
646
+ }
647
+ return closest_idx;
648
+ }
649
+ }
650
+ // Fallback: find closest labeled point
651
+ let closest_idx = 0;
652
+ let min_dist = Infinity;
653
+ for (const branch of band_struct.branches) {
654
+ const start_idx = branch.start_index;
655
+ const end_idx = branch.end_index;
656
+ const start_label = band_struct.qpoints[start_idx]?.label ?? undefined;
657
+ const end_label = band_struct.qpoints[end_idx]?.label ?? undefined;
658
+ const segment_key = get_segment_key(start_label, end_label);
659
+ const segment_range = x_positions[segment_key];
660
+ if (!segment_range)
661
+ continue;
662
+ const [x_start, x_end] = segment_range;
663
+ for (const [x_pos, idx] of [
664
+ [x_start, start_idx],
665
+ [x_end, end_idx],
666
+ ]) {
667
+ const dist = Math.abs(rescaled_x - x_pos);
668
+ if (dist < min_dist) {
669
+ min_dist = dist;
670
+ closest_idx = idx;
671
+ }
672
+ }
673
+ }
674
+ return closest_idx;
675
+ }
676
+ // Extract projected DOS from pymatgen CompleteDos format.
677
+ // Returns a dict of label → DosData for each atom or orbital.
678
+ // filter_keys: optional list of keys to include (e.g., ["Fe", "O"] for atoms or ["s", "p", "d"] for orbitals)
679
+ export function extract_pdos(dos, pdos_type, filter_keys) {
680
+ if (!dos || typeof dos !== `object`)
681
+ return null;
682
+ const dos_obj = dos;
683
+ // Get the appropriate projected DOS dict
684
+ const pdos_dict = pdos_type === `atom`
685
+ ? dos_obj.atom_dos
686
+ : dos_obj.spd_dos;
687
+ if (!pdos_dict || typeof pdos_dict !== `object`)
688
+ return null;
689
+ const result = {};
690
+ for (const [key, nested_dos] of Object.entries(pdos_dict)) {
691
+ // Apply filter if provided
692
+ if (filter_keys && filter_keys.length > 0 && !filter_keys.includes(key))
693
+ continue;
694
+ if (!nested_dos || typeof nested_dos !== `object`)
695
+ continue;
696
+ const energies = nested_dos.energies;
697
+ const spin_channels = extract_spin_channels(nested_dos.densities);
698
+ if (!Array.isArray(energies) || !spin_channels)
699
+ continue;
700
+ const densities = spin_channels.up;
701
+ if (!Array.isArray(densities) || energies.length !== densities.length)
702
+ continue;
703
+ const is_spin_polarized = spin_channels.down !== null && spin_channels.down.length === densities.length;
704
+ result[key] = {
705
+ type: `electronic`,
706
+ energies,
707
+ densities,
708
+ spin_down_densities: is_spin_polarized ? (spin_channels.down ?? undefined) : undefined,
709
+ spin_polarized: is_spin_polarized,
710
+ efermi: nested_dos.efermi,
711
+ };
712
+ }
713
+ return Object.keys(result).length > 0 ? result : null;
714
+ }
715
+ // Shift a single DOS object's energies by the given amount
716
+ const shift_dos_energies = (dos, shift) => ({
717
+ ...dos,
718
+ efermi: dos.efermi - shift,
719
+ energies: dos.energies.map((energy) => energy - shift),
720
+ });
721
+ // Shift DOS energies relative to Fermi energy so E_F = 0
722
+ // Recursively shifts nested DOS in atom_dos and spd_dos for consistency
723
+ export function shift_to_fermi(dos) {
724
+ const shift = dos.efermi;
725
+ // Shift root DOS energies using the shared helper
726
+ const shifted_root = shift_dos_energies(dos, shift);
727
+ // Shift nested atom_dos if present
728
+ const atom_dos = dos.atom_dos
729
+ ? Object.fromEntries(Object.entries(dos.atom_dos).map(([key, nested_dos]) => [
730
+ key,
731
+ shift_dos_energies(nested_dos, shift),
732
+ ]))
733
+ : undefined;
734
+ // Shift nested spd_dos if present
735
+ const spd_dos = dos.spd_dos
736
+ ? Object.fromEntries(Object.entries(dos.spd_dos).map(([key, nested_dos]) => [
737
+ key,
738
+ shift_dos_energies(nested_dos, shift),
739
+ ]))
740
+ : undefined;
741
+ return {
742
+ ...shifted_root,
743
+ efermi: 0, // Explicitly set to 0 (shift_dos_energies would give efermi - shift)
744
+ ...(atom_dos && { atom_dos }),
745
+ ...(spd_dos && { spd_dos }),
746
+ };
747
+ }
748
+ // Generate an SVG path for a fat band ribbon.
749
+ // Creates a closed polygon by tracing the upper edge (y - half_width) forward,
750
+ // then tracing the lower edge (y + half_width) backward.
751
+ // Non-finite or non-positive widths are clamped to 0.
752
+ export function generate_ribbon_path(x_values, y_values, width_values, x_scale_fn, y_scale_fn, max_width_px, scale = 1) {
753
+ const len = x_values.length;
754
+ if (len < 2 || len !== y_values.length || len !== width_values.length)
755
+ return ``;
756
+ // Normalize width values to [0, 1] range based on the max positive finite value
757
+ const finite_positive_widths = width_values.filter((width) => Number.isFinite(width) && width > 0);
758
+ if (finite_positive_widths.length === 0)
759
+ return ``;
760
+ const max_width_val = Math.max(...finite_positive_widths);
761
+ // Build upper edge path (forward direction)
762
+ const upper_points = [];
763
+ const lower_points = [];
764
+ for (let idx = 0; idx < x_values.length; idx++) {
765
+ const x_px = x_scale_fn(x_values[idx]);
766
+ const y_data = y_values[idx];
767
+ const raw_width = width_values[idx] ?? 0;
768
+ const width_normalized = Number.isFinite(raw_width) && raw_width > 0 ? raw_width / max_width_val : 0;
769
+ const half_width_px = width_normalized * max_width_px * scale;
770
+ // In SVG, y increases downward, so upper edge has smaller y value
771
+ const y_upper_px = y_scale_fn(y_data) - half_width_px;
772
+ const y_lower_px = y_scale_fn(y_data) + half_width_px;
773
+ upper_points.push(`${x_px.toFixed(2)},${y_upper_px.toFixed(2)}`);
774
+ lower_points.push(`${x_px.toFixed(2)},${y_lower_px.toFixed(2)}`);
775
+ }
776
+ // Combine: upper edge forward, lower edge backward, close path
777
+ const path_parts = [
778
+ `M${upper_points[0]}`,
779
+ ...upper_points.slice(1).map((pt) => `L${pt}`),
780
+ ...lower_points.toReversed().map((pt) => `L${pt}`),
781
+ `Z`,
782
+ ];
783
+ return path_parts.join(` `);
784
+ }
785
+ // Extract efermi from a data source (band structure or DOS).
786
+ // Handles both single objects with an efermi field and dicts of objects.
787
+ // Returns undefined if no valid efermi is found or if the source is empty.
788
+ export function extract_efermi(data) {
789
+ if (!data || typeof data !== `object`)
790
+ return undefined;
791
+ const obj = data;
792
+ // Direct efermi field on the object
793
+ if (`efermi` in obj && typeof obj.efermi === `number`)
794
+ return obj.efermi;
795
+ // Dict of objects - try to get efermi from first value
796
+ const values = Object.values(obj);
797
+ if (values.length === 0)
798
+ return undefined;
799
+ const first_val = values[0];
800
+ if (first_val && typeof first_val === `object`) {
801
+ const efermi = first_val.efermi;
802
+ if (typeof efermi === `number`)
803
+ return efermi;
804
+ }
805
+ return undefined;
806
+ }
807
+ // Calculate fraction of |values| that are negative. Used to detect imaginary phonon modes.
808
+ export function negative_fraction(values) {
809
+ let [neg, total] = [0, 0];
810
+ for (const val of values) {
811
+ if (!Number.isFinite(val))
812
+ continue;
813
+ const abs_val = Math.abs(val);
814
+ total += abs_val;
815
+ if (val < 0)
816
+ neg += abs_val;
817
+ }
818
+ return total > 0 ? neg / total : 0;
819
+ }
820
+ // Check if raw band structure input has electronic markers (efermi, kpoints, or electronic @class).
821
+ // Must be called on raw input before normalization since these fields aren't preserved.
822
+ function is_electronic_band_struct(bs) {
823
+ if (!bs || typeof bs !== `object`)
824
+ return false;
825
+ const obj = bs;
826
+ // Electronic band structures have efermi field
827
+ if (`efermi` in obj && typeof obj.efermi === `number`)
828
+ return true;
829
+ // Pymatgen electronic format uses kpoints (not qpoints)
830
+ if (`kpoints` in obj && Array.isArray(obj.kpoints) && obj.kpoints.length > 0) {
831
+ return true;
832
+ }
833
+ // Pymatgen @class: BandStructure* but not Phonon*
834
+ const raw_class = obj[`@class`];
835
+ const py_class_name = typeof raw_class === `string` ? raw_class : ``;
836
+ if (py_class_name.startsWith(`BandStructure`) && !py_class_name.includes(`Phonon`)) {
837
+ return true;
838
+ }
839
+ return false;
840
+ }
841
+ // Compute frequency/energy range from bands and DOS. Clamps phonon min to 0 if noise < 0.5%.
842
+ export function compute_frequency_range(band_structs, doses, padding_factor = 0.02) {
843
+ let [min_val, max_val, is_phonon] = [Infinity, -Infinity, false];
844
+ const all_freqs = [];
845
+ // Check raw band_structs for electronic markers before normalization
846
+ // (normalized structures always have qpoints, so we can't detect from them)
847
+ let has_electronic_bs = false;
848
+ // Support both qpoints (phonon) and kpoints (electronic) to detect single vs dict
849
+ const is_single_bs = band_structs &&
850
+ typeof band_structs === `object` &&
851
+ (`qpoints` in band_structs || `kpoints` in band_structs);
852
+ if (band_structs && typeof band_structs === `object`) {
853
+ // Single structure check
854
+ if (is_electronic_band_struct(band_structs)) {
855
+ has_electronic_bs = true;
856
+ }
857
+ else if (!is_single_bs) {
858
+ // Dict of band structures - check each value
859
+ for (const bs_val of Object.values(band_structs)) {
860
+ if (is_electronic_band_struct(bs_val)) {
861
+ has_electronic_bs = true;
862
+ break;
863
+ }
864
+ }
865
+ }
866
+ }
867
+ const bs_list = band_structs
868
+ ? is_single_bs
869
+ ? [normalize_band_structure(band_structs)]
870
+ : Object.values(band_structs).map(normalize_band_structure)
871
+ : [];
872
+ // If band structures exist and aren't electronic, mark as phonon
873
+ const has_band_structs = bs_list.some(Boolean);
874
+ if (has_band_structs && !has_electronic_bs)
875
+ is_phonon = true;
876
+ for (const bs of bs_list) {
877
+ if (!bs)
878
+ continue;
879
+ for (const band of bs.bands) {
880
+ for (const val of band) {
881
+ if (!Number.isFinite(val))
882
+ continue;
883
+ all_freqs.push(val);
884
+ min_val = Math.min(min_val, val);
885
+ max_val = Math.max(max_val, val);
886
+ }
887
+ }
888
+ }
889
+ const dos_list = doses
890
+ ? `densities` in doses
891
+ ? [normalize_dos(doses)]
892
+ : Object.values(doses).map((dos) => normalize_dos(dos))
893
+ : [];
894
+ for (const dos of dos_list) {
895
+ if (!dos)
896
+ continue;
897
+ // DOS type detection: explicit type field is authoritative
898
+ if (dos.type === `phonon`)
899
+ is_phonon = true;
900
+ if (dos.type === `electronic`)
901
+ is_phonon = false;
902
+ for (const val of dos.type === `phonon` ? dos.frequencies : dos.energies) {
903
+ if (!Number.isFinite(val))
904
+ continue;
905
+ all_freqs.push(val);
906
+ min_val = Math.min(min_val, val);
907
+ max_val = Math.max(max_val, val);
908
+ }
909
+ }
910
+ if (!Number.isFinite(min_val) || !Number.isFinite(max_val))
911
+ return undefined;
912
+ const clamp_min = is_phonon &&
913
+ min_val < 0 && // clamp phonon noise to 0
914
+ negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD;
915
+ if (clamp_min)
916
+ min_val = 0;
917
+ // Calculate padding from (possibly clamped) range for consistency with Bands.svelte
918
+ const padding = (max_val - min_val) * padding_factor;
919
+ return [min_val === 0 ? 0 : min_val - padding, max_val + padding];
920
+ }
921
+ // Parse axis label: "Frequency (THz)" → { name: "Frequency", unit: "THz" }
922
+ function parse_axis_label(label) {
923
+ const match = /^(.+?)\s*\(([^)]+)\)$/.exec(label);
924
+ return match ? { name: match[1], unit: match[2] } : { name: label };
925
+ }
926
+ const format_tooltip_line = (name, value, unit) => `${name}: ${value}${unit ? ` ${unit}` : ``}`;
927
+ // Format DOS tooltip content from axis labels and values
928
+ export function format_dos_tooltip(x_formatted, y_formatted, label, is_horizontal, is_phonon, units, x_axis_label, y_axis_label, num_series) {
929
+ const x_parsed = parse_axis_label(x_axis_label);
930
+ const y_parsed = parse_axis_label(y_axis_label);
931
+ const freq_defaults = {
932
+ name: is_phonon ? `Frequency` : `Energy`,
933
+ unit: is_phonon ? units : `eV`,
934
+ };
935
+ const lines = is_horizontal
936
+ ? [
937
+ format_tooltip_line(y_parsed.name || freq_defaults.name, y_formatted, y_parsed.unit || freq_defaults.unit),
938
+ format_tooltip_line(x_parsed.name || `Density`, x_formatted),
939
+ ]
940
+ : [
941
+ format_tooltip_line(y_parsed.name || `Density`, y_formatted),
942
+ format_tooltip_line(x_parsed.name || freq_defaults.name, x_formatted, x_parsed.unit || freq_defaults.unit),
943
+ ];
944
+ return { title: num_series > 1 && label ? label : undefined, lines };
945
+ }
946
+ // Spin mode options for DOS visualization
947
+ export const SPIN_MODES = [
948
+ { value: `mirror`, label: `↕`, title: `Mirror: spin-up above, spin-down below zero` },
949
+ { value: `overlay`, label: `≡`, title: `Overlay: both spins on same axis` },
950
+ { value: `up_only`, label: `↑`, title: `Show spin-up only` },
951
+ { value: `down_only`, label: `↓`, title: `Show spin-down only` },
952
+ ];
953
+ // Normalization mode options
954
+ export const NORMALIZATION_MODES = [
955
+ { value: null, label: `None` },
956
+ { value: `max`, label: `Max=1` },
957
+ { value: `sum`, label: `Sum=1` },
958
+ { value: `integral`, label: `∫=1` },
959
+ ];
960
+ // Available frequency units for phonon DOS
961
+ export const FREQUENCY_UNITS = [`THz`, `eV`, `meV`, `cm-1`, `Ha`];
962
+ // Default values for DOS controls
963
+ export const DEFAULT_SPIN_MODE = `mirror`;
964
+ export const DEFAULT_SIGMA = 0;
965
+ export const DEFAULT_NORMALIZE = null;
966
+ export const DEFAULT_UNITS = `THz`;
967
+ // Format sigma with adaptive precision: 0→"0", <0.01→exp, <1→3dp, else→2dp
968
+ export function format_sigma(val) {
969
+ if (val === 0)
970
+ return `0`;
971
+ if (val < 0.01)
972
+ return val.toExponential(1);
973
+ return val.toFixed(val < 1 ? 3 : 2);
974
+ }
975
+ // Validate sigma_range: ensures min < max, returns [0, 1] if invalid
976
+ export const validate_sigma_range = ([min, max]) => Number.isFinite(min) && Number.isFinite(max) && min < max ? [min, max] : [0, 1];
977
+ // Calculate slider step: 1/100th of range, or 0.01 fallback
978
+ export function calculate_sigma_step(range) {
979
+ const [min, max] = validate_sigma_range(range);
980
+ return (max - min) / 100 || 0.01;
981
+ }
982
+ // Central difference for local slope (dω/dk or dE/dk).
983
+ // Uses forward/backward difference at endpoints, central difference for interior points.
984
+ export function compute_slope(x_vals, y_vals, idx) {
985
+ const len = Math.min(x_vals.length, y_vals.length);
986
+ if (len < 2 || idx < 0 || idx >= len)
987
+ return null;
988
+ const lo = idx === 0 ? 0 : idx - 1;
989
+ const hi = idx >= len - 1 ? len - 1 : idx + 1;
990
+ const dx = x_vals[hi] - x_vals[lo];
991
+ return dx ? (y_vals[hi] - y_vals[lo]) / dx : null;
992
+ }
993
+ // Find Gamma-point indices (q ≈ integer lattice point) in a band structure.
994
+ // Returns indices of q-points whose fractional coordinates are all within 0.01 of integers.
995
+ export function find_gamma_indices(bs) {
996
+ const indices = [];
997
+ for (let q_idx = 0; q_idx < bs.qpoints.length; q_idx++) {
998
+ const coords = bs.qpoints[q_idx]?.frac_coords;
999
+ if (coords?.every((coord) => Math.abs(coord - Math.round(coord)) < 0.01)) {
1000
+ indices.push(q_idx);
1001
+ }
1002
+ }
1003
+ return indices;
1004
+ }
1005
+ // Threshold below which a band's frequency at Gamma is considered acoustic (THz).
1006
+ // Assumes bands are stored in THz (normalize_band_structure converts to THz).
1007
+ export const ACOUSTIC_FREQ_THRESHOLD = 0.5;
1008
+ // Classify a band as acoustic based on near-zero frequency at Gamma points.
1009
+ // Returns true (acoustic), false (optical), or null (no Gamma points → can't determine).
1010
+ export function classify_acoustic(bs, band_idx, gamma_indices, threshold = ACOUSTIC_FREQ_THRESHOLD) {
1011
+ if (gamma_indices.length === 0)
1012
+ return null;
1013
+ return gamma_indices.some((gamma_idx) => Math.abs(bs.bands[band_idx]?.[gamma_idx] ?? Infinity) < threshold);
1014
+ }
1015
+ // Build per-point metadata array for a band series in the tooltip.
1016
+ export function build_point_metadata(opts) {
1017
+ const { x_vals, y_vals, band_idx, spin, is_acoustic, bs, start_idx } = opts;
1018
+ return x_vals.map((_, pt_idx) => {
1019
+ const global_idx = start_idx + pt_idx;
1020
+ const qpoint = bs.qpoints[global_idx];
1021
+ return {
1022
+ band_idx,
1023
+ spin,
1024
+ is_acoustic,
1025
+ nb_bands: bs.nb_bands,
1026
+ frac_coords: qpoint?.frac_coords ?? null,
1027
+ qpoint_label: qpoint?.label ?? null,
1028
+ band_width: bs.band_widths?.[band_idx]?.[global_idx] ?? null,
1029
+ slope: compute_slope(x_vals, y_vals, pt_idx),
1030
+ };
1031
+ });
1032
+ }