matterviz 0.4.1 → 0.4.2

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 (395) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +75 -85
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  11. package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  13. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
  15. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
  17. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  18. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  19. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  20. package/dist/colors/index.d.ts +0 -4
  21. package/dist/colors/index.js +19 -20
  22. package/dist/composition/BarChart.svelte +37 -31
  23. package/dist/composition/BubbleChart.svelte +17 -17
  24. package/dist/composition/Composition.svelte +7 -11
  25. package/dist/composition/Formula.svelte +18 -25
  26. package/dist/composition/FormulaFilter.svelte +92 -95
  27. package/dist/composition/PieChart.svelte +55 -41
  28. package/dist/composition/format.js +1 -1
  29. package/dist/composition/index.d.ts +2 -0
  30. package/dist/composition/index.js +14 -0
  31. package/dist/composition/parse.d.ts +2 -2
  32. package/dist/composition/parse.js +11 -10
  33. package/dist/constants.js +11 -9
  34. package/dist/convex-hull/ConvexHull.svelte +12 -15
  35. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  36. package/dist/convex-hull/ConvexHull2D.svelte +93 -92
  37. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  38. package/dist/convex-hull/ConvexHull3D.svelte +109 -140
  39. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  40. package/dist/convex-hull/ConvexHull4D.svelte +75 -94
  41. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  42. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  43. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  44. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  45. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  46. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  47. package/dist/convex-hull/StructurePopup.svelte +17 -21
  48. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  49. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  50. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  51. package/dist/convex-hull/helpers.d.ts +8 -10
  52. package/dist/convex-hull/helpers.js +36 -36
  53. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  54. package/dist/convex-hull/thermodynamics.js +18 -17
  55. package/dist/coordination/CoordinationBarPlot.svelte +38 -33
  56. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  57. package/dist/coordination/calc-coordination.d.ts +1 -1
  58. package/dist/coordination/calc-coordination.js +28 -25
  59. package/dist/element/BohrAtom.svelte +5 -8
  60. package/dist/element/ElementHeading.svelte +4 -1
  61. package/dist/element/ElementPhoto.svelte +11 -9
  62. package/dist/element/ElementStats.svelte +12 -10
  63. package/dist/element/ElementTile.svelte +24 -29
  64. package/dist/element/Nucleus.svelte +4 -2
  65. package/dist/element/data.d.ts +1 -2
  66. package/dist/element/helpers.d.ts +4 -0
  67. package/dist/element/helpers.js +18 -0
  68. package/dist/element/index.d.ts +1 -4
  69. package/dist/element/index.js +3 -18
  70. package/dist/feedback/DragOverlay.svelte +5 -5
  71. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  72. package/dist/feedback/StatusMessage.svelte +7 -4
  73. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  74. package/dist/fermi-surface/FermiSurface.svelte +14 -22
  75. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
  76. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  77. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  80. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  81. package/dist/fermi-surface/compute.js +3 -3
  82. package/dist/fermi-surface/parse.js +22 -24
  83. package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
  84. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  85. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  86. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  87. package/dist/heatmap-matrix/index.d.ts +5 -0
  88. package/dist/icons.d.ts +4 -0
  89. package/dist/icons.js +4 -0
  90. package/dist/io/ExportPane.svelte +10 -6
  91. package/dist/io/decompress.d.ts +2 -1
  92. package/dist/io/decompress.js +22 -35
  93. package/dist/io/export.d.ts +4 -0
  94. package/dist/io/export.js +5 -1
  95. package/dist/io/fetch.d.ts +0 -3
  96. package/dist/io/fetch.js +0 -11
  97. package/dist/io/index.d.ts +0 -1
  98. package/dist/io/index.js +2 -9
  99. package/dist/io/is-binary.d.ts +9 -0
  100. package/dist/io/is-binary.js +45 -1
  101. package/dist/io/url-drop.js +13 -25
  102. package/dist/isosurface/Isosurface.svelte +17 -23
  103. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  104. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  105. package/dist/isosurface/parse-vaspwave.js +138 -0
  106. package/dist/isosurface/parse.js +6 -6
  107. package/dist/labels.d.ts +6 -2
  108. package/dist/labels.js +43 -13
  109. package/dist/layout/FullscreenButton.svelte +2 -1
  110. package/dist/layout/FullscreenToggle.svelte +10 -4
  111. package/dist/layout/InfoCard.svelte +7 -18
  112. package/dist/layout/InfoTag.svelte +1 -3
  113. package/dist/layout/NumberRangeInput.svelte +46 -0
  114. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  115. package/dist/layout/PropertyFilter.svelte +2 -6
  116. package/dist/layout/SettingsSection.svelte +21 -17
  117. package/dist/layout/SubpageGrid.svelte +3 -1
  118. package/dist/layout/ViewerChrome.svelte +9 -10
  119. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  120. package/dist/layout/fullscreen.js +3 -5
  121. package/dist/layout/fullscreen.svelte.js +1 -2
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  125. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  126. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  127. package/dist/layout/json-tree/utils.js +14 -23
  128. package/dist/math.d.ts +2 -0
  129. package/dist/math.js +19 -0
  130. package/dist/overlays/ContextMenu.svelte +4 -2
  131. package/dist/overlays/CopyButton.svelte +11 -5
  132. package/dist/overlays/DragControlTab.svelte +6 -1
  133. package/dist/overlays/DraggablePane.svelte +81 -26
  134. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  135. package/dist/overlays/GlassChip.svelte +30 -0
  136. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  137. package/dist/overlays/InfoPaneCards.svelte +11 -23
  138. package/dist/overlays/index.d.ts +7 -0
  139. package/dist/overlays/index.js +26 -0
  140. package/dist/overlays/portal.d.ts +2 -0
  141. package/dist/overlays/portal.js +14 -0
  142. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  143. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  144. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  145. package/dist/periodic-table/TableInset.svelte +9 -4
  146. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  147. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  148. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  149. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  150. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  151. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  152. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  153. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  154. package/dist/phase-diagram/build-diagram.js +3 -3
  155. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  156. package/dist/phase-diagram/parse.js +15 -15
  157. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  158. package/dist/phase-diagram/utils.js +2 -3
  159. package/dist/plot/bar/BarPlot.svelte +430 -391
  160. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  161. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  162. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  163. package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
  164. package/dist/plot/bar/data.d.ts +5 -4
  165. package/dist/plot/bar/data.js +2 -1
  166. package/dist/plot/box/BoxPlot.svelte +301 -209
  167. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  168. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  169. package/dist/plot/box/box-plot.js +1 -1
  170. package/dist/plot/core/auto-place.js +1 -1
  171. package/dist/plot/core/axis-utils.d.ts +12 -7
  172. package/dist/plot/core/axis-utils.js +48 -48
  173. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  174. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  175. package/dist/plot/core/components/ColorBar.svelte +101 -106
  176. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  177. package/dist/plot/core/components/FillArea.svelte +10 -17
  178. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  179. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  180. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  181. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  182. package/dist/plot/core/components/Line.svelte +18 -9
  183. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  184. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  185. package/dist/plot/core/components/PlotControls.svelte +65 -41
  186. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  187. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  188. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  189. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  190. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  191. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  192. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  193. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  194. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  195. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  196. package/dist/plot/core/components/index.d.ts +1 -0
  197. package/dist/plot/core/components/index.js +1 -0
  198. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  199. package/dist/plot/core/data-cleaning-signal.js +467 -0
  200. package/dist/plot/core/data-cleaning.d.ts +2 -42
  201. package/dist/plot/core/data-cleaning.js +27 -474
  202. package/dist/plot/core/data-transform.js +9 -5
  203. package/dist/plot/core/fill-utils.d.ts +3 -1
  204. package/dist/plot/core/fill-utils.js +28 -6
  205. package/dist/plot/core/index.d.ts +1 -0
  206. package/dist/plot/core/index.js +1 -0
  207. package/dist/plot/core/interactions.js +0 -2
  208. package/dist/plot/core/layout.d.ts +3 -1
  209. package/dist/plot/core/layout.js +22 -13
  210. package/dist/plot/core/marginals.d.ts +170 -0
  211. package/dist/plot/core/marginals.js +436 -0
  212. package/dist/plot/core/reference-line.js +1 -1
  213. package/dist/plot/core/scales.d.ts +23 -0
  214. package/dist/plot/core/scales.js +39 -13
  215. package/dist/plot/core/types/fills.d.ts +101 -0
  216. package/dist/plot/core/types/fills.js +15 -0
  217. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  218. package/dist/plot/core/types/plot-3d.js +4 -0
  219. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  220. package/dist/plot/core/types/reference-lines.js +9 -0
  221. package/dist/plot/core/types.d.ts +29 -324
  222. package/dist/plot/core/types.js +23 -20
  223. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  224. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  225. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  226. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  227. package/dist/plot/core/utils/label-placement.js +2 -2
  228. package/dist/plot/histogram/Histogram.svelte +304 -325
  229. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  230. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  231. package/dist/plot/histogram/histogram.d.ts +31 -0
  232. package/dist/plot/histogram/histogram.js +70 -0
  233. package/dist/plot/histogram/index.d.ts +1 -0
  234. package/dist/plot/histogram/index.js +1 -0
  235. package/dist/plot/index.d.ts +1 -0
  236. package/dist/plot/index.js +1 -0
  237. package/dist/plot/sankey/Sankey.svelte +78 -69
  238. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  239. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  240. package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
  241. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  242. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  243. package/dist/plot/scatter/ScatterPlot.svelte +477 -385
  244. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  245. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  246. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  247. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  248. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  249. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  250. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  251. package/dist/plot/scatter/scatter-data.js +8 -7
  252. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  253. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  254. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  255. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  256. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  257. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  258. package/dist/plot/sunburst/Sunburst.svelte +251 -329
  259. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  260. package/dist/plot/sunburst/index.d.ts +1 -1
  261. package/dist/plot/sunburst/index.js +2 -1
  262. package/dist/plot/sunburst/render.d.ts +2 -2
  263. package/dist/plot/sunburst/render.js +47 -22
  264. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  265. package/dist/plot/sunburst/sunburst.js +10 -3
  266. package/dist/plot/treemap/Treemap.svelte +907 -0
  267. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  268. package/dist/plot/treemap/index.d.ts +3 -0
  269. package/dist/plot/treemap/index.js +4 -0
  270. package/dist/plot/treemap/treemap.d.ts +26 -0
  271. package/dist/plot/treemap/treemap.js +99 -0
  272. package/dist/rdf/RdfPlot.svelte +22 -26
  273. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  274. package/dist/rdf/calc-rdf.js +4 -8
  275. package/dist/sanitize.js +1 -1
  276. package/dist/scene/bind-renderer.svelte.js +14 -6
  277. package/dist/settings.d.ts +19 -9
  278. package/dist/settings.js +77 -50
  279. package/dist/spectral/Bands.svelte +223 -230
  280. package/dist/spectral/BandsAndDos.svelte +11 -9
  281. package/dist/spectral/BrillouinBandsDos.svelte +19 -27
  282. package/dist/spectral/Dos.svelte +70 -73
  283. package/dist/spectral/helpers.d.ts +3 -3
  284. package/dist/spectral/helpers.js +25 -35
  285. package/dist/state.svelte.js +5 -18
  286. package/dist/structure/Arrow.svelte +5 -18
  287. package/dist/structure/ArrowInstances.svelte +160 -0
  288. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  289. package/dist/structure/AtomLegend.svelte +115 -75
  290. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  291. package/dist/structure/Bond.svelte +31 -23
  292. package/dist/structure/CanvasTooltip.svelte +15 -3
  293. package/dist/structure/CellSelect.svelte +11 -26
  294. package/dist/structure/Cylinder.svelte +24 -40
  295. package/dist/structure/InstancedAtoms.svelte +114 -0
  296. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  297. package/dist/structure/Lattice.svelte +85 -149
  298. package/dist/structure/SiteLabels.svelte +122 -0
  299. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  300. package/dist/structure/Structure.svelte +473 -419
  301. package/dist/structure/Structure.svelte.d.ts +4 -2
  302. package/dist/structure/StructureCarousel.svelte +630 -0
  303. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  304. package/dist/structure/StructureControls.svelte +157 -399
  305. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  306. package/dist/structure/StructureExportPane.svelte +17 -21
  307. package/dist/structure/StructureInfoPane.svelte +72 -66
  308. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  309. package/dist/structure/StructureScene.svelte +467 -476
  310. package/dist/structure/StructureScene.svelte.d.ts +3 -1
  311. package/dist/structure/StructureViewport.svelte +386 -0
  312. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  313. package/dist/structure/atom-label-placement.d.ts +16 -12
  314. package/dist/structure/atom-label-placement.js +70 -37
  315. package/dist/structure/atom-properties.d.ts +2 -0
  316. package/dist/structure/atom-properties.js +104 -38
  317. package/dist/structure/bonding.d.ts +10 -3
  318. package/dist/structure/bonding.js +84 -28
  319. package/dist/structure/edit-history.d.ts +6 -0
  320. package/dist/structure/edit-history.js +27 -0
  321. package/dist/structure/export.d.ts +1 -0
  322. package/dist/structure/export.js +39 -31
  323. package/dist/structure/format-detect.d.ts +1 -0
  324. package/dist/structure/format-detect.js +22 -0
  325. package/dist/structure/geometry.d.ts +9 -0
  326. package/dist/structure/geometry.js +27 -0
  327. package/dist/structure/index.d.ts +16 -1
  328. package/dist/structure/index.js +13 -2
  329. package/dist/structure/measure.d.ts +1 -1
  330. package/dist/structure/measure.js +6 -12
  331. package/dist/structure/parse.d.ts +2 -1
  332. package/dist/structure/parse.js +243 -222
  333. package/dist/structure/partial-occupancy.js +4 -2
  334. package/dist/structure/pbc.js +78 -98
  335. package/dist/structure/polyhedra.d.ts +0 -1
  336. package/dist/structure/polyhedra.js +3 -18
  337. package/dist/structure/supercell.d.ts +1 -2
  338. package/dist/structure/supercell.js +7 -13
  339. package/dist/symmetry/SymmetryElements.svelte +11 -15
  340. package/dist/symmetry/SymmetryStats.svelte +56 -68
  341. package/dist/symmetry/WyckoffTable.svelte +5 -24
  342. package/dist/symmetry/cell-transform.js +1 -0
  343. package/dist/symmetry/index.d.ts +1 -0
  344. package/dist/symmetry/index.js +8 -2
  345. package/dist/symmetry/spacegroups.js +3 -2
  346. package/dist/table/HeatmapTable.svelte +1102 -365
  347. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  348. package/dist/table/ToggleMenu.svelte +5 -12
  349. package/dist/table/index.d.ts +21 -6
  350. package/dist/table/index.js +34 -21
  351. package/dist/theme/ThemeControl.svelte +16 -8
  352. package/dist/theme/index.d.ts +1 -5
  353. package/dist/theme/index.js +4 -10
  354. package/dist/theme/themes.mjs +14 -7
  355. package/dist/tooltip/KCoords.svelte +4 -1
  356. package/dist/tooltip/TooltipContent.svelte +2 -5
  357. package/dist/trajectory/Trajectory.svelte +515 -308
  358. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  359. package/dist/trajectory/TrajectoryError.svelte +11 -8
  360. package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
  361. package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
  362. package/dist/trajectory/extract.js +56 -34
  363. package/dist/trajectory/format-detect.js +11 -9
  364. package/dist/trajectory/frame-reader.d.ts +2 -0
  365. package/dist/trajectory/frame-reader.js +33 -29
  366. package/dist/trajectory/helpers.d.ts +2 -0
  367. package/dist/trajectory/helpers.js +18 -7
  368. package/dist/trajectory/index.d.ts +1 -0
  369. package/dist/trajectory/index.js +3 -0
  370. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  371. package/dist/trajectory/parse/h5-utils.js +109 -0
  372. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  373. package/dist/trajectory/parse/hdf5.js +116 -106
  374. package/dist/trajectory/parse/index.d.ts +2 -3
  375. package/dist/trajectory/parse/index.js +17 -20
  376. package/dist/trajectory/parse/lammps.js +8 -12
  377. package/dist/trajectory/parse/vasp.js +10 -7
  378. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  379. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  380. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  381. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  382. package/dist/trajectory/parse/xyz.js +11 -7
  383. package/dist/trajectory/plotting.d.ts +8 -9
  384. package/dist/trajectory/plotting.js +99 -27
  385. package/dist/utils.d.ts +3 -0
  386. package/dist/utils.js +7 -0
  387. package/dist/xrd/XrdPlot.svelte +47 -61
  388. package/dist/xrd/broadening.js +2 -1
  389. package/dist/xrd/calc-xrd.js +2 -4
  390. package/dist/xrd/parse.d.ts +0 -1
  391. package/dist/xrd/parse.js +56 -73
  392. package/package.json +61 -33
  393. package/dist/api/mp.d.ts +0 -6
  394. package/dist/api/mp.js +0 -22
  395. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
