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
@@ -1,62 +1,77 @@
1
1
  import { calc_lattice_params, create_lattice_converters, euclidean_dist, pbc_dist, } from '../math';
2
- import { make_supercell } from '../structure/supercell';
3
2
  const get_occu = (site, elem) => elem ? (site.species.find((spec) => spec.element === elem)?.occu ?? 0) : 1;
4
3
  const has_species = (site, elem) => !elem || site.species.some((spec) => spec.element === elem);
5
4
  const sum_occu = (sites, elem) => sites.reduce((sum, site) => sum + get_occu(site, elem), 0);
5
+ // Symmetric ± lattice images on expanded PBC axes. Extents use reciprocal-axis norms
6
+ // with search radius cutoff + cell diagonal (length-based ceil undercounts skewed cells).
7
+ function build_rdf_neighbor_sites(structure, pbc, cutoff, auto_expand) {
8
+ const dist_lattice = structure.lattice.matrix;
9
+ if (!auto_expand)
10
+ return { sites: structure.sites, dist_pbc: pbc, dist_lattice };
11
+ const [[ax, ay, az], [bx, by, bz], [cx, cy, cz]] = dist_lattice;
12
+ let cell_diag = 0;
13
+ for (let bits = 0; bits < 8; bits++) {
14
+ const [ua, ub, uc] = [bits & 1, (bits >> 1) & 1, (bits >> 2) & 1];
15
+ cell_diag = Math.max(cell_diag, Math.hypot(ua * ax + ub * bx + uc * cx, ua * ay + ub * by + uc * cy, ua * az + ub * bz + uc * cz));
16
+ }
17
+ const { reciprocal_axis_norms } = create_lattice_converters(dist_lattice);
18
+ const search_radius = cutoff + cell_diag;
19
+ const extents = [0, 1, 2].map((axis) => pbc[axis]
20
+ ? Math.max(0, Math.ceil(search_radius * reciprocal_axis_norms[axis] - 1e-12))
21
+ : 0);
22
+ if (extents.every((extent) => extent === 0)) {
23
+ return { sites: structure.sites, dist_pbc: pbc, dist_lattice };
24
+ }
25
+ const sites = [];
26
+ for (let ia = -extents[0]; ia <= extents[0]; ia++) {
27
+ for (let ib = -extents[1]; ib <= extents[1]; ib++) {
28
+ for (let ic = -extents[2]; ic <= extents[2]; ic++) {
29
+ const tx = ia * ax + ib * bx + ic * cx;
30
+ const ty = ia * ay + ib * by + ic * cy;
31
+ const tz = ia * az + ib * bz + ic * cz;
32
+ for (const site of structure.sites) {
33
+ sites.push({ ...site, xyz: [site.xyz[0] + tx, site.xyz[1] + ty, site.xyz[2] + tz] });
34
+ }
35
+ }
36
+ }
37
+ }
38
+ const dist_pbc = [
39
+ pbc[0] && extents[0] === 0,
40
+ pbc[1] && extents[1] === 0,
41
+ pbc[2] && extents[2] === 0,
42
+ ];
43
+ return { sites, dist_pbc, dist_lattice };
44
+ }
6
45
  // Calculate radial distribution function
