matterviz 0.3.2 → 0.3.4

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 (281) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +123 -82
  3. package/dist/Icon.svelte +18 -12
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -207
  7. package/dist/brillouin/BrillouinZone.svelte +292 -149
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
  20. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
  21. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  22. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  23. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  24. package/dist/chempot-diagram/chempot-worker.js +11 -0
  25. package/dist/chempot-diagram/color.js +1 -2
  26. package/dist/chempot-diagram/compute.d.ts +10 -0
  27. package/dist/chempot-diagram/compute.js +250 -88
  28. package/dist/chempot-diagram/index.d.ts +2 -1
  29. package/dist/chempot-diagram/index.js +2 -1
  30. package/dist/chempot-diagram/temperature.js +8 -9
  31. package/dist/chempot-diagram/types.d.ts +3 -0
  32. package/dist/chempot-diagram/types.js +1 -0
  33. package/dist/colors/index.d.ts +1 -1
  34. package/dist/colors/index.js +5 -3
  35. package/dist/composition/BarChart.svelte +128 -55
  36. package/dist/composition/BubbleChart.svelte +102 -49
  37. package/dist/composition/Composition.svelte +100 -79
  38. package/dist/composition/Formula.svelte +108 -62
  39. package/dist/composition/FormulaFilter.svelte +665 -537
  40. package/dist/composition/PieChart.svelte +183 -108
  41. package/dist/composition/format.d.ts +5 -0
  42. package/dist/composition/format.js +20 -3
  43. package/dist/composition/parse.js +14 -9
  44. package/dist/convex-hull/ConvexHull.svelte +93 -40
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +549 -360
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  53. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  54. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  55. package/dist/convex-hull/ConvexHullStats.svelte +425 -328
  56. package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
  57. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  58. package/dist/convex-hull/StructurePopup.svelte +25 -4
  59. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  60. package/dist/convex-hull/barycentric-coords.js +13 -7
  61. package/dist/convex-hull/demo-temperature.js +8 -4
  62. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  63. package/dist/convex-hull/helpers.d.ts +9 -0
  64. package/dist/convex-hull/helpers.js +77 -34
  65. package/dist/convex-hull/thermodynamics.js +61 -56
  66. package/dist/convex-hull/types.d.ts +9 -14
  67. package/dist/convex-hull/types.js +0 -17
  68. package/dist/coordination/CoordinationBarPlot.svelte +227 -154
  69. package/dist/element/BohrAtom.svelte +55 -12
  70. package/dist/element/ElementHeading.svelte +7 -2
  71. package/dist/element/ElementPhoto.svelte +15 -9
  72. package/dist/element/ElementStats.svelte +10 -4
  73. package/dist/element/ElementTile.svelte +137 -73
  74. package/dist/element/Nucleus.svelte +39 -11
  75. package/dist/element/data.js +1 -1
  76. package/dist/feedback/ClickFeedback.svelte +16 -5
  77. package/dist/feedback/DragOverlay.svelte +10 -2
  78. package/dist/feedback/Spinner.svelte +4 -2
  79. package/dist/feedback/StatusMessage.svelte +8 -2
  80. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  81. package/dist/fermi-surface/FermiSurface.svelte +328 -187
  82. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  83. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  84. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  85. package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
  86. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  87. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  88. package/dist/fermi-surface/compute.js +16 -20
  89. package/dist/fermi-surface/parse.js +24 -14
  90. package/dist/fermi-surface/symmetry.js +2 -7
  91. package/dist/fermi-surface/types.d.ts +3 -5
  92. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
  93. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
  94. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
  95. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
  96. package/dist/icons.js +47 -0
  97. package/dist/index.d.ts +2 -1
  98. package/dist/index.js +2 -1
  99. package/dist/io/decompress.js +1 -1
  100. package/dist/io/export.d.ts +3 -0
  101. package/dist/io/export.js +129 -143
  102. package/dist/io/is-binary.js +2 -3
  103. package/dist/io/url-drop.js +1 -2
  104. package/dist/isosurface/Isosurface.svelte +202 -148
  105. package/dist/isosurface/IsosurfaceControls.svelte +46 -28
  106. package/dist/isosurface/parse.js +34 -29
  107. package/dist/isosurface/slice.js +5 -10
  108. package/dist/isosurface/types.d.ts +2 -1
  109. package/dist/isosurface/types.js +61 -12
  110. package/dist/labels.js +11 -8
  111. package/dist/layout/FullscreenToggle.svelte +11 -2
  112. package/dist/layout/InfoCard.svelte +38 -6
  113. package/dist/layout/InfoTag.svelte +63 -32
  114. package/dist/layout/PropertyFilter.svelte +82 -37
  115. package/dist/layout/SettingsSection.svelte +85 -55
  116. package/dist/layout/SubpageGrid.svelte +10 -2
  117. package/dist/layout/json-tree/JsonNode.svelte +183 -138
  118. package/dist/layout/json-tree/JsonTree.svelte +499 -413
  119. package/dist/layout/json-tree/JsonValue.svelte +127 -99
  120. package/dist/layout/json-tree/utils.js +4 -2
  121. package/dist/marching-cubes.js +25 -2
  122. package/dist/math.d.ts +13 -17
  123. package/dist/math.js +133 -67
  124. package/dist/overlays/ContextMenu.svelte +65 -40
  125. package/dist/overlays/DraggablePane.svelte +211 -139
  126. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  127. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  128. package/dist/periodic-table/PropertySelect.svelte +25 -7
  129. package/dist/periodic-table/TableInset.svelte +8 -3
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
  131. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
  133. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  134. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
  136. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
  137. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
  138. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  139. package/dist/phase-diagram/build-diagram.js +9 -9
  140. package/dist/phase-diagram/colors.js +1 -3
  141. package/dist/phase-diagram/parse.js +10 -9
  142. package/dist/phase-diagram/svg-to-diagram.js +53 -49
  143. package/dist/phase-diagram/utils.d.ts +1 -0
  144. package/dist/phase-diagram/utils.js +80 -25
  145. package/dist/plot/AxisLabel.svelte +28 -3
  146. package/dist/plot/BarPlot.svelte +1182 -734
  147. package/dist/plot/BarPlot.svelte.d.ts +2 -2
  148. package/dist/plot/BarPlotControls.svelte +31 -5
  149. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  150. package/dist/plot/ColorBar.svelte +479 -329
  151. package/dist/plot/ColorScaleSelect.svelte +27 -6
  152. package/dist/plot/ElementScatter.svelte +36 -15
  153. package/dist/plot/FillArea.svelte +152 -95
  154. package/dist/plot/Histogram.svelte +934 -571
  155. package/dist/plot/Histogram.svelte.d.ts +1 -1
  156. package/dist/plot/HistogramControls.svelte +53 -9
  157. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  158. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  159. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  160. package/dist/plot/Line.svelte +63 -28
  161. package/dist/plot/PlotControls.svelte +157 -114
  162. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  163. package/dist/plot/PlotLegend.svelte +174 -91
  164. package/dist/plot/PlotTooltip.svelte +45 -6
  165. package/dist/plot/PortalSelect.svelte +175 -147
  166. package/dist/plot/ReferenceLine.svelte +76 -22
  167. package/dist/plot/ReferenceLine3D.svelte +132 -107
  168. package/dist/plot/ReferencePlane.svelte +146 -121
  169. package/dist/plot/ScatterPlot.svelte +1681 -1091
  170. package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
  171. package/dist/plot/ScatterPlot3D.svelte +256 -131
  172. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  173. package/dist/plot/ScatterPlot3DControls.svelte +113 -63
  174. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  175. package/dist/plot/ScatterPlot3DScene.svelte +608 -403
  176. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  177. package/dist/plot/ScatterPlotControls.svelte +65 -25
  178. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  179. package/dist/plot/ScatterPoint.svelte +98 -26
  180. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  181. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  182. package/dist/plot/Surface3D.svelte +159 -108
  183. package/dist/plot/ZeroLines.svelte +55 -3
  184. package/dist/plot/ZoomRect.svelte +4 -2
  185. package/dist/plot/axis-utils.js +1 -3
  186. package/dist/plot/data-cleaning.js +12 -28
  187. package/dist/plot/data-transform.js +2 -1
  188. package/dist/plot/fill-utils.js +2 -0
  189. package/dist/plot/layout.d.ts +4 -1
  190. package/dist/plot/layout.js +33 -14
  191. package/dist/plot/reference-line.d.ts +2 -2
  192. package/dist/plot/reference-line.js +7 -5
  193. package/dist/plot/scales.js +24 -36
  194. package/dist/plot/types.d.ts +11 -23
  195. package/dist/plot/types.js +6 -11
  196. package/dist/plot/utils/label-placement.d.ts +32 -15
  197. package/dist/plot/utils/label-placement.js +227 -66
  198. package/dist/plot/utils/series-visibility.js +2 -3
  199. package/dist/rdf/RdfPlot.svelte +143 -91
  200. package/dist/rdf/calc-rdf.js +4 -5
  201. package/dist/sanitize.d.ts +4 -0
  202. package/dist/sanitize.js +107 -0
  203. package/dist/settings.d.ts +18 -6
  204. package/dist/settings.js +46 -16
  205. package/dist/spectral/Bands.svelte +632 -453
  206. package/dist/spectral/BandsAndDos.svelte +90 -49
  207. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  208. package/dist/spectral/Dos.svelte +389 -258
  209. package/dist/spectral/helpers.js +55 -43
  210. package/dist/state.svelte.d.ts +1 -1
  211. package/dist/state.svelte.js +3 -2
  212. package/dist/structure/Arrow.svelte +59 -20
  213. package/dist/structure/AtomLegend.svelte +215 -134
  214. package/dist/structure/Bond.svelte +73 -47
  215. package/dist/structure/CanvasTooltip.svelte +10 -2
  216. package/dist/structure/CellSelect.svelte +72 -45
  217. package/dist/structure/Cylinder.svelte +33 -17
  218. package/dist/structure/Lattice.svelte +88 -33
  219. package/dist/structure/Structure.svelte +1063 -797
  220. package/dist/structure/Structure.svelte.d.ts +1 -1
  221. package/dist/structure/StructureControls.svelte +349 -118
  222. package/dist/structure/StructureExportPane.svelte +124 -89
  223. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  224. package/dist/structure/StructureInfoPane.svelte +304 -237
  225. package/dist/structure/StructureScene.svelte +879 -443
  226. package/dist/structure/StructureScene.svelte.d.ts +15 -7
  227. package/dist/structure/atom-properties.js +8 -8
  228. package/dist/structure/bonding.js +6 -7
  229. package/dist/structure/export.js +14 -29
  230. package/dist/structure/ferrox-wasm.js +1 -1
  231. package/dist/structure/index.d.ts +13 -3
  232. package/dist/structure/index.js +83 -23
  233. package/dist/structure/measure.d.ts +2 -2
  234. package/dist/structure/measure.js +4 -44
  235. package/dist/structure/parse.js +113 -141
  236. package/dist/structure/partial-occupancy.js +7 -10
  237. package/dist/structure/pbc.d.ts +1 -0
  238. package/dist/structure/pbc.js +16 -6
  239. package/dist/structure/supercell.d.ts +2 -2
  240. package/dist/structure/supercell.js +12 -22
  241. package/dist/structure/validation.js +1 -2
  242. package/dist/symmetry/SymmetryStats.svelte +84 -41
  243. package/dist/symmetry/WyckoffTable.svelte +26 -6
  244. package/dist/symmetry/cell-transform.js +5 -3
  245. package/dist/symmetry/index.js +8 -7
  246. package/dist/symmetry/spacegroups.js +148 -148
  247. package/dist/table/HeatmapTable.svelte +790 -554
  248. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  249. package/dist/table/ToggleMenu.svelte +125 -92
  250. package/dist/table/index.js +2 -4
  251. package/dist/theme/ThemeControl.svelte +21 -12
  252. package/dist/time.js +4 -1
  253. package/dist/tooltip/TooltipContent.svelte +33 -8
  254. package/dist/trajectory/Trajectory.svelte +758 -558
  255. package/dist/trajectory/TrajectoryError.svelte +14 -3
  256. package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
  257. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  258. package/dist/trajectory/extract.js +10 -26
  259. package/dist/trajectory/format-detect.js +5 -5
  260. package/dist/trajectory/frame-reader.d.ts +1 -1
  261. package/dist/trajectory/frame-reader.js +5 -12
  262. package/dist/trajectory/helpers.d.ts +0 -1
  263. package/dist/trajectory/helpers.js +2 -17
  264. package/dist/trajectory/index.js +14 -12
  265. package/dist/trajectory/parse/ase.js +5 -4
  266. package/dist/trajectory/parse/hdf5.js +26 -18
  267. package/dist/trajectory/parse/index.js +13 -18
  268. package/dist/trajectory/parse/lammps.js +17 -7
  269. package/dist/trajectory/parse/vasp.js +5 -2
  270. package/dist/trajectory/parse/xyz.js +8 -7
  271. package/dist/trajectory/plotting.js +13 -8
  272. package/dist/utils.d.ts +1 -0
  273. package/dist/utils.js +13 -0
  274. package/dist/xrd/XrdPlot.svelte +337 -247
  275. package/dist/xrd/broadening.js +14 -9
  276. package/dist/xrd/calc-xrd.js +12 -18
  277. package/dist/xrd/parse.d.ts +1 -1
  278. package/dist/xrd/parse.js +17 -17
  279. package/package.json +99 -103
  280. package/readme.md +1 -1
  281. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,115 +1,172 @@
