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
@@ -143,25 +143,25 @@
143
143
  if (!band_structs) return {}
144
144
 
145
145
  // Detect single band structure by checking for characteristic fields
146
- // - pymatgen format: has @class or @module markers (may also have branches)
147
146
  // - matterviz format: has qpoints + branches (no pymatgen markers)
148
- const has_qpoints = `qpoints` in band_structs &&
147
+ const has_qpoints =
148
+ `qpoints` in band_structs &&
149
149
  Array.isArray(band_structs.qpoints) &&
150
150
  band_structs.qpoints.length > 0
151
- const has_kpoints = `kpoints` in band_structs &&
151
+ const has_kpoints =
152
+ `kpoints` in band_structs &&
152
153
  Array.isArray(band_structs.kpoints) &&
153
154
  band_structs.kpoints.length > 0
154
155
  const has_bands = `bands` in band_structs
155
- const has_frequencies_cm = `frequencies_cm` in band_structs &&
156
- Array.isArray(band_structs.frequencies_cm)
156
+ const has_frequencies_cm =
157
+ `frequencies_cm` in band_structs && Array.isArray(band_structs.frequencies_cm)
157
158
  const has_branches = `branches` in band_structs
158
159
  // Pymatgen structures have explicit class/module markers
159
160
  const is_pymatgen = `@class` in band_structs || `@module` in band_structs
160
161
 
161
162
  // Pymatgen single: has markers and point/band data (may have branches too)
162
- const is_pymatgen_single = is_pymatgen &&
163
- (has_qpoints || has_kpoints) &&
164
- (has_bands || has_frequencies_cm)
163
+ const is_pymatgen_single =
164
+ is_pymatgen && (has_qpoints || has_kpoints) && (has_bands || has_frequencies_cm)
165
165
  // Matterviz single: has qpoints + branches but NO pymatgen markers
166
166
  const is_matterviz_single = !is_pymatgen && has_qpoints && has_branches
167
167
  const is_single = is_matterviz_single || is_pymatgen_single
@@ -186,8 +186,11 @@
186
186
  if (!band_structs) return `phonon`
187
187
 
188
188
  // Single structure has marker fields; dict of structures has label keys
189
- const is_single = `@class` in band_structs || `@module` in band_structs ||
190
- `kpoints` in band_structs || `qpoints` in band_structs
189
+ const is_single =
190
+ `@class` in band_structs ||
191
+ `@module` in band_structs ||
192
+ `kpoints` in band_structs ||
193
+ `qpoints` in band_structs
191
194
  const source = (is_single ? band_structs : Object.values(band_structs)[0]) as
192
195
  | Record<string, unknown>
193
196
  | undefined
@@ -196,12 +199,11 @@
196
199
  // Electronic: has kpoints, BandStructure* class (not Phonon*), or electronic_structure module
197
200
  const py_class_name = String(source[`@class`] ?? ``)
198
201
  if (
199
- (`kpoints` in source && Array.isArray(source.kpoints) &&
200
- source.kpoints.length > 0) ||
201
- (py_class_name.startsWith(`BandStructure`) &&
202
- !py_class_name.startsWith(`Phonon`)) ||
202
+ (`kpoints` in source && Array.isArray(source.kpoints) && source.kpoints.length > 0) ||
203
+ (py_class_name.startsWith(`BandStructure`) && !py_class_name.startsWith(`Phonon`)) ||
203
204
  String(source[`@module`] ?? ``).includes(`electronic_structure`)
204
- ) return `electronic`
205
+ )
206
+ return `electronic`
205
207
 
206
208
  return `phonon`
207
209
  })
@@ -212,16 +214,15 @@
212
214
  if (detected_band_type !== `electronic`) return undefined
213
215
 
214
216
  // Check raw input for efermi field
215
- const source = `efermi` in (band_structs as object)
216
- ? band_structs
217
- : Object.values(band_structs)[0]
217
+ const source =
218
+ `efermi` in (band_structs as object) ? band_structs : Object.values(band_structs)[0]
218
219
  const efermi = (source as Record<string, unknown>)?.efermi
