matterviz 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -0,0 +1,467 @@
1
+ // Signal-processing primitives for plot data cleaning: rolling variance, instability/oscillation
2
+ // detection, smoothing (moving average, Savitzky-Golay) and local (MAD-based) outlier removal.
3
+ // Pure numeric helpers with no plot/series dependencies; orchestration lives in ./data-cleaning.
4
+ // Default configuration values
5
+ const DEFAULT_WINDOW_SIZE = 5;
6
+ const DEFAULT_OSCILLATION_THRESHOLD = 3.0;
7
+ const DEFAULT_POLYNOMIAL_ORDER = 2;
8
+ // --- Core Detection Functions ---
9
+ // Compute rolling variance using Welford's online algorithm - O(n)
10
+ // Returns variance for each point based on surrounding window
11
+ export function compute_local_variance(values, window_size) {
12
+ const len = values.length;
13
+ if (len === 0)
14
+ return [];
15
+ if (len === 1)
16
+ return [0];
17
+ const half_window = Math.floor(window_size / 2);
18
+ const result = Array(len);
19
+ // Single pass for each index, no slice allocation (avoids O(n × window) allocations)
20
+ for (let idx = 0; idx < len; idx++) {
21
+ const start = Math.max(0, idx - half_window);
22
+ const end = Math.min(len, idx + half_window + 1);
23
+ // Welford's online variance calculation
24
+ let [mean, m2, count] = [0, 0, 0];
25
+ for (let jdx = start; jdx < end; jdx++) {
26
+ const val = values[jdx];
27
+ if (!Number.isFinite(val))
28
+ continue;
29
+ count++;
30
+ const delta = val - mean;
31
+ mean += delta / count;
32
+ const delta2 = val - mean;
33
+ m2 += delta * delta2;
34
+ }
35
+ result[idx] = count > 1 ? m2 / (count - 1) : 0;
36
+ }
37
+ return result;
38
+ }
39
+ // Compute first-order finite differences (discrete derivative)
40
+ function compute_derivatives(values) {
41
+ if (values.length < 2)
42
+ return [];
43
+ const derivs = Array(values.length - 1);
44
+ for (let idx = 0; idx < values.length - 1; idx++) {
45
+ derivs[idx] = values[idx + 1] - values[idx];
46
+ }
47
+ return derivs;
48
+ }
49
+ // Detect derivative variance spikes (method 1)
50
+ // Returns onset index where derivative variance exceeds threshold
51
+ function detect_derivative_variance(values, window_size, threshold_multiplier) {
52
+ const derivs = compute_derivatives(values);
53
+ if (derivs.length < window_size) {
54
+ return { onset_index: -1, score: 0 };
55
+ }
56
+ const local_var = compute_local_variance(derivs, window_size);
57
+ // Compute baseline variance from first stable portion
58
+ const baseline_end = Math.min(Math.floor(derivs.length / 4), 50);
59
+ const baseline_vars = local_var.slice(0, Math.max(baseline_end, window_size));
60
+ const baseline_median = median(baseline_vars.filter((val) => val > 0));
61
+ if (baseline_median === 0) {
62
+ return { onset_index: -1, score: 0 };
63
+ }
64
+ // Find first point where variance exceeds threshold
65
+ let max_score = 0;
66
+ for (let idx = baseline_end; idx < local_var.length; idx++) {
67
+ const ratio = local_var[idx] / baseline_median;
68
+ if (ratio > max_score)
69
+ max_score = ratio;
70
+ if (ratio > threshold_multiplier) {
71
+ return { onset_index: idx + 1, score: ratio }; // +1 to convert from deriv index to value index
72
+ }
73
+ }
74
+ return { onset_index: -1, score: max_score };
75
+ }
76
+ // Detect exponential amplitude growth (method 2)
77
+ // Looks for values growing exponentially from their mean
78
+ function detect_amplitude_growth(values, window_size) {
79
+ if (values.length < window_size * 3) {
80
+ return { onset_index: -1, score: 0 };
81
+ }
82
+ // Compute running amplitude (deviation from local mean)
83
+ const amplitudes = [];
84
+ const half_window = Math.floor(window_size / 2);
85
+ for (let idx = half_window; idx < values.length - half_window; idx++) {
86
+ const start = idx - half_window;
87
+ const end = idx + half_window + 1;
88
+ const window_len = end - start;
89
+ // Compute local mean without slice allocation
90
+ let sum = 0;
91
+ for (let jdx = start; jdx < end; jdx++)
92
+ sum += values[jdx];
93
+ const local_mean = sum / window_len;
94
+ // Find max deviation without slice allocation
95
+ let max_deviation = 0;
96
+ for (let jdx = start; jdx < end; jdx++) {
97
+ const deviation = Math.abs(values[jdx] - local_mean);
98
+ if (deviation > max_deviation)
99
+ max_deviation = deviation;
100
+ }
101
+ amplitudes.push(max_deviation);
102
+ }
103
+ if (amplitudes.length < 10) {
104
+ return { onset_index: -1, score: 0 };
105
+ }
106
+ // Detect exponential growth by checking if amplitude ratio increases
107
+ const baseline_amp = median(amplitudes.slice(0, Math.floor(amplitudes.length / 4)));
108
+ if (baseline_amp === 0) {
109
+ return { onset_index: -1, score: 0 };
110
+ }
111
+ let max_score = 0;
112
+ for (let idx = Math.floor(amplitudes.length / 4); idx < amplitudes.length; idx++) {
113
+ const ratio = amplitudes[idx] / baseline_amp;
114
+ if (ratio > max_score)
115
+ max_score = ratio;
116
+ // Exponential growth threshold: amplitude 10x baseline
117
+ if (ratio > 10) {
118
+ return { onset_index: idx + half_window, score: ratio / 10 };
119
+ }
120
+ }
121
+ return { onset_index: -1, score: max_score / 10 };
122
+ }
123
+ // Count derivative sign changes per window (method 3)
124
+ // Detects high-frequency oscillations
125
+ function detect_sign_change_frequency(values, window_size, max_changes_per_window = 3) {
126
+ const derivs = compute_derivatives(values);
127
+ if (derivs.length < window_size * 2) {
128
+ return { onset_index: -1, score: 0 };
129
+ }
130
+ // Count sign changes in sliding windows
131
+ const half_window = Math.floor(window_size / 2);
132
+ let max_score = 0;
133
+ for (let idx = half_window; idx < derivs.length - half_window; idx++) {
134
+ const start = idx - half_window;
135
+ const end = idx + half_window + 1;
136
+ let sign_changes = 0;
137
+ // Count sign changes without slice allocation
138
+ for (let jdx = start + 1; jdx < end; jdx++) {
139
+ if (derivs[jdx] * derivs[jdx - 1] < 0) {
140
+ sign_changes++;
141
+ }
142
+ }
143
+ const normalized_score = sign_changes / max_changes_per_window;
144
+ if (normalized_score > max_score)
145
+ max_score = normalized_score;
146
+ if (sign_changes > max_changes_per_window) {
147
+ return { onset_index: idx + 1, score: normalized_score };
148
+ }
149
+ }
150
+ return { onset_index: -1, score: max_score };
151
+ }
152
+ // Combined detection with configurable weights
153
+ export function detect_instability(x_values, y_values, config = {}) {
154
+ const window_size = config.window_size ?? DEFAULT_WINDOW_SIZE;
155
+ const threshold = config.oscillation_threshold ?? DEFAULT_OSCILLATION_THRESHOLD;
156
+ const weights = {
157
+ derivative_variance: config.oscillation_weights?.derivative_variance ?? 1.0,
158
+ amplitude_growth: config.oscillation_weights?.amplitude_growth ?? 1.0,
159
+ sign_changes: config.oscillation_weights?.sign_changes ?? 1.0,
160
+ };
161
+ // Filter out invalid values for detection
162
+ const valid_indices = [];
163
+ const valid_y = [];
164
+ for (let idx = 0; idx < y_values.length; idx++) {
165
+ if (Number.isFinite(y_values[idx])) {
166
+ valid_indices.push(idx);
167
+ valid_y.push(y_values[idx]);
168
+ }
169
+ }
170
+ if (valid_y.length < window_size * 2) {
171
+ const method_scores = { derivative_variance: 0, amplitude_growth: 0, sign_changes: 0 };
172
+ const detected = false;
173
+ return { detected, onset_index: -1, onset_x: NaN, combined_score: 0, method_scores };
174
+ }
175
+ // Run all three detection methods
176
+ const deriv_result = detect_derivative_variance(valid_y, window_size, threshold);
177
+ const amp_result = detect_amplitude_growth(valid_y, window_size);
178
+ const sign_result = detect_sign_change_frequency(valid_y, window_size);
179
+ const method_scores = {
180
+ derivative_variance: deriv_result.score,
181
+ amplitude_growth: amp_result.score,
182
+ sign_changes: sign_result.score,
183
+ };
184
+ // Compute weighted combined score
185
+ const total_weight = weights.derivative_variance + weights.amplitude_growth + weights.sign_changes;
186
+ const combined_score = total_weight > 0
187
+ ? (weights.derivative_variance * deriv_result.score +
188
+ weights.amplitude_growth * amp_result.score +
189
+ weights.sign_changes * sign_result.score) /
190
+ total_weight
191
+ : 0;
192
+ // Find earliest onset across all methods that exceeded threshold
193
+ const onset_candidates = [
194
+ {
195
+ idx: deriv_result.onset_index,
196
+ score: deriv_result.score * weights.derivative_variance,
197
+ },
198
+ { idx: amp_result.onset_index, score: amp_result.score * weights.amplitude_growth },
199
+ { idx: sign_result.onset_index, score: sign_result.score * weights.sign_changes },
200
+ ].filter((candidate) => candidate.idx >= 0);
201
+ let onset_index = -1;
202
+ if (onset_candidates.length > 0) {
203
+ // Take earliest detected onset
204
+ onset_index = Math.min(...onset_candidates.map((candidate) => candidate.idx));
205
+ // Map back to original index if we filtered values
206
+ if (onset_index >= 0 && onset_index < valid_indices.length) {
207
+ onset_index = valid_indices[onset_index];
208
+ }
209
+ }
210
+ const detected = combined_score >= threshold || onset_index >= 0;
211
+ const onset_x = onset_index >= 0 && onset_index < x_values.length ? x_values[onset_index] : NaN;
212
+ return { detected, onset_index, onset_x, combined_score, method_scores };
213
+ }
214
+ // --- Smoothing Functions ---
215
+ // Moving average - O(n)
216
+ export function smooth_moving_average(values, window) {
217
+ if (values.length === 0 || window <= 1)
218
+ return [...values];
219
+ const result = Array(values.length);
220
+ const half_window = Math.floor(window / 2);
221
+ for (let idx = 0; idx < values.length; idx++) {
222
+ const start = Math.max(0, idx - half_window);
223
+ const end = Math.min(values.length, idx + half_window + 1);
224
+ let [sum, count] = [0, 0];
225
+ for (let jdx = start; jdx < end; jdx++) {
226
+ if (Number.isFinite(values[jdx])) {
227
+ sum += values[jdx];
228
+ count++;
229
+ }
230
+ }
231
+ result[idx] = count > 0 ? sum / count : values[idx];
232
+ }
233
+ return result;
234
+ }
235
+ // Savitzky-Golay filter coefficients for polynomial smoothing
236
+ // Uses least-squares polynomial fitting in each window
237
+ function compute_savgol_coefficients(window, order) {
238
+ // Ensure window is odd
239
+ const half = Math.floor(window / 2);
240
+ const size = 2 * half + 1;
241
+ // Build Vandermonde matrix for polynomial fitting
242
+ const vandermonde = [];
243
+ for (let idx = -half; idx <= half; idx++) {
244
+ const row = [];
245
+ for (let power = 0; power <= order; power++) {
246
+ row.push(idx ** power);
247
+ }
248
+ vandermonde.push(row);
249
+ }
250
+ // Compute (V^T V)^-1 V^T using simple pseudoinverse
251
+ // For smoothing, we only need the first row (constant term coefficients)
252
+ const vtv = multiply_matrices(transpose(vandermonde), vandermonde);
253
+ const vtv_inv = invert_matrix(vtv);
254
+ if (!vtv_inv) {
255
+ // Fallback to uniform weights
256
+ return Array(size).fill(1 / size);
257
+ }
258
+ const vt = transpose(vandermonde);
259
+ const coeffs_matrix = multiply_matrices(vtv_inv, vt);
260
+ // First row gives smoothing coefficients
261
+ return coeffs_matrix[0];
262
+ }
263
+ // Savitzky-Golay filter (derivative-preserving) - O(n * window)
264
+ export function smooth_savitzky_golay(values, window, polynomial_order = DEFAULT_POLYNOMIAL_ORDER) {
265
+ if (values.length === 0)
266
+ return [];
267
+ // Ensure window is odd and >= polynomial_order + 1
268
+ let actual_window = window % 2 === 0 ? window + 1 : window;
269
+ actual_window = Math.max(actual_window, polynomial_order + 2);
270
+ actual_window = Math.min(actual_window, values.length);
271
+ // max/min clamps above can re-even the window (polynomial_order + 2 is even for even orders;
272
+ // values.length may be even). Force odd so the kernel stays symmetric and matches
273
+ // compute_savgol_coefficients' (2 * floor(window / 2) + 1)-length row.
274
+ if (actual_window % 2 === 0)
275
+ actual_window -= 1;
276
+ if (actual_window < 3)
277
+ return [...values];
278
+ const coeffs = compute_savgol_coefficients(actual_window, polynomial_order);
279
+ const half = Math.floor(actual_window / 2);
280
+ const result = Array(values.length);
281
+ // Cache coefficient sum to avoid O(n × window) redundant reductions in loop
282
+ const coeffs_sum = coeffs.reduce((sum, coeff) => sum + coeff, 0);
283
+ for (let idx = 0; idx < values.length; idx++) {
284
+ let [sum, weight_sum] = [0, 0];
285
+ for (let jdx = 0; jdx < actual_window; jdx++) {
286
+ const data_idx = idx - half + jdx;
287
+ if (data_idx >= 0 && data_idx < values.length && Number.isFinite(values[data_idx])) {
288
+ sum += coeffs[jdx] * values[data_idx];
289
+ weight_sum += coeffs[jdx];
290
+ }
291
+ }
292
+ result[idx] = weight_sum !== 0 ? (sum / weight_sum) * coeffs_sum : values[idx];
293
+ }
294
+ return result;
295
+ }
296
+ // --- Local Outlier Detection ---
297
+ // Default values for local outlier detection
298
+ const DEFAULT_LOCAL_WINDOW_HALF = 7;
299
+ const DEFAULT_LOCAL_MAD_THRESHOLD = 2.0;
300
+ const DEFAULT_LOCAL_MAX_ITERATIONS = 5;
301
+ // Compute local median within a window, excluding the center point
302
+ // This allows detecting if the center point is an outlier relative to its neighbors
303
+ function compute_local_median_excluding_center(values, center_idx, window_half) {
304
+ const window_values = [];
305
+ const start = Math.max(0, center_idx - window_half);
306
+ const end = Math.min(values.length - 1, center_idx + window_half);
307
+ for (let idx = start; idx <= end; idx++) {
308
+ if (idx !== center_idx && Number.isFinite(values[idx])) {
309
+ window_values.push(values[idx]);
310
+ }
311
+ }
312
+ if (window_values.length === 0)
313
+ return values[center_idx];
314
+ return median(window_values);
315
+ }
316
+ // Compute local MAD (median absolute deviation) within a window, excluding center
317
+ function compute_local_mad_excluding_center(values, center_idx, window_half, local_median) {
318
+ const abs_devs = [];
319
+ const start = Math.max(0, center_idx - window_half);
320
+ const end = Math.min(values.length - 1, center_idx + window_half);
321
+ for (let idx = start; idx <= end; idx++) {
322
+ if (idx !== center_idx && Number.isFinite(values[idx])) {
323
+ abs_devs.push(Math.abs(values[idx] - local_median));
324
+ }
325
+ }
326
+ if (abs_devs.length === 0)
327
+ return 0;
328
+ return median(abs_devs);
329
+ }
330
+ // Remove local outliers using iterative sliding window MAD-based detection
331
+ // Detects points that deviate significantly from their local neighborhood
332
+ // Returns only the indices to keep, preserving good data before AND after bad regions
333
+ export function remove_local_outliers(y_values, config = {}) {
334
+ const window_half = config.window_half ?? DEFAULT_LOCAL_WINDOW_HALF;
335
+ const mad_threshold = config.mad_threshold ?? DEFAULT_LOCAL_MAD_THRESHOLD;
336
+ const max_iterations = config.max_iterations ?? DEFAULT_LOCAL_MAX_ITERATIONS;
337
+ const len = y_values.length;
338
+ if (len === 0) {
339
+ return { kept_indices: [], removed_indices: [], iterations_used: 0 };
340
+ }
341
+ // Need enough neighbors for meaningful local statistics
342
+ const min_points_needed = window_half * 2 + 1;
343
+ if (len < min_points_needed) {
344
+ return {
345
+ kept_indices: Array.from({ length: len }, (_, idx) => idx),
346
+ removed_indices: [],
347
+ iterations_used: 0,
348
+ };
349
+ }
350
+ let kept_mask = Array(len).fill(true);
351
+ let iterations_used = 0;
352
+ for (let iter = 0; iter < max_iterations; iter++) {
353
+ let removed_any = false;
354
+ const new_kept_mask = [...kept_mask];
355
+ // Note: Local statistics are computed from original values, not filtered values.
356
+ // This prevents cascading removals where one outlier's removal dramatically
357
+ // shifts statistics and causes false positives on neighboring points.
358
+ for (let idx = 0; idx < len; idx++) {
359
+ if (!kept_mask[idx])
360
+ continue; // Already removed
361
+ if (!Number.isFinite(y_values[idx]))
362
+ continue; // Skip invalid values
363
+ const local_median = compute_local_median_excluding_center(y_values, idx, window_half);
364
+ const local_mad = compute_local_mad_excluding_center(y_values, idx, window_half, local_median);
365
+ // Cannot compute robust threshold if MAD is zero (all neighbors identical)
366
+ if (local_mad === 0)
367
+ continue;
368
+ const threshold = local_mad * mad_threshold;
369
+ const deviation = Math.abs(y_values[idx] - local_median);
370
+ if (deviation > threshold) {
371
+ new_kept_mask[idx] = false;
372
+ removed_any = true;
373
+ }
374
+ }
375
+ kept_mask = new_kept_mask;
376
+ iterations_used = iter + 1;
377
+ if (!removed_any)
378
+ break;
379
+ }
380
+ const kept_indices = [];
381
+ const removed_indices = [];
382
+ for (let idx = 0; idx < len; idx++) {
383
+ if (kept_mask[idx]) {
384
+ kept_indices.push(idx);
385
+ }
386
+ else {
387
+ removed_indices.push(idx);
388
+ }
389
+ }
390
+ return { kept_indices, removed_indices, iterations_used };
391
+ }
392
+ // --- Utility Functions ---
393
+ function median(values) {
394
+ if (values.length === 0)
395
+ return 0;
396
+ const sorted = [...values].sort((a, b) => a - b);
397
+ const mid = Math.floor(sorted.length / 2);
398
+ return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
399
+ }
400
+ // Simple matrix operations for Savitzky-Golay
401
+ function transpose(matrix) {
402
+ if (matrix.length === 0)
403
+ return [];
404
+ const rows = matrix.length;
405
+ const cols = matrix[0].length;
406
+ const result = Array.from({ length: cols }, () => Array(rows).fill(0));
407
+ for (let row = 0; row < rows; row++) {
408
+ for (let col = 0; col < cols; col++) {
409
+ result[col][row] = matrix[row][col];
410
+ }
411
+ }
412
+ return result;
413
+ }
414
+ function multiply_matrices(matrix_a, matrix_b) {
415
+ const rows_a = matrix_a.length;
416
+ const cols_a = matrix_a[0]?.length ?? 0;
417
+ const cols_b = matrix_b[0]?.length ?? 0;
418
+ const result = Array.from({ length: rows_a }, () => Array(cols_b).fill(0));
419
+ for (let row = 0; row < rows_a; row++) {
420
+ for (let col = 0; col < cols_b; col++) {
421
+ for (let idx_k = 0; idx_k < cols_a; idx_k++) {
422
+ result[row][col] += matrix_a[row][idx_k] * matrix_b[idx_k][col];
423
+ }
424
+ }
425
+ }
426
+ return result;
427
+ }
428
+ function invert_matrix(matrix) {
429
+ const size = matrix.length;
430
+ if (size === 0 || matrix[0].length !== size)
431
+ return null;
432
+ // Create augmented matrix [A | I]
433
+ const aug = matrix.map((row, idx) => [
434
+ ...row,
435
+ ...Array.from({ length: size }, (_, jdx) => (idx === jdx ? 1 : 0)),
436
+ ]);
437
+ // Gaussian elimination with partial pivoting
438
+ for (let col = 0; col < size; col++) {
439
+ // Find pivot
440
+ let max_row = col;
441
+ for (let row = col + 1; row < size; row++) {
442
+ if (Math.abs(aug[row][col]) > Math.abs(aug[max_row][col])) {
443
+ max_row = row;
444
+ }
445
+ }
446
+ if (Math.abs(aug[max_row][col]) < 1e-10) {
447
+ return null; // Singular
448
+ } // Swap rows
449
+ ;
450
+ [aug[col], aug[max_row]] = [aug[max_row], aug[col]];
451
+ // Eliminate column
452
+ const pivot = aug[col][col];
453
+ for (let jdx = 0; jdx < 2 * size; jdx++) {
454
+ aug[col][jdx] /= pivot;
455
+ }
456
+ for (let row = 0; row < size; row++) {
457
+ if (row !== col) {
458
+ const factor = aug[row][col];
459
+ for (let jdx = 0; jdx < 2 * size; jdx++) {
460
+ aug[row][jdx] -= factor * aug[col][jdx];
461
+ }
462
+ }
463
+ }
464
+ }
465
+ // Extract inverse
466
+ return aug.map((row) => row.slice(size));
467
+ }
@@ -1,10 +1,7 @@
1
1
  import type { Vec2 } from '../../math';
