matterviz 0.4.0 → 0.4.1

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 (326) hide show
  1. package/dist/brillouin/BrillouinZone.svelte +68 -145
  2. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -14
  3. package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
  4. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  5. package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
  6. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  7. package/dist/brillouin/BrillouinZoneScene.svelte +49 -203
  8. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  9. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  10. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  11. package/dist/brillouin/compute.d.ts +2 -0
  12. package/dist/brillouin/compute.js +80 -77
  13. package/dist/brillouin/geometry.d.ts +8 -0
  14. package/dist/brillouin/geometry.js +57 -0
  15. package/dist/brillouin/index.d.ts +2 -0
  16. package/dist/brillouin/index.js +2 -0
  17. package/dist/brillouin/types.d.ts +2 -2
  18. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +100 -191
  20. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  21. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +176 -464
  22. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  23. package/dist/chempot-diagram/color.d.ts +3 -6
  24. package/dist/chempot-diagram/color.js +5 -5
  25. package/dist/chempot-diagram/compute.d.ts +3 -3
  26. package/dist/chempot-diagram/compute.js +3 -1
  27. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  28. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  29. package/dist/chempot-diagram/export.d.ts +47 -0
  30. package/dist/chempot-diagram/export.js +133 -0
  31. package/dist/chempot-diagram/index.d.ts +1 -0
  32. package/dist/chempot-diagram/index.js +1 -0
  33. package/dist/chempot-diagram/pointer.d.ts +0 -10
  34. package/dist/chempot-diagram/pointer.js +4 -4
  35. package/dist/chempot-diagram/types.d.ts +3 -3
  36. package/dist/colors/index.js +2 -2
  37. package/dist/composition/FormulaFilter.svelte +6 -5
  38. package/dist/composition/PieChart.svelte +5 -5
  39. package/dist/composition/chem-sys.js +3 -2
  40. package/dist/composition/format.js +3 -2
  41. package/dist/composition/parse.d.ts +0 -1
  42. package/dist/composition/parse.js +17 -19
  43. package/dist/controls.d.ts +1 -0
  44. package/dist/controls.js +0 -1
  45. package/dist/convex-hull/ConvexHull.svelte +8 -10
  46. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  47. package/dist/convex-hull/ConvexHull2D.svelte +94 -175
  48. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  49. package/dist/convex-hull/ConvexHull3D.svelte +176 -680
  50. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  51. package/dist/convex-hull/ConvexHull4D.svelte +180 -680
  52. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  53. package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
  54. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  55. package/dist/convex-hull/ConvexHullControls.svelte +88 -7
  56. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  57. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  58. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  59. package/dist/convex-hull/ConvexHullStats.svelte +29 -168
  60. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  61. package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
  62. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  63. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  64. package/dist/convex-hull/barycentric-coords.js +6 -33
  65. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  66. package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
  67. package/dist/convex-hull/helpers.d.ts +39 -7
  68. package/dist/convex-hull/helpers.js +154 -69
  69. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  70. package/dist/convex-hull/hull-state.svelte.js +124 -0
  71. package/dist/convex-hull/index.d.ts +9 -7
  72. package/dist/convex-hull/index.js +7 -2
  73. package/dist/convex-hull/thermodynamics.js +91 -920
  74. package/dist/convex-hull/types.d.ts +12 -4
  75. package/dist/convex-hull/types.js +12 -0
  76. package/dist/coordination/CoordinationBarPlot.svelte +4 -11
  77. package/dist/element/BohrAtom.svelte +2 -1
  78. package/dist/element/ElementTile.svelte.d.ts +1 -1
  79. package/dist/element/index.d.ts +4 -0
  80. package/dist/element/index.js +18 -0
  81. package/dist/feedback/DragOverlay.svelte +3 -1
  82. package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
  83. package/dist/feedback/StatusMessage.svelte +13 -3
  84. package/dist/fermi-surface/FermiSurface.svelte +67 -146
  85. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
  86. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  87. package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -224
  88. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  89. package/dist/fermi-surface/compute.js +11 -10
  90. package/dist/fermi-surface/export.js +4 -15
  91. package/dist/fermi-surface/index.d.ts +0 -1
  92. package/dist/fermi-surface/index.js +0 -1
  93. package/dist/fermi-surface/parse.d.ts +1 -1
  94. package/dist/fermi-surface/parse.js +64 -75
  95. package/dist/fermi-surface/types.d.ts +2 -2
  96. package/dist/heatmap-matrix/HeatmapMatrix.svelte +55 -40
  97. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
  98. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
  99. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  100. package/dist/heatmap-matrix/index.d.ts +3 -2
  101. package/dist/index.d.ts +1 -0
  102. package/dist/index.js +1 -0
  103. package/dist/io/ExportPane.svelte +166 -0
  104. package/dist/io/ExportPane.svelte.d.ts +17 -0
  105. package/dist/io/decompress.js +1 -2
  106. package/dist/io/export.d.ts +5 -1
  107. package/dist/io/export.js +32 -28
  108. package/dist/io/fetch.d.ts +2 -1
  109. package/dist/io/file-drop.d.ts +7 -0
  110. package/dist/io/file-drop.js +13 -0
  111. package/dist/io/index.d.ts +2 -0
  112. package/dist/io/index.js +10 -0
  113. package/dist/io/types.d.ts +13 -0
  114. package/dist/isosurface/parse.js +46 -44
  115. package/dist/labels.js +1 -1
  116. package/dist/layout/FullscreenButton.svelte +33 -0
  117. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  118. package/dist/layout/FullscreenToggle.svelte +8 -14
  119. package/dist/layout/ViewerChrome.svelte +116 -0
  120. package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
  121. package/dist/layout/fullscreen.d.ts +4 -0
  122. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  123. package/dist/layout/fullscreen.svelte.js +37 -0
  124. package/dist/layout/index.d.ts +3 -0
  125. package/dist/layout/index.js +3 -0
  126. package/dist/math.d.ts +7 -3
  127. package/dist/math.js +18 -21
  128. package/dist/overlays/index.d.ts +4 -0
  129. package/dist/periodic-table/PeriodicTable.svelte +9 -8
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  131. package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  133. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  134. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
  136. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  137. package/dist/phase-diagram/colors.js +1 -1
  138. package/dist/phase-diagram/parse.d.ts +2 -1
  139. package/dist/plot/bar/BarPlot.svelte +79 -316
  140. package/dist/plot/bar/BarPlot.svelte.d.ts +7 -15
  141. package/dist/plot/bar/BarPlotControls.svelte.d.ts +1 -1
  142. package/dist/plot/bar/SpacegroupBarPlot.svelte +2 -1
  143. package/dist/plot/box/BoxPlot.svelte +76 -246
  144. package/dist/plot/box/BoxPlot.svelte.d.ts +4 -3
  145. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  146. package/dist/plot/box/Violin.svelte.d.ts +1 -1
  147. package/dist/plot/box/box-plot.d.ts +3 -2
  148. package/dist/plot/box/box-plot.js +5 -2
  149. package/dist/plot/box/kde.d.ts +2 -1
  150. package/dist/plot/box/kde.js +4 -4
  151. package/dist/plot/core/auto-place.d.ts +1 -1
  152. package/dist/plot/core/auto-place.js +4 -1
  153. package/dist/plot/core/components/ColorBar.svelte +5 -5
  154. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  155. package/dist/plot/core/components/Line.svelte +3 -2
  156. package/dist/plot/core/components/Line.svelte.d.ts +3 -2
  157. package/dist/plot/core/components/PlotAxis.svelte +2 -1
  158. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  159. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  160. package/dist/plot/core/components/ReferenceLine3D.svelte +2 -2
  161. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  162. package/dist/plot/core/components/ReferencePlane.svelte +2 -2
  163. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  164. package/dist/plot/core/data-cleaning.js +18 -18
  165. package/dist/plot/core/fill-utils.d.ts +4 -3
  166. package/dist/plot/core/fill-utils.js +6 -3
  167. package/dist/plot/core/interactions.d.ts +5 -1
  168. package/dist/plot/core/interactions.js +14 -0
  169. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  170. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  171. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  172. package/dist/plot/core/placed-tween.svelte.js +68 -0
  173. package/dist/plot/core/reference-line.d.ts +10 -10
  174. package/dist/plot/core/reference-line.js +6 -6
  175. package/dist/plot/core/scales.d.ts +17 -25
  176. package/dist/plot/core/scales.js +10 -8
  177. package/dist/plot/core/svg.d.ts +2 -1
  178. package/dist/plot/core/types.d.ts +18 -7
  179. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  180. package/dist/plot/core/utils/label-placement.js +3 -3
  181. package/dist/plot/core/utils.d.ts +2 -1
  182. package/dist/plot/histogram/Histogram.svelte +77 -314
  183. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  184. package/dist/plot/sankey/Sankey.svelte +2 -5
  185. package/dist/plot/sankey/Sankey.svelte.d.ts +1 -1
  186. package/dist/plot/sankey/sankey.js +3 -1
  187. package/dist/plot/scatter/BinnedScatterPlot.svelte +3 -5
  188. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +4 -4
  189. package/dist/plot/scatter/ScatterPlot.svelte +160 -450
  190. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +7 -15
  191. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  192. package/dist/plot/scatter/binned-scatter-types.d.ts +4 -11
  193. package/dist/plot/scatter/index.d.ts +1 -1
  194. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +15 -26
  195. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  196. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +9 -10
  197. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  198. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +122 -121
  199. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  200. package/dist/plot/scatter-3d/Surface3D.svelte +6 -5
  201. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  202. package/dist/plot/sunburst/Sunburst.svelte +16 -20
  203. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  204. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +1 -1
  205. package/dist/plot/sunburst/sunburst.js +4 -1
  206. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  207. package/dist/sanitize.js +13 -2
  208. package/dist/scene/SceneCamera.svelte +62 -0
  209. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  210. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  211. package/dist/scene/bind-renderer.svelte.js +14 -0
  212. package/dist/scene/index.d.ts +4 -0
  213. package/dist/scene/index.js +5 -0
  214. package/dist/scene/props.js +52 -0
  215. package/dist/scene/types.d.ts +26 -0
  216. package/dist/scene/types.js +1 -0
  217. package/dist/settings.d.ts +14 -2
  218. package/dist/settings.js +59 -1
  219. package/dist/spectral/Bands.svelte +8 -7
  220. package/dist/spectral/Bands.svelte.d.ts +3 -2
  221. package/dist/spectral/BandsAndDos.svelte +22 -24
  222. package/dist/spectral/BrillouinBandsDos.svelte +3 -3
  223. package/dist/spectral/Dos.svelte +5 -4
  224. package/dist/spectral/Dos.svelte.d.ts +2 -1
  225. package/dist/spectral/helpers.d.ts +6 -6
  226. package/dist/spectral/helpers.js +43 -37
  227. package/dist/state.svelte.d.ts +0 -7
  228. package/dist/state.svelte.js +0 -6
  229. package/dist/structure/Arrow.svelte +2 -4
  230. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  231. package/dist/structure/CanvasTooltip.svelte +1 -0
  232. package/dist/structure/CellSelect.svelte +11 -3
  233. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  234. package/dist/structure/Lattice.svelte +2 -2
  235. package/dist/structure/Structure.svelte +291 -355
  236. package/dist/structure/Structure.svelte.d.ts +5 -15
  237. package/dist/structure/StructureControls.svelte +217 -2
  238. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  239. package/dist/structure/StructureExportPane.svelte +54 -156
  240. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  241. package/dist/structure/StructureInfoPane.svelte +5 -3
  242. package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
  243. package/dist/structure/StructureScene.svelte +365 -198
  244. package/dist/structure/StructureScene.svelte.d.ts +22 -20
  245. package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
  246. package/dist/structure/{label-placement.js → atom-label-placement.js} +12 -2
  247. package/dist/structure/atom-properties.d.ts +1 -1
  248. package/dist/structure/atom-properties.js +11 -16
  249. package/dist/structure/bond-order-perception.js +2 -4
  250. package/dist/structure/bonding.d.ts +3 -0
  251. package/dist/structure/bonding.js +91 -48
  252. package/dist/structure/export.d.ts +24 -4
  253. package/dist/structure/export.js +64 -122
  254. package/dist/structure/index.d.ts +2 -0
  255. package/dist/structure/index.js +2 -0
  256. package/dist/structure/parse.d.ts +3 -2
  257. package/dist/structure/parse.js +333 -370
  258. package/dist/structure/partial-occupancy.d.ts +0 -1
  259. package/dist/structure/partial-occupancy.js +1 -1
  260. package/dist/structure/pbc.d.ts +1 -1
  261. package/dist/structure/pbc.js +186 -13
  262. package/dist/structure/polyhedra.d.ts +41 -0
  263. package/dist/structure/polyhedra.js +602 -0
  264. package/dist/structure/site.d.ts +4 -0
  265. package/dist/structure/site.js +1 -0
  266. package/dist/structure/supercell.js +3 -2
  267. package/dist/structure/validation.js +5 -6
  268. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  269. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  270. package/dist/symmetry/SymmetryElements.svelte +354 -0
  271. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  272. package/dist/symmetry/SymmetryStats.svelte +111 -6
  273. package/dist/symmetry/WyckoffTable.svelte +68 -7
  274. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  275. package/dist/symmetry/cell-transform.js +7 -14
  276. package/dist/symmetry/index.d.ts +14 -4
  277. package/dist/symmetry/index.js +301 -80
  278. package/dist/symmetry/spacegroups.d.ts +5 -1
  279. package/dist/symmetry/spacegroups.js +15 -1
  280. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  281. package/dist/symmetry/symmetry-elements.js +521 -0
  282. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  283. package/dist/symmetry/wyckoff-db.js +87 -0
  284. package/dist/table/HeatmapTable.svelte +4 -15
  285. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  286. package/dist/trajectory/Trajectory.svelte +58 -61
  287. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  288. package/dist/trajectory/TrajectoryExportPane.svelte +15 -24
  289. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  290. package/dist/trajectory/TrajectoryInfoPane.svelte +3 -2
  291. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  292. package/dist/trajectory/constants.js +6 -2
  293. package/dist/trajectory/extract.js +17 -37
  294. package/dist/trajectory/format-detect.d.ts +0 -1
  295. package/dist/trajectory/format-detect.js +3 -9
  296. package/dist/trajectory/frame-reader.d.ts +0 -1
  297. package/dist/trajectory/frame-reader.js +62 -128
  298. package/dist/trajectory/helpers.d.ts +10 -2
  299. package/dist/trajectory/helpers.js +56 -36
  300. package/dist/trajectory/parse/ase.d.ts +9 -1
  301. package/dist/trajectory/parse/ase.js +47 -32
  302. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  303. package/dist/trajectory/parse/diagnostics.js +14 -0
  304. package/dist/trajectory/parse/index.d.ts +1 -1
  305. package/dist/trajectory/parse/index.js +54 -102
  306. package/dist/trajectory/parse/lammps.d.ts +0 -2
  307. package/dist/trajectory/parse/lammps.js +8 -6
  308. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  309. package/dist/trajectory/parse/pymatgen.js +74 -0
  310. package/dist/trajectory/parse/vasp.js +4 -3
  311. package/dist/trajectory/parse/xyz.d.ts +9 -21
  312. package/dist/trajectory/parse/xyz.js +28 -33
  313. package/dist/trajectory/plotting.d.ts +0 -1
  314. package/dist/trajectory/plotting.js +3 -100
  315. package/dist/utils.d.ts +1 -0
  316. package/dist/utils.js +1 -1
  317. package/dist/xrd/XrdPlot.svelte +14 -29
  318. package/dist/xrd/broadening.d.ts +2 -1
  319. package/dist/xrd/calc-xrd.js +6 -11
  320. package/dist/xrd/index.d.ts +2 -2
  321. package/package.json +29 -16
  322. package/dist/element/data.json +0 -11864
  323. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  324. package/dist/fermi-surface/marching-cubes.js +0 -2
  325. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  326. package/dist/plot/core/hover-lock.svelte.js +0 -45