219
220
  return typeof efermi === `number` ? efermi : undefined
220
221
  })
221
222
 
222
223
  let effective_spin_mode = $derived.by((): BandsSpinMode => {
223
224
  if (detected_band_type !== `electronic`) return null
224
- return (band_spin_mode === `up_only` || band_spin_mode === `down_only`)
225
+ return band_spin_mode === `up_only` || band_spin_mode === `down_only`
225
226
  ? band_spin_mode
226
227
  : `overlay`
227
228
  })
@@ -249,16 +250,18 @@
249
250
 
250
251
  let num_structures = $derived(Object.keys(band_structs_dict).length)
251
252
  let all_segment_keys = $derived(Object.keys(all_segments))
252
- let common_segment_keys = $derived.by(() =>
253
+ let common_segment_keys = $derived(
253
254
  all_segment_keys.filter(
254
255
  (segment_key) => all_segments[segment_key].length === num_structures,
255
- )
256
+ ),
256
257
  )
257
258
  let empty_state_attrs = $derived.by(() => {
258
259
  const attrs: Record<string, Dom_attr_value> = {}
259
260
  for (const [attr_name, attr_value] of Object.entries(rest)) {
260
261
  if (
261
- (attr_name === `class` || attr_name === `style` || attr_name === `role` ||
262
+ (attr_name === `class` ||
263
+ attr_name === `style` ||
264
+ attr_name === `role` ||
262
265
  attr_name.startsWith(`aria-`)) &&
263
266
  is_dom_attr_value(attr_value)
264
267
  ) {
@@ -299,8 +302,7 @@
299
302
  }
300
303
  const ordered_segments = helpers.get_ordered_segments(canonical, segments_to_plot)
301
304
 
302
- for (let seg_idx = 0; seg_idx < ordered_segments.length; seg_idx++) {
303
- const segment_key = ordered_segments[seg_idx]
305
+ for (const segment_key of ordered_segments) {
304
306
  if (positions[segment_key]) continue
305
307
 
306
308
  const [start_label, end_label] = segment_key.split(`_`)
@@ -322,8 +324,8 @@
322
324
  // Place at same x position as current, no advancement
323
325
  positions[segment_key] = [current_x, current_x]
324
326
  } else {
325
- const segment_len = bs.distance[matching_branch.end_index] -
326
- bs.distance[matching_branch.start_index]
327
+ const segment_len =
328
+ bs.distance[matching_branch.end_index] - bs.distance[matching_branch.start_index]
327
329
  positions[segment_key] = [current_x, current_x + segment_len]
328
330
  current_x += segment_len
329
331
  }
@@ -335,53 +337,75 @@
335
337
  x_positions = positions
336
338
  })
337
339
 
338
- // Convert band structures to scatter plot series + track max slope in one pass
339
- let { series_data, max_abs_slope } = $derived.by((): {
340
- series_data: DataSeries[]
341
- max_abs_slope: number
342
- } => {
343
- if (Object.keys(band_structs_dict).length === 0 || segments_to_plot.size === 0) {
344
- return { series_data: [], max_abs_slope: 1 }
345
- }
346
-
347
- const all_series: DataSeries[] = []
348
- let max_slope = 0
349
-
340
+ // Plottable branch segments with rescaled x coordinates, shared by the band-line
341
+ // series and fat-band ribbon computations below
342
+ interface PlotSegment {
343
+ bs_idx: number
344
+ label: string
345
+ bs: BaseBandStructure
346
+ start_idx: number
347
+ end_idx: number // exclusive
348
+ segment_key: string
349
+ scaled_distances: number[]
350
+ }
351
+ let plot_segments = $derived.by((): PlotSegment[] => {
352
+ const segments: PlotSegment[] = []
350
353
  for (const [bs_idx, [label, bs]] of Object.entries(band_structs_dict).entries()) {
351
- const color = PLOT_COLORS[bs_idx % PLOT_COLORS.length]
352
- const structure_label = label || `Structure ${bs_idx + 1}`
353
- const gamma_indices = detected_band_type === `phonon`
354
- ? helpers.find_gamma_indices(bs)
355
- : []
356
-
357
354
  for (const branch of bs.branches) {
355
+ // Skip discontinuous segments (consecutive labeled points)
356
+ if (branch.end_index - branch.start_index === 1) continue
357
+
358
358
  const start_idx = branch.start_index
359
359
  const end_idx = branch.end_index + 1
360
- const start_label = bs.qpoints[start_idx]?.label ?? undefined
361
- const end_label = bs.qpoints[end_idx - 1]?.label ?? undefined
362
- const segment_key = helpers.get_segment_key(start_label, end_label)
363
-
360
+ const segment_key = helpers.get_segment_key(
361
+ bs.qpoints[start_idx]?.label ?? undefined,
362
+ bs.qpoints[end_idx - 1]?.label ?? undefined,
363
+ )
364
364
  if (!segments_to_plot.has(segment_key)) continue
365
365
 
366
- // Skip discontinuous segments (consecutive labeled points)
367
- const is_discontinuity = branch.end_index - branch.start_index === 1
368
- if (is_discontinuity) continue
369
-
370
366
  const [x_start, x_end] = x_positions?.[segment_key] || [0, 1]
371
-
372
- // Scale distances for this segment
373
- const segment_distances = bs.distance.slice(start_idx, end_idx)
374
367
  const scaled_distances = helpers.scale_segment_distances(
375
- segment_distances,
368
+ bs.distance.slice(start_idx, end_idx),
376
369
  x_start,
377
370
  x_end,
378
371
  )
372
+ segments.push({ bs_idx, label, bs, start_idx, end_idx, segment_key, scaled_distances })
373
+ }
374
+ }
375
+ return segments
376
+ })
377
+
378
+ // Convert band structures to scatter plot series + track max slope in one pass
379
+ let { series_data, max_abs_slope } = $derived.by(
380
+ (): {
381
+ series_data: DataSeries[]
382
+ max_abs_slope: number
383
+ } => {
384
+ const all_series: DataSeries[] = []
385
+ let max_slope = 0
386
+ // Cache per band structure: segments share their bs, so avoid re-scanning
387
+ // all q-points once per plotted segment
388
+ const gamma_cache = new Map<BaseBandStructure, number[]>()
389
+
390
+ for (const {
391
+ bs_idx,
392
+ label,
393
+ bs,
394
+ start_idx,
395
+ end_idx,
396
+ scaled_distances,
397
+ } of plot_segments) {
398
+ const color = PLOT_COLORS[bs_idx % PLOT_COLORS.length]
399
+ const structure_label = label || `Structure ${bs_idx + 1}`
400
+ let gamma_indices = gamma_cache.get(bs)
401
+ if (!gamma_indices) {
402
+ gamma_indices = detected_band_type === `phonon` ? helpers.find_gamma_indices(bs) : []
403
+ gamma_cache.set(bs, gamma_indices)
404
+ }
379
405
 
380
406
  // Create series for each band (and spin channel for electronic structures)
381
407
  for (let band_idx = 0; band_idx < bs.nb_bands; band_idx++) {
382
- const frequencies = convert_band_values(
383
- bs.bands[band_idx].slice(start_idx, end_idx),
384
- )
408
+ const frequencies = convert_band_values(bs.bands[band_idx].slice(start_idx, end_idx))
385
409
  const is_acoustic = helpers.classify_acoustic(bs, band_idx, gamma_indices)
386
410
 
387
411
  const line_style_up = get_line_style(
@@ -392,7 +416,8 @@
392
416
  )
393
417
 
394
418
  const spin_down_band = bs.spin_down_bands?.[band_idx]
395
- const has_spin_down_channel = detected_band_type === `electronic` &&
419
+ const has_spin_down_channel =
420
+ detected_band_type === `electronic` &&
396
421
  Array.isArray(spin_down_band) &&
397
422
  spin_down_band.length >= end_idx
398
423
 
@@ -419,9 +444,7 @@
419
444
  x: scaled_distances,
420
445
  y: frequencies,
421
446
  markers: `line`,
422
- label: has_spin_down_channel
423
- ? `${structure_label} (↑)`
424
- : structure_label,
447
+ label: has_spin_down_channel ? `${structure_label} (↑)` : structure_label,
425
448
  line_style: line_style_up,
426
449
  metadata: meta,
427
450
  })
@@ -456,76 +479,46 @@
456
479
  }
457
480
  }
458
481
  }
459
- }
460
482
 
461
- return { series_data: all_series, max_abs_slope: max_slope || 1 }
462
- })
483
+ return { series_data: all_series, max_abs_slope: max_slope || 1 }
484
+ },
485
+ )
463
486
 
