matterviz 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/dist/FilePicker.svelte +37 -20
  2. package/dist/Icon.svelte +2 -2
  3. package/dist/MillerIndexInput.svelte +60 -0
  4. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  5. package/dist/app.css +38 -2
  6. package/dist/brillouin/BrillouinZone.svelte +20 -62
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  8. package/dist/brillouin/BrillouinZoneExportPane.svelte +12 -20
  9. package/dist/brillouin/BrillouinZoneScene.svelte +2 -2
  10. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  11. package/dist/chempot-diagram/ChemPotDiagram.svelte +192 -0
  12. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  13. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +677 -0
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  15. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2688 -0
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  17. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -0
  18. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  19. package/dist/chempot-diagram/color.d.ts +10 -0
  20. package/dist/chempot-diagram/color.js +33 -0
  21. package/dist/chempot-diagram/compute.d.ts +38 -0
  22. package/dist/chempot-diagram/compute.js +650 -0
  23. package/dist/chempot-diagram/index.d.ts +5 -0
  24. package/dist/chempot-diagram/index.js +5 -0
  25. package/dist/chempot-diagram/pointer.d.ts +16 -0
  26. package/dist/chempot-diagram/pointer.js +40 -0
  27. package/dist/chempot-diagram/temperature.d.ts +15 -0
  28. package/dist/chempot-diagram/temperature.js +37 -0
  29. package/dist/chempot-diagram/types.d.ts +83 -0
  30. package/dist/chempot-diagram/types.js +27 -0
  31. package/dist/colors/index.d.ts +3 -1
  32. package/dist/colors/index.js +4 -0
  33. package/dist/composition/BarChart.svelte +13 -22
  34. package/dist/composition/BubbleChart.svelte +5 -3
  35. package/dist/composition/FormulaFilter.svelte +770 -90
  36. package/dist/composition/FormulaFilter.svelte.d.ts +37 -1
  37. package/dist/composition/PieChart.svelte +43 -18
  38. package/dist/composition/PieChart.svelte.d.ts +1 -1
  39. package/dist/constants.d.ts +1 -0
  40. package/dist/constants.js +2 -0
  41. package/dist/convex-hull/ConvexHull.svelte +14 -1
  42. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  43. package/dist/convex-hull/ConvexHull2D.svelte +14 -45
  44. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  45. package/dist/convex-hull/ConvexHull3D.svelte +396 -134
  46. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  47. package/dist/convex-hull/ConvexHull4D.svelte +93 -42
  48. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  49. package/dist/convex-hull/ConvexHullControls.svelte +94 -31
  50. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +4 -2
  51. package/dist/convex-hull/ConvexHullStats.svelte +697 -128
  52. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
  53. package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
  54. package/dist/convex-hull/GasPressureControls.svelte +72 -38
  55. package/dist/convex-hull/GasPressureControls.svelte.d.ts +2 -1
  56. package/dist/convex-hull/TemperatureSlider.svelte +46 -19
  57. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +2 -1
  58. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  59. package/dist/convex-hull/demo-temperature.js +36 -0
  60. package/dist/convex-hull/gas-thermodynamics.js +16 -5
  61. package/dist/convex-hull/helpers.d.ts +7 -1
  62. package/dist/convex-hull/helpers.js +45 -15
  63. package/dist/convex-hull/index.d.ts +15 -1
  64. package/dist/convex-hull/index.js +1 -0
  65. package/dist/convex-hull/thermodynamics.d.ts +8 -21
  66. package/dist/convex-hull/thermodynamics.js +106 -17
  67. package/dist/convex-hull/types.d.ts +7 -0
  68. package/dist/convex-hull/types.js +11 -0
  69. package/dist/coordination/CoordinationBarPlot.svelte +29 -46
  70. package/dist/element/BohrAtom.svelte +1 -1
  71. package/dist/element/data.js +2 -14
  72. package/dist/element/data.json.gz +0 -0
  73. package/dist/element/index.d.ts +1 -1
  74. package/dist/element/index.js +1 -0
  75. package/dist/element/types.d.ts +1 -0
  76. package/dist/fermi-surface/FermiSurface.svelte +21 -65
  77. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte +1 -1
  80. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  81. package/dist/fermi-surface/compute.js +1 -21
  82. package/dist/fermi-surface/marching-cubes.d.ts +2 -13
  83. package/dist/fermi-surface/marching-cubes.js +2 -519
  84. package/dist/fermi-surface/parse.js +17 -23
  85. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1273 -0
  86. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  87. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +171 -0
  88. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +31 -0
  89. package/dist/heatmap-matrix/index.d.ts +53 -0
  90. package/dist/heatmap-matrix/index.js +100 -0
  91. package/dist/heatmap-matrix/shared.d.ts +2 -0
  92. package/dist/heatmap-matrix/shared.js +4 -0
  93. package/dist/icons.d.ts +119 -0
  94. package/dist/icons.js +119 -0
  95. package/dist/index.d.ts +6 -1
  96. package/dist/index.js +6 -1
  97. package/dist/io/export.js +15 -3
  98. package/dist/io/file-drop.d.ts +7 -0
  99. package/dist/io/file-drop.js +43 -0
  100. package/dist/io/index.d.ts +2 -2
  101. package/dist/io/index.js +2 -112
  102. package/dist/io/types.d.ts +1 -0
  103. package/dist/io/url-drop.d.ts +2 -0
  104. package/dist/io/url-drop.js +118 -0
  105. package/dist/isosurface/Isosurface.svelte +231 -0
  106. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  107. package/dist/isosurface/IsosurfaceControls.svelte +273 -0
  108. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  109. package/dist/isosurface/index.d.ts +5 -0
  110. package/dist/isosurface/index.js +6 -0
  111. package/dist/isosurface/parse.d.ts +6 -0
  112. package/dist/isosurface/parse.js +548 -0
  113. package/dist/isosurface/slice.d.ts +11 -0
  114. package/dist/isosurface/slice.js +145 -0
  115. package/dist/isosurface/types.d.ts +55 -0
  116. package/dist/isosurface/types.js +178 -0
  117. package/dist/labels.d.ts +2 -1
  118. package/dist/labels.js +1 -0
  119. package/dist/layout/InfoTag.svelte +62 -62
  120. package/dist/layout/SubpageGrid.svelte +74 -0
  121. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +226 -53
  125. package/dist/layout/json-tree/JsonTree.svelte +425 -51
  126. package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
  127. package/dist/layout/json-tree/JsonValue.svelte +218 -97
  128. package/dist/layout/json-tree/types.d.ts +27 -2
  129. package/dist/layout/json-tree/utils.d.ts +14 -1
  130. package/dist/layout/json-tree/utils.js +254 -0
  131. package/dist/marching-cubes.d.ts +14 -0
  132. package/dist/marching-cubes.js +519 -0
  133. package/dist/math.d.ts +8 -0
  134. package/dist/math.js +374 -7
  135. package/dist/overlays/ContextMenu.svelte +3 -2
  136. package/dist/overlays/DraggablePane.svelte +163 -58
  137. package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
  138. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +232 -77
  139. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
  140. package/dist/phase-diagram/PhaseDiagramControls.svelte +32 -11
  141. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
  142. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +103 -0
  143. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  144. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +102 -95
  145. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +7 -0
  146. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +100 -26
  147. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
  148. package/dist/phase-diagram/index.d.ts +2 -0
  149. package/dist/phase-diagram/index.js +2 -0
  150. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  151. package/dist/phase-diagram/svg-to-diagram.js +865 -0
  152. package/dist/phase-diagram/types.d.ts +10 -0
  153. package/dist/phase-diagram/utils.d.ts +7 -4
  154. package/dist/phase-diagram/utils.js +149 -59
  155. package/dist/plot/AxisLabel.svelte +26 -0
  156. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  157. package/dist/plot/BarPlot.svelte +473 -228
  158. package/dist/plot/BarPlot.svelte.d.ts +3 -3
  159. package/dist/plot/BarPlotControls.svelte +3 -2
  160. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  161. package/dist/plot/ColorBar.svelte +54 -54
  162. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  163. package/dist/plot/ElementScatter.svelte +4 -3
  164. package/dist/plot/FillArea.svelte +4 -1
  165. package/dist/plot/Histogram.svelte +320 -230
  166. package/dist/plot/Histogram.svelte.d.ts +2 -2
  167. package/dist/plot/HistogramControls.svelte +29 -10
  168. package/dist/plot/HistogramControls.svelte.d.ts +6 -2
  169. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +2 -2
  170. package/dist/plot/PlotControls.svelte +109 -27
  171. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  172. package/dist/plot/PlotLegend.svelte +1 -1
  173. package/dist/plot/PortalSelect.svelte +2 -1
  174. package/dist/plot/ReferenceLine.svelte +2 -1
  175. package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
  176. package/dist/plot/ReferencePlane.svelte +1 -3
  177. package/dist/plot/ScatterPlot.svelte +343 -209
  178. package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
  179. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  180. package/dist/plot/ScatterPlot3DControls.svelte +203 -250
  181. package/dist/plot/ScatterPlot3DScene.svelte +4 -7
  182. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  183. package/dist/plot/ScatterPlotControls.svelte +95 -55
  184. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  185. package/dist/plot/ZeroLines.svelte +44 -0
  186. package/dist/plot/ZeroLines.svelte.d.ts +32 -0
  187. package/dist/plot/ZoomRect.svelte +21 -0
  188. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  189. package/dist/plot/axis-utils.d.ts +1 -1
  190. package/dist/plot/data-cleaning.js +1 -5
  191. package/dist/plot/index.d.ts +6 -2
  192. package/dist/plot/index.js +6 -2
  193. package/dist/plot/interactions.d.ts +8 -10
  194. package/dist/plot/interactions.js +10 -19
  195. package/dist/plot/layout.d.ts +7 -1
  196. package/dist/plot/layout.js +12 -4
  197. package/dist/plot/reference-line.d.ts +4 -21
  198. package/dist/plot/reference-line.js +7 -81
  199. package/dist/plot/types.d.ts +42 -17
  200. package/dist/plot/types.js +10 -0
  201. package/dist/plot/utils/label-placement.js +14 -11
  202. package/dist/plot/utils.d.ts +1 -0
  203. package/dist/plot/utils.js +14 -0
  204. package/dist/rdf/RdfPlot.svelte +55 -66
  205. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  206. package/dist/rdf/index.d.ts +1 -1
  207. package/dist/rdf/index.js +1 -1
  208. package/dist/settings.d.ts +5 -0
  209. package/dist/settings.js +37 -3
  210. package/dist/spectral/Bands.svelte +515 -143
  211. package/dist/spectral/Bands.svelte.d.ts +22 -2
  212. package/dist/spectral/helpers.d.ts +23 -1
  213. package/dist/spectral/helpers.js +65 -9
  214. package/dist/spectral/types.d.ts +2 -0
  215. package/dist/structure/AtomLegend.svelte +31 -10
  216. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  217. package/dist/structure/CellSelect.svelte +92 -22
  218. package/dist/structure/Lattice.svelte +2 -0
  219. package/dist/structure/Structure.svelte +716 -173
  220. package/dist/structure/Structure.svelte.d.ts +7 -2
  221. package/dist/structure/StructureControls.svelte +26 -14
  222. package/dist/structure/StructureControls.svelte.d.ts +5 -1
  223. package/dist/structure/StructureInfoPane.svelte +7 -1
  224. package/dist/structure/StructureScene.svelte +386 -95
  225. package/dist/structure/StructureScene.svelte.d.ts +15 -4
  226. package/dist/structure/atom-properties.d.ts +6 -2
  227. package/dist/structure/atom-properties.js +38 -25
  228. package/dist/structure/export.js +10 -7
  229. package/dist/structure/ferrox-wasm-types.d.ts +3 -2
  230. package/dist/structure/ferrox-wasm-types.js +0 -3
  231. package/dist/structure/ferrox-wasm.d.ts +3 -2
  232. package/dist/structure/ferrox-wasm.js +1 -2
  233. package/dist/structure/index.d.ts +7 -0
  234. package/dist/structure/index.js +22 -0
  235. package/dist/structure/parse.js +19 -16
  236. package/dist/structure/partial-occupancy.d.ts +25 -0
  237. package/dist/structure/partial-occupancy.js +102 -0
  238. package/dist/structure/validation.js +6 -3
  239. package/dist/symmetry/SymmetryStats.svelte +18 -4
  240. package/dist/symmetry/WyckoffTable.svelte +18 -10
  241. package/dist/symmetry/index.d.ts +7 -4
  242. package/dist/symmetry/index.js +83 -18
  243. package/dist/table/HeatmapTable.svelte +468 -69
  244. package/dist/table/HeatmapTable.svelte.d.ts +13 -1
  245. package/dist/table/ToggleMenu.svelte +291 -44
  246. package/dist/table/ToggleMenu.svelte.d.ts +4 -1
  247. package/dist/table/index.d.ts +3 -0
  248. package/dist/tooltip/index.d.ts +1 -1
  249. package/dist/tooltip/index.js +1 -0
  250. package/dist/trajectory/Trajectory.svelte +147 -145
  251. package/dist/trajectory/TrajectoryExportPane.svelte +13 -9
  252. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
  253. package/dist/trajectory/constants.d.ts +6 -0
  254. package/dist/trajectory/constants.js +7 -0
  255. package/dist/trajectory/extract.js +3 -5
  256. package/dist/trajectory/format-detect.d.ts +9 -0
  257. package/dist/trajectory/format-detect.js +76 -0
  258. package/dist/trajectory/frame-reader.d.ts +17 -0
  259. package/dist/trajectory/frame-reader.js +339 -0
  260. package/dist/trajectory/helpers.d.ts +15 -0
  261. package/dist/trajectory/helpers.js +187 -0
  262. package/dist/trajectory/index.d.ts +1 -0
  263. package/dist/trajectory/index.js +11 -4
  264. package/dist/trajectory/parse/ase.d.ts +2 -0
  265. package/dist/trajectory/parse/ase.js +76 -0
  266. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  267. package/dist/trajectory/parse/hdf5.js +121 -0
  268. package/dist/trajectory/parse/index.d.ts +12 -0
  269. package/dist/trajectory/parse/index.js +304 -0
  270. package/dist/trajectory/parse/lammps.d.ts +5 -0
  271. package/dist/trajectory/parse/lammps.js +169 -0
  272. package/dist/trajectory/parse/vasp.d.ts +2 -0
  273. package/dist/trajectory/parse/vasp.js +65 -0
  274. package/dist/trajectory/parse/xyz.d.ts +2 -0
  275. package/dist/trajectory/parse/xyz.js +109 -0
  276. package/dist/trajectory/types.d.ts +11 -0
  277. package/dist/trajectory/types.js +1 -0
  278. package/dist/utils.d.ts +2 -0
  279. package/dist/utils.js +4 -0
  280. package/dist/xrd/XrdPlot.svelte +6 -4
  281. package/dist/xrd/calc-xrd.js +0 -1
  282. package/package.json +33 -23
  283. package/readme.md +4 -4
  284. package/dist/trajectory/parse.d.ts +0 -42
  285. package/dist/trajectory/parse.js +0 -1267
  286. /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