@@ -2,31 +2,26 @@ import type { D3InterpolateName } from '../colors';
2
2
  import type { ElementSymbol } from '../element';
3
3
  import type { IsosurfaceSettings, VolumetricData } from '../isosurface/types';
4
4
  import type { Vec3 } from '../math';
5
- import type { CameraProjection, ShowBonds, VectorColorMode, VectorLayerConfig } from '../settings';
5
+ import type { SceneControlProps } from '../scene';
6
+ import type { ShowBonds, VectorColorMode, VectorLayerConfig } from '../settings';
6
7
  import type { AnyStructure, BondEditMode, BondOrder, MeasureMode, Site, StructureBond } from './';
7
8
  import { Lattice } from './';
8
9
  import type { AtomColorConfig } from './atom-properties';
10
+ import type { SymmetryElement } from '../symmetry';
11
+ import SymmetryElements from '../symmetry/SymmetryElements.svelte';
9
12
  import type { MoyoDataset } from '@spglib/moyo-wasm';
10
13
  import * as extras from '@threlte/extras';
11
14
  import { type ComponentProps, type Snippet } from 'svelte';
12
15
  import { SvelteMap } from 'svelte/reactivity';
13
- import { type Camera, type Scene } from 'three';
14
16
  import type { BondingStrategy } from './bonding';
