matterviz 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +75 -85
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  11. package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  13. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
  15. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
  17. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  18. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  19. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  20. package/dist/colors/index.d.ts +0 -4
  21. package/dist/colors/index.js +19 -20
  22. package/dist/composition/BarChart.svelte +37 -31
  23. package/dist/composition/BubbleChart.svelte +17 -17
  24. package/dist/composition/Composition.svelte +7 -11
  25. package/dist/composition/Formula.svelte +18 -25
  26. package/dist/composition/FormulaFilter.svelte +92 -95
  27. package/dist/composition/PieChart.svelte +55 -41
  28. package/dist/composition/format.js +1 -1
  29. package/dist/composition/index.d.ts +2 -0
  30. package/dist/composition/index.js +14 -0
  31. package/dist/composition/parse.d.ts +2 -2
  32. package/dist/composition/parse.js +11 -10
  33. package/dist/constants.js +11 -9
  34. package/dist/convex-hull/ConvexHull.svelte +12 -15
  35. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  36. package/dist/convex-hull/ConvexHull2D.svelte +93 -92
  37. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  38. package/dist/convex-hull/ConvexHull3D.svelte +109 -140
  39. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  40. package/dist/convex-hull/ConvexHull4D.svelte +75 -94
  41. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  42. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  43. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  44. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  45. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  46. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  47. package/dist/convex-hull/StructurePopup.svelte +17 -21
  48. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  49. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  50. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  51. package/dist/convex-hull/helpers.d.ts +8 -10
  52. package/dist/convex-hull/helpers.js +36 -36
  53. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  54. package/dist/convex-hull/thermodynamics.js +18 -17
  55. package/dist/coordination/CoordinationBarPlot.svelte +38 -33
  56. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  57. package/dist/coordination/calc-coordination.d.ts +1 -1
  58. package/dist/coordination/calc-coordination.js +28 -25
  59. package/dist/element/BohrAtom.svelte +5 -8
  60. package/dist/element/ElementHeading.svelte +4 -1
  61. package/dist/element/ElementPhoto.svelte +11 -9
  62. package/dist/element/ElementStats.svelte +12 -10
  63. package/dist/element/ElementTile.svelte +24 -29
  64. package/dist/element/Nucleus.svelte +4 -2
  65. package/dist/element/data.d.ts +1 -2
  66. package/dist/element/helpers.d.ts +4 -0
  67. package/dist/element/helpers.js +18 -0
  68. package/dist/element/index.d.ts +1 -4
  69. package/dist/element/index.js +3 -18
  70. package/dist/feedback/DragOverlay.svelte +5 -5
  71. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  72. package/dist/feedback/StatusMessage.svelte +7 -4
  73. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  74. package/dist/fermi-surface/FermiSurface.svelte +14 -22
  75. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
  76. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  77. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  80. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  81. package/dist/fermi-surface/compute.js +3 -3
  82. package/dist/fermi-surface/parse.js +22 -24
  83. package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
  84. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  85. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  86. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  87. package/dist/heatmap-matrix/index.d.ts +5 -0
  88. package/dist/icons.d.ts +4 -0
  89. package/dist/icons.js +4 -0
  90. package/dist/io/ExportPane.svelte +10 -6
  91. package/dist/io/decompress.d.ts +2 -1
  92. package/dist/io/decompress.js +22 -35
  93. package/dist/io/export.d.ts +4 -0
  94. package/dist/io/export.js +5 -1
  95. package/dist/io/fetch.d.ts +0 -3
  96. package/dist/io/fetch.js +0 -11
  97. package/dist/io/index.d.ts +0 -1
  98. package/dist/io/index.js +2 -9
  99. package/dist/io/is-binary.d.ts +9 -0
  100. package/dist/io/is-binary.js +45 -1
  101. package/dist/io/url-drop.js +13 -25
  102. package/dist/isosurface/Isosurface.svelte +17 -23
  103. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  104. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  105. package/dist/isosurface/parse-vaspwave.js +138 -0
  106. package/dist/isosurface/parse.js +6 -6
  107. package/dist/labels.d.ts +6 -2
  108. package/dist/labels.js +43 -13
  109. package/dist/layout/FullscreenButton.svelte +2 -1
  110. package/dist/layout/FullscreenToggle.svelte +10 -4
  111. package/dist/layout/InfoCard.svelte +7 -18
  112. package/dist/layout/InfoTag.svelte +1 -3
  113. package/dist/layout/NumberRangeInput.svelte +46 -0
  114. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  115. package/dist/layout/PropertyFilter.svelte +2 -6
  116. package/dist/layout/SettingsSection.svelte +21 -17
  117. package/dist/layout/SubpageGrid.svelte +3 -1
  118. package/dist/layout/ViewerChrome.svelte +9 -10
  119. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  120. package/dist/layout/fullscreen.js +3 -5
  121. package/dist/layout/fullscreen.svelte.js +1 -2
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  125. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  126. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  127. package/dist/layout/json-tree/utils.js +14 -23
  128. package/dist/math.d.ts +2 -0
  129. package/dist/math.js +19 -0
  130. package/dist/overlays/ContextMenu.svelte +4 -2
  131. package/dist/overlays/CopyButton.svelte +11 -5
  132. package/dist/overlays/DragControlTab.svelte +6 -1
  133. package/dist/overlays/DraggablePane.svelte +81 -26
  134. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  135. package/dist/overlays/GlassChip.svelte +30 -0
  136. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  137. package/dist/overlays/InfoPaneCards.svelte +11 -23
  138. package/dist/overlays/index.d.ts +7 -0
  139. package/dist/overlays/index.js +26 -0
  140. package/dist/overlays/portal.d.ts +2 -0
  141. package/dist/overlays/portal.js +14 -0
  142. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  143. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  144. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  145. package/dist/periodic-table/TableInset.svelte +9 -4
  146. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  147. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  148. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  149. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  150. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  151. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  152. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  153. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  154. package/dist/phase-diagram/build-diagram.js +3 -3
  155. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  156. package/dist/phase-diagram/parse.js +15 -15
  157. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  158. package/dist/phase-diagram/utils.js +2 -3
  159. package/dist/plot/bar/BarPlot.svelte +430 -391
  160. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  161. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  162. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  163. package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
  164. package/dist/plot/bar/data.d.ts +5 -4
  165. package/dist/plot/bar/data.js +2 -1
  166. package/dist/plot/box/BoxPlot.svelte +301 -209
  167. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  168. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  169. package/dist/plot/box/box-plot.js +1 -1
  170. package/dist/plot/core/auto-place.js +1 -1
  171. package/dist/plot/core/axis-utils.d.ts +12 -7
  172. package/dist/plot/core/axis-utils.js +48 -48
  173. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  174. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  175. package/dist/plot/core/components/ColorBar.svelte +101 -106
  176. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  177. package/dist/plot/core/components/FillArea.svelte +10 -17
  178. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  179. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  180. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  181. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  182. package/dist/plot/core/components/Line.svelte +18 -9
  183. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  184. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  185. package/dist/plot/core/components/PlotControls.svelte +65 -41
  186. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  187. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  188. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  189. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  190. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  191. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  192. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  193. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  194. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  195. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  196. package/dist/plot/core/components/index.d.ts +1 -0
  197. package/dist/plot/core/components/index.js +1 -0
  198. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  199. package/dist/plot/core/data-cleaning-signal.js +467 -0
  200. package/dist/plot/core/data-cleaning.d.ts +2 -42
  201. package/dist/plot/core/data-cleaning.js +27 -474
  202. package/dist/plot/core/data-transform.js +9 -5
  203. package/dist/plot/core/fill-utils.d.ts +3 -1
  204. package/dist/plot/core/fill-utils.js +28 -6
  205. package/dist/plot/core/index.d.ts +1 -0
  206. package/dist/plot/core/index.js +1 -0
  207. package/dist/plot/core/interactions.js +0 -2
  208. package/dist/plot/core/layout.d.ts +3 -1
  209. package/dist/plot/core/layout.js +22 -13
  210. package/dist/plot/core/marginals.d.ts +170 -0
  211. package/dist/plot/core/marginals.js +436 -0
  212. package/dist/plot/core/reference-line.js +1 -1
  213. package/dist/plot/core/scales.d.ts +23 -0
  214. package/dist/plot/core/scales.js +39 -13
  215. package/dist/plot/core/types/fills.d.ts +101 -0
  216. package/dist/plot/core/types/fills.js +15 -0
  217. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  218. package/dist/plot/core/types/plot-3d.js +4 -0
  219. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  220. package/dist/plot/core/types/reference-lines.js +9 -0
  221. package/dist/plot/core/types.d.ts +29 -324
  222. package/dist/plot/core/types.js +23 -20
  223. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  224. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  225. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  226. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  227. package/dist/plot/core/utils/label-placement.js +2 -2
  228. package/dist/plot/histogram/Histogram.svelte +304 -325
  229. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  230. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  231. package/dist/plot/histogram/histogram.d.ts +31 -0
  232. package/dist/plot/histogram/histogram.js +70 -0
  233. package/dist/plot/histogram/index.d.ts +1 -0
  234. package/dist/plot/histogram/index.js +1 -0
  235. package/dist/plot/index.d.ts +1 -0
  236. package/dist/plot/index.js +1 -0
  237. package/dist/plot/sankey/Sankey.svelte +78 -69
  238. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  239. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  240. package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
  241. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  242. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  243. package/dist/plot/scatter/ScatterPlot.svelte +477 -385
  244. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  245. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  246. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  247. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  248. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  249. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  250. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  251. package/dist/plot/scatter/scatter-data.js +8 -7
  252. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  253. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  254. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  255. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  256. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  257. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  258. package/dist/plot/sunburst/Sunburst.svelte +251 -329
  259. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  260. package/dist/plot/sunburst/index.d.ts +1 -1
  261. package/dist/plot/sunburst/index.js +2 -1
  262. package/dist/plot/sunburst/render.d.ts +2 -2
  263. package/dist/plot/sunburst/render.js +47 -22
  264. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  265. package/dist/plot/sunburst/sunburst.js +10 -3
  266. package/dist/plot/treemap/Treemap.svelte +907 -0
  267. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  268. package/dist/plot/treemap/index.d.ts +3 -0
  269. package/dist/plot/treemap/index.js +4 -0
  270. package/dist/plot/treemap/treemap.d.ts +26 -0
  271. package/dist/plot/treemap/treemap.js +99 -0
  272. package/dist/rdf/RdfPlot.svelte +22 -26
  273. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  274. package/dist/rdf/calc-rdf.js +4 -8
  275. package/dist/sanitize.js +1 -1
  276. package/dist/scene/bind-renderer.svelte.js +14 -6
  277. package/dist/settings.d.ts +19 -9
  278. package/dist/settings.js +77 -50
  279. package/dist/spectral/Bands.svelte +223 -230
  280. package/dist/spectral/BandsAndDos.svelte +11 -9
  281. package/dist/spectral/BrillouinBandsDos.svelte +19 -27
  282. package/dist/spectral/Dos.svelte +70 -73
  283. package/dist/spectral/helpers.d.ts +3 -3
  284. package/dist/spectral/helpers.js +25 -35
  285. package/dist/state.svelte.js +5 -18
  286. package/dist/structure/Arrow.svelte +5 -18
  287. package/dist/structure/ArrowInstances.svelte +160 -0
  288. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  289. package/dist/structure/AtomLegend.svelte +115 -75
  290. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  291. package/dist/structure/Bond.svelte +31 -23
  292. package/dist/structure/CanvasTooltip.svelte +15 -3
  293. package/dist/structure/CellSelect.svelte +11 -26
  294. package/dist/structure/Cylinder.svelte +24 -40
  295. package/dist/structure/InstancedAtoms.svelte +114 -0
  296. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  297. package/dist/structure/Lattice.svelte +85 -149
  298. package/dist/structure/SiteLabels.svelte +122 -0
  299. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  300. package/dist/structure/Structure.svelte +473 -419
  301. package/dist/structure/Structure.svelte.d.ts +4 -2
  302. package/dist/structure/StructureCarousel.svelte +630 -0
  303. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  304. package/dist/structure/StructureControls.svelte +157 -399
  305. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  306. package/dist/structure/StructureExportPane.svelte +17 -21
  307. package/dist/structure/StructureInfoPane.svelte +72 -66
  308. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  309. package/dist/structure/StructureScene.svelte +467 -476
  310. package/dist/structure/StructureScene.svelte.d.ts +3 -1
  311. package/dist/structure/StructureViewport.svelte +386 -0
  312. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  313. package/dist/structure/atom-label-placement.d.ts +16 -12
  314. package/dist/structure/atom-label-placement.js +70 -37
  315. package/dist/structure/atom-properties.d.ts +2 -0
  316. package/dist/structure/atom-properties.js +104 -38
  317. package/dist/structure/bonding.d.ts +10 -3
  318. package/dist/structure/bonding.js +84 -28
  319. package/dist/structure/edit-history.d.ts +6 -0
  320. package/dist/structure/edit-history.js +27 -0
  321. package/dist/structure/export.d.ts +1 -0
  322. package/dist/structure/export.js +39 -31
  323. package/dist/structure/format-detect.d.ts +1 -0
  324. package/dist/structure/format-detect.js +22 -0
  325. package/dist/structure/geometry.d.ts +9 -0
  326. package/dist/structure/geometry.js +27 -0
  327. package/dist/structure/index.d.ts +16 -1
  328. package/dist/structure/index.js +13 -2
  329. package/dist/structure/measure.d.ts +1 -1
  330. package/dist/structure/measure.js +6 -12
  331. package/dist/structure/parse.d.ts +2 -1
  332. package/dist/structure/parse.js +243 -222
  333. package/dist/structure/partial-occupancy.js +4 -2
  334. package/dist/structure/pbc.js +78 -98
  335. package/dist/structure/polyhedra.d.ts +0 -1
  336. package/dist/structure/polyhedra.js +3 -18
  337. package/dist/structure/supercell.d.ts +1 -2
  338. package/dist/structure/supercell.js +7 -13
  339. package/dist/symmetry/SymmetryElements.svelte +11 -15
  340. package/dist/symmetry/SymmetryStats.svelte +56 -68
  341. package/dist/symmetry/WyckoffTable.svelte +5 -24
  342. package/dist/symmetry/cell-transform.js +1 -0
  343. package/dist/symmetry/index.d.ts +1 -0
  344. package/dist/symmetry/index.js +8 -2
  345. package/dist/symmetry/spacegroups.js +3 -2
  346. package/dist/table/HeatmapTable.svelte +1102 -365
  347. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  348. package/dist/table/ToggleMenu.svelte +5 -12
  349. package/dist/table/index.d.ts +21 -6
  350. package/dist/table/index.js +34 -21
  351. package/dist/theme/ThemeControl.svelte +16 -8
  352. package/dist/theme/index.d.ts +1 -5
  353. package/dist/theme/index.js +4 -10
  354. package/dist/theme/themes.mjs +14 -7
  355. package/dist/tooltip/KCoords.svelte +4 -1
  356. package/dist/tooltip/TooltipContent.svelte +2 -5
  357. package/dist/trajectory/Trajectory.svelte +515 -308
  358. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  359. package/dist/trajectory/TrajectoryError.svelte +11 -8
  360. package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
  361. package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
  362. package/dist/trajectory/extract.js +56 -34
  363. package/dist/trajectory/format-detect.js +11 -9
  364. package/dist/trajectory/frame-reader.d.ts +2 -0
  365. package/dist/trajectory/frame-reader.js +33 -29
  366. package/dist/trajectory/helpers.d.ts +2 -0
  367. package/dist/trajectory/helpers.js +18 -7
  368. package/dist/trajectory/index.d.ts +1 -0
  369. package/dist/trajectory/index.js +3 -0
  370. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  371. package/dist/trajectory/parse/h5-utils.js +109 -0
  372. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  373. package/dist/trajectory/parse/hdf5.js +116 -106
  374. package/dist/trajectory/parse/index.d.ts +2 -3
  375. package/dist/trajectory/parse/index.js +17 -20
  376. package/dist/trajectory/parse/lammps.js +8 -12
  377. package/dist/trajectory/parse/vasp.js +10 -7
  378. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  379. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  380. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  381. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  382. package/dist/trajectory/parse/xyz.js +11 -7
  383. package/dist/trajectory/plotting.d.ts +8 -9
  384. package/dist/trajectory/plotting.js +99 -27
  385. package/dist/utils.d.ts +3 -0
  386. package/dist/utils.js +7 -0
  387. package/dist/xrd/XrdPlot.svelte +47 -61
  388. package/dist/xrd/broadening.js +2 -1
  389. package/dist/xrd/calc-xrd.js +2 -4
  390. package/dist/xrd/parse.d.ts +0 -1
  391. package/dist/xrd/parse.js +56 -73
  392. package/package.json +61 -33
  393. package/dist/api/mp.d.ts +0 -6
  394. package/dist/api/mp.js +0 -22
  395. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