464
487
  // Compute ribbon data for bands with width information
465
488
  let ribbon_data = $derived.by((): RibbonData[] => {
466
- if (Object.keys(band_structs_dict).length === 0 || segments_to_plot.size === 0) {
467
- return []
468
- }
469
-
470
489
  const all_ribbons: RibbonData[] = []
471
490
 
472
- for (const [bs_idx, [label, bs]] of Object.entries(band_structs_dict).entries()) {
491
+ for (const segment of plot_segments) {
492
+ const { bs_idx, label, bs, start_idx, end_idx, segment_key, scaled_distances } = segment
473
493
  // Skip if this band structure has no width data
474
- if (!bs.band_widths || bs.band_widths.length === 0) continue
494
+ if (!bs.band_widths?.length) continue
475
495
 
476
- const color = PLOT_COLORS[bs_idx % PLOT_COLORS.length]
477
- const structure_label = label || `Structure ${bs_idx + 1}`
478
496
  const config = helpers.get_ribbon_config(ribbon_config, label)
497
+ const structure_label = label || `Structure ${bs_idx + 1}`
479
498
 
480
- for (const branch of bs.branches) {
481
- const start_idx = branch.start_index
482
- const end_idx = branch.end_index + 1
483
- const start_label = bs.qpoints[start_idx]?.label ?? undefined
484
- const end_label = bs.qpoints[end_idx - 1]?.label ?? undefined
485
- const segment_key = helpers.get_segment_key(start_label, end_label)
486
-
487
- if (!segments_to_plot.has(segment_key)) continue
488
-
489
- // Skip discontinuous segments
490
- const is_discontinuity = branch.end_index - branch.start_index === 1
491
- if (is_discontinuity) continue
492
-
493
- const [x_start, x_end] = x_positions?.[segment_key] || [0, 1]
494
-
495
- // Scale distances for this segment
496
- const segment_distances = bs.distance.slice(start_idx, end_idx)
497
- const scaled_distances = helpers.scale_segment_distances(
498
- segment_distances,
499
- x_start,
500
- x_end,
501
- )
502
-
503
- // Create ribbon data for each band that has width data
504
- for (let band_idx = 0; band_idx < bs.nb_bands; band_idx++) {
505
- const band_widths = bs.band_widths[band_idx]
506
- if (!band_widths) continue
507
-
508
- const width_values = band_widths.slice(start_idx, end_idx)
509
- // Skip if all widths are zero or missing
510
- if (width_values.every((wv) => !wv || wv <= 0)) continue
511
-
512
- const y_values = convert_band_values(
513
- bs.bands[band_idx].slice(start_idx, end_idx),
514
- )
515
-
516
- all_ribbons.push({
517
- x_values: scaled_distances,
518
- y_values,
519
- width_values,
520
- color: config.color ?? color,
521
- opacity: config.opacity ?? 0.3,
522
- max_width: config.max_width ?? 6,
523
- scale: config.scale ?? 1,
524
- band_idx,
525
- structure_label,
526
- segment_key,
527
- })
528
- }
499
+ // Create ribbon data for each band that has width data
500
+ for (let band_idx = 0; band_idx < bs.nb_bands; band_idx++) {
501
+ const band_widths = bs.band_widths[band_idx]
502
+ if (!band_widths) continue
503
+
504
+ const width_values = band_widths.slice(start_idx, end_idx)
505
+ // Skip if all widths are zero or missing
506
+ if (width_values.every((wv) => !wv || wv <= 0)) continue
507
+
508
+ const y_values = convert_band_values(bs.bands[band_idx].slice(start_idx, end_idx))
509
+
510
+ all_ribbons.push({
511
+ x_values: scaled_distances,
512
+ y_values,
513
+ width_values,
514
+ color: config.color ?? PLOT_COLORS[bs_idx % PLOT_COLORS.length],
515
+ opacity: config.opacity ?? 0.3,
516
+ max_width: config.max_width ?? 6,
517
+ scale: config.scale ?? 1,
518
+ band_idx,
519
+ structure_label,
520
+ segment_key,
521
+ })
529
522
  }
530
523
  }
531
524
 
@@ -548,9 +541,7 @@
548
541
  .sort(([, [a]], [, [b]]) => a - b)
549
542
  .forEach(([segment_key, [x_start, x_end]]) => {
550
543
  const [start_lbl, end_lbl] = segment_key.split(`_`)
551
- const pretty_start = start_lbl !== `null`
552
- ? helpers.pretty_sym_point(start_lbl)
553
- : ``
544
+ const pretty_start = start_lbl !== `null` ? helpers.pretty_sym_point(start_lbl) : ``
554
545
  const pretty_end = end_lbl !== `null` ? helpers.pretty_sym_point(end_lbl) : ``
555
546
 
556
547
  // Check if this is a discontinuity (zero-length segment)
@@ -569,10 +560,7 @@
569
560
 
570
561
  // Merge labels at same position with pipe separator
571
562
  return Object.fromEntries(
572
- Array.from(tick_map.entries()).map(([pos, labels]) => [
573
- pos,
574
- labels.join(` | `),
575
- ]),
563
+ Array.from(tick_map.entries()).map(([pos, labels]) => [pos, labels.join(` | `)]),
576
564
  )
577
565
  })
578
566
 
@@ -588,16 +576,17 @@
588
576
  ...(bs.spin_down_bands?.flat() ?? []),
589
577
  ])
590
578
  // Keep electronic y-range independent of phonon unit conversion options.
591
- const display_values = detected_band_type === `phonon`
592
- ? convert_band_values(all_freqs)
593
- : all_freqs
579
+ const display_values =
580
+ detected_band_type === `phonon` ? convert_band_values(all_freqs) : all_freqs
594
581
  if (display_values.length === 0) return undefined
595
582
  const finite = display_values.filter(Number.isFinite)
596
583
  if (finite.length === 0) return undefined
597
- let min_val = Math.min(...finite), max_val = Math.max(...finite)
584
+ let min_val = Math.min(...finite),
585
+ max_val = Math.max(...finite)
598
586
  if (
599
587
  // clamp phonon min to 0 if negatives are noise
600
- detected_band_type === `phonon` && min_val < 0 &&
588
+ detected_band_type === `phonon` &&
589
+ min_val < 0 &&
601
590
  helpers.negative_fraction(finite) < helpers.IMAGINARY_MODE_NOISE_THRESHOLD
602
591
  ) {
603
592
  min_val = 0
@@ -631,48 +620,47 @@
631
620
  !shade_imaginary_modes ||
632
621
  !y_range ||
633
622
  y_range[0] >= 0
634
- ) return []
635
- return [{
636
- lower: y_range[0],
637
- upper: 0,
638
- fill: `var(--bands-imaginary-region-color, light-dark(#f8d7da, #5a1a1f))`,
639
- fill_opacity: 0.2,
640
- label: `Imaginary modes`,
641
- show_in_legend: false,
642
- z_index: `below-lines`,
643
- }]
623
+ )
624
+ return []
625
+ return [
626
+ {
627
+ lower: y_range[0],
628
+ upper: 0,
629
+ fill: `var(--bands-imaginary-region-color, light-dark(#f8d7da, #5a1a1f))`,
630
+ fill_opacity: 0.2,
631
+ label: `Imaginary modes`,
632
+ show_in_legend: false,
633
+ z_index: `below-lines`,
634
+ },
635
+ ]
644
636
  })