2
2
  import type { DataSeries } from './types';
3
- export interface OscillationWeights {
4
- derivative_variance?: number;
5
- amplitude_growth?: number;
6
- sign_changes?: number;
7
- }
3
+ import { type LocalOutlierConfig, type OscillationWeights, type SmoothingConfig } from './data-cleaning-signal';
4
+ export * from './data-cleaning-signal';
8
5
  export type InvalidValueMode = `remove` | `propagate` | `interpolate`;
9
6
  export type TruncationMode = `hard_cut` | `mark_unstable`;
10
7
  export interface PhysicalBounds {
@@ -12,27 +9,6 @@ export interface PhysicalBounds {
12
9
  max?: number | ((x: number) => number);
13
10
  mode?: `clamp` | `filter` | `null`;
14
11
  }
15
- export type SmoothingConfig = {
16
- type: `moving_avg`;
17
- window: number;
18
- } | {
19
- type: `savgol`;
20
- window: number;
21
- polynomial_order?: number;
22
- } | {
23
- type: `gaussian`;
24
- sigma: number;
25
- };
26
- export interface LocalOutlierConfig {
27
- window_half?: number;
28
- mad_threshold?: number;
29
- max_iterations?: number;
30
- }
31
- export interface LocalOutlierResult {
32
- kept_indices: number[];
33
- removed_indices: number[];
34
- iterations_used: number;
35
- }
36
12
  export interface CleaningConfig {
37
13
  oscillation_threshold?: number;
38
14
  oscillation_weights?: OscillationWeights;
@@ -58,22 +34,6 @@ export interface CleaningResult<T = DataSeries> {
58
34
  series: T;
59
35
  quality: CleaningQuality;
60
36
  }
61
- export interface InstabilityResult {
62
- detected: boolean;
63
- onset_index: number;
64
- onset_x: number;
65
- combined_score: number;
66
- method_scores: {
67
- derivative_variance: number;
68
- amplitude_growth: number;
69
- sign_changes: number;
70
- };
71
- }
72
- export declare function compute_local_variance(values: number[], window_size: number): number[];
73
- export declare function detect_instability(x_values: readonly number[], y_values: readonly number[], config?: Pick<CleaningConfig, `oscillation_weights` | `oscillation_threshold` | `window_size`>): InstabilityResult;
74
- export declare function smooth_moving_average(values: number[], window: number): number[];
75
- export declare function smooth_savitzky_golay(values: number[], window: number, polynomial_order?: number): number[];
76
- export declare function remove_local_outliers(y_values: readonly number[], config?: LocalOutlierConfig): LocalOutlierResult;
77
37
  export declare function handle_invalid_values(values: number[], mode: InvalidValueMode): {
78
38
  cleaned: number[];
79
39
  removed_indices: number[];