@@ -34,11 +34,7 @@
34
34
  const pattern_obj = obj as { x?: unknown; y?: unknown }
35
35
  const x_vals = pattern_obj.x
36
36
  const y_vals = pattern_obj.y
37
- return (
38
- Array.isArray(x_vals) &&
39
- Array.isArray(y_vals) &&
40
- x_vals.length === y_vals.length
41
- )
37
+ return Array.isArray(x_vals) && Array.isArray(y_vals) && x_vals.length === y_vals.length
42
38
  }
43
39
 
44
40
  function format_hkl(hkl: Hkl, format: HklFormat): string {
@@ -82,10 +78,8 @@
82
78
  broadening_params = $bindable({ ...DEFAULT_BROADENING }),
83
79
  controls = {},
84
80
  ...rest
85
- }:
86
- & ComponentProps<typeof BarPlot>
87
- & ComponentProps<typeof ScatterPlot>
88
- & {
81
+ }: ComponentProps<typeof BarPlot> &
82
+ ComponentProps<typeof ScatterPlot> & {
89
83
  patterns:
90
84
  | XrdPattern
91
85
  | Record<string, XrdPattern | { pattern: XrdPattern; color?: string }>
@@ -115,25 +109,18 @@
115
109
  const base_entries = Array.isArray(patterns)
116
110
  ? (patterns as PatternEntry[])
117
111
  : is_xrd_pattern(patterns)
118
- ? [{ label: `XRD Pattern`, pattern: patterns as XrdPattern }]
119
- : Object.entries(
120
- patterns as Record<
121
- string,
122
- XrdPattern | { pattern: XrdPattern; color?: string }
123
- >,
124
- ).map(([label, value]) =>
125
- `pattern` in value
126
- ? { label, ...value }
127
- : { label, pattern: value as XrdPattern }
128
- )
112
+ ? [{ label: `XRD Pattern`, pattern: patterns as XrdPattern }]
113
+ : Object.entries(
114
+ patterns as Record<string, XrdPattern | { pattern: XrdPattern; color?: string }>,
115
+ ).map(([label, value]) =>
116
+ `pattern` in value ? { label, ...value } : { label, pattern: value as XrdPattern },
117
+ )
129
118
  // Merge user-provided patterns with any dropped-on-the-fly entries
130
119
  return [...base_entries, ...dropped_entries]
131
120
  })