package/dist/icons.js CHANGED
@@ -331,6 +331,14 @@ export const ICON_DATA = {
331
331
  viewBox: `0 0 15 15`,
332
332
  path: `M4.854 2.146a.5.5 0 0 1 0 .708L3.707 4H9a4.5 4.5 0 1 1 0 9H5a.5.5 0 0 1 0-1h4a3.5 3.5 0 1 0 0-7H3.707l1.147 1.146a.5.5 0 1 1-.708.708l-2-2a.5.5 0 0 1 0-.708l2-2a.5.5 0 0 1 .708 0`,
333
333
  },
334
+ Undo: {
335
+ viewBox: `0 0 24 24`,
336
+ path: `M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88c3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z`,
337
+ },
338
+ Redo: {
339
+ viewBox: `0 0 24 24`,
340
+ path: `M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5c1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z`,
341
+ },
334
342
  TwoColumns: {
335
343
  viewBox: `0 0 24 24`,
336
344
  path: `M3 5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2zm6 0H5v14h4zm4 0a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2zm6 0h-4v14h4z`,
@@ -479,4 +487,115 @@ export const ICON_DATA = {
479
487
  viewBox: `0 0 24 24`,
480
488
  path: `M4 18q-1.25 0-2.125-.875T1 15V9q0-1.25.875-2.125T4 6h13.5q1.25 0 2.125.875T20.5 9v6q0 1.25-.875 2.125T17.5 18zm0-2h13.5q.425 0 .713-.288T18.5 15V9q0-.425-.288-.712T17.5 8H4q-.425 0-.712.288T3 9v6q0 .425.288.713T4 16m17.5-1.5v-5h.5q.425 0 .713.288T23 10.5v3q0 .425-.288.713T22 14.5zM4 14v-4q0-.425.288-.712T5 9h10q.425 0 .713.288T16 10v4q0 .425-.288.713T15 15H5q-.425 0-.712-.288T4 14`,
481
489
  },
490
+ Filter: {
491
+ viewBox: `0 0 24 24`,
492
+ path: `M22 3H2l8 9.46V19l4 2v-8.54z`,
493
+ },
494
+ Eye: {
495
+ viewBox: `0 0 24 24`,
496
+ path: `M12 9a3 3 0 1 0 0 6a3 3 0 0 0 0-6m0 8a5 5 0 1 1 0-10a5 5 0 0 1 0 10m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5`,
497
+ },
498
+ EyeOff: {
499
+ viewBox: `0 0 24 24`,
500
+ path: `M11.83 9L15 12.16V12a3 3 0 0 0-3-3zm-4.3.8l1.55 1.55c-.05.21-.08.42-.08.65a3 3 0 0 0 3 3c.22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53a5 5 0 0 1-5-5c0-.79.2-1.53.53-2.2M2 4.27l2.28 2.28l.45.45C3.08 8.3 1.78 10 1 12c1.73 4.39 6 7.5 11 7.5c1.55 0 3.03-.3 4.38-.84l.43.42L19.73 22L21 20.73L3.27 3M12 7a5 5 0 0 1 5 5c0 .64-.13 1.26-.36 1.82l2.93 2.93c1.5-1.25 2.7-2.89 3.43-4.75c-1.73-4.39-6-7.5-11-7.5c-1.4 0-2.74.25-4 .7l2.17 2.15C10.74 7.13 11.35 7 12 7`,
501
+ },
502
+ Pin: {
503
+ viewBox: `0 0 24 24`,
504
+ path: `M16 12V4h1V2H7v2h1v8l-2 2v2h5.2v6h1.6v-6H18v-2z`,
505
+ },
506
+ Unpin: {
507
+ viewBox: `0 0 24 24`,
508
+ path: `M2 5.27L3.28 4L20 20.72L18.73 22l-5.93-5.93V22h-1.6v-6H6v-2l2-2v-.73zM16 12l2 2v2h-.18L8 6.18V4H7V2h10v2h-1z`,
509
+ },
510
+ ArrowLeft: {
511
+ viewBox: `0 0 24 24`,
512
+ path: `M20 11H7.83l5.59-5.59L12 4l-8 8l8 8l1.41-1.41L7.83 13H20z`,
513
+ },
514
+ ArrowRight: {
515
+ viewBox: `0 0 24 24`,
516
+ path: `M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z`,
517
+ },
518
+ ZoomIn: {
519
+ viewBox: `0 0 24 24`,
520
+ stroke: `currentColor`,
521
+ path: `<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></g>`,
522
+ },
523
+ ZoomOut: {
524
+ viewBox: `0 0 24 24`,
525
+ stroke: `currentColor`,
526
+ path: `<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="8" y1="11" x2="14" y2="11"/></g>`,
527
+ },
528
+ Play: {
529
+ viewBox: `0 0 24 24`,
530
+ path: `M8 5v14l11-7z`,
531
+ },
532
+ Pause: {
533
+ viewBox: `0 0 24 24`,
534
+ path: `M6 19h4V5H6zm8-14v14h4V5z`,
535
+ },
536
+ ExternalLink: {
537
+ viewBox: `0 0 24 24`,
538
+ stroke: `currentColor`,
539
+ path: `<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></g>`,
540
+ },
541
+ Sort: {
542
+ viewBox: `0 0 24 24`,
543
+ path: `M3 18h6v-2H3zM3 6v2h18V6zm0 7h12v-2H3z`,
544
+ },
545
+ SortAsc: {
546
+ viewBox: `0 0 24 24`,
547
+ path: `M3 18v-2h6v2zM3 13v-2h12v2zM3 8V6h13v2zM19 18V10h-2l3-5l3 5h-2v8z`,
548
+ },
549
+ SortDesc: {
550
+ viewBox: `0 0 24 24`,
551
+ path: `M3 18v-2h6v2zM3 13v-2h12v2zM3 8V6h13v2zM19 6v8h-2l3 5l3-5h-2V6z`,
552
+ },
553
+ BrillouinZone: {
554
+ viewBox: `0 0 24 24`,
555
+ stroke: `currentColor`,
556
+ path: `<g stroke-width="1.3" fill="none"><polygon points="12,1 22,7 22,17 12,23 2,17 2,7"/><line x1="2" y1="7" x2="22" y2="17"/><line x1="12" y1="1" x2="12" y2="23"/><line x1="22" y1="7" x2="2" y2="17"/></g>`,
557
+ },
558
+ BandStructure: {
559
+ viewBox: `0 0 28 24`,
560
+ stroke: `currentColor`,
561
+ path: `<g stroke-width="1.3" fill="none" stroke-linecap="round"><path d="M1 20c3-4 5-6 7-6s5 5 7 5 5-4 7-4"/><path d="M1 17c2-3 5-5 7-3s5 4 7 3 5-5 7-3"/><line x1="1" y1="12" x2="27" y2="12" stroke-dasharray="2 1.5" opacity="0.2"/><path d="M1 9c3 3 5 5 7 5s5-5 7-5 5 3 7 3"/><path d="M1 6c2 2 5 4 7 2s5-3 7-2 5 4 7 2"/><path d="M1 4c3 1 5 1 7 0s5-1 7 0 5 1 7 0" opacity="0.5"/><line x1="8" y1="1" x2="8" y2="23" stroke-dasharray="1.5 1.5" opacity="0.2"/><line x1="15" y1="1" x2="15" y2="23" stroke-dasharray="1.5 1.5" opacity="0.2"/><line x1="22" y1="1" x2="22" y2="23" stroke-dasharray="1.5 1.5" opacity="0.2"/></g>`,
562
+ },
563
+ DensityOfStates: {
564
+ viewBox: `0 0 24 24`,
565
+ stroke: `currentColor`,
566
+ path: `<line x1="3" y1="21" x2="21" y2="21" stroke-width="0.7" opacity="0.3"/><path d="M3 21C3 21 4 21 5 11C6 21 7 21 9 21C9 21 10 21 11 15C12 21 13 21 14 21C14 21 15 21 16.5 6C18 21 19 21 21 21" stroke-width="1.2" fill="none" stroke-linecap="round"/><path d="M3 21C3 21 4 21 5 11C6 21 7 21 9 21C9 21 10 21 11 15C12 21 13 21 14 21C14 21 15 21 16.5 6C18 21 19 21 21 21Z" fill="currentColor" stroke="none" opacity="0.12"/>`,
567
+ },
568
+ BandsDOS: {
569
+ viewBox: `0 0 24 24`,
570
+ path: `<path fill="currentColor" d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M4 4h10v16H4zm12 0h4v16h-4z"/>`,
571
+ },
572
+ ThreePanels: {
573
+ viewBox: `0 0 24 24`,
574
+ path: `<path fill="currentColor" d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M4 4h5v16H4zm7 0h9v8h-9zm0 10h9v6h-9z"/>`,
575
+ },
576
+ FermiSurface: {
577
+ viewBox: `0 0 24 24`,
578
+ stroke: `currentColor`,
579
+ path: `<g stroke-width="1.3" fill="none"><circle cx="12" cy="12" r="9" opacity="0.3"/><ellipse cx="12" cy="12" rx="9" ry="4"/><ellipse cx="12" cy="12" rx="4" ry="9"/><ellipse cx="12" cy="12" rx="6" ry="7" transform="rotate(45 12 12)" opacity="0.5"/></g>`,
580
+ },
581
+ ScatterPlot3D: {
582
+ viewBox: `0 0 24 24`,
583
+ path: `<g stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round"><line x1="3" y1="21" x2="3" y2="5"/><line x1="3" y1="21" x2="21" y2="21"/><line x1="3" y1="21" x2="9" y2="15"/></g><circle cx="11" cy="11" r="1.5" fill="currentColor"/><circle cx="16" cy="15" r="1.5" fill="currentColor"/><circle cx="8" cy="16" r="1.5" fill="currentColor"/><circle cx="15" cy="8" r="1.5" fill="currentColor"/>`,
584
+ },
585
+ SpacegroupBarPlot: {
586
+ viewBox: `0 0 24 24`,
587
+ path: `<rect x="2" y="13" width="3.5" height="8" fill="currentColor"/><rect x="7" y="7" width="3.5" height="14" fill="currentColor"/><rect x="12" y="10" width="3.5" height="11" fill="currentColor"/><rect x="17" y="5" width="3.5" height="16" fill="currentColor"/><path d="M21 2l1.5 2.5h-3z" fill="currentColor" opacity="0.5"/>`,
588
+ },
589
+ HeatmapMatrix: {
590
+ viewBox: `0 0 24 24`,
591
+ path: `<rect x="2" y="2" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.9"/><rect x="9.2" y="2" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.4"/><rect x="16.5" y="2" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.15"/><rect x="2" y="9.2" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.5"/><rect x="9.2" y="9.2" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.8"/><rect x="16.5" y="9.2" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.35"/><rect x="2" y="16.5" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.2"/><rect x="9.2" y="16.5" width="5.5" height="5.5" rx="0.8" fill="currentColor" opacity="0.65"/><rect x="16.5" y="16.5" width="5.5" height="5.5" rx="0.8" fill="currentColor"/>`,
592
+ },
593
+ HeatmapTable: {
594
+ viewBox: `0 0 24 24`,
595
+ path: `<rect x="2" y="2" width="20" height="4" rx="1" fill="currentColor" opacity="0.25"/><rect x="2" y="8" width="9" height="3.5" rx="0.5" fill="currentColor" opacity="0.6"/><rect x="13" y="8" width="9" height="3.5" rx="0.5" fill="currentColor" opacity="0.35"/><rect x="2" y="13.5" width="9" height="3.5" rx="0.5" fill="currentColor" opacity="0.85"/><rect x="13" y="13.5" width="9" height="3.5" rx="0.5" fill="currentColor" opacity="0.5"/><rect x="2" y="19" width="9" height="3.5" rx="0.5" fill="currentColor" opacity="0.3"/><rect x="13" y="19" width="9" height="3.5" rx="0.5" fill="currentColor" opacity="0.9"/>`,
596
+ },
597
+ ColorBar: {
598
+ viewBox: `0 0 24 24`,
599
+ path: `<rect x="6" y="2" width="5" height="20" rx="2.5" fill="currentColor" opacity="0.15"/><rect x="6" y="2" width="5" height="15" rx="2.5" fill="currentColor" opacity="0.4"/><rect x="6" y="2" width="5" height="10" rx="2.5" fill="currentColor" opacity="0.7"/><rect x="6" y="2" width="5" height="5" rx="2.5" fill="currentColor"/><g stroke="currentColor" stroke-width="1.2" opacity="0.5"><line x1="13" y1="4" x2="16" y2="4"/><line x1="13" y1="12" x2="16" y2="12"/><line x1="13" y1="20" x2="16" y2="20"/></g>`,
600
+ },
482
601
  };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './brillouin';