1
- <script lang="ts">import { ATOMIC_WEIGHTS } from '../composition/parse';
2
- import { format_num } from '../labels';
3
- import { TooltipContent } from '../tooltip';
4
- import { convert_temp, format_composition, format_formula_html, format_label_html, format_temperature, get_phase_stability_range, } from './utils';
5
- let { hover_info, temperature_unit = `K`, data_temperature_unit, composition_unit = `at%`, component_a = `A`, component_b = `B`, boundaries = [], lever_rule_mode = `horizontal`, use_subscripts = true, tooltip, } = $props();
6
- // The unit that hover_info.temperature is actually in
7
- const data_unit = $derived(data_temperature_unit ?? temperature_unit);
8
- // Convert a temperature from data unit to display unit
9
- function to_display(temp) {
10
- return convert_temp(temp, data_unit, temperature_unit);
11
- }
12
- // Convert atomic fraction to weight fraction: wt_B = (x_B * M_B) / (x_A * M_A + x_B * M_B)
13
- const wt_fraction_b = $derived.by(() => {
14
- const mass_a = ATOMIC_WEIGHTS.get(component_a);
15
- const mass_b = ATOMIC_WEIGHTS.get(component_b);
16
- if (!mass_a || !mass_b)
17
- return null;
18
- const { composition: x_b } = hover_info;
19
- const denom = (1 - x_b) * mass_a + x_b * mass_b;
20
- return denom > 0 ? (x_b * mass_b) / denom : null;
21
- });
22
- const stability = $derived(get_phase_stability_range(hover_info.region));
23
- // Format special point type for display (e.g., "peritectic" → "Peritectic")
24
- // For melting points and congruent points at composition edges, show element-specific info
25
- const special_point_info = $derived.by(() => {
26
- const point = hover_info.special_point;
27
- if (!point)
28
- return null;
29
- const type = point.type;
30
- const position = point.position;
31
- const temp = format_temperature(to_display(position[1]), temperature_unit);
1
+ <script lang="ts">
2
+ import { ATOMIC_WEIGHTS } from '../composition/parse'
3
+ import type { ElementSymbol } from '../element'
4
+ import { format_num } from '../labels'
5
+ import { sanitize_formula, sanitize_html } from '../sanitize'
6
+ import { TooltipContent } from '../tooltip'
7
+ import type {
8
+ CompUnit,
9
+ LeverRuleMode,
10
+ PhaseBoundary,
11
+ PhaseDiagramTooltipProp,
12
+ PhaseHoverInfo,
13
+ TempUnit,
14
+ } from './types'
15
+ import {
16
+ convert_temp,
17
+ format_composition,
18
+ format_label_html,
19
+ format_temperature,
20
+ get_phase_stability_range,
21
+ } from './utils'
22
+
23
+ let {
24
+ hover_info,
25
+ temperature_unit = `K`,
26
+ data_temperature_unit,
27
+ composition_unit = `at%`,
28
+ component_a = `A`,
29
+ component_b = `B`,
30
+ boundaries = [],
31
+ lever_rule_mode = `horizontal`,
32
+ use_subscripts = true,
33
+ tooltip,
34
+ }: {
35
+ hover_info: PhaseHoverInfo
36
+ temperature_unit?: TempUnit
37
+ // Original unit of hover_info.temperature (defaults to temperature_unit)
38
+ data_temperature_unit?: TempUnit
39
+ composition_unit?: CompUnit
40
+ component_a?: string
41
+ component_b?: string
42
+ boundaries?: PhaseBoundary[]
43
+ lever_rule_mode?: LeverRuleMode
44
+ use_subscripts?: boolean
45
+ tooltip?: PhaseDiagramTooltipProp
46
+ } = $props()
47
+
48
+ // The unit that hover_info.temperature is actually in
49
+ const data_unit = $derived(data_temperature_unit ?? temperature_unit)
50
+
51
+ const safe_formula = (comp: string) => sanitize_formula(comp, use_subscripts)
52
+
53
+ // Convert a temperature from data unit to display unit
54
+ function to_display(temp: number): number {
55
+ return convert_temp(temp, data_unit, temperature_unit)
56
+ }
57
+
58
+ // Convert atomic fraction to weight fraction: wt_B = (x_B * M_B) / (x_A * M_A + x_B * M_B)
59
+ const wt_fraction_b = $derived.by(() => {
60
+ const mass_a = ATOMIC_WEIGHTS.get(component_a as ElementSymbol)
61
+ const mass_b = ATOMIC_WEIGHTS.get(component_b as ElementSymbol)
62
+ if (!mass_a || !mass_b) return null
63
+ const { composition: x_b } = hover_info
64
+ const denom = (1 - x_b) * mass_a + x_b * mass_b
65
+ return denom > 0 ? (x_b * mass_b) / denom : null
66
+ })
67
+
68
+ const stability = $derived(get_phase_stability_range(hover_info.region))
69
+
70
+ // Format special point type for display (e.g., "peritectic" → "Peritectic")
71
+ // For melting points and congruent points at composition edges, show element-specific info
72
+ const special_point_info = $derived.by(() => {
73
+ const point = hover_info.special_point
74
+ if (!point) return null
75
+
76
+ const type = point.type
77
+ const position = point.position
78
+ const temp = format_temperature(to_display(position[1]), temperature_unit)
79
+
32
80
  // Check if this is a melting point (at composition edge)
33
- const is_at_edge = position[0] <= 0.01 || position[0] >= 0.99;
34
- const is_melting = type === `melting_point` || type === `congruent`;
81
+ const is_at_edge = position[0] <= 0.01 || position[0] >= 0.99
82
+ const is_melting = type === `melting_point` || type === `congruent`
83
+
35
84
  if (is_melting && is_at_edge) {
36
- const element = position[0] <= 0.01 ? component_a : component_b;
37
- return {
38
- badge: `Melting Point`,
39
- description: `${element} melts at ${temp}`,
40
- };
85
+ const element = position[0] <= 0.01 ? component_a : component_b
86
+ return {
87
+ badge: `Melting Point`,
88
+ description: `${element} melts at ${temp}`,
89
+ }
41
90
  }
91
+
42
92
  // Handle other special point types with descriptive info
43
- const type_descriptions = {
44
- eutectic: `Liquid → two solid phases at ${temp}`,
45
- peritectic: `Liquid + solid → different solid at ${temp}`,
46
- eutectoid: `Solid → two solid phases at ${temp}`,
47
- peritectoid: `Two solids → different solid at ${temp}`,
48
- congruent: `Congruent phase change at ${temp}`,
49
- };
50
- const badge = type.charAt(0).toUpperCase() + type.slice(1).replace(/_/g, ` `);
93
+ const type_descriptions: Record<string, string> = {
94
+ eutectic: `Liquid → two solid phases at ${temp}`,
95
+ peritectic: `Liquid + solid → different solid at ${temp}`,
96
+ eutectoid: `Solid → two solid phases at ${temp}`,
97
+ peritectoid: `Two solids → different solid at ${temp}`,
98
+ congruent: `Congruent phase change at ${temp}`,
99
+ }
100
+
101
+ const badge = type.charAt(0).toUpperCase() + type.slice(1).replaceAll(`_`, ` `)
51
102
  return {
52
- badge,
53
- description: type_descriptions[type] ?? null,
54
- };
55
- });
56
- // Calculate distance to nearest phase boundary (liquidus/solidus)
57
- const boundary_distance = $derived.by(() => {
58
- if (!boundaries.length)
59
- return null;
60
- const { composition, temperature } = hover_info;
61
- let min_dist = null;
103
+ badge,
104
+ description: type_descriptions[type] ?? null,
105
+ }
106
+ })
107
+
108
+ // Calculate distance to nearest phase boundary (liquidus/solidus)
109
+ const boundary_distance = $derived.by(() => {
110
+ if (!boundaries.length) return null
111
+ const { composition, temperature } = hover_info
112
+ let min_dist: { type: string; delta_t: number } | null = null
113
+
62
114
  for (const boundary of boundaries) {
63
- if (![`liquidus`, `solidus`, `solvus`].includes(boundary.type))
64
- continue;
65
- // Find the boundary point closest in composition
66
- for (const [bx, bt] of boundary.points) {
67
- if (Math.abs(bx - composition) < 0.02) {
68
- // Within 2% composition
69
- const delta = temperature - bt;
70
- if (!min_dist || Math.abs(delta) < Math.abs(min_dist.delta_t)) {
71
- min_dist = { type: boundary.type, delta_t: delta };
72
- }
73
- }
115
+ if (![`liquidus`, `solidus`, `solvus`].includes(boundary.type)) continue
116
+ // Find the boundary point closest in composition
117
+ for (const [bx, bt] of boundary.points) {
118
+ if (Math.abs(bx - composition) < 0.02) {
119
+ // Within 2% composition
120
+ const delta = temperature - bt
121
+ if (!min_dist || Math.abs(delta) < Math.abs(min_dist.delta_t)) {
122
+ min_dist = { type: boundary.type, delta_t: delta }
123
+ }
74
124
  }
125
+ }
75
126
  }
76
- return min_dist;
77
- });
78
- // Normalized lever rule display data (unifies horizontal and vertical modes)
79
- const lever_display = $derived.by(() => {
127
+ return min_dist
128
+ })
129
+
130
+ // Normalized lever rule display data (unifies horizontal and vertical modes)
131
+ const lever_display = $derived.by(() => {
80
132
  if (lever_rule_mode === `vertical` && hover_info.vertical_lever_rule) {
81
- const vlr = hover_info.vertical_lever_rule;
82
- return {
83
- label: `Lever Rule (vertical)`,
84
- phase_a: vlr.bottom_phase,
85
- phase_b: vlr.top_phase,
86
- fraction_a: vlr.fraction_bottom,
87
- fraction_b: vlr.fraction_top,
88
- detail_a: format_temperature(to_display(vlr.bottom_temperature), temperature_unit),
89
- detail_b: format_temperature(to_display(vlr.top_temperature), temperature_unit),
90
- };
133
+ const vlr = hover_info.vertical_lever_rule
134
+ return {
135
+ label: `Lever Rule (vertical)`,
136
+ phase_a: vlr.bottom_phase,
137
+ phase_b: vlr.top_phase,
138
+ fraction_a: vlr.fraction_bottom,
139
+ fraction_b: vlr.fraction_top,
140
+ detail_a: format_temperature(
141
+ to_display(vlr.bottom_temperature),
142
+ temperature_unit,
143
+ ),
144
+ detail_b: format_temperature(
145
+ to_display(vlr.top_temperature),
146
+ temperature_unit,
147
+ ),
148
+ }
91
149
  }
92
150
  if (lever_rule_mode === `horizontal` && hover_info.lever_rule) {
93
- const lr = hover_info.lever_rule;
94
- return {
95
- label: `Lever Rule`,
96
- phase_a: lr.left_phase,
97
- phase_b: lr.right_phase,
98
- fraction_a: lr.fraction_left,
99
- fraction_b: lr.fraction_right,
100
- detail_a: format_composition(lr.left_composition, composition_unit),
101
- detail_b: format_composition(lr.right_composition, composition_unit),
102
- };
151
+ const lr = hover_info.lever_rule
152
+ return {
153
+ label: `Lever Rule`,
154
+ phase_a: lr.left_phase,
155
+ phase_b: lr.right_phase,
156
+ fraction_a: lr.fraction_left,
157
+ fraction_b: lr.fraction_right,
158
+ detail_a: format_composition(lr.left_composition, composition_unit),
159
+ detail_b: format_composition(lr.right_composition, composition_unit),
160
+ }
103
161
  }
104
- return null;
105
- });
162
+ return null
163
+ })
106
164
  </script>
