matterviz 0.3.5 → 0.3.7

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 (229) hide show
  1. package/dist/MillerIndexInput.svelte +5 -5
  2. package/dist/api/optimade.js +3 -3
  3. package/dist/brillouin/BrillouinZone.svelte +5 -2
  4. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  5. package/dist/brillouin/BrillouinZoneExportPane.svelte +1 -3
  6. package/dist/brillouin/BrillouinZoneInfoPane.svelte +1 -1
  7. package/dist/brillouin/BrillouinZoneScene.svelte +5 -5
  8. package/dist/brillouin/compute.js +21 -21
  9. package/dist/brillouin/index.d.ts +1 -1
  10. package/dist/brillouin/index.js +0 -1
  11. package/dist/brillouin/types.d.ts +8 -13
  12. package/dist/chempot-diagram/ChemPotDiagram.svelte +3 -3
  13. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +3 -4
  14. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +33 -34
  15. package/dist/chempot-diagram/compute.js +1 -7
  16. package/dist/chempot-diagram/temperature.d.ts +1 -1
  17. package/dist/chempot-diagram/temperature.js +1 -3
  18. package/dist/chempot-diagram/types.d.ts +4 -9
  19. package/dist/colors/index.js +5 -5
  20. package/dist/composition/Composition.svelte +2 -1
  21. package/dist/composition/Formula.svelte +7 -4
  22. package/dist/composition/FormulaFilter.svelte +1 -3
  23. package/dist/composition/format.js +4 -4
  24. package/dist/composition/parse.d.ts +2 -1
  25. package/dist/composition/parse.js +61 -46
  26. package/dist/convex-hull/ConvexHull2D.svelte +62 -51
  27. package/dist/convex-hull/ConvexHull3D.svelte +101 -90
  28. package/dist/convex-hull/ConvexHull4D.svelte +70 -58
  29. package/dist/convex-hull/ConvexHullControls.svelte +24 -35
  30. package/dist/convex-hull/ConvexHullInfoPane.svelte +8 -5
  31. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +2 -0
  32. package/dist/convex-hull/ConvexHullStats.svelte +9 -2
  33. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +2 -0
  34. package/dist/convex-hull/GasPressureControls.svelte +7 -7
  35. package/dist/convex-hull/StructurePopup.svelte +65 -30
  36. package/dist/convex-hull/StructurePopup.svelte.d.ts +6 -6
  37. package/dist/convex-hull/TemperatureSlider.svelte +8 -5
  38. package/dist/convex-hull/barycentric-coords.d.ts +2 -2
  39. package/dist/convex-hull/barycentric-coords.js +2 -2
  40. package/dist/convex-hull/gas-thermodynamics.js +2 -4
  41. package/dist/convex-hull/helpers.d.ts +13 -2
  42. package/dist/convex-hull/helpers.js +37 -16
  43. package/dist/convex-hull/index.d.ts +1 -0
  44. package/dist/convex-hull/index.js +1 -0
  45. package/dist/convex-hull/thermodynamics.d.ts +2 -1
  46. package/dist/convex-hull/thermodynamics.js +7 -7
  47. package/dist/convex-hull/types.d.ts +15 -15
  48. package/dist/effects.svelte.d.ts +12 -0
  49. package/dist/effects.svelte.js +37 -0
  50. package/dist/element/BohrAtom.svelte +4 -4
  51. package/dist/element/data.json.gz.d.ts +3 -1
  52. package/dist/element/index.d.ts +1 -1
  53. package/dist/element/index.js +0 -1
  54. package/dist/fermi-surface/FermiSurface.svelte +4 -4
  55. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  56. package/dist/fermi-surface/FermiSurfaceControls.svelte +15 -19
  57. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  58. package/dist/fermi-surface/FermiSurfaceScene.svelte +8 -6
  59. package/dist/fermi-surface/compute.js +2 -2
  60. package/dist/fermi-surface/export.js +13 -26
  61. package/dist/fermi-surface/parse.js +8 -12
  62. package/dist/fermi-surface/types.d.ts +2 -5
  63. package/dist/heatmap-matrix/HeatmapMatrix.svelte +21 -3
  64. package/dist/heatmap-matrix/index.js +6 -6
  65. package/dist/io/decompress.d.ts +2 -1
  66. package/dist/io/decompress.js +1 -1
  67. package/dist/io/export.js +1 -1
  68. package/dist/io/index.d.ts +1 -1
  69. package/dist/io/index.js +0 -1
  70. package/dist/io/url-drop.js +7 -1
  71. package/dist/isosurface/IsosurfaceControls.svelte +11 -25
  72. package/dist/isosurface/slice.js +1 -1
  73. package/dist/isosurface/types.js +12 -12
  74. package/dist/labels.d.ts +1 -1
  75. package/dist/labels.js +14 -11
  76. package/dist/layout/InfoTag.svelte +6 -4
  77. package/dist/layout/PropertyFilter.svelte +4 -2
  78. package/dist/layout/json-tree/JsonTree.svelte +22 -14
  79. package/dist/layout/json-tree/JsonValue.svelte +2 -2
  80. package/dist/layout/json-tree/types.d.ts +3 -2
  81. package/dist/layout/json-tree/types.js +0 -1
  82. package/dist/layout/json-tree/utils.d.ts +4 -4
  83. package/dist/layout/json-tree/utils.js +12 -20
  84. package/dist/marching-cubes.js +13 -15
  85. package/dist/math.d.ts +11 -1
  86. package/dist/math.js +15 -6
  87. package/dist/overlays/DragControlTab.svelte +98 -0
  88. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  89. package/dist/overlays/DraggablePane.svelte +7 -84
  90. package/dist/overlays/index.d.ts +1 -0
  91. package/dist/overlays/index.js +1 -0
  92. package/dist/periodic-table/PeriodicTable.svelte +11 -11
  93. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +4 -2
  94. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  95. package/dist/phase-diagram/PhaseDiagramControls.svelte +4 -9
  96. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  97. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +2 -10
  98. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +2 -3
  99. package/dist/phase-diagram/TdbInfoPanel.svelte +3 -3
  100. package/dist/phase-diagram/build-diagram.js +11 -18
  101. package/dist/phase-diagram/diagram-input.d.ts +5 -9
  102. package/dist/phase-diagram/index.d.ts +2 -2
  103. package/dist/phase-diagram/index.js +0 -2
  104. package/dist/phase-diagram/parse.d.ts +2 -2
  105. package/dist/phase-diagram/parse.js +6 -10
  106. package/dist/phase-diagram/svg-to-diagram.js +15 -15
  107. package/dist/phase-diagram/types.d.ts +5 -11
  108. package/dist/phase-diagram/utils.d.ts +2 -2
  109. package/dist/phase-diagram/utils.js +9 -11
  110. package/dist/plot/BarPlot.svelte +162 -314
  111. package/dist/plot/BarPlot.svelte.d.ts +5 -4
  112. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  113. package/dist/plot/BinnedScatterPlot.svelte +1114 -0
  114. package/dist/plot/BinnedScatterPlot.svelte.d.ts +66 -0
  115. package/dist/plot/ColorBar.svelte +19 -17
  116. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  117. package/dist/plot/FillArea.svelte +2 -4
  118. package/dist/plot/FillArea.svelte.d.ts +1 -1
  119. package/dist/plot/Histogram.svelte +167 -281
  120. package/dist/plot/Histogram.svelte.d.ts +1 -1
  121. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  122. package/dist/plot/InteractiveAxisLabel.svelte +5 -3
  123. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  124. package/dist/plot/PlotAxis.svelte +169 -0
  125. package/dist/plot/PlotAxis.svelte.d.ts +24 -0
  126. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  127. package/dist/plot/ReferenceLine3D.svelte +53 -51
  128. package/dist/plot/ReferencePlane.svelte +39 -42
  129. package/dist/plot/ScatterPlot.svelte +300 -367
  130. package/dist/plot/ScatterPlot.svelte.d.ts +8 -5
  131. package/dist/plot/ScatterPlot3D.svelte +33 -6
  132. package/dist/plot/ScatterPlot3D.svelte.d.ts +3 -2
  133. package/dist/plot/ScatterPlot3DControls.svelte +9 -9
  134. package/dist/plot/ScatterPlotControls.svelte +3 -4
  135. package/dist/plot/ScatterPoint.svelte +18 -27
  136. package/dist/plot/ScatterPoint.svelte.d.ts +4 -3
  137. package/dist/plot/Surface3D.svelte +4 -7
  138. package/dist/plot/ZeroLines.svelte +2 -1
  139. package/dist/plot/ZeroLines.svelte.d.ts +2 -1
  140. package/dist/plot/ZoomRect.svelte +2 -2
  141. package/dist/plot/ZoomRect.svelte.d.ts +3 -3
  142. package/dist/plot/adaptive-density.d.ts +69 -0
  143. package/dist/plot/adaptive-density.js +191 -0
  144. package/dist/plot/auto-place.d.ts +43 -0
  145. package/dist/plot/auto-place.js +122 -0
  146. package/dist/plot/axis-utils.js +3 -5
  147. package/dist/plot/binned-scatter-types.d.ts +59 -0
  148. package/dist/plot/binned-scatter-types.js +1 -0
  149. package/dist/plot/data-cleaning.js +1 -1
  150. package/dist/plot/data-transform.js +1 -1
  151. package/dist/plot/fill-utils.d.ts +4 -9
  152. package/dist/plot/fill-utils.js +29 -44
  153. package/dist/plot/index.d.ts +4 -0
  154. package/dist/plot/index.js +2 -0
  155. package/dist/plot/interactions.d.ts +4 -4
  156. package/dist/plot/interactions.js +4 -3
  157. package/dist/plot/layout.d.ts +20 -2
  158. package/dist/plot/layout.js +59 -16
  159. package/dist/plot/reference-line.d.ts +1 -1
  160. package/dist/plot/reference-line.js +9 -11
  161. package/dist/plot/scales.d.ts +1 -1
  162. package/dist/plot/scales.js +20 -23
  163. package/dist/plot/types.d.ts +30 -58
  164. package/dist/plot/types.js +2 -6
  165. package/dist/plot/utils/label-placement.d.ts +24 -3
  166. package/dist/plot/utils/label-placement.js +82 -12
  167. package/dist/plot/utils/series-visibility.d.ts +8 -2
  168. package/dist/plot/utils/series-visibility.js +23 -5
  169. package/dist/rdf/RdfPlot.svelte +5 -5
  170. package/dist/rdf/calc-rdf.js +3 -3
  171. package/dist/sanitize.d.ts +2 -0
  172. package/dist/sanitize.js +2 -0
  173. package/dist/spectral/Bands.svelte +1 -1
  174. package/dist/spectral/BandsAndDos.svelte +22 -16
  175. package/dist/spectral/BrillouinBandsDos.svelte +20 -16
  176. package/dist/spectral/Dos.svelte +1 -1
  177. package/dist/spectral/helpers.d.ts +4 -2
  178. package/dist/spectral/helpers.js +44 -35
  179. package/dist/spectral/index.d.ts +1 -1
  180. package/dist/spectral/index.js +0 -1
  181. package/dist/structure/AtomLegend.svelte +23 -6
  182. package/dist/structure/AtomLegend.svelte.d.ts +1 -0
  183. package/dist/structure/CanvasTooltip.svelte +9 -9
  184. package/dist/structure/CanvasTooltip.svelte.d.ts +1 -1
  185. package/dist/structure/CellSelect.svelte +14 -16
  186. package/dist/structure/Structure.svelte +317 -68
  187. package/dist/structure/Structure.svelte.d.ts +4 -2
  188. package/dist/structure/StructureControls.svelte +20 -45
  189. package/dist/structure/StructureExportPane.svelte +2 -1
  190. package/dist/structure/StructureInfoPane.svelte +10 -8
  191. package/dist/structure/StructureScene.svelte +527 -177
  192. package/dist/structure/StructureScene.svelte.d.ts +5 -2
  193. package/dist/structure/atom-properties.js +4 -4
  194. package/dist/structure/bond-order-perception.js +115 -98
  195. package/dist/structure/bonding.d.ts +27 -1
  196. package/dist/structure/bonding.js +187 -16
  197. package/dist/structure/export.js +1 -1
  198. package/dist/structure/index.d.ts +3 -2
  199. package/dist/structure/index.js +0 -2
  200. package/dist/structure/parse.js +88 -59
  201. package/dist/symmetry/WyckoffTable.svelte +7 -0
  202. package/dist/symmetry/index.js +13 -14
  203. package/dist/table/HeatmapTable.svelte +45 -66
  204. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  205. package/dist/table/ToggleMenu.svelte +19 -10
  206. package/dist/theme/themes.mjs +12 -0
  207. package/dist/tooltip/index.d.ts +1 -1
  208. package/dist/tooltip/index.js +0 -1
  209. package/dist/trajectory/Trajectory.svelte +43 -15
  210. package/dist/trajectory/TrajectoryInfoPane.svelte +2 -2
  211. package/dist/trajectory/extract.js +1 -1
  212. package/dist/trajectory/frame-reader.js +4 -4
  213. package/dist/trajectory/helpers.d.ts +5 -4
  214. package/dist/trajectory/helpers.js +9 -17
  215. package/dist/trajectory/index.d.ts +2 -2
  216. package/dist/trajectory/index.js +2 -2
  217. package/dist/trajectory/parse/ase.js +4 -4
  218. package/dist/trajectory/parse/hdf5.js +1 -1
  219. package/dist/trajectory/parse/index.js +2 -3
  220. package/dist/trajectory/parse/lammps.js +1 -1
  221. package/dist/trajectory/parse/vasp.js +1 -1
  222. package/dist/trajectory/plotting.d.ts +1 -1
  223. package/dist/trajectory/plotting.js +38 -38
  224. package/dist/trajectory/types.d.ts +1 -1
  225. package/dist/utils.d.ts +1 -0
  226. package/dist/utils.js +9 -0
  227. package/dist/xrd/calc-xrd.js +3 -4
  228. package/dist/xrd/parse.js +1 -1
  229. package/package.json +42 -22