@@ -44,10 +44,12 @@
44
44
  const bands_default_axis = (range = shared_frequency_range): AxisConfig =>
45
45
  shared_y_axis ? axis_with_range(bands_props.y_axis, range) : { ...bands_props.y_axis }
46
46
  const dos_default_axis = (range = shared_frequency_range): AxisConfig =>
47
- shared_y_axis ? axis_with_range(dos_props.y_axis, range, ``) : {
48
- label: ``,
49
- ...dos_props.y_axis,
50
- }
47
+ shared_y_axis
48
+ ? axis_with_range(dos_props.y_axis, range, ``)
49
+ : {
50
+ label: ``,
51
+ ...dos_props.y_axis,
52
+ }
51
53
 
52
54
  let synced_zoom_range = $state<Vec2 | null>(null)
53
55
  let bands_y_axis = $state<AxisConfig>(bands_default_axis())
@@ -88,14 +90,14 @@
88
90
  $effect(() =>
89
91
  propagate_synced_range(
90
92
  untrack(() => bands_y_axis.range) as Vec2 | undefined,
91
- (base_range) => bands_y_axis = bands_default_axis(base_range),
92
- )
93
+ (base_range) => (bands_y_axis = bands_default_axis(base_range)),
94
+ ),
93
95
  )
94
96
  $effect(() =>
95
97
  propagate_synced_range(
96
98
  untrack(() => dos_y_axis.range) as Vec2 | undefined,
97
- (base_range) => dos_y_axis = dos_default_axis(base_range),
98
- )
99
+ (base_range) => (dos_y_axis = dos_default_axis(base_range)),
100
+ ),
99
101
  )
