matterviz 0.4.0 → 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 (527) 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 +132 -219
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +9 -20
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +47 -96
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +15 -42
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  13. package/dist/brillouin/BrillouinZoneScene.svelte +63 -230
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  15. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  16. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  17. package/dist/brillouin/compute.d.ts +2 -0
  18. package/dist/brillouin/compute.js +80 -77
  19. package/dist/brillouin/geometry.d.ts +8 -0
  20. package/dist/brillouin/geometry.js +57 -0
  21. package/dist/brillouin/index.d.ts +2 -0
  22. package/dist/brillouin/index.js +2 -0
  23. package/dist/brillouin/types.d.ts +2 -2
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  25. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +143 -246
  27. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +652 -976
  29. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  30. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  31. package/dist/chempot-diagram/color.d.ts +3 -6
  32. package/dist/chempot-diagram/color.js +5 -5
  33. package/dist/chempot-diagram/compute.d.ts +3 -3
  34. package/dist/chempot-diagram/compute.js +3 -1
  35. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  36. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  37. package/dist/chempot-diagram/export.d.ts +47 -0
  38. package/dist/chempot-diagram/export.js +133 -0
  39. package/dist/chempot-diagram/index.d.ts +1 -0
  40. package/dist/chempot-diagram/index.js +1 -0
  41. package/dist/chempot-diagram/pointer.d.ts +0 -10
  42. package/dist/chempot-diagram/pointer.js +4 -4
  43. package/dist/chempot-diagram/types.d.ts +3 -3
  44. package/dist/colors/index.d.ts +0 -4
  45. package/dist/colors/index.js +21 -22
  46. package/dist/composition/BarChart.svelte +37 -31
  47. package/dist/composition/BubbleChart.svelte +17 -17
  48. package/dist/composition/Composition.svelte +7 -11
  49. package/dist/composition/Formula.svelte +18 -25
  50. package/dist/composition/FormulaFilter.svelte +96 -98
  51. package/dist/composition/PieChart.svelte +60 -46
  52. package/dist/composition/chem-sys.js +3 -2
  53. package/dist/composition/format.js +4 -3
  54. package/dist/composition/index.d.ts +2 -0
  55. package/dist/composition/index.js +14 -0
  56. package/dist/composition/parse.d.ts +2 -3
  57. package/dist/composition/parse.js +27 -28
  58. package/dist/constants.js +11 -9
  59. package/dist/controls.d.ts +1 -0
  60. package/dist/controls.js +0 -1
  61. package/dist/convex-hull/ConvexHull.svelte +20 -25
  62. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  63. package/dist/convex-hull/ConvexHull2D.svelte +176 -256
  64. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  65. package/dist/convex-hull/ConvexHull3D.svelte +269 -804
  66. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  67. package/dist/convex-hull/ConvexHull4D.svelte +236 -755
  68. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  69. package/dist/convex-hull/ConvexHullChrome.svelte +264 -0
  70. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  71. package/dist/convex-hull/ConvexHullControls.svelte +128 -49
  72. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  73. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  74. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  75. package/dist/convex-hull/ConvexHullStats.svelte +210 -351
  76. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  77. package/dist/convex-hull/ConvexHullTooltip.svelte +16 -14
  78. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  79. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  80. package/dist/convex-hull/StructurePopup.svelte +17 -21
  81. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  82. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  83. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  84. package/dist/convex-hull/barycentric-coords.js +6 -33
  85. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  86. package/dist/convex-hull/canvas-interactions.svelte.js +279 -0
  87. package/dist/convex-hull/helpers.d.ts +47 -17
  88. package/dist/convex-hull/helpers.js +186 -101
  89. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  90. package/dist/convex-hull/hull-state.svelte.js +124 -0
  91. package/dist/convex-hull/index.d.ts +9 -7
  92. package/dist/convex-hull/index.js +7 -2
  93. package/dist/convex-hull/thermodynamics.js +109 -937
  94. package/dist/convex-hull/types.d.ts +12 -4
  95. package/dist/convex-hull/types.js +12 -0
  96. package/dist/coordination/CoordinationBarPlot.svelte +41 -43
  97. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  98. package/dist/coordination/calc-coordination.d.ts +1 -1
  99. package/dist/coordination/calc-coordination.js +28 -25
  100. package/dist/element/BohrAtom.svelte +6 -8
  101. package/dist/element/ElementHeading.svelte +4 -1
  102. package/dist/element/ElementPhoto.svelte +11 -9
  103. package/dist/element/ElementStats.svelte +12 -10
  104. package/dist/element/ElementTile.svelte +24 -29
  105. package/dist/element/ElementTile.svelte.d.ts +1 -1
  106. package/dist/element/Nucleus.svelte +4 -2
  107. package/dist/element/data.d.ts +1 -2
  108. package/dist/element/helpers.d.ts +4 -0
  109. package/dist/element/helpers.js +18 -0
  110. package/dist/element/index.d.ts +1 -0
  111. package/dist/element/index.js +3 -0
  112. package/dist/feedback/DragOverlay.svelte +5 -3
  113. package/dist/feedback/DragOverlay.svelte.d.ts +2 -1
  114. package/dist/feedback/StatusMessage.svelte +20 -7
  115. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  116. package/dist/fermi-surface/FermiSurface.svelte +78 -165
  117. package/dist/fermi-surface/FermiSurface.svelte.d.ts +9 -20
  118. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  119. package/dist/fermi-surface/FermiSurfaceScene.svelte +93 -272
  120. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  121. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  122. package/dist/fermi-surface/compute.js +14 -13
  123. package/dist/fermi-surface/export.js +4 -15
  124. package/dist/fermi-surface/index.d.ts +0 -1
  125. package/dist/fermi-surface/index.js +0 -1
  126. package/dist/fermi-surface/parse.d.ts +1 -1
  127. package/dist/fermi-surface/parse.js +84 -97
  128. package/dist/fermi-surface/types.d.ts +2 -2
  129. package/dist/heatmap-matrix/HeatmapMatrix.svelte +161 -185
  130. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +6 -5
  131. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +12 -9
  132. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  133. package/dist/heatmap-matrix/index.d.ts +8 -2
  134. package/dist/icons.d.ts +4 -0
  135. package/dist/icons.js +4 -0
  136. package/dist/index.d.ts +1 -0
  137. package/dist/index.js +1 -0
  138. package/dist/io/ExportPane.svelte +170 -0
  139. package/dist/io/ExportPane.svelte.d.ts +17 -0
  140. package/dist/io/decompress.d.ts +2 -1
  141. package/dist/io/decompress.js +22 -36
  142. package/dist/io/export.d.ts +9 -1
  143. package/dist/io/export.js +37 -29
  144. package/dist/io/fetch.d.ts +2 -4
  145. package/dist/io/fetch.js +0 -11
  146. package/dist/io/file-drop.d.ts +7 -0
  147. package/dist/io/file-drop.js +13 -0
  148. package/dist/io/index.d.ts +1 -0
  149. package/dist/io/index.js +3 -0
  150. package/dist/io/is-binary.d.ts +9 -0
  151. package/dist/io/is-binary.js +45 -1
  152. package/dist/io/types.d.ts +13 -0
  153. package/dist/io/url-drop.js +13 -25
  154. package/dist/isosurface/Isosurface.svelte +17 -23
  155. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  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 +50 -48
  159. package/dist/labels.d.ts +6 -2
  160. package/dist/labels.js +44 -14
  161. package/dist/layout/FullscreenButton.svelte +34 -0
  162. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  163. package/dist/layout/FullscreenToggle.svelte +12 -12
  164. package/dist/layout/InfoCard.svelte +7 -18
  165. package/dist/layout/InfoTag.svelte +1 -3
  166. package/dist/layout/NumberRangeInput.svelte +46 -0
  167. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  168. package/dist/layout/PropertyFilter.svelte +2 -6
  169. package/dist/layout/SettingsSection.svelte +21 -17
  170. package/dist/layout/SubpageGrid.svelte +3 -1
  171. package/dist/layout/ViewerChrome.svelte +115 -0
  172. package/dist/layout/ViewerChrome.svelte.d.ts +18 -0
  173. package/dist/layout/fullscreen.d.ts +4 -0
  174. package/dist/layout/fullscreen.js +3 -5
  175. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  176. package/dist/layout/fullscreen.svelte.js +36 -0
  177. package/dist/layout/index.d.ts +4 -0
  178. package/dist/layout/index.js +4 -0
  179. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  180. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  181. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  182. package/dist/layout/json-tree/utils.js +14 -23
  183. package/dist/math.d.ts +9 -3
  184. package/dist/math.js +37 -21
  185. package/dist/overlays/ContextMenu.svelte +4 -2
  186. package/dist/overlays/CopyButton.svelte +11 -5
  187. package/dist/overlays/DragControlTab.svelte +6 -1
  188. package/dist/overlays/DraggablePane.svelte +81 -26
  189. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  190. package/dist/overlays/GlassChip.svelte +30 -0
  191. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  192. package/dist/overlays/InfoPaneCards.svelte +11 -23
  193. package/dist/overlays/index.d.ts +11 -0
  194. package/dist/overlays/index.js +26 -0
  195. package/dist/overlays/portal.d.ts +2 -0
  196. package/dist/overlays/portal.js +14 -0
  197. package/dist/periodic-table/PeriodicTable.svelte +115 -146
  198. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  199. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  200. package/dist/periodic-table/TableInset.svelte +9 -4
  201. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  202. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  203. package/dist/phase-diagram/PhaseDiagramControls.svelte +73 -96
  204. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  205. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  206. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  207. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +49 -134
  208. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  209. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  210. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  211. package/dist/phase-diagram/build-diagram.js +3 -3
  212. package/dist/phase-diagram/colors.js +1 -1
  213. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  214. package/dist/phase-diagram/parse.d.ts +2 -1
  215. package/dist/phase-diagram/parse.js +15 -15
  216. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  217. package/dist/phase-diagram/utils.js +2 -3
  218. package/dist/plot/bar/BarPlot.svelte +494 -692
  219. package/dist/plot/bar/BarPlot.svelte.d.ts +9 -15
  220. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  221. package/dist/plot/bar/BarPlotControls.svelte.d.ts +5 -7
  222. package/dist/plot/bar/SpacegroupBarPlot.svelte +31 -37
  223. package/dist/plot/bar/data.d.ts +5 -4
  224. package/dist/plot/bar/data.js +2 -1
  225. package/dist/plot/box/BoxPlot.svelte +361 -439
  226. package/dist/plot/box/BoxPlot.svelte.d.ts +6 -3
  227. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  228. package/dist/plot/box/Violin.svelte.d.ts +2 -1
  229. package/dist/plot/box/box-plot.d.ts +3 -2
  230. package/dist/plot/box/box-plot.js +6 -3
  231. package/dist/plot/box/kde.d.ts +2 -1
  232. package/dist/plot/box/kde.js +4 -4
  233. package/dist/plot/core/auto-place.d.ts +1 -1
  234. package/dist/plot/core/auto-place.js +5 -2
  235. package/dist/plot/core/axis-utils.d.ts +12 -7
  236. package/dist/plot/core/axis-utils.js +48 -48
  237. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  238. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  239. package/dist/plot/core/components/ColorBar.svelte +106 -111
  240. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  241. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  242. package/dist/plot/core/components/FillArea.svelte +10 -17
  243. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  244. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  245. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  246. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  247. package/dist/plot/core/components/Line.svelte +21 -11
  248. package/dist/plot/core/components/Line.svelte.d.ts +5 -2
  249. package/dist/plot/core/components/PlotAxis.svelte +42 -18
  250. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  251. package/dist/plot/core/components/PlotControls.svelte +65 -41
  252. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  253. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  254. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  255. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  256. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  257. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  258. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  259. package/dist/plot/core/components/ReferenceLine3D.svelte +56 -59
  260. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  261. package/dist/plot/core/components/ReferencePlane.svelte +9 -10
  262. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  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 +29 -476
  271. package/dist/plot/core/data-transform.js +9 -5
  272. package/dist/plot/core/fill-utils.d.ts +7 -4
  273. package/dist/plot/core/fill-utils.js +34 -9
  274. package/dist/plot/core/index.d.ts +1 -0
  275. package/dist/plot/core/index.js +1 -0
  276. package/dist/plot/core/interactions.d.ts +5 -1
  277. package/dist/plot/core/interactions.js +14 -2
  278. package/dist/plot/core/layout.d.ts +3 -1
  279. package/dist/plot/core/layout.js +22 -13
  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 +35 -0
  283. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  284. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -0
  286. package/dist/plot/core/reference-line.d.ts +10 -10
  287. package/dist/plot/core/reference-line.js +7 -7
  288. package/dist/plot/core/scales.d.ts +40 -25
  289. package/dist/plot/core/scales.js +49 -21
  290. package/dist/plot/core/svg.d.ts +2 -1
  291. package/dist/plot/core/types/fills.d.ts +101 -0
  292. package/dist/plot/core/types/fills.js +15 -0
  293. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  294. package/dist/plot/core/types/plot-3d.js +4 -0
  295. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  296. package/dist/plot/core/types/reference-lines.js +9 -0
  297. package/dist/plot/core/types.d.ts +47 -331
  298. package/dist/plot/core/types.js +23 -20
  299. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  300. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  301. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  302. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  303. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  304. package/dist/plot/core/utils/label-placement.js +5 -5
  305. package/dist/plot/core/utils.d.ts +2 -1
  306. package/dist/plot/histogram/Histogram.svelte +373 -631
  307. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  308. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  309. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  310. package/dist/plot/histogram/histogram.d.ts +31 -0
  311. package/dist/plot/histogram/histogram.js +70 -0
  312. package/dist/plot/histogram/index.d.ts +1 -0
  313. package/dist/plot/histogram/index.js +1 -0
  314. package/dist/plot/index.d.ts +1 -0
  315. package/dist/plot/index.js +1 -0
  316. package/dist/plot/sankey/Sankey.svelte +79 -73
  317. package/dist/plot/sankey/Sankey.svelte.d.ts +3 -3
  318. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  319. package/dist/plot/sankey/sankey.js +3 -1
  320. package/dist/plot/scatter/BinnedScatterPlot.svelte +264 -112
  321. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +11 -4
  322. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  323. package/dist/plot/scatter/ScatterPlot.svelte +623 -821
  324. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +9 -15
  325. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  326. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  327. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  328. package/dist/plot/scatter/binned-scatter-types.d.ts +6 -12
  329. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  330. package/dist/plot/scatter/index.d.ts +1 -1
  331. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  332. package/dist/plot/scatter/scatter-data.js +8 -7
  333. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +40 -60
  334. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  335. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +17 -15
  336. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  337. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +232 -234
  338. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  339. package/dist/plot/scatter-3d/Surface3D.svelte +9 -17
  340. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  341. package/dist/plot/sunburst/Sunburst.svelte +256 -338
  342. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  343. package/dist/plot/sunburst/index.d.ts +1 -1
  344. package/dist/plot/sunburst/index.js +2 -1
  345. package/dist/plot/sunburst/render.d.ts +2 -2
  346. package/dist/plot/sunburst/render.js +47 -22
  347. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  348. package/dist/plot/sunburst/sunburst.js +14 -4
  349. package/dist/plot/treemap/Treemap.svelte +907 -0
  350. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  351. package/dist/plot/treemap/index.d.ts +3 -0
  352. package/dist/plot/treemap/index.js +4 -0
  353. package/dist/plot/treemap/treemap.d.ts +26 -0
  354. package/dist/plot/treemap/treemap.js +99 -0
  355. package/dist/rdf/RdfPlot.svelte +22 -26
  356. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  357. package/dist/rdf/calc-rdf.js +4 -8
  358. package/dist/sanitize.js +14 -3
  359. package/dist/scene/SceneCamera.svelte +62 -0
  360. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  361. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  362. package/dist/scene/bind-renderer.svelte.js +22 -0
  363. package/dist/scene/index.d.ts +4 -0
  364. package/dist/scene/index.js +5 -0
  365. package/dist/scene/props.js +52 -0
  366. package/dist/scene/types.d.ts +26 -0
  367. package/dist/scene/types.js +1 -0
  368. package/dist/settings.d.ts +33 -11
  369. package/dist/settings.js +136 -51
  370. package/dist/spectral/Bands.svelte +231 -237
  371. package/dist/spectral/Bands.svelte.d.ts +3 -2
  372. package/dist/spectral/BandsAndDos.svelte +29 -29
  373. package/dist/spectral/BrillouinBandsDos.svelte +21 -29
  374. package/dist/spectral/Dos.svelte +75 -77
  375. package/dist/spectral/Dos.svelte.d.ts +2 -1
  376. package/dist/spectral/helpers.d.ts +9 -9
  377. package/dist/spectral/helpers.js +66 -70
  378. package/dist/state.svelte.d.ts +0 -7
  379. package/dist/state.svelte.js +5 -24
  380. package/dist/structure/Arrow.svelte +6 -21
  381. package/dist/structure/ArrowInstances.svelte +160 -0
  382. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  383. package/dist/structure/AtomLegend.svelte +115 -75
  384. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  385. package/dist/structure/Bond.svelte +31 -23
  386. package/dist/structure/CanvasTooltip.svelte +16 -3
  387. package/dist/structure/CellSelect.svelte +22 -29
  388. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  389. package/dist/structure/Cylinder.svelte +24 -40
  390. package/dist/structure/InstancedAtoms.svelte +114 -0
  391. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  392. package/dist/structure/Lattice.svelte +85 -149
  393. package/dist/structure/SiteLabels.svelte +122 -0
  394. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  395. package/dist/structure/Structure.svelte +725 -735
  396. package/dist/structure/Structure.svelte.d.ts +8 -16
  397. package/dist/structure/StructureCarousel.svelte +630 -0
  398. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  399. package/dist/structure/StructureControls.svelte +298 -325
  400. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  401. package/dist/structure/StructureExportPane.svelte +62 -168
  402. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  403. package/dist/structure/StructureInfoPane.svelte +77 -69
  404. package/dist/structure/StructureInfoPane.svelte.d.ts +6 -6
  405. package/dist/structure/StructureScene.svelte +758 -600
  406. package/dist/structure/StructureScene.svelte.d.ts +24 -20
  407. package/dist/structure/StructureViewport.svelte +386 -0
  408. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  409. package/dist/structure/atom-label-placement.d.ts +18 -0
  410. package/dist/structure/atom-label-placement.js +115 -0
  411. package/dist/structure/atom-properties.d.ts +3 -1
  412. package/dist/structure/atom-properties.js +115 -54
  413. package/dist/structure/bond-order-perception.js +2 -4
  414. package/dist/structure/bonding.d.ts +12 -2
  415. package/dist/structure/bonding.js +172 -73
  416. package/dist/structure/edit-history.d.ts +6 -0
  417. package/dist/structure/edit-history.js +27 -0
  418. package/dist/structure/export.d.ts +25 -4
  419. package/dist/structure/export.js +103 -153
  420. package/dist/structure/format-detect.d.ts +1 -0
  421. package/dist/structure/format-detect.js +22 -0
  422. package/dist/structure/geometry.d.ts +9 -0
  423. package/dist/structure/geometry.js +27 -0
  424. package/dist/structure/index.d.ts +18 -1
  425. package/dist/structure/index.js +15 -2
  426. package/dist/structure/measure.d.ts +1 -1
  427. package/dist/structure/measure.js +6 -12
  428. package/dist/structure/parse.d.ts +5 -3
  429. package/dist/structure/parse.js +551 -567
  430. package/dist/structure/partial-occupancy.d.ts +0 -1
  431. package/dist/structure/partial-occupancy.js +5 -3
  432. package/dist/structure/pbc.d.ts +1 -1
  433. package/dist/structure/pbc.js +204 -51
  434. package/dist/structure/polyhedra.d.ts +40 -0
  435. package/dist/structure/polyhedra.js +587 -0
  436. package/dist/structure/site.d.ts +4 -0
  437. package/dist/structure/site.js +1 -0
  438. package/dist/structure/supercell.d.ts +1 -2
  439. package/dist/structure/supercell.js +10 -15
  440. package/dist/structure/validation.js +5 -6
  441. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  442. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  443. package/dist/symmetry/SymmetryElements.svelte +350 -0
  444. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  445. package/dist/symmetry/SymmetryStats.svelte +142 -49
  446. package/dist/symmetry/WyckoffTable.svelte +58 -16
  447. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  448. package/dist/symmetry/cell-transform.js +8 -14
  449. package/dist/symmetry/index.d.ts +15 -4
  450. package/dist/symmetry/index.js +308 -81
  451. package/dist/symmetry/spacegroups.d.ts +5 -1
  452. package/dist/symmetry/spacegroups.js +18 -3
  453. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  454. package/dist/symmetry/symmetry-elements.js +521 -0
  455. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  456. package/dist/symmetry/wyckoff-db.js +87 -0
  457. package/dist/table/HeatmapTable.svelte +1104 -378
  458. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  459. package/dist/table/ToggleMenu.svelte +5 -12
  460. package/dist/table/index.d.ts +21 -6
  461. package/dist/table/index.js +34 -21
  462. package/dist/theme/ThemeControl.svelte +16 -8
  463. package/dist/theme/index.d.ts +1 -5
  464. package/dist/theme/index.js +4 -10
  465. package/dist/theme/themes.mjs +14 -7
  466. package/dist/tooltip/KCoords.svelte +4 -1
  467. package/dist/tooltip/TooltipContent.svelte +2 -5
  468. package/dist/trajectory/Trajectory.svelte +556 -352
  469. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  470. package/dist/trajectory/TrajectoryError.svelte +11 -8
  471. package/dist/trajectory/TrajectoryExportPane.svelte +28 -54
  472. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  473. package/dist/trajectory/TrajectoryInfoPane.svelte +88 -99
  474. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  475. package/dist/trajectory/constants.js +6 -2
  476. package/dist/trajectory/extract.js +73 -71
  477. package/dist/trajectory/format-detect.d.ts +0 -1
  478. package/dist/trajectory/format-detect.js +13 -17
  479. package/dist/trajectory/frame-reader.d.ts +2 -1
  480. package/dist/trajectory/frame-reader.js +74 -136
  481. package/dist/trajectory/helpers.d.ts +12 -2
  482. package/dist/trajectory/helpers.js +68 -37
  483. package/dist/trajectory/index.d.ts +1 -0
  484. package/dist/trajectory/index.js +3 -0
  485. package/dist/trajectory/parse/ase.d.ts +9 -1
  486. package/dist/trajectory/parse/ase.js +47 -32
  487. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  488. package/dist/trajectory/parse/diagnostics.js +14 -0
  489. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  490. package/dist/trajectory/parse/h5-utils.js +109 -0
  491. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  492. package/dist/trajectory/parse/hdf5.js +116 -106
  493. package/dist/trajectory/parse/index.d.ts +3 -4
  494. package/dist/trajectory/parse/index.js +68 -119
  495. package/dist/trajectory/parse/lammps.d.ts +0 -2
  496. package/dist/trajectory/parse/lammps.js +14 -16
  497. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  498. package/dist/trajectory/parse/pymatgen.js +74 -0
  499. package/dist/trajectory/parse/vasp.js +13 -9
  500. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  501. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  502. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  503. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  504. package/dist/trajectory/parse/xyz.d.ts +9 -21
  505. package/dist/trajectory/parse/xyz.js +38 -39
  506. package/dist/trajectory/plotting.d.ts +8 -10
  507. package/dist/trajectory/plotting.js +102 -127
  508. package/dist/utils.d.ts +4 -0
  509. package/dist/utils.js +8 -1
  510. package/dist/xrd/XrdPlot.svelte +56 -85
  511. package/dist/xrd/broadening.d.ts +2 -1
  512. package/dist/xrd/broadening.js +2 -1
  513. package/dist/xrd/calc-xrd.js +8 -15
  514. package/dist/xrd/index.d.ts +2 -2
  515. package/dist/xrd/parse.d.ts +0 -1
  516. package/dist/xrd/parse.js +56 -73
  517. package/package.json +77 -36
  518. package/dist/api/mp.d.ts +0 -6
  519. package/dist/api/mp.js +0 -22
  520. package/dist/element/data.json +0 -11864
  521. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  522. package/dist/fermi-surface/marching-cubes.js +0 -2
  523. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  524. package/dist/plot/core/hover-lock.svelte.js +0 -45
  525. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  526. package/dist/structure/label-placement.d.ts +0 -14
  527. package/dist/structure/label-placement.js +0 -72