2
+ export * from './chempot-diagram';
2
3
  export * from './colors';
3
4
  export * from './composition';
4
5
  export * from './constants';
@@ -10,9 +11,13 @@ export { default as EmptyState } from './EmptyState.svelte';
10
11
  export * from './feedback';
11
12
  export * from './fermi-surface';
12
13
  export { default as FilePicker } from './FilePicker.svelte';
14
+ export * from './heatmap-matrix';
13
15
  export { default as Icon } from './Icon.svelte';
14
- export { ICON_DATA, type IconName } from './icons';
16
+ export * from './icons';
15
17
  export * from './io';
18
+ export { default as MillerIndexInput } from './MillerIndexInput.svelte';
19
+ export { auto_isosurface_settings, DEFAULT_ISOSURFACE_SETTINGS, generate_layers, grid_data_range, Isosurface as VolumetricIsosurface, IsosurfaceControls, LAYER_COLORS, parse_chgcar, parse_cube, parse_volumetric_file, sample_hkl_slice, trilinear_interpolate, } from './isosurface';
20
+ export type { DataRange, IsosurfaceLayer, IsosurfaceSettings, SliceResult, VolumetricData, VolumetricFileData, } from './isosurface';
16
21
  export * from './labels';
17
22
  export * from './layout';
18
23
  export * from './math';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './brillouin';
