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
@@ -0,0 +1,138 @@
1
+ // Parser for VASP vaspwave.h5 charge density: charge/charge on charge/grid
2
+ // plus the embedded structure under structure/positions (dataset paths follow
3
+ // ferrox's VASPWAVE_* constants / py4vasp's VASP 6.x schema). Full files are
4
+ // hundreds of MB, so embedding hosts are expected to prune them server-side
5
+ // first; this parser sees only charge/{charge,grid} + structure/positions.
6
+ //
7
+ // Prototype scope: charge (+ magnetization) isosurfaces only — wavefunctions
8
+ // are out of scope. The "charge density RMS per SCF step" convergence signal
9
+ // is already covered by OSZICAR's rms(c) column in the vaspout.h5 parser
10
+ // (scf_charge_rms frame metadata); diffing charge grids between live reloads
11
+ // is explicitly out of scope here.
12
+ import { calc_lattice_params, create_frac_to_cart } from '../math';
13
+ import { wrap_to_unit_cell } from '../structure/pbc';
14
+ import { make_site } from '../structure/site';
15
+ import { validate_3x3_matrix } from '../trajectory/helpers';
16
+ import { expand_ion_types, is_hdf5_dataset, read_dataset, scale_matrix, to_number_array, to_scalar_number, to_string_array, with_h5_file, } from '../trajectory/parse/h5-utils';
17
+ import { grid_data_range } from './types';
18
+ const CHARGE_PATH = `charge/charge`;
19
+ const CHARGE_GRID_PATH = `charge/grid`;
20
+ const STRUCTURE_PREFIX = `structure/positions`;
21
+ // vaspwave carries charge density/wavefunctions, never a trajectory — used by
22
+ // file-open routing to divert from the HDF5 trajectory dispatcher.
23
+ export const is_vaspwave_filename = (filename) => {
24
+ const basename = filename.split(`/`).pop() ?? filename;
25
+ return /vaspwave.*\.(?:h5|hdf5)$/i.test(basename);
26
+ };
27
+ const dataset_shape = (h5_file, path) => {
28
+ const entity = h5_file.get(path);
29
+ return is_hdf5_dataset(entity) ? (entity.shape ?? null) : null;
30
+ };
31
+ const read_embedded_structure = (h5_file) => {
32
+ const lattice_data = read_dataset(h5_file, `${STRUCTURE_PREFIX}/lattice_vectors`);
33
+ if (!lattice_data) {
34
+ throw new Error(`vaspwave.h5 has no embedded structure (${STRUCTURE_PREFIX}/lattice_vectors) — ` +
35
+ `cannot place the charge grid in a lattice`);
36
+ }
37
+ const scale = to_scalar_number(read_dataset(h5_file, `${STRUCTURE_PREFIX}/scale`)) ?? 1;
38
+ const lattice = scale_matrix(validate_3x3_matrix(lattice_data), scale);
39
+ // Sites are optional for rendering (the isosurface needs only the lattice),
40
+ // so a pruned/torn file missing ion data still opens with an empty cell.
41
+ const sites = [];
42
+ const ion_types = to_string_array(read_dataset(h5_file, `${STRUCTURE_PREFIX}/ion_types`));
43
+ const ion_counts = to_number_array(read_dataset(h5_file, `${STRUCTURE_PREFIX}/number_ion_types`));
44
+ const frac_positions = read_dataset(h5_file, `${STRUCTURE_PREFIX}/position_ions`);
45
+ if (ion_types && ion_counts && frac_positions && ion_types.length === ion_counts.length) {
46
+ const elements = expand_ion_types(ion_types, ion_counts);
47
+ const frac_to_cart = create_frac_to_cart(lattice);
48
+ for (const [site_idx, element] of elements.entries()) {
49
+ const frac = frac_positions[site_idx];
50
+ if (!Array.isArray(frac) || frac.length < 3)
51
+ break; // torn positions: keep what parsed
52
+ const abc = wrap_to_unit_cell(frac.slice(0, 3));
53
+ sites.push(make_site(element, abc, frac_to_cart(abc), `${element}${site_idx + 1}`));
54
+ }
55
+ }
56
+ return {
57
+ sites,
58
+ lattice: { matrix: lattice, pbc: [true, true, true], ...calc_lattice_params(lattice) },
59
+ };
60
+ };
61
+ // VASP writes volumetric data C-order [components, nz, ny, nx]; the grid
62
+ // dataset [nx, ny, nz] disambiguates (same logic as ferrox's
63
+ // volumetric_grid_shape_and_order — when nx == nz both layouts match, so
64
+ // default to the canonical zyx order).
65
+ const charge_axis_order = (spatial_shape, grid_dims) => {
66
+ const [nx, ny, nz] = grid_dims;
67
+ const matches = (dims) => dims.every((dim, idx) => dim === spatial_shape[idx]);
68
+ if (matches([nz, ny, nx]))
69
+ return `zyx`;
70
+ if (matches([nx, ny, nz]))
71
+ return `xyz`;
72
+ throw new Error(`vaspwave.h5 ${CHARGE_GRID_PATH} [${grid_dims}] is incompatible with ` +
73
+ `${CHARGE_PATH} spatial shape [${spatial_shape}]`);
74
+ };
75
+ function parse_vaspwave_charge_file(h5_file) {
76
+ const shape = dataset_shape(h5_file, CHARGE_PATH);
77
+ if (!shape) {
78
+ throw new Error(`vaspwave.h5 file has no charge density (missing ${CHARGE_PATH})`);
79
+ }
80
+ // Only the dimension count is checked here — the spatial axis order (zyx vs
81
+ // xyz) is disambiguated later by charge_axis_order against CHARGE_GRID_PATH.
82
+ if (shape.length !== 4) {
83
+ throw new Error(`${CHARGE_PATH} must have 4 dimensions, got [${shape}]`);
84
+ }
85
+ const n_components = shape[0];
86
+ if (n_components < 1 || n_components > 2) {
87
+ throw new Error(`${CHARGE_PATH} has unsupported component count ${n_components}; expected 1 ` +
88
+ `(non-spin-polarized) or 2 (total + magnetization)`);
89
+ }
90
+ const grid_dims = to_number_array(read_dataset(h5_file, CHARGE_GRID_PATH));
91
+ if (grid_dims?.length !== 3) {
92
+ throw new Error(`vaspwave.h5 is missing ${CHARGE_GRID_PATH}; cannot determine the axis order of ${CHARGE_PATH}`);
93
+ }
94
+ const axis_order = charge_axis_order(shape.slice(1), grid_dims);
95
+ const [nx, ny, nz] = grid_dims;
96
+ const structure = read_embedded_structure(h5_file);
97
+ const lattice = structure.lattice.matrix;
98
+ const charge_data = read_dataset(h5_file, CHARGE_PATH);
99
+ if (!charge_data)
100
+ throw new Error(`Failed to read ${CHARGE_PATH} data`);
101
+ // Metadata shape and decoded data can disagree in torn/corrupt files — fail
102
+ // loudly instead of silently rendering fewer components than the file claims
103
+ if (charge_data.length !== n_components) {
104
+ throw new Error(`${CHARGE_PATH} decoded ${charge_data.length} components but its shape claims ${n_components}`);
105
+ }
106
+ const component_labels = [`charge density`, `magnetization density`];
107
+ const volumes = charge_data.map((component, component_idx) => {
108
+ const grid = Array(nx);
109
+ for (let x_idx = 0; x_idx < nx; x_idx++) {
110
+ const plane = Array(ny);
111
+ for (let y_idx = 0; y_idx < ny; y_idx++) {
112
+ const row = Array(nz);
113
+ for (let z_idx = 0; z_idx < nz; z_idx++) {
114
+ row[z_idx] =
115
+ axis_order === `zyx`
116
+ ? component[z_idx][y_idx][x_idx]
117
+ : component[x_idx][y_idx][z_idx];
118
+ }
119
+ plane[y_idx] = row;
120
+ }
121
+ grid[x_idx] = plane;
122
+ }
123
+ return {
124
+ grid,
125
+ grid_dims: [nx, ny, nz],
126
+ lattice,
127
+ origin: [0, 0, 0],
128
+ data_range: grid_data_range(grid),
129
+ data_order: `x_fastest`,
130
+ periodic: true,
131
+ label: component_labels[component_idx],
132
+ };
133
+ });
134
+ return { structure, volumes };
135
+ }
136
+ export async function parse_vaspwave_charge(buffer, filename) {
137
+ return with_h5_file(buffer, filename, parse_vaspwave_charge_file);
138
+ }
@@ -1,11 +1,12 @@
1
1
  // Parsers for volumetric data file formats (VASP CHGCAR, Gaussian .cube)