@@ -1,5 +1,4 @@
1
1
  import type { Site } from './';
2
- export declare const PARTIAL_OCCUPANCY_SLICE_GAP_RAD = 0.001;
3
2
  export type RenderSite = {
4
3
  site_idx: number;
5
4
  site: Site;
@@ -1,4 +1,4 @@
1
- export const PARTIAL_OCCUPANCY_SLICE_GAP_RAD = 1e-3;
1
+ const PARTIAL_OCCUPANCY_SLICE_GAP_RAD = 1e-3;
2
2
  const OCCUPANCY_EPS = 1e-6;
3
3
  const MIN_PHI_LENGTH = 1e-4;
4
4
  const MERGE_DISTANCE_TOLERANCE = 1e-8;
@@ -60,7 +60,8 @@ export const PARTIAL_OCCUPANCY_CAP_ARC = {
60
60
  };
61
61
  export const merge_split_partial_sites = (sites, hidden_elements = new Set()) => {
62
62
  const grouped_indices = group_split_partial_indices(sites, hidden_elements);
63
- return build_render_sites(sites, grouped_indices.non_grouped_site_indices, grouped_indices.grouped_site_indices);
63
+ const { non_grouped_site_indices, grouped_site_indices } = grouped_indices;
64
+ return build_render_sites(sites, non_grouped_site_indices, grouped_site_indices);
64
65
  };
65
66
  export const compute_slice_geometry = (visible_species, slice_gap_rad = PARTIAL_OCCUPANCY_SLICE_GAP_RAD) => {
66
67
  if (visible_species.length === 0)
@@ -72,7 +73,8 @@ export const compute_slice_geometry = (visible_species, slice_gap_rad = PARTIAL_
72
73
  element,
73
74
  occu: occu * occupancy_scale_factor,
74
75
  }));