2
+ export * from './chempot-diagram';
2
3
  export * from './colors';
3
4
  export * from './composition';
4
5
  export * from './constants';
@@ -10,9 +11,13 @@ export { default as EmptyState } from './EmptyState.svelte';
10
11
  export * from './feedback';
11
12
  export * from './fermi-surface';
12
13
  export { default as FilePicker } from './FilePicker.svelte';
14
+ export * from './heatmap-matrix';
13
15
  export { default as Icon } from './Icon.svelte';
14
- export { ICON_DATA } from './icons';
16
+ export * from './icons';
15
17
  export * from './io';
18
+ export { default as MillerIndexInput } from './MillerIndexInput.svelte';
19
+ // Explicit exports to avoid name clash with fermi-surface's Isosurface type
20
+ export { auto_isosurface_settings, DEFAULT_ISOSURFACE_SETTINGS, generate_layers, grid_data_range, Isosurface as VolumetricIsosurface, IsosurfaceControls, LAYER_COLORS, parse_chgcar, parse_cube, parse_volumetric_file, sample_hkl_slice, trilinear_interpolate, } from './isosurface';
16
21
  export * from './labels';
17
22
  export * from './layout';
18
23
  export * from './math';
package/dist/io/export.js CHANGED
@@ -1,6 +1,16 @@
1
1
  import { download } from './fetch';
