matterviz 0.3.3 → 0.3.5

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 (126) hide show
  1. package/dist/FilePicker.svelte +1 -1
  2. package/dist/app.css +7 -0
  3. package/dist/brillouin/BrillouinZone.svelte +5 -2
  4. package/dist/brillouin/compute.js +8 -4
  5. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +6 -6
  6. package/dist/chempot-diagram/async-compute.svelte.js +6 -5
  7. package/dist/chempot-diagram/chempot-worker.js +2 -2
  8. package/dist/chempot-diagram/compute.js +16 -16
  9. package/dist/composition/FormulaFilter.svelte +3 -3
  10. package/dist/constants.js +2 -8
  11. package/dist/convex-hull/ConvexHull.svelte +2 -2
  12. package/dist/convex-hull/ConvexHull2D.svelte +11 -10
  13. package/dist/convex-hull/ConvexHull3D.svelte +16 -14
  14. package/dist/convex-hull/ConvexHull4D.svelte +26 -14
  15. package/dist/convex-hull/ConvexHullControls.svelte +1 -1
  16. package/dist/convex-hull/ConvexHullInfoPane.svelte +68 -61
  17. package/dist/convex-hull/ConvexHullStats.svelte +23 -6
  18. package/dist/convex-hull/GasPressureControls.svelte +3 -3
  19. package/dist/convex-hull/TemperatureSlider.svelte +1 -1
  20. package/dist/convex-hull/barycentric-coords.js +2 -2
  21. package/dist/convex-hull/helpers.js +45 -27
  22. package/dist/convex-hull/thermodynamics.js +2 -2
  23. package/dist/element/BohrAtom.svelte +25 -27
  24. package/dist/element/BohrAtom.svelte.d.ts +2 -2
  25. package/dist/element/data.d.ts +2 -3
  26. package/dist/element/data.js +1 -1
  27. package/dist/fermi-surface/FermiSurface.svelte +5 -2
  28. package/dist/fermi-surface/compute.js +3 -3
  29. package/dist/fermi-surface/parse.js +2 -2
  30. package/dist/fermi-surface/symmetry.js +1 -1
  31. package/dist/heatmap-matrix/HeatmapMatrix.svelte +8 -8
  32. package/dist/icons.d.ts +6 -6
  33. package/dist/icons.js +6 -6
  34. package/dist/io/decompress.js +12 -7
  35. package/dist/io/export.js +20 -16
  36. package/dist/io/is-binary.js +19 -4
  37. package/dist/isosurface/parse.js +8 -8
  38. package/dist/isosurface/types.js +9 -9
  39. package/dist/layout/InfoTag.svelte +1 -1
  40. package/dist/layout/json-tree/JsonNode.svelte +1 -0
  41. package/dist/layout/json-tree/utils.js +2 -1
  42. package/dist/marching-cubes.js +1 -1
  43. package/dist/math.js +1 -1
  44. package/dist/overlays/CopyButton.svelte +45 -0
  45. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  46. package/dist/overlays/InfoPaneCards.svelte +149 -0
  47. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  48. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +33 -35
  49. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +2 -2
  50. package/dist/phase-diagram/PhaseDiagramControls.svelte +27 -29
  51. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +2 -2
  52. package/dist/phase-diagram/parse.js +3 -3
  53. package/dist/phase-diagram/svg-to-diagram.js +10 -12
  54. package/dist/plot/BarPlot.svelte +24 -15
  55. package/dist/plot/BarPlot.svelte.d.ts +3 -2
  56. package/dist/plot/FillArea.svelte +2 -3
  57. package/dist/plot/FillArea.svelte.d.ts +3 -2
  58. package/dist/plot/Histogram.svelte +37 -19
  59. package/dist/plot/Line.svelte +2 -3
  60. package/dist/plot/Line.svelte.d.ts +2 -2
  61. package/dist/plot/PlotLegend.svelte +79 -8
  62. package/dist/plot/PlotLegend.svelte.d.ts +4 -0
  63. package/dist/plot/PortalSelect.svelte +5 -5
  64. package/dist/plot/ScatterPlot.svelte +47 -33
  65. package/dist/plot/ScatterPlot.svelte.d.ts +5 -4
  66. package/dist/plot/ScatterPlot3D.svelte +6 -3
  67. package/dist/plot/ScatterPoint.svelte +10 -4
  68. package/dist/plot/ScatterPoint.svelte.d.ts +4 -2
  69. package/dist/plot/SpacegroupBarPlot.svelte +5 -4
  70. package/dist/plot/data-cleaning.js +9 -9
  71. package/dist/plot/index.d.ts +0 -6
  72. package/dist/plot/scales.d.ts +3 -3
  73. package/dist/plot/scales.js +29 -29
  74. package/dist/plot/types.d.ts +5 -9
  75. package/dist/rdf/calc-rdf.js +1 -1
  76. package/dist/sanitize.js +22 -15
  77. package/dist/settings.d.ts +2 -0
  78. package/dist/settings.js +12 -3
  79. package/dist/spectral/Bands.svelte +6 -6
  80. package/dist/spectral/BandsAndDos.svelte +4 -4
  81. package/dist/spectral/BrillouinBandsDos.svelte +3 -3
  82. package/dist/spectral/Dos.svelte +2 -2
  83. package/dist/spectral/helpers.js +1 -1
  84. package/dist/structure/AtomLegend.svelte +4 -4
  85. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  86. package/dist/structure/Cylinder.svelte +7 -7
  87. package/dist/structure/Structure.svelte +169 -27
  88. package/dist/structure/Structure.svelte.d.ts +6 -2
  89. package/dist/structure/StructureControls.svelte +130 -16
  90. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  91. package/dist/structure/StructureInfoPane.svelte +519 -218
  92. package/dist/structure/StructureInfoPane.svelte.d.ts +2 -1
  93. package/dist/structure/StructureScene.svelte +399 -68
  94. package/dist/structure/StructureScene.svelte.d.ts +8 -4
  95. package/dist/structure/atom-properties.js +3 -1
  96. package/dist/structure/bond-order-perception.d.ts +13 -0
  97. package/dist/structure/bond-order-perception.js +367 -0
  98. package/dist/structure/bonding.d.ts +10 -1
  99. package/dist/structure/bonding.js +232 -11
  100. package/dist/structure/export.js +6 -4
  101. package/dist/structure/index.d.ts +19 -4
  102. package/dist/structure/index.js +3 -0
  103. package/dist/structure/label-placement.d.ts +14 -0
  104. package/dist/structure/label-placement.js +72 -0
  105. package/dist/structure/parse.d.ts +2 -1
  106. package/dist/structure/parse.js +25 -36
  107. package/dist/structure/supercell.js +35 -2
  108. package/dist/symmetry/SymmetryStats.svelte +1 -1
  109. package/dist/symmetry/cell-transform.js +15 -1
  110. package/dist/symmetry/index.js +3 -3
  111. package/dist/table/HeatmapTable.svelte +3 -3
  112. package/dist/table/ToggleMenu.svelte +1 -1
  113. package/dist/trajectory/Trajectory.svelte +2 -2
  114. package/dist/trajectory/TrajectoryInfoPane.svelte +14 -88
  115. package/dist/trajectory/extract.js +4 -4
  116. package/dist/trajectory/frame-reader.js +2 -2
  117. package/dist/trajectory/parse/ase.js +2 -6
  118. package/dist/trajectory/parse/hdf5.js +1 -3
  119. package/dist/trajectory/plotting.js +1 -1
  120. package/dist/utils.js +1 -1
  121. package/dist/xrd/calc-xrd.js +1 -1
  122. package/package.json +23 -38
  123. package/dist/structure/ferrox-wasm-types.d.ts +0 -46
  124. package/dist/structure/ferrox-wasm-types.js +0 -18
  125. package/dist/structure/ferrox-wasm.d.ts +0 -94
  126. package/dist/structure/ferrox-wasm.js +0 -249