75
- const normalized_total_occupancy = normalized_species.reduce((occupancy_sum, { occu }) => occupancy_sum + occu, 0);
76
+ // Sum of scaled occupancies equals total * scale (avoids a second O(n) pass)
77
+ const normalized_total_occupancy = total_visible_occupancy * occupancy_scale_factor;
76
78
  const has_vacancy_gap = normalized_total_occupancy < 1 - OCCUPANCY_EPS;
77
79
  const last_visible_species_idx = normalized_species.length - 1;
78
80
  let start_angle = 0;
@@ -5,5 +5,5 @@ export declare const wrap_frac_coord: (coord: number) => number;
5
5
  export declare const wrap_to_unit_cell: (frac: Vec3) => Vec3;
6
6
  export declare function find_image_atoms(structure: ParsedStructure, { tolerance }?: {
7
7
  tolerance?: number;
8
- }): [number, Vec3, Vec3][];
8
+ }): [number, Vec3, Vec3, boolean?][];
9
9
  export declare function get_pbc_image_sites(...args: Parameters<typeof find_image_atoms>): ParsedStructure;
@@ -1,6 +1,21 @@
1
1
  import * as math from '../math';
2
+ import { element_lookup, get_majority_element, has_framework_potential, is_spectator_center, pack_cell_key, } from './bonding';
3
+ // Distance slack added to the covalent-radii sum when deciding whether a
4
+ // candidate image atom bonds to a base atom (VESTA-like bond search criterion)
5
+ const BOND_SLACK = 0.4; // Å
6
+ // Below this separation two sites are overlapping copies, not a bond (matches
7
+ // the min_bond_dist default in bonding.ts)
8
+ const MIN_BOND_DIST = 0.4; // Å
2
9
  // Wrap a single fractional coordinate to [0, 1), clamping near-1 values to 0