645
637
 
646
- let custom_highlight_regions = $derived.by((): FillRegion[] =>
638
+ let custom_highlight_regions = $derived(
647
639
  (highlight_regions ?? [])
648
- .filter((region) =>
649
- Number.isFinite(region.y_min) && Number.isFinite(region.y_max)
650
- )
640
+ .filter((region) => Number.isFinite(region.y_min) && Number.isFinite(region.y_max))
651
641
  .map((region) => ({
652
642
  lower: Math.min(region.y_min, region.y_max),
653
643
  upper: Math.max(region.y_min, region.y_max),
654
- fill: region.color ??
655
- `var(--bands-highlight-region-color, light-dark(#f6e8c3, #4d3f20))`,
644
+ fill:
645
+ region.color ?? `var(--bands-highlight-region-color, light-dark(#f6e8c3, #4d3f20))`,
656
646
  fill_opacity: region.opacity ?? 0.2,
657
647
  label: region.label,
658
648
  show_in_legend: Boolean(region.label),
659
649
  z_index: `below-lines` as const,
660
- }))
650
+ })),
661
651
  )
662
652
 
663
- let fill_regions = $derived([
664
- ...imaginary_mode_region,
665
- ...custom_highlight_regions,
666
- ])
653
+ let fill_regions = $derived([...imaginary_mode_region, ...custom_highlight_regions])
667
654
 
