matterviz 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +75 -85
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  11. package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  13. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
  15. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
  17. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  18. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  19. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  20. package/dist/colors/index.d.ts +0 -4
  21. package/dist/colors/index.js +19 -20
  22. package/dist/composition/BarChart.svelte +37 -31
  23. package/dist/composition/BubbleChart.svelte +17 -17
  24. package/dist/composition/Composition.svelte +7 -11
  25. package/dist/composition/Formula.svelte +18 -25
  26. package/dist/composition/FormulaFilter.svelte +92 -95
  27. package/dist/composition/PieChart.svelte +55 -41
  28. package/dist/composition/format.js +1 -1
  29. package/dist/composition/index.d.ts +2 -0
  30. package/dist/composition/index.js +14 -0
  31. package/dist/composition/parse.d.ts +2 -2
  32. package/dist/composition/parse.js +11 -10
  33. package/dist/constants.js +11 -9
  34. package/dist/convex-hull/ConvexHull.svelte +12 -15
  35. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  36. package/dist/convex-hull/ConvexHull2D.svelte +93 -92
  37. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  38. package/dist/convex-hull/ConvexHull3D.svelte +109 -140
  39. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  40. package/dist/convex-hull/ConvexHull4D.svelte +75 -94
  41. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  42. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  43. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  44. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  45. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  46. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  47. package/dist/convex-hull/StructurePopup.svelte +17 -21
  48. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  49. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  50. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  51. package/dist/convex-hull/helpers.d.ts +8 -10
  52. package/dist/convex-hull/helpers.js +36 -36
  53. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  54. package/dist/convex-hull/thermodynamics.js +18 -17
  55. package/dist/coordination/CoordinationBarPlot.svelte +38 -33
  56. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  57. package/dist/coordination/calc-coordination.d.ts +1 -1
  58. package/dist/coordination/calc-coordination.js +28 -25
  59. package/dist/element/BohrAtom.svelte +5 -8
  60. package/dist/element/ElementHeading.svelte +4 -1
  61. package/dist/element/ElementPhoto.svelte +11 -9
  62. package/dist/element/ElementStats.svelte +12 -10
  63. package/dist/element/ElementTile.svelte +24 -29
  64. package/dist/element/Nucleus.svelte +4 -2
  65. package/dist/element/data.d.ts +1 -2
  66. package/dist/element/helpers.d.ts +4 -0
  67. package/dist/element/helpers.js +18 -0
  68. package/dist/element/index.d.ts +1 -4
  69. package/dist/element/index.js +3 -18
  70. package/dist/feedback/DragOverlay.svelte +5 -5
  71. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  72. package/dist/feedback/StatusMessage.svelte +7 -4
  73. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  74. package/dist/fermi-surface/FermiSurface.svelte +14 -22
  75. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
  76. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  77. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  80. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  81. package/dist/fermi-surface/compute.js +3 -3
  82. package/dist/fermi-surface/parse.js +22 -24
  83. package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
  84. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  85. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  86. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  87. package/dist/heatmap-matrix/index.d.ts +5 -0
  88. package/dist/icons.d.ts +4 -0
  89. package/dist/icons.js +4 -0
  90. package/dist/io/ExportPane.svelte +10 -6
  91. package/dist/io/decompress.d.ts +2 -1
  92. package/dist/io/decompress.js +22 -35
  93. package/dist/io/export.d.ts +4 -0
  94. package/dist/io/export.js +5 -1
  95. package/dist/io/fetch.d.ts +0 -3
  96. package/dist/io/fetch.js +0 -11
  97. package/dist/io/index.d.ts +0 -1
  98. package/dist/io/index.js +2 -9
  99. package/dist/io/is-binary.d.ts +9 -0
  100. package/dist/io/is-binary.js +45 -1
  101. package/dist/io/url-drop.js +13 -25
  102. package/dist/isosurface/Isosurface.svelte +17 -23
  103. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  104. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  105. package/dist/isosurface/parse-vaspwave.js +138 -0
  106. package/dist/isosurface/parse.js +6 -6
  107. package/dist/labels.d.ts +6 -2
  108. package/dist/labels.js +43 -13
  109. package/dist/layout/FullscreenButton.svelte +2 -1
  110. package/dist/layout/FullscreenToggle.svelte +10 -4
  111. package/dist/layout/InfoCard.svelte +7 -18
  112. package/dist/layout/InfoTag.svelte +1 -3
  113. package/dist/layout/NumberRangeInput.svelte +46 -0
  114. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  115. package/dist/layout/PropertyFilter.svelte +2 -6
  116. package/dist/layout/SettingsSection.svelte +21 -17
  117. package/dist/layout/SubpageGrid.svelte +3 -1
  118. package/dist/layout/ViewerChrome.svelte +9 -10
  119. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  120. package/dist/layout/fullscreen.js +3 -5
  121. package/dist/layout/fullscreen.svelte.js +1 -2
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  125. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  126. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  127. package/dist/layout/json-tree/utils.js +14 -23
  128. package/dist/math.d.ts +2 -0
  129. package/dist/math.js +19 -0
  130. package/dist/overlays/ContextMenu.svelte +4 -2
  131. package/dist/overlays/CopyButton.svelte +11 -5
  132. package/dist/overlays/DragControlTab.svelte +6 -1
  133. package/dist/overlays/DraggablePane.svelte +81 -26
  134. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  135. package/dist/overlays/GlassChip.svelte +30 -0
  136. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  137. package/dist/overlays/InfoPaneCards.svelte +11 -23
  138. package/dist/overlays/index.d.ts +7 -0
  139. package/dist/overlays/index.js +26 -0
  140. package/dist/overlays/portal.d.ts +2 -0
  141. package/dist/overlays/portal.js +14 -0
  142. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  143. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  144. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  145. package/dist/periodic-table/TableInset.svelte +9 -4
  146. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  147. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  148. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  149. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  150. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  151. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  152. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  153. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  154. package/dist/phase-diagram/build-diagram.js +3 -3
  155. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  156. package/dist/phase-diagram/parse.js +15 -15
  157. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  158. package/dist/phase-diagram/utils.js +2 -3
  159. package/dist/plot/bar/BarPlot.svelte +430 -391
  160. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  161. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  162. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  163. package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
  164. package/dist/plot/bar/data.d.ts +5 -4
  165. package/dist/plot/bar/data.js +2 -1
  166. package/dist/plot/box/BoxPlot.svelte +301 -209
  167. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  168. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  169. package/dist/plot/box/box-plot.js +1 -1
  170. package/dist/plot/core/auto-place.js +1 -1
  171. package/dist/plot/core/axis-utils.d.ts +12 -7
  172. package/dist/plot/core/axis-utils.js +48 -48
  173. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  174. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  175. package/dist/plot/core/components/ColorBar.svelte +101 -106
  176. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  177. package/dist/plot/core/components/FillArea.svelte +10 -17
  178. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  179. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  180. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  181. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  182. package/dist/plot/core/components/Line.svelte +18 -9
  183. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  184. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  185. package/dist/plot/core/components/PlotControls.svelte +65 -41
  186. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  187. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  188. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  189. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  190. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  191. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  192. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  193. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  194. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  195. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  196. package/dist/plot/core/components/index.d.ts +1 -0
  197. package/dist/plot/core/components/index.js +1 -0
  198. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  199. package/dist/plot/core/data-cleaning-signal.js +467 -0
  200. package/dist/plot/core/data-cleaning.d.ts +2 -42
  201. package/dist/plot/core/data-cleaning.js +27 -474
  202. package/dist/plot/core/data-transform.js +9 -5
  203. package/dist/plot/core/fill-utils.d.ts +3 -1
  204. package/dist/plot/core/fill-utils.js +28 -6
  205. package/dist/plot/core/index.d.ts +1 -0
  206. package/dist/plot/core/index.js +1 -0
  207. package/dist/plot/core/interactions.js +0 -2
  208. package/dist/plot/core/layout.d.ts +3 -1
  209. package/dist/plot/core/layout.js +22 -13
  210. package/dist/plot/core/marginals.d.ts +170 -0
  211. package/dist/plot/core/marginals.js +436 -0
  212. package/dist/plot/core/reference-line.js +1 -1
  213. package/dist/plot/core/scales.d.ts +23 -0
  214. package/dist/plot/core/scales.js +39 -13
  215. package/dist/plot/core/types/fills.d.ts +101 -0
  216. package/dist/plot/core/types/fills.js +15 -0
  217. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  218. package/dist/plot/core/types/plot-3d.js +4 -0
  219. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  220. package/dist/plot/core/types/reference-lines.js +9 -0
  221. package/dist/plot/core/types.d.ts +29 -324
  222. package/dist/plot/core/types.js +23 -20
  223. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  224. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  225. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  226. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  227. package/dist/plot/core/utils/label-placement.js +2 -2
  228. package/dist/plot/histogram/Histogram.svelte +304 -325
  229. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  230. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  231. package/dist/plot/histogram/histogram.d.ts +31 -0
  232. package/dist/plot/histogram/histogram.js +70 -0
  233. package/dist/plot/histogram/index.d.ts +1 -0
  234. package/dist/plot/histogram/index.js +1 -0
  235. package/dist/plot/index.d.ts +1 -0
  236. package/dist/plot/index.js +1 -0
  237. package/dist/plot/sankey/Sankey.svelte +78 -69
  238. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  239. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  240. package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
  241. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  242. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  243. package/dist/plot/scatter/ScatterPlot.svelte +477 -385
  244. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  245. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  246. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  247. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  248. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  249. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  250. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  251. package/dist/plot/scatter/scatter-data.js +8 -7
  252. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  253. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  254. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  255. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  256. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  257. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  258. package/dist/plot/sunburst/Sunburst.svelte +251 -329
  259. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  260. package/dist/plot/sunburst/index.d.ts +1 -1
  261. package/dist/plot/sunburst/index.js +2 -1
  262. package/dist/plot/sunburst/render.d.ts +2 -2
  263. package/dist/plot/sunburst/render.js +47 -22
  264. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  265. package/dist/plot/sunburst/sunburst.js +10 -3
  266. package/dist/plot/treemap/Treemap.svelte +907 -0
  267. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  268. package/dist/plot/treemap/index.d.ts +3 -0
  269. package/dist/plot/treemap/index.js +4 -0
  270. package/dist/plot/treemap/treemap.d.ts +26 -0
  271. package/dist/plot/treemap/treemap.js +99 -0
  272. package/dist/rdf/RdfPlot.svelte +22 -26
  273. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  274. package/dist/rdf/calc-rdf.js +4 -8
  275. package/dist/sanitize.js +1 -1
  276. package/dist/scene/bind-renderer.svelte.js +14 -6
  277. package/dist/settings.d.ts +19 -9
  278. package/dist/settings.js +77 -50
  279. package/dist/spectral/Bands.svelte +223 -230
  280. package/dist/spectral/BandsAndDos.svelte +11 -9
  281. package/dist/spectral/BrillouinBandsDos.svelte +19 -27
  282. package/dist/spectral/Dos.svelte +70 -73
  283. package/dist/spectral/helpers.d.ts +3 -3
  284. package/dist/spectral/helpers.js +25 -35
  285. package/dist/state.svelte.js +5 -18
  286. package/dist/structure/Arrow.svelte +5 -18
  287. package/dist/structure/ArrowInstances.svelte +160 -0
  288. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  289. package/dist/structure/AtomLegend.svelte +115 -75
  290. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  291. package/dist/structure/Bond.svelte +31 -23
  292. package/dist/structure/CanvasTooltip.svelte +15 -3
  293. package/dist/structure/CellSelect.svelte +11 -26
  294. package/dist/structure/Cylinder.svelte +24 -40
  295. package/dist/structure/InstancedAtoms.svelte +114 -0
  296. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  297. package/dist/structure/Lattice.svelte +85 -149
  298. package/dist/structure/SiteLabels.svelte +122 -0
  299. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  300. package/dist/structure/Structure.svelte +473 -419
  301. package/dist/structure/Structure.svelte.d.ts +4 -2
  302. package/dist/structure/StructureCarousel.svelte +630 -0
  303. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  304. package/dist/structure/StructureControls.svelte +157 -399
  305. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  306. package/dist/structure/StructureExportPane.svelte +17 -21
  307. package/dist/structure/StructureInfoPane.svelte +72 -66
  308. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  309. package/dist/structure/StructureScene.svelte +467 -476
  310. package/dist/structure/StructureScene.svelte.d.ts +3 -1
  311. package/dist/structure/StructureViewport.svelte +386 -0
  312. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  313. package/dist/structure/atom-label-placement.d.ts +16 -12
  314. package/dist/structure/atom-label-placement.js +70 -37
  315. package/dist/structure/atom-properties.d.ts +2 -0
  316. package/dist/structure/atom-properties.js +104 -38
  317. package/dist/structure/bonding.d.ts +10 -3
  318. package/dist/structure/bonding.js +84 -28
  319. package/dist/structure/edit-history.d.ts +6 -0
  320. package/dist/structure/edit-history.js +27 -0
  321. package/dist/structure/export.d.ts +1 -0
  322. package/dist/structure/export.js +39 -31
  323. package/dist/structure/format-detect.d.ts +1 -0
  324. package/dist/structure/format-detect.js +22 -0
  325. package/dist/structure/geometry.d.ts +9 -0
  326. package/dist/structure/geometry.js +27 -0
  327. package/dist/structure/index.d.ts +16 -1
  328. package/dist/structure/index.js +13 -2
  329. package/dist/structure/measure.d.ts +1 -1
  330. package/dist/structure/measure.js +6 -12
  331. package/dist/structure/parse.d.ts +2 -1
  332. package/dist/structure/parse.js +243 -222
  333. package/dist/structure/partial-occupancy.js +4 -2
  334. package/dist/structure/pbc.js +78 -98
  335. package/dist/structure/polyhedra.d.ts +0 -1
  336. package/dist/structure/polyhedra.js +3 -18
  337. package/dist/structure/supercell.d.ts +1 -2
  338. package/dist/structure/supercell.js +7 -13
  339. package/dist/symmetry/SymmetryElements.svelte +11 -15
  340. package/dist/symmetry/SymmetryStats.svelte +56 -68
  341. package/dist/symmetry/WyckoffTable.svelte +5 -24
  342. package/dist/symmetry/cell-transform.js +1 -0
  343. package/dist/symmetry/index.d.ts +1 -0
  344. package/dist/symmetry/index.js +8 -2
  345. package/dist/symmetry/spacegroups.js +3 -2
  346. package/dist/table/HeatmapTable.svelte +1102 -365
  347. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  348. package/dist/table/ToggleMenu.svelte +5 -12
  349. package/dist/table/index.d.ts +21 -6
  350. package/dist/table/index.js +34 -21
  351. package/dist/theme/ThemeControl.svelte +16 -8
  352. package/dist/theme/index.d.ts +1 -5
  353. package/dist/theme/index.js +4 -10
  354. package/dist/theme/themes.mjs +14 -7
  355. package/dist/tooltip/KCoords.svelte +4 -1
  356. package/dist/tooltip/TooltipContent.svelte +2 -5
  357. package/dist/trajectory/Trajectory.svelte +515 -308
  358. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  359. package/dist/trajectory/TrajectoryError.svelte +11 -8
  360. package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
  361. package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
  362. package/dist/trajectory/extract.js +56 -34
  363. package/dist/trajectory/format-detect.js +11 -9
  364. package/dist/trajectory/frame-reader.d.ts +2 -0
  365. package/dist/trajectory/frame-reader.js +33 -29
  366. package/dist/trajectory/helpers.d.ts +2 -0
  367. package/dist/trajectory/helpers.js +18 -7
  368. package/dist/trajectory/index.d.ts +1 -0
  369. package/dist/trajectory/index.js +3 -0
  370. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  371. package/dist/trajectory/parse/h5-utils.js +109 -0
  372. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  373. package/dist/trajectory/parse/hdf5.js +116 -106
  374. package/dist/trajectory/parse/index.d.ts +2 -3
  375. package/dist/trajectory/parse/index.js +17 -20
  376. package/dist/trajectory/parse/lammps.js +8 -12
  377. package/dist/trajectory/parse/vasp.js +10 -7
  378. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  379. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  380. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  381. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  382. package/dist/trajectory/parse/xyz.js +11 -7
  383. package/dist/trajectory/plotting.d.ts +8 -9
  384. package/dist/trajectory/plotting.js +99 -27
  385. package/dist/utils.d.ts +3 -0
  386. package/dist/utils.js +7 -0
  387. package/dist/xrd/XrdPlot.svelte +47 -61
  388. package/dist/xrd/broadening.js +2 -1
  389. package/dist/xrd/calc-xrd.js +2 -4
  390. package/dist/xrd/parse.d.ts +0 -1
  391. package/dist/xrd/parse.js +56 -73
  392. package/package.json +61 -33
  393. package/dist/api/mp.d.ts +0 -6
  394. package/dist/api/mp.js +0 -22
  395. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