3
10
  // and rounding to 15 digits to suppress floating-point noise.
11
+ // NOTE on epsilon: this is the tightest of three intentionally different wrap
12
+ // helpers. Coordinates here come almost straight from file parsing, so float
13
+ // error is tiny and a 1e-10 snap + toFixed(15) preserves maximal precision.
14
+ // Compare wrap_frac @1e-9 [[src/lib/symmetry/index.ts:80]] (post moyo
15
+ // standardization + matrix transforms) and wrap_point @1e-8
16
+ // [[src/lib/symmetry/symmetry-elements.ts:214]] (feeds symmetry-element dedup
17
+ // keys). Do not unify: loosening this epsilon changes snapping near cell
18
+ // boundaries for parsed structures.
4
19
  export const wrap_frac_coord = (coord) => {
5
20
  const wrapped = coord - Math.floor(coord);
6
21
  if (wrapped >= 1 - 1e-10)
@@ -13,42 +28,36 @@ export const wrap_to_unit_cell = (frac) => [
13
28
  wrap_frac_coord(frac[1]),
14
29
  wrap_frac_coord(frac[2]),
15
30
  ];
31
+ // Trajectory-like data: >10% of atoms far outside the unit cell. Image-atom
32
+ // generation is skipped for such structures.
33
+ const is_scattered_trajectory = (sites) => {
34
+ const atoms_outside_cell = sites.filter(({ abc }) => abc.some((coord) => coord < -0.1 || coord > 1.1));
35
+ return atoms_outside_cell.length > sites.length * 0.1;
36
+ };
16
37
  export function find_image_atoms(structure, { tolerance } = {}) {
17
- // Find image atoms for PBC. Returns [atom_idx, image_xyz, image_abc] tuples.
18
- // Skips image generation for trajectory data with scattered atoms.
38
+ // Find image atoms for PBC. Returns [atom_idx, image_xyz, image_abc, is_completion?]
39
+ // tuples; is_completion marks phase-2 images that only complete bonds / coordination
40
+ // polyhedra at cell faces (renderers may hide them). Skips scattered trajectories.
19
41
  if (!structure.lattice || !structure.sites || structure.sites.length === 0)
20
42
  return [];
21
- // Skip trajectory data (>10% atoms outside cell)
22
- const atoms_outside_cell = structure.sites.filter(({ abc }) => abc.some((coord) => coord < -0.1 || coord > 1.1));
23
- // Skip image generation for trajectory data (>10% atoms outside cell)
24
- if (atoms_outside_cell.length > structure.sites.length * 0.1) {
43
+ if (is_scattered_trajectory(structure.sites))
25
44
  return [];
26
- }
27
- // Check if this is a supercell to correctly identify external boundaries correctly
28
45
  const image_sites = [];
29
46
  const lattice_vecs = structure.lattice.matrix;
30
- // Scale zero-displacement threshold by lattice length scale to avoid hard-coded magic numbers
31
- const lattice_norm = Math.max(Math.hypot(...lattice_vecs[0]), Math.hypot(...lattice_vecs[1]), Math.hypot(...lattice_vecs[2]));
32
- // Threshold to filter out floating-point-identical (zero-displacement) images; rarely triggers but guards against edge cases
47
+ const frac_to_cart = math.create_frac_to_cart(lattice_vecs);
48
+ const vec_lens = lattice_vecs.map((vec) => Math.hypot(...vec));
49
+ // Scale zero-displacement threshold by lattice length scale to avoid magic numbers
50
+ const lattice_norm = Math.max(...vec_lens);
33
51
  const displacement_eps_sq = (1e-10 * lattice_norm) ** 2;
34
- // Tolerances determine which atoms are near cell boundaries and need image generation
35
- // Use provided tolerance or default to physical tolerance of 0.5 Angstroms converted to fractional
36
- // This prevents excessive image generation for large unit cells (e.g. MOFs) where 0.05 fractional is huge
37
- const PHYSICAL_TOLERANCE = 0.5; // Angstroms
38
- const tolerances = [0, 1, 2].map((dim) => {
39
- if (tolerance !== undefined)
40
- return tolerance;
41
- const vec_len = Math.hypot(...lattice_vecs[dim]);
42
- // zero-length lattice vector should not occur in valid structures,
43
- // but fall back to 0.05 fractional tolerance if it does
44
- return vec_len > 0 ? PHYSICAL_TOLERANCE / vec_len : 0.05;
45
- });
46
- // Respect per-axis periodicity: no images across non-periodic (vacuum) directions
47
- const pbc = structure.lattice.pbc ?? [true, true, true];
52
+ // Boundary tolerance: physical 0.5 Å as fractional per-axis, so large cells (MOFs)
53
+ // don't over-generate (a flat 0.05 fractional would be huge there)
54
+ const PHYSICAL_TOLERANCE = 0.5; // Å
55
+ const tolerances = vec_lens.map((vec_len) => tolerance ?? (vec_len > 0 ? PHYSICAL_TOLERANCE / vec_len : 0.05));
56
+ const pbc = structure.lattice.pbc ?? [true, true, true]; // no images across vacuum
57
+ // Phase 1: true periodic copies of atoms within `tolerance` of a cell face (bond
58
+ // lengths preserved, rather than clamping the copy to the cell face)
48
59
  for (const [idx, site] of structure.sites.entries()) {
49
- // Find edge dimensions and translation directions
50
60
  const edge_dims = [];
51
- // Find boundary dimensions
52
61
  for (let dim = 0; dim < 3; dim++) {
53
62
  if (!pbc[dim])
54
63
  continue;
@@ -59,10 +68,9 @@ export function find_image_atoms(structure, { tolerance } = {}) {
59
68
  if (Math.abs(coord - 1) < dim_tolerance)
60
69
  edge_dims.push({ dim, direction: -1 });
61
70
  }
62
- // Generate all translation combinations
71
+ // Generate all translation combinations; if both +1 and -1 are selected for a dim the
72
+ // net shift is zero and we skip (yields no image).
63
73
  for (let mask = 1; mask < 1 << edge_dims.length; mask++) {
64
- // Track selected translation per dimension. If both +1 and -1 are selected for a dim,
65
- // the net shift is zero and we skip because it yields no image.
66
74
  const selected_shift = [0, 0, 0];
67
75
  for (let bit = 0; bit < edge_dims.length; bit++) {
68
76
  if (mask & (1 << bit)) {
@@ -70,25 +78,18 @@ export function find_image_atoms(structure, { tolerance } = {}) {
70
78
  selected_shift[dim] += direction;
71
79
  }
72
80
  }
73
- // Early skip if no net shift across any dimension
74
81
  if (selected_shift.every((val) => val === 0))
75
82
  continue;
76
- // Build fractional coordinates by applying the integer translation
77
- // This ensures the image is a true periodic copy (preserving bond lengths)
78
- // rather than clamping it to the cell face.
83
+ const [s_a, s_b, s_c] = site.abc;
79
84
  const img_abc = [
80
- site.abc[0] + selected_shift[0],
81
- site.abc[1] + selected_shift[1],
82
- site.abc[2] + selected_shift[2],
85
+ s_a + selected_shift[0],
86
+ s_b + selected_shift[1],
87
+ s_c + selected_shift[2],
83
88
  ];
84
- // If no dimension actually shifted, continue
85
- if (img_abc[0] === site.abc[0] &&
86
- img_abc[1] === site.abc[1] &&
87
- img_abc[2] === site.abc[2])
89
+ if (img_abc[0] === s_a && img_abc[1] === s_b && img_abc[2] === s_c)
88
90
  continue;
89
- // Compute xyz from img_abc to ensure consistency
90
- const img_xyz = math.add(math.scale(lattice_vecs[0], img_abc[0]), math.scale(lattice_vecs[1], img_abc[1]), math.scale(lattice_vecs[2], img_abc[2]));
91
- // Skip zero-displacement images (should not happen, guards against FP edge cases)
91
+ const img_xyz = frac_to_cart(img_abc);
92
+ // Skip zero-displacement images (guards against FP edge cases)
92
93
  const displacement = math.subtract(img_xyz, site.xyz);
93
94
  const displacement_len_sq = displacement.reduce((sum, val) => sum + val * val, 0);
94
95
  if (displacement_len_sq < displacement_eps_sq)
@@ -96,6 +97,157 @@ export function find_image_atoms(structure, { tolerance } = {}) {
96
97
  image_sites.push([idx, img_xyz, img_abc]);
97
98
  }
98
99
  }
100
+ // Per-site element data for the phase-2 completion pass. present_elements is the tiny
101
+ // composition (so has_framework_potential doesn't re-scan every site in big supercells).
102
+ const site_elements = [];
103
+ const site_radii = [];
104
+ const site_en = [];
105
+ const site_is_metal = [];
106
+ const present_elements = new Set();
107
+ let max_radius = 0;
108
+ for (const site of structure.sites) {
109
+ const elem = get_majority_element(site);
110
+ const data = elem === null ? undefined : element_lookup.get(elem);
111
+ const radius = data?.covalent_radius ?? null;
112
+ site_elements.push(elem);
113
+ if (elem !== null)
114
+ present_elements.add(elem);
115
+ site_radii.push(radius);
116
+ site_en.push(data?.electronegativity ?? null);
117
+ site_is_metal.push(data?.metal === true);
118
+ if (radius !== null && radius > max_radius)
119
+ max_radius = radius;
120
+ }
121
+ // Skip spectator A-site cations (Li/Na, heavy alkaline earths) when a framework cation
122
+ // is present: they render no polyhedron, so completing their shells floats coordination
123
+ // groups (e.g. a PO4 around a corner Li) beyond the cell. Purely ionic binaries (NaCl)
124
+ // keep theirs. Note: a spectator force-included as a polyhedra center (compute_polyhedra's
125
+ // included_center_elements) is still skipped here, so its boundary polyhedra truncate at
126
+ // cell faces - accepted to keep image generation independent of render-only settings.
127
+ const skip_spectators = has_framework_potential(present_elements);
128
+ const site_skipped = site_elements.map((elem) => skip_spectators && elem !== null && is_spectator_center(elem));
129
+ // Phase 2: anion images that complete coordination polyhedra / bonds at cell faces.
130
+ // Phase 1's ~0.5 Å face tolerance misses anions just beyond a face that still bond a
131
+ // cation near it, truncating boundary polyhedra. We add ONLY such images: a candidate
132
+ // must be a polyhedron vertex (non-metal/metalloid, like is_anion_vertex in polyhedra.ts)
133
+ // AND strictly more electronegative than the anchor it bonds. Metals, intermetallics,
134
+ // equal-EN networks and cation copies get none, keeping renders minimal.
135
+ // Min anchor EN: a candidate only completes a cation's shell if more electronegative
136
+ // than it. Over non-skipped anchors only, so skipped spectators can't loosen the filter.
137
+ let min_anchor_en = Infinity;
138
+ for (let idx = 0; idx < structure.sites.length; idx++) {
139
+ if (site_skipped[idx])
140
+ continue;
141
+ const en = site_en[idx];
142
+ if (site_radii[idx] !== null && en !== null && en < min_anchor_en)
143
+ min_anchor_en = en;
144
+ }
145
+ const max_bond_dist = 2 * max_radius + BOND_SLACK;
146
+ if (max_bond_dist > BOND_SLACK && min_anchor_en < Infinity) {
147
+ // Per-axis fractional bond reach via perpendicular cell heights (correct for oblique
148
+ // cells; 0 for degenerate cells → no images). The + face tolerance covers phase-1
149
+ // anchors sitting slightly outside the cell.
150
+ const pad_per_axis = math.frac_cutoff_per_axis(lattice_vecs, max_bond_dist + PHYSICAL_TOLERANCE);
151
+ // Bond-test anchors = base atoms + phase-1 boundary images, so every displayed
152
+ // boundary cation gets its shell completed (VESTA-like; e.g. all 8 rutile corners).
153
+ const anchor_positions = structure.sites.map((site) => site.xyz);
154
+ const anchor_radii = [...site_radii];
155
+ const anchor_en = [...site_en];
156
+ const anchor_skipped = [...site_skipped];
157
+ for (const [src_idx, img_xyz] of image_sites) {
158
+ anchor_positions.push(img_xyz);
159
+ anchor_radii.push(site_radii[src_idx]);
160
+ anchor_en.push(site_en[src_idx]);
161
+ anchor_skipped.push(site_skipped[src_idx]);
162
+ }
163
+ // Spatial grid over anchors for the bond check (integer-packed keys: this
164
+ // grid is probed 27x per candidate image in the loop below)
165
+ const grid = new Map();
166
+ for (const [idx, pos] of anchor_positions.entries()) {
167
+ const key = pack_cell_key(Math.floor(pos[0] / max_bond_dist), Math.floor(pos[1] / max_bond_dist), Math.floor(pos[2] / max_bond_dist));
168
+ const cell = grid.get(key);
169
+ if (cell)
170
+ cell.push(idx);
171
+ else
172
+ grid.set(key, [idx]);
173
+ }
174
+ // True when the candidate (an anion image) bonds a strictly less electronegative
175
+ // anchor, i.e. completes some cation's coordination shell
176
+ const completes_cation_shell = (pos, radius, en) => {
177
+ const [cx, cy, cz] = pos.map((coord) => Math.floor(coord / max_bond_dist));
178
+ for (let dx = -1; dx <= 1; dx++) {
179
+ for (let dy = -1; dy <= 1; dy++) {
180
+ for (let dz = -1; dz <= 1; dz++) {
181
+ for (const anchor_idx of grid.get(pack_cell_key(cx + dx, cy + dy, cz + dz)) ??
182
+ []) {
183
+ if (anchor_skipped[anchor_idx])
184
+ continue;
185
+ const anchor_radius = anchor_radii[anchor_idx];
186
+ const anchor_electroneg = anchor_en[anchor_idx];
187
+ if (anchor_radius === null)
188
+ continue;
189
+ if (anchor_electroneg === null || en <= anchor_electroneg)
190
+ continue;
191
+ const dist = math.euclidean_dist(pos, anchor_positions[anchor_idx]);
192
+ if (dist > MIN_BOND_DIST && dist <= radius + anchor_radius + BOND_SLACK) {
193
+ return true;
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ return false;
200
+ };
201
+ // Dedupe against phase-1 images via (site, integer shift) keys
202
+ const seen_images = new Set(image_sites.map(([idx, _xyz, img_abc]) => `${idx}|${img_abc
203
+ .map((coord, axis) => Math.round(coord - structure.sites[idx].abc[axis]))
204
+ .join(`,`)}`));
205
+ for (const [idx, site] of structure.sites.entries()) {
206
+ const radius = site_radii[idx];
207
+ const en = site_en[idx];
208
+ // Skip candidates that could never be a polyhedron vertex: metals (e.g. Fe/Ni in
209
+ // Al-Fe-Ni intermetallics) and anything not strictly more electronegative than at
210
+ // least one anchor (covers elemental/equal-EN structures and all cations)
211
+ if (radius === null || en === null || en <= min_anchor_en)
212
+ continue;
213
+ if (site_is_metal[idx])
214
+ continue;
215
+ // Per-axis shifts that could land a copy of this atom within bonding reach of the
216
+ // cell: {0} plus +1/-1 when the atom is within max_bond_dist of the boundary
217
+ const axis_shifts = [0, 1, 2].map((axis) => {
218
+ if (!pbc[axis])
219
+ return [0];
220
+ const pad = pad_per_axis[axis];
221
+ const shifts = [0];
222
+ if (site.abc[axis] < pad)
223
+ shifts.push(1);
224
+ if (site.abc[axis] > 1 - pad)
225
+ shifts.push(-1);
226
+ return shifts;
227
+ });
228
+ for (const shift_a of axis_shifts[0]) {
229
+ for (const shift_b of axis_shifts[1]) {
230
+ for (const shift_c of axis_shifts[2]) {
231
+ if (shift_a === 0 && shift_b === 0 && shift_c === 0)
232
+ continue;
233
+ const key = `${idx}|${shift_a},${shift_b},${shift_c}`;
234
+ if (seen_images.has(key))
235
+ continue;
236
+ const img_abc = [
237
+ site.abc[0] + shift_a,
238
+ site.abc[1] + shift_b,
239
+ site.abc[2] + shift_c,
240
+ ];
241
+ const img_xyz = frac_to_cart(img_abc);
242
+ if (!completes_cation_shell(img_xyz, radius, en))
243
+ continue;
244
+ seen_images.add(key);
245
+ image_sites.push([idx, img_xyz, img_abc, true]);
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
99
251
  return image_sites;
100
252
  }
101
253
  // Return structure with image atoms added
@@ -104,23 +256,24 @@ export function get_pbc_image_sites(...args) {
104
256
  if (!structure || !structure.sites || structure.sites.length === 0) {
105
257
  return structure;
106
258
  }
107
- // Check for trajectory data
108
- const atoms_outside_cell = structure.sites.filter((site) => site.abc.some((coord) => coord < -0.1 || coord > 1.1));
109
259
  // Return trajectory data unchanged
110
- if (atoms_outside_cell.length > structure.sites.length * 0.1) {
260
+ if (is_scattered_trajectory(structure.sites))
111
261
  return structure;
112
- }
113
262
  // Add image atoms to regular crystal structures
114
263
  const image_sites = find_image_atoms(...args);
115
264
  const imaged_struct = { ...structure, sites: [...structure.sites] };
116
- // Add image atoms as new sites using provided (xyz, abc) from find_image_atoms
117
- for (const [site_idx, img_xyz, img_abc] of image_sites) {
265
+ for (const [site_idx, img_xyz, img_abc, is_completion] of image_sites) {
118
266
  const orig_site = structure.sites[site_idx];
119
267
  imaged_struct.sites.push({
120
268
  ...orig_site,
121
269
  abc: img_abc,
122
270
  xyz: img_xyz,
123
- properties: { ...orig_site.properties, orig_site_idx: site_idx },
271
+ properties: {
272
+ ...orig_site.properties,
273
+ orig_site_idx: site_idx,
274
+ // phase-2 images only complete bonds/polyhedra - hidden when neither renders
275
+ ...(is_completion ? { completion_image: true } : {}),
276
+ },
124
277
  });
125
278
  }
126
279
  return imaged_struct;
@@ -0,0 +1,40 @@
1
+ import type { ElementSymbol } from '../element';
2
+ import type { Vec3 } from '../math';
3
+ import type { AnyStructure, BondPair } from './';
4
+ export type PolyhedraColorMode = `vertex` | `center` | `uniform`;
5
+ export interface PolyhedraOptions {
6
+ min_neighbors?: number;
7
+ max_neighbors?: number;
8
+ excluded_center_elements?: readonly string[];
9
+ included_center_elements?: readonly string[];
10
+ electronegativity_margin?: number;
11
+ distance_factor?: number;
12
+ weak_bond_norm?: number;
13
+ volume_eps?: number;
14
+ }
15
+ export interface ConvexHullResult {
16
+ vertices: Vec3[];
17
+ input_idxs: number[];
18
+ faces: [number, number, number][];
19
+ volume: number;
20
+ }
21
+ export interface Polyhedron {
22
+ center_site_idx: number;
23
+ center_orig_idx: number;
24
+ center_element: ElementSymbol;
25
+ vertices: Vec3[];
26
+ vertex_site_idxs: number[];
27
+ faces: [number, number, number][];
28
+ volume: number;
29
+ }
30
+ export interface MergedPolyhedraBuffers {
31
+ positions: Float32Array;
32
+ colors: Float32Array;
33
+ edge_positions: Float32Array;
34
+ triangle_count: number;
35
+ edge_count: number;
36
+ }
37
+ export declare function convex_hull_3d(points: readonly Vec3[], eps_scale?: number): ConvexHullResult;
38
+ export declare function build_adjacency(bonds: readonly BondPair[]): Map<number, Set<number>>;
39
+ export declare function compute_polyhedra(structure: AnyStructure, bonds: readonly BondPair[], options?: PolyhedraOptions): Polyhedron[];
40
+ export declare function merge_polyhedra_buffers(polyhedra: readonly Polyhedron[], get_vertex_color: (poly: Polyhedron, vertex_idx: number) => string, coplanar_tol?: number): MergedPolyhedraBuffers;