107
165
 
108
166
  <TooltipContent data={hover_info} snippet_arg={hover_info} {tooltip}>
109
167
  <div class="phase-diagram-tooltip">
110
- <!-- Note: {@html} is safe here because region/phase names come from trusted JSON data files -->
111
168
  <header>
112
- <strong>{@html format_label_html(hover_info.region.name, use_subscripts)}</strong>
169
+ <strong>{@html sanitize_html(format_label_html(hover_info.region.name, use_subscripts))}</strong>
113
170
  {#if special_point_info}<span class="special-point-badge">{
114
171
  special_point_info.badge
115
172
  }</span>{/if}
@@ -140,17 +197,17 @@ const lever_display = $derived.by(() => {
140
197
  <dt>Composition</dt>
141
198
  <dd>
142
199
  {format_composition(hover_info.composition, composition_unit)}
143
- {@html format_formula_html(component_b, use_subscripts)}
200
+ {@html safe_formula(component_b)}
144
201
  <small>({format_composition(1 - hover_info.composition, composition_unit)}
145
- {@html format_formula_html(component_a, use_subscripts)})</small>
202
+ {@html safe_formula(component_a)})</small>
146
203
  </dd>
147
204
  {#if wt_fraction_b !== null}
148
205
  <dt>Weight</dt>
149
206
  <dd>
150
207
  {format_num(wt_fraction_b * 100, `.1f`)}%
151
- {@html format_formula_html(component_b, use_subscripts)}
208
+ {@html safe_formula(component_b)}
152
209
  <small>({format_num((1 - wt_fraction_b) * 100, `.1f`)}%
153
- {@html format_formula_html(component_a, use_subscripts)})</small>
210
+ {@html safe_formula(component_a)})</small>
154
211
  </dd>
155
212
  {/if}
156
213
  {#if stability}
@@ -193,10 +250,10 @@ const lever_display = $derived.by(() => {
193
250
  <i style:left="{ld.fraction_a * 100}%"></i>
194
251
  </div>
195
252
  <div class="phase-info">
196
- <span>{@html format_formula_html(ld.phase_a, use_subscripts)}: {
253
+ <span>{@html safe_formula(ld.phase_a)}: {
197
254
  format_num(ld.fraction_a * 100, `.0f`)
198
255
  }% <small>at {ld.detail_a}</small></span>
199
- <span>{@html format_formula_html(ld.phase_b, use_subscripts)}: {
256
+ <span>{@html safe_formula(ld.phase_b)}: {
200
257
  format_num(ld.fraction_b * 100, `.0f`)
201
258
  }% <small>at {ld.detail_b}</small></span>
202
259
  </div>
@@ -1,7 +1,31 @@
1
- <script lang="ts">import { extract_tdb_reference, summarize_models } from './utils';
2
- let { result, system_name = ``, has_precomputed = false, is_precomputed_loaded = false, on_load_precomputed, style = ``, } = $props();
3
- const reference = $derived(result.data ? extract_tdb_reference(result.data.comments) : null);
4
- const model_summary = $derived(result.data ? summarize_models(result.data.phases) : null);
1
+ <script lang="ts">
2
+ import type { TdbParseResult } from './parse'
3
+ import { extract_tdb_reference, summarize_models } from './utils'
4
+
5
+ interface Props {
6
+ result: TdbParseResult
7
+ system_name?: string
8
+ has_precomputed?: boolean
9
+ is_precomputed_loaded?: boolean
10
+ on_load_precomputed?: () => void
11
+ style?: string
12
+ }
13
+
14
+ let {
15
+ result,
16
+ system_name = ``,
17
+ has_precomputed = false,
18
+ is_precomputed_loaded = false,
19
+ on_load_precomputed,
20
+ style = ``,
21
+ }: Props = $props()
22
+
23
+ const reference = $derived(
24
+ result.data ? extract_tdb_reference(result.data.comments) : null,
25
+ )
26
+ const model_summary = $derived(
27
+ result.data ? summarize_models(result.data.phases) : null,
28
+ )
5
29
  </script>
6
30
 
7
31
  <div class="tdb-info-panel" {style}>
@@ -19,7 +19,7 @@ export function parse_curve_ref(ref) {
19
19
  name = name.slice(1);
20
20
  }
21
21
  // Check for slice suffix [start:end]
22
- const slice_match = name.match(/^(.+)\[(-?\d*):(-?\d*)\]$/);
22
+ const slice_match = /^(.+)\[(-?\d*):(-?\d*)\]$/.exec(name);
23
23
  if (slice_match) {
24
24
  name = slice_match[1];
25
25
  start = slice_match[2] ? parseInt(slice_match[2]) : null;
@@ -30,14 +30,14 @@ export function parse_curve_ref(ref) {
30
30
  // Apply slicing to array (Python-style negative indices supported)
31
31
  export function apply_slice(arr, start, end) {
32
32
  const len = arr.length;
33
- let s = start ?? 0;
34
- let e = end ?? len;
33
+ let start_idx = start ?? 0;
34
+ let end_idx = end ?? len;
35
35
  // Handle negative indices
36
- if (s < 0)
37
- s = Math.max(0, len + s);
38
- if (e < 0)
39
- e = Math.max(0, len + e);
40
- return arr.slice(s, e);
36
+ if (start_idx < 0)
37
+ start_idx = Math.max(0, len + start_idx);
38
+ if (end_idx < 0)
39
+ end_idx = Math.max(0, len + end_idx);
40
+ return arr.slice(start_idx, end_idx);
41
41
  }
42
42
  // Expand bounds to vertex list
43
43
  function expand_bounds(bounds, curves) {
@@ -57,7 +57,7 @@ function expand_bounds(bounds, curves) {
57
57
  }
58
58
  // Apply reverse first (to match Python's `reversed(curve)[1:]` pattern)
59
59
  if (ref.reverse) {
60
- points = [...points].reverse();
60
+ points = points.toReversed();
61
61
  }
62
62
  // Then apply slice
63
63
  points = apply_slice(points, ref.start, ref.end);
@@ -1,8 +1,6 @@
1
1
  // Phase diagram color palette
2
2
  // Keys can be referenced in diagram JSON files
3
- function rgba(r, g, b, a = 0.6) {
4
- return `rgba(${r}, ${g}, ${b}, ${a})`;
5
- }
3
+ const rgba = (r, g, b, a = 0.6) => `rgba(${r}, ${g}, ${b}, ${a})`;
6
4
  // Color palette for diagram JSON files - keyed colors that can be referenced by name
7
5
  export const DIAGRAM_COLORS = {
8
6
  // Single-phase regions (alpha=0.6)
@@ -44,13 +44,10 @@ export function parse_tdb(content) {
44
44
  }
45
45
  // Derive binary system from elements (excluding VA)
46
46
  const real_elements = data.elements.map((el) => el.symbol).filter(is_real_element);
47
- const binary_system = real_elements.length === 2
48
- ? [real_elements[0], real_elements[1]]
49
- : undefined;
47
+ const binary_system = real_elements.length === 2 ? [real_elements[0], real_elements[1]] : undefined;
50
48
  // Extract temperature range from functions/parameters
51
49
  // Find the actual min and max temperatures across all ranges
52
- let min_temp = Infinity;
53
- let max_temp = -Infinity;
50
+ let [min_temp, max_temp] = [Infinity, -Infinity];
54
51
  for (const func of data.functions) {
55
52
  for (const range of func.temperature_ranges) {
56
53
  if (range.min < min_temp)
@@ -152,7 +149,7 @@ const LINE_PARSERS = [
152
149
  prefix: `PARAMETER `,
153
150
  pattern: /PARAMETER\s+(\w+)\(([^)]+)\)\s+(.+?)!/i,
154
151
  handler: (match, data) => {
155
- const spec_match = match[2].match(/([^,]+),([^;]+);(\d+)/);
152
+ const spec_match = /([^,]+),([^;]+);(\d+)/.exec(match[2]);
156
153
  if (spec_match) {
157
154
  data.parameters.push({
158
155
  type: match[1],
@@ -172,7 +169,7 @@ function parse_temperature_ranges(body) {
172
169
  const trimmed = segment.trim();
173
170
  if (!trimmed)
174
171
  continue;
175
- const temp_match = trimmed.match(/^([\d.E+-]+)\s+(.+)/i);
172
+ const temp_match = /^([\d.E+-]+)\s+(.+)/i.exec(trimmed);
176
173
  if (temp_match) {
177
174
  const next_temp = parseFloat(temp_match[1]);
178
175
  const expr = temp_match[2].replace(/\s+[YN]\s*$/, ``).trim();
@@ -193,7 +190,7 @@ function parse_tdb_line(line, data) {
193
190
  parser.handler(match, data);
194
191
  else if (parser.prefix === `ELEMENT `) {
195
192
  // Fallback for simpler ELEMENT format: ELEMENT AL FCC_A1!
196
- const simple_match = line.match(/ELEMENT\s+(\S+)\s+(\S+)/i);
193
+ const simple_match = /ELEMENT\s+(\S+)\s+(\S+)/i.exec(line);
197
194
  if (simple_match) {
198
195
  data.elements.push({
199
196
  symbol: simple_match[1].toUpperCase(),
@@ -211,7 +208,11 @@ function parse_tdb_line(line, data) {
211
208
  }
212
209
  // Get a normalized system name from elements (e.g., "AL-ZN" always alphabetically sorted)
213
210
  export function get_system_name(elements) {
214
- return elements.filter(is_real_element).map((el) => el.toUpperCase()).sort().join(`-`);
211
+ return elements
212
+ .filter(is_real_element)
213
+ .map((el) => el.toUpperCase())
214
+ .sort()
215
+ .join(`-`);
215
216
  }
216
217
  // Check if a TDB file represents a binary system
217
218
  export function is_binary_system(tdb_data) {