15
- type $$ComponentProps = {
17
+ import type { PolyhedraColorMode } from './polyhedra';
18
+ type $$ComponentProps = SceneControlProps & {
16
19
  structure?: AnyStructure;
17
20
  base_structure?: AnyStructure;
18
21
  atom_radius?: number;
19
22
  same_size_atoms?: boolean;
20
23
  camera_position?: [x: number, y: number, z: number];
21
24
  camera_target?: Vec3;
22
- camera_projection?: CameraProjection;
23
- rotation_damping?: number;
24
- max_zoom?: number;
25
- min_zoom?: number;
26
- rotate_speed?: number;
27
- zoom_speed?: number;
28
- pan_speed?: number;
29
- zoom_to_cursor?: boolean;
30
25
  show_atoms?: boolean;
31
26
  show_bonds?: ShowBonds;
32
27
  show_site_labels?: boolean;
@@ -42,23 +37,32 @@ type $$ComponentProps = {
42
37
  vector_shaft_radius?: number;
43
38
  vector_arrow_head_radius?: number;
44
39
  vector_arrow_head_length?: number;
45
- gizmo?: boolean | ComponentProps<typeof extras.Gizmo>;
46
40
  hovered_idx?: number | null;
47
41
  hovered_site?: Site | null;
48
42
  float_fmt?: string;
49
- auto_rotate?: number;
50
- initial_zoom?: number;
51
43
  bond_thickness?: number;
52
44
  bond_color?: string;
53
45
  bonding_strategy?: BondingStrategy;
54
46
  auto_bond_order?: boolean;
55
47
  aromatic_display?: `aromatic` | `kekule`;
56
48
  bonding_options?: Record<string, unknown>;
57
- fov?: number;
58
- ambient_light?: number;
59
- directional_light?: number;
49
+ show_polyhedra?: ShowBonds;
50
+ polyhedra_opacity?: number;
51
+ polyhedra_show_edges?: boolean;
52
+ polyhedra_edge_color?: string;
53
+ polyhedra_color_mode?: PolyhedraColorMode;
54
+ polyhedra_color?: string;
55
+ polyhedra_hide_center_atoms?: boolean;
56
+ polyhedra_min_neighbors?: number;
57
+ polyhedra_max_neighbors?: number;
58
+ polyhedra_excluded_elements?: readonly string[];
59
+ polyhedra_included_elements?: readonly string[];
60
+ polyhedra_rendered_elements?: string[];
60
61
  sphere_segments?: number;
61
62
  lattice_props?: ComponentProps<typeof Lattice>;
63
+ symmetry_elements?: SymmetryElement[];
64
+ symmetry_elements_props?: Omit<ComponentProps<typeof SymmetryElements>, `elements` | `lattice`>;
65
+ symmetry_declutter?: boolean;
62
66
  atom_label?: Snippet<[{
63
67
  site: Site;
64
68
  site_idx: number;
@@ -84,8 +88,6 @@ type $$ComponentProps = {
84
88
  active_sites?: number[];
85
89
  active_highlight_color?: string;
86
90
  rotation?: Vec3;
87
- scene?: Scene;
88
- camera?: Camera;
89
91
  orbit_controls?: ComponentProps<typeof extras.OrbitControls>[`ref`];
90
92
  rotation_target_ref?: Vec3;
91
93
  initial_computed_zoom?: number;
@@ -106,6 +108,6 @@ type $$ComponentProps = {
106
108
  volumetric_data?: VolumetricData;
107
109
  isosurface_settings?: IsosurfaceSettings;
108
110
  };
109
- declare const StructureScene: import("svelte").Component<$$ComponentProps, {}, "cursor" | "site_label_offset" | "vector_configs" | "camera" | "scene" | "orbit_controls" | "site_radius_overrides" | "hovered_idx" | "hovered_site" | "camera_is_moving" | "selected_sites" | "measured_sites" | "added_bonds" | "removed_bonds" | "bond_order_overrides" | "bond_edit_mode" | "active_sites" | "rotation_target_ref" | "initial_computed_zoom" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "add_atom_mode" | "add_element" | "dragging_atoms">;
111
+ declare const StructureScene: import("svelte").Component<$$ComponentProps, {}, "cursor" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "selected_sites" | "site_label_offset" | "vector_configs" | "hovered_idx" | "hovered_site" | "polyhedra_rendered_elements" | "camera_is_moving" | "measured_sites" | "added_bonds" | "removed_bonds" | "bond_order_overrides" | "bond_edit_mode" | "active_sites" | "scene" | "camera" | "orbit_controls" | "rotation_target_ref" | "initial_computed_zoom" | "add_atom_mode" | "add_element" | "dragging_atoms">;
110
112
  type StructureScene = ReturnType<typeof StructureScene>;
111
113
  export default StructureScene;
@@ -1,4 +1,4 @@
1
- import type { Vec3 } from '../math';
1
+ import type { Vec2, Vec3 } from '../math';
2
2
  import type { Camera, Object3D } from 'three';
3
3
  export declare const LABEL_OFFSET_EPS = 1e-9;
4
4
  type LabelOffsetSource = Vec3 | (() => Vec3);
@@ -6,9 +6,9 @@ export declare const choose_site_label_offset: (bond_directions: Vec3[], base_of
6
6
  export declare const label_screen_position: (atom_position: Vec3, label_offset: Vec3, visual_radius: number, label_screen_margin: number, label_camera: Camera, size: {
7
7
  width: number;
8
8
  height: number;
9
- }) => [number, number];
9
+ }) => Vec2;
10
10
  export declare const make_label_position_calculator: (_atom_position: Vec3, label_offset: LabelOffsetSource, visual_radius: number, label_screen_margin: number) => (object: Object3D, label_camera: Camera, size: {
11
11
  width: number;
12
12
  height: number;
13
- }) => [number, number];
13
+ }) => Vec2;
14
14
  export {};
@@ -59,8 +59,18 @@ export const label_screen_position = (atom_position, label_offset, visual_radius
59
59
  const offset_length = Math.hypot(offset_x, offset_y);
60
60
  const direction_x = offset_length > LABEL_OFFSET_EPS ? offset_x / offset_length : 0;
61
61
  const direction_y = offset_length > LABEL_OFFSET_EPS ? offset_y / offset_length : label_offset[1] >= 0 ? -1 : 1;
62
- const radius_direction = math.normalize_vec(label_offset, [0, 1, 0]);
63
- const radius_edge = math.add(atom_position, math.scale(radius_direction, visual_radius));
62
+ // Measure the atom's projected radius along the camera's right axis (always
63
+ // view-perpendicular). Measuring along label_offset would collapse the clearance
64
+ // to ~zero for offsets near the view axis, letting the label overlap the atom.
65
+ const radius_dir = new Vector3()
66
+ .setFromMatrixColumn(label_camera.matrixWorld, 0)
67
+ .normalize()
68
+ .multiplyScalar(visual_radius);
69
+ const radius_edge = math.add(atom_position, [
70
+ radius_dir.x,
71
+ radius_dir.y,
72
+ radius_dir.z,
73
+ ]);
64
74
  const radius_screen = project_to_screen(radius_edge, label_camera, size);
65
75
  const atom_screen_radius = Math.hypot(radius_screen[0] - atom_screen[0], radius_screen[1] - atom_screen[1]);
66
76
  const screen_gap = atom_screen_radius + label_screen_margin;
@@ -17,7 +17,7 @@ export interface AtomPropertyColors {
17
17
  unique_values?: (number | string)[];
18
18
  }
19
19
  type SymmetryDataWithOrigMap = MoyoDataset & {
20
- orig_site_indices_by_std_idx?: number[][];
20
+ orig_site_indices_by_input_idx?: number[][];
21
21
  };
22
22
  export declare const get_d3_color_scales: () => string[];
23
23
  export declare function apply_color_scale(vals: number[], scale?: string, type?: ColorScaleType): {
@@ -1,4 +1,5 @@
1
1
  // Utility functions for computing atom properties and applying color scales
2
+ import { get_d3_interpolator } from '../colors';
2
3
  import { calc_coordination_nums } from '../coordination';
3
4
  import * as math from '../math';
4
5
  import { wrap_to_unit_cell } from './pbc';
@@ -7,15 +8,7 @@ import * as d3_sc from 'd3-scale-chromatic';
7
8
  const GRAY = `#808080`;
8
9
  const DEFAULT_COLOR_SCALE = `interpolateViridis`;
9
10
  export const get_d3_color_scales = () => Object.keys(d3_sc).filter((key) => key.startsWith(`interpolate`));
10
- const get_interpolator = (scale) => {
11
- const interp_fn = d3_sc[scale];
12
- if (typeof interp_fn !== `function`) {
13
- console.warn(`Unknown D3 scale: ${scale}, using ${DEFAULT_COLOR_SCALE}`);
14
- return d3_sc.interpolateViridis;
15
- }
16
- return interp_fn;
17
- };
18
- const to_hex = (interp_fn, t) => rgb(interp_fn(t)).formatHex();
11
+ const to_hex = (interp_fn, frac) => rgb(interp_fn(frac)).formatHex();
19
12
  const build_image_site = (site, frac_to_cart, offset, orig_idx) => {
20
13
  const img_abc = [
21
14
  site.abc[0] + offset[0],
@@ -36,7 +29,7 @@ const get_all_offsets = (pbc) => [-1, 0, 1]
36
29
  (pbc[1] || dy === 0) &&
37
30
  (pbc[2] || dz === 0));
38
31
  const make_categorical = (vals, scale, sort_fn) => {
39
- const interp_fn = get_interpolator(scale);
32
+ const interp_fn = get_d3_interpolator(scale);
40
33
  const uniq = sort_fn
41
34
  ? [...new Set(vals)].sort(sort_fn)
42
35
  : [...new Set(vals)].sort((val_a, val_b) => String(val_a).localeCompare(String(val_b)));
@@ -61,7 +54,7 @@ export function apply_color_scale(vals, scale = DEFAULT_COLOR_SCALE, type = `con
61
54
  const result = make_categorical(vals, scale, (val_a, val_b) => val_a - val_b);
62
55
  return { colors: result.colors, unique_values: result.unique_values };
63
56
  }
64
- const interp_fn = get_interpolator(scale);
57
+ const interp_fn = get_d3_interpolator(scale);
65
58
  // Compute min/max in single pass to avoid spreading large arrays
66
59
  let [min, max] = [vals[0], vals[0]];
67
60
  for (const val of vals) {
@@ -134,12 +127,14 @@ export function get_wyckoff_colors(structure, sym_data, scale = DEFAULT_COLOR_SC
134
127
  unique_values: [`unknown`],
135
128
  };
136
129
  }
130
+ // moyo's wyckoffs array is indexed by INPUT cell sites (the merged moyo input cell),
131
+ // so map letters to original sites through orig_site_indices_by_input_idx
137
132
  const wyckoff_by_orig_idx = new Map();
138
- const mapping_by_std_idx = sym_data.orig_site_indices_by_std_idx;
139
- if (mapping_by_std_idx) {
140
- for (let std_idx = 0; std_idx < sym_data.wyckoffs.length; std_idx += 1) {
141
- const wyckoff = sym_data.wyckoffs[std_idx];
142
- for (const orig_idx of mapping_by_std_idx[std_idx] ?? []) {
133
+ const mapping_by_input_idx = sym_data.orig_site_indices_by_input_idx;
134
+ if (mapping_by_input_idx) {
135
+ for (let input_idx = 0; input_idx < sym_data.wyckoffs.length; input_idx += 1) {
136
+ const wyckoff = sym_data.wyckoffs[input_idx];
137
+ for (const orig_idx of mapping_by_input_idx[input_idx] ?? []) {
143
138
  if (!wyckoff_by_orig_idx.has(orig_idx))
144
139
  wyckoff_by_orig_idx.set(orig_idx, wyckoff);
145
140
  }
@@ -1,7 +1,5 @@
1
- import { get_bond_key } from './bonding';
2
- const primary_element = (site) => {
3
- return (site.species?.reduce((best_species, species) => (species.occu > best_species.occu ? species : best_species), site.species[0])?.element ?? ``);
4
- };
1
+ import { get_bond_key, get_majority_element } from './bonding';
2
+ const primary_element = (site) => get_majority_element(site) ?? ``;
5
3
  // xyz2mol atomic_valence. Valence combinations are re-sorted by total
6
4
  // valence sum so the least-saturated solution is tried first.
7
5
  const ATOMIC_VALENCE = {
@@ -1,5 +1,8 @@
1
+ import type { ElementSymbol } from '../element';
1
2
  import type { Vec3 } from '../math';
2
3
  import type { AnyStructure, BondOrder, BondPair, Site, StructureBond } from './';
4
+ export declare const element_lookup: Map<"S" | "K" | "B" | "H" | "He" | "Li" | "Be" | "C" | "N" | "O" | "F" | "Ne" | "Na" | "Mg" | "Al" | "Si" | "P" | "Cl" | "Ar" | "Ca" | "Sc" | "Ti" | "V" | "Cr" | "Mn" | "Fe" | "Co" | "Ni" | "Cu" | "Zn" | "Ga" | "Ge" | "As" | "Se" | "Br" | "Kr" | "Rb" | "Sr" | "Y" | "Zr" | "Nb" | "Mo" | "Tc" | "Ru" | "Rh" | "Pd" | "Ag" | "Cd" | "In" | "Sn" | "Sb" | "Te" | "I" | "Xe" | "Cs" | "Ba" | "La" | "Ce" | "Pr" | "Nd" | "Pm" | "Sm" | "Eu" | "Gd" | "Tb" | "Dy" | "Ho" | "Er" | "Tm" | "Yb" | "Lu" | "Hf" | "Ta" | "W" | "Re" | "Os" | "Ir" | "Pt" | "Au" | "Hg" | "Tl" | "Pb" | "Bi" | "Po" | "At" | "Rn" | "Fr" | "Ra" | "Ac" | "Th" | "Pa" | "U" | "Np" | "Pu" | "Am" | "Cm" | "Bk" | "Cf" | "Es" | "Fm" | "Md" | "No" | "Lr" | "Rf" | "Db" | "Sg" | "Bh" | "Hs" | "Mt" | "Ds" | "Rg" | "Cn" | "Nh" | "Fl" | "Mc" | "Lv" | "Ts" | "Og", import("../element").ChemicalElement>;
5
+ export declare const get_majority_element: (site: Site | undefined) => ElementSymbol | null;
3
6
  export declare const normalize_structure_bond: (site_idx_1: number, site_idx_2: number, order: BondOrder, cell_shift?: Vec3) => StructureBond;
4
7
  export declare const get_bond_key: (idx_1: number, idx_2: number, cell_shift?: Vec3) => string;
5
8
  export declare function remap_bonds_after_deletion(bonds: readonly StructureBond[], deleted_indices: ReadonlySet<number>): StructureBond[];
@@ -1,8 +1,15 @@
1
1
  // Bonding algorithms for structure visualization
2
2
  import { element_data } from '../element';
3
3
  import * as math from '../math';
4
- const element_lookup = new Map(element_data.map((el) => [el.symbol, el]));
4
+ // Shared per-symbol element data lookup (also used by pbc.ts and polyhedra.ts)
5
+ export const element_lookup = new Map(element_data.map((el) => [el.symbol, el]));
5
6
  const covalent_radii = new Map(element_data.flatMap((el) => el.covalent_radius === null ? [] : [[el.symbol, el.covalent_radius]]));
7
+ // Majority-occupancy element of a (possibly disordered) site
8
+ export const get_majority_element = (site) => {
9
+ if (!site?.species?.length)
10
+ return null;
11
+ return site.species.reduce((max, spec) => (spec.occu > max.occu ? spec : max)).element;
12
+ };
6
13
  const is_zero_cell_shift = (cell_shift) => cell_shift === undefined || cell_shift.every((val) => val === 0);
7
14
  const format_cell_shift = (cell_shift) => {
8
15
  if (cell_shift === undefined || is_zero_cell_shift(cell_shift))
@@ -413,8 +420,6 @@ export function get_bond_render_matrices(bond, bond_thickness) {
413
420
  ? [bond.transform_matrix]
414
421
  : offsets_and_scales.map(([offset, radius_scale]) => scale_and_offset_bond_matrix(bond.transform_matrix, offset, radius_scale));
415
422
  }
416
- // Get the species with highest occupancy from a site.
417
- const get_majority_species = (site) => (site.species ?? []).reduce((max_species, species) => (species.occu > max_species.occu ? species : max_species), site.species?.[0] ?? { element: ``, occu: -1 });
418
423
  // Helper to extract numeric index from site properties
419
424
  function get_orig_idx(site, fallback) {
420
425
  const props = site.properties;
@@ -496,12 +501,16 @@ export function compute_bond_transform(pos_1, pos_2) {
496
501
  1,
497
502
  ]);
498
503
  }
504
+ // Pack quantized cell coordinates into one integer key (exact for cell coords in
505
+ // [-512, 511], i.e. structures up to ~1000 cells per axis - far beyond any real
506
+ // case). Integer Map keys avoid per-lookup string building in the hot pair loop.
507
+ const CELL_OFFSET = 512;
508
+ const pack_cell_key = (x, y, z) => (x + CELL_OFFSET) * 1048576 + (y + CELL_OFFSET) * 1024 + (z + CELL_OFFSET);
499
509
  // Build spatial grid by dividing 3D space into cubic cells.
500
510
  function build_spatial_grid(sites, cell_size) {
501
511
  const grid = new Map();
502
512
  for (let idx = 0; idx < sites.length; idx++) {
503
- const [x, y, z] = sites[idx].xyz.map((coord) => Math.floor(coord / cell_size));
504
- const key = `${x},${y},${z}`;
513
+ const key = pack_cell_key(Math.floor(sites[idx].xyz[0] / cell_size), Math.floor(sites[idx].xyz[1] / cell_size), Math.floor(sites[idx].xyz[2] / cell_size));
505
514
  const cell = grid.get(key);
506
515
  if (cell)
507
516
  cell.push(idx);
@@ -521,9 +530,10 @@ function get_neighbors_from_grid(pos, grid, cell_size) {
521
530
  for (let dx = -1; dx <= 1; dx++) {
522
531
  for (let dy = -1; dy <= 1; dy++) {
523
532
  for (let dz = -1; dz <= 1; dz++) {
524
- const cell = grid.get(`${cx + dx},${cy + dy},${cz + dz}`);
533
+ const cell = grid.get(pack_cell_key(cx + dx, cy + dy, cz + dz));
525
534
  if (cell)
526
- neighbors.push(...cell);
535
+ for (const idx of cell)
536
+ neighbors.push(idx);
527
537
  }
528
538
  }
529
539
  }
@@ -557,19 +567,39 @@ strength_threshold = 0.3, // Minimum bond strength to include in results
557
567
  return [];
558
568
  const bonds = [];
559
569
  const min_dist_sq = min_bond_dist ** 2;
560
- const closest = new Map();
561
- const props = sites.map((site) => {
562
- const majority = get_majority_species(site);
563
- const elem = majority.element;
564
- const data = element_lookup.get(elem);
565
- return {
566
- element: elem,
567
- electroneg: data?.electronegativity ?? 2.0,
568
- is_metal: data?.metal ?? false,
569
- is_nonmetal: data?.nonmetal ?? false,
570
- radius: elem ? covalent_radii.get(elem) : undefined,
571
- };
572
- });
570
+ // Per-site properties in flat typed arrays - the pair loop below visits
571
+ // millions of candidate pairs in large supercells, so object property chains
572
+ // and Map lookups are replaced with indexed array reads.
573
+ const n_sites = sites.length;
574
+ const electronegs = new Float64Array(n_sites);
575
+ const radii = new Float64Array(n_sites); // 0 = no covalent radius known
576
+ const metal_flags = new Uint8Array(n_sites);
577
+ const nonmetal_flags = new Uint8Array(n_sites);
578
+ const elem_ids = new Int32Array(n_sites); // same-species check via integer ids
579
+ const orig_idxs = new Int32Array(n_sites);
580
+ const elem_id_lookup = new Map();
581
+ for (let idx = 0; idx < n_sites; idx++) {
582
+ const elem = get_majority_element(sites[idx]);
583
+ const data = elem ? element_lookup.get(elem) : undefined;
584
+ electronegs[idx] = data?.electronegativity ?? 2.0;
585
+ metal_flags[idx] = data?.metal ? 1 : 0;
586
+ nonmetal_flags[idx] = data?.nonmetal ? 1 : 0;
587
+ radii[idx] = (elem ? covalent_radii.get(elem) : undefined) ?? 0;
588
+ let elem_id = elem_id_lookup.get(elem ?? ``);
589
+ if (elem_id === undefined) {
590
+ elem_id = elem_id_lookup.size;
591
+ elem_id_lookup.set(elem ?? ``, elem_id);
592
+ }
593
+ elem_ids[idx] = elem_id;
594
+ // Valid orig indices always reference a site in this structure; fall back to
595
+ // the site's own index on malformed orig_*_idx properties so the typed
596
+ // `closest` array below stays bounded by n_sites
597
+ const orig_idx = get_orig_idx(sites[idx], idx);
598
+ orig_idxs[idx] =
599
+ Number.isInteger(orig_idx) && orig_idx >= 0 && orig_idx < n_sites ? orig_idx : idx;
600
+ }
601
+ // Closest normalized bond distance per original atom (typed array instead of Map)
602
+ const closest = new Float64Array(n_sites).fill(Infinity);
573
603
  let max_radius = 0;
574
604
  for (const radius of covalent_radii.values()) {
575
605
  if (radius > max_radius)
@@ -579,29 +609,44 @@ strength_threshold = 0.3, // Minimum bond strength to include in results
579
609
  const spatial = setup_spatial_grid(sites, max_cutoff);
580
610
  const potential_bonds = [];
581
611
  for (let idx_a = 0; idx_a < sites.length - 1; idx_a++) {
612
+ const radius_a = radii[idx_a];
613
+ if (radius_a === 0)
614
+ continue; // no covalent radius -> no pairs (symmetric: idx_b skips too)
582
615
  const [x1, y1, z1] = sites[idx_a].xyz;
583
- const props_a = props[idx_a];
616
+ const electroneg_a = electronegs[idx_a];
617
+ const is_metal_a = metal_flags[idx_a] === 1;
618
+ const is_nonmetal_a = nonmetal_flags[idx_a] === 1;
619
+ const elem_id_a = elem_ids[idx_a];
584
620
  for (const idx_b of get_candidates(sites[idx_a].xyz, sites, spatial)) {
585
621
  if (idx_b <= idx_a)
586
622
  continue;
623
+ const radius_b = radii[idx_b];
624
+ if (radius_b === 0)
625
+ continue;
587
626
  const [x2, y2, z2] = sites[idx_b].xyz;
588
- const props_b = props[idx_b];
589
- const [dx, dy, dz] = [x2 - x1, y2 - y1, z2 - z1];
627
+ const dx = x2 - x1;
628
+ const dy = y2 - y1;
629
+ const dz = z2 - z1;
590
630
  const dist_sq = dx * dx + dy * dy + dz * dz;
591
- const dist = Math.sqrt(dist_sq);
592
- if (dist_sq < min_dist_sq || !props_a.radius || !props_b.radius)
631
+ if (dist_sq < min_dist_sq)
593
632
  continue;
594
- const expected = props_a.radius + props_b.radius;
595
- if (dist > expected * max_distance_ratio)
633
+ // Compare squared distances to defer the sqrt until a pair survives the
634
+ // cutoff (the vast majority of candidate pairs are rejected here)
635
+ const expected = radius_a + radius_b;
636
+ const max_dist = expected * max_distance_ratio;
637
+ if (dist_sq > max_dist * max_dist)
596
638
  continue;
597
- const electroneg_diff = Math.abs(props_a.electroneg - props_b.electroneg);
598
- const electroneg_balance = electroneg_diff / (props_a.electroneg + props_b.electroneg);
639
+ const dist = Math.sqrt(dist_sq);
640
+ const electroneg_b = electronegs[idx_b];
641
+ const electroneg_diff = Math.abs(electroneg_a - electroneg_b);
642
+ const electroneg_balance = electroneg_diff / (electroneg_a + electroneg_b);
643
+ const is_metal_b = metal_flags[idx_b] === 1;
644
+ const is_nonmetal_b = nonmetal_flags[idx_b] === 1;
599
645
  let bond_strength = 1.0;
600
- if (props_a.is_metal && props_b.is_metal) {
646
+ if (is_metal_a && is_metal_b) {
601
647
  bond_strength *= metal_metal_penalty;
602
648
  }
603
- else if ((props_a.is_metal && props_b.is_nonmetal) ||
604
- (props_a.is_nonmetal && props_b.is_metal)) {
649
+ else if ((is_metal_a && is_nonmetal_b) || (is_nonmetal_a && is_metal_b)) {
605
650
  bond_strength *= metal_nonmetal_bonus;
606
651
  if (electroneg_diff > electronegativity_threshold)
607
652
  bond_strength *= 1.3;
@@ -612,25 +657,23 @@ strength_threshold = 0.3, // Minimum bond strength to include in results
612
657
  const dist_weight = Math.exp(-((dist / expected - 1) ** 2) / 0.18);
613
658
  const electroneg_weight = 1.0 - 0.3 * electroneg_balance;
614
659
  let strength = bond_strength * dist_weight * electroneg_weight;
615
- if (props_a.element === props_b.element)
660
+ if (elem_id_a === elem_ids[idx_b])
616
661
  strength *= same_species_penalty;
617
662
  // If raw strength is already too low, we can skip early
618
663
  // (penalty will only reduce it further)
619
664
  if (strength <= strength_threshold)
620
665
  continue;
621
- // Use helper logic to handle both supercell and image atoms with robust normalization
622
- const orig_idx_a = get_orig_idx(sites[idx_a], idx_a);
623
- const orig_idx_b = get_orig_idx(sites[idx_b], idx_b);
666
+ // Use precomputed original-site indices to handle supercell and image atoms
667
+ const orig_idx_a = orig_idxs[idx_a];
668
+ const orig_idx_b = orig_idxs[idx_b];
624
669
  // Update closest known normalized distance (dist / expected) for original atoms
625
670
  // Normalized distance handles atoms of different sizes better than raw distance
626
671
  // (e.g. C-H is short but C-C is longer; we don't want C-H to penalize C-C just because H is small)
627
672
  const norm_dist = dist / expected;
628
- const closest_dist_a = closest.get(orig_idx_a) ?? Infinity;
629
- if (norm_dist < closest_dist_a)
630
- closest.set(orig_idx_a, norm_dist);
631
- const closest_dist_b = closest.get(orig_idx_b) ?? Infinity;
632
- if (norm_dist < closest_dist_b)
633
- closest.set(orig_idx_b, norm_dist);
673
+ if (norm_dist < closest[orig_idx_a])
674
+ closest[orig_idx_a] = norm_dist;
675
+ if (norm_dist < closest[orig_idx_b])
676
+ closest[orig_idx_b] = norm_dist;
634
677
  potential_bonds.push({
635
678
  site_idx_1: idx_a,
636
679
  site_idx_2: idx_b,
@@ -645,8 +688,8 @@ strength_threshold = 0.3, // Minimum bond strength to include in results
645
688
  // Second pass: Apply penalties and filter
646
689
  for (const bond of potential_bonds) {
647
690
  const { site_idx_1, site_idx_2, dist, expected_dist, base_strength, orig_idx_a, orig_idx_b, } = bond;
648
- const closest_dist_a = closest.get(orig_idx_a) ?? Infinity;
649
- const closest_dist_b = closest.get(orig_idx_b) ?? Infinity;
691
+ const closest_dist_a = closest[orig_idx_a];
692
+ const closest_dist_b = closest[orig_idx_b];
650
693
  const norm_dist = dist / expected_dist;
651
694
  let strength = base_strength;
652
695
  // Apply penalty if this bond is much longer (relative to radii) than the closest known bond
@@ -685,14 +728,14 @@ export function solid_angle(structure, { min_solid_angle = 0.01, min_face_area =
685
728
  const spatial = setup_spatial_grid(sites, max_distance);
686
729
  for (let idx_a = 0; idx_a < sites.length - 1; idx_a++) {
687
730
  const [x1, y1, z1] = sites[idx_a].xyz;
688
- const majority_a = get_majority_species(sites[idx_a]);
689
- const radius_a = majority_a.element ? covalent_radii.get(majority_a.element) : undefined;
731
+ const elem_a = get_majority_element(sites[idx_a]);
732
+ const radius_a = elem_a ? covalent_radii.get(elem_a) : undefined;
690
733
  for (const idx_b of get_candidates(sites[idx_a].xyz, sites, spatial)) {
691
734
  if (idx_b <= idx_a)
692
735
  continue;
693
736
  const [x2, y2, z2] = sites[idx_b].xyz;
694
- const majority_b = get_majority_species(sites[idx_b]);
695
- const radius_b = majority_b.element ? covalent_radii.get(majority_b.element) : undefined;
737
+ const elem_b = get_majority_element(sites[idx_b]);
738
+ const radius_b = elem_b ? covalent_radii.get(elem_b) : undefined;
696
739
  const [dx, dy, dz] = [x2 - x1, y2 - y1, z2 - z1];
697
740
  const dist_sq = dx * dx + dy * dy + dz * dz;
698
741
  const dist = Math.sqrt(dist_sq);
@@ -12,9 +12,29 @@ export declare function structure_to_xyz_str(structure?: AnyStructure): string;
12
12
  export declare function structure_to_cif_str(structure?: AnyStructure): string;
13
13
  export declare function structure_to_poscar_str(structure?: AnyStructure): string;
14
14
  export declare function structure_to_json_str(structure?: AnyStructure): string;
15
- export declare function export_structure_as_cif(structure?: AnyStructure): void;
16
- export declare function export_structure_as_poscar(structure?: AnyStructure): void;
17
- export declare function export_structure_as_xyz(structure?: AnyStructure): void;
18
- export declare function export_structure_as_json(structure?: AnyStructure): void;
15
+ export declare const STRUCT_TEXT_FORMATS: {
16
+ readonly json: {
17
+ readonly to_str: typeof structure_to_json_str;
18
+ readonly ext: "json";
19
+ readonly mime: "application/json";
20
+ };
21
+ readonly xyz: {
22
+ readonly to_str: typeof structure_to_xyz_str;
23
+ readonly ext: "xyz";
24
+ readonly mime: "text/plain";
25
+ };
26
+ readonly cif: {
27
+ readonly to_str: typeof structure_to_cif_str;
28
+ readonly ext: "cif";
29
+ readonly mime: "chemical/x-cif";
30
+ };
31
+ readonly poscar: {
32
+ readonly to_str: typeof structure_to_poscar_str;
33
+ readonly ext: "poscar";
34
+ readonly mime: "text/plain";
35
+ };
36
+ };
37
+ export type StructTextFormat = keyof typeof STRUCT_TEXT_FORMATS;
38
+ export declare function export_structure_as(fmt: StructTextFormat, structure?: AnyStructure): void;
19
39
  export declare function export_structure_as_glb(scene: Scene | null, structure: AnyStructure | undefined): void;
20
40
  export declare function export_structure_as_obj(scene: Scene | null, structure: AnyStructure | undefined): void;