@@ -55,25 +55,19 @@ export function get_value_type(value) {
55
55
  return `object`; // fallback
56
56
  }
57
57
  // Check if a value type is expandable (has children)
58
- export function is_expandable_type(value_type) {
59
- return (value_type === `object` ||
60
- value_type === `array` ||
61
- value_type === `map` ||
62
- value_type === `set`);
63
- }
58
+ export const is_expandable_type = (value_type) => value_type === `object` ||
59
+ value_type === `array` ||
60
+ value_type === `map` ||
61
+ value_type === `set`;
64
62
  // Check if a value type is a primitive (searchable as string)
65
- export function is_primitive_type(value_type) {
66
- return (value_type === `string` ||
67
- value_type === `number` ||
68
- value_type === `boolean` ||
69
- value_type === `null` ||
70
- value_type === `undefined` ||
71
- value_type === `bigint`);
72
- }
63
+ export const is_primitive_type = (value_type) => value_type === `string` ||
64
+ value_type === `number` ||
65
+ value_type === `boolean` ||
66
+ value_type === `null` ||
67
+ value_type === `undefined` ||
68
+ value_type === `bigint`;
73
69
  // Check if a value is expandable
74
- export function is_expandable(value) {
75
- return is_expandable_type(get_value_type(value));
76
- }
70
+ export const is_expandable = (value) => is_expandable_type(get_value_type(value));
77
71
  // Get the number of children for a value