2
2
  import { create_structure_filename } from '../structure/export';
3
- import { Vector2 } from 'three';
3
+ import { Vector2, WebGLRenderer } from 'three';
4
+ function is_webgl_renderer_like(value) {
5
+ if (typeof value !== `object` || !value)
6
+ return false;
7
+ const renderer_obj = value;
8
+ return typeof renderer_obj.render === `function` &&
9
+ typeof renderer_obj.getPixelRatio === `function` &&
10
+ typeof renderer_obj.setPixelRatio === `function` &&
11
+ typeof renderer_obj.getSize === `function` &&
12
+ typeof renderer_obj.setSize === `function`;
13
+ }
4
14
  // Export structure as PNG image from canvas
5
15
  export function export_canvas_as_png(canvas, structure_or_filename, png_dpi = 150, scene = null, camera = null) {
6
16
  try {
@@ -25,7 +35,8 @@ export function export_canvas_as_png(canvas, structure_or_filename, png_dpi = 15
25
35
  // Convert DPI to multiplier (72 DPI is baseline web resolution)
26
36
  // Cap to a reasonable upper bound to avoid excessive memory use
27
37
  const resolution_multiplier = Math.min(png_dpi / 72, 10);
28
- const renderer = canvas.__renderer;
38
+ const renderer_val = canvas.__renderer;
39
+ const renderer = is_webgl_renderer_like(renderer_val) ? renderer_val : undefined;
29
40
  // Force render to populate buffer
30
41
  if (renderer && scene && camera)
31
42
  renderer.render(scene, camera);
@@ -208,7 +219,8 @@ export async function export_trajectory_video(canvas, filename, options = {}) {
208
219
  typeof MediaRecorder === `undefined` ||
209
220
  !MediaRecorder.isTypeSupported(`video/webm;codecs=vp9`))
210
221
  throw new Error(`WebM video recording not supported in this browser`);
211
- const renderer = canvas.__renderer;
222
+ const renderer_val = canvas.__renderer;
223
+ const renderer = is_webgl_renderer_like(renderer_val) ? renderer_val : undefined;
212
224
  // Store original renderer settings if changing resolution
213
225
  let orig_pixel_ratio;
214
226
  let orig_size;
@@ -0,0 +1,7 @@
1
+ export interface FileDropOptions {
2
+ allow: () => boolean;
3
+ on_drop: (content: string | ArrayBuffer, filename: string) => void | Promise<void>;
4
+ on_error?: (msg: string) => void;
5
+ set_loading?: (loading: boolean) => void;
6
+ }
7
+ export declare function create_file_drop_handler(opts: FileDropOptions): (event: DragEvent) => Promise<void>;
@@ -0,0 +1,43 @@
1
+ // Shared file-drop handler composable for drag-and-drop file loading.
2
+ import { decompress_file } from './decompress';
3
+ import { handle_url_drop } from './url-drop';
4
+ // Handles URL drops (from FilePicker), direct file drops with decompression,
5
+ // loading state, and error reporting.
6
+ export function create_file_drop_handler(opts) {
7
+ return async (event) => {
8
+ event.preventDefault();
9
+ if (!opts.allow())
10
+ return;
11
+ opts.set_loading?.(true);
12
+ let drop_filename = ``;
13
+ try {
14
+ let url_error;
15
+ const handled = await handle_url_drop(event, opts.on_drop).catch((exc) => {
16
+ url_error = exc instanceof Error ? exc.message : String(exc);
17
+ return false;
18
+ });
19
+ if (handled)
20
+ return;
21
+ const file = event.dataTransfer?.files[0];
22
+ if (!file) {
23
+ if (url_error)
24
+ opts.on_error?.(`Failed to load from URL: ${url_error}`);
25
+ return;
26
+ }
27
+ drop_filename = file.name;
28
+ const { content, filename } = await decompress_file(file);
29
+ if (content)
30
+ await opts.on_drop(content, filename);
31
+ }
32
+ catch (exc) {
33
+ const detail = exc instanceof Error ? exc.message : String(exc);
34
+ const msg = drop_filename
35
+ ? `Failed to load file ${drop_filename}: ${detail}`
36
+ : `Failed to load file: ${detail}`;
37
+ opts.on_error?.(msg);
38
+ }
39
+ finally {
40
+ opts.set_loading?.(false);
41
+ }
42
+ };
43
+ }
@@ -1,7 +1,7 @@
1
1
  export * from './decompress';
2
2
  export * from './export';
3
3
  export * from './fetch';
4
+ export * from './file-drop';
4
5
  export * from './is-binary';
5
6
  export * from './types';
6
- export declare function handle_url_drop(drag_event: DragEvent, callback: (content: string | ArrayBuffer, filename: string) => Promise<void> | void): Promise<boolean>;
7
- export declare function load_from_url(url: string, callback: (content: string | ArrayBuffer, filename: string) => Promise<void> | void): Promise<void>;
7
+ export * from './url-drop';
package/dist/io/index.js CHANGED
@@ -1,117 +1,7 @@
1
- import { load_binary_traj } from '../trajectory/parse';
2
1
  export * from './decompress';
3
2
  export * from './export';
4
3
  export * from './fetch';
4
+ export * from './file-drop';
5
5
  export * from './is-binary';
6
6
  export * from './types';
7
- // Handle URL-based file drop data by fetching content lazily
8
- export async function handle_url_drop(drag_event, callback) {
9
- const json_data = drag_event.dataTransfer?.getData(`application/json`);
10
- if (!json_data)
11
- return false;
12
- const file_info = JSON.parse(json_data);
13
- if (!file_info.url)
14
- return false;
15
- await load_from_url(file_info.url, callback);
16
- return true;
17
- }
18
- export async function load_from_url(url, callback) {
19
- const url_basename = url.split(`/`).pop() || url;
20
- const ext = url_basename.split(`.`).pop()?.toLowerCase() || ``;
21
- const extract_filename = (headers) => {
22
- const fallback = url_basename;
23
- if (!headers)
24
- return fallback;
25
- const content_disposition_str = headers.get(`content-disposition`);
26
- if (!content_disposition_str)
27
- return fallback;
28
- const star_match = /filename\*=(?:UTF-8''|)([^;]+)/i.exec(content_disposition_str);
29
- if (star_match?.[1]) {
30
- const raw = star_match[1].trim().replace(/^"|"$/g, ``);
31
- try {
32
- return decodeURIComponent(raw);
33
- }
34
- catch {
35
- return raw;
36
- }
37
- }
38
- const plain_match = /filename\s*=\s*"?([^";]+)"?/i.exec(content_disposition_str);
39
- return plain_match?.[1]?.trim() || fallback;
40
- };
41
- // Check for known binary file extensions
42
- const known_bin_extensions = `h5 hdf5 traj npz pkl dat gz gzip zip bz2 xz brml`.split(` `);
43
- if (known_bin_extensions.includes(ext)) {
44
- // Force binary mode for known binary files to handle GitHub Pages content-type issues
45
- const resp = await fetch(url);
46
- if (!resp.ok)
47
- throw new Error(`Fetch failed: ${resp.status}`);
48
- const filename = extract_filename(resp.headers);
49
- // Handle gzipped files with proper content-encoding detection
50
- if (ext === `gz` || ext === `gzip`) {
51
- if (resp.headers.get(`content-encoding`) === `gzip`) {
52
- // Browser automatically decompressed it, so it's text
53
- return callback(await resp.text(), filename);
54
- }
55
- else {
56
- // Need to decompress manually
57
- const { decompress_data } = await import(`./decompress`);
58
- const buffer = await resp.arrayBuffer();
59
- const content = await decompress_data(buffer, `gzip`);
60
- // Remove .gz extension when manually decompressing
61
- return callback(content, filename.replace(/\.gz$/, ``));
62
- }
63
- }
64
- // For H5 files, always load as binary regardless of signature
65
- // to handle files that have .h5/.hdf5 extensions but may not have the proper HDF5 signature
66
- if ([`h5`, `hdf5`].includes(ext)) {
67
- const result = await load_binary_traj(resp, `H5`, true);
68
- // Log warning if signature doesn't match (only for ArrayBuffer results)
69
- if (result instanceof ArrayBuffer && result.byteLength >= 8) {
70
- const view = new Uint8Array(result.slice(0, 8));
71
- const hdf5_signature = [0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a];
72
- if (!hdf5_signature.every((byte, idx) => view[idx] === byte)) {
73
- console.warn(`File has .h5/.hdf5 extension but missing HDF5 signature`);
74
- }
75
- }
76
- return callback(result, extract_filename(resp.headers));
77
- }
78
- // For .traj files, ensure we always get ArrayBuffer for proper ASE parsing
79
- if (ext === `traj`) {
80
- const buffer = await load_binary_traj(resp, `.traj`);
81
- return callback(buffer, extract_filename(resp.headers));
82
- }
83
- if (resp.headers.get(`content-encoding`) === `gzip`) {
84
- return callback(await resp.text(), extract_filename(resp.headers));
85
- }
86
- return callback(await resp.arrayBuffer(), extract_filename(resp.headers));
87
- }
88
- // Skip Range requests for known text formats to avoid production server issues
89
- const known_text_extensions = `xyz extxyz json cif poscar yaml yml txt md py js ts css html xml`.split(` `);
90
- // Include VASP files that don't have extensions (POSCAR, XDATCAR, CONTCAR)
91
- const is_known_text = known_text_extensions.includes(ext) ||
92
- url_basename.toLowerCase().match(/^(poscar|xdatcar|contcar)$/i);
93
- if (!is_known_text) {
94
- try { // Check for magic bytes only for unknown formats
95
- const head = await fetch(url, { headers: { Range: `bytes=0-15` } });
96
- if (head.ok) {
97
- const buf = new Uint8Array(await head.arrayBuffer());
98
- const is_gzip = buf[0] === 0x1f && buf[1] === 0x8b;
99
- const is_hdf5 = buf[0] === 0x89 && buf[1] === 0x48 && buf[2] === 0x44 &&
100
- buf[3] === 0x46;
101
- if (is_gzip || is_hdf5) {
102
- const resp = await fetch(url);
103
- if (!resp.ok)
104
- throw new Error(`Fetch failed: ${resp.status}`);
105
- return callback(await resp.arrayBuffer(), extract_filename(resp.headers));
106
- }
107
- }
108
- }
109
- catch {
110
- // Fall through to text fetch if HEAD request fails
111
- }
112
- }
113
- const resp = await fetch(url);
114
- if (!resp.ok)
115
- throw new Error(`Fetch failed: ${resp.status}`);
116
- return callback(await resp.text(), extract_filename(resp.headers));
117
- }
7
+ export * from './url-drop';
@@ -1,6 +1,7 @@
1
1
  export interface FileInfo {
2
2
  name: string;
3
3
  url: string;
4
+ label?: string;
4
5
  type?: string;
5
6
  category?: string;
6
7
  category_icon?: string;
@@ -0,0 +1,2 @@
1
+ export declare function handle_url_drop(drag_event: DragEvent, callback: (content: string | ArrayBuffer, filename: string) => Promise<void> | void): Promise<boolean>;
2
+ export declare function load_from_url(url: string, callback: (content: string | ArrayBuffer, filename: string) => Promise<void> | void): Promise<void>;
@@ -0,0 +1,118 @@
1
+ import { load_binary_traj } from '../trajectory/parse';
2
+ const BINARY_EXTENSIONS = new Set(`h5 hdf5 traj npz pkl dat gz gzip zip bz2 xz brml`.split(` `));
3
+ const TEXT_EXTENSIONS = new Set(`xyz extxyz json cif poscar yaml yml txt md py js ts css html xml`.split(` `));
4
+ const VASP_BASENAME_RE = /^(poscar|xdatcar|contcar)$/i;
5
+ // Extract filename from Content-Disposition header, falling back to url_basename.
6
+ function extract_filename(headers, fallback) {
7
+ if (!headers)
8
+ return fallback;
9
+ const content_disposition_str = headers.get(`content-disposition`);
10
+ if (!content_disposition_str)
11
+ return fallback;
12
+ const star_match = /filename\*=(?:UTF-8''|)([^;]+)/i.exec(content_disposition_str);
13
+ if (star_match?.[1]) {
14
+ const raw = star_match[1].trim().replace(/^"|"$/g, ``);
15
+ try {
16
+ return decodeURIComponent(raw);
17
+ }
18
+ catch {
19
+ return raw;
20
+ }
21
+ }
22
+ const plain_match = /filename\s*=\s*"?([^";]+)"?/i.exec(content_disposition_str);
23
+ return plain_match?.[1]?.trim() || fallback;
24
+ }
25
+ // Handle URL-based file drop data by fetching content lazily
26
+ export async function handle_url_drop(drag_event, callback) {
27
+ const json_data = drag_event.dataTransfer?.getData(`application/json`);
28
+ if (!json_data)
29
+ return false;
30
+ let file_info;
31
+ try {
32
+ file_info = JSON.parse(json_data);
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ if (!file_info.url)
38
+ return false;
39
+ await load_from_url(file_info.url, callback);
40
+ return true;
41
+ }
42
+ export async function load_from_url(url, callback) {
43
+ const url_basename = url.split(`/`).pop() || url;
44
+ const ext = url_basename.split(`.`).pop()?.toLowerCase() || ``;
45
+ if (BINARY_EXTENSIONS.has(ext)) {
46
+ // Force binary mode for known binary files to handle GitHub Pages content-type issues
47
+ const resp = await fetch(url);
48
+ if (!resp.ok)
49
+ throw new Error(`Fetch failed: ${resp.status}`);
50
+ const filename = extract_filename(resp.headers, url_basename);
51
+ // Handle gzipped files with proper content-encoding detection
52
+ if (ext === `gz` || ext === `gzip`) {
53
+ if (resp.headers.get(`content-encoding`) === `gzip`) {
54
+ // Browser automatically decompressed it, so it's text
55
+ return callback(await resp.text(), filename);
56
+ }
57
+ else {
58
+ // Need to decompress manually
59
+ const { decompress_data } = await import(`./decompress`);
60
+ const buffer = await resp.arrayBuffer();
61
+ const content = await decompress_data(buffer, `gzip`);
62
+ // Remove .gz extension when manually decompressing
63
+ return callback(content, filename.replace(/\.gz$/, ``));
64
+ }
65
+ }
66
+ // For H5 files, always load as binary regardless of signature
67
+ // to handle files that have .h5/.hdf5 extensions but may not have the proper HDF5 signature
68
+ if (ext === `h5` || ext === `hdf5`) {
69
+ const result = await load_binary_traj(resp, `H5`, true);
70
+ // Log warning if signature doesn't match (only for ArrayBuffer results)
71
+ if (result instanceof ArrayBuffer && result.byteLength >= 8) {
72
+ const view = new Uint8Array(result.slice(0, 8));
73
+ const hdf5_signature = [0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a];
74
+ if (!hdf5_signature.every((byte, idx) => view[idx] === byte)) {
75
+ console.warn(`File has .h5/.hdf5 extension but missing HDF5 signature`);
76
+ }
77
+ }
78
+ return callback(result, filename);
79
+ }
80
+ // For .traj files, ensure we always get ArrayBuffer for proper ASE parsing
81
+ if (ext === `traj`) {
82
+ const buffer = await load_binary_traj(resp, `.traj`);
83
+ return callback(buffer, filename);
84
+ }
85
+ if (resp.headers.get(`content-encoding`) === `gzip`) {
86
+ return callback(await resp.text(), filename);
87
+ }
88
+ return callback(await resp.arrayBuffer(), filename);
89
+ }
90
+ // Skip Range requests for known text formats to avoid production server issues
91
+ // Include VASP files that don't have extensions (POSCAR, XDATCAR, CONTCAR)
92
+ const is_known_text = TEXT_EXTENSIONS.has(ext) || VASP_BASENAME_RE.test(url_basename);
93
+ if (!is_known_text) {
94
+ try {
95
+ // Check for magic bytes only for unknown formats
96
+ const head = await fetch(url, { headers: { Range: `bytes=0-15` } });
97
+ if (head.ok) {
98
+ const buf = new Uint8Array(await head.arrayBuffer());
99
+ const is_gzip = buf[0] === 0x1f && buf[1] === 0x8b;
100
+ const is_hdf5 = buf[0] === 0x89 && buf[1] === 0x48 && buf[2] === 0x44 &&
101
+ buf[3] === 0x46;
102
+ if (is_gzip || is_hdf5) {
103
+ const resp = await fetch(url);
104
+ if (!resp.ok)
105
+ throw new Error(`Fetch failed: ${resp.status}`);
106
+ return callback(await resp.arrayBuffer(), extract_filename(resp.headers, url_basename));
107
+ }
108
+ }
109
+ }
110
+ catch {
111
+ // Fall through to text fetch if HEAD request fails
112
+ }
113
+ }
114
+ const resp = await fetch(url);
115
+ if (!resp.ok)
116
+ throw new Error(`Fetch failed: ${resp.status}`);
117
+ return callback(await resp.text(), extract_filename(resp.headers, url_basename));
118
+ }