2
2
  import { ATOMIC_NUMBER_TO_SYMBOL } from '../composition/parse';
3
3
  import { VASP_VOLUMETRIC_REGEX } from '../constants';
4
- import { coerce_elem_symbol, FALLBACK_ELEMENTS } from '../element';
5
- import { strip_compression_extensions } from '../io';
4
+ import { coerce_elem_symbol, FALLBACK_ELEMENTS } from '../element/helpers';
5
+ import { strip_compression_extensions } from '../io/decompress';
6
6
  import * as math from '../math';
7
7
  import { wrap_to_unit_cell } from '../structure/pbc';
8
8
  import { make_site } from '../structure/site';
9
+ import { parse_leading_num } from '../utils';
9
10
  // Bohr radius in Angstroms (for Gaussian .cube unit conversion)
10
11
  const BOHR_TO_ANGSTROM = 0.529177249;
11
12
  // === Parse error contract ===
@@ -188,7 +189,7 @@ export function parse_chgcar(content) {
188
189
  pos = cur.next;
189
190
  // Line 1: scale factor
190
191
  cur = read_line(content, pos);
191
- const scale_factor = parseFloat(cur.line);
192
+ const scale_factor = parse_leading_num(cur.line);
192
193
  if (isNaN(scale_factor)) {
193
194
  vol_error(`Invalid scaling factor in CHGCAR`);
194
195
  return null;
@@ -212,8 +213,7 @@ export function parse_chgcar(content) {
212
213
  return null;
213
214
  }
214
215
  // Detect VASP 5+ format (has element symbols before counts)
215
- const first_token = cur.line.trim().split(/\s+/)[0];
216
- const has_element_symbols = isNaN(parseInt(first_token, 10));
216
+ const has_element_symbols = isNaN(parse_leading_num(cur.line));
217
217
  if (has_element_symbols) {
218
218
  element_symbols = cur.line.trim().split(/\s+/);
219
219
  pos = cur.next;
@@ -536,7 +536,7 @@ export function parse_volumetric_file(content, filename) {
536
536
  // CHGCAR detection: requires POSCAR-like header (scale factor on line 2) AND
537
537
  // a grid dimensions line (3 integers) somewhere after the header. This distinguishes
538
538
  // CHGCAR from plain POSCAR/CONTCAR files which share the same header format.
539
- if (lines.length > 2 && !isNaN(parseFloat(lines[1].trim()))) {
539
+ if (lines.length > 2 && !isNaN(parse_leading_num(lines[1]))) {
540
540
  // Scan for grid dimensions line (3 integers) starting from ~line 7
541
541
  let scan_pos = find_line_offset(content, 7);
542
542
  // Only scan a limited window, not the entire file
@@ -0,0 +1,12 @@
1
+ export type IsosurfaceProfileStage = `prepare_geometry` | `marching_cubes` | `build_geometry` | `sample_scalars` | `scalar_range` | `apply_colormap` | `rebuild_total` | `recolor_total`;
2
+ export type IsosurfaceProfileMeta = Record<string, boolean | number | string>;
3
+ export interface IsosurfaceProfileEvent {
4
+ stage: IsosurfaceProfileStage;
5
+ duration_ms: number;
6
+ meta: IsosurfaceProfileMeta;
7
+ }
8
+ export type IsosurfaceProfiler = (event: IsosurfaceProfileEvent) => void;
9
+ /** Record a stage whose duration was measured elsewhere. */
10
+ export declare function record_profile(profiler: IsosurfaceProfiler | undefined, stage: IsosurfaceProfileStage, duration_ms: number, meta?: IsosurfaceProfileMeta): void;
11
+ /** Time a synchronous pipeline stage only when an internal profiler is attached. */
12
+ export declare function profile_stage<Result>(profiler: IsosurfaceProfiler | undefined, stage: IsosurfaceProfileStage, operation: () => Result, meta?: IsosurfaceProfileMeta | ((result: Result) => IsosurfaceProfileMeta)): Result;
@@ -0,0 +1,19 @@
1
+ // Internal, opt-in profiling primitives for the isosurface benchmark route.
2
+ // This module is intentionally not re-exported from the public package barrels.
3
+ /** Record a stage whose duration was measured elsewhere. */
4
+ export function record_profile(profiler, stage, duration_ms, meta = {}) {
5
+ profiler?.({ stage, duration_ms, meta });
6
+ }
7
+ /** Time a synchronous pipeline stage only when an internal profiler is attached. */
8
+ export function profile_stage(profiler, stage, operation, meta = {}) {
9
+ if (!profiler)
10
+ return operation();
11
+ const start_time = performance.now();
12
+ const result = operation();
13
+ profiler({
14
+ stage,
15
+ duration_ms: performance.now() - start_time,
16
+ meta: typeof meta === `function` ? meta(result) : meta,
17
+ });
18
+ return result;
19
+ }
@@ -0,0 +1,34 @@
1
+ import type { Matrix3x3, Vec2, Vec3 } from '../math';
2
+ import { type VolumetricData } from './types';
3
+ export declare function trilinear_interpolate(grid: number[][][], fx: number, fy: number, fz: number, periodic: boolean): number;
4
+ export type OutOfBoundsPolicy = `clamp` | `fallback`;
5
+ export interface VolumeSamplerOptions {
6
+ out_of_bounds?: OutOfBoundsPolicy;
7
+ }
8
+ export interface BulkVolumeSamplerOptions extends VolumeSamplerOptions {
9
+ position_offset?: Vec3;
10
+ out?: Float32Array;
11
+ }
12
+ export declare function create_volume_sampler(volume: VolumetricData, options?: VolumeSamplerOptions): (position: Vec3) => number;
13
+ export declare function sample_volume_at_positions(volume: VolumetricData, positions: Float32Array | Float64Array, options?: BulkVolumeSamplerOptions): Float32Array;
14
+ export interface GridCompatibility {
15
+ ok: boolean;
16
+ reason?: string;
17
+ }
18
+ export declare function compare_volume_grids(vol_a: VolumetricData, vol_b: VolumetricData, { tolerance }?: {
19
+ tolerance?: number;
20
+ }): GridCompatibility;
21
+ export type DisplayRange = [Vec2, Vec2, Vec2];
22
+ export declare function sanitize_display_range(range: DisplayRange, periodic: boolean): DisplayRange;
23
+ export interface VolumeDisplayRangeOptions {
24
+ display_range?: DisplayRange;
25
+ tiling?: Vec3;
26
+ halo?: number;
27
+ }
28
+ export declare function resolve_volume_display_range(volume: VolumetricData, { display_range, tiling, halo }?: VolumeDisplayRangeOptions): DisplayRange | null;
29
+ export declare function extract_volume_range(volume: VolumetricData, range: DisplayRange, max_points?: number): VolumetricData;
30
+ export declare function prepare_geometry_grid(volume: VolumetricData, range: DisplayRange | null): {
31
+ grid: number[][][];
32
+ lattice: Matrix3x3;
33
+ origin: Vec3;
34
+ };
@@ -0,0 +1,408 @@
1
+ import { create_cart_to_frac_matrix, scale_lattice_matrix } from '../math';
2
+ import { grid_dimensions } from './grid';
3
+ import { downsample_grid, MAX_GRID_POINTS } from './types';
4
+ const safe_mod = (val, dim) => ((val % dim) + dim) % dim;
5
+ // Lower/upper voxel indices for one axis of a trilinear sample. Singleton axes
6
+ // (n===1) pin both corners to 0 so nx-2 clamping never goes negative.
7
+ const voxel_corners = (n, floor_g, periodic) => {
8
+ if (n === 1)
9
+ return [0, 0];
10
+ const lower = periodic ? safe_mod(floor_g, n) : Math.max(0, Math.min(floor_g, n - 2));
11
+ return [lower, periodic ? (lower + 1) % n : Math.min(lower + 1, n - 1)];
12
+ };
13
+ // Trilinear interpolation of a scalar 3D grid at fractional coordinates.
14
+ // Periodic grids wrap with modulo; non-periodic return 0 for out-of-bounds.
15
+ export function trilinear_interpolate(grid, fx, fy, fz, periodic) {
16
+ const nx = grid.length;
17
+ const ny = grid[0]?.length ?? 0;
18
+ const nz = grid[0]?.[0]?.length ?? 0;
19
+ if (nx === 0 || ny === 0 || nz === 0)
20
+ return 0;
21
+ // Convert fractional to grid coordinates
22
+ const gx = periodic ? fx * nx : fx * (nx - 1);
23
+ const gy = periodic ? fy * ny : fy * (ny - 1);
24
+ const gz = periodic ? fz * nz : fz * (nz - 1);
25
+ if (!periodic) {
26
+ // Out-of-bounds check for non-periodic grids
27
+ if (fx < 0 || fx > 1 || fy < 0 || fy > 1 || fz < 0 || fz > 1)
28
+ return 0;
29
+ }
30
+ const [x0, x1] = voxel_corners(nx, Math.floor(gx), periodic);
31
+ const [y0, y1] = voxel_corners(ny, Math.floor(gy), periodic);
32
+ const [z0, z1] = voxel_corners(nz, Math.floor(gz), periodic);
33
+ // deltas from clamped lower index (non-periodic x0 clamps to nx-2 so floor(gx) may != x0)
34
+ const xd = periodic ? gx - Math.floor(gx) : gx - x0;
35
+ const yd = periodic ? gy - Math.floor(gy) : gy - y0;
36
+ const zd = periodic ? gz - Math.floor(gz) : gz - z0;
37
+ // 8-point interpolation
38
+ const c000 = grid[x0][y0][z0];
39
+ const c001 = grid[x0][y0][z1];
40
+ const c010 = grid[x0][y1][z0];
41
+ const c011 = grid[x0][y1][z1];
42
+ const c100 = grid[x1][y0][z0];
43
+ const c101 = grid[x1][y0][z1];
44
+ const c110 = grid[x1][y1][z0];
45
+ const c111 = grid[x1][y1][z1];
46
+ const c00 = c000 + (c100 - c000) * xd;
47
+ const c01 = c001 + (c101 - c001) * xd;
48
+ const c10 = c010 + (c110 - c010) * xd;
49
+ const c11 = c011 + (c111 - c011) * xd;
50
+ const c0 = c00 + (c10 - c00) * yd;
51
+ const c1 = c01 + (c11 - c01) * yd;
52
+ return c0 + (c1 - c0) * zd;
53
+ }
54
+ // Small tolerance so vertices numerically on the boundary of a finite grid
55
+ // (e.g. marching-cubes output at fractional coordinate 1.0 + 1e-16) still sample.
56
+ const OOB_TOL = 1e-6;
57
+ const prepared_sampler_cache = new WeakMap();
58
+ const prepare_volume_sampler = (volume) => {
59
+ const grid_dims = grid_dimensions(volume.grid);
60
+ const signature = [
61
+ ...volume.lattice.flat(),
62
+ ...volume.origin,
63
+ ...grid_dims,
64
+ Number(volume.periodic),
65
+ ].join(`,`);
66
+ const cached = prepared_sampler_cache.get(volume);
67
+ if (cached?.grid === volume.grid && cached.signature === signature)
68
+ return cached;
69
+ const prepared = {
70
+ grid: volume.grid,
71
+ inv: create_cart_to_frac_matrix(volume.lattice),
72
+ origin: volume.origin,
73
+ periodic: volume.periodic,
74
+ grid_dims,
75
+ signature,
76
+ };
77
+ prepared_sampler_cache.set(volume, prepared);
78
+ return prepared;
79
+ };
80
+ // Create a sampler that maps absolute Cartesian positions (in the same physical
81
+ // frame as the volume's `origin`) to trilinearly-interpolated scalar values.
82
+ // Handles non-orthogonal lattices, origin offsets, and periodic wrapping, so it
83
+ // works both for strictly matching grids and for general resampling between
84
+ // volumes that share a Cartesian coordinate system.
85
+ // The hot callback uses scalar arithmetic only (no per-call array allocations)
86
+ // since it runs once per isosurface vertex.
87
+ export function create_volume_sampler(volume, options = {}) {
88
+ const { out_of_bounds = `clamp` } = options;
89
+ const { grid, inv, origin, periodic } = prepare_volume_sampler(volume);
90
+ const [ox, oy, oz] = origin;
91
+ return (position) => {
92
+ const cx = position[0] - ox;
93
+ const cy = position[1] - oy;
94
+ const cz = position[2] - oz;
95
+ let fx = inv[0][0] * cx + inv[0][1] * cy + inv[0][2] * cz;
96
+ let fy = inv[1][0] * cx + inv[1][1] * cy + inv[1][2] * cz;
97
+ let fz = inv[2][0] * cx + inv[2][1] * cy + inv[2][2] * cz;
98
+ if (periodic) {
99
+ fx = safe_mod(fx, 1);
100
+ fy = safe_mod(fy, 1);
101
+ fz = safe_mod(fz, 1);
102
+ }
103
+ else {
104
+ if (out_of_bounds === `fallback` &&
105
+ (fx < -OOB_TOL ||
106
+ fx > 1 + OOB_TOL ||
107
+ fy < -OOB_TOL ||
108
+ fy > 1 + OOB_TOL ||
109
+ fz < -OOB_TOL ||
110
+ fz > 1 + OOB_TOL))
111
+ return NaN;
112
+ // Clamp both genuine out-of-bounds ('clamp' policy = nearest edge value)
113
+ // and tiny numerical overshoot at the boundary
114
+ fx = Math.min(1, Math.max(0, fx));
115
+ fy = Math.min(1, Math.max(0, fy));
116
+ fz = Math.min(1, Math.max(0, fz));
117
+ }
118
+ return trilinear_interpolate(grid, fx, fy, fz, periodic);
119
+ };
120
+ }
121
+ // Sample a volume at many Cartesian positions (flat xyz triplets).
122
+ // Returns one scalar per position; NaN marks out-of-bounds under 'fallback' policy.
123
+ export function sample_volume_at_positions(volume, positions, options = {}) {
124
+ const { out_of_bounds = `clamp`, position_offset = [0, 0, 0] } = options;
125
+ const { grid, inv, origin, periodic, grid_dims } = prepare_volume_sampler(volume);
126
+ const [nx, ny, nz] = grid_dims;
127
+ const [offset_x, offset_y, offset_z] = position_offset;
128
+ const [origin_x, origin_y, origin_z] = origin;
129
+ const n_points = Math.floor(positions.length / 3);
130
+ const out = options.out?.length === n_points ? options.out : new Float32Array(n_points);
131
+ if (nx === 0 || ny === 0 || nz === 0) {
132
+ out.fill(0);
133
+ return out;
134
+ }
135
+ for (let idx = 0; idx < n_points; idx++) {
136
+ const position_idx = idx * 3;
137
+ const cart_x = positions[position_idx] + offset_x - origin_x;
138
+ const cart_y = positions[position_idx + 1] + offset_y - origin_y;
139
+ const cart_z = positions[position_idx + 2] + offset_z - origin_z;
140
+ let frac_x = inv[0][0] * cart_x + inv[0][1] * cart_y + inv[0][2] * cart_z;
141
+ let frac_y = inv[1][0] * cart_x + inv[1][1] * cart_y + inv[1][2] * cart_z;
142
+ let frac_z = inv[2][0] * cart_x + inv[2][1] * cart_y + inv[2][2] * cart_z;
143
+ if (periodic) {
144
+ frac_x = safe_mod(frac_x, 1);
145
+ frac_y = safe_mod(frac_y, 1);
146
+ frac_z = safe_mod(frac_z, 1);
147
+ }
148
+ else {
149
+ if (out_of_bounds === `fallback` &&
150
+ (frac_x < -OOB_TOL ||
151
+ frac_x > 1 + OOB_TOL ||
152
+ frac_y < -OOB_TOL ||
153
+ frac_y > 1 + OOB_TOL ||
154
+ frac_z < -OOB_TOL ||
155
+ frac_z > 1 + OOB_TOL)) {
156
+ out[idx] = Number.NaN;
157
+ continue;
158
+ }
159
+ frac_x = Math.min(1, Math.max(0, frac_x));
160
+ frac_y = Math.min(1, Math.max(0, frac_y));
161
+ frac_z = Math.min(1, Math.max(0, frac_z));
162
+ }
163
+ const grid_x = frac_x * (periodic ? nx : nx - 1);
164
+ const grid_y = frac_y * (periodic ? ny : ny - 1);
165
+ const grid_z = frac_z * (periodic ? nz : nz - 1);
166
+ const floor_x = Math.floor(grid_x);
167
+ const floor_y = Math.floor(grid_y);
168
+ const floor_z = Math.floor(grid_z);
169
+ const [x_lower, x_upper] = voxel_corners(nx, floor_x, periodic);
170
+ const [y_lower, y_upper] = voxel_corners(ny, floor_y, periodic);
171
+ const [z_lower, z_upper] = voxel_corners(nz, floor_z, periodic);
172
+ const x_weight = grid_x - x_lower;
173
+ const y_weight = grid_y - y_lower;
174
+ const z_weight = grid_z - z_lower;
175
+ const row_00 = grid[x_lower][y_lower];
176
+ const row_01 = grid[x_lower][y_upper];
177
+ const row_10 = grid[x_upper][y_lower];
178
+ const row_11 = grid[x_upper][y_upper];
179
+ const value_00 = row_00[z_lower] + (row_10[z_lower] - row_00[z_lower]) * x_weight;
180
+ const value_01 = row_00[z_upper] + (row_10[z_upper] - row_00[z_upper]) * x_weight;
181
+ const value_10 = row_01[z_lower] + (row_11[z_lower] - row_01[z_lower]) * x_weight;
182
+ const value_11 = row_01[z_upper] + (row_11[z_upper] - row_01[z_upper]) * x_weight;
183
+ const value_0 = value_00 + (value_10 - value_00) * y_weight;
184
+ const value_1 = value_01 + (value_11 - value_01) * y_weight;
185
+ out[idx] = value_0 + (value_1 - value_0) * z_weight;
186
+ }
187
+ return out;
188
+ }
189
+ const incompatible_grids = (reason) => ({ ok: false, reason });
190
+ const fmt_vec = (vec) => `[${vec.map((val) => Number(val.toPrecision(6))).join(`, `)}]`;
191
+ // Strictly compare two volumetric grids: identical dimensions, origins equal
192
+ // within tolerance, all voxel vectors equal within tolerance, and matching
193
+ // periodic/finite boundary modes. Cross-volume coloring via create_volume_sampler
194
+ // works for any two volumes sharing a Cartesian frame, but strictly matching
195
+ // grids guarantee the sampled field is exact (no cross-grid resampling).
196
+ export function compare_volume_grids(vol_a, vol_b, { tolerance = 1e-4 } = {}) {
197
+ const [nx_a, ny_a, nz_a] = vol_a.grid_dims;
198
+ const [nx_b, ny_b, nz_b] = vol_b.grid_dims;
199
+ if (nx_a !== nx_b || ny_a !== ny_b || nz_a !== nz_b) {
200
+ return incompatible_grids(`grid dimensions differ: ${nx_a}×${ny_a}×${nz_a} vs ${nx_b}×${ny_b}×${nz_b}`);
201
+ }
202
+ if (vol_a.periodic !== vol_b.periodic) {
203
+ return incompatible_grids(`boundary modes differ: ${vol_a.periodic ? `periodic` : `finite`} vs ${vol_b.periodic ? `periodic` : `finite`}`);
204
+ }
205
+ for (let axis = 0; axis < 3; axis++) {
206
+ const delta = Math.abs(vol_a.origin[axis] - vol_b.origin[axis]);
207
+ if (delta > tolerance) {
208
+ return incompatible_grids(`origins differ by ${delta.toPrecision(3)} Å along axis ${axis}: ${fmt_vec(vol_a.origin)} vs ${fmt_vec(vol_b.origin)}`);
209
+ }
210
+ }
211
+ // Compare voxel vectors: lattice_row / n for periodic grids (spacing 1/n),
212
+ // lattice_row / (n-1) for finite grids (spacing 1/(n-1), endpoints included).
213
+ // Dims and boundary modes already match at this point, so one divisor per
214
+ // axis suffices for both volumes.
215
+ for (let axis = 0; axis < 3; axis++) {
216
+ const divisor = Math.max(vol_a.periodic ? vol_a.grid_dims[axis] : vol_a.grid_dims[axis] - 1, 1);
217
+ for (let comp = 0; comp < 3; comp++) {
218
+ const voxel_delta = Math.abs(vol_a.lattice[axis][comp] - vol_b.lattice[axis][comp]) / divisor;
219
+ if (voxel_delta > tolerance) {
220
+ return incompatible_grids(`voxel vectors differ along axis ${axis}: ${fmt_vec(vol_a.lattice[axis])} vs ${fmt_vec(vol_b.lattice[axis])} (lattice rows)`);
221
+ }
222
+ }
223
+ }
224
+ return { ok: true };
225
+ }
226
+ // Replace invalid axes (non-finite bounds or non-positive width) with [0, 1].
227
+ // Non-periodic volumes additionally clamp to [0, 1] — a finite volume must not
228
+ // be repeated implicitly.
229
+ export function sanitize_display_range(range, periodic) {
230
+ return range.map(([lo, hi]) => {
231
+ if (!Number.isFinite(lo) || !Number.isFinite(hi) || hi - lo <= 1e-6)
232
+ return [0, 1];
233
+ if (periodic)
234
+ return [lo, hi];
235
+ const clamped = [Math.max(lo, 0), Math.min(hi, 1)];
236
+ return clamped[1] - clamped[0] > 1e-6 ? clamped : [0, 1];
237
+ });
238
+ }
239
+ // Resolve the finite window used for marching cubes. Periodic volumes always
240
+ // need an endpoint-inclusive window, including for an integer structure
241
+ // supercell: a periodic N-point grid spans [0, 1), while finite marching cubes
242
+ // interprets N points as spanning [0, 1]. Resampling [0, S] to N*S + 1 points
243
+ // preserves the original voxel spacing and closes the final periodic interval.
244
+ // Finite volumes only get a window when one is explicitly requested and are
245
+ // never repeated to follow the structure supercell.
246
+ export function resolve_volume_display_range(volume, { display_range, tiling = [1, 1, 1], halo = 0 } = {}) {
247
+ if (!display_range && !volume.periodic)
248
+ return null;
249
+ const range = display_range
250
+ ? sanitize_display_range(display_range, volume.periodic)
251
+ : tiling.map((factor) => [0, factor]);
252
+ if (!volume.periodic)
253
+ return range;
254
+ const padding = Math.max(0, halo);
255
+ return range.map(([lo, hi]) => [lo - padding, hi + padding]);
256
+ }
257
+ const precompute_axis_interpolation = (range, count, source_dim, periodic) => {
258
+ const intervals = periodic ? source_dim : Math.max(source_dim - 1, 1);
259
+ const fractional_step = (range[1] - range[0]) / (count - 1);
260
+ const grid_step = fractional_step * intervals;
261
+ const grid_start = range[0] * intervals;
262
+ const direct = Math.abs(grid_step - 1) < 1e-10 && Math.abs(grid_start - Math.round(grid_start)) < 1e-10;
263
+ const lower = new Int32Array(count);
264
+ const upper = new Int32Array(count);
265
+ const weight = new Float64Array(count);
266
+ for (let sample_idx = 0; sample_idx < count; sample_idx++) {
267
+ const grid_coord = grid_start + sample_idx * grid_step;
268
+ const grid_floor = Math.floor(grid_coord);
269
+ if (periodic) {
270
+ lower[sample_idx] = safe_mod(grid_floor, source_dim);
271
+ upper[sample_idx] = (lower[sample_idx] + 1) % source_dim;
272
+ weight[sample_idx] = grid_coord - grid_floor;
273
+ }
274
+ else {
275
+ lower[sample_idx] = Math.max(0, Math.min(grid_floor, source_dim - 2));
276
+ upper[sample_idx] = Math.min(lower[sample_idx] + 1, source_dim - 1);
277
+ weight[sample_idx] = grid_coord - lower[sample_idx];
278
+ }
279
+ }
280
+ return { lower, upper, weight, direct };
281
+ };
282
+ // Resample a volume over a fractional display range (VESTA-style non-integer
283
+ // supercell) into a finite grid whose bounds land exactly on the requested
284
+ // fractional coordinates, so marching cubes clips repeated surfaces precisely
285
+ // at the range instead of at integer cell boundaries. Periodic volumes wrap;
286
+ // the sample resolution follows the source voxel density, capped at max_points
287
+ // (matching the downsampling budget applied to integer-tiled grids).
288
+ // The returned volume's lattice spans the range and its origin shifts by
289
+ // range_min·lattice, keeping vertices in the same Cartesian frame as the source.
290
+ export function extract_volume_range(volume, range, max_points = MAX_GRID_POINTS) {
291
+ const [rx, ry, rz] = sanitize_display_range(range, volume.periodic);
292
+ const widths = [rx[1] - rx[0], ry[1] - ry[0], rz[1] - rz[0]];
293
+ // Sample counts follow the source voxel density (inclusive endpoints), capped
294
+ // to the point budget. The reduction loop guards against cbrt undershoot when
295
+ // the min-2 floor prevents an axis from shrinking.
296
+ let counts = widths.map((width, axis) => {
297
+ const source_intervals = volume.periodic
298
+ ? volume.grid_dims[axis]
299
+ : Math.max(volume.grid_dims[axis] - 1, 1);
300
+ return Math.max(2, Math.round(width * source_intervals) + 1);
301
+ });
302
+ const total = counts[0] * counts[1] * counts[2];
303
+ if (total > max_points) {
304
+ const shrink = Math.cbrt(max_points / total);
305
+ counts = counts.map((count) => Math.max(2, Math.floor(count * shrink)));
306
+ while (counts[0] * counts[1] * counts[2] > Math.max(max_points, 8)) {
307
+ const largest = counts.indexOf(Math.max(...counts));
308
+ counts[largest] = Math.max(2, Math.floor(counts[largest] * 0.9));
309
+ }
310
+ }
311
+ const [nx, ny, nz] = counts;
312
+ const grid = Array(nx);
313
+ const x_samples = precompute_axis_interpolation(rx, nx, volume.grid_dims[0], volume.periodic);
314
+ const y_samples = precompute_axis_interpolation(ry, ny, volume.grid_dims[1], volume.periodic);
315
+ const z_samples = precompute_axis_interpolation(rz, nz, volume.grid_dims[2], volume.periodic);
316
+ let [min_val, max_val, sum] = [Infinity, -Infinity, 0];
317
+ const direct_copy = x_samples.direct && y_samples.direct && z_samples.direct;
318
+ if (direct_copy) {
319
+ for (let x_idx = 0; x_idx < nx; x_idx++) {
320
+ const source_x = x_samples.weight[x_idx] > 0.5 ? x_samples.upper[x_idx] : x_samples.lower[x_idx];
321
+ const source_plane = volume.grid[source_x];
322
+ const plane = Array(ny);
323
+ for (let y_idx = 0; y_idx < ny; y_idx++) {
324
+ const source_y = y_samples.weight[y_idx] > 0.5 ? y_samples.upper[y_idx] : y_samples.lower[y_idx];
325
+ const source_row = source_plane[source_y];
326
+ const row = Array(nz);
327
+ for (let z_idx = 0; z_idx < nz; z_idx++) {
328
+ const source_z = z_samples.weight[z_idx] > 0.5 ? z_samples.upper[z_idx] : z_samples.lower[z_idx];
329
+ const value = source_row[source_z];
330
+ row[z_idx] = value;
331
+ if (value < min_val)
332
+ min_val = value;
333
+ if (value > max_val)
334
+ max_val = value;
335
+ sum += value;
336
+ }
337
+ plane[y_idx] = row;
338
+ }
339
+ grid[x_idx] = plane;
340
+ }
341
+ }
342
+ else {
343
+ for (let x_idx = 0; x_idx < nx; x_idx++) {
344
+ const x_lower_plane = volume.grid[x_samples.lower[x_idx]];
345
+ const x_upper_plane = volume.grid[x_samples.upper[x_idx]];
346
+ const x_weight = x_samples.weight[x_idx];
347
+ const plane = Array(ny);
348
+ for (let y_idx = 0; y_idx < ny; y_idx++) {
349
+ const y_lower = y_samples.lower[y_idx];
350
+ const y_upper = y_samples.upper[y_idx];
351
+ const y_weight = y_samples.weight[y_idx];
352
+ const row_00 = x_lower_plane[y_lower];
353
+ const row_01 = x_lower_plane[y_upper];
354
+ const row_10 = x_upper_plane[y_lower];
355
+ const row_11 = x_upper_plane[y_upper];
356
+ const row = Array(nz);
357
+ for (let z_idx = 0; z_idx < nz; z_idx++) {
358
+ const z_lower = z_samples.lower[z_idx];
359
+ const z_upper = z_samples.upper[z_idx];
360
+ const z_weight = z_samples.weight[z_idx];
361
+ const value_00 = row_00[z_lower] + (row_10[z_lower] - row_00[z_lower]) * x_weight;
362
+ const value_01 = row_00[z_upper] + (row_10[z_upper] - row_00[z_upper]) * x_weight;
363
+ const value_10 = row_01[z_lower] + (row_11[z_lower] - row_01[z_lower]) * x_weight;
364
+ const value_11 = row_01[z_upper] + (row_11[z_upper] - row_01[z_upper]) * x_weight;
365
+ const value_0 = value_00 + (value_10 - value_00) * y_weight;
366
+ const value_1 = value_01 + (value_11 - value_01) * y_weight;
367
+ const value = value_0 + (value_1 - value_0) * z_weight;
368
+ row[z_idx] = value;
369
+ if (value < min_val)
370
+ min_val = value;
371
+ if (value > max_val)
372
+ max_val = value;
373
+ sum += value;
374
+ }
375
+ plane[y_idx] = row;
376
+ }
377
+ grid[x_idx] = plane;
378
+ }
379
+ }
380
+ const [row_a, row_b, row_c] = volume.lattice;
381
+ return {
382
+ ...volume,
383
+ grid,
384
+ grid_dims: counts,
385
+ lattice: scale_lattice_matrix(volume.lattice, widths),
386
+ origin: [
387
+ volume.origin[0] + rx[0] * row_a[0] + ry[0] * row_b[0] + rz[0] * row_c[0],
388
+ volume.origin[1] + rx[0] * row_a[1] + ry[0] * row_b[1] + rz[0] * row_c[1],
389
+ volume.origin[2] + rx[0] * row_a[2] + ry[0] * row_b[2] + rz[0] * row_c[2],
390
+ ],
391
+ data_range: {
392
+ min: min_val,
393
+ max: max_val,
394
+ abs_max: Math.max(Math.abs(min_val), Math.abs(max_val)),
395
+ mean: sum / (nx * ny * nz),
396
+ },
397
+ periodic: false, // the extracted block is a finite window; endpoints included
398
+ };
399
+ }
400
+ export function prepare_geometry_grid(volume, range) {
401
+ if (range)
402
+ return extract_volume_range(volume, range);
403
+ return {
404
+ grid: downsample_grid(volume.grid, volume.grid_dims).grid,
405
+ lattice: volume.lattice,
406
+ origin: volume.origin,
407
+ };
408
+ }
@@ -0,0 +1,13 @@
1
+ import { type D3InterpolateName } from '../colors';
2
+ import type { Vec2 } from '../math';
3
+ import type { SliceResult } from './slice';
4
+ export type VolumeSliceMode = `both` | `contours` | `filled`;
5
+ /** Resolve an explicit or automatic slice color range. */
6
+ export declare function resolve_slice_color_range(slice: Pick<SliceResult, `min` | `max`>, color_range?: Vec2, symmetric?: boolean | `auto`): Vec2;
7
+ /** Convert a sampled slice to browser-sRGB RGBA pixels, preserving its exact mask. */
8
+ export declare function slice_to_rgba(slice: Pick<SliceResult, `data` | `mask` | `width` | `height`>, colormap: D3InterpolateName, color_range: Vec2, { flip_y, out }?: {
9
+ flip_y?: boolean;
10
+ out?: Uint8ClampedArray;
11
+ }): Uint8ClampedArray;
12
+ /** Resolve a contour count or explicit threshold list against a color range. */
13
+ export declare function resolve_contour_thresholds(color_range: Vec2, contour_levels: number | number[]): number[];