7
46
  export function calculate_rdf(structure, options = {}) {
8
- const { center_species, neighbor_species, cutoff = 15, n_bins = 75, auto_expand = true, expansion_factor = 2.0, } = options;
9
- const { pbc = [true, true, true] } = options;
47
+ const { center_species, neighbor_species, cutoff = 15, n_bins = 75, auto_expand = true, } = options;
48
+ const pbc = options.pbc ?? structure.lattice?.pbc ?? [true, true, true];
10
49
  if (cutoff <= 0 || n_bins <= 0) {
11
50
  throw new Error(`cutoff and n_bins must be positive`);
12
51
  }
13
- // Validate structure has lattice
14
52
  if (!structure.lattice?.matrix) {
15
53
  throw new Error(`Crystal must have a lattice for RDF calculation`);
16
54
  }
17
- let lattice = structure.lattice.matrix;
18
- let { sites } = structure;
19
- let center_sites = sites;
20
- // Expand structure if needed to ensure shortest lattice vector is expansion_factor× the cutoff
21
- // This prevents artificial close contacts at cell boundaries when using PBC
22
- // Standard practice uses 2.0-2.5× to eliminate finite-size effects
23
- if (auto_expand) {
24
- const { a, b, c } = calc_lattice_params(lattice);
25
- const min_size = cutoff * expansion_factor;
26
- const [n_a, n_b, n_c] = [a, b, c].map((len) => Math.ceil(min_size / len));
27
- if (n_a > 1 || n_b > 1 || n_c > 1) {
28
- const expanded_structure = make_supercell(structure, [n_a, n_b, n_c], false);
29
- sites = expanded_structure.sites;
30
- lattice = expanded_structure.lattice.matrix;
31
- // Keep PBC: min-image is exact once every lattice vector ≥ 2× cutoff (disabling PBC
32
- // starves boundary atoms and biases g(r) low). Under full PBC all periodic copies are
33
- // equivalent, so restrict centers to the first copy (make_supercell emits (0,0,0) first)
34
- center_sites = pbc.every(Boolean) ? sites.slice(0, structure.sites.length) : sites;
35
- }
36
- }
55
+ const { sites: neighbor_sites, dist_pbc, dist_lattice, } = build_rdf_neighbor_sites(structure, pbc, cutoff, auto_expand);
37
56
  const bin_size = cutoff / n_bins;
38
57
  const r = Array.from({ length: n_bins }, (_, idx) => (idx + 0.5) * bin_size);
39
58
  const g_r = Array(n_bins).fill(0);
40
- if (sites.length === 0)
41
- return { r, g_r };
42
- // Get occupancy weight for a site-species pair (supports mixed occupancy)
43
- const centers = center_sites.filter((site) => has_species(site, center_species));
44
- const neighbors = sites.filter((site) => has_species(site, neighbor_species));
45
- if (centers.length === 0 || neighbors.length === 0) {
46
- const element_pair = center_species && neighbor_species
47
- ? [center_species, neighbor_species]
48
- : undefined;
59
+ // Centers stay in the original cell; neighbor_sites may include periodic images
60
+ const centers = structure.sites.filter((site) => has_species(site, center_species));
61
+ const neighbors = neighbor_sites.filter((site) => has_species(site, neighbor_species));
62
+ // Normalization density uses the original cell (not the image cloud)
63
+ const norm_neighbors = structure.sites.filter((site) => has_species(site, neighbor_species));
64
+ const element_pair = center_species && neighbor_species
65
+ ? [center_species, neighbor_species]
66
+ : undefined;
67
+ if (centers.length === 0 || neighbors.length === 0)
49
68
  return { r, g_r, element_pair };
50
- }
51
- // Calculate distances and bin them with occupancy weighting
52
- const use_pbc = pbc.some(Boolean);
53
- const converters = use_pbc ? create_lattice_converters(lattice) : undefined;
69
+ const use_pbc = dist_pbc.some(Boolean);
70
+ const converters = use_pbc ? create_lattice_converters(dist_lattice) : undefined;
54
71
  for (const center of centers) {
55
72
  for (const neighbor of neighbors) {
56
- if (center === neighbor)
57
- continue;
58
73
  const dist = use_pbc
59
- ? pbc_dist(center.xyz, neighbor.xyz, lattice, converters, pbc)
74
+ ? pbc_dist(center.xyz, neighbor.xyz, dist_lattice, converters, dist_pbc)
60
75
  : euclidean_dist(center.xyz, neighbor.xyz);
61
76
  if (dist > 0 && dist < cutoff) {
62
77
  // Weight by product of occupancies for the species pair
@@ -65,22 +80,18 @@ export function calculate_rdf(structure, options = {}) {
65
80
  }
66
81
  }
67
82
  }
68
- // Normalize using occupancy-weighted pair count (excludes self-interactions for same species)
83
+ // Ideal-gas normalization with original-cell density. Do not subtract self-pairs:
84
+ // dist > 0 already drops the true self term, while periodic images of the same atom
85
+ // are valid neighbors (critical for 1-atom cells).
69
86
  const center_weight = sum_occu(centers, center_species);
70
- const neighbor_weight = sum_occu(neighbors, neighbor_species);
71
- const self_weight = center_species === neighbor_species
72
- ? centers.reduce((sum, site) => sum + get_occu(site, center_species) ** 2, 0)
73
- : 0;
74
- const n_pairs = center_weight * neighbor_weight - self_weight;
75
- if (n_pairs > 0) {
76
- const volume = calc_lattice_params(lattice).volume;
87
+ const neighbor_weight = sum_occu(norm_neighbors, neighbor_species);
88
+ const volume = calc_lattice_params(structure.lattice.matrix).volume;
89
+ if (center_weight > 0 && neighbor_weight > 0 && volume > 0) {
77
90
  for (let idx = 0; idx < n_bins; idx++) {
78
- g_r[idx] /= n_pairs * ((4 * Math.PI * r[idx] ** 2 * bin_size) / volume);
91
+ g_r[idx] /=
92
+ center_weight * neighbor_weight * ((4 * Math.PI * r[idx] ** 2 * bin_size) / volume);
79
93
  }
80
94
  }
81
- const element_pair = center_species && neighbor_species
82
- ? [center_species, neighbor_species]
83
- : undefined;
84
95
  return { r, g_r, element_pair };
85
96
  }
86
97
  // Calculate RDF for all element pairs
@@ -19,5 +19,4 @@ export interface RdfOptions {
19
19
  n_bins?: number;
20
20
  pbc?: Pbc;
21
21
  auto_expand?: boolean;
22
- expansion_factor?: number;
23
22
  }
package/dist/sanitize.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import DOMPurify from 'dompurify';
2
2
  import { format_formula_html } from './phase-diagram/utils';
3
+ import { escape_html } from './utils';
3
4
  const SAFE_TAGS = [`a`, `b`, `i`, `em`, `strong`, `sub`, `sup`, `br`, `span`, `code`, `small`];
4
5
  const SAFE_ATTRS = [`style`, `class`, `title`, `href`, `target`, `rel`];
6
+ const SAFE_TAG_SET = new Set(SAFE_TAGS);
7
+ const SAFE_ATTR_SET = new Set(SAFE_ATTRS);
5
8
  // only allow safe CSS properties for text formatting
6
- const SAFE_STYLE_RE = /^\s*(color|font-weight|font-style|font-size|text-decoration|vertical-align)\s*:/;
7
- // Add a token to a space-separated string if not already present
9
+ const SAFE_STYLE_RE = /^\s*(?:color|font-weight|font-style|font-size|text-decoration|vertical-align)\s*:/;
8
10
  const ensure_token = (value, token) => {
9
11
  const tokens = new Set(value.split(/\s+/).filter(Boolean));
10
12
  tokens.add(token);
@@ -18,10 +20,8 @@ function get_purify() {
18
20
  if (typeof globalThis.window === `undefined`)
19
21
  return (purify = null);
20
22
  const instance = DOMPurify();
21
- if (typeof instance.sanitize !== `function`) {
22
- purify = null;
23
- return null;
24
- }
23
+ if (typeof instance.sanitize !== `function`)
24
+ return (purify = null);
25
25
  purify = instance;
26
26
  instance.addHook(`uponSanitizeAttribute`, (node, data) => {
27
27
  if (data.attrName === `style`) {
@@ -35,21 +35,83 @@ function get_purify() {
35
35
  if (data.attrName === `href`) {
36
36
  node.setAttribute(`rel`, ensure_token(node.getAttribute(`rel`) ?? ``, `noopener`));
37
37
  }
38
- if (data.attrName === `rel`) {
38
+ if (data.attrName === `rel`)
39
39
  data.attrValue = ensure_token(data.attrValue, `noopener`);
40
- }
41
40
  });
42
41
  return instance;
43
42
  }
43
+ // Strip void / raw-text blocks that must not leak content when tags are removed
44
+ const DANGEROUS_BLOCK_RE = /<(?<block>script|style|iframe|object|embed|textarea|noscript|template)\b[^>]*>[\s\S]*?<\/\k<block>\s*>/gi;
45
+ const ATTR_RE = /(?<name>[^\s=]+)(?:\s*=\s*(?:"(?<dq>[^"]*)"|'(?<sq>[^']*)'|(?<bare>[^\s"'=<>`]+)))?/g;
46
+ const SAFE_HREF_RE = /^(?:\/|#|https?:|mailto:)/i;
47
+ function filter_attrs(attr_str, allowed, tag) {
48
+ let out = ``;
49
+ let rel = ``;
50
+ let has_href = false;
51
+ ATTR_RE.lastIndex = 0;
52
+ for (const match of attr_str.matchAll(ATTR_RE)) {
53
+ const name = (match.groups?.name ?? ``).toLowerCase();
54
+ if (name.startsWith(`on`) || !allowed.has(name))
55
+ continue;
56
+ const raw = match.groups?.dq ?? match.groups?.sq ?? match.groups?.bare ?? ``;
57
+ if (name === `rel`) {
58
+ rel = raw;
59
+ continue;
60
+ }
61
+ if (name === `href`) {
62
+ if (!SAFE_HREF_RE.test(raw.trim()))
63
+ continue;
64
+ has_href = true;
65
+ }
66
+ else if (name === `style`) {
67
+ const rules = raw.split(`;`).filter((rule) => SAFE_STYLE_RE.test(rule));
68
+ if (rules.length === 0)
69
+ continue;
70
+ out += ` style="${escape_html(rules.join(`;`))}"`;
71
+ continue;
72
+ }
73
+ out += ` ${name}="${escape_html(raw)}"`;
74
+ }
75
+ if (tag === `a` && (has_href || rel)) {
76
+ out += ` rel="${escape_html(ensure_token(rel, `noopener`))}"`;
77
+ }
78
+ return out;
79
+ }
80
+ // DOM-free allowlist sanitizer for SSR / no-window contexts. Never returns raw input.
81
+ function sanitize_allowlist_ssr(html, tags, attrs) {
82
+ const without_blocks = html
83
+ .replace(DANGEROUS_BLOCK_RE, ``)
84
+ .replaceAll(/<!--[\s\S]*?-->/g, ``);
85
+ const tag_re = /<\/?(?<tag>[A-Za-z][\w:-]*)\b(?<attrs>[^>]*)\/?>/g;
86
+ let out = ``;
87
+ let last = 0;
88
+ for (const match of without_blocks.matchAll(tag_re)) {
89
+ out += without_blocks.slice(last, match.index);
90
+ last = match.index + match[0].length;
91
+ const name = (match.groups?.tag ?? ``).toLowerCase();
92
+ if (!tags.has(name))
93
+ continue;
94
+ if (match[0].startsWith(`</`)) {
95
+ out += `</${name}>`;
96
+ continue;
97
+ }
98
+ const filtered = filter_attrs(match.groups?.attrs ?? ``, attrs, name);
99
+ out +=
100
+ match[0].endsWith(`/>`) || name === `br`
101
+ ? `<${name}${filtered} />`
102
+ : `<${name}${filtered}>`;
103
+ }
104
+ return out + without_blocks.slice(last);
105
+ }
44
106
  // Wrap in <svg>, sanitize with allowlist, then unwrap. Required because DOMPurify
45
107
  // needs the <svg> parent to parse children in the SVG namespace.
46
- function sanitize_svg_content(html, allowed_tags, allowed_attrs) {
108
+ function sanitize_svg_content(html, tags, attrs) {
47
109
  const dp = get_purify();
48
110
  if (!dp)
49
- return html;
111
+ return sanitize_allowlist_ssr(html, tags, new Set(attrs));
50
112
  const wrapped = dp.sanitize(`<svg>${html}</svg>`, {
51
- ALLOWED_TAGS: [...allowed_tags, `svg`],
52
- ALLOWED_ATTR: allowed_attrs,
113
+ ALLOWED_TAGS: [...tags, `svg`],
114
+ ALLOWED_ATTR: [...attrs],
53
115
  });
54
116
  const open_end = wrapped.indexOf(`>`);
55
117
  const close_start = wrapped.lastIndexOf(`</svg>`);
@@ -75,10 +137,13 @@ const stringify_html_input = (html) => {
75
137
  return ``;
76
138
  }
77
139
  };
78
- // Memoize by input: two DOMPurify passes per call are costly when a component re-sanitizes
79
- // many cells on every render (e.g. HeatmapTable). Sanitization is deterministic for the
80
- // fixed config, so caching is output-identical.
81
140
  const sanitize_cache = new Map();
141
+ const cache_sanitize = (key, result) => {
142
+ if (sanitize_cache.size >= 4096)
143
+ sanitize_cache.clear();
144
+ sanitize_cache.set(key, result);
145
+ return result;
146
+ };
82
147
  // Sanitize HTML string, allowing only safe formatting tags and links.
83
148
  // Two-pass: happy-dom promotes dangerous children when a non-allowed parent is
84
149
  // stripped (e.g. <div><script>…</script></div> → <script>…</script>). The first
@@ -90,32 +155,26 @@ export function sanitize_html(html) {
90
155
  return cached;
91
156
  const dp = get_purify();
92
157
  if (!dp)
93
- return str; // no DOM (SSR): return as-is, don't cache
158
+ return cache_sanitize(str, sanitize_allowlist_ssr(str, SAFE_TAG_SET, SAFE_ATTR_SET));
94
159
  // oxfmt-ignore
95
160
  const safe = dp.sanitize(str, { ADD_ATTR: [`target`], FORBID_TAGS: [
96
161
  `script`, `style`, `iframe`, `object`, `embed`, `form`, `input`, `textarea`,
97
162
  `select`, `button`, `meta`, `link`, `base`, `template`, `noscript`,
98
163
  ] });
99
- const result = dp.sanitize(safe, { ALLOWED_TAGS: SAFE_TAGS, ALLOWED_ATTR: SAFE_ATTRS });
100
- if (sanitize_cache.size >= 4096)
101
- sanitize_cache.clear(); // bound memory (rarely hit)
102
- sanitize_cache.set(str, result);
103
- return result;
164
+ return cache_sanitize(str, dp.sanitize(safe, { ALLOWED_TAGS: SAFE_TAGS, ALLOWED_ATTR: SAFE_ATTRS }));
104
165
  }
105
166
  export const compact_formula = (formula) => formula.replaceAll(/\s+/g, ``);
106
- // Sanitize a chemical formula with optional subscript formatting
107
167
  export const sanitize_formula = (formula, use_subscripts = true) => sanitize_html(format_formula_html(formula, use_subscripts));
108
168
  export const sanitize_compact_formula = (formula, use_subscripts = true) => sanitize_formula(compact_formula(formula), use_subscripts);
109
- const SVG_TEXT_TAGS = [`tspan`, `title`];
169
+ const SVG_TEXT_TAGS = new Set([`tspan`, `title`]);
110
170
  // oxfmt-ignore
111
171
  const SVG_TEXT_ATTRS = [`dx`, `dy`, `x`, `y`, `fill`, `font-size`, `font-weight`, `baseline-shift`];
112
- // Sanitize HTML intended for SVG text contexts (tspan, title)
113
172
  export const sanitize_svg = (html) => sanitize_svg_content(html, SVG_TEXT_TAGS, SVG_TEXT_ATTRS);
114
173
  // oxfmt-ignore
115
- const SVG_ICON_TAGS = [
174
+ const SVG_ICON_TAGS = new Set([
116
175
  `path`, `circle`, `rect`, `line`, `polyline`, `polygon`, `g`, `ellipse`,
117
176
  `clipPath`, `defs`, `mask`, `use`, `title`,
118
- ];
177
+ ]);
119
178
  // oxfmt-ignore
120
179
  const SVG_ICON_ATTRS = [
121
180
  `d`, `fill`, `stroke`, `stroke-width`, `stroke-linecap`, `stroke-linejoin`,
@@ -123,5 +182,4 @@ const SVG_ICON_ATTRS = [
123
182
  `width`, `height`, `viewBox`, `points`, `transform`, `opacity`,
124
183
  `clip-path`, `clip-rule`, `fill-rule`, `id`, `class`,
125
184
  ];
126
- // Sanitize inline SVG markup (path, circle, rect, etc.) for icon rendering
127
185
  export const sanitize_icon_svg = (html) => sanitize_svg_content(html, SVG_ICON_TAGS, SVG_ICON_ATTRS);
@@ -5,7 +5,7 @@
5
5
  import { T } from '@threlte/core'
6
6
  import * as extras from '@threlte/extras'
7
7
  import type { ComponentProps } from 'svelte'
8
- import { build_gizmo_props, build_orbit_props } from './props'
8
+ import { build_gizmo_props, build_orbit_props } from './props.svelte'
9
9
 
10
10
  let {
11
11
  camera_projection = `perspective`,
@@ -2,7 +2,7 @@ import type { Vec3 } from '../math';
2
2
  import { type CameraProjection } from '../settings';
3
3
  import * as extras from '@threlte/extras';
4
4
  import type { ComponentProps } from 'svelte';
5
- import { build_orbit_props } from './props';
5
+ import { build_orbit_props } from './props.svelte';
6
6
  type $$ComponentProps = {
7
7
  camera_projection?: CameraProjection;
8
8
  position: Vec3;
@@ -1,14 +1,22 @@
1
- import { renderer_registry } from '../io/export';
1
+ import { renderer_registry, scene_registry } from '../io/export';
2
2
  import { useThrelte } from '@threlte/core';
3
- // Mirror the Threlte scene + active camera into bindable props (for export panes etc.) and register the canvas->renderer mapping so PNG-export helpers can find it. Creates an $effect (call during component init). Returns the Threlte context for further use (e.g. clipping planes).
3
+ // Mirror the Threlte scene + active camera into bindable props (for export panes etc.) and register the canvas->renderer/scene mappings so PNG-export and element-capture helpers can find them. Creates an $effect (call during component init). Returns the Threlte context for further use (e.g. clipping planes).
4
4
  export function bind_renderer(on_bind, on_renderer) {
5
5
  const threlte = useThrelte();
6
6
  $effect(() => {
7
- on_bind(threlte.scene, threlte.camera.current);
8
- if (threlte.renderer) {
9
- on_renderer?.(threlte.renderer);
10
- renderer_registry.set(threlte.renderer.domElement, threlte.renderer);
7
+ const renderer = threlte.renderer;
8
+ // `camera.current` is not reactive, so subscribe to be notified when the active camera changes
9
+ const unsubscribe = threlte.camera.subscribe((camera) => {
10
+ on_bind(threlte.scene, camera);
11
+ if (renderer) {
12
+ scene_registry.set(renderer.domElement, { scene: threlte.scene, camera });
13
+ }
14
+ });
15
+ if (renderer) {
16
+ on_renderer?.(renderer);
17
+ renderer_registry.set(renderer.domElement, renderer);
11
18
  }
19
+ return unsubscribe;
12
20
  });
13
21
  return threlte;
14
22
  }
@@ -1,4 +1,3 @@
1
1
  export * from './bind-renderer.svelte';
2
- export * from './props';
2
+ export * from './props.svelte';
3
3
  export { default as SceneCamera } from './SceneCamera.svelte';
4
- export type * from './types';
@@ -1,5 +1,5 @@
1
1
  // Shared Three.js/Threlte scene boilerplate (cameras, orbit controls, gizmo,
2
2
  // renderer binding) used by BrillouinZoneScene, FermiSurfaceScene and StructureScene.
3
3
  export * from './bind-renderer.svelte';
4
- export * from './props';
4
+ export * from './props.svelte';
5
5
  export { default as SceneCamera } from './SceneCamera.svelte';
@@ -1,4 +1,15 @@
1
1
  import { AXIS_COLORS, NEG_AXIS_COLORS } from '../colors';
2
+ // Reactive page visibility — pause auto-rotation while the tab/window is
3
+ // hidden. Desktop embedders like Tauri often disable background throttling,
4
+ // which would otherwise leave every auto-rotating WebGL canvas burning GPU.
5
+ export const page_visibility = $state({
6
+ visible: typeof document === `undefined` || document.visibilityState === `visible`,
7
+ });
8
+ if (typeof document !== `undefined`) {
9
+ document.addEventListener(`visibilitychange`, () => {
10
+ page_visibility.visible = document.visibilityState === `visible`;
11
+ });
12
+ }
2
13
  // ScatterPlot3DScene keeps its own gizmo/orbit props on purpose: its gizmo offset is
3
14
  // ColorBar-aware (build_gizmo_props' fixed offset would clobber it) and its orbit controls
4
15
  // differ by design (no zoom-to-cursor / ortho zoom-doubling / camera-moving tracking).
@@ -39,7 +50,10 @@ export function build_orbit_props(opts) {
39
50
  panSpeed: opts.pan_speed,
40
51
  maxZoom: opts.max_zoom,
41
52
  minZoom: opts.min_zoom,
42
- autoRotate: Boolean(opts.auto_rotate),
53
+ // pause auto-rotation while the page is hidden: callers build these props
54
+ // in $derived, so the visibility flip re-runs them and stops the per-frame
55
+ // OrbitControls task (threlte only runs it while autoRotate/damping is on)
56
+ autoRotate: Boolean(opts.auto_rotate) && page_visibility.visible,
43
57
  autoRotateSpeed: opts.auto_rotate,
44
58
  enableDamping: Boolean(opts.rotation_damping),
45
59
  dampingFactor: opts.rotation_damping,
@@ -111,6 +111,15 @@ type ConvexHullWith3DType = ConvexHullCommonType & {
111
111
  hull_face_opacity: SettingType<number>;
112
112
  hull_face_color_mode: SettingType<HullFaceColorMode>;
113
113
  };
114
+ type HierarchyChartSettingsSchema = {
115
+ value_mode: SettingType<SunburstValueMode>;
116
+ max_depth: SettingType<number>;
117
+ min_fraction: SettingType<number>;
118
+ show_labels: SettingType<boolean>;
119
+ label_text: SettingType<SunburstLabelText>;
120
+ zoom_on_click: SettingType<boolean>;
121
+ show_breadcrumbs: SettingType<boolean>;
122
+ };
114
123
  export interface SettingsConfig {
115
124
  color_scheme: SettingType<string>;
116
125
  background_color: SettingType<string>;
@@ -289,18 +298,16 @@ export interface SettingsConfig {
289
298
  show_node_labels: SettingType<boolean>;
290
299
  iterations: SettingType<number>;
291
300
  };
292
- sunburst: {
301
+ sunburst: HierarchyChartSettingsSchema & {
293
302
  shape: SettingType<SunburstShape>;
294
- value_mode: SettingType<SunburstValueMode>;
295
- max_depth: SettingType<number>;
296
303
  inner_radius: SettingType<number>;
297
304
  pad_angle: SettingType<number>;
298
- min_fraction: SettingType<number>;
299
- show_labels: SettingType<boolean>;
300
305
  label_rotation: SettingType<SunburstLabelRotation>;
301
- label_text: SettingType<SunburstLabelText>;
302
- zoom_on_click: SettingType<boolean>;
303
- show_breadcrumbs: SettingType<boolean>;
306
+ };
307
+ treemap: HierarchyChartSettingsSchema & {
308
+ padding_inner: SettingType<number>;
309
+ padding_top: SettingType<number>;
310
+ padding_outer: SettingType<number>;
304
311
  };
305
312
  composition: {
306
313
  display_mode: SettingType<`pie` | `bubble` | `bar`>;
@@ -327,5 +334,8 @@ export type DefaultSettings = {
327
334
  } : never;
328
335
  };
329
336
  export declare const DEFAULTS: DefaultSettings;
330
- export declare const merge: (user?: Partial<DefaultSettings>) => DefaultSettings;
337
+ export type PartialSettings = {
338
+ [Key in keyof DefaultSettings]?: DefaultSettings[Key] extends Record<string, unknown> ? Partial<DefaultSettings[Key]> : DefaultSettings[Key];
339
+ };
340
+ export declare const merge: (user?: PartialSettings) => DefaultSettings;
331
341
  export {};