100
102
 
101
103
  let hovered_frequency = $state<number | null>(null)
@@ -106,7 +108,7 @@
106
108
 
107
109
  <div
108
110
  {...rest}
109
- class="bands-and-dos {rest.class ?? ``}"
111
+ class={[`bands-and-dos`, rest.class]}
110
112
  style={`display: grid; grid-template-columns: 1fr 200px; gap: 0;` + (rest.style ?? ``)}
111
113
  >
112
114
  {@render children?.({ hovered_frequency })}
@@ -44,16 +44,13 @@
44
44
  ) as BaseBandStructure | null
45
45
 
46
46
  // Compute shared frequency/energy range from both bands and DOS data
47
- let shared_frequency_range = $derived(
48
- helpers.compute_frequency_range(band_structs, doses),
49
- )
47
+ let shared_frequency_range = $derived(helpers.compute_frequency_range(band_structs, doses))
50
48
 
51
49
  // Extract Fermi level from electronic band structure or DOS data
52
50
  let fermi_level = $derived.by((): number | undefined => {
53
51
  // Check band structures for efermi
54
- const bs_source = `efermi` in (band_structs as object)
55
- ? band_structs
56
- : Object.values(band_structs)[0]
52
+ const bs_source =
53
+ `efermi` in (band_structs as object) ? band_structs : Object.values(band_structs)[0]
57
54
  const bs_efermi = (bs_source as Record<string, unknown>)?.efermi
58
55
  if (typeof bs_efermi === `number`) return bs_efermi
59
56
 
@@ -75,13 +72,12 @@
75
72
  let hovered_band_point = $state<InternalPoint | null>(null)
76
73
  let bands_x_positions = $state<Record<string, Vec2>>({})
77
74
  let hovered_qpoint_index = $derived(
78
- hovered_band_point && first_band_struct &&
79
- Object.keys(bands_x_positions).length > 0
75
+ hovered_band_point && first_band_struct && Object.keys(bands_x_positions).length > 0
80
76
  ? helpers.find_qpoint_at_rescaled_x(
81
- first_band_struct,
82
- hovered_band_point.x,
83
- bands_x_positions,
84
- )
77
+ first_band_struct,
78
+ hovered_band_point.x,
79
+ bands_x_positions,
80
+ )
85
81
  : null,
86
82
  )
87
83
  // Q-point hovered directly on the BZ k-path (reverse direction: BZ -> bands/DOS)
@@ -89,9 +85,7 @@
89
85
  // Unified hovered q-point: a band-point hover takes priority, else a BZ k-path hover
90
86
  let active_qpoint_index = $derived(hovered_qpoint_index ?? bz_hovered_qpoint_index)
91
87
  let hovered_k_point = $derived(
92
- active_qpoint_index !== null
93
- ? (k_path_points[active_qpoint_index] as Vec3)
94
- : null,
88
+ active_qpoint_index !== null ? (k_path_points[active_qpoint_index] as Vec3) : null,
95
89
  )
96
90
  const [desktop_width, tablet_width] = [1200, 600]
97
91
  let clientWidth = $state(desktop_width)
@@ -101,8 +95,8 @@
101
95
  clientWidth >= desktop_width
102
96
  ? `desktop`
103
97
  : clientWidth >= tablet_width
104
- ? `tablet`
105
- : `phone`,
98
+ ? `tablet`
99
+ : `phone`,
106
100
  )