132
121
 
133
122
  // Decide default show_angles
134
- const actual_show_angles = $derived(
135
- show_angles ?? pattern_entries.length <= 2,
136
- )
123
+ const actual_show_angles = $derived(show_angles ?? pattern_entries.length <= 2)
137
124
 
138
125
  // Compute global max intensity for normalization (as in pymatviz xrd_pattern)
139
126
  const global_max_intensity = $derived.by(() => {
@@ -221,12 +208,11 @@
221
208
  metadata.push({ hkls, d: d_hkl, label: entry.label })
222
209
 
223
210
  if (selected_indices.includes(idx)) {
224
- const angle_text = actual_show_angles
225
- ? `${format_value(xs[idx], `.2f`)}°`
226
- : ``
227
- const hkl_text = hkls && hkl_format
228
- ? hkls.map((hkl_val) => format_hkl(hkl_val, hkl_format)).join(`, `)
229
- : ``
211
+ const angle_text = actual_show_angles ? `${format_value(xs[idx], `.2f`)}°` : ``
212
+ const hkl_text =
213
+ hkls && hkl_format
214
+ ? hkls.map((hkl_val) => format_hkl(hkl_val, hkl_format)).join(`, `)
215
+ : ``
230
216
  // Use @ separator between hkl and angle for better clarity
231
217
  const separator = hkl_text && angle_text ? ` @ ` : ``
232
218
  const text = [hkl_text, angle_text].filter(Boolean).join(separator)
@@ -305,10 +291,7 @@
305
291
  loading = true
306
292
  error_msg = undefined
307
293
 
308
- const compute_and_add = async (
309
- content: string | ArrayBuffer,
310
- filename: string,
311
- ) => {
294
+ const compute_and_add = async (content: string | ArrayBuffer, filename: string) => {
312
295
  const result = await add_xrd_pattern(content, filename, wavelength)
313
296
  if (result.error) {
314
297
  error_msg = result.error
@@ -319,10 +302,9 @@
319
302
 
320
303
  try {
321
304
  // Handle URL-based drops
322
- const handled = await handle_url_drop(
323
- event,
324
- on_file_drop || compute_and_add,
325
- ).catch(() => false)
305
+ const handled = await handle_url_drop(event, on_file_drop || compute_and_add).catch(
306
+ () => false,
307
+ )
326
308
  if (handled) return
327
309
 
328
310
  const file = event.dataTransfer?.files?.[0]
@@ -332,7 +314,7 @@
332
314
  const compression_format = detect_compression_format(lower_name)
333
315
  // Get base filename without compression extension
334
316
  const base_name = compression_format
335
- ? lower_name.replace(/\.(gz|gzip)$/i, ``)
317
+ ? lower_name.replace(/\.(?:gz|gzip)$/i, ``)
336
318
  : lower_name
337
319
  const base_ext = base_name.split(`.`).pop()
338
320
 
@@ -353,9 +335,7 @@
353
335
  if (content) await (on_file_drop || compute_and_add)(content, filename)
354
336
  }
355
337
  } catch (exc) {
356
- error_msg = `Failed to load file ${file.name}: ${
357
- to_error(exc).message
358
- }`
338
+ error_msg = `Failed to load file ${file.name}: ${to_error(exc).message}`
359
339
  }
360
340
  }
361
341
  } finally {
@@ -381,11 +361,9 @@
381
361
  </label>
382
362
 
383
363
  {#if broadening_enabled}
384
- <div
385
- class="pane-grid"
386
- style="display: grid; grid-template-columns: 1fr 1fr; gap: 1ex"
387
- >
388
- <label title="Caglioti U parameter">U:
364
+ <div class="pane-grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: 1ex">
365
+ <label title="Caglioti U parameter"
366
+ >U:
389
367
  <input
390
368
  type="number"
391
369
  step="0.001"
@@ -393,7 +371,8 @@
393
371
  class="param-input"
394
372
  />
395
373
  </label>
396
- <label title="Caglioti V parameter">V:
374
+ <label title="Caglioti V parameter"
375
+ >V:
397
376
  <input
398
377
  type="number"
399
378
  step="0.001"
@@ -401,7 +380,8 @@
401
380
  class="param-input"
402
381
  />
403
382
  </label>
404
- <label title="Caglioti W parameter">W:
383
+ <label title="Caglioti W parameter"
384
+ >W:
405
385
  <input
406
386
  type="number"
407
387
  step="0.001"
@@ -409,7 +389,8 @@
409
389
  class="param-input"
410
390
  />
411
391
  </label>
412
- <label title="Pseudo-Voigt shape factor (0=Gaussian, 1=Lorentzian)">η:
392
+ <label title="Pseudo-Voigt shape factor (0=Gaussian, 1=Lorentzian)"
393
+ >η:
413
394
  <input
414
395
  type="number"
415
396
  min="0"
@@ -438,8 +419,8 @@
438
419
  {:else}
439
420
  <StatusMessage
440
421
  message={allow_file_drop
441
- ? `Drag and drop structure files (.cif, .json, etc.) or XRD data files (.xy, .csv, .ras, .uxd, .gsas, .xrdml, .brml, .raw, + .gz) here`
442
- : `No XRD data to display`}
422
+ ? `Drag and drop structure files (.cif, .json, etc.) or XRD data files (.xy, .csv, .ras, .uxd, .gsas, .xrdml, .brml, .raw, + .gz) here`
423
+ : `No XRD data to display`}
443
424
  />
444
425
  {/if}
445
426
  </EmptyState>
@@ -475,24 +456,26 @@
475
456
  }}
476
457
  {tooltip}
477
458
  ondrop={handle_file_drop}
478
- {...drag_over_handlers({ allow: () => allow_file_drop, set_dragover: (over) => dragover = over })}
479
- class={(rest.class ?? ``) + (dragover ? ` dragover` : ``)}
459
+ {...drag_over_handlers({
460
+ allow: () => allow_file_drop,
461
+ set_dragover: (over) => (dragover = over),
462
+ })}
463
+ class={[rest.class, dragover && `dragover`]}
480
464
  style={`overflow: visible; ${rest.style ?? ``}`}
481
465
  {controls}
482
466
  controls_extra={broadening_controls_snippet}
483
467
  />
484
468
  {:else}
485
469
  <!-- Discrete Stick View -->
486
- {#snippet tooltip(
487
- info: BarHandlerProps<{ label?: string; hkls?: Hkl[]; d?: number }>,
488
- )}
470
+ {#snippet tooltip(info: BarHandlerProps<{ label?: string; hkls?: Hkl[]; d?: number }>)}
489
471
  {@const angle_text = `${format_value(info.x, `.2f`)}°`}
490
472
  {@const intensity_text = `${format_value(info.y, `.1f`)}`}
491
473
  {@const hkls = info.metadata?.hkls}
492
474
  {@const d_spacing = info.metadata?.d}
493
- {@const hkl_text = hkls && hkl_format
494
- ? hkls.map((hkl: Hkl) => format_hkl(hkl, hkl_format)).join(`, `)
495
- : ``}
475
+ {@const hkl_text =
476
+ hkls && hkl_format
477
+ ? hkls.map((hkl: Hkl) => format_hkl(hkl, hkl_format)).join(`, `)
478
+ : ``}
496
479
  {@const d_text = d_spacing != null ? `${format_value(d_spacing, `.3f`)} Å` : ``}
497
480
  {@html sanitize_html(info.metadata?.label ?? ``)}<br />
498
481
  2θ: {angle_text}<br />
@@ -526,8 +509,11 @@
526
509
  }}