@@ -1,6 +1,13 @@
1
1
  import { ATOMIC_NUMBER_TO_SYMBOL } from '../composition/parse';
2
2
  import * as math from '../math';
3
3
  import { wrap_to_unit_cell } from '../structure/pbc';
4
+ const transferable_properties = (properties) => {
5
+ if (properties === undefined)
6
+ return undefined;
7
+ const rest = { ...properties };
8
+ delete rest.bonds;
9
+ return Object.keys(rest).length > 0 ? rest : undefined;
10
+ };
4
11
  // Convert a MoyoCell (from moyo-wasm symmetry analysis) to Crystal format.
5
12
  // MoyoCell has a flat 9-element basis array and atomic numbers; this converts to
6
13
  // the full Crystal with lattice parameters and element symbols.
@@ -41,7 +48,14 @@ original_structure) {
41
48
  pbc: original_structure.lattice.pbc,
42
49
  ...lattice_params,
43
50
  };
44
- return { lattice, sites, charge: original_structure.charge, id: original_structure.id };
51
+ const properties = transferable_properties(original_structure.properties);
52
+ return {
53
+ lattice,
54
+ sites,
55
+ charge: original_structure.charge,
56
+ id: original_structure.id,
57
+ ...(properties === undefined ? {} : { properties }),
58
+ };
45
59
  }
46
60
  // Get the conventional (standardized) cell from symmetry analysis data.
47
61
  // The conventional cell is the standard crystallographic setting for the space group.
@@ -149,12 +149,12 @@ export function wyckoff_positions_from_moyo(sym_data) {
149
149
  group.positions.push(position);
150
150
  groups.set(key, group);
151
151
  }
