matterviz 0.4.1 → 0.4.3

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 (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -81,7 +81,7 @@ export const IMAGINARY_MODE_NOISE_THRESHOLD = 0.005; // Clamp negatives < 0.5% a
81
81
  export function pretty_sym_point(symbol) {
82
82
  if (!symbol)
83
83
  return ``;
84
- // Remove underscores (htmlify maps S0 S<sub>0</sub> but leaves S_0 as is)
84
+ // Remove underscores so S_0 and S0 are treated alike
85
85
  // Replace common symmetry point names with Greek letters
86
86
  // Handle both plain names (GAMMA) and LaTeX notation (\Gamma) from pymatgen
87
87
  // Handle subscripts: convert S0 to S₀, K1 to K₁, Γ1 to Γ₁, etc.
@@ -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
@@ -347,35 +336,15 @@ const SPIN_DOWN_KEYS = [`-1`, `Spin.down`];
347
336
  export function extract_spin_channels(data) {
348
337
  if (Array.isArray(data))
349
338
  return { up: data, down: null };
350
- if (data && typeof data === `object`) {
351
- const record = data;
352
- let spin_up = null;
353
- let spin_down = null;
354
- // Extract spin-up channel
355
- for (const key of SPIN_UP_KEYS) {
356
- if (key in record) {
357
- spin_up = record[key];
358
- break;
359
- }
360
- }
361
- // Extract spin-down channel
362
- for (const key of SPIN_DOWN_KEYS) {
363
- if (key in record) {
364
- spin_down = record[key];
365
- break;
366
- }
367
- }
368
- // Fall back to first key if no spin-up key found
369
- if (spin_up === null) {
370
- const keys = Object.keys(record);
371
- if (keys.length > 0)
372
- spin_up = record[keys[0]];
373
- }
374
- if (spin_up === null)
375
- return null;
376
- return { up: spin_up, down: spin_down };
377
- }
378
- return null;
339
+ if (!data || typeof data !== `object`)
340
+ return null;
341
+ const record = data;
342
+ const up_key = SPIN_UP_KEYS.find((key) => key in record);
343
+ const down_key = SPIN_DOWN_KEYS.find((key) => key in record);
344
+ // No spin-up key: do not fall back to Object.keys()[0] (could be spin-down)
345
+ if (up_key === undefined)
346
+ return null;
347
+ return { up: record[up_key], down: down_key !== undefined ? record[down_key] : null };
379
348
  }
380
349
  // Convert pymatgen PhononBandStructureSymmLine or BandStructure to matterviz format
381
350
  function convert_pymatgen_band_structure(pmg) {
@@ -651,6 +620,8 @@ export function find_qpoint_at_distance(band_struct, target) {
651
620
  return null;
652
621
  return distance.reduce((closest, dist, idx) => Math.abs(dist - target) < Math.abs(distance[closest] - target) ? idx : closest, 0);
653
622
  }
623
+ // Look up a branch's x-range in the plot via its start/end q-point labels
624
+ const branch_x_range = (bs, branch, x_positions) => x_positions[get_segment_key(bs.qpoints[branch.start_index]?.label ?? undefined, bs.qpoints[branch.end_index]?.label ?? undefined)];
654
625
  // Rescaled x-position of a q-point index along the band plot path. Inverse of
655
626
  // find_qpoint_at_rescaled_x, used to highlight a q-point hovered in the Brillouin zone.
656
627
  // Returns null if the index doesn't fall on a plotted (non-discontinuity) branch.
@@ -660,9 +631,7 @@ export function qpoint_x_position(band_struct, qpoint_index, x_positions) {
660
631
  for (const branch of band_struct.branches) {
661
632
  if (qpoint_index < branch.start_index || qpoint_index > branch.end_index)
662
633
  continue;
663
- const start_label = band_struct.qpoints[branch.start_index]?.label ?? undefined;
664
- const end_label = band_struct.qpoints[branch.end_index]?.label ?? undefined;
665
- const range = x_positions[get_segment_key(start_label, end_label)];
634
+ const range = branch_x_range(band_struct, branch, x_positions);
666
635
  if (!range)
667
636
  continue;
668
637
  const [x_start, x_end] = range;
@@ -682,74 +651,50 @@ export function find_qpoint_at_rescaled_x(band_struct, rescaled_x, x_positions)
682
651
  return null;
683
652
  // Find which segment contains this x coordinate
684
653
  for (const branch of band_struct.branches) {
685
- const start_idx = branch.start_index;
686
- const end_idx = branch.end_index;
687
- const start_label = band_struct.qpoints[start_idx]?.label ?? undefined;
688
- const end_label = band_struct.qpoints[end_idx]?.label ?? undefined;
689
- const segment_key = get_segment_key(start_label, end_label);
690
- const segment_range = x_positions[segment_key];
654
+ const { start_index: start_idx, end_index: end_idx } = branch;
655
+ const segment_range = branch_x_range(band_struct, branch, x_positions);
691
656
  if (!segment_range)
692
657
  continue;
693
658
  const [x_start, x_end] = segment_range;
694
- // Check if discontinuity (zero-length segment)
695
- const is_discontinuity = Math.abs(x_end - x_start) < 1e-6;
696
- if (is_discontinuity) {
697
- // For discontinuities, check if x is exactly at this point
698
- if (Math.abs(rescaled_x - x_start) < 1e-6) {
659
+ // Discontinuity (zero-length segment): match only if x is exactly at this point
660
+ if (Math.abs(x_end - x_start) < 1e-6) {
661
+ if (Math.abs(rescaled_x - x_start) < 1e-6)
699
662
  return start_idx;
700
- }
701
663
  continue;
702
664
  }
703
665
  // Check if x is within this segment (with small tolerance for edges)
704
666
  if (rescaled_x >= x_start - 1e-6 && rescaled_x <= x_end + 1e-6) {
705
667
  // Map from rescaled x back to original distance
706
- const segment_distances = band_struct.distance.slice(start_idx, end_idx + 1);
707
- const dist_min = segment_distances[0];
708
- const dist_max = segment_distances.at(-1) ?? dist_min;
709
- const dist_range = dist_max - dist_min;
710
- // Handle zero-length segments
711
- if (dist_range === 0) {
668
+ const dist_min = band_struct.distance[start_idx];
669
+ const dist_range = band_struct.distance[end_idx] - dist_min;
670
+ if (dist_range === 0)
712
671
  return start_idx;
713
- }
714
672
  // Inverse of the scaling: x = x_start + ((dist - dist_min) / dist_range) * (x_end - x_start)
715
- // Solving for dist: dist = dist_min + ((x - x_start) / (x_end - x_start)) * dist_range
716
673
  const normalized_x = (rescaled_x - x_start) / (x_end - x_start);
717
674
  const target_dist = dist_min + normalized_x * dist_range;
718
675
  // Find closest qpoint in this branch to the target distance
719
- let closest_idx = start_idx;
720
- let min_diff = Math.abs(band_struct.distance[start_idx] - target_dist);
676
+ let [closest_idx, min_diff] = [start_idx, Infinity];
721
677
  for (let idx = start_idx; idx <= end_idx; idx++) {
722
678
  const diff = Math.abs(band_struct.distance[idx] - target_dist);
723
- if (diff < min_diff) {
724
- min_diff = diff;
725
- closest_idx = idx;
726
- }
679
+ if (diff < min_diff)
680
+ [closest_idx, min_diff] = [idx, diff];
727
681
  }
728
682
  return closest_idx;
729
683
  }
730
684
  }
731
685
  // Fallback: find closest labeled point
732
- let closest_idx = 0;
733
- let min_dist = Infinity;
686
+ let [closest_idx, min_dist] = [0, Infinity];
734
687
  for (const branch of band_struct.branches) {
735
- const start_idx = branch.start_index;
736
- const end_idx = branch.end_index;
737
- const start_label = band_struct.qpoints[start_idx]?.label ?? undefined;
738
- const end_label = band_struct.qpoints[end_idx]?.label ?? undefined;
739
- const segment_key = get_segment_key(start_label, end_label);
740
- const segment_range = x_positions[segment_key];
688
+ const segment_range = branch_x_range(band_struct, branch, x_positions);
741
689
  if (!segment_range)
742
690
  continue;
743
- const [x_start, x_end] = segment_range;
744
691
  for (const [x_pos, idx] of [
745
- [x_start, start_idx],
746
- [x_end, end_idx],
692
+ [segment_range[0], branch.start_index],
693
+ [segment_range[1], branch.end_index],
747
694
  ]) {
748
695
  const dist = Math.abs(rescaled_x - x_pos);
749
- if (dist < min_dist) {
750
- min_dist = dist;
751
- closest_idx = idx;
752
- }
696
+ if (dist < min_dist)
697
+ [closest_idx, min_dist] = [idx, dist];
753
698
  }
754
699
  }
755
700
  return closest_idx;
@@ -802,24 +747,15 @@ const shift_dos_energies = (dos, shift) => ({
802
747
  // Recursively shifts nested DOS in atom_dos and spd_dos for consistency
803
748
  export function shift_to_fermi(dos) {
804
749
  const shift = dos.efermi;
805
- // Shift root DOS energies using the shared helper
806
- const shifted_root = shift_dos_energies(dos, shift);
807
- // Shift nested atom_dos if present
808
- const atom_dos = dos.atom_dos
809
- ? Object.fromEntries(Object.entries(dos.atom_dos).map(([key, nested_dos]) => [
810
- key,
811
- shift_dos_energies(nested_dos, shift),
812
- ]))
813
- : undefined;
814
- // Shift nested spd_dos if present
815
- const spd_dos = dos.spd_dos
816
- ? Object.fromEntries(Object.entries(dos.spd_dos).map(([key, nested_dos]) => [
750
+ const shift_nested = (nested) => nested &&
751
+ Object.fromEntries(Object.entries(nested).map(([key, nested_dos]) => [
817
752
  key,
818
753
  shift_dos_energies(nested_dos, shift),
819
- ]))
820
- : undefined;
754
+ ]));
755
+ const atom_dos = shift_nested(dos.atom_dos);
756
+ const spd_dos = shift_nested(dos.spd_dos);
821
757
  return {
822
- ...shifted_root,
758
+ ...shift_dos_energies(dos, shift),
823
759
  efermi: 0, // Explicitly set to 0 (shift_dos_energies would give efermi - shift)
824
760
  ...(atom_dos && { atom_dos }),
825
761
  ...(spd_dos && { spd_dos }),
@@ -916,26 +852,14 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
916
852
  const all_freqs = [];
917
853
  // Check raw band_structs for electronic markers before normalization
918
854
  // (normalized structures always have qpoints, so we can't detect from them)
919
- let has_electronic_bs = false;
920
855
  // Support both qpoints (phonon) and kpoints (electronic) to detect single vs dict
921
856
  const is_single_bs = band_structs &&
922
857
  typeof band_structs === `object` &&
923
858
  (`qpoints` in band_structs || `kpoints` in band_structs);
924
- if (band_structs && typeof band_structs === `object`) {
925
- // Single structure check
926
- if (is_electronic_band_struct(band_structs)) {
927
- has_electronic_bs = true;
928
- }
929
- else if (!is_single_bs) {
930
- // Dict of band structures - check each value
931
- for (const bs_val of Object.values(band_structs)) {
932
- if (is_electronic_band_struct(bs_val)) {
933
- has_electronic_bs = true;
934
- break;
935
- }
936
- }
937
- }
938
- }
859
+ const has_electronic_bs = band_structs &&
860
+ typeof band_structs === `object` &&
861
+ (is_electronic_band_struct(band_structs) ||
862
+ (!is_single_bs && Object.values(band_structs).some(is_electronic_band_struct)));
939
863
  const bs_list = band_structs
940
864
  ? is_single_bs
941
865
  ? [normalize_band_structure(band_structs)]
@@ -958,7 +882,7 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
958
882
  }
959
883
  }
960
884
  }
961
- const dos_list = doses
885
+ const dos_list = doses && typeof doses === `object`
962
886
  ? `densities` in doses
963
887
  ? [normalize_dos(doses)]
964
888
  : Object.values(doses).map((dos) => normalize_dos(dos))
@@ -981,18 +905,19 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
981
905
  }
982
906
  if (!Number.isFinite(min_val) || !Number.isFinite(max_val))
983
907
  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)
908
+ // clamp phonon noise to 0
909
+ if (is_phonon &&
910
+ min_val < 0 &&
911
+ negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD) {
988
912
  min_val = 0;
913
+ }
989
914
  // Calculate padding from (possibly clamped) range for consistency with Bands.svelte
990
915
  const padding = (max_val - min_val) * padding_factor;
991
916
  return [min_val === 0 ? 0 : min_val - padding, max_val + padding];
992
917
  }
993
918
  // Parse axis label: "Frequency (THz)" → { name: "Frequency", unit: "THz" }
994
919
  function parse_axis_label(label) {
995
- const match = /^(.+?)\s*\(([^)]+)\)$/.exec(label);
920
+ const match = /^(?<name>.+?)\s*\((?<unit>[^)]+)\)$/.exec(label);
996
921
  return match ? { name: match[1], unit: match[2] } : { name: label };
997
922
  }
998
923
  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}
@@ -0,0 +1,160 @@
1
+ <script lang="ts">
2
+ // Instanced arrows (shaft cylinders + head cones) for per-site vector layers
3
+ // (forces, magnetic moments, ...). Replaces one <Arrow> component per site
4
+ // (2 meshes + 2 geometries + 2 materials each) with 2 draw calls per layer.
5
+ // Sizing math mirrors Arrow.svelte so the two render identically.
6
+ import type { Vec3 } from '../math'
7
+ import { EPS } from '../math'
8
+ import { T, useThrelte } from '@threlte/core'
9
+ import { untrack } from 'svelte'
10
+ import type { BufferGeometry } from 'three'
11
+ import {
12
+ Color,
13
+ ConeGeometry,
14
+ CylinderGeometry,
15
+ InstancedMesh,
16
+ Matrix4,
17
+ MeshStandardMaterial,
18
+ Quaternion,
19
+ Vector3,
20
+ } from 'three'
21
+
22
+ type ArrowInstance = {
23
+ position: Vec3
24
+ vector: Vec3
25
+ scale: number
26
+ color: string
27
+ }
28
+
29
+ let {
30
+ arrows,
31
+ shaft_radius,
32
+ arrow_head_radius,
33
+ arrow_head_length,
34
+ }: {
35
+ arrows: ArrowInstance[]
36
+ shaft_radius: number // negative = relative to shaft length
37
+ arrow_head_radius: number // negative = relative to shaft length
38
+ arrow_head_length: number // negative = relative to arrow length
39
+ } = $props()
40
+
41
+ const { invalidate } = useThrelte()
42
+
43
+ // Unit primitives scaled per instance: cylinder radius/length via (x=r, y=len, z=r)
44
+ const shaft_geometry = new CylinderGeometry(1, 1, 1, 12)
45
+ const head_geometry = new ConeGeometry(1, 1, 12)
46
+ const shaft_material = new MeshStandardMaterial()
47
+ const head_material = new MeshStandardMaterial()
48
+ $effect(() => () => {
49
+ shaft_geometry.dispose()
50
+ head_geometry.dispose()
51
+ shaft_material.dispose()
52
+ head_material.dispose()
53
+ })
54
+
55
+ const make_mesh = (
56
+ geometry: BufferGeometry,
57
+ material: MeshStandardMaterial,
58
+ count: number,
59
+ ): InstancedMesh => {
60
+ const mesh = new InstancedMesh(geometry, material, count)
61
+ mesh.frustumCulled = false
62
+ mesh.raycast = () => undefined // arrows are display-only
63
+ mesh.userData.per_instance_color = true
64
+ return mesh
65
+ }
66
+
67
+ // Recreate meshes only when the arrow count changes (fixed buffer capacity)
68
+ let shaft_mesh = $state.raw<InstancedMesh | null>(null)
69
+ let head_mesh = $state.raw<InstancedMesh | null>(null)
70
+ $effect(() => {
71
+ const count = arrows.length
72
+ const prev = untrack(() => shaft_mesh)
73
+ if (prev && prev.count === count) return
74
+ prev?.dispose()
75
+ untrack(() => head_mesh)?.dispose()
76
+ if (count === 0) {
77
+ shaft_mesh = null
78
+ head_mesh = null
79
+ return
80
+ }
81
+ shaft_mesh = make_mesh(shaft_geometry, shaft_material, count)
82
+ head_mesh = make_mesh(head_geometry, head_material, count)
83
+ })
84
+ // Unmount-only cleanup (a cleanup on the effect above would dispose meshes
85
+ // on every re-run, including runs that keep them; cleanups run untracked)
86
+ $effect(() => () => {
87
+ shaft_mesh?.dispose()
88
+ head_mesh?.dispose()
89
+ })
90
+
91
+ const up_axis = new Vector3(0, 1, 0)
92
+ const scratch_dir = new Vector3()
93
+ const scratch_quat = new Quaternion()
94
+ const scratch_pos = new Vector3()
95
+ const scratch_scale = new Vector3()
96
+ const scratch_matrix = new Matrix4()
97
+ const scratch_color = new Color()
98
+
99
+ $effect(() => {
100
+ const shafts = shaft_mesh
101
+ const heads = head_mesh
102
+ if (!shafts || !heads) return
103
+ const limit = Math.min(arrows.length, shafts.count)
104
+ for (let idx = 0; idx < limit; idx++) {
105
+ const { position, vector, scale, color } = arrows[idx]
106
+ const mag = Math.hypot(vector[0], vector[1], vector[2])
107
+ if (mag > EPS) {
108
+ scratch_dir.set(vector[0] / mag, vector[1] / mag, vector[2] / mag)
109
+ scratch_quat.setFromUnitVectors(up_axis, scratch_dir)
110
+ } else {
111
+ scratch_dir.set(0, 1, 0)
112
+ scratch_quat.identity()
113
+ }
114
+ const vec_len = mag * scale
115
+ const head_len = arrow_head_length < 0 ? vec_len * -arrow_head_length : arrow_head_length
116
+ const shaft_len = Math.max(0, vec_len - head_len * 0.5)
117
+ const shaft_r = shaft_radius < 0 ? shaft_len * -shaft_radius : shaft_radius
118
+ const head_r = arrow_head_radius < 0 ? shaft_len * -arrow_head_radius : arrow_head_radius
119
+
120
+ // Shafts shorter than Arrow.svelte's 0.01 render threshold collapse to zero scale
121
+ const draw_shaft = shaft_len > 0.01
122
+ scratch_pos.set(
123
+ position[0] + scratch_dir.x * shaft_len * 0.5,
124
+ position[1] + scratch_dir.y * shaft_len * 0.5,
125
+ position[2] + scratch_dir.z * shaft_len * 0.5,
126
+ )
127
+ scratch_scale.set(
128
+ draw_shaft ? shaft_r : 0,
129
+ draw_shaft ? shaft_len : 0,
130
+ draw_shaft ? shaft_r : 0,
131
+ )
132
+ shafts.setMatrixAt(idx, scratch_matrix.compose(scratch_pos, scratch_quat, scratch_scale))
133
+
134
+ const head_offset = shaft_len + head_len * 0.5
135
+ scratch_pos.set(
136
+ position[0] + scratch_dir.x * head_offset,
137
+ position[1] + scratch_dir.y * head_offset,
138
+ position[2] + scratch_dir.z * head_offset,
139
+ )
140
+ scratch_scale.set(head_r, head_len, head_r)
141
+ heads.setMatrixAt(idx, scratch_matrix.compose(scratch_pos, scratch_quat, scratch_scale))
142
+
143
+ scratch_color.set(color)
144
+ shafts.setColorAt(idx, scratch_color)
145
+ heads.setColorAt(idx, scratch_color)
146
+ }
147
+ for (const mesh of [shafts, heads]) {
148
+ mesh.instanceMatrix.needsUpdate = true
149
+ if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true
150
+ }
151
+ invalidate()
152
+ })
153
+ </script>
154
+
155
+ {#if shaft_mesh}
156
+ <T is={shaft_mesh} />
157
+ {/if}
158
+ {#if head_mesh}
159
+ <T is={head_mesh} />
160
+ {/if}
@@ -0,0 +1,16 @@
1
+ import type { Vec3 } from '../math';
2
+ type ArrowInstance = {
3
+ position: Vec3;
4
+ vector: Vec3;
5
+ scale: number;
6
+ color: string;
7
+ };
8
+ type $$ComponentProps = {
9
+ arrows: ArrowInstance[];
10
+ shaft_radius: number;
11
+ arrow_head_radius: number;
12
+ arrow_head_length: number;
13
+ };
14
+ declare const ArrowInstances: import("svelte").Component<$$ComponentProps, {}, "">;
15
+ type ArrowInstances = ReturnType<typeof ArrowInstances>;
16
+ export default ArrowInstances;