107
101
 
108
102
  const bands_default_axis = (range = shared_frequency_range): AxisConfig =>
@@ -169,11 +163,7 @@
169
163
  let hovered_frequency = $state<number | null>(null)
170
164
  </script>
171
165
 
172
- <div
173
- {...rest}
174
- class="bands-dos-brillouin {screen_class} {rest.class ?? ``}"
175
- bind:clientWidth
176
- >
166
+ <div {...rest} class={[`bands-dos-brillouin`, screen_class, rest.class]} bind:clientWidth>
177
167
  {@render children?.({
178
168
  hovered_frequency,
179
169
  hovered_band_point,
@@ -201,11 +191,13 @@
201
191
  {k_path_points}
202
192
  k_path_labels={first_band_struct?.qpoints?.flatMap((qpoint, idx) =>
203
193
  k_path_points[idx]
204
- ? [{
205
- position: k_path_points[idx],
206
- label: qpoint.label ? helpers.pretty_sym_point(qpoint.label) : null,
207
- }]
208
- : []
194
+ ? [
195
+ {
196
+ position: k_path_points[idx],
197
+ label: qpoint.label ? helpers.pretty_sym_point(qpoint.label) : null,
198
+ },
199
+ ]
200
+ : [],
209
201
  ) ?? []}
210
202
  {hovered_k_point}
211
203
  hovered_qpoint_index={active_qpoint_index}
@@ -175,17 +175,18 @@
175
175
  }
176
176
 
177
177
  // Check for spin-down data (only for electronic DOS)
178
- const has_spin_down = dos.type === `electronic` &&
179
- dos.spin_down_densities?.length === dos.densities.length
178
+ const has_spin_down =
179
+ dos.type === `electronic` && dos.spin_down_densities?.length === dos.densities.length
180
180
  const should_show_spin_up = effective_spin_mode !== `down_only`
181
- const should_show_spin_down = has_spin_down &&
182
- effective_spin_mode !== `up_only` && effective_spin_mode !== null
181
+ const should_show_spin_down =
182
+ has_spin_down && effective_spin_mode !== `up_only` && effective_spin_mode !== null
183
183
 
184
184
  // Process spin-up (or total) densities
185
185
  if (should_show_spin_up) {
186
- let densities_up = sigma > 0
187
- ? apply_gaussian_smearing(x_values, dos.densities, sigma)
188
- : [...dos.densities]
186
+ let densities_up =
187
+ sigma > 0
188
+ ? apply_gaussian_smearing(x_values, dos.densities, sigma)
189
+ : [...dos.densities]
189
190
 
190
191
  densities_up = normalize_densities(densities_up, x_values, normalize)
191
192
 
@@ -194,8 +195,8 @@
194
195
 
195
196
  // For stacked plots, accumulate densities (only if array lengths match)
196
197
  if (stack && cumulative_spin_up?.length === densities_up.length) {
197
- densities_up = densities_up.map((density, idx) =>
198
- density + (cumulative_spin_up?.[idx] ?? 0)
198
+ densities_up = densities_up.map(
199
+ (density, idx) => density + (cumulative_spin_up?.[idx] ?? 0),
199
200
  )
200
201
  } else if (stack && cumulative_spin_up) {
201
202
  console.warn(`DOS stacking: length mismatch for "${label}"`)
@@ -212,9 +213,10 @@
212
213
  cumulative_spin_up = densities_up
213
214
  }
214
215
 
215
- const spin_label = has_spin_down && effective_spin_mode
216
- ? `${label || `DOS ${dos_idx + 1}`} (↑)`
217
- : (label || `DOS ${dos_idx + 1}`)
216
+ const spin_label =
217
+ has_spin_down && effective_spin_mode
218
+ ? `${label || `DOS ${dos_idx + 1}`} (↑)`
219
+ : label || `DOS ${dos_idx + 1}`
218
220
 
219
221
  const series_up: DataSeries = {
220
222
  x: is_horizontal ? densities_up : x_values,
@@ -228,13 +230,11 @@
228
230
  }
229
231
 
230
232
  // Process spin-down densities if available
231
- if (
232
- should_show_spin_down && dos.type === `electronic` &&
233
- dos.spin_down_densities
234
- ) {
235
- let densities_down = sigma > 0
236
- ? apply_gaussian_smearing(x_values, dos.spin_down_densities, sigma)
237
- : [...dos.spin_down_densities]
233
+ if (should_show_spin_down && dos.type === `electronic` && dos.spin_down_densities) {
234
+ let densities_down =
235
+ sigma > 0
236
+ ? apply_gaussian_smearing(x_values, dos.spin_down_densities, sigma)
237
+ : [...dos.spin_down_densities]
238
238
 
239
239
  densities_down = normalize_densities(densities_down, x_values, normalize)
240
240
 
@@ -246,12 +246,10 @@
246
246
  // For stacked plots with overlay mode, use separate spin-down cumulative
247
247
  // This prevents spin-down from stacking on top of spin-up within the same DOS
248
248
  if (stack && effective_spin_mode === `overlay`) {
249
- const prev_spin_down = cumulative_spin_down
250
- ? [...cumulative_spin_down]
251
- : null
249
+ const prev_spin_down = cumulative_spin_down ? [...cumulative_spin_down] : null
252
250
  if (cumulative_spin_down?.length === densities_down.length) {
253
- densities_down = densities_down.map((density, idx) =>
254
- density + (cumulative_spin_down?.[idx] ?? 0)
251
+ densities_down = densities_down.map(
252
+ (density, idx) => density + (cumulative_spin_down?.[idx] ?? 0),
255
253
  )
256
254
  } else if (cumulative_spin_down) {
257
255
  console.warn(`DOS stacking (spin-down): length mismatch for "${label}"`)
@@ -268,9 +266,10 @@
268
266
  }
269
267
 
270
268
  // Use a slightly different shade for spin-down in overlay mode
271
- const spin_down_color = effective_spin_mode === `overlay`
272
- ? PLOT_COLORS[(dos_idx * 2 + 1) % PLOT_COLORS.length]
273
- : color
269
+ const spin_down_color =
270
+ effective_spin_mode === `overlay`
271
+ ? PLOT_COLORS[(dos_idx * 2 + 1) % PLOT_COLORS.length]
272
+ : color
274
273
 
275
274
  const series_down: DataSeries = {
276
275
  x: is_horizontal ? densities_down : x_values,
@@ -291,9 +290,10 @@
291
290
  },
292
291
  )
293
292
 
294
- let all_freqs = $derived( // for clamping phonon noise
293
+ let all_freqs = $derived(
294
+ // for clamping phonon noise
295
295
  Object.values(doses_dict).flatMap((dos) =>
296
- dos.type === `phonon` ? dos.frequencies : dos.energies
296
+ dos.type === `phonon` ? dos.frequencies : dos.energies,
297
297
  ),
298
298
  )
299
299
  let clamp_to_zero = $derived(
@@ -304,14 +304,13 @@
304
304
  )
305
305
 
306
306
  // Check if we have mirrored spin-down data (negative densities)
307
- let has_mirrored_spin = $derived(
308
- effective_spin_mode === `mirror` && has_spin_polarized,
309
- )
307
+ let has_mirrored_spin = $derived(effective_spin_mode === `mirror` && has_spin_polarized)
310
308
 
311
309
  let x_range = $derived.by((): Vec2 | undefined => {
312
310
  if (series_data.length === 0) return undefined
313
311
  const all_x = series_data.flatMap((srs) => srs.x)
314
- const min_x = Math.min(...all_x), max_x = Math.max(...all_x)
312
+ const min_x = Math.min(...all_x),
313
+ max_x = Math.max(...all_x)
315
314
  // For horizontal orientation with mirror mode, allow negative values (mirrored densities)
316
315
  if (is_horizontal && has_mirrored_spin) return [min_x, max_x]
317
316
  if (is_horizontal || clamp_to_zero) return [0, max_x]
@@ -321,7 +320,8 @@
321
320
  let y_range = $derived.by((): Vec2 | undefined => {
322
321
  if (series_data.length === 0) return undefined
323
322
  const all_y = series_data.flatMap((srs) => srs.y)
324
- const min_y = Math.min(...all_y), max_y = Math.max(...all_y)
323
+ const min_y = Math.min(...all_y),
324
+ max_y = Math.max(...all_y)
325
325
  // For vertical orientation with mirror mode, allow negative values (mirrored densities)
326
326
  if (!is_horizontal && has_mirrored_spin) return [min_y, max_y]
327
327
  if (!is_horizontal || clamp_to_zero) return [0, max_y]
@@ -330,16 +330,10 @@
330
330
 
331
331
  // Get axis labels based on orientation
332
332
  let x_label = $derived(
333
- is_horizontal
334
- ? `Density of States`
335
- : is_phonon
336
- ? `Frequency (${units})`
337
- : `Energy (eV)`,
333
+ is_horizontal ? `Density of States` : is_phonon ? `Frequency (${units})` : `Energy (eV)`,
338
334
  )
339
335
  let y_label = $derived(
340
- is_horizontal
341
- ? (is_phonon ? `Frequency (${units})` : `Energy (eV)`)
342
- : `Density of States`,
336
+ is_horizontal ? (is_phonon ? `Frequency (${units})` : `Energy (eV)`) : `Density of States`,
343
337
  )
344
338
 
345
339
  // Compute final axis configurations with default labels
@@ -359,7 +353,6 @@
359
353
  range: y_range,
360
354
  ...y_axis,
361
355
  })
362
-
363
356
  // Sync zoom changes from ScatterPlot back to parent via bindable y_axis
364
357
  // Also clears parent range when internal range becomes invalid (auto-range reset)
365
358
  $effect(() => {
@@ -420,9 +413,13 @@
420
413
  lower_coords.push(`${lower_x.toFixed(2)},${lower_y.toFixed(2)}`)
421
414
  }
422
415
  // Trace upper edge forward, lower edge backward, close path
423
- return `M${upper_coords[0]} ${
424
- upper_coords.slice(1).map((coord) => `L${coord}`).join(` `)
425
- } ${lower_coords.toReversed().map((coord) => `L${coord}`).join(` `)} Z`
416
+ return `M${upper_coords[0]} ${upper_coords
417
+ .slice(1)
418
+ .map((coord) => `L${coord}`)
419
+ .join(` `)} ${lower_coords
420
+ .toReversed()
421
+ .map((coord) => `L${coord}`)
422
+ .join(` `)} Z`
426
423
  }
427
424
  </script>
428
425
 
@@ -436,24 +433,22 @@
436
433
  hover_config={{ threshold_px: 50 }}
437
434
  controls={{ show: show_controls }}
438
435
  on_point_hover={(event) => {
439
- hovered_frequency = is_horizontal
440
- ? (event?.point?.y ?? null)
441
- : (event?.point?.x ?? null)
436
+ hovered_frequency = is_horizontal ? (event?.point?.y ?? null) : (event?.point?.x ?? null)
442
437
  }}
443
438
  {...{ range_padding: 0, ...rest }}
444
439
  >
445
440
  {#snippet tooltip({ x_formatted, y_formatted, label })}
446
441
  {@const tooltip_data = format_dos_tooltip(
447
- x_formatted,
448
- y_formatted,
449
- label ?? null,
450
- is_horizontal,
451
- is_phonon,
452
- units,
453
- final_x_axis.label ?? ``,
454
- internal_y_axis.label ?? ``,
455
- Object.keys(doses_dict).length,
456
- )}
442
+ x_formatted,
443
+ y_formatted,
444
+ label ?? null,
445
+ is_horizontal,
446
+ is_phonon,
447
+ units,
448
+ final_x_axis.label ?? ``,
449
+ internal_y_axis.label ?? ``,
450
+ Object.keys(doses_dict).length,
451
+ )}
457
452
  {#if tooltip_data.title}<strong>{tooltip_data.title}</strong><br />{/if}
458
453
  {#each tooltip_data.lines as line, line_idx (line_idx)}
459
454
  {line}{#if line_idx < tooltip_data.lines.length - 1}<br />{/if}
@@ -559,15 +554,16 @@
559
554
  {/if}
560
555
 
561
556
  <!-- Fermi level line for electronic DOS -->
562
- {@const fermi_pos = effective_fermi_level !== undefined
563
- ? (is_horizontal
564
- ? y_scale_fn(effective_fermi_level)
565
- : x_scale_fn(effective_fermi_level))
566
- : NaN}
557
+ {@const fermi_pos =
558
+ effective_fermi_level !== undefined
559
+ ? is_horizontal
560
+ ? y_scale_fn(effective_fermi_level)
561
+ : x_scale_fn(effective_fermi_level)
562
+ : NaN}
567
563
  {#if Number.isFinite(fermi_pos)}
568
564
  {@const [x1, x2, y1, y2] = is_horizontal
569
- ? [pad.l, width - pad.r, fermi_pos, fermi_pos]
570
- : [fermi_pos, fermi_pos, pad.t, height - pad.b]}
565
+ ? [pad.l, width - pad.r, fermi_pos, fermi_pos]
566
+ : [fermi_pos, fermi_pos, pad.t, height - pad.b]}
571
567
  <line
572
568
  class="fermi-level-line"
573
569
  {x1}
@@ -608,15 +604,16 @@
608
604
  {/if}
609
605
 
610
606
  <!-- Reference frequency line -->
611
- {@const ref_pos = reference_frequency !== null
612
- ? (is_horizontal
613
- ? y_scale_fn(reference_frequency)
614
- : x_scale_fn(reference_frequency))
615
- : NaN}
607
+ {@const ref_pos =
608
+ reference_frequency !== null
609
+ ? is_horizontal
610
+ ? y_scale_fn(reference_frequency)
611
+ : x_scale_fn(reference_frequency)
612
+ : NaN}
616
613
  {#if Number.isFinite(ref_pos)}
617
614
  {@const [x1, x2, y1, y2] = is_horizontal
618
- ? [pad.l, width - pad.r, ref_pos, ref_pos]
619
- : [ref_pos, ref_pos, pad.t, height - pad.b]}
615
+ ? [pad.l, width - pad.r, ref_pos, ref_pos]
616
+ : [ref_pos, ref_pos, pad.t, height - pad.b]}
620
617
  <line
621
618
  {x1}
622
619
  {x2}
@@ -34,14 +34,14 @@ export declare function qpoint_x_position(band_struct: types.BaseBandStructure,
34
34
  export declare function find_qpoint_at_rescaled_x(band_struct: types.BaseBandStructure, rescaled_x: number, x_positions: Record<string, Vec2>): number | null;
35
35
  type SpinDensities = Record<string, number[]>;
36
36
  export interface PymatgenDos {
37
- '@class': string;
38
- '@module': string;
37
+ '@class'?: string;
38
+ '@module'?: string;
39
39
  energies: number[];
40
40
  densities: SpinDensities | number[];
41
41
  efermi: number;
42
42
  }
43
43
  export interface PymatgenCompleteDos extends PymatgenDos {
44
- '@class': `CompleteDos` | `LobsterCompleteDos`;
44
+ '@class'?: `CompleteDos` | `LobsterCompleteDos`;
45
45
  structure?: Record<string, unknown>;
46
46
  pdos?: Record<string, SpinDensities>[];
47
47
  atom_dos?: Record<string, PymatgenDos>;
@@ -92,7 +92,7 @@ export function pretty_sym_point(symbol) {
92
92
  .replaceAll(/\\?DELTA/gi, `Δ`)
93
93
  .replaceAll(/\\?SIGMA/gi, `Σ`)
94
94
  .replaceAll(/\\?LAMBDA/gi, `Λ`)
95
- .replaceAll(/(\p{L})(\d+)/gu, (_, letter, num) => letter +
95
+ .replaceAll(/(?<letter>\p{L})(?<num>\d+)/gu, (_, letter, num) => letter +
96
96
  num
97
97
  .split(``)
98
98
  .map((digit) => (is_subscript_key(digit) ? SUBSCRIPT_MAP[digit] : digit))
@@ -195,33 +195,24 @@ export function convert_frequencies(frequencies, unit = `THz`) {
195
195
  }
196
196
  // Normalize DOS densities according to specified mode.
197
197
  export function normalize_densities(densities, freqs_or_energies, mode) {
198
- if (!mode)
199
- return densities;
200
- const normalized = [...densities];
201
198
  if (mode === `max`) {
202
- const max_val = Math.max(...normalized);
203
- if (max_val === 0)
204
- return normalized;
205
- return normalized.map((dens) => dens / max_val);
199
+ const max_val = Math.max(...densities);
200
+ return max_val === 0 ? densities : densities.map((dens) => dens / max_val);
206
201
  }
207
- else if (mode === `sum`) {
208
- const sum = normalized.reduce((acc, dens) => acc + dens, 0);
209
- if (sum === 0)
210
- return normalized;
211
- return normalized.map((dens) => dens / sum);
202
+ if (mode === `sum`) {
203
+ const sum = densities.reduce((acc, dens) => acc + dens, 0);
204
+ return sum === 0 ? densities : densities.map((dens) => dens / sum);
212
205
  }
213
- else if (mode === `integral`) {
206
+ if (mode === `integral`) {
214
207
  if (freqs_or_energies.length < 2)
215
- return normalized;
208
+ return densities;
216
209
  const bin_width = freqs_or_energies[1] - freqs_or_energies[0];
217
- if (bin_width === 0)
218
- return normalized;
219
- const sum = normalized.reduce((acc, dens) => acc + dens, 0);
220
- if (sum === 0)
221
- return normalized;
222
- return normalized.map((dens) => dens / (sum * bin_width));
210
+ const sum = densities.reduce((acc, dens) => acc + dens, 0);
211
+ if (bin_width === 0 || sum === 0)
212
+ return densities;
213
+ return densities.map((dens) => dens / (sum * bin_width));
223
214
  }
224
- return normalized;
215
+ return densities;
225
216
  }
226
217
  // Simple LRU cache for Gaussian smearing results
227
218
  // Key: hash of (frequencies, densities, sigma), Value: smeared densities
@@ -255,18 +246,16 @@ function apply_gaussian_smearing_core(freqs_or_energies, densities, sigma) {
255
246
  if (sigma <= 0 || orig_sum === 0)
256
247
  return densities;
257
248
  const smeared = Array(densities.length).fill(0);
258
- const truncation_width = 4; // Truncate Gaussian at ±4σ (contribution < 0.01%)
249
+ const cutoff = 4 * sigma; // Truncate Gaussian at ±4σ (contribution < 0.01%)
250
+ const inv_two_sigma_sq = 1 / (2 * sigma ** 2);
259
251
  for (let idx = 0; idx < freqs_or_energies.length; idx++) {
260
252
  const energy = freqs_or_energies[idx];
261
- const cutoff = truncation_width * sigma;
262
253
  for (let jdx = 0; jdx < freqs_or_energies.length; jdx++) {
263
- const e_j = freqs_or_energies[jdx];
264
- const delta = Math.abs(energy - e_j);
254
+ const delta = energy - freqs_or_energies[jdx];
265
255
  // Skip points beyond truncation width
266
- if (delta > cutoff)
256
+ if (Math.abs(delta) > cutoff)
267
257
  continue;
268
- const gaussian = Math.exp(-((energy - e_j) ** 2) / (2 * sigma ** 2));
269
- smeared[idx] += densities[jdx] * gaussian;
258
+ smeared[idx] += densities[jdx] * Math.exp(-(delta ** 2) * inv_two_sigma_sq);
270
259
  }
271
260
  }
272
261
  // Normalize to preserve integral
@@ -958,7 +947,7 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
958
947
  }
959
948
  }
960
949
  }
961
- const dos_list = doses
950
+ const dos_list = doses && typeof doses === `object`
962
951
  ? `densities` in doses
963
952
  ? [normalize_dos(doses)]
964
953
  : Object.values(doses).map((dos) => normalize_dos(dos))
@@ -981,18 +970,19 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
981
970
  }
982
971
  if (!Number.isFinite(min_val) || !Number.isFinite(max_val))
983
972
  return undefined;
984
- const clamp_min = is_phonon &&
985
- min_val < 0 && // clamp phonon noise to 0
986
- negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD;
987
- if (clamp_min)
973
+ // clamp phonon noise to 0
974
+ if (is_phonon &&
975
+ min_val < 0 &&
976
+ negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD) {
988
977
  min_val = 0;
978
+ }
989
979
  // Calculate padding from (possibly clamped) range for consistency with Bands.svelte
990
980
  const padding = (max_val - min_val) * padding_factor;
991
981
  return [min_val === 0 ? 0 : min_val - padding, max_val + padding];
992
982
  }
993
983
  // Parse axis label: "Frequency (THz)" → { name: "Frequency", unit: "THz" }
994
984
  function parse_axis_label(label) {
995
- const match = /^(.+?)\s*\(([^)]+)\)$/.exec(label);
985
+ const match = /^(?<name>.+?)\s*\((?<unit>[^)]+)\)$/.exec(label);
996
986
  return match ? { name: match[1], unit: match[2] } : { name: label };
997
987
  }
998
988
  const format_tooltip_line = (name, value, unit) => `${name}: ${value}${unit ? ` ${unit}` : ``}`;
@@ -1,6 +1,6 @@
1
1
  import { AUTO_THEME, COLOR_THEMES, THEME_TYPE } from './theme/index';
2
2
  import { DEFAULT_CATEGORY_COLORS, default_element_colors } from './colors';
3
- import { is_valid_theme_mode } from './theme';
3
+ import { get_theme_preference } from './theme';
4
4
  export const selected = $state({
5
5
  category: null,
6
6
  element: null,
@@ -11,23 +11,10 @@ export const colors = $state({
11
11
  category: { ...DEFAULT_CATEGORY_COLORS },
12
12
  element: { ...default_element_colors },
13
13
  });
14
- // Theme state with safe initialization
15
- let initial_theme_mode = AUTO_THEME;
16
- let initial_system_mode = COLOR_THEMES.light;
17
- // Safe theme initialization for test environments
18
- try {
19
- if (typeof window !== `undefined` && globalThis.localStorage) {
20
- const saved_theme = localStorage.getItem(`matterviz-theme`) ?? ``;
21
- initial_theme_mode = is_valid_theme_mode(saved_theme) ? saved_theme : AUTO_THEME;
22
- }
23
- else {
24
- initial_theme_mode = AUTO_THEME;
25
- initial_system_mode = COLOR_THEMES.light;
26
- }
27
- }
28
- catch {
29
- // Fallback for test environments or when localStorage is not available
30
- }
14
+ // Theme state with safe initialization (get_theme_preference handles SSR +
15
+ // missing/invalid localStorage, falling back to AUTO_THEME)
16
+ const initial_theme_mode = get_theme_preference();
17
+ const initial_system_mode = COLOR_THEMES.light;
31
18
  export const theme_state = $state({
32
19
  mode: initial_theme_mode,
33
20
  system_mode: initial_system_mode,
@@ -4,7 +4,7 @@
4
4
  import { DEFAULTS } from '../settings'
5
5
  import { T } from '@threlte/core'
6
6
  import type { ComponentProps } from 'svelte'
7
- import { Euler, Quaternion, Vector3 } from 'three'
7
+ import { rotation_from_direction } from './geometry'
8
8
 
9
9
  let {
10
10
  position,
@@ -26,35 +26,22 @@
26
26
  } = $props()
27
27
 
28
28
  const mag = $derived(Math.hypot(...vector))
29
- const dir = $derived(
30
- mag > math.EPS ? math.scale(vector, 1 / mag) : ([0, 1, 0] as Vec3),
31
- )
29
+ const dir = $derived(mag > math.EPS ? math.scale(vector, 1 / mag) : ([0, 1, 0] as Vec3))
32
30
  const vec_len = $derived(mag * scale)
33
31
 
34
32
  const head_len = $derived(
35
33
  arrow_head_length < 0 ? vec_len * -arrow_head_length : arrow_head_length,
36
34
  )
37
35
  const shaft_len = $derived(Math.max(0, vec_len - head_len * 0.5))
38
- const shaft_r = $derived(
39
- shaft_radius < 0 ? shaft_len * -shaft_radius : shaft_radius,
40
- )
36
+ const shaft_r = $derived(shaft_radius < 0 ? shaft_len * -shaft_radius : shaft_radius)
41
37
  const head_r = $derived(
42
38
  arrow_head_radius < 0 ? shaft_len * -arrow_head_radius : arrow_head_radius,
43
39
  )
44
40
 
45
41
  const shaft_pos = $derived(math.add(position, math.scale(dir, shaft_len * 0.5)))
46
- const head_pos = $derived(
47
- math.add(position, math.scale(dir, shaft_len + head_len * 0.5)),
48
- )
42
+ const head_pos = $derived(math.add(position, math.scale(dir, shaft_len + head_len * 0.5)))
49
43
 
50
- const rotation = $derived.by((): Vec3 => {
51
- if (mag < math.EPS) return [0, 0, 0]
52
- const quat = new Quaternion().setFromUnitVectors(
53
- new Vector3(0, 1, 0),
54
- new Vector3(...dir),
55
- )
56
- return new Euler().setFromQuaternion(quat).toArray().slice(0, 3) as Vec3
57
- })
44
+ const rotation = $derived(rotation_from_direction(vector))
58
45
  </script>
59
46
 
60
47
  {#if shaft_len > 0.01}