152
- const rows = Array.from(groups.values()).map(({ letter, elem, indices, positions }) => {
152
+ const rows = Array.from(groups.values()).map(({ letter, elem, indices, positions: group_positions }) => {
153
153
  // Find the position with the best simplicity score to display
154
- const best_pos = positions.reduce((best, pos) => {
154
+ const best_pos = group_positions.reduce((best, pos) => {
155
155
  const score = simplicity_score(pos);
156
156
  return score < best.score ? { pos, score } : best;
157
- }, { pos: positions[0], score: simplicity_score(positions[0]) }).pos;
157
+ }, { pos: group_positions[0], score: simplicity_score(group_positions[0]) }).pos;
158
158
  // Map standardized cell indices back to original structure indices
159
159
  const orig_site_indices = orig_site_indices_by_std_idx
160
160
  ? indices.flatMap((std_idx) => orig_site_indices_by_std_idx[std_idx] ?? [])
@@ -696,7 +696,7 @@
696
696
  ),
697
697
  )
698
698
 
699
- const sort_indicator = (col: Label, sort_state: SortState) => {
699
+ const sort_indicator = (col: Label, current_sort_state: SortState) => {
700
700
  const hide_sort_indicator = col.show_sort_indicator === false ||
701
701
  col.style?.includes(`--hide-sort-indicator`)
702
702
  if (hide_sort_indicator) return ``
@@ -711,10 +711,10 @@
711
711
  return `<span style="font-size: 0.8em;">${arrow}${badge}</span>`
712
712
  }
713
713
 
714
- const is_sorted = sort_state.column === col_id
714
+ const is_sorted = current_sort_state.column === col_id
715
715
  if (!is_sorted) return ``
716
716
  // Show indicator only for actively sorted columns.
717
- const arrow = sort_state.ascending ? `↓` : `↑`
717
+ const arrow = current_sort_state.ascending ? `↓` : `↑`
718
718
 
719
719
  return arrow ? `<span style="font-size: 0.8em;">${arrow}</span>` : ``
720
720
  }
@@ -112,7 +112,7 @@
112
112
  )
113
113
 
114
114
  // Reposition dropdown: left-aligned by default, switch to right if it overflows viewport
115
- let details_el: HTMLElement | undefined
115
+ let details_el: HTMLElement | undefined = undefined
116
116
  $effect(() => {
117
117
  if (!column_panel_open || !details_el) return
118
118
  // Re-run when section state changes while open
@@ -466,8 +466,8 @@
466
466
  async function read_file_content(file: File): Promise<string | ArrayBuffer> {
467
467
  return new Promise((resolve, reject) => {
468
468
  const reader = new FileReader()
469
- reader.onload = () => resolve(reader.result as string | ArrayBuffer)
470
- reader.onerror = () => reject(new Error(`Failed to read file`))
469
+ reader.addEventListener(`load`, () => resolve(reader.result as string | ArrayBuffer))
470
+ reader.addEventListener(`error`, () => reject(new Error(`Failed to read file`)))
471
471
 
472
472
  // Read as text for text-based formats, binary for others
473
473
  if (file.name.toLowerCase().match(/\.(xyz|json|extxyz|lammpstrj)$/)) {
@@ -1,15 +1,12 @@
1
1
  <script lang="ts">
2
2
  import type { InfoItem } from '../layout'
3
- import Icon from '../Icon.svelte'
3
+ import InfoPaneCards from '../overlays/InfoPaneCards.svelte'
4
4
  import { format_num } from '../labels'
5
- import { sanitize_html } from '../sanitize'
6
5
  import DraggablePane from '../overlays/DraggablePane.svelte'
7
6
  import { get_electro_neg_formula } from '../composition'
8
7
  import { SETTINGS_CONFIG } from '../settings'
9
8
  import { type AnyStructure } from '../structure'
10
9
  import type { ComponentProps } from 'svelte'
11
- import { tooltip as create_tooltip } from 'svelte-multiselect/attachments'
12
- import { SvelteSet } from 'svelte/reactivity'
13
10
  import type { TrajectoryType } from './index'
14
11
 
15
12
  let {
@@ -35,20 +32,6 @@
35
32
  pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`]
36
33
  } = $props()
37
34
 
38
- let copied_items = new SvelteSet<string>()
39
-
40
- async function copy_item(label: string, value: string | number, key: string) {
41
- try {
42
- await navigator.clipboard.writeText(`${label}: ${value}`)
43
- copied_items.add(key)
44
- setTimeout(() => {
45
- copied_items.delete(key)
46
- }, 1000)
47
- } catch (error) {
48
- console.error(`Failed to copy to clipboard:`, error)
49
- }
50
- }
51
-
52
35
  // Helper functions
53
36
  const format_size = (bytes: number) =>
54
37
  bytes > 1024 * 1024
@@ -296,9 +279,15 @@
296
279
  }
297
280
  }
298
281
  }
299
-
300
282
  return sections
301
283
  })
284
+
285
+ let info_cards = $derived(
286
+ info_pane_data.map(({ title, items }) => ({ title, rows: items })),
287
+ )
288
+ let n_info_items = $derived(
289
+ info_pane_data.reduce((count, { items }) => count + items.length, 0),
290
+ )
302
291
  </script>
303
292
 
304
293
  <DraggablePane
@@ -315,73 +304,10 @@
315
304
  {...rest}
316
305
  >
317
306
  <h4 id="trajectory-info" style="margin-top: 0">Trajectory Info</h4>
318
- {#each info_pane_data as section, sec_idx (section.title)}
319
- {#if sec_idx > 0}<hr />{/if}
320
- <section>
321
- {#if section.title && section.title !== `File`}
322
- <h4>{section.title}</h4>
323
- {/if}
324
- {#each section.items as item (item.key ?? item.label)}
325
- {@const { key, label, value, tooltip } = item}
326
- <div
327
- class="clickable"
328
- aria-label="Click to copy: {label}: {value}"
329
- onclick={() => copy_item(label, value, key ?? label)}
330
- role="button"
331
- tabindex="0"
332
- onkeydown={(event) => {
333
- if ([`Enter`, ` `].includes(event.key)) {
334
- event.preventDefault()
335
- copy_item(label, value, key ?? label)
336
- }
337
- }}
338
- >
339
- <span>{@html sanitize_html(label)}</span>
340
- <span title={tooltip} {@attach create_tooltip()}>{@html sanitize_html(value)}</span>
341
- {#if copied_items.has(key ?? label)}
342
- <Icon
343
- icon="Check"
344
- style="color: var(--success-color, #10b981); width: 12px; height: 12px"
345
- class="copy-checkmark"
346
- />
347
- {/if}
348
- </div>
349
- {/each}
350
- </section>
351
- {/each}
307
+ <InfoPaneCards
308
+ cards={info_cards}
309
+ filter_placeholder="Filter trajectory info"
310
+ empty_label="trajectory info"
311
+ show_filter={n_info_items > 5}
312
+ />
352
313
  </DraggablePane>
353
-
354
- <style>
355
- section div {
356
- display: flex;
357
- justify-content: space-between;
358
- gap: 6pt;
359
- padding: 1pt;
360
- line-height: 1.5;
361
- }
362
- section div.clickable {
363
- cursor: pointer;
364
- position: relative;
365
- }
366
- section div:hover {
367
- background: var(--pane-btn-bg-hover, rgba(255, 255, 255, 0.03));
368
- }
369
- section :global(.copy-checkmark) {
370
- position: absolute;
371
- top: 50%;
372
- right: 3pt;
373
- transform: translateY(-50%);
374
- background: var(--pane-bg);
375
- border-radius: 50%;
376
- padding: 3pt;
377
- display: flex;
378
- align-items: center;
379
- justify-content: center;
380
- animation: fade-in 0.1s ease-out;
381
- }
382
- @keyframes fade-in {
383
- 0% {
384
- opacity: 0;
385
- }
386
- }
387
- </style>
@@ -1,7 +1,7 @@
1
1
  // Data extraction functions for trajectory analysis and plotting
2
2
  import { get_density } from '../structure';
3
3
  // Common data extractor that extracts energy and structural properties
4
- export const energy_data_extractor = (frame, _trajectory) => {
4
+ export const energy_data_extractor = (frame) => {
5
5
  const data = {
6
6
  Step: frame.step,
7
7
  };
@@ -23,7 +23,7 @@ export const energy_data_extractor = (frame, _trajectory) => {
23
23
  return data;
24
24
  };
25
25
  // Data extractor for forces and stresses
26
- export const force_stress_data_extractor = (frame, _trajectory) => {
26
+ export const force_stress_data_extractor = (frame) => {
27
27
  const data = {
28
28
  Step: frame.step,
29
29
  };
@@ -62,7 +62,7 @@ export const force_stress_data_extractor = (frame, _trajectory) => {
62
62
  return data;
63
63
  };
64
64
  // Data extractor for structural properties
65
- export const structural_data_extractor = (frame, _trajectory) => {
65
+ export const structural_data_extractor = (frame) => {
66
66
  const data = {
67
67
  Step: frame.step,
68
68
  };
@@ -155,7 +155,7 @@ export const full_data_extractor = (frame, trajectory) => {
155
155
  for (const param of lattice_params) {
156
156
  if (!property_varies(trajectory, param)) {
157
157
  // Mark individual lattice parameters as constant
158
- result[`_constant_${param}`] = 1;
158
+ result[`constant_${param}`] = 1;
159
159
  }
160
160
  }
161
161
  return result;
@@ -255,8 +255,8 @@ export class TrajFrameReader {
255
255
  const cell = frame_data.cell ? validate_3x3_matrix(frame_data.cell) : undefined;
256
256
  const metadata = {
257
257
  step: frame_number,
258
- ...(frame_data.calculator || {}),
259
- ...(frame_data.info || {}),
258
+ ...frame_data.calculator,
259
+ ...frame_data.info,
260
260
  };
261
261
  if (cell) {
262
262
  try {
@@ -8,7 +8,7 @@ export function parse_ase_trajectory(buffer, filename) {
8
8
  if (signature !== `- of Ulm`)
9
9
  throw new Error(`Invalid ASE trajectory`);
10
10
  offset += 24;
11
- const _version = Number(view.getBigInt64(offset, true));
11
+ // Skip ASE/Ulm version field; current parsing logic is version-independent.
12
12
  offset += 8;
13
13
  const n_items = Number(view.getBigInt64(offset, true));
14
14
  offset += 8;
@@ -46,11 +46,7 @@ export function parse_ase_trajectory(buffer, filename) {
46
46
  continue;
47
47
  }
48
48
  const elements = convert_atomic_numbers(numbers);
49
- const metadata = {
50
- step: idx,
51
- ...(frame_data.calculator || {}),
52
- ...(frame_data.info || {}),
53
- };
49
+ const metadata = { step: idx, ...frame_data.calculator, ...frame_data.info };
54
50
  frames.push(create_trajectory_frame(positions, elements, frame_data.cell ? validate_3x3_matrix(frame_data.cell) : undefined, frame_data.pbc || [true, true, true], idx, metadata));
55
51
  }
56
52
  catch (error) {
@@ -63,9 +63,7 @@ export async function parse_torch_sim_hdf5(buffer, filename) {
63
63
  }
64
64
  const positions_are_frames = positions_data.length > 0 &&
65
65
  positions_data.every((entry) => Array.isArray(entry) && entry.every((coord) => Array.isArray(coord)));
66
- const positions = positions_are_frames
67
- ? positions_data
68
- : [positions_data];
66
+ const positions = positions_are_frames ? positions_data : [positions_data];
69
67
  const atomic_numbers_are_frames = atomic_numbers_data.length > 0 &&
70
68
  atomic_numbers_data.every((entry) => Array.isArray(entry));
71
69
  const atomic_numbers = atomic_numbers_are_frames
@@ -29,7 +29,7 @@ function extract_property_statistics(trajectory, data_extractor) {
29
29
  trajectory.frames.forEach((frame) => {
30
30
  const data = data_extractor(frame, trajectory);
31
31
  Object.entries(data).forEach(([key, value]) => {
32
- if (typeof value !== `number` || key === `Step` || key.startsWith(`_constant_`)) {
32
+ if (typeof value !== `number` || key === `Step` || key.startsWith(`constant_`)) {
33
33
  return;
34
34
  }
35
35
  if (!property_stats.has(key)) {
package/dist/utils.js CHANGED
@@ -2,7 +2,7 @@
2
2
  const is_plain_object = (val) => typeof val === `object` && val !== null && !Array.isArray(val);
3
3
  // Merge nested objects (1 level deep).
4
4
  export function merge_nested(obj1, obj2) {
5
- const result = { ...obj1, ...(obj2 || {}) };
5
+ const result = { ...obj1, ...obj2 };
6
6
  for (const key in obj1) {
7
7
  if (is_plain_object(obj1[key]) && is_plain_object(obj2?.[key])) {
8
8
  result[key] = { ...obj1[key], ...obj2[key] };
@@ -44,7 +44,7 @@ function get_unique_families(hkls) {
44
44
  // Port of pymatgen's get_unique_families: group Miller indices by absolute-value permutations
45
45
  const key_map = new Map();
46
46
  for (const hkl of hkls) {
47
- const abs_sorted = [...hkl.map((val) => Math.abs(val))].sort((x, y) => x - y);
47
+ const abs_sorted = hkl.map((val) => Math.abs(val)).sort((x, y) => x - y);
48
48
  const key = abs_sorted.join(`,`);
49
49
  const list = key_map.get(key);
50
50
  if (list)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterviz",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Interactive visualizations for materials science: periodic tables, 3D structures, MD trajectories, heatmaps, scatter plots.",
5
5
  "keywords": [
6
6
  "chemistry",
@@ -19,8 +19,6 @@
19
19
  "dist"
20
20
  ],
21
21
  "type": "module",
22
- "types": "./dist/index.d.ts",
23
- "svelte": "./dist/index.js",
24
22
  "exports": {
25
23
  ".": {
26
24
  "types": "./dist/index.d.ts",
@@ -111,10 +109,6 @@
111
109
  "types": "./dist/structure/index.d.ts",
112
110
  "default": "./dist/structure/index.js"
113
111
  },
114
- "./structure/ferrox-wasm": {
115
- "types": "./dist/structure/ferrox-wasm.d.ts",
116
- "default": "./dist/structure/ferrox-wasm.js"
117
- },
118
112
  "./structure/parse": {
119
113
  "types": "./dist/structure/parse.d.ts",
120
114
  "default": "./dist/structure/parse.js"
@@ -161,27 +155,17 @@
161
155
  "access": "public"
162
156
  },
163
157
  "scripts": {
164
- "dev": "vp dev",
165
- "build": "vp build",
166
- "preview": "vp preview",
167
158
  "test": "vp test --run && playwright test",
168
- "check": "vp check",
169
- "lint": "vp lint",
170
- "fmt": "vp fmt --write",
171
- "package-dist-assets": "node scripts/package-dist-assets.mjs",
159
+ "package-dist-assets": "NODE_OPTIONS=--experimental-strip-types node scripts/package-dist-assets.ts",
172
160
  "package:dist": "svelte-package && npm run package-dist-assets",
173
- "package": "npm run package:dist",
174
161
  "prepare": "NODE_OPTIONS=--experimental-strip-types svelte-kit sync && npm run package:dist",
175
162
  "prepublishOnly": "npm run package:dist"
176
163
  },
177
164
  "dependencies": {
178
- "@spglib/moyo-wasm": "^0.7.9",
179
- "@sveltejs/kit": "2.58.0",
180
- "@threlte/core": "^8.5.10",
181
- "@threlte/extras": "^9.15.0",
182
- "@types/d3-hierarchy": "^3.1.7",
183
- "@types/js-yaml": "^4.0.9",
184
- "d3": "^7.9.0",
165
+ "@spglib/moyo-wasm": "^0.9.0",
166
+ "@sveltejs/kit": "2.60.1",
167
+ "@threlte/core": "^8.5.14",
168
+ "@threlte/extras": "^9.19.0",
185
169
  "d3-array": "^3.2.4",
186
170
  "d3-color": "^3.1.0",
187
171
  "d3-format": "^3.1.2",
@@ -190,51 +174,52 @@
190
174
  "d3-scale": "^4.0.2",
191
175
  "d3-scale-chromatic": "^3.1.0",
192
176
  "d3-shape": "^3.2.0",
193
- "dompurify": "^3.4.1",
194
- "fflate": "^0.8.2",
177
+ "d3-time-format": "^4.1.0",
178
+ "dompurify": "^3.4.5",
179
+ "fflate": "^0.8.3",
195
180
  "h5wasm": "^0.10.1",
196
181
  "js-yaml": "^4.1.1",
197
- "svelte-multiselect": "^11.7.0",
182
+ "svelte-multiselect": "^11.7.1",
198
183
  "three": "^0.184.0"
199
184
  },
200
185
  "devDependencies": {
201
- "@playwright/test": "^1.59.1",
186
+ "@playwright/test": "^1.60.0",
202
187
  "@rollup/plugin-yaml": "^4.1.2",
203
188
  "@sveltejs/adapter-static": "3.0.10",
204
189
  "@sveltejs/package": "^2.5.7",
205
- "@sveltejs/vite-plugin-svelte": "^7.0.0",
190
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
206
191
  "@types/d3-array": "^3.2.2",
207
192
  "@types/d3-color": "^3.1.3",
208
193
  "@types/d3-format": "^3.0.4",
194
+ "@types/d3-hierarchy": "^3.1.7",
209
195
  "@types/d3-interpolate-path": "^2.0.3",
210
196
  "@types/d3-scale": "^4.0.9",
211
197
  "@types/d3-scale-chromatic": "^3.1.0",
212
198
  "@types/d3-shape": "^3.1.8",
213
199
  "@types/d3-time-format": "^4.0.3",
214
- "@types/node": "^25.6.0",
215
- "@types/three": "^0.184.0",
216
- "@typescript/native-preview": "7.0.0-dev.20260429.1",
200
+ "@types/js-yaml": "^4.0.9",
201
+ "@types/node": "^25.9.0",
202
+ "@types/three": "^0.184.1",
203
+ "@typescript/native-preview": "7.0.0-dev.20260519.1",
217
204
  "@vitest/coverage-v8": "4.1.5",
218
205
  "@wooorm/starry-night": "^3.9.0",
219
- "d3-time-format": "^4.1.0",
220
206
  "happy-dom": "^20.9.0",
221
- "matterviz-wasm": "^0.0.10",
222
207
  "mdsvex": "^0.12.7",
223
208
  "rehype-katex": "^7.0.1",
224
209
  "remark-math": "3.0.1",
225
- "svelte": "5.55.5",
226
- "svelte-check-rs": "0.9.7",
210
+ "svelte": "5.55.8",
211
+ "svelte-check-rs": "0.9.13",
227
212
  "typescript": "6.0.3",
228
- "vite": "npm:@voidzero-dev/vite-plus-core@^0.1.20",
213
+ "vite": "npm:@voidzero-dev/vite-plus-core@^0.1.21",
229
214
  "vite-plus": "latest",
230
- "vitest": "npm:@voidzero-dev/vite-plus-test@^0.1.20"
215
+ "vitest": "npm:@voidzero-dev/vite-plus-test@^0.1.21"
231
216
  },
232
217
  "peerDependencies": {
233
218
  "svelte": "^5.0.0"
234
219
  },
235
220
  "overrides": {
236
- "vite": "npm:@voidzero-dev/vite-plus-core@^0.1.20",
237
- "vitest": "npm:@voidzero-dev/vite-plus-test@^0.1.20"
221
+ "vite": "npm:@voidzero-dev/vite-plus-core@^0.1.21",
222
+ "vitest": "npm:@voidzero-dev/vite-plus-test@^0.1.21"
238
223
  },
239
224
  "engines": {
240
225
  "node": ">=24"
@@ -1,46 +0,0 @@
1
- import type { Vec3 } from '../math';
2
- export type WasmResult<T> = {
3
- ok: T;
4
- } | {
5
- error: string;
6
- };
7
- export declare function is_ok<T>(result: WasmResult<T>): result is {
8
- ok: T;
9
- };
10
- export declare function is_error<T>(result: WasmResult<T>): result is {
11
- error: string;
12
- };
13
- export declare function unwrap<T>(result: WasmResult<T>): T;
14
- export declare function unwrap_or<T>(result: WasmResult<T>, default_value: T): T;
15
- export interface NeighborListResult {
16
- center_indices: number[];
17
- neighbor_indices: number[];
18
- image_offsets: Vec3[];
19
- distances: number[];
20
- }
21
- export interface MatcherOptions {
22
- latt_len_tol?: number;
23
- site_pos_tol?: number;
24
- angle_tol?: number;
25
- primitive_cell?: boolean;
26
- scale?: boolean;
27
- element_only?: boolean;
28
- }
29
- export type StructureFormat = `cif` | `poscar` | `json`;
30
- export type ReductionAlgorithm = `niggli` | `lll`;
31
- export interface HklInfo {
32
- hkl: Vec3;
33
- multiplicity: number;
34
- }
35
- export interface XrdPattern {
36
- two_theta: number[];
37
- intensities: number[];
38
- hkls: HklInfo[][];
39
- d_spacings: number[];
40
- }
41
- export interface XrdOptions {
42
- wavelength?: number;
43
- two_theta_range?: [number, number] | null;
44
- debye_waller_factors?: Record<string, number>;
45
- scaled?: boolean;
46
- }
@@ -1,18 +0,0 @@
1
- // Type guard to check if result is successful
2
- export function is_ok(result) {
3
- return `ok` in result;
4
- }
5
- // Type guard to check if result is an error
6
- export function is_error(result) {
7
- return `error` in result;
8
- }
9
- // Unwrap a successful result or throw an error
10
- export function unwrap(result) {
11
- if (is_ok(result))
12
- return result.ok;
13
- throw new Error(result.error);
14
- }
15
- // Unwrap with a default value on error
16
- export function unwrap_or(result, default_value) {
17
- return is_ok(result) ? result.ok : default_value;
18
- }
@@ -1,94 +0,0 @@
1
- import type { Vec3 } from '../math';
2
- import type { Crystal } from './';
3
- import type { MatcherOptions, NeighborListResult, ReductionAlgorithm, StructureFormat, WasmResult, XrdOptions, XrdPattern } from './ferrox-wasm-types';
4
- export * from './ferrox-wasm-types';
5
- interface WasmStructureMatcherClass {
6
- new (): WasmStructureMatcherInstance;
7
- }
8
- interface WasmStructureMatcherInstance {
9
- with_latt_len_tol(tol: number): WasmStructureMatcherInstance;
10
- with_site_pos_tol(tol: number): WasmStructureMatcherInstance;
11
- with_angle_tol(tol: number): WasmStructureMatcherInstance;
12
- with_primitive_cell(val: boolean): WasmStructureMatcherInstance;
13
- with_scale(val: boolean): WasmStructureMatcherInstance;
14
- with_element_comparator(val: boolean): WasmStructureMatcherInstance;
15
- fit(struct1: unknown, struct2: unknown): WasmResult<boolean>;
16
- fit_anonymous(struct1: unknown, struct2: unknown): WasmResult<boolean>;
17
- get_rms_dist(struct1: unknown, struct2: unknown): WasmResult<{
18
- rms: number;
19
- max_dist: number;
20
- } | null>;
21
- get_structure_distance(struct1: unknown, struct2: unknown): WasmResult<number>;
22
- deduplicate(structures: unknown[]): WasmResult<number[]>;
23
- find_matches(new_structures: unknown[], existing: unknown[]): WasmResult<(number | null)[]>;
24
- }
25
- interface FerroxWasmModule {
26
- WasmStructureMatcher: WasmStructureMatcherClass;
27
- parse_structure: (input: unknown) => WasmResult<Crystal>;
28
- parse_cif: (content: string) => WasmResult<Crystal>;
29
- parse_poscar: (content: string) => WasmResult<Crystal>;
30
- make_supercell_diag: (structure: unknown, nx: number, ny: number, nz: number) => WasmResult<Crystal>;
31
- make_supercell: (structure: unknown, matrix: number[][]) => WasmResult<Crystal>;
32
- get_reduced_structure: (structure: unknown, algo: string) => WasmResult<Crystal>;
33
- get_primitive: (structure: unknown, symprec: number) => WasmResult<Crystal>;
34
- get_spacegroup_number: (structure: unknown, symprec: number) => WasmResult<number>;
35
- structure_to_json: (structure: unknown) => WasmResult<string>;
36
- get_volume: (structure: unknown) => WasmResult<number>;
37
- get_total_mass: (structure: unknown) => WasmResult<number>;
38
- get_density: (structure: unknown) => WasmResult<number>;
39
- get_neighbor_list: (structure: unknown, r: number, numerical_tol: number, exclude_self: boolean) => WasmResult<NeighborListResult>;
40
- get_distance: (structure: unknown, i: number, j: number) => WasmResult<number>;
41
- get_distance_matrix: (structure: unknown) => WasmResult<number[][]>;
42
- get_sorted_structure: (structure: unknown, reverse: boolean) => WasmResult<Crystal>;
43
- get_sorted_by_electronegativity: (structure: unknown, reverse: boolean) => WasmResult<Crystal>;
44
- interpolate_structures: (start: unknown, end: unknown, n_images: number, interpolate_lattices: boolean, use_pbc: boolean) => WasmResult<Crystal[]>;
45
- copy_structure: (structure: unknown, sanitize: boolean) => WasmResult<Crystal>;
46
- wrap_to_unit_cell: (structure: unknown) => WasmResult<Crystal>;
47
- translate_sites: (structure: unknown, indices: number[], vector: number[], frac_coords: boolean) => WasmResult<Crystal>;
48
- perturb_structure: (structure: unknown, distance: number, min_distance?: number, seed?: number) => WasmResult<Crystal>;
49
- get_atomic_mass: (symbol: string) => WasmResult<number>;
50
- get_electronegativity: (symbol: string) => WasmResult<number>;
51
- compute_xrd: (structure: unknown, options?: XrdOptions) => WasmResult<XrdPattern>;
52
- get_atomic_scattering_params: () => string;
53
- }
54
- export declare function ensure_ferrox_wasm_ready(): Promise<FerroxWasmModule>;
55
- export declare function is_wasm_ready(): boolean;
56
- export declare function match_structures(struct1: Crystal, struct2: Crystal, options?: MatcherOptions): Promise<WasmResult<boolean>>;
57
- export declare function match_structures_anonymous(struct1: Crystal, struct2: Crystal, options?: MatcherOptions): Promise<WasmResult<boolean>>;
58
- export declare function get_structure_rms_dist(struct1: Crystal, struct2: Crystal, options?: MatcherOptions): Promise<WasmResult<{
59
- rms: number;
60
- max_dist: number;
61
- } | null>>;
62
- export declare function get_structure_distance(struct1: Crystal, struct2: Crystal, options?: MatcherOptions): Promise<WasmResult<number>>;
63
- export declare function find_matching_structure(query: Crystal, database: Crystal[], options?: MatcherOptions): Promise<WasmResult<number | null>>;
64
- export declare function deduplicate_structures(structures: Crystal[], options?: MatcherOptions): Promise<WasmResult<number[]>>;
65
- export declare function parse_structure_file(content: string, format: StructureFormat): Promise<WasmResult<Crystal>>;
66
- export declare function create_supercell(structure: Crystal, nx: number, ny: number, nz: number): Promise<WasmResult<Crystal>>;
67
- export declare function reduce_lattice(structure: Crystal, algo?: ReductionAlgorithm): Promise<WasmResult<Crystal>>;
68
- export declare function get_primitive_cell(structure: Crystal, symprec?: number): Promise<WasmResult<Crystal>>;
69
- export declare function get_spacegroup(structure: Crystal, symprec?: number): Promise<WasmResult<number>>;
70
- export declare function serialize_structure(structure: Crystal): Promise<WasmResult<string>>;
71
- export declare function get_volume(structure: Crystal): Promise<WasmResult<number>>;
72
- export declare function get_total_mass(structure: Crystal): Promise<WasmResult<number>>;
73
- export declare function get_density(structure: Crystal): Promise<WasmResult<number>>;
74
- export declare function get_neighbor_list(structure: Crystal, cutoff_radius: number, numerical_tol?: number, exclude_self?: boolean): Promise<WasmResult<NeighborListResult>>;
75
- export declare function get_distance(structure: Crystal, i: number, j: number): Promise<WasmResult<number>>;
76
- export declare function get_distance_matrix(structure: Crystal): Promise<WasmResult<number[][]>>;
77
- export declare function get_sorted_structure(structure: Crystal, reverse?: boolean): Promise<WasmResult<Crystal>>;
78
- export declare function get_sorted_by_electronegativity(structure: Crystal, reverse?: boolean): Promise<WasmResult<Crystal>>;
79
- export declare function interpolate_structures(start: Crystal, end: Crystal, n_images: number, options?: {
80
- interpolate_lattices?: boolean;
81
- use_pbc?: boolean;
82
- }): Promise<WasmResult<Crystal[]>>;
83
- export declare function copy_structure(structure: Crystal, sanitize?: boolean): Promise<WasmResult<Crystal>>;
84
- export declare function wrap_to_unit_cell(structure: Crystal): Promise<WasmResult<Crystal>>;
85
- export declare function create_supercell_matrix(structure: Crystal, matrix: [Vec3, Vec3, Vec3]): Promise<WasmResult<Crystal>>;
86
- export declare function translate_sites(structure: Crystal, indices: number[], vector: Vec3, frac_coords?: boolean): Promise<WasmResult<Crystal>>;
87
- export declare function perturb_structure(structure: Crystal, distance: number, options?: {
88
- min_distance?: number;
89
- seed?: number;
90
- }): Promise<WasmResult<Crystal>>;
91
- export declare function get_atomic_mass(symbol: string): Promise<WasmResult<number>>;
92
- export declare function get_electronegativity(symbol: string): Promise<WasmResult<number>>;
93
- export declare function compute_xrd_wasm(structure: Crystal, options?: XrdOptions): Promise<WasmResult<XrdPattern>>;
94
- export declare function get_atomic_scattering_params_wasm(): Promise<string>;