527
510
  {tooltip}
528
511
  ondrop={handle_file_drop}
529
- {...drag_over_handlers({ allow: () => allow_file_drop, set_dragover: (over) => dragover = over })}
530
- class={(rest.class ?? ``) + (dragover ? ` dragover` : ``)}
512
+ {...drag_over_handlers({
513
+ allow: () => allow_file_drop,
514
+ set_dragover: (over) => (dragover = over),
515
+ })}
516
+ class={[rest.class, dragover && `dragover`]}
531
517
  style={`overflow: visible; ${rest.style ?? ``}`}
532
518
  show_controls={controls.show}
533
519
  controls_open={controls.open}
@@ -1,3 +1,4 @@
1
+ import { clamp01 } from '../utils';
1
2
  const LOG_2 = Math.log(2);
2
3
  export const DEFAULT_BROADENING = {
3
4
  U: 0.04,
@@ -43,7 +44,7 @@ fwhm, // Full Width at Half Maximum
43
44
  eta) {
44
45
  // Intensity at x
45
46
  // Clamp eta to [0, 1]
46
- const safe_eta = Math.max(0, Math.min(1, eta));
47
+ const safe_eta = clamp01(eta);
47
48
  return safe_eta * lorentzian(x, x0, fwhm) + (1 - safe_eta) * gaussian(x, x0, fwhm);
48
49
  }