668
655
  let electronic_gap_annotation = $derived.by(() => {
669
656
  if (
670
657
  !show_gap_annotation ||
671
658
  detected_band_type !== `electronic` ||
672
659
  effective_fermi_level === undefined
673
- ) return null
660
+ )
661
+ return null
674
662
  const all_energies = series_data.flatMap((series_item) =>
675
- series_item.y.filter(Number.isFinite)
663
+ series_item.y.filter(Number.isFinite),
676
664
  )
677
665
  const occupied = all_energies.filter((energy) => energy <= effective_fermi_level)
678
666
  const unoccupied = all_energies.filter((energy) => energy > effective_fermi_level)
@@ -701,11 +689,14 @@
701
689
  let highlight_x = $derived.by(() => {
702
690
  if (highlighted_qpoint_index == null) return null
703
691
  const bs = Object.values(band_structs_dict)[0]
704
- return bs ? helpers.qpoint_x_position(bs, highlighted_qpoint_index, x_positions ?? {}) : null
692
+ return bs
693
+ ? helpers.qpoint_x_position(bs, highlighted_qpoint_index, x_positions ?? {})
694
+ : null
705
695
  })
706
696
 
707
697
  let display = $state({ x_grid: false, y_grid: true, y_zero_line: true })
708
698
  </script>
699
+
709
700
  {#if has_series && !is_strict_path_error}
710
701
  <ScatterPlot
711
702
  {id}
@@ -728,32 +719,37 @@
728
719
  >
729
720
  {#snippet tooltip({ x, y, y_formatted, label, metadata })}
730
721
  {@const y_label_full = internal_y_axis.label ?? ``}
731
- {@const [, y_label, y_unit] = y_label_full.match(/^(.+?)\s*\(([^)]+)\)$/) ??
732
- [, y_label_full, ``]}
733
- {@const segment = Object.entries(x_positions ?? {}).find(([, [start, end]]) =>
734
- x >= start && x <= end
735
- )}
736
- {@const path = segment?.[0].split(`_`).map((lbl) =>
737
- lbl !== `null` ? helpers.pretty_sym_point(lbl) : ``
738
- ).filter(Boolean).join(` → `) || null}
722
+ {@const [, y_label, y_unit] = y_label_full.match(/^(.+?)\s*\(([^)]+)\)$/) ?? [
723
+ ,
724
+ y_label_full,
725
+ ``,
726
+ ]}
727
+ {@const segment = Object.entries(x_positions ?? {}).find(
728
+ ([, [start, end]]) => x >= start && x <= end,
729
+ )}
730
+ {@const path =
731
+ segment?.[0]
732
+ .split(`_`)
733
+ .map((lbl) => (lbl !== `null` ? helpers.pretty_sym_point(lbl) : ``))
734
+ .filter(Boolean)
735
+ .join(` → `) || null}
739
736
  {@const {
740
- band_idx,
741
- spin,
742
- is_acoustic,
743
- nb_bands,
744
- frac_coords,
745
- qpoint_label,
746
- band_width,
747
- slope,
748
- } = (metadata ?? {}) as Partial<helpers.BandPointMeta>}
737
+ band_idx,
738
+ spin,
739
+ is_acoustic,
740
+ nb_bands,
741
+ frac_coords,
742
+ qpoint_label,
743
+ band_width,
744
+ slope,
745
+ } = (metadata ?? {}) as Partial<helpers.BandPointMeta>}
749
746
  {@const num_structs = Object.keys(band_structs_dict).length}