78
72
  export function get_child_count(value) {
79
73
  const type = get_value_type(value);
@@ -430,9 +424,7 @@ const URL_RE = /^https?:\/\/\S+$/;
430
424
  const HEX_COLOR_RE = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
431
425
  const FUNC_COLOR_RE = /^(?:rgba?|hsla?|oklch|oklab|lch|lab|color)\([^)]*\)$/i;
432
426
  // Check if a string is a URL
433
- export function is_url(str) {
434
- return URL_RE.test(str.trim());
435
- }
427
+ export const is_url = (str) => URL_RE.test(str.trim());
436
428
  // Check if a string looks like a CSS color value
437
429
  // Rejects strings with semicolons to prevent CSS injection
438
430
  export function is_css_color(str) {
@@ -1,3 +1,5 @@
1
+ const wrap_grid_idx = (val, dim) => ((val % dim) + dim) % dim;
2
+ const clamp_grid_idx = (val, max) => Math.max(0, Math.min(val, max));
1
3
  // Edge table: for each cube configuration (256 cases), which edges are intersected
2
4
  // Each bit indicates whether that edge has an intersection
3
5
  // oxfmt-ignore
@@ -297,19 +299,17 @@ const EDGE_V2 = new Uint8Array([1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7]);
297
299
  // Compute gradient (normal) at a grid point using central differences
298
300
  function compute_gradient(grid, ix, iy, iz, nx, ny, nz, periodic) {
299
301
  // Wrap for periodic, clamp for non-periodic boundaries
300
- const wrap = (val, dim) => ((val % dim) + dim) % dim;
301
- const clamp = (val, max) => Math.max(0, Math.min(val, max));
302
302
  const [ix_w, iy_w, iz_w] = periodic
303
- ? [wrap(ix, nx), wrap(iy, ny), wrap(iz, nz)]
304
- : [clamp(ix, nx - 1), clamp(iy, ny - 1), clamp(iz, nz - 1)];
303
+ ? [wrap_grid_idx(ix, nx), wrap_grid_idx(iy, ny), wrap_grid_idx(iz, nz)]
304
+ : [clamp_grid_idx(ix, nx - 1), clamp_grid_idx(iy, ny - 1), clamp_grid_idx(iz, nz - 1)];
305
305
  const [ix_m, ix_p] = periodic
306
- ? [wrap(ix - 1, nx), wrap(ix + 1, nx)]
306
+ ? [wrap_grid_idx(ix - 1, nx), wrap_grid_idx(ix + 1, nx)]
307
307
  : [Math.max(0, ix - 1), Math.min(nx - 1, ix + 1)];
308
308
  const [iy_m, iy_p] = periodic
309
- ? [wrap(iy - 1, ny), wrap(iy + 1, ny)]
309
+ ? [wrap_grid_idx(iy - 1, ny), wrap_grid_idx(iy + 1, ny)]
310
310
  : [Math.max(0, iy - 1), Math.min(ny - 1, iy + 1)];
311
311
  const [iz_m, iz_p] = periodic
312
- ? [wrap(iz - 1, nz), wrap(iz + 1, nz)]
312
+ ? [wrap_grid_idx(iz - 1, nz), wrap_grid_idx(iz + 1, nz)]
313
313
  : [Math.max(0, iz - 1), Math.min(nz - 1, iz + 1)];
314
314
  const dx = (grid[ix_p][iy_w][iz_w] - grid[ix_m][iy_w][iz_w]) * 0.5;
315
315
  const dy = (grid[ix_w][iy_p][iz_w] - grid[ix_w][iy_m][iz_w]) * 0.5;
@@ -346,8 +346,6 @@ export function marching_cubes(grid, iso_value, k_lattice, options = {}) {
346
346
  console.warn(`Grid size ${nx}×${ny}×${nz} may cause cache key overflow`);
347
347
  }
348
348
  const vertex_cache = new Map();
349
- // Safe modulo wrapping helper (handles negative values correctly)
350
- const wrap = (val, size) => ((val % size) + size) % size;
351
349
  // Precompute k_lattice values for faster coordinate transform
352
350
  const [kx0, kx1, kx2] = k_lattice[0];
353
351
  const [ky0, ky1, ky2] = k_lattice[1];
@@ -370,12 +368,12 @@ export function marching_cubes(grid, iso_value, k_lattice, options = {}) {
370
368
  const oy2 = CUBE_VERTS_Y[v2_idx];
371
369
  const oz2 = CUBE_VERTS_Z[v2_idx];
372
370
  // Compute wrapped grid positions using safe modulo for periodic boundaries
373
- const g1x = periodic ? wrap(ix + ox1, nx) : ix + ox1;
374
- const g1y = periodic ? wrap(iy + oy1, ny) : iy + oy1;
375
- const g1z = periodic ? wrap(iz + oz1, nz) : iz + oz1;
376
- const g2x = periodic ? wrap(ix + ox2, nx) : ix + ox2;
377
- const g2y = periodic ? wrap(iy + oy2, ny) : iy + oy2;
378
- const g2z = periodic ? wrap(iz + oz2, nz) : iz + oz2;
371
+ const g1x = periodic ? wrap_grid_idx(ix + ox1, nx) : ix + ox1;
372
+ const g1y = periodic ? wrap_grid_idx(iy + oy1, ny) : iy + oy1;
373
+ const g1z = periodic ? wrap_grid_idx(iz + oz1, nz) : iz + oz1;
374
+ const g2x = periodic ? wrap_grid_idx(ix + ox2, nx) : ix + ox2;
375
+ const g2y = periodic ? wrap_grid_idx(iy + oy2, ny) : iy + oy2;
376
+ const g2z = periodic ? wrap_grid_idx(iz + oz2, nz) : iz + oz2;
379
377
  // Create numeric cache key (sorted for consistency)
380
378
  // Safe for grids up to ~300³ before exceeding Number.MAX_SAFE_INTEGER
381
379
  const flat1 = g1x * ny_nz + g1y * nz + g1z;
package/dist/math.d.ts CHANGED
@@ -3,9 +3,18 @@ export type Vec2 = [number, number];
3
3
  export type Vec3 = [number, number, number];
4
4
  export type Vec4 = [number, number, number, number];
5
5
  export type Vec9 = [number, number, number, number, number, number, number, number, number];
6
+ export type Point2D = {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ export type Point3D = Point2D & {
11
+ z: number;
12
+ };
6
13
  export type Matrix3x3 = [Vec3, Vec3, Vec3];
7
14
  export type Matrix4x4 = [Vec4, Vec4, Vec4, Vec4];
8
15
  export type NdVector = number[];
16
+ export declare const is_finite_vec3_like: (values: ArrayLike<unknown> | undefined) => values is ArrayLike<number>;
17
+ export declare const finite_vec3_from_values: (values: ArrayLike<unknown> | undefined) => Vec3 | undefined;
9
18
  export type Matrix4Tuple = [
10
19
  number,
11
20
  number,
@@ -37,7 +46,7 @@ export declare function calc_lattice_params(matrix: Matrix3x3): LatticeParams &
37
46
  export declare const scale: <T extends NdVector>(vec: T, factor: number) => T;
38
47
  export declare const euclidean_dist: (vec1: NdVector, vec2: NdVector) => number;
39
48
  export declare function min_image_displacement(from: Vec3, to: Vec3, lattice_matrix: Matrix3x3, converters?: LatticeConverters, pbc?: Pbc): Vec3;
40
- export declare function pbc_dist(pos1: Vec3, pos2: Vec3, lattice_matrix: Matrix3x3, converters?: LatticeConverters, pbc?: Pbc): number;
49
+ export declare const pbc_dist: (pos1: Vec3, pos2: Vec3, lattice_matrix: Matrix3x3, converters?: LatticeConverters, pbc?: Pbc) => number;
41
50
  export declare function matrix_inverse_3x3(matrix: Matrix3x3): Matrix3x3;
42
51
  export declare function mat3x3_vec3_multiply(matrix: Matrix3x3, vector: Vec3): Vec3;
43
52
  export declare function add<T extends NdVector>(...vecs: T[]): T;
@@ -88,4 +97,5 @@ export declare function compute_bounding_box_2d(vertices: Vec2[]): {
88
97
  export declare function polygon_centroid(vertices: Vec2[]): Vec2;
89
98
  export declare function solve_linear_system(A: number[][], // NxN coefficient matrix
90
99
  b: number[]): number[] | null;
100
+ export declare const cross_2d: (origin: Vec2, point_a: Vec2, point_b: Vec2) => number;
91
101
  export declare function convex_hull_2d(points: Vec2[]): Vec2[];
package/dist/math.js CHANGED
@@ -1,3 +1,13 @@
1
+ export const is_finite_vec3_like = (values) => {
2
+ if (values?.length !== 3)
3
+ return false;
4
+ return [0, 1, 2].every((idx) => typeof values[idx] === `number` && Number.isFinite(values[idx]));
5
+ };
6
+ export const finite_vec3_from_values = (values) => {
7
+ if (!is_finite_vec3_like(values))
8
+ return undefined;
9
+ return [values[0], values[1], values[2]];
10
+ };
1
11
  // Generate all k-element combinations from an array.
2
12
  export function combinations(arr, k) {
3
13
  if (k === 0)
@@ -107,9 +117,7 @@ export function min_image_displacement(from, to, lattice_matrix, converters, pbc
107
117
  return best_displacement;
108
118
  }
109
119
  // Calculate the minimum distance between two points considering periodic boundary conditions.
110
- export function pbc_dist(pos1, pos2, lattice_matrix, converters, pbc = [true, true, true]) {
111
- return Math.hypot(...min_image_displacement(pos1, pos2, lattice_matrix, converters, pbc));
112
- }
120
+ export const pbc_dist = (pos1, pos2, lattice_matrix, converters, pbc = [true, true, true]) => Math.hypot(...min_image_displacement(pos1, pos2, lattice_matrix, converters, pbc));
113
121
  export function matrix_inverse_3x3(matrix) {
114
122
  const [[m11, m12, m13], [m21, m22, m23], [m31, m32, m33]] = matrix;
115
123
  const det = det_3x3(matrix);
@@ -863,18 +871,19 @@ b) {
863
871
  }
864
872
  return x;
865
873
  }
874
+ export const cross_2d = (origin, point_a, point_b) => (point_a[0] - origin[0]) * (point_b[1] - origin[1]) -
875
+ (point_a[1] - origin[1]) * (point_b[0] - origin[0]);
866
876
  // Full 2D convex hull via Andrew's monotone chain algorithm.
867
877
  // Returns vertices in counter-clockwise order.
868
878
  export function convex_hull_2d(points) {
869
879
  if (points.length < 3)
870
880
  return [...points];
871
881
  const sorted = points.toSorted((a, b) => a[0] - b[0] || a[1] - b[1]);
872
- const cross = (o, a, b) => (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
873
882
  // Lower hull
874
883
  const lower = [];
875
884
  for (const pt of sorted) {
876
885
  while (lower.length >= 2 &&
877
- cross(lower[lower.length - 2], lower[lower.length - 1], pt) <= 0) {
886
+ cross_2d(lower[lower.length - 2], lower[lower.length - 1], pt) <= 0) {
878
887
  lower.pop();
879
888
  }
880
889
  lower.push(pt);
@@ -884,7 +893,7 @@ export function convex_hull_2d(points) {
884
893
  for (let idx = sorted.length - 1; idx >= 0; idx--) {
885
894
  const pt = sorted[idx];
886
895
  while (upper.length >= 2 &&
887
- cross(upper[upper.length - 2], upper[upper.length - 1], pt) <= 0) {
896
+ cross_2d(upper[upper.length - 2], upper[upper.length - 1], pt) <= 0) {
888
897
  upper.pop();
889
898
  }
890
899
  upper.push(pt);
@@ -0,0 +1,98 @@
1
+ <script lang="ts">
2
+ import Icon from '../Icon.svelte'
3
+ import type { IconName } from '../icons'
4
+
5
+ let {
6
+ show_controls = false,
7
+ on_reset,
8
+ on_close,
9
+ }: {
10
+ show_controls?: boolean
11
+ on_reset?: () => void
12
+ on_close?: () => void
13
+ } = $props()
14
+ </script>
15
+
16
+ {#snippet control_button(callback: () => void, css_class: string, icon: IconName, label: string)}
17
+ <button
18
+ type="button"
19
+ class={css_class}
20
+ onclick={(event) => {
21
+ event.stopPropagation()
22
+ callback()
23
+ }}
24
+ title={label}
25
+ aria-label={label}
26
+ >
27
+ <Icon {icon} style="width: 1em; height: 1em" />
28
+ </button>
29
+ {/snippet}
30
+
31
+ <div class="control-tab">
32
+ <Icon icon="DragIndicator" class="drag-handle" style="width: 1em; height: 1em" />
33
+ {#if show_controls}
34
+ {#if on_reset}
35
+ {@render control_button(on_reset, `reset-button`, `Reset`, `Reset pane position`)}
36
+ {/if}
37
+ {#if on_close}
38
+ {@render control_button(on_close, `close-button`, `Cross`, `Close pane`)}
39
+ {/if}
40
+ {/if}
41
+ </div>
42
+
43
+ <style>
44
+ .control-tab {
45
+ position: absolute;
46
+ top: 6px;
47
+ right: -1px;
48
+ transform: translateX(100%);
49
+ display: flex;
50
+ flex-direction: column;
51
+ align-items: center;
52
+ gap: 1px;
53
+ padding: 3px 2px;
54
+ background: var(--pane-bg, var(--page-bg, light-dark(white, black)));
55
+ border: var(
56
+ --pane-border,
57
+ 1px solid light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.15))
58
+ );
59
+ border-left: none;
60
+ border-radius: 0 5px 5px 0;
61
+ z-index: var(--pane-control-tab-z-index, var(--pane-control-buttons-z-index, 1));
62
+ }
63
+ .control-tab :global(.drag-handle) {
64
+ width: 1.1em;
65
+ height: 1.1em;
66
+ cursor: grab;
67
+ border-radius: 3px;
68
+ padding: 1px;
69
+ box-sizing: border-box;
70
+ opacity: 0.5;
71
+ pointer-events: auto;
72
+ }
73
+ .control-tab :global(.drag-handle:hover) {
74
+ opacity: 0.8;
75
+ background-color: color-mix(in srgb, currentColor 15%, transparent);
76
+ }
77
+ .control-tab :global(.drag-handle:active) {
78
+ cursor: grabbing;
79
+ }
80
+ :where(.reset-button, .close-button) {
81
+ background: none;
82
+ border: none;
83
+ padding: 1px;
84
+ border-radius: 3px;
85
+ box-sizing: border-box;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ width: 1.1em;
90
+ height: 1.1em;
91
+ opacity: 0.5;
92
+ cursor: pointer;
93
+ }
94
+ :where(.reset-button:hover, .close-button:hover) {
95
+ opacity: 0.8;
96
+ background-color: color-mix(in srgb, currentColor 15%, transparent);
97
+ }
98
+ </style>
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ show_controls?: boolean;
3
+ on_reset?: () => void;
4
+ on_close?: () => void;
5
+ };
6
+ declare const DragControlTab: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type DragControlTab = ReturnType<typeof DragControlTab>;
8
+ export default DragControlTab;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import Icon from '../Icon.svelte'
3
3
  import type { IconName } from '../icons'
4
+ import { DragControlTab } from './'
4
5
  import type { Snippet } from 'svelte'
5
6
  import { draggable, tooltip } from 'svelte-multiselect/attachments'
6
7
  import type { HTMLAttributes } from 'svelte/elements'
@@ -260,38 +261,13 @@
260
261
  style:left={initial_position.left}
261
262
  style:display={show ? `grid` : `none`}
262
263
  {...pane_props}
263
- class="draggable-pane {show ? `pane-open` : ``} {pane_props.class ?? ``}"
264
+ class="draggable-pane toc-exclude {show ? `pane-open` : ``} {pane_props.class ?? ``}"
264
265
  >
265
- <div class="control-tab">
266
- <Icon
267
- icon="DragIndicator"
268
- class="drag-handle"
269
- style="width: 1em; height: 1em"
270
- />
271
- {#if show_control_buttons}
272
- <button
273
- type="button"
274
- class="reset-button"
275
- onclick={(event: MouseEvent) => {
276
- event.stopPropagation()
277
- reset_position()
278
- }}
279
- title="Reset pane position"
280
- aria-label="Reset pane position"
281
- >
282
- <Icon icon="Reset" style="width: 1em; height: 1em" />
283
- </button>
284
- <button
285
- type="button"
286
- class="close-button"
287
- onclick={close_pane}
288
- title="Close pane"
289
- aria-label="Close pane"
290
- >
291
- <Icon icon="Cross" style="width: 1em; height: 1em" />
292
- </button>
293
- {/if}
294
- </div>
266
+ <DragControlTab
267
+ show_controls={show_control_buttons}
268
+ on_reset={reset_position}
269
+ on_close={close_pane}
270
+ />
295
271
  <div class="pane-content">
296
272
  {@render children?.({
297
273
  show,
@@ -484,59 +460,6 @@
484
460
  .draggable-pane :global(label:has(input[type='range'])) {
485
461
  flex: 1;
486
462
  }
487
- .draggable-pane .control-tab {
488
- position: absolute;
489
- top: 6px;
490
- right: -1px;
491
- transform: translateX(100%);
492
- display: flex;
493
- flex-direction: column;
494
- align-items: center;
495
- gap: 1px;
496
- padding: 3px 2px;
497
- background: var(--pane-bg, var(--page-bg, light-dark(white, black)));
498
- border: var(
499
- --pane-border,
500
- 1px solid light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.15))
501
- );
502
- border-left: none;
503
- border-radius: 0 5px 5px 0;
504
- z-index: var(--pane-control-tab-z-index, var(--pane-control-buttons-z-index, 1));
505
- }
506
- .draggable-pane :global(.drag-handle) {
507
- width: 1.1em;
508
- height: 1.1em;
509
- cursor: grab;
510
- border-radius: 3px;
511
- padding: 1px;
512
- box-sizing: border-box;
513
- opacity: 0.5;
514
- pointer-events: auto;
515
- }
516
- .draggable-pane :global(.drag-handle:hover) {
517
- opacity: 0.8;
518
- background-color: color-mix(in srgb, currentColor 15%, transparent);
519
- }
520
- .draggable-pane :global(.drag-handle:active) {
521
- cursor: grabbing;
522
- }
523
- .draggable-pane :where(.reset-button, .close-button) {
524
- background: none;
525
- border: none;
526
- padding: 1px;
527
- border-radius: 3px;
528
- box-sizing: border-box;
529
- display: flex;
530
- align-items: center;
531
- justify-content: center;
532
- width: 1.1em;
533
- height: 1.1em;
534
- opacity: 0.5;
535
- }
536
- .draggable-pane :where(.reset-button:hover, .close-button:hover) {
537
- opacity: 0.8;
538
- background-color: color-mix(in srgb, currentColor 15%, transparent);
539
- }
540
463
  .draggable-pane .resize-grip {
541
464
  position: absolute;
542
465
  bottom: 0;
@@ -1,2 +1,3 @@
1
1
  export { default as ContextMenu } from './ContextMenu.svelte';
2
2
  export { default as DraggablePane } from './DraggablePane.svelte';
3
+ export { default as DragControlTab } from './DragControlTab.svelte';
@@ -1,2 +1,3 @@
1
1
  export { default as ContextMenu } from './ContextMenu.svelte';
2
2
  export { default as DraggablePane } from './DraggablePane.svelte';
3
+ export { default as DragControlTab } from './DragControlTab.svelte';
@@ -3,8 +3,7 @@
3
3
  import type { ChemicalElement, ElementCategory, ElementSymbol } from '../element'
4
4
  import { element_data, ElementPhoto, ElementTile } from '../element'
5
5
  import { ELEM_SYMBOLS } from '../labels'
6
- import type { Vec2 } from '../math'
7
- import type { XyObj } from '../plot'
6
+ import type { Point2D, Vec2 } from '../math'
8
7
  import { ColorBar } from '../plot'
9
8
  import { colors } from '../state.svelte'
10
9
  import * as d3_sc from 'd3-scale-chromatic'
@@ -139,7 +138,7 @@
139
138
 
140
139
  let window_width: number = $state(0)
141
140
  let tooltip_element: ChemicalElement | null = $state(null)
142
- let tooltip_pos: XyObj = $state({ x: 0, y: 0 })
141
+ let tooltip_pos: Point2D = $state({ x: 0, y: 0 })
143
142
  let tooltip_visible: boolean = $state(false)
144
143
 
145
144
  function handle_key(event: KeyboardEvent) {
@@ -173,7 +172,8 @@
173
172
  function handle_tooltip_enter(element: ChemicalElement, event: MouseEvent) {
174
173
  if (tooltip === false || disabled) return
175
174
  tooltip_element = element
176
- const target = event.currentTarget as HTMLElement
175
+ const target = event.currentTarget
176
+ if (!(target instanceof HTMLElement)) return
177
177
  const rect = target.getBoundingClientRect()
178
178
  const container_rect = target.closest(`.ptable-grid`)?.getBoundingClientRect()
179
179
  if (container_rect) {
@@ -251,11 +251,11 @@
251
251
  ) => {
252
252
  if (!Array.isArray(value)) return []
253
253
 
254
- return value.map((v) => {
254
+ return value.map((val) => {
255
255
  // If it's already a color string, return it directly
256
- if (is_color(v)) return v as string
256
+ if (is_color(val)) return val as string
257
257
  // Otherwise, map it through the color scale
258
- return bg_color(v as number, element)
258
+ return bg_color(val as number, element)
259
259
  })
260
260
  },
261
261
  )
@@ -266,9 +266,9 @@
266
266
 
267
267
  const num_vals = heat_values
268
268
  .flat()
269
- .filter((v): v is number => typeof v === `number`)
269
+ .filter((val): val is number => typeof val === `number`)
270
270
 
271
- const usable_values = log ? num_vals.filter((v) => v > 0) : num_vals
271
+ const usable_values = log ? num_vals.filter((val) => val > 0) : num_vals
272
272
 
273
273
  return usable_values.length > 0
274
274
  })
@@ -279,8 +279,8 @@
279
279
 
280
280
  const numeric_values = heat_values
281
281
  .flat()
282
- .filter((v): v is number => typeof v === `number`)
283
- const usable_values = log ? numeric_values.filter((v) => v > 0) : numeric_values
282
+ .filter((val): val is number => typeof val === `number`)
283
+ const usable_values = log ? numeric_values.filter((val) => val > 0) : numeric_values
284
284
 
285
285
  if (usable_values.length === 0) return [0, 1]
286
286
 
@@ -366,8 +366,10 @@
366
366
  }
367
367
 
368
368
  // Pointer move handler (unified mouse/touch via Pointer Events API)
369
- function handle_pointer_move(event: PointerEvent) {
370
- const svg = event.currentTarget as SVGElement
369
+ function handle_pointer_move(
370
+ event: PointerEvent & { currentTarget: SVGElement },
371
+ ) {
372
+ const svg = event.currentTarget
371
373
  const rect = svg.getBoundingClientRect()
372
374
  const svg_x = event.clientX - rect.left
373
375
  const svg_y = event.clientY - rect.top
@@ -39,6 +39,6 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
39
39
  }
40
40
  ]>;
41
41
  };
42
- declare const IsobaricBinaryPhaseDiagram: import("svelte").Component<$$ComponentProps, {}, "fullscreen" | "controls_open" | "x_axis" | "y_axis" | "show_grid" | "wrapper" | "hovered_region" | "config" | "show_boundaries" | "show_labels" | "show_special_points" | "show_component_labels" | "png_dpi" | "export_pane_open" | "lever_rule_mode" | "editor_open" | "diagram_input" | "display_temp_unit">;
42
+ declare const IsobaricBinaryPhaseDiagram: import("svelte").Component<$$ComponentProps, {}, "x_axis" | "y_axis" | "fullscreen" | "controls_open" | "wrapper" | "show_grid" | "config" | "show_boundaries" | "show_labels" | "show_special_points" | "show_component_labels" | "png_dpi" | "export_pane_open" | "lever_rule_mode" | "editor_open" | "diagram_input" | "hovered_region" | "display_temp_unit">;
43
43
  type IsobaricBinaryPhaseDiagram = ReturnType<typeof IsobaricBinaryPhaseDiagram>;
44
44
  export default IsobaricBinaryPhaseDiagram;
@@ -110,8 +110,8 @@
110
110
  on_change: (val: number) => void,
111
111
  tip: string,
112
112
  )}
113
- {@const oninput = (ev: Event) =>
114
- on_change(Number((ev.currentTarget as HTMLInputElement).value))}
113
+ {@const oninput = (ev: Event & { currentTarget: HTMLInputElement }) =>
114
+ on_change(Number(ev.currentTarget.value))}
115
115
  <label {@attach tooltip({ content: tip })}>
116
116
  {label}
117
117
  <input type="number" {min} {max} {step} {value} {oninput} />
@@ -177,9 +177,7 @@
177
177
  </label>
178
178
  {/if}
179
179
  <label
180
- {@attach tooltip({
181
- content: `Show component labels at axes`,
182
- })}
180
+ {@attach tooltip({ content: `Show component labels at axes` })}
183
181
  >
184
182
  <input type="checkbox" bind:checked={show_component_labels} />
185
183
  Comp. Labels
@@ -354,10 +352,7 @@
354
352
  }}
355
353
  >
356
354
  <label
357
- {@attach tooltip({
358
- content:
359
- `DPI (dots per inch) for PNG export. Higher values produce larger, higher-quality images.`,
360
- })}
355
+ {@attach tooltip({ content: `DPI (dots per inch) for PNG export. Higher values produce larger, higher-quality images.` })}
361
356
  >
362
357
  PNG DPI
363
358
  <input
@@ -25,6 +25,6 @@ type $$ComponentProps = Omit<ComponentProps<typeof DraggablePane>, `children`> &
25
25
  controls_open: boolean;
26
26
  }]>;
27
27
  };
28
- declare const PhaseDiagramControls: import("svelte").Component<$$ComponentProps, {}, "controls_open" | "x_axis" | "y_axis" | "show_grid" | "config" | "show_boundaries" | "show_labels" | "show_special_points" | "show_component_labels" | "png_dpi" | "lever_rule_mode">;
28
+ declare const PhaseDiagramControls: import("svelte").Component<$$ComponentProps, {}, "x_axis" | "y_axis" | "controls_open" | "show_grid" | "config" | "show_boundaries" | "show_labels" | "show_special_points" | "show_component_labels" | "png_dpi" | "lever_rule_mode">;
29
29
  type PhaseDiagramControls = ReturnType<typeof PhaseDiagramControls>;
30
30
  export default PhaseDiagramControls;
@@ -84,11 +84,7 @@
84
84
  }}
85
85
  >
86
86
  <div class="export-grid">
87
- <h4 id="image"
88
- {@attach tooltip({
89
- content: `Download or copy the phase diagram`,
90
- })}
91
- >
87
+ <h4 id="image" {@attach tooltip({ content: `Download or copy the phase diagram` })}>
92
88
  Image
93
89
  </h4>
94
90
  <label>
@@ -128,11 +124,7 @@
128
124
  />)</span>
129
125
  </label>
130
126
 
131
- <h4 id="data"
132
- {@attach tooltip({
133
- content: `Export phase diagram data as JSON`,
134
- })}
135
- >
127
+ <h4 id="data" {@attach tooltip({ content: `Export phase diagram data as JSON` })}>
136
128
  Data
137
129
  </h4>
138
130
  <label>
@@ -51,9 +51,8 @@
51
51
  const safe_formula = (comp: string) => sanitize_formula(comp, use_subscripts)
52
52
 
53
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
- }
54
+ const to_display = (temp: number): number =>
55
+ convert_temp(temp, data_unit, temperature_unit)
57
56
 
58
57
  // Convert atomic fraction to weight fraction: wt_B = (x_B * M_B) / (x_A * M_A + x_B * M_B)
59
58
  const wt_fraction_b = $derived.by(() => {
@@ -63,9 +63,9 @@
63
63
  {/if}
64
64
  </p>
65
65
  {:else}
66
- {@const elems = result.data.elements.map((e) => e.symbol).filter((s) =>
67
- s !== `VA` && s !== `/-`
68
- )}
66
+ {@const elems = result.data.elements
67
+ .map((element) => element.symbol)
68
+ .filter((symbol) => symbol !== `VA` && symbol !== `/-`)}
69
69
  {@const [el_a, el_b] = [elems[0] ?? `EL1`, elems[1] ?? `EL2`]}
70
70
  {@const tdb = system_name || `your_system`}
71
71
  <div class="notice warning">
@@ -105,19 +105,16 @@ function infer_boundary_type(curve_name) {
105
105
  }
106
106
  // Get default boundary style based on type
107
107
  function get_boundary_style(btype) {
108
- switch (btype) {
109
- case `liquidus`:
110
- return { color: `#1565c0`, width: 2.5 };
111
- case `solidus`:
112
- return { color: `#2e7d32`, width: 2, dash: `4,2` };
113
- case `solvus`:
114
- return { color: `#7b1fa2`, width: 1.5, dash: `2,2` };
115
- case `eutectic`:
116
- case `peritectic`:
117
- return { color: `#d32f2f`, width: 2 };
118
- default:
119
- return { color: `#333`, width: 1.5 };
108
+ if (btype === `liquidus`)
109
+ return { color: `#1565c0`, width: 2.5 };
110
+ if (btype === `solidus`)
111
+ return { color: `#2e7d32`, width: 2, dash: `4,2` };
112
+ if (btype === `solvus`)
113
+ return { color: `#7b1fa2`, width: 1.5, dash: `2,2` };
114
+ if (btype === `eutectic` || btype === `peritectic`) {
115
+ return { color: `#d32f2f`, width: 2 };
120
116
  }
117
+ return { color: `#333`, width: 1.5 };
121
118
  }
122
119
  // Build full PhaseDiagramData from compact DiagramInput JSON format
123
120
  // Expands curve references in region bounds to full vertex lists
@@ -138,12 +135,8 @@ export function build_diagram(input) {
138
135
  // Build boundaries from all curves
139
136
  const boundaries = Object.entries(curves).map(([name, points]) => {
140
137
  const btype = infer_boundary_type(name);
141
- return {
142
- id: name,
143
- type: btype,
144
- points,
145
- style: get_boundary_style(btype),
146
- };
138
+ const style = get_boundary_style(btype);
139
+ return { id: name, type: btype, points, style };
147
140
  });
148
141
  // Build the full diagram data (spread optional fields conditionally)
149
142
  return {