49
50
  // Computes a broadened XRD pattern from discrete peaks.
@@ -121,9 +121,7 @@ export function compute_xrd_pattern(structure, options = {}) {
121
121
  }
122
122
  wavelength = WAVELENGTHS[wl_input];
123
123
  }
124
- // Symmetry refinement (symprec > 0) is not implemented in TS version.
125
- // Option retained for API parity.
126
- // const symprec = options.symprec ?? 0
124
+ // Symmetry refinement (symprec > 0) is not implemented in TS version. Option retained for API parity.
127
125
  // For row-wise lattice matrix A (rows are a, b, c), reciprocal rows are inv(A)^T
128
126
  const recip_rows = math.transpose_3x3_matrix(math.matrix_inverse_3x3(structure.lattice.matrix));
129
127
  // Bragg condition bounds: reciprocal vector length r = 2 sin(theta) / lambda
@@ -259,7 +257,7 @@ export function compute_xrd_pattern(structure, options = {}) {
259
257
  const fam = get_unique_families(item.hkls);
260
258
  const fam_array = [];
261
259
  for (const [repr_key, multiplicity] of fam.entries()) {
262
- const repr = repr_key.split(`,`).map((num_str) => parseInt(num_str, 10));
260
+ const repr = repr_key.split(`,`).map(Number);
263
261
  fam_array.push({ hkl: repr, multiplicity });
264
262
  }
265
263
  hkls_out.push(fam_array);
@@ -1,6 +1,5 @@
1
1
  import type { XrdPattern } from './index';
2
2
  export declare function parse_xy_file(content: string): XrdPattern | null;
3
- export declare function parse_xye_file(content: string): XrdPattern | null;
4
3
  export declare function parse_ras_file(content: string): XrdPattern | null;
5
4
  export declare function parse_uxd_file(content: string): XrdPattern | null;
6
5
  export declare function parse_gsas_file(content: string): XrdPattern | null;
package/dist/xrd/parse.js CHANGED
@@ -20,13 +20,24 @@ const parse_number_list = (text) => text
20
20
  .split(/\s+/)
21
21
  .map(parseFloat)
22
22
  .filter((val) => !isNaN(val));
23
+ // Return the first parseable number from the text content of any of `tags`
24
+ // (in order) that also passes the optional `ok` predicate. Null when none match.
25
+ const query_first_number = (doc, tags, ok = () => true) => {
26
+ for (const tag of tags) {
27
+ const text = doc.querySelector(tag)?.textContent?.trim();
28
+ const val = text ? Number(text) : NaN;
29
+ if (!isNaN(val) && ok(val))
30
+ return val;
31
+ }
32
+ return null;
33
+ };
23
34
  // Extract numeric value from header line matching "KEY=VALUE" or "KEY VALUE" pattern.
24
35
  // Returns null if not found or not a valid number.
25
36
  function extract_header_value(lines, key_pattern) {
26
37
  for (const line of lines) {
27
38
  const match = line.match(key_pattern);
28
39
  if (match?.[1]) {
29
- const val = parseFloat(match[1]);
40
+ const val = Number(match[1]);
30
41
  if (!isNaN(val))
31
42
  return val;
32
43
  }
@@ -53,17 +64,17 @@ function normalize_and_subsample(x_values, y_values) {
53
64
  }
54
65
  // Subsample data while preserving peaks (local maxima).
55
66
  // Uses a combination of uniform sampling and peak preservation.
56
- function subsample_preserve_peaks(x_values, y_values, target_points) {
57
- const num_points = x_values.length;
67
+ function subsample_preserve_peaks(x_vals, y_vals, target_points) {
68
+ const num_points = x_vals.length;
58
69
  if (num_points <= target_points)
59
- return { x: x_values, y: y_values };
70
+ return { x: x_vals, y: y_vals };
60
71
  // Find peaks (local maxima with significant height)
61
72
  const peaks = [];
62
- const threshold = Math.max(...y_values) * 0.05; // 5% of max as significance threshold
73
+ const threshold = Math.max(...y_vals) * 0.05; // 5% of max as significance threshold
63
74
  for (let idx = 1; idx < num_points - 1; idx++) {
64
- if (y_values[idx] > y_values[idx - 1] &&
65
- y_values[idx] > y_values[idx + 1] &&
66
- y_values[idx] > threshold) {
75
+ if (y_vals[idx] > y_vals[idx - 1] &&
76
+ y_vals[idx] > y_vals[idx + 1] &&
77
+ y_vals[idx] > threshold) {
67
78
  peaks.push(idx);
68
79
  }
69
80
  }
@@ -72,7 +83,7 @@ function subsample_preserve_peaks(x_values, y_values, target_points) {
72
83
  const uniform_slots = target_points - peak_slots;
73
84
  // Select top peaks by height
74
85
  const top_peaks = peaks
75
- .map((idx) => ({ idx, y: y_values[idx] }))
86
+ .map((idx) => ({ idx, y: y_vals[idx] }))
76
87
  .sort((a, b) => b.y - a.y)
77
88
  .slice(0, peak_slots)
78
89
  .map((peak) => peak.idx);
@@ -90,8 +101,8 @@ function subsample_preserve_peaks(x_values, y_values, target_points) {
90
101
  // Merge and sort all selected indices
91
102
  const selected = [...new Set([...uniform_indices, ...top_peaks])].sort((a, b) => a - b);
92
103
  return {
93
- x: selected.map((idx) => x_values[idx]),
94
- y: selected.map((idx) => y_values[idx]),
104
+ x: selected.map((idx) => x_vals[idx]),
105
+ y: selected.map((idx) => y_vals[idx]),
95
106
  };
96
107
  }
97
108
  // Parse a two-column ASCII file containing XRD data (2θ, intensity).
@@ -110,8 +121,8 @@ export function parse_xy_file(content) {
110
121
  const parts = trimmed.split(/[\s,]+/).filter(Boolean);
111
122
  if (parts.length < 2)
112
123
  continue;
113
- const two_theta = parseFloat(parts[0]);
114
- const intensity = parseFloat(parts[1]);
124
+ const two_theta = Number(parts[0]);
125
+ const intensity = Number(parts[1]);
115
126
  if (!isNaN(two_theta) && !isNaN(intensity)) {
116
127
  x_values.push(two_theta);
117
128
  y_values.push(intensity);
@@ -122,24 +133,17 @@ export function parse_xy_file(content) {
122
133
  const normalized = normalize_and_subsample(x_values, y_values);
123
134
  return { x: normalized.x, y: normalized.y };
124
135
  }
125
- // Parse a .xye file containing three-column XRD data (2θ, intensity, error).
126
- // Same as .xy but with an optional third column for uncertainties (ignored for plotting).
127
- export function parse_xye_file(content) {
128
- // XYE is just XY with an extra error column - reuse parse_xy_file which already
129
- // handles extra columns by only taking the first two
130
- return parse_xy_file(content);
131
- }
132
136
  // Parse a Rigaku .ras file (ASCII format with structured header).
133
137
  // Format: *RAS_HEADER_START ... *RAS_HEADER_END followed by *RAS_INT_START ... *RAS_INT_END
134
138
  // Data can be single-column (intensity only) or multi-column (2-theta, intensity, [error])
135
139
  export function parse_ras_file(content) {
136
140
  const lines = content.split(/\r?\n/);
137
141
  // Extract header values (used as fallback for single-column data)
138
- const header_start = extract_header_value(lines, /\*MEAS_SCAN_START\s*=\s*([\d.+-]+)/i) ??
139
- extract_header_value(lines, /\*SCAN_START\s*=\s*([\d.+-]+)/i) ??
142
+ const header_start = extract_header_value(lines, /\*MEAS_SCAN_START\s*=\s*(?<value>[\d.+-]+)/i) ??
143
+ extract_header_value(lines, /\*SCAN_START\s*=\s*(?<value>[\d.+-]+)/i) ??
140
144
  0;
141
- const header_step = extract_header_value(lines, /\*MEAS_SCAN_STEP\s*=\s*([\d.+-]+)/i) ??
142
- extract_header_value(lines, /\*SCAN_STEP\s*=\s*([\d.+-]+)/i) ??
145
+ const header_step = extract_header_value(lines, /\*MEAS_SCAN_STEP\s*=\s*(?<value>[\d.+-]+)/i) ??
146
+ extract_header_value(lines, /\*SCAN_STEP\s*=\s*(?<value>[\d.+-]+)/i) ??
143
147
  DEFAULT_STEP_SIZE;
144
148
  // Find intensity data section between *RAS_INT_START and *RAS_INT_END
145
149
  // Also handle older format with *RAS_DATA_START
@@ -204,11 +208,11 @@ export function parse_ras_file(content) {
204
208
  export function parse_uxd_file(content) {
205
209
  const lines = content.split(/\r?\n/);
206
210
  // Extract header values (underscore-prefixed keys)
207
- const start = extract_header_value(lines, /_2THETA_?START\s*=?\s*([\d.+-]+)/i) ??
208
- extract_header_value(lines, /_START\s*=?\s*([\d.+-]+)/i) ??
211
+ const start = extract_header_value(lines, /_2THETA_?START\s*=?\s*(?<value>[\d.+-]+)/i) ??
212
+ extract_header_value(lines, /_START\s*=?\s*(?<value>[\d.+-]+)/i) ??
209
213
  0;
210
- const step = extract_header_value(lines, /_STEP_?SIZE\s*=?\s*([\d.+-]+)/i) ??
211
- extract_header_value(lines, /_STEPWIDTH\s*=?\s*([\d.+-]+)/i) ??
214
+ const step = extract_header_value(lines, /_STEP_?SIZE\s*=?\s*(?<value>[\d.+-]+)/i) ??
215
+ extract_header_value(lines, /_STEPWIDTH\s*=?\s*(?<value>[\d.+-]+)/i) ??
212
216
  DEFAULT_STEP_SIZE;
213
217
  // Find intensity data after _COUNTS marker
214
218
  let in_data_section = false;
@@ -247,13 +251,13 @@ export function parse_gsas_file(content) {
247
251
  let bin_type = `CONST`; // CONST, RALF, or others
248
252
  let found_bank = false;
249
253
  for (const line of lines) {
250
- const bank_match = /BANK\s+\d+\s+(\d+)\s+\d+\s+(\w+)\s+([\d.+-]+)\s+([\d.+-]+)/i.exec(line);
254
+ const bank_match = /BANK\s+\d+\s+(?<npts>\d+)\s+\d+\s+(?<bin_type>\w+)\s+(?<bcoef1>[\d.+-]+)\s+(?<bcoef2>[\d.+-]+)/i.exec(line);
251
255
  if (bank_match) {
252
256
  bin_type = bank_match[2].toUpperCase();
253
257
  // For CONST type: BCOEF1 is start*100 (centidegrees), BCOEF2 is step*100
254
258
  if (bin_type === `CONST`) {
255
- start = parseFloat(bank_match[3]) / 100; // Convert centidegrees to degrees
256
- step = parseFloat(bank_match[4]) / 100;
259
+ start = Number(bank_match[3]) / 100; // Convert centidegrees to degrees
260
+ step = Number(bank_match[4]) / 100;
257
261
  }
258
262
  else if (bin_type !== `FXYE`) {
259
263
  // Other bin types like RALF (time-of-flight) are not fully supported
@@ -335,15 +339,15 @@ function parse_bruker_raw_v1(view, bytes) {
335
339
  // V1 has ASCII header with scan parameters followed by binary data
336
340
  const header_text = String.fromCharCode(...bytes.slice(0, 512));
337
341
  // Try to find scan parameters in ASCII header
338
- const start_match = /START\s*=\s*([\d.+-]+)/i.exec(header_text);
339
- const step_match = /STEP\s*=\s*([\d.+-]+)/i.exec(header_text);
340
- const count_match = /(?:COUNT|POINTS|NPTS)\s*=\s*(\d+)/i.exec(header_text);
341
- const start = start_match ? parseFloat(start_match[1]) : 0;
342
- const step = step_match ? parseFloat(step_match[1]) : DEFAULT_STEP_SIZE;
342
+ const start_match = /START\s*=\s*(?<value>[\d.+-]+)/i.exec(header_text);
343
+ const step_match = /STEP\s*=\s*(?<value>[\d.+-]+)/i.exec(header_text);
344
+ const count_match = /(?:COUNT|POINTS|NPTS)\s*=\s*(?<value>\d+)/i.exec(header_text);
345
+ const start = start_match ? Number(start_match[1]) : 0;
346
+ const step = step_match ? Number(step_match[1]) : DEFAULT_STEP_SIZE;
343
347
  // Find where binary data starts (after header)
344
348
  let data_offset = 512;
345
349
  if (count_match) {
346
- const expected_count = parseInt(count_match[1], 10);
350
+ const expected_count = Math.trunc(Number(count_match[1]));
347
351
  // Binary data is typically 4 bytes per intensity (float32)
348
352
  data_offset = bytes.length - expected_count * 4;
349
353
  }
@@ -399,14 +403,14 @@ function parse_rigaku_raw_file(data) {
399
403
  const bytes = new Uint8Array(data);
400
404
  // Try to find ASCII header section with scan parameters
401
405
  const header_text = String.fromCharCode(...bytes.slice(0, Math.min(2048, bytes.length)));
402
- const start_match = /(?:START|2THETA_START|SCAN_START)\s*[:=]?\s*([\d.+-]+)/i.exec(header_text);
403
- const step_match = /(?:STEP|STEP_SIZE|SCAN_STEP)\s*[:=]?\s*([\d.+-]+)/i.exec(header_text);
404
- const count_match = /(?:COUNT|POINTS|NPTS|STEPS)\s*[:=]?\s*(\d+)/i.exec(header_text);
406
+ const start_match = /(?:START|2THETA_START|SCAN_START)\s*[:=]?\s*(?<value>[\d.+-]+)/i.exec(header_text);
407
+ const step_match = /(?:STEP|STEP_SIZE|SCAN_STEP)\s*[:=]?\s*(?<value>[\d.+-]+)/i.exec(header_text);
408
+ const count_match = /(?:COUNT|POINTS|NPTS|STEPS)\s*[:=]?\s*(?<value>\d+)/i.exec(header_text);
405
409
  if (!start_match && !step_match && !count_match)
406
410
  return null; // Not a recognizable Rigaku format
407
- const start = start_match ? parseFloat(start_match[1]) : 0;
408
- const step = step_match ? parseFloat(step_match[1]) : DEFAULT_STEP_SIZE;
409
- const expected_count = count_match ? parseInt(count_match[1], 10) : 0;
411
+ const start = start_match ? Number(start_match[1]) : 0;
412
+ const step = step_match ? Number(step_match[1]) : DEFAULT_STEP_SIZE;
413
+ const expected_count = count_match ? Math.trunc(Number(count_match[1])) : 0;
410
414
  // Find binary data section
411
415
  // Rigaku typically stores intensities as 32-bit floats or integers
412
416
  let data_offset = 0;
@@ -538,7 +542,7 @@ function extract_scan_parameters_xml(doc) {
538
542
  const intensity_elements = doc.querySelectorAll(`I, Count`);
539
543
  if (intensity_elements.length > 0) {
540
544
  intensities = Array.from(intensity_elements)
541
- .map((el) => parseFloat(el.textContent || ``))
545
+ .map((el) => Number(el.textContent?.trim() || NaN))
542
546
  .filter((val) => !isNaN(val));
543
547
  }
544
548
  }
@@ -559,9 +563,9 @@ function extract_scan_parameters_xml(doc) {
559
563
  const parts = text.split(`,`);
560
564
  // Need at least 5 columns: time, flag, 2Theta, Theta/Omega, Intensity
561
565
  if (parts.length >= 5) {
562
- const two_theta = parseFloat(parts[2]);
566
+ const two_theta = Number(parts[2]);
563
567
  // Intensity is always the last column
564
- const intensity = parseFloat(parts[parts.length - 1]);
568
+ const intensity = Number(parts[parts.length - 1]);
565
569
  if (!isNaN(two_theta) && !isNaN(intensity)) {
566
570
  two_theta_values.push(two_theta);
567
571
  intensities.push(intensity);
@@ -582,9 +586,7 @@ function extract_scan_parameters_xml(doc) {
582
586
  if (!intensities?.length)
583
587
  return null;
584
588
  // Extract scan range parameters
585
- let start_angle = 0;
586
- let step_size = DEFAULT_STEP_SIZE;
587
- // Try to find start angle - multiple possible locations
589
+ // Try multiple possible tag names, returning the first that parses (and passes `ok`)
588
590
  const start_candidates = [
589
591
  `Start`,
590
592
  `TwoThetaStart`,
@@ -593,17 +595,6 @@ function extract_scan_parameters_xml(doc) {
593
595
  `ScanAxisBeginPosition`,
594
596
  `Begin`,
595
597
  ];
596
- for (const tag of start_candidates) {
597
- const el = doc.querySelector(tag);
598
- if (el?.textContent) {
599
- const val = parseFloat(el.textContent);
600
- if (!isNaN(val)) {
601
- start_angle = val;
602
- break;
603
- }
604
- }
605
- }
606
- // Try to find step size - multiple possible locations
607
598
  const step_candidates = [
608
599
  `Step`,
609
600
  `StepSize`,
@@ -612,23 +603,15 @@ function extract_scan_parameters_xml(doc) {
612
603
  `ScanAxisIncrement`,
613
604
  `StepWidth`,
614
605
  ];
615
- for (const tag of step_candidates) {
616
- const el = doc.querySelector(tag);
617
- if (el?.textContent) {
618
- const val = parseFloat(el.textContent);
619
- if (!isNaN(val) && val > 0) {
620
- step_size = val;
621
- break;
622
- }
623
- }
624
- }
606
+ const start_angle = query_first_number(doc, start_candidates) ?? 0;
607
+ let step_size = query_first_number(doc, step_candidates, (val) => val > 0) ?? DEFAULT_STEP_SIZE;
625
608
  // Alternative: calculate step from start/end and count
626
609
  if (step_size === DEFAULT_STEP_SIZE) {
627
610
  const end_candidates = [`Stop`, `TwoThetaEnd`, `EndPosition`, `2ThetaEnd`, `End`];
628
611
  for (const tag of end_candidates) {
629
612
  const el = doc.querySelector(tag);
630
613
  if (el?.textContent) {
631
- const end_val = parseFloat(el.textContent);
614
+ const end_val = Number(el.textContent);
632
615
  if (!isNaN(end_val) && end_val > start_angle && intensities.length > 1) {
633
616
  step_size = (end_val - start_angle) / (intensities.length - 1);
634
617
  break;
@@ -660,8 +643,8 @@ export function parse_xrdml_file(content) {
660
643
  const end_el = two_theta_positions.querySelector(`endPosition`);
661
644
  if (!start_el?.textContent || !end_el?.textContent)
662
645
  return null;
663
- const start_angle = parseFloat(start_el.textContent);
664
- const end_angle = parseFloat(end_el.textContent);
646
+ const start_angle = Number(start_el.textContent);
647
+ const end_angle = Number(end_el.textContent);
665
648
  if (isNaN(start_angle) || isNaN(end_angle))
666
649
  return null;
667
650
  // Extract intensities