@@ -0,0 +1,160 @@
1
+ <script lang="ts">
2
+ // Instanced arrows (shaft cylinders + head cones) for per-site vector layers
3
+ // (forces, magnetic moments, ...). Replaces one <Arrow> component per site
4
+ // (2 meshes + 2 geometries + 2 materials each) with 2 draw calls per layer.
5
+ // Sizing math mirrors Arrow.svelte so the two render identically.
6
+ import type { Vec3 } from '../math'
7
+ import { EPS } from '../math'
8
+ import { T, useThrelte } from '@threlte/core'
9
+ import { untrack } from 'svelte'
10
+ import type { BufferGeometry } from 'three'
11
+ import {
12
+ Color,
13
+ ConeGeometry,
14
+ CylinderGeometry,
15
+ InstancedMesh,
16
+ Matrix4,
17
+ MeshStandardMaterial,
18
+ Quaternion,
19
+ Vector3,
20
+ } from 'three'
21
+
22
+ type ArrowInstance = {
23
+ position: Vec3
24
+ vector: Vec3
25
+ scale: number
26
+ color: string
27
+ }
28
+
29
+ let {
30
+ arrows,
31
+ shaft_radius,
32
+ arrow_head_radius,
33
+ arrow_head_length,
34
+ }: {
35
+ arrows: ArrowInstance[]
36
+ shaft_radius: number // negative = relative to shaft length
37
+ arrow_head_radius: number // negative = relative to shaft length
38
+ arrow_head_length: number // negative = relative to arrow length
39
+ } = $props()
40
+
41
+ const { invalidate } = useThrelte()
42
+
43
+ // Unit primitives scaled per instance: cylinder radius/length via (x=r, y=len, z=r)
44
+ const shaft_geometry = new CylinderGeometry(1, 1, 1, 12)
45
+ const head_geometry = new ConeGeometry(1, 1, 12)
46
+ const shaft_material = new MeshStandardMaterial()
47
+ const head_material = new MeshStandardMaterial()
48
+ $effect(() => () => {
49
+ shaft_geometry.dispose()
50
+ head_geometry.dispose()
51
+ shaft_material.dispose()
52
+ head_material.dispose()
53
+ })
54
+
55
+ const make_mesh = (
56
+ geometry: BufferGeometry,
57
+ material: MeshStandardMaterial,
58
+ count: number,
59
+ ): InstancedMesh => {
60
+ const mesh = new InstancedMesh(geometry, material, count)
61
+ mesh.frustumCulled = false
62
+ mesh.raycast = () => undefined // arrows are display-only
63
+ mesh.userData.per_instance_color = true
64
+ return mesh
65
+ }
66
+
67
+ // Recreate meshes only when the arrow count changes (fixed buffer capacity)
68
+ let shaft_mesh = $state.raw<InstancedMesh | null>(null)
69
+ let head_mesh = $state.raw<InstancedMesh | null>(null)
70
+ $effect(() => {
71
+ const count = arrows.length
72
+ const prev = untrack(() => shaft_mesh)
73
+ if (prev && prev.count === count) return
74
+ prev?.dispose()
75
+ untrack(() => head_mesh)?.dispose()
76
+ if (count === 0) {
77
+ shaft_mesh = null
78
+ head_mesh = null
79
+ return
80
+ }
81
+ shaft_mesh = make_mesh(shaft_geometry, shaft_material, count)
82
+ head_mesh = make_mesh(head_geometry, head_material, count)
83
+ })
84
+ // Unmount-only cleanup (a cleanup on the effect above would dispose meshes
85
+ // on every re-run, including runs that keep them; cleanups run untracked)
86
+ $effect(() => () => {
87
+ shaft_mesh?.dispose()
88
+ head_mesh?.dispose()
89
+ })
90
+
91
+ const up_axis = new Vector3(0, 1, 0)
92
+ const scratch_dir = new Vector3()
93
+ const scratch_quat = new Quaternion()
94
+ const scratch_pos = new Vector3()
95
+ const scratch_scale = new Vector3()
96
+ const scratch_matrix = new Matrix4()
97
+ const scratch_color = new Color()
98
+
99
+ $effect(() => {
100
+ const shafts = shaft_mesh
101
+ const heads = head_mesh
102
+ if (!shafts || !heads) return
103
+ const limit = Math.min(arrows.length, shafts.count)
104
+ for (let idx = 0; idx < limit; idx++) {
105
+ const { position, vector, scale, color } = arrows[idx]
106
+ const mag = Math.hypot(vector[0], vector[1], vector[2])
107
+ if (mag > EPS) {
108
+ scratch_dir.set(vector[0] / mag, vector[1] / mag, vector[2] / mag)
109
+ scratch_quat.setFromUnitVectors(up_axis, scratch_dir)
110
+ } else {
111
+ scratch_dir.set(0, 1, 0)
112
+ scratch_quat.identity()
113
+ }
114
+ const vec_len = mag * scale
115
+ const head_len = arrow_head_length < 0 ? vec_len * -arrow_head_length : arrow_head_length
116
+ const shaft_len = Math.max(0, vec_len - head_len * 0.5)
117
+ const shaft_r = shaft_radius < 0 ? shaft_len * -shaft_radius : shaft_radius
118
+ const head_r = arrow_head_radius < 0 ? shaft_len * -arrow_head_radius : arrow_head_radius
119
+
120
+ // Shafts shorter than Arrow.svelte's 0.01 render threshold collapse to zero scale
121
+ const draw_shaft = shaft_len > 0.01
122
+ scratch_pos.set(
123
+ position[0] + scratch_dir.x * shaft_len * 0.5,
124
+ position[1] + scratch_dir.y * shaft_len * 0.5,
125
+ position[2] + scratch_dir.z * shaft_len * 0.5,
126
+ )
127
+ scratch_scale.set(
128
+ draw_shaft ? shaft_r : 0,
129
+ draw_shaft ? shaft_len : 0,
130
+ draw_shaft ? shaft_r : 0,
131
+ )
132
+ shafts.setMatrixAt(idx, scratch_matrix.compose(scratch_pos, scratch_quat, scratch_scale))
133
+
134
+ const head_offset = shaft_len + head_len * 0.5
135
+ scratch_pos.set(
136
+ position[0] + scratch_dir.x * head_offset,
137
+ position[1] + scratch_dir.y * head_offset,
138
+ position[2] + scratch_dir.z * head_offset,
139
+ )
140
+ scratch_scale.set(head_r, head_len, head_r)
141
+ heads.setMatrixAt(idx, scratch_matrix.compose(scratch_pos, scratch_quat, scratch_scale))
142
+
143
+ scratch_color.set(color)
144
+ shafts.setColorAt(idx, scratch_color)
145
+ heads.setColorAt(idx, scratch_color)
146
+ }
147
+ for (const mesh of [shafts, heads]) {
148
+ mesh.instanceMatrix.needsUpdate = true
149
+ if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true
150
+ }
151
+ invalidate()
152
+ })
153
+ </script>
154
+
155
+ {#if shaft_mesh}
156
+ <T is={shaft_mesh} />
157
+ {/if}
158
+ {#if head_mesh}
159
+ <T is={head_mesh} />
160
+ {/if}
@@ -0,0 +1,16 @@
1
+ import type { Vec3 } from '../math';
2
+ type ArrowInstance = {
3
+ position: Vec3;
4
+ vector: Vec3;
5
+ scale: number;
6
+ color: string;
7
+ };
8
+ type $$ComponentProps = {
9
+ arrows: ArrowInstance[];
10
+ shaft_radius: number;
11
+ arrow_head_radius: number;
12
+ arrow_head_length: number;
13
+ };
14
+ declare const ArrowInstances: import("svelte").Component<$$ComponentProps, {}, "">;
15
+ type ArrowInstances = ReturnType<typeof ArrowInstances>;
16
+ export default ArrowInstances;
@@ -10,10 +10,7 @@
10
10
  import { colors } from '../state.svelte'
11
11
  import type { AnyStructure } from './'
12
12
  import { atomic_radii } from './'
13
- import type {
14
- AtomColorConfig,
15
- AtomPropertyColors,
16
- } from './atom-properties'
13
+ import type { AtomColorConfig, AtomPropertyColors } from './atom-properties'
17
14
  import type { MoyoDataset } from '@spglib/moyo-wasm'
18
15
  import type { Snippet } from 'svelte'
19
16
  import { click_outside, tooltip } from 'svelte-multiselect/attachments'
@@ -77,8 +74,7 @@
77
74
  }
78
75
 
79
76
  let show_element_legend = $derived(
80
- atom_color_config.mode === `element` && elements &&
81
- Object.keys(elements).length > 0,
77
+ atom_color_config.mode === `element` && elements && Object.keys(elements).length > 0,
82
78
  )
83
79
  let show_property_legend = $derived(
84
80
  atom_color_config.mode !== `element` && property_colors?.colors.length,
@@ -111,33 +107,43 @@
111
107
  let format_value = (val: number | string): string => {
112
108
  if (typeof val === `number`) return format_num(val, `.3~f`)
113
109
 
114
- if (typeof val === `string` && val.includes(`|`)) { // Format Wyckoff orbit IDs
110
+ if (typeof val === `string` && val.includes(`|`)) {
111
+ // Format Wyckoff orbit IDs
115
112
  const [wyckoff, element] = val.split(`|`, 2)
116
113
  // Count how many sites have this wyckoff+element combination
117
- const count = property_colors?.values.filter((property_value) =>
118
- property_value === val
119
- ).length ?? 0
114
+ const count =
115
+ property_colors?.values.filter((property_value) => property_value === val).length ?? 0
120
116
  return `${element}:${count}${wyckoff}`
121
117
  }
122
118
  return String(val)
123
119
  }
124
120
 
125
- // Map from property value to color (computed once, reused in categorical legend)
126
- let color_map = $derived(
127
- new Map(
128
- // Use unique_values instead of values to avoid undefined colors from duplicates
129
- property_colors?.unique_values?.flatMap((val) => {
130
- const idx = property_colors.values.indexOf(val)
131
- return idx !== -1 ? [[val, property_colors.colors[idx]]] : []
132
- }),
133
- ),
134
- )
121
+ // Map each property value to its first color in a single O(n) pass (reused in
122
+ // categorical and discrete legends). Skips undefined colors if arrays ever drift.
123
+ let color_map = $derived.by(() => {
124
+ const map = new Map<number | string, string>()
125
+ const { values = [], colors: value_colors = [] } = property_colors ?? {}
126
+ for (const [idx, val] of values.entries()) {
127
+ const color = value_colors[idx]
128
+ if (color !== undefined && !map.has(val)) map.set(val, color)
129
+ }
130
+ return map
131
+ })
132
+
133
+ // Continuous integer properties (e.g. coordination numbers) render as a discrete
134
+ // segmented bar with one labeled block per integer value instead of a smooth gradient.
135
+ // Cap segment count so high-cardinality numeric properties keep the gradient bar.
136
+ const MAX_DISCRETE_SEGMENTS = 20
137
+ let is_discrete_numeric = $derived.by(() => {
138
+ const uniq = property_colors?.unique_values
139
+ // Number.isInteger is false for strings/non-numbers (no coercion), so it also
140
+ // excludes categorical (e.g. Wyckoff) data without a separate type check
141
+ return Boolean(
142
+ uniq?.length && uniq.length <= MAX_DISCRETE_SEGMENTS && uniq.every(Number.isInteger),
143
+ )
144
+ })
135
145
 
136
- function toggle_visibility<T>(
137
- set: Set<T>,
138
- value: T,
139
- event: MouseEvent,
140
- ): Set<T> {
146
+ function toggle_visibility<T>(set: Set<T>, value: T, event: MouseEvent): Set<T> {
141
147
  event.preventDefault()
142
148
  event.stopPropagation()
143
149
  const new_set = new SvelteSet(set)
@@ -156,8 +162,7 @@
156
162
  const query = remap_search.toLowerCase()
157
163
  return ELEM_SYMBOLS.filter((elem) => {
158
164
  const data = element_data?.find((el) => el.symbol === elem)
159
- return elem.toLowerCase().includes(query) ||
160
- data?.name?.toLowerCase().includes(query)
165
+ return elem.toLowerCase().includes(query) || data?.name?.toLowerCase().includes(query)
161
166
  })
162
167
  })
163
168
 
@@ -165,14 +170,13 @@
165
170
  let sorted_element_entries = $derived.by(() => {
166
171
  if (!elements) return []
167
172
  const element_amounts = elements as Record<string, number>
168
- const ordered_known_entries = ELEM_SYMBOLS
169
- .flatMap((element_symbol) => {
170
- const amount = element_amounts[element_symbol]
171
- return amount === undefined ? [] : [[element_symbol, amount] as const]
172
- })
173
+ const ordered_known_entries = ELEM_SYMBOLS.flatMap((element_symbol) => {
174
+ const amount = element_amounts[element_symbol]
175
+ return amount === undefined ? [] : [[element_symbol, amount] as const]
176
+ })
173
177
  const unknown_entries = Object.entries(element_amounts)
174
- .filter(([element_symbol]) =>
175
- !known_element_symbols.has(element_symbol as ElementSymbol)
178
+ .filter(
179
+ ([element_symbol]) => !known_element_symbols.has(element_symbol as ElementSymbol),
176
180
  )
177
181
  .sort(([element_a], [element_b]) => element_a.localeCompare(element_b))
178
182
  return [...ordered_known_entries, ...unknown_entries]
@@ -195,7 +199,7 @@
195
199
  const MAX_RADIUS = 5
196
200
 
197
201
  const parse_radius = (value: string): number | null => {
198
- const num = parseFloat(value)
202
+ const num = Number(value)
199
203
  return !isNaN(num) && num >= MIN_RADIUS && num <= MAX_RADIUS ? num : null
200
204
  }
201
205
 
@@ -238,7 +242,7 @@
238
242
  {#snippet mode_selector_snippet()}
239
243
  <div
240
244
  class="mode-selector"
241
- {@attach click_outside({ callback: () => mode_menu_open = false })}
245
+ {@attach click_outside({ callback: () => (mode_menu_open = false) })}
242
246
  >
243
247
  <button
244
248
  class="mode-toggle"
@@ -254,10 +258,7 @@
254
258
  </button>
255
259
  {#if mode_menu_open}
256
260
  <div class="mode-dropdown">
257
- {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as
258
- [value, label]
259
- (value)
260
- }
261
+ {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as [value, label] (value)}
261
262
  <button
262
263
  class="mode-option"
263
264
  class:selected={atom_color_config.mode === value}
@@ -323,7 +324,7 @@
323
324
  {/snippet}
324
325
 
325
326
  {#if show_element_legend}
326
- <div {...rest} class="atom-legend element-legend {rest.class ?? ``}">
327
+ <div {...rest} class={[`atom-legend element-legend`, rest.class]}>
327
328
  {@render mode_selector_snippet()}
328
329
  {#each sorted_element_entries as [elem, amt], idx (elem)}
329
330
  {@const is_hidden = hidden_elements.has(elem as ElementSymbol)}
@@ -331,7 +332,8 @@
331
332
  <div class="legend-item">
332
333
  <label
333
334
  bind:this={labels[idx]}
334
- title="{element_data?.find((el) => el.symbol === displayed_elem)?.name ?? ``}{displayed_elem !== elem ? ` (remapped from ${elem})` : ``}"
335
+ title="{element_data?.find((el) => el.symbol === displayed_elem)?.name ??
336
+ ``}{displayed_elem !== elem ? ` (remapped from ${elem})` : ``}"
335
337
  {@attach tooltip()}
336
338
  style:background-color={colors.element[displayed_elem]}
337
339
  class:hidden={is_hidden}
@@ -364,13 +366,12 @@
364
366
  <button
365
367
  class="toggle-visibility"
366
368
  class:element-hidden={is_hidden}
367
- onclick={(
368
- event,
369
- ) => (hidden_elements = toggle_visibility(
370
- hidden_elements,
371
- elem as ElementSymbol,
372
- event,
373
- ))}
369
+ onclick={(event) =>
370
+ (hidden_elements = toggle_visibility(
371
+ hidden_elements,
372
+ elem as ElementSymbol,
373
+ event,
374
+ ))}
374
375
  title={is_hidden ? `Show ${elem} atoms` : `Hide ${elem} atoms`}
375
376
  {@attach tooltip({ placement: `top` })}
376
377
  type="button"
@@ -390,8 +391,8 @@
390
391
  <div class="radius-control">
391
392
  <label
392
393
  title={displayed_elem !== elem
393
- ? `Radius for ${elem} atoms (displayed as ${displayed_elem})`
394
- : `Radius for ${elem} atoms`}
394
+ ? `Radius for ${elem} atoms (displayed as ${displayed_elem})`
395
+ : `Radius for ${elem} atoms`}
395
396
  {@attach tooltip({ placement: `top` })}
396
397
  >
397
398
  <span>Radius ({elem})</span>
@@ -403,10 +404,7 @@
403
404
  value={get_element_radius(elem as ElementSymbol)}
404
405
  oninput={(event) => {
405
406
  if (event.target instanceof HTMLInputElement) {
406
- update_element_radius(
407
- elem as ElementSymbol,
408
- event.target.value,
409
- )
407
+ update_element_radius(elem as ElementSymbol, event.target.value)
410
408
  }
411
409
  }}
412
410
  />
@@ -480,11 +478,29 @@
480
478
  <h4>{legend_title}</h4>
481
479
  </div>
482
480
  {/if}
483
- {#if atom_color_config.scale_type === `continuous` && property_colors}
484
- <div
485
- title={legend_title}
486
- {@attach tooltip({ placement: `top` })}
487
- >
481
+ {#if atom_color_config.scale_type === `continuous` && property_colors && is_discrete_numeric}
482
+ <div class="discrete-colorbar">
483
+ {#each property_colors.unique_values ?? [] as value (value)}
484
+ {@const color = color_map.get(value)}
485
+ {@const is_hidden = hidden_prop_vals.has(value)}
486
+ <button
487
+ type="button"
488
+ class="discrete-segment"
489
+ class:hidden={is_hidden}
490
+ style:background-color={color}
491
+ aria-pressed={is_hidden}
492
+ onclick={(event) =>
493
+ (hidden_prop_vals = toggle_visibility(hidden_prop_vals, value, event))}
494
+ title={is_hidden ? `Show ${format_value(value)}` : `Hide ${format_value(value)}`}
495
+ {@attach tooltip({ placement: `top` })}
496
+ {@attach contrast_color()}
497
+ >
498
+ {format_value(value)}
499
+ </button>
500
+ {/each}
501
+ </div>
502
+ {:else if atom_color_config.scale_type === `continuous` && property_colors}
503
+ <div title={legend_title} {@attach tooltip({ placement: `top` })}>
488
504
  <ColorBar
489
505
  color_scale={atom_color_config.scale}
490
506
  range={[property_colors.min_value ?? 0, property_colors.max_value ?? 0]}
@@ -499,10 +515,7 @@
499
515
  />
500
516
  </div>
501
517
  {:else if atom_color_config.scale_type === `categorical` && property_colors}
502
- {#each property_colors.unique_values || [] as
503
- value
504
- (`${atom_color_config.mode}-${value}`)
505
- }
518
+ {#each property_colors.unique_values || [] as value (`${atom_color_config.mode}-${value}`)}
506
519
  {@const color = color_map.get(value)}
507
520
  {@const is_hidden = hidden_prop_vals.has(value)}
508
521
  <div class="legend-item">
@@ -517,13 +530,8 @@
517
530
  <button
518
531
  class="toggle-visibility"
519
532
  class:element-hidden={is_hidden}
520
- onclick={(
521
- event,
522
- ) => (hidden_prop_vals = toggle_visibility(
523
- hidden_prop_vals,
524
- value,
525
- event,
526
- ))}
533
+ onclick={(event) =>
534
+ (hidden_prop_vals = toggle_visibility(hidden_prop_vals, value, event))}
527
535
  title={is_hidden ? `Show ${format_value(value)}` : `Hide ${format_value(value)}`}
528
536
  {@attach tooltip({ placement: `top` })}
529
537
  type="button"
@@ -552,7 +560,9 @@
552
560
  gap: var(--struct-legend-gap, clamp(3pt, 2cqmin, 7pt));
553
561
  }
554
562
  .element-legend {
555
- font-size: var(--struct-legend-font, clamp(7pt, 2.5cqmin, 12pt));
563
+ /* 9pt floor keeps chips legible in small embeds (carousel cards) where
564
+ the cqmin term collapses */
565
+ font-size: var(--struct-legend-font, clamp(9pt, 2.5cqmin, 12pt));
556
566
  }
557
567
  .atom-legend .legend-item {
558
568
  position: relative;
@@ -598,7 +608,10 @@
598
608
  display: grid;
599
609
  place-items: center;
600
610
  opacity: 0;
601
- transition: opacity 0.2s ease, background 0.2s ease, transform 0.1s ease;
611
+ transition:
612
+ opacity 0.2s ease,
613
+ background 0.2s ease,
614
+ transform 0.1s ease;
602
615
  z-index: 2;
603
616
  pointer-events: auto;
604
617
  }
@@ -717,7 +730,7 @@
717
730
 
718
731
  /* Property Legend Styles */
719
732
  .property-legend {
720
- font-size: var(--struct-legend-font, clamp(8pt, 3cqmin, 14pt));
733
+ font-size: var(--struct-legend-font, clamp(9pt, 3cqmin, 14pt));
721
734
  }
722
735
  .mode-selector {
723
736
  position: relative;
@@ -753,7 +766,9 @@
753
766
  margin-bottom: 0.25rem;
754
767
  background: var(--surface-bg);
755
768
  border-radius: var(--border-radius, 3pt);
756
- box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.3), 0 4px 8px -2px rgba(0, 0, 0, 0.1);
769
+ box-shadow:
770
+ 0 8px 16px -4px rgba(0, 0, 0, 0.3),
771
+ 0 4px 8px -2px rgba(0, 0, 0, 0.1);
757
772
  display: flex;
758
773
  flex-direction: column;
759
774
  z-index: 10;
@@ -795,6 +810,31 @@
795
810
  .mode-option span {
796
811
  white-space: nowrap;
797
812
  }
813
+ /* Discrete color bar: contiguous integer-labeled segments (e.g. coordination numbers) */
814
+ .discrete-colorbar {
815
+ display: flex;
816
+ height: var(--struct-discrete-bar-height, 16px);
817
+ border-radius: var(--border-radius, 3pt);
818
+ overflow: hidden;
819
+ }
820
+ .discrete-segment {
821
+ flex: 1 1 0;
822
+ min-width: 1.7em;
823
+ margin: 0;
824
+ padding: 0 4pt;
825
+ border: none;
826
+ border-radius: 0;
827
+ font-size: 0.85em;
828
+ line-height: 1;
829
+ cursor: pointer;
830
+ display: grid;
831
+ place-items: center;
832
+ transition: opacity 0.2s ease;
833
+ }
834
+ .discrete-segment.hidden {
835
+ opacity: 0.35;
836
+ text-decoration: line-through;
837
+ }
798
838
  .category-label {
799
839
  padding: var(--struct-legend-padding, 0 4pt);
800
840
  border-radius: var(--struct-legend-radius, var(--border-radius, 3pt));
@@ -30,6 +30,6 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `children`> & {
30
30
  structure?: AnyStructure | null;
31
31
  }]>;
32
32
  };
33
- declare const AtomLegend: import("svelte").Component<$$ComponentProps, {}, "labels" | "atom_color_config" | "hidden_elements" | "hidden_prop_vals" | "element_mapping" | "element_radius_overrides" | "site_radius_overrides">;
33
+ declare const AtomLegend: import("svelte").Component<$$ComponentProps, {}, "labels" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "atom_color_config" | "element_mapping">;
34
34
  type AtomLegend = ReturnType<typeof AtomLegend>;
35
35
  export default AtomLegend;
@@ -4,7 +4,11 @@
4
4
  import type { InstancedMesh } from 'three'
5
5
  import { Color, InstancedBufferAttribute, Matrix4, ShaderMaterial } from 'three'
6
6
 
7
- let { group, saturation = 0.5, brightness = 0.7 }: {
7
+ let {
8
+ group,
9
+ saturation = 0.5,
10
+ brightness = 0.7,
11
+ }: {
8
12
  group: BondGroupWithGradients
9
13
  saturation?: number
10
14
  brightness?: number
@@ -104,12 +108,10 @@
104
108
 
105
109
  // Update geometry color attributes
106
110
  const { geometry } = mesh
107
- for (
108
- const [name, buffer] of [
109
- [`instanceColorStart`, colors_start],
110
- [`instanceColorEnd`, colors_end],
111
- ] as const
112
- ) {
111
+ for (const [name, buffer] of [
112
+ [`instanceColorStart`, colors_start],
113
+ [`instanceColorEnd`, colors_end],
114
+ ] as const) {
113
115
  const existing = geometry.getAttribute(name)
114
116
  if (existing?.array === buffer) existing.needsUpdate = true
115
117
  else geometry.setAttribute(name, new InstancedBufferAttribute(buffer, 3))
@@ -118,23 +120,29 @@
118
120
  mesh.count = count
119
121
  })
120
122
 
121
- let shader_material = $derived(
122
- new ShaderMaterial({
123
- vertexShader: vertex_shader,
124
- fragmentShader: fragment_shader,
125
- uniforms: {
126
- ambientIntensity: { value: group.ambient_light ?? 0.7 },
127
- directionalIntensity: { value: group.directional_light ?? 0.3 },
128
- saturation: { value: saturation },
129
- brightness: { value: brightness },
130
- },
131
- }),
132
- )
123
+ // Create the GPU material once + mutate uniforms reactively (a $derived would leak a new
124
+ // ShaderMaterial per lighting tweak). The $effect sets real uniform values before paint.
125
+ const shader_material = new ShaderMaterial({
126
+ vertexShader: vertex_shader,
127
+ fragmentShader: fragment_shader,
128
+ uniforms: {
129
+ ambientIntensity: { value: 0.7 },
130
+ directionalIntensity: { value: 0.3 },
131
+ saturation: { value: 0.5 },
132
+ brightness: { value: 0.7 },
133
+ },
134
+ })
135
+
136
+ $effect(() => {
137
+ shader_material.uniforms.ambientIntensity.value = group.ambient_light ?? 0.7
138
+ shader_material.uniforms.directionalIntensity.value = group.directional_light ?? 0.3
139
+ shader_material.uniforms.saturation.value = saturation
140
+ shader_material.uniforms.brightness.value = brightness
141
+ })
142
+
143
+ $effect(() => () => shader_material.dispose())
133
144
  </script>
134
145
 
135
- <T.InstancedMesh
136
- args={[undefined, shader_material, group.instances.length]}
137
- bind:ref={mesh}
138
- >
146
+ <T.InstancedMesh args={[undefined, shader_material, group.instances.length]} bind:ref={mesh}>
139
147
  <T.CylinderGeometry args={[group.thickness, group.thickness, 1, 8]} />
140
148
  </T.InstancedMesh>
@@ -4,13 +4,22 @@
4
4
  import type { HTMLAttributes } from 'svelte/elements'
5
5
  import type { Vec3 } from '../math'
6
6
 
7
- let { position, children, ...rest }: HTMLAttributes<HTMLDivElement> & {
7
+ let {
8
+ position,
9
+ children,
10
+ ...rest
11
+ }: HTMLAttributes<HTMLDivElement> & {
8
12
  position: Vec3
9
13
  children: Snippet<[{ position: Vec3 }]>
10
14
  } = $props()
11
15
  </script>
12
16
 
13
- <HTML {position} pointerEvents="none">
17
+ <!-- Constant zIndexRange: threlte's default [16777271, 0] maps camera distance
18
+ over [near, far], which extrapolates to a NEGATIVE z-index for sites beyond
19
+ camera.far (common in zoomed-out carousel cards) — painting the tooltip
20
+ behind the canvas. A degenerate range pins z-index at 1000, always above the
21
+ canvas and sibling overlays. -->
22
+ <HTML {position} pointerEvents="none" zIndexRange={[1000, 1000]}>
14
23
  <div {...rest} role="tooltip">
15
24
  {@render children({ position })}
16
25
  </div>
@@ -23,7 +32,10 @@
23
32
  box-sizing: border-box;
24
33
  text-align: var(--canvas-tooltip-text-align, left);
25
34
  border-radius: var(--canvas-tooltip-border-radius, var(--border-radius, 3pt));
26
- background: var(--canvas-tooltip-bg, light-dark(rgba(226, 232, 240, 0.96), rgba(15, 23, 42, 0.96)));
35
+ background: var(
36
+ --canvas-tooltip-bg,
37
+ light-dark(rgba(226, 232, 240, 0.96), rgba(15, 23, 42, 0.96))
38
+ );
27
39
  padding: var(--canvas-tooltip-padding, 1pt 5pt);
28
40
  color: var(--canvas-tooltip-text-color, light-dark(#0f172a, #f8fafc));
29
41
  font-family: var(--canvas-tooltip-font-family);