750
747
  {#if num_structs > 1 && label}<strong>{label}</strong><br />{/if}
751
- {@html sanitize_html(y_label || `Value`)}: {y_formatted}{y_unit ? ` ${y_unit}` : ``}<br />
748
+ {@html sanitize_html(y_label || `Value`)}: {y_formatted}{y_unit ? ` ${y_unit}` : ``}<br
749
+ />
752
750
  {#if path}Path: {path}<br />{/if}
753
751
  {#if typeof band_idx === `number`}
754
- Band: {band_idx + 1}{#if typeof nb_bands === `number`}&thinsp;/&thinsp;{
755
- nb_bands
756
- }{/if}
752
+ Band: {band_idx + 1}{#if typeof nb_bands === `number`}&thinsp;/&thinsp;{nb_bands}{/if}
757
753
  {#if typeof is_acoustic === `boolean`}
758
754
  ({is_acoustic ? `acoustic` : `optical`})
759
755
  {:else if detected_band_type === `electronic` && effective_fermi_level !== undefined}
@@ -767,9 +763,9 @@
767
763
  <br />At: {helpers.pretty_sym_point(qpoint_label)}
768
764
  {/if}
769
765
  {#if Array.isArray(frac_coords)}
770
- <br />{detected_band_type === `electronic` ? `k` : `q`}: [{
771
- frac_coords.map((coord: number) => format_num(coord, `.3f`)).join(`, `)
772
- }]
766
+ <br />{detected_band_type === `electronic` ? `k` : `q`}: [{frac_coords
767
+ .map((coord: number) => format_num(coord, `.3f`))
768
+ .join(`, `)}]
773
769
  {/if}
774
770
  {#if typeof band_width === `number` && band_width > 0}
775
771
  <br />Projection: {format_num(band_width, `.3~g`)}
@@ -854,19 +850,16 @@
854
850
 
855
851
  {#snippet user_content({ height, x_scale_fn, y_scale_fn, pad })}
856
852
  <!-- Fat band ribbons (rendered behind band lines) -->
857
- {#each ribbon_data as
858
- ribbon
859
- (`${ribbon.structure_label}-${ribbon.segment_key}-${ribbon.band_idx}`)
860
- }
853
+ {#each ribbon_data as ribbon (`${ribbon.structure_label}-${ribbon.segment_key}-${ribbon.band_idx}`)}
861
854
  {@const path_d = helpers.generate_ribbon_path(
862
- ribbon.x_values,
863
- ribbon.y_values,
864
- ribbon.width_values,
865
- x_scale_fn,
866
- y_scale_fn,
867
- ribbon.max_width,
868
- ribbon.scale,
869
- )}
855
+ ribbon.x_values,
856
+ ribbon.y_values,
857
+ ribbon.width_values,
858
+ x_scale_fn,
859
+ y_scale_fn,
860
+ ribbon.max_width,
861
+ ribbon.scale,
862
+ )}
870
863
  {#if path_d}
871
864
  <path
872
865
  d={path_d}
@@ -879,12 +872,10 @@
879
872
  {/each}
880
873
 
881
874
  <!-- Symmetry point vertical lines (filter NaN from scale) -->
882
- {#each Object.keys(x_axis_ticks).map(Number).map((tick) => x_scale_fn(tick)).filter(
883
- Number.isFinite,
884
- ) as
885
- scaled_x
886
- (scaled_x)
887
- }
875
+ {#each Object.keys(x_axis_ticks)
876
+ .map(Number)
877
+ .map((tick) => x_scale_fn(tick))
878
+ .filter(Number.isFinite) as scaled_x (scaled_x)}
888
879
  <line
889
880
  x1={scaled_x}
890
881
  x2={scaled_x}
@@ -914,19 +905,22 @@
914
905
  {/if}
915
906
 
916
907
  <!-- Shared geometry for Fermi level and gap annotations -->
917
- {@const fermi_y = effective_fermi_level !== undefined
918
- ? y_scale_fn(effective_fermi_level)
919
- : NaN}
920
- {@const bands_x_end = x_scale_fn(Object.values(x_positions ?? {}).flat().at(-1) ?? 1)}
908
+ {@const fermi_y =
909
+ effective_fermi_level !== undefined ? y_scale_fn(effective_fermi_level) : NaN}
910
+ {@const bands_x_end = x_scale_fn(
911
+ Object.values(x_positions ?? {})
912
+ .flat()
913
+ .at(-1) ?? 1,
914
+ )}
921
915
  {@const gap_data = electronic_gap_annotation}
922
916
  {@const vbm_y = gap_data ? y_scale_fn(gap_data.vbm) : NaN}
923
917
  {@const cbm_y = gap_data ? y_scale_fn(gap_data.cbm) : NaN}
924
918
  {@const gap_mid_y = (vbm_y + cbm_y) / 2}
925
- {@const ef_needs_offset = Number.isFinite(gap_mid_y) &&
926
- Math.abs(fermi_y - gap_mid_y) < 16}
919
+ {@const ef_needs_offset =
920
+ Number.isFinite(gap_mid_y) && Math.abs(fermi_y - gap_mid_y) < 16}
927
921
  {@const ef_label_y = ef_needs_offset
928
- ? gap_mid_y + (fermi_y >= gap_mid_y ? 16 : -16)
929
- : fermi_y}
922
+ ? gap_mid_y + (fermi_y >= gap_mid_y ? 16 : -16)
923
+ : fermi_y}
930
924
 
931
925
  <!-- Fermi level line for electronic bands -->
932
926
  {#if Number.isFinite(fermi_y) && Number.isFinite(bands_x_end)}
@@ -966,9 +960,8 @@
966
960
  {/if}
967
961
 
968
962
  <!-- Reference frequency horizontal line -->
969
- {@const ref_freq = reference_frequency != null
970
- ? convert_band_values([reference_frequency])[0]
971
- : NaN}
963
+ {@const ref_freq =
964
+ reference_frequency != null ? convert_band_values([reference_frequency])[0] : NaN}
972
965
  {@const ref_y = Number.isFinite(ref_freq) ? y_scale_fn(ref_freq) : NaN}
973
966
  {#if Number.isFinite(ref_y) && Number.isFinite(bands_x_end)}
974
967
  <line
@@ -984,15 +977,8 @@
984
977
  {/if}
985
978
 
986
979
  <!-- Electronic band edge and gap annotation -->
987
- {#if gap_data && Number.isFinite(vbm_y) && Number.isFinite(cbm_y) &&
988
- Number.isFinite(bands_x_end)}
989
- {#each [
990
- [vbm_y, `var(--bands-gap-vbm-color, light-dark(#1f77b4, #7db7ff))`],
991
- [cbm_y, `var(--bands-gap-cbm-color, light-dark(#2ca02c, #7ddc7d))`],
992
- ] as [number, string][] as
993
- [edge_y, color]
994
- (edge_y)
995
- }
980
+ {#if gap_data && Number.isFinite(vbm_y) && Number.isFinite(cbm_y) && Number.isFinite(bands_x_end)}
981
+ {#each [[vbm_y, `var(--bands-gap-vbm-color, light-dark(#1f77b4, #7db7ff))`], [cbm_y, `var(--bands-gap-cbm-color, light-dark(#2ca02c, #7ddc7d))`]] as [number, string][] as [edge_y, color] (edge_y)}
996
982
  <line
997
983
  x1={pad.l}
998
984
  x2={bands_x_end + 3}