matterviz 0.3.4 → 0.3.6

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 (852) hide show
  1. package/.vscode/launch.json +13 -0
  2. package/.vscodeignore +7 -0
  3. package/dist/assets/STLExporter-BpTH3YHE.js +8 -0
  4. package/dist/assets/browser-DdDecX_W.js +1 -0
  5. package/dist/assets/export-qgn-H9y6.js +2 -0
  6. package/dist/assets/main-DiKYzti2.css +1 -0
  7. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  8. package/dist/extension.js +31293 -0
  9. package/dist/src/lib/FilePicker.svelte +360 -0
  10. package/dist/src/lib/MillerIndexInput.svelte +66 -0
  11. package/dist/src/lib/api/mp.ts +26 -0
  12. package/dist/src/lib/api/optimade.ts +204 -0
  13. package/dist/src/lib/app.css +247 -0
  14. package/dist/src/lib/brillouin/BrillouinZone.svelte +549 -0
  15. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +144 -0
  16. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +146 -0
  17. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  18. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +476 -0
  19. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +92 -0
  20. package/dist/src/lib/brillouin/compute.ts +529 -0
  21. package/dist/src/lib/brillouin/index.ts +8 -0
  22. package/dist/src/lib/brillouin/types.ts +51 -0
  23. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +327 -0
  24. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  25. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  26. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +94 -0
  27. package/dist/src/lib/chempot-diagram/chempot-worker.ts +11 -0
  28. package/dist/src/lib/chempot-diagram/color.ts +42 -0
  29. package/dist/src/lib/chempot-diagram/compute.ts +1014 -0
  30. package/dist/src/lib/chempot-diagram/index.ts +6 -0
  31. package/dist/src/lib/chempot-diagram/pointer.ts +56 -0
  32. package/dist/src/lib/chempot-diagram/temperature.ts +77 -0
  33. package/dist/src/lib/chempot-diagram/types.ts +130 -0
  34. package/dist/src/lib/colors/index.ts +249 -0
  35. package/dist/src/lib/composition/BarChart.svelte +297 -0
  36. package/dist/src/lib/composition/BubbleChart.svelte +218 -0
  37. package/dist/src/lib/composition/Composition.svelte +165 -0
  38. package/dist/src/lib/composition/Formula.svelte +268 -0
  39. package/dist/src/lib/composition/FormulaFilter.svelte +1257 -0
  40. package/dist/src/lib/composition/PieChart.svelte +323 -0
  41. package/dist/src/lib/composition/format.ts +155 -0
  42. package/dist/src/lib/composition/index.ts +37 -0
  43. package/dist/src/lib/composition/parse.ts +605 -0
  44. package/dist/src/lib/constants.ts +134 -0
  45. package/dist/src/lib/controls.ts +42 -0
  46. package/dist/src/lib/convex-hull/ConvexHull.svelte +157 -0
  47. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +825 -0
  48. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +1801 -0
  49. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +1398 -0
  50. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +535 -0
  51. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +125 -0
  52. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +929 -0
  53. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +131 -0
  54. package/dist/src/lib/convex-hull/GasPressureControls.svelte +247 -0
  55. package/dist/src/lib/convex-hull/StructurePopup.svelte +151 -0
  56. package/dist/src/lib/convex-hull/TemperatureSlider.svelte +140 -0
  57. package/dist/src/lib/convex-hull/barycentric-coords.ts +246 -0
  58. package/dist/src/lib/convex-hull/demo-temperature.ts +63 -0
  59. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +405 -0
  60. package/dist/src/lib/convex-hull/helpers.ts +932 -0
  61. package/dist/src/lib/convex-hull/index.ts +202 -0
  62. package/dist/src/lib/convex-hull/thermodynamics.ts +2192 -0
  63. package/dist/src/lib/convex-hull/types.ts +267 -0
  64. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +311 -0
  65. package/dist/src/lib/coordination/calc-coordination.ts +93 -0
  66. package/dist/src/lib/coordination/index.ts +9 -0
  67. package/dist/src/lib/effects.svelte.ts +48 -0
  68. package/dist/src/lib/element/BohrAtom.svelte +147 -0
  69. package/dist/src/lib/element/ElementHeading.svelte +26 -0
  70. package/dist/src/lib/element/ElementPhoto.svelte +57 -0
  71. package/dist/src/lib/element/ElementStats.svelte +80 -0
  72. package/dist/src/lib/element/ElementTile.svelte +484 -0
  73. package/dist/src/lib/element/data.json.gz.d.ts +4 -0
  74. package/dist/src/lib/element/data.ts +14 -0
  75. package/dist/src/lib/element/index.ts +8 -0
  76. package/dist/src/lib/element/types.ts +62 -0
  77. package/dist/src/lib/feedback/ClickFeedback.svelte +58 -0
  78. package/dist/src/lib/feedback/DragOverlay.svelte +42 -0
  79. package/dist/src/lib/feedback/index.ts +4 -0
  80. package/dist/src/lib/fermi-surface/FermiSlice.svelte +189 -0
  81. package/dist/src/lib/fermi-surface/FermiSurface.svelte +600 -0
  82. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +448 -0
  83. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +794 -0
  84. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  85. package/dist/src/lib/fermi-surface/compute.ts +728 -0
  86. package/dist/src/lib/fermi-surface/constants.ts +32 -0
  87. package/dist/src/lib/fermi-surface/export.ts +64 -0
  88. package/dist/src/lib/fermi-surface/index.ts +14 -0
  89. package/dist/src/lib/fermi-surface/marching-cubes.ts +3 -0
  90. package/dist/src/lib/fermi-surface/parse.ts +574 -0
  91. package/dist/src/lib/fermi-surface/symmetry.ts +56 -0
  92. package/dist/src/lib/fermi-surface/types.ts +159 -0
  93. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  94. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  95. package/dist/src/lib/heatmap-matrix/index.ts +167 -0
  96. package/dist/src/lib/heatmap-matrix/shared.ts +7 -0
  97. package/dist/src/lib/icons.ts +650 -0
  98. package/dist/src/lib/index.ts +61 -0
  99. package/dist/src/lib/io/decompress.ts +92 -0
  100. package/dist/src/lib/io/export.ts +385 -0
  101. package/dist/src/lib/io/fetch.ts +46 -0
  102. package/dist/src/lib/io/file-drop.ts +51 -0
  103. package/dist/src/lib/io/index.ts +7 -0
  104. package/dist/src/lib/io/is-binary.ts +24 -0
  105. package/dist/src/lib/io/types.ts +8 -0
  106. package/dist/src/lib/io/url-drop.ts +141 -0
  107. package/dist/src/lib/isosurface/Isosurface.svelte +285 -0
  108. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +277 -0
  109. package/dist/src/lib/isosurface/index.ts +7 -0
  110. package/dist/src/lib/isosurface/parse.ts +656 -0
  111. package/dist/src/lib/isosurface/slice.ts +175 -0
  112. package/dist/src/lib/isosurface/types.ts +309 -0
  113. package/dist/src/lib/labels.ts +320 -0
  114. package/dist/src/lib/layout/FullscreenToggle.svelte +50 -0
  115. package/dist/src/lib/layout/InfoCard.svelte +120 -0
  116. package/dist/src/lib/layout/InfoTag.svelte +185 -0
  117. package/dist/src/lib/layout/PropertyFilter.svelte +246 -0
  118. package/dist/src/lib/layout/SettingsSection.svelte +148 -0
  119. package/dist/src/lib/layout/SubpageGrid.svelte +82 -0
  120. package/dist/src/lib/layout/fullscreen.ts +65 -0
  121. package/dist/src/lib/layout/index.ts +11 -0
  122. package/dist/src/lib/layout/json-tree/JsonNode.svelte +548 -0
  123. package/dist/src/lib/layout/json-tree/JsonTree.svelte +1230 -0
  124. package/dist/src/lib/layout/json-tree/JsonValue.svelte +334 -0
  125. package/dist/src/lib/layout/json-tree/index.ts +3 -0
  126. package/dist/src/lib/layout/json-tree/types.ts +126 -0
  127. package/dist/src/lib/layout/json-tree/utils.ts +682 -0
  128. package/dist/src/lib/marching-cubes.ts +614 -0
  129. package/dist/src/lib/math.ts +1081 -0
  130. package/dist/src/lib/overlays/ContextMenu.svelte +162 -0
  131. package/dist/src/lib/overlays/CopyButton.svelte +45 -0
  132. package/dist/src/lib/overlays/DragControlTab.svelte +98 -0
  133. package/dist/src/lib/overlays/DraggablePane.svelte +487 -0
  134. package/dist/src/lib/overlays/InfoPaneCards.svelte +149 -0
  135. package/dist/src/lib/overlays/index.ts +3 -0
  136. package/dist/src/lib/periodic-table/PeriodicTable.svelte +469 -0
  137. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +557 -0
  138. package/dist/src/lib/periodic-table/PropertySelect.svelte +37 -0
  139. package/dist/src/lib/periodic-table/index.ts +12 -0
  140. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  141. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +444 -0
  142. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  143. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  144. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  145. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +203 -0
  146. package/dist/src/lib/phase-diagram/build-diagram.ts +186 -0
  147. package/dist/src/lib/phase-diagram/colors.ts +58 -0
  148. package/dist/src/lib/phase-diagram/diagram-input.ts +40 -0
  149. package/dist/src/lib/phase-diagram/index.ts +13 -0
  150. package/dist/src/lib/phase-diagram/parse.ts +348 -0
  151. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +1023 -0
  152. package/dist/src/lib/phase-diagram/types.ts +144 -0
  153. package/dist/src/lib/phase-diagram/utils.ts +775 -0
  154. package/dist/src/lib/plot/AxisLabel.svelte +51 -0
  155. package/dist/src/lib/plot/BarPlot.svelte +2113 -0
  156. package/dist/src/lib/plot/BarPlotControls.svelte +66 -0
  157. package/dist/src/lib/plot/BinnedScatterPlot.svelte +1114 -0
  158. package/dist/src/lib/plot/ColorBar.svelte +721 -0
  159. package/dist/src/lib/plot/ColorScaleSelect.svelte +54 -0
  160. package/dist/src/lib/plot/ElementScatter.svelte +63 -0
  161. package/dist/src/lib/plot/FillArea.svelte +223 -0
  162. package/dist/src/lib/plot/Histogram.svelte +1558 -0
  163. package/dist/src/lib/plot/HistogramControls.svelte +212 -0
  164. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +96 -0
  165. package/dist/src/lib/plot/Line.svelte +84 -0
  166. package/dist/src/lib/plot/PlotAxis.svelte +169 -0
  167. package/dist/src/lib/plot/PlotControls.svelte +537 -0
  168. package/dist/src/lib/plot/PlotLegend.svelte +569 -0
  169. package/dist/src/lib/plot/PlotTooltip.svelte +67 -0
  170. package/dist/src/lib/plot/PortalSelect.svelte +253 -0
  171. package/dist/src/lib/plot/ReferenceLine3D.svelte +156 -0
  172. package/dist/src/lib/plot/ReferencePlane.svelte +175 -0
  173. package/dist/src/lib/plot/ScatterPlot.svelte +2778 -0
  174. package/dist/src/lib/plot/ScatterPlot3D.svelte +529 -0
  175. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +437 -0
  176. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +912 -0
  177. package/dist/src/lib/plot/ScatterPlotControls.svelte +306 -0
  178. package/dist/src/lib/plot/ScatterPoint.svelte +182 -0
  179. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +293 -0
  180. package/dist/src/lib/plot/Surface3D.svelte +197 -0
  181. package/dist/src/lib/plot/ZeroLines.svelte +97 -0
  182. package/dist/src/lib/plot/ZoomRect.svelte +23 -0
  183. package/dist/src/lib/plot/adaptive-density.ts +316 -0
  184. package/dist/src/lib/plot/auto-place.ts +184 -0
  185. package/dist/src/lib/plot/axis-utils.ts +122 -0
  186. package/dist/src/lib/plot/binned-scatter-types.ts +83 -0
  187. package/dist/src/lib/plot/data-cleaning.ts +1069 -0
  188. package/dist/src/lib/plot/data-transform.ts +69 -0
  189. package/dist/src/lib/plot/defaults.ts +9 -0
  190. package/dist/src/lib/plot/fill-utils.ts +494 -0
  191. package/dist/src/lib/plot/hover-lock.svelte.ts +60 -0
  192. package/dist/src/lib/plot/index.ts +53 -0
  193. package/dist/src/lib/plot/interactions.ts +119 -0
  194. package/dist/src/lib/plot/layout.ts +425 -0
  195. package/dist/src/lib/plot/reference-line.ts +426 -0
  196. package/dist/src/lib/plot/scales.ts +654 -0
  197. package/dist/src/lib/plot/svg.ts +23 -0
  198. package/dist/src/lib/plot/types.ts +1144 -0
  199. package/dist/src/lib/plot/utils/label-placement.ts +541 -0
  200. package/dist/src/lib/plot/utils/series-visibility.ts +140 -0
  201. package/dist/src/lib/plot/utils.ts +11 -0
  202. package/dist/src/lib/rdf/RdfPlot.svelte +247 -0
  203. package/dist/src/lib/rdf/calc-rdf.ts +167 -0
  204. package/dist/src/lib/rdf/index.ts +27 -0
  205. package/dist/src/lib/sanitize.ts +126 -0
  206. package/dist/src/lib/settings.ts +1479 -0
  207. package/dist/src/lib/spectral/Bands.svelte +1040 -0
  208. package/dist/src/lib/spectral/BandsAndDos.svelte +134 -0
  209. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +252 -0
  210. package/dist/src/lib/spectral/Dos.svelte +697 -0
  211. package/dist/src/lib/spectral/helpers.ts +1381 -0
  212. package/dist/src/lib/spectral/index.ts +8 -0
  213. package/dist/src/lib/spectral/types.ts +112 -0
  214. package/dist/src/lib/state.svelte.ts +64 -0
  215. package/dist/src/lib/structure/Arrow.svelte +72 -0
  216. package/dist/src/lib/structure/AtomLegend.svelte +815 -0
  217. package/dist/src/lib/structure/Bond.svelte +140 -0
  218. package/dist/src/lib/structure/CanvasTooltip.svelte +33 -0
  219. package/dist/src/lib/structure/CellSelect.svelte +349 -0
  220. package/dist/src/lib/structure/Cylinder.svelte +45 -0
  221. package/dist/src/lib/structure/Lattice.svelte +196 -0
  222. package/dist/src/lib/structure/Structure.svelte +2248 -0
  223. package/dist/src/lib/structure/StructureControls.svelte +1273 -0
  224. package/dist/src/lib/structure/StructureExportPane.svelte +252 -0
  225. package/dist/src/lib/structure/StructureInfoPane.svelte +737 -0
  226. package/dist/src/lib/structure/StructureScene.svelte +2255 -0
  227. package/dist/src/lib/structure/atom-properties.ts +316 -0
  228. package/dist/src/lib/structure/bond-order-perception.ts +447 -0
  229. package/dist/src/lib/structure/bonding.ts +944 -0
  230. package/dist/src/lib/structure/export.ts +861 -0
  231. package/dist/src/lib/structure/index.ts +291 -0
  232. package/dist/src/lib/structure/label-placement.ts +130 -0
  233. package/dist/src/lib/structure/measure.ts +45 -0
  234. package/dist/src/lib/structure/parse.ts +1705 -0
  235. package/dist/src/lib/structure/partial-occupancy.ts +183 -0
  236. package/dist/src/lib/structure/pbc.ts +164 -0
  237. package/dist/src/lib/structure/supercell.ts +226 -0
  238. package/dist/src/lib/structure/validation.ts +11 -0
  239. package/dist/src/lib/symmetry/SymmetryStats.svelte +226 -0
  240. package/dist/src/lib/symmetry/WyckoffTable.svelte +120 -0
  241. package/dist/src/lib/symmetry/cell-transform.ts +118 -0
  242. package/dist/src/lib/symmetry/index.ts +348 -0
  243. package/dist/src/lib/symmetry/spacegroups.ts +404 -0
  244. package/dist/src/lib/table/HeatmapTable.svelte +1833 -0
  245. package/dist/src/lib/table/ToggleMenu.svelte +385 -0
  246. package/dist/src/lib/table/index.ts +139 -0
  247. package/dist/src/lib/theme/ThemeControl.svelte +53 -0
  248. package/dist/src/lib/theme/index.ts +107 -0
  249. package/dist/src/lib/theme/themes.mjs +297 -0
  250. package/dist/src/lib/time.ts +71 -0
  251. package/dist/src/lib/tooltip/TooltipContent.svelte +58 -0
  252. package/dist/src/lib/tooltip/index.ts +2 -0
  253. package/dist/src/lib/tooltip/types.ts +13 -0
  254. package/dist/src/lib/trajectory/Trajectory.svelte +1545 -0
  255. package/dist/src/lib/trajectory/TrajectoryError.svelte +128 -0
  256. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +357 -0
  257. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +313 -0
  258. package/dist/src/lib/trajectory/constants.ts +7 -0
  259. package/dist/src/lib/trajectory/extract.ts +196 -0
  260. package/dist/src/lib/trajectory/format-detect.ts +96 -0
  261. package/dist/src/lib/trajectory/frame-reader.ts +456 -0
  262. package/dist/src/lib/trajectory/helpers.ts +217 -0
  263. package/dist/src/lib/trajectory/index.ts +218 -0
  264. package/dist/src/lib/trajectory/parse/ase.ts +109 -0
  265. package/dist/src/lib/trajectory/parse/hdf5.ts +173 -0
  266. package/dist/src/lib/trajectory/parse/index.ts +411 -0
  267. package/dist/src/lib/trajectory/parse/lammps.ts +215 -0
  268. package/dist/src/lib/trajectory/parse/vasp.ts +102 -0
  269. package/dist/src/lib/trajectory/parse/xyz.ts +143 -0
  270. package/dist/src/lib/trajectory/plotting.ts +599 -0
  271. package/dist/src/lib/trajectory/types.ts +13 -0
  272. package/dist/src/lib/utils.ts +56 -0
  273. package/dist/src/lib/xrd/XrdPlot.svelte +615 -0
  274. package/dist/src/lib/xrd/broadening.ts +130 -0
  275. package/dist/src/lib/xrd/calc-xrd.ts +397 -0
  276. package/dist/src/lib/xrd/index.ts +38 -0
  277. package/dist/src/lib/xrd/parse.ts +858 -0
  278. package/dist/webview.js +29421 -0
  279. package/icon.png +0 -0
  280. package/license +1 -1
  281. package/matterviz-0.3.2.vsix +0 -0
  282. package/matterviz-0.3.4.vsix +0 -0
  283. package/matterviz-0.3.5.vsix +0 -0
  284. package/package.json +1461 -231
  285. package/readme.md +171 -98
  286. package/scripts/sync-config.ts +101 -0
  287. package/src/declarations.d.ts +2 -0
  288. package/src/extension.ts +972 -0
  289. package/src/node-io.ts +65 -0
  290. package/src/types.ts +17 -0
  291. package/src/webview/JsonBrowser.svelte +1079 -0
  292. package/src/webview/PlotPanel.svelte +346 -0
  293. package/src/webview/detect.ts +444 -0
  294. package/src/webview/main.ts +764 -0
  295. package/src/webview/plot-utils.ts +250 -0
  296. package/test-fixtures/all-viz-types.json.gz +0 -0
  297. package/test-fixtures/plot-demo-data.json.gz +0 -0
  298. package/tests/detect.test.ts +604 -0
  299. package/tests/extension.test.ts +2041 -0
  300. package/tests/node-io.test.ts +39 -0
  301. package/tests/plot-utils.test.ts +302 -0
  302. package/tests/vite-plugin-json-gz.test.ts +114 -0
  303. package/tests/vscode-mock.ts +18 -0
  304. package/tests/webview.test.ts +231 -0
  305. package/tsconfig.json +20 -0
  306. package/vite-plugin-json-gz.ts +29 -0
  307. package/vite.config.ts +34 -0
  308. package/vite.extension.config.ts +34 -0
  309. package/dist/EmptyState.svelte.d.ts +0 -9
  310. package/dist/FilePicker.svelte +0 -360
  311. package/dist/FilePicker.svelte.d.ts +0 -17
  312. package/dist/Icon.svelte.d.ts +0 -13
  313. package/dist/MillerIndexInput.svelte +0 -66
  314. package/dist/MillerIndexInput.svelte.d.ts +0 -7
  315. package/dist/api/mp.d.ts +0 -6
  316. package/dist/api/mp.js +0 -22
  317. package/dist/api/optimade.d.ts +0 -45
  318. package/dist/api/optimade.js +0 -135
  319. package/dist/app.css +0 -240
  320. package/dist/brillouin/BrillouinZone.svelte +0 -543
  321. package/dist/brillouin/BrillouinZone.svelte.d.ts +0 -83
  322. package/dist/brillouin/BrillouinZoneControls.svelte +0 -144
  323. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +0 -17
  324. package/dist/brillouin/BrillouinZoneExportPane.svelte +0 -148
  325. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +0 -15
  326. package/dist/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  327. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +0 -13
  328. package/dist/brillouin/BrillouinZoneScene.svelte +0 -476
  329. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +0 -48
  330. package/dist/brillouin/BrillouinZoneTooltip.svelte +0 -92
  331. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +0 -8
  332. package/dist/brillouin/compute.d.ts +0 -17
  333. package/dist/brillouin/compute.js +0 -422
  334. package/dist/brillouin/index.d.ts +0 -8
  335. package/dist/brillouin/index.js +0 -8
  336. package/dist/brillouin/types.d.ts +0 -48
  337. package/dist/brillouin/types.js +0 -1
  338. package/dist/chempot-diagram/ChemPotDiagram.svelte +0 -327
  339. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +0 -13
  340. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +0 -847
  341. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +0 -16
  342. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +0 -3194
  343. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +0 -16
  344. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +0 -7
  345. package/dist/chempot-diagram/async-compute.svelte.d.ts +0 -3
  346. package/dist/chempot-diagram/async-compute.svelte.js +0 -77
  347. package/dist/chempot-diagram/chempot-worker.d.ts +0 -1
  348. package/dist/chempot-diagram/chempot-worker.js +0 -11
  349. package/dist/chempot-diagram/color.d.ts +0 -10
  350. package/dist/chempot-diagram/color.js +0 -32
  351. package/dist/chempot-diagram/compute.d.ts +0 -48
  352. package/dist/chempot-diagram/compute.js +0 -812
  353. package/dist/chempot-diagram/index.d.ts +0 -6
  354. package/dist/chempot-diagram/index.js +0 -6
  355. package/dist/chempot-diagram/pointer.d.ts +0 -16
  356. package/dist/chempot-diagram/pointer.js +0 -40
  357. package/dist/chempot-diagram/temperature.d.ts +0 -15
  358. package/dist/chempot-diagram/temperature.js +0 -36
  359. package/dist/chempot-diagram/types.d.ts +0 -86
  360. package/dist/chempot-diagram/types.js +0 -28
  361. package/dist/colors/index.d.ts +0 -47
  362. package/dist/colors/index.js +0 -203
  363. package/dist/composition/BarChart.svelte +0 -297
  364. package/dist/composition/BarChart.svelte.d.ts +0 -39
  365. package/dist/composition/BubbleChart.svelte +0 -218
  366. package/dist/composition/BubbleChart.svelte.d.ts +0 -28
  367. package/dist/composition/Composition.svelte +0 -164
  368. package/dist/composition/Composition.svelte.d.ts +0 -15
  369. package/dist/composition/Formula.svelte +0 -265
  370. package/dist/composition/Formula.svelte.d.ts +0 -19
  371. package/dist/composition/FormulaFilter.svelte +0 -1259
  372. package/dist/composition/FormulaFilter.svelte.d.ts +0 -51
  373. package/dist/composition/PieChart.svelte +0 -323
  374. package/dist/composition/PieChart.svelte.d.ts +0 -37
  375. package/dist/composition/format.d.ts +0 -15
  376. package/dist/composition/format.js +0 -109
  377. package/dist/composition/index.d.ts +0 -20
  378. package/dist/composition/index.js +0 -14
  379. package/dist/composition/parse.d.ts +0 -55
  380. package/dist/composition/parse.js +0 -459
  381. package/dist/constants.d.ts +0 -29
  382. package/dist/constants.js +0 -105
  383. package/dist/controls.d.ts +0 -14
  384. package/dist/controls.js +0 -30
  385. package/dist/convex-hull/ConvexHull.svelte +0 -157
  386. package/dist/convex-hull/ConvexHull.svelte.d.ts +0 -13
  387. package/dist/convex-hull/ConvexHull2D.svelte +0 -813
  388. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +0 -11
  389. package/dist/convex-hull/ConvexHull3D.svelte +0 -1788
  390. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +0 -8
  391. package/dist/convex-hull/ConvexHull4D.svelte +0 -1374
  392. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +0 -8
  393. package/dist/convex-hull/ConvexHullControls.svelte +0 -546
  394. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +0 -48
  395. package/dist/convex-hull/ConvexHullInfoPane.svelte +0 -115
  396. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +0 -18
  397. package/dist/convex-hull/ConvexHullStats.svelte +0 -905
  398. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +0 -15
  399. package/dist/convex-hull/ConvexHullTooltip.svelte +0 -131
  400. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +0 -33
  401. package/dist/convex-hull/GasPressureControls.svelte +0 -247
  402. package/dist/convex-hull/GasPressureControls.svelte.d.ts +0 -11
  403. package/dist/convex-hull/StructurePopup.svelte +0 -116
  404. package/dist/convex-hull/StructurePopup.svelte.d.ts +0 -18
  405. package/dist/convex-hull/TemperatureSlider.svelte +0 -137
  406. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +0 -8
  407. package/dist/convex-hull/barycentric-coords.d.ts +0 -18
  408. package/dist/convex-hull/barycentric-coords.js +0 -182
  409. package/dist/convex-hull/demo-temperature.d.ts +0 -6
  410. package/dist/convex-hull/demo-temperature.js +0 -40
  411. package/dist/convex-hull/gas-thermodynamics.d.ts +0 -16
  412. package/dist/convex-hull/gas-thermodynamics.js +0 -316
  413. package/dist/convex-hull/helpers.d.ts +0 -103
  414. package/dist/convex-hull/helpers.js +0 -671
  415. package/dist/convex-hull/index.d.ts +0 -118
  416. package/dist/convex-hull/index.js +0 -57
  417. package/dist/convex-hull/thermodynamics.d.ts +0 -66
  418. package/dist/convex-hull/thermodynamics.js +0 -1752
  419. package/dist/convex-hull/types.d.ts +0 -162
  420. package/dist/convex-hull/types.js +0 -36
  421. package/dist/coordination/CoordinationBarPlot.svelte +0 -311
  422. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +0 -30
  423. package/dist/coordination/calc-coordination.d.ts +0 -15
  424. package/dist/coordination/calc-coordination.js +0 -63
  425. package/dist/coordination/index.d.ts +0 -8
  426. package/dist/coordination/index.js +0 -7
  427. package/dist/element/BohrAtom.svelte +0 -149
  428. package/dist/element/BohrAtom.svelte.d.ts +0 -20
  429. package/dist/element/ElementHeading.svelte +0 -26
  430. package/dist/element/ElementHeading.svelte.d.ts +0 -8
  431. package/dist/element/ElementPhoto.svelte +0 -57
  432. package/dist/element/ElementPhoto.svelte.d.ts +0 -9
  433. package/dist/element/ElementStats.svelte +0 -80
  434. package/dist/element/ElementStats.svelte.d.ts +0 -8
  435. package/dist/element/ElementTile.svelte +0 -484
  436. package/dist/element/ElementTile.svelte.d.ts +0 -29
  437. package/dist/element/Nucleus.svelte.d.ts +0 -17
  438. package/dist/element/data.d.ts +0 -3
  439. package/dist/element/data.js +0 -2
  440. package/dist/element/data.json.gz.d.ts +0 -2
  441. package/dist/element/index.d.ts +0 -8
  442. package/dist/element/index.js +0 -8
  443. package/dist/element/types.d.ts +0 -57
  444. package/dist/element/types.js +0 -1
  445. package/dist/feedback/ClickFeedback.svelte +0 -58
  446. package/dist/feedback/ClickFeedback.svelte.d.ts +0 -12
  447. package/dist/feedback/DragOverlay.svelte +0 -42
  448. package/dist/feedback/DragOverlay.svelte.d.ts +0 -7
  449. package/dist/feedback/Spinner.svelte.d.ts +0 -7
  450. package/dist/feedback/StatusMessage.svelte.d.ts +0 -9
  451. package/dist/feedback/index.d.ts +0 -4
  452. package/dist/feedback/index.js +0 -4
  453. package/dist/fermi-surface/FermiSlice.svelte +0 -189
  454. package/dist/fermi-surface/FermiSlice.svelte.d.ts +0 -24
  455. package/dist/fermi-surface/FermiSurface.svelte +0 -597
  456. package/dist/fermi-surface/FermiSurface.svelte.d.ts +0 -83
  457. package/dist/fermi-surface/FermiSurfaceControls.svelte +0 -452
  458. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +0 -35
  459. package/dist/fermi-surface/FermiSurfaceScene.svelte +0 -792
  460. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +0 -50
  461. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  462. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +0 -8
  463. package/dist/fermi-surface/compute.d.ts +0 -5
  464. package/dist/fermi-surface/compute.js +0 -538
  465. package/dist/fermi-surface/constants.d.ts +0 -9
  466. package/dist/fermi-surface/constants.js +0 -27
  467. package/dist/fermi-surface/export.d.ts +0 -5
  468. package/dist/fermi-surface/export.js +0 -63
  469. package/dist/fermi-surface/index.d.ts +0 -12
  470. package/dist/fermi-surface/index.js +0 -13
  471. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  472. package/dist/fermi-surface/marching-cubes.js +0 -2
  473. package/dist/fermi-surface/parse.d.ts +0 -2
  474. package/dist/fermi-surface/parse.js +0 -495
  475. package/dist/fermi-surface/symmetry.d.ts +0 -3
  476. package/dist/fermi-surface/symmetry.js +0 -46
  477. package/dist/fermi-surface/types.d.ts +0 -113
  478. package/dist/fermi-surface/types.js +0 -4
  479. package/dist/heatmap-matrix/HeatmapMatrix.svelte +0 -1527
  480. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +0 -110
  481. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  482. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +0 -30
  483. package/dist/heatmap-matrix/index.d.ts +0 -53
  484. package/dist/heatmap-matrix/index.js +0 -100
  485. package/dist/heatmap-matrix/shared.d.ts +0 -2
  486. package/dist/heatmap-matrix/shared.js +0 -4
  487. package/dist/icons.d.ts +0 -569
  488. package/dist/icons.js +0 -648
  489. package/dist/index.d.ts +0 -39
  490. package/dist/index.js +0 -39
  491. package/dist/io/decompress.d.ts +0 -10
  492. package/dist/io/decompress.js +0 -69
  493. package/dist/io/export.d.ts +0 -16
  494. package/dist/io/export.js +0 -312
  495. package/dist/io/fetch.d.ts +0 -5
  496. package/dist/io/fetch.js +0 -39
  497. package/dist/io/file-drop.d.ts +0 -7
  498. package/dist/io/file-drop.js +0 -43
  499. package/dist/io/index.d.ts +0 -7
  500. package/dist/io/index.js +0 -7
  501. package/dist/io/is-binary.d.ts +0 -1
  502. package/dist/io/is-binary.js +0 -5
  503. package/dist/io/types.d.ts +0 -8
  504. package/dist/io/types.js +0 -1
  505. package/dist/io/url-drop.d.ts +0 -2
  506. package/dist/io/url-drop.js +0 -117
  507. package/dist/isosurface/Isosurface.svelte +0 -285
  508. package/dist/isosurface/Isosurface.svelte.d.ts +0 -8
  509. package/dist/isosurface/IsosurfaceControls.svelte +0 -291
  510. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +0 -9
  511. package/dist/isosurface/index.d.ts +0 -5
  512. package/dist/isosurface/index.js +0 -6
  513. package/dist/isosurface/parse.d.ts +0 -6
  514. package/dist/isosurface/parse.js +0 -553
  515. package/dist/isosurface/slice.d.ts +0 -11
  516. package/dist/isosurface/slice.js +0 -140
  517. package/dist/isosurface/types.d.ts +0 -56
  518. package/dist/isosurface/types.js +0 -227
  519. package/dist/labels.d.ts +0 -53
  520. package/dist/labels.js +0 -274
  521. package/dist/layout/FullscreenToggle.svelte +0 -50
  522. package/dist/layout/FullscreenToggle.svelte.d.ts +0 -7
  523. package/dist/layout/InfoCard.svelte +0 -120
  524. package/dist/layout/InfoCard.svelte.d.ts +0 -21
  525. package/dist/layout/InfoTag.svelte +0 -183
  526. package/dist/layout/InfoTag.svelte.d.ts +0 -19
  527. package/dist/layout/PropertyFilter.svelte +0 -244
  528. package/dist/layout/PropertyFilter.svelte.d.ts +0 -24
  529. package/dist/layout/SettingsSection.svelte +0 -148
  530. package/dist/layout/SettingsSection.svelte.d.ts +0 -17
  531. package/dist/layout/SubpageGrid.svelte +0 -82
  532. package/dist/layout/SubpageGrid.svelte.d.ts +0 -14
  533. package/dist/layout/fullscreen.d.ts +0 -9
  534. package/dist/layout/fullscreen.js +0 -53
  535. package/dist/layout/index.d.ts +0 -10
  536. package/dist/layout/index.js +0 -8
  537. package/dist/layout/json-tree/JsonNode.svelte +0 -547
  538. package/dist/layout/json-tree/JsonNode.svelte.d.ts +0 -11
  539. package/dist/layout/json-tree/JsonTree.svelte +0 -1222
  540. package/dist/layout/json-tree/JsonTree.svelte.d.ts +0 -6
  541. package/dist/layout/json-tree/JsonValue.svelte +0 -334
  542. package/dist/layout/json-tree/JsonValue.svelte.d.ts +0 -9
  543. package/dist/layout/json-tree/index.d.ts +0 -3
  544. package/dist/layout/json-tree/index.js +0 -3
  545. package/dist/layout/json-tree/types.d.ts +0 -73
  546. package/dist/layout/json-tree/types.js +0 -3
  547. package/dist/layout/json-tree/utils.d.ts +0 -29
  548. package/dist/layout/json-tree/utils.js +0 -648
  549. package/dist/marching-cubes.d.ts +0 -14
  550. package/dist/marching-cubes.js +0 -542
  551. package/dist/math.d.ts +0 -91
  552. package/dist/math.js +0 -896
  553. package/dist/overlays/ContextMenu.svelte +0 -162
  554. package/dist/overlays/ContextMenu.svelte.d.ts +0 -25
  555. package/dist/overlays/DraggablePane.svelte +0 -564
  556. package/dist/overlays/DraggablePane.svelte.d.ts +0 -36
  557. package/dist/overlays/index.d.ts +0 -2
  558. package/dist/overlays/index.js +0 -2
  559. package/dist/periodic-table/PeriodicTable.svelte +0 -469
  560. package/dist/periodic-table/PeriodicTable.svelte.d.ts +0 -55
  561. package/dist/periodic-table/PeriodicTableControls.svelte +0 -557
  562. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +0 -24
  563. package/dist/periodic-table/PropertySelect.svelte +0 -37
  564. package/dist/periodic-table/PropertySelect.svelte.d.ts +0 -13
  565. package/dist/periodic-table/TableInset.svelte.d.ts +0 -9
  566. package/dist/periodic-table/index.d.ts +0 -10
  567. package/dist/periodic-table/index.js +0 -4
  568. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  569. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +0 -44
  570. package/dist/phase-diagram/PhaseDiagramControls.svelte +0 -451
  571. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +0 -30
  572. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  573. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +0 -15
  574. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +0 -192
  575. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +0 -19
  576. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +0 -392
  577. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +0 -16
  578. package/dist/phase-diagram/TdbInfoPanel.svelte +0 -203
  579. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +0 -12
  580. package/dist/phase-diagram/build-diagram.d.ts +0 -11
  581. package/dist/phase-diagram/build-diagram.js +0 -167
  582. package/dist/phase-diagram/colors.d.ts +0 -35
  583. package/dist/phase-diagram/colors.js +0 -51
  584. package/dist/phase-diagram/diagram-input.d.ts +0 -33
  585. package/dist/phase-diagram/diagram-input.js +0 -3
  586. package/dist/phase-diagram/index.d.ts +0 -13
  587. package/dist/phase-diagram/index.js +0 -13
  588. package/dist/phase-diagram/parse.d.ts +0 -55
  589. package/dist/phase-diagram/parse.js +0 -276
  590. package/dist/phase-diagram/svg-to-diagram.d.ts +0 -2
  591. package/dist/phase-diagram/svg-to-diagram.js +0 -869
  592. package/dist/phase-diagram/types.d.ts +0 -99
  593. package/dist/phase-diagram/types.js +0 -1
  594. package/dist/phase-diagram/utils.d.ts +0 -118
  595. package/dist/phase-diagram/utils.js +0 -606
  596. package/dist/plot/AxisLabel.svelte +0 -51
  597. package/dist/plot/AxisLabel.svelte.d.ts +0 -16
  598. package/dist/plot/BarPlot.svelte +0 -2256
  599. package/dist/plot/BarPlot.svelte.d.ts +0 -82
  600. package/dist/plot/BarPlotControls.svelte +0 -66
  601. package/dist/plot/BarPlotControls.svelte.d.ts +0 -18
  602. package/dist/plot/ColorBar.svelte +0 -719
  603. package/dist/plot/ColorBar.svelte.d.ts +0 -31
  604. package/dist/plot/ColorScaleSelect.svelte +0 -54
  605. package/dist/plot/ColorScaleSelect.svelte.d.ts +0 -15
  606. package/dist/plot/ElementScatter.svelte +0 -63
  607. package/dist/plot/ElementScatter.svelte.d.ts +0 -14
  608. package/dist/plot/FillArea.svelte +0 -226
  609. package/dist/plot/FillArea.svelte.d.ts +0 -20
  610. package/dist/plot/Histogram.svelte +0 -1654
  611. package/dist/plot/Histogram.svelte.d.ts +0 -50
  612. package/dist/plot/HistogramControls.svelte +0 -212
  613. package/dist/plot/HistogramControls.svelte.d.ts +0 -22
  614. package/dist/plot/InteractiveAxisLabel.svelte +0 -94
  615. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +0 -14
  616. package/dist/plot/Line.svelte +0 -85
  617. package/dist/plot/Line.svelte.d.ts +0 -15
  618. package/dist/plot/PlotControls.svelte +0 -537
  619. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  620. package/dist/plot/PlotLegend.svelte +0 -498
  621. package/dist/plot/PlotLegend.svelte.d.ts +0 -25
  622. package/dist/plot/PlotTooltip.svelte +0 -67
  623. package/dist/plot/PlotTooltip.svelte.d.ts +0 -17
  624. package/dist/plot/PortalSelect.svelte +0 -253
  625. package/dist/plot/PortalSelect.svelte.d.ts +0 -16
  626. package/dist/plot/ReferenceLine.svelte.d.ts +0 -20
  627. package/dist/plot/ReferenceLine3D.svelte +0 -154
  628. package/dist/plot/ReferenceLine3D.svelte.d.ts +0 -14
  629. package/dist/plot/ReferencePlane.svelte +0 -178
  630. package/dist/plot/ReferencePlane.svelte.d.ts +0 -14
  631. package/dist/plot/ScatterPlot.svelte +0 -2831
  632. package/dist/plot/ScatterPlot.svelte.d.ts +0 -92
  633. package/dist/plot/ScatterPlot3D.svelte +0 -499
  634. package/dist/plot/ScatterPlot3D.svelte.d.ts +0 -94
  635. package/dist/plot/ScatterPlot3DControls.svelte +0 -437
  636. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +0 -20
  637. package/dist/plot/ScatterPlot3DScene.svelte +0 -912
  638. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +0 -74
  639. package/dist/plot/ScatterPlotControls.svelte +0 -307
  640. package/dist/plot/ScatterPlotControls.svelte.d.ts +0 -17
  641. package/dist/plot/ScatterPoint.svelte +0 -185
  642. package/dist/plot/ScatterPoint.svelte.d.ts +0 -19
  643. package/dist/plot/SpacegroupBarPlot.svelte +0 -292
  644. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +0 -9
  645. package/dist/plot/Surface3D.svelte +0 -200
  646. package/dist/plot/Surface3D.svelte.d.ts +0 -13
  647. package/dist/plot/ZeroLines.svelte +0 -96
  648. package/dist/plot/ZeroLines.svelte.d.ts +0 -32
  649. package/dist/plot/ZoomRect.svelte +0 -23
  650. package/dist/plot/ZoomRect.svelte.d.ts +0 -8
  651. package/dist/plot/axis-utils.d.ts +0 -19
  652. package/dist/plot/axis-utils.js +0 -80
  653. package/dist/plot/data-cleaning.d.ts +0 -37
  654. package/dist/plot/data-cleaning.js +0 -855
  655. package/dist/plot/data-transform.d.ts +0 -16
  656. package/dist/plot/data-transform.js +0 -45
  657. package/dist/plot/defaults.d.ts +0 -19
  658. package/dist/plot/defaults.js +0 -9
  659. package/dist/plot/fill-utils.d.ts +0 -51
  660. package/dist/plot/fill-utils.js +0 -337
  661. package/dist/plot/hover-lock.svelte.d.ts +0 -14
  662. package/dist/plot/hover-lock.svelte.js +0 -46
  663. package/dist/plot/index.d.ts +0 -43
  664. package/dist/plot/index.js +0 -37
  665. package/dist/plot/interactions.d.ts +0 -12
  666. package/dist/plot/interactions.js +0 -100
  667. package/dist/plot/layout.d.ts +0 -60
  668. package/dist/plot/layout.js +0 -230
  669. package/dist/plot/reference-line.d.ts +0 -60
  670. package/dist/plot/reference-line.js +0 -316
  671. package/dist/plot/scales.d.ts +0 -48
  672. package/dist/plot/scales.js +0 -484
  673. package/dist/plot/svg.d.ts +0 -1
  674. package/dist/plot/svg.js +0 -11
  675. package/dist/plot/types.d.ts +0 -863
  676. package/dist/plot/types.js +0 -103
  677. package/dist/plot/utils/label-placement.d.ts +0 -47
  678. package/dist/plot/utils/label-placement.js +0 -256
  679. package/dist/plot/utils/series-visibility.d.ts +0 -9
  680. package/dist/plot/utils/series-visibility.js +0 -67
  681. package/dist/plot/utils.d.ts +0 -1
  682. package/dist/plot/utils.js +0 -14
  683. package/dist/rdf/RdfPlot.svelte +0 -247
  684. package/dist/rdf/RdfPlot.svelte.d.ts +0 -27
  685. package/dist/rdf/calc-rdf.d.ts +0 -4
  686. package/dist/rdf/calc-rdf.js +0 -111
  687. package/dist/rdf/index.d.ts +0 -23
  688. package/dist/rdf/index.js +0 -2
  689. package/dist/sanitize.d.ts +0 -4
  690. package/dist/sanitize.js +0 -107
  691. package/dist/settings.d.ts +0 -253
  692. package/dist/settings.js +0 -1123
  693. package/dist/spectral/Bands.svelte +0 -1040
  694. package/dist/spectral/Bands.svelte.d.ts +0 -40
  695. package/dist/spectral/BandsAndDos.svelte +0 -128
  696. package/dist/spectral/BandsAndDos.svelte.d.ts +0 -18
  697. package/dist/spectral/BrillouinBandsDos.svelte +0 -248
  698. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +0 -20
  699. package/dist/spectral/Dos.svelte +0 -697
  700. package/dist/spectral/Dos.svelte.d.ts +0 -29
  701. package/dist/spectral/helpers.d.ts +0 -117
  702. package/dist/spectral/helpers.js +0 -1023
  703. package/dist/spectral/index.d.ts +0 -6
  704. package/dist/spectral/index.js +0 -7
  705. package/dist/spectral/types.d.ts +0 -84
  706. package/dist/spectral/types.js +0 -2
  707. package/dist/state.svelte.d.ts +0 -25
  708. package/dist/state.svelte.js +0 -45
  709. package/dist/structure/Arrow.svelte +0 -72
  710. package/dist/structure/Arrow.svelte.d.ts +0 -15
  711. package/dist/structure/AtomLegend.svelte +0 -798
  712. package/dist/structure/AtomLegend.svelte.d.ts +0 -34
  713. package/dist/structure/Bond.svelte +0 -140
  714. package/dist/structure/Bond.svelte.d.ts +0 -9
  715. package/dist/structure/CanvasTooltip.svelte +0 -33
  716. package/dist/structure/CanvasTooltip.svelte.d.ts +0 -12
  717. package/dist/structure/CellSelect.svelte +0 -351
  718. package/dist/structure/CellSelect.svelte.d.ts +0 -13
  719. package/dist/structure/Cylinder.svelte +0 -45
  720. package/dist/structure/Cylinder.svelte.d.ts +0 -10
  721. package/dist/structure/Lattice.svelte +0 -196
  722. package/dist/structure/Lattice.svelte.d.ts +0 -17
  723. package/dist/structure/Structure.svelte +0 -1857
  724. package/dist/structure/Structure.svelte.d.ts +0 -83
  725. package/dist/structure/StructureControls.svelte +0 -1184
  726. package/dist/structure/StructureControls.svelte.d.ts +0 -31
  727. package/dist/structure/StructureExportPane.svelte +0 -251
  728. package/dist/structure/StructureExportPane.svelte.d.ts +0 -17
  729. package/dist/structure/StructureInfoPane.svelte +0 -434
  730. package/dist/structure/StructureInfoPane.svelte.d.ts +0 -18
  731. package/dist/structure/StructureScene.svelte +0 -1574
  732. package/dist/structure/StructureScene.svelte.d.ts +0 -104
  733. package/dist/structure/atom-properties.d.ts +0 -37
  734. package/dist/structure/atom-properties.js +0 -198
  735. package/dist/structure/bonding.d.ts +0 -33
  736. package/dist/structure/bonding.js +0 -304
  737. package/dist/structure/export.d.ts +0 -20
  738. package/dist/structure/export.js +0 -725
  739. package/dist/structure/ferrox-wasm-types.d.ts +0 -46
  740. package/dist/structure/ferrox-wasm-types.js +0 -18
  741. package/dist/structure/ferrox-wasm.d.ts +0 -94
  742. package/dist/structure/ferrox-wasm.js +0 -249
  743. package/dist/structure/index.d.ts +0 -110
  744. package/dist/structure/index.js +0 -168
  745. package/dist/structure/measure.d.ts +0 -6
  746. package/dist/structure/measure.js +0 -29
  747. package/dist/structure/parse.d.ts +0 -65
  748. package/dist/structure/parse.js +0 -1374
  749. package/dist/structure/partial-occupancy.d.ts +0 -25
  750. package/dist/structure/partial-occupancy.js +0 -99
  751. package/dist/structure/pbc.d.ts +0 -9
  752. package/dist/structure/pbc.js +0 -123
  753. package/dist/structure/supercell.d.ts +0 -8
  754. package/dist/structure/supercell.js +0 -137
  755. package/dist/structure/validation.d.ts +0 -2
  756. package/dist/structure/validation.js +0 -10
  757. package/dist/symmetry/SymmetryStats.svelte +0 -226
  758. package/dist/symmetry/SymmetryStats.svelte.d.ts +0 -21
  759. package/dist/symmetry/WyckoffTable.svelte +0 -113
  760. package/dist/symmetry/WyckoffTable.svelte.d.ts +0 -11
  761. package/dist/symmetry/cell-transform.d.ts +0 -12
  762. package/dist/symmetry/cell-transform.js +0 -77
  763. package/dist/symmetry/index.d.ts +0 -43
  764. package/dist/symmetry/index.js +0 -229
  765. package/dist/symmetry/spacegroups.d.ts +0 -9
  766. package/dist/symmetry/spacegroups.js +0 -394
  767. package/dist/table/HeatmapTable.svelte +0 -1854
  768. package/dist/table/HeatmapTable.svelte.d.ts +0 -49
  769. package/dist/table/ToggleMenu.svelte +0 -376
  770. package/dist/table/ToggleMenu.svelte.d.ts +0 -11
  771. package/dist/table/index.d.ts +0 -74
  772. package/dist/table/index.js +0 -38
  773. package/dist/theme/ThemeControl.svelte +0 -53
  774. package/dist/theme/ThemeControl.svelte.d.ts +0 -9
  775. package/dist/theme/index.d.ts +0 -29
  776. package/dist/theme/index.js +0 -79
  777. package/dist/theme/themes.mjs +0 -285
  778. package/dist/time.d.ts +0 -4
  779. package/dist/time.js +0 -70
  780. package/dist/tooltip/TooltipContent.svelte +0 -58
  781. package/dist/tooltip/TooltipContent.svelte.d.ts +0 -31
  782. package/dist/tooltip/index.d.ts +0 -2
  783. package/dist/tooltip/index.js +0 -2
  784. package/dist/tooltip/types.d.ts +0 -8
  785. package/dist/tooltip/types.js +0 -1
  786. package/dist/trajectory/Trajectory.svelte +0 -1517
  787. package/dist/trajectory/Trajectory.svelte.d.ts +0 -77
  788. package/dist/trajectory/TrajectoryError.svelte +0 -128
  789. package/dist/trajectory/TrajectoryError.svelte.d.ts +0 -13
  790. package/dist/trajectory/TrajectoryExportPane.svelte +0 -357
  791. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +0 -17
  792. package/dist/trajectory/TrajectoryInfoPane.svelte +0 -387
  793. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +0 -17
  794. package/dist/trajectory/constants.d.ts +0 -6
  795. package/dist/trajectory/constants.js +0 -7
  796. package/dist/trajectory/extract.d.ts +0 -5
  797. package/dist/trajectory/extract.js +0 -162
  798. package/dist/trajectory/format-detect.d.ts +0 -9
  799. package/dist/trajectory/format-detect.js +0 -76
  800. package/dist/trajectory/frame-reader.d.ts +0 -17
  801. package/dist/trajectory/frame-reader.js +0 -332
  802. package/dist/trajectory/helpers.d.ts +0 -14
  803. package/dist/trajectory/helpers.js +0 -172
  804. package/dist/trajectory/index.d.ts +0 -63
  805. package/dist/trajectory/index.js +0 -126
  806. package/dist/trajectory/parse/ase.d.ts +0 -2
  807. package/dist/trajectory/parse/ase.js +0 -77
  808. package/dist/trajectory/parse/hdf5.d.ts +0 -2
  809. package/dist/trajectory/parse/hdf5.js +0 -129
  810. package/dist/trajectory/parse/index.d.ts +0 -12
  811. package/dist/trajectory/parse/index.js +0 -299
  812. package/dist/trajectory/parse/lammps.d.ts +0 -5
  813. package/dist/trajectory/parse/lammps.js +0 -179
  814. package/dist/trajectory/parse/vasp.d.ts +0 -2
  815. package/dist/trajectory/parse/vasp.js +0 -68
  816. package/dist/trajectory/parse/xyz.d.ts +0 -2
  817. package/dist/trajectory/parse/xyz.js +0 -110
  818. package/dist/trajectory/plotting.d.ts +0 -28
  819. package/dist/trajectory/plotting.js +0 -423
  820. package/dist/trajectory/types.d.ts +0 -11
  821. package/dist/trajectory/types.js +0 -1
  822. package/dist/utils.d.ts +0 -5
  823. package/dist/utils.js +0 -36
  824. package/dist/xrd/XrdPlot.svelte +0 -615
  825. package/dist/xrd/XrdPlot.svelte.d.ts +0 -28
  826. package/dist/xrd/broadening.d.ts +0 -20
  827. package/dist/xrd/broadening.js +0 -97
  828. package/dist/xrd/calc-xrd.d.ts +0 -37
  829. package/dist/xrd/calc-xrd.js +0 -337
  830. package/dist/xrd/index.d.ts +0 -37
  831. package/dist/xrd/index.js +0 -4
  832. package/dist/xrd/parse.d.ts +0 -13
  833. package/dist/xrd/parse.js +0 -749
  834. /package/dist/{EmptyState.svelte → src/lib/EmptyState.svelte} +0 -0
  835. /package/dist/{Icon.svelte → src/lib/Icon.svelte} +0 -0
  836. /package/dist/{chempot-diagram → src/lib/chempot-diagram}/ChemPotScene3D.svelte +0 -0
  837. /package/dist/{colors → src/lib/colors}/alloy-colors.json +0 -0
  838. /package/dist/{colors → src/lib/colors}/dark-mode-colors.json +0 -0
  839. /package/dist/{colors → src/lib/colors}/jmol-colors.json +0 -0
  840. /package/dist/{colors → src/lib/colors}/muted-colors.json +0 -0
  841. /package/dist/{colors → src/lib/colors}/pastel-colors.json +0 -0
  842. /package/dist/{colors → src/lib/colors}/vesta-colors.json +0 -0
  843. /package/dist/{element → src/lib/element}/Nucleus.svelte +0 -0
  844. /package/dist/{element → src/lib/element}/data.json +0 -0
  845. /package/dist/{element → src/lib/element}/data.json.gz +0 -0
  846. /package/dist/{element → src/lib/element}/data.schema.json +0 -0
  847. /package/dist/{element-image-urls.json → src/lib/element-image-urls.json} +0 -0
  848. /package/dist/{feedback → src/lib/feedback}/Spinner.svelte +0 -0
  849. /package/dist/{feedback → src/lib/feedback}/StatusMessage.svelte +0 -0
  850. /package/dist/{periodic-table → src/lib/periodic-table}/TableInset.svelte +0 -0
  851. /package/dist/{plot → src/lib/plot}/ReferenceLine.svelte +0 -0
  852. /package/dist/{xrd → src/lib/xrd}/atomic_scattering_params.json +0 -0
@@ -1,1854 +0,0 @@
1
- <script lang="ts">
2
- import { luminance, watch_dark_mode } from '../colors'
3
- import Icon from '../Icon.svelte'
4
- import { format_num } from '../labels'
5
- import { SettingsSection } from '../layout'
6
- import ContextMenu from '../overlays/ContextMenu.svelte'
7
- import DraggablePane from '../overlays/DraggablePane.svelte'
8
- import type {
9
- CellSnippet,
10
- CellVal,
11
- ExportData,
12
- InitialSort,
13
- Label,
14
- MultiSortState,
15
- Pagination,
16
- RowData,
17
- Search,
18
- SortHint,
19
- SortState,
20
- SpecialCells,
21
- } from './'
22
- import { calc_cell_color, strip_html } from './'
23
- import { sanitize_html } from '../sanitize'
24
- import { normalize_unicode_minus } from '../utils'
25
- import type { Snippet } from 'svelte'
26
- import { tooltip } from 'svelte-multiselect/attachments'
27
- import { flip } from 'svelte/animate'
28
- import type { HTMLAttributes } from 'svelte/elements'
29
- import { SvelteMap } from 'svelte/reactivity'
30
-
31
- let {
32
- data = $bindable([]),
33
- columns = [],
34
- sort_hint = undefined,
35
- cell,
36
- special_cells,
37
- controls,
38
- initial_sort = undefined,
39
- sort = $bindable({ column: ``, dir: `asc` }), // allows external control/sync of sorting
40
- fixed_header = false,
41
- default_num_format = `.3`,
42
- show_heatmap = $bindable(true),
43
- heatmap_class = `heatmap`,
44
- onrowclick,
45
- onrowdblclick,
46
- column_order = $bindable([]),
47
- export_data = false,
48
- show_column_toggle = false,
49
- search = false,
50
- show_row_select = false,
51
- pagination = false,
52
- selected_rows = $bindable([]),
53
- hidden_columns = $bindable([]),
54
- scroll_style,
55
- root_style,
56
- onsort = undefined,
57
- onsorterror = undefined,
58
- loading = $bindable(false),
59
- sort_data = true,
60
- heatmap_opacity = $bindable(1),
61
- empty_message = `No data`,
62
- show_row_numbers = false,
63
- allow_better_toggle = false,
64
- show_controls = $bindable(false),
65
- controls_open = $bindable(false),
66
- header_cell,
67
- footer,
68
- ...rest
69
- }: HTMLAttributes<HTMLDivElement> & {
70
- data: RowData[]
71
- columns?: Label[]
72
- sort_hint?: SortHint
73
- cell?: CellSnippet
74
- special_cells?: SpecialCells
75
- controls?: Snippet
76
- initial_sort?: InitialSort
77
- sort?: { column: string; dir: `asc` | `desc` }
78
- fixed_header?: boolean
79
- default_num_format?: string
80
- show_heatmap?: boolean
81
- heatmap_class?: string
82
- onrowclick?: (event: MouseEvent | KeyboardEvent, row: RowData) => void
83
- onrowdblclick?: (event: MouseEvent, row: RowData) => void
84
- // Array of column IDs to control display order. IDs are derived as:
85
- // - Ungrouped columns: col.key ?? col.label
86
- // - Grouped columns: `${col.key ?? col.label} (${col.group})`
87
- // This allows persisting/restoring column order across sessions.
88
- column_order?: string[]
89
- export_data?: ExportData
90
- show_column_toggle?: boolean
91
- search?: Search
92
- show_row_select?: boolean
93
- pagination?: Pagination
94
- selected_rows?: RowData[]
95
- hidden_columns?: string[]
96
- scroll_style?: string
97
- // Inline styles for the root table container (merged with rest.style). Use instead of global CSS overrides.
98
- root_style?: string
99
- // Async callback for server-side sorting. When provided, client-side sorting is skipped
100
- // and the callback is called with (column_id, direction) to fetch new data from server.
101
- onsort?: (column: string, dir: `asc` | `desc`) => Promise<RowData[]>
102
- // Callback when onsort fails, receives the error for parent handling (e.g. toast notification)
103
- onsorterror?: (error: unknown, column: string, dir: `asc` | `desc`) => void
104
- // Loading state during async sort operations
105
- loading?: boolean
106
- // Whether to sort data client-side. Set to false when parent handles sorting externally.
107
- // When onsort is provided, sort_data behavior is implicitly false.
108
- sort_data?: boolean
109
- // Heatmap cell background opacity (0–1). Controls both the visual fade via CSS
110
- // color-mix() and the JS text contrast correction. Default 1 (fully opaque).
111
- heatmap_opacity?: number
112
- // Message shown when the table has no data rows. Set to empty string to hide.
113
- empty_message?: string
114
- // Show a row number column as the first column
115
- show_row_numbers?: boolean
116
- // When true, show a toggle in colored column headers to cycle gradient direction
117
- allow_better_toggle?: boolean
118
- // Whether the gear icon for the controls pane is visible
119
- show_controls?: boolean
120
- // Whether the controls pane is expanded
121
- controls_open?: boolean
122
- // Custom snippet for rendering header cells. Falls back to {@html col.label}.
123
- header_cell?: Snippet<[{ col: Label }]>
124
- // Footer snippet rendered inside <tfoot> below the table body
125
- footer?: Snippet
126
- } = $props()
127
-
128
- let container_el = $state<HTMLDivElement>()
129
-
130
- // Read --page-bg from computed style for text contrast calculation.
131
- // Recalculates on mount and when the theme changes (dark/light mode toggle).
132
- let page_bg_lum = $state(luminance(`white`))
133
- $effect(() => {
134
- if (!container_el) return
135
- const read_page_bg = () => {
136
- if (!container_el) return
137
- const page_bg = getComputedStyle(container_el).getPropertyValue(`--page-bg`)
138
- .trim()
139
- page_bg_lum = luminance(page_bg || `white`)
140
- }
141
- read_page_bg()
142
- return watch_dark_mode(read_page_bg)
143
- })
144
-
145
- // Detect HTML to prevent setting raw HTML as data-sort-value. Simple string matching
146
- // suffices since false positives just skip setting the attr (sorting still works by inner data-sort-value).
147
- function is_html_str(val: unknown): boolean {
148
- if (typeof val !== `string`) return false
149
- return (
150
- (val.includes(`<`) && val.includes(`>`)) || // Has angle brackets
151
- val.startsWith(`&lt;`) || // Has HTML entity for <
152
- val.includes(`href=`) || // Has href attribute
153
- val.includes(`class=`) // Has class attribute
154
- )
155
- }
156
-
157
- // Normalize initial_sort config
158
- let initial_sort_config = $derived(
159
- initial_sort
160
- ? typeof initial_sort === `string`
161
- ? { column: initial_sort, direction: `asc` as const }
162
- : { direction: `asc` as const, ...initial_sort }
163
- : null,
164
- )
165
-
166
- // Normalize pagination config
167
- let pagination_config = $derived(
168
- pagination
169
- ? { page_size: 25, ...(typeof pagination === `object` ? pagination : {}) }
170
- : null,
171
- )
172
-
173
- // Mutable page size — writable $derived allows user to change via dropdown
174
- let effective_page_size = $derived(pagination_config?.page_size ?? 25)
175
-
176
- // Normalize search config
177
- let search_config = $derived(
178
- search
179
- ? {
180
- placeholder: `Filter...`,
181
- expanded: false,
182
- ...(typeof search === `object` ? search : {}),
183
- }
184
- : null,
185
- )
186
-
187
- // Normalize export_data config
188
- type ExportFormat = `csv` | `json`
189
- const default_formats: ExportFormat[] = [`csv`, `json`]
190
- let export_config = $derived(
191
- export_data
192
- ? {
193
- formats: default_formats,
194
- filename: `table-export`,
195
- ...(typeof export_data === `object` ? export_data : {}),
196
- }
197
- : null,
198
- )
199
-
200
- // Derive sort_state from bindable prop, falling back to initial_sort if sort not yet set
201
- // This ensures immediate sorting on first render without waiting for effects
202
- let sort_state = $derived<SortState>({
203
- column: sort.column || initial_sort_config?.column || ``,
204
- ascending: sort.column
205
- ? sort.dir !== `desc`
206
- : initial_sort_config?.direction !== `desc`,
207
- })
208
-
209
- // Multi-column sort state (for Shift+click)
210
- let multi_sort = $state<MultiSortState>([])
211
-
212
- // Search/filter state
213
- let search_query = $state(``)
214
- let search_expanded = $derived(search_config?.expanded ?? false)
215
-
216
- // Pagination state
217
- let current_page = $state(1)
218
-
219
- // Dropdown states
220
- let show_column_dropdown = $state(false)
221
- let show_export_dropdown = $state(false)
222
-
223
- // Per-column gradient direction overrides (user-toggled via header)
224
- let better_overrides = new SvelteMap<string, `higher` | `lower`>()
225
-
226
- // Per-column color scale overrides
227
- let color_scale_overrides = new SvelteMap<string, string>()
228
-
229
- const color_scale_options = [
230
- `interpolateViridis`,
231
- `interpolatePlasma`,
232
- `interpolateInferno`,
233
- `interpolateCividis`,
234
- `interpolateTurbo`,
235
- `interpolateBlues`,
236
- `interpolateGreens`,
237
- `interpolateReds`,
238
- `interpolateYlOrRd`,
239
- ] as const
240
-
241
- // Columns that have a color gradient
242
- let colored_columns = $derived(
243
- columns.filter((col) =>
244
- col.color_scale !== null && col.color_scale !== undefined
245
- ),
246
- )
247
-
248
- // Column resize state
249
- let resize_col_id = $state<string | null>(null)
250
- let resize_start_x = $state(0)
251
- let resize_start_width = $state(0)
252
- let column_widths = $state<Record<string, number>>({})
253
-
254
- // Auto-discover columns from data keys when none are provided
255
- $effect.pre(() => {
256
- if (columns.length > 0 || data.length === 0) return
257
- const seen: Record<string, true> = {}
258
- for (const row of data.slice(0, 50)) {
259
- for (const key of Object.keys(row)) {
260
- if (key !== `style` && key !== `class`) seen[key] = true
261
- }
262
- }
263
- columns = Object.keys(seen).map((key) => ({ label: key }))
264
- })
265
-
266
- // Helper to make column IDs (needed since column labels in different groups can be repeated)
267
- const get_col_id = (col: Label) =>
268
- col.group ? `${col.key ?? col.label} (${col.group})` : (col.key ?? col.label)
269
-
270
- // Sync column_order with columns: initialize if empty, remove stale IDs, append new IDs
271
- $effect(() => {
272
- if (columns.length === 0) return
273
- const col_ids = columns.map(get_col_id)
274
-
275
- // Case 1: First render - initialize with default order
276
- if (column_order.length === 0) {
277
- column_order = col_ids
278
- return
279
- }
280
-
281
- // Case 2: Sync needed - keep valid IDs in their order, append any new ones
282
- const valid_ids = new Set(col_ids)
283
- const kept = column_order.filter((id) => valid_ids.has(id))
284
- const new_ids = col_ids.filter((id) => !kept.includes(id))
285
- const new_order = [...kept, ...new_ids]
286
-
287
- // Skip assignment if content is unchanged to prevent infinite effect loop.
288
- // After drag reorder, column_order differs from col_ids (default order) but the
289
- // computed new_order equals the current column_order — assigning a new array
290
- // reference would re-trigger this effect endlessly.
291
- if (new_order.length === column_order.length &&
292
- new_order.every((id, idx) => id === column_order[idx])) return
293
-
294
- column_order = new_order
295
- })
296
-
297
- // Reorder columns based on column_order
298
- let ordered_columns = $derived.by(() => {
299
- if (column_order.length === 0) return columns
300
-
301
- const col_map = new SvelteMap(columns.map((col) => [get_col_id(col), col]))
302
-
303
- // Add columns in specified order, then any remaining columns that weren't in the order list
304
- const ordered = column_order
305
- .map((id) => col_map.get(id))
306
- .filter((col): col is Label => col != null)
307
-
308
- const ordered_ids = new Set(ordered.map(get_col_id))
309
- const remaining = columns.filter((col) => !ordered_ids.has(get_col_id(col)))
310
-
311
- return [...ordered, ...remaining]
312
- })
313
-
314
- let drag_col_id = $state<string | null>(null)
315
- let drag_over_col_id = $state<string | null>(null)
316
-
317
- // Merge root_style with rest.style for root div; omit style from rest to avoid duplicate
318
- let rest_props = $derived.by(() => {
319
- const { style: rest_style, ...other_props } = rest
320
- const merged = [rest_style, root_style].filter(Boolean).join(`; `)
321
- return { ...other_props, ...(merged ? { style: merged } : {}) }
322
- })
323
-
324
- // WeakMap to assign stable unique IDs to row objects for efficient comparison and keying
325
- // This avoids O(n) JSON.stringify calls and prevents unnecessary re-renders
326
- const row_id_map = new WeakMap<RowData, string>()
327
- let row_id_counter = 0
328
-
329
- function get_row_id(row: RowData): string {
330
- let id = row_id_map.get(row)
331
- if (id === undefined) {
332
- id = `row_${row_id_counter++}`
333
- row_id_map.set(row, id)
334
- }
335
- return id
336
- }
337
-
338
- // Returns 'left' or 'right' to indicate which side of target to insert dragged column
339
- function get_drag_side(target_col_id: string): `left` | `right` | null {
340
- if (!drag_col_id) return null
341
- const drag_idx = column_order.indexOf(drag_col_id)
342
- const target_idx = column_order.indexOf(target_col_id)
343
- if (drag_idx === -1 || target_idx === -1) return null
344
- return drag_idx < target_idx ? `right` : `left`
345
- }
346
-
347
- function reset_drag_state() {
348
- drag_col_id = null
349
- drag_over_col_id = null
350
- }
351
-
352
- const get_drag_col_group = () =>
353
- ordered_columns.find((col) => get_col_id(col) === drag_col_id)?.group
354
-
355
- function handle_drag_start(event: DragEvent, col: Label) {
356
- if (!event.dataTransfer) return
357
- drag_col_id = get_col_id(col)
358
- event.dataTransfer.effectAllowed = `move`
359
- event.dataTransfer.setData(`text/html`, ``)
360
- }
361
-
362
- function handle_drag_over(event: DragEvent, col: Label) {
363
- event.preventDefault()
364
- if (!event.dataTransfer) return
365
- event.dataTransfer.dropEffect = `move`
366
-
367
- // Prevent cross-group drag-over to keep group headers contiguous
368
- if (get_drag_col_group() !== col.group) {
369
- event.dataTransfer.dropEffect = `none`
370
- drag_over_col_id = null
371
- return
372
- }
373
-
374
- drag_over_col_id = get_col_id(col)
375
- }
376
-
377
- function handle_drop(event: DragEvent, target_col: Label) {
378
- event.preventDefault()
379
-
380
- // Block cross-group (or group→ungroup) reorders to preserve group contiguity
381
- if (!drag_col_id || drag_col_id === get_col_id(target_col)) {
382
- reset_drag_state()
383
- return
384
- }
385
-
386
- // Block cross-group reorders to preserve group contiguity
387
- if (get_drag_col_group() !== target_col.group) {
388
- reset_drag_state()
389
- return
390
- }
391
-
392
- const target_col_id = get_col_id(target_col)
393
- const drag_idx = column_order.indexOf(drag_col_id)
394
- const target_idx = column_order.indexOf(target_col_id)
395
-
396
- if (drag_idx === -1 || target_idx === -1) {
397
- reset_drag_state()
398
- return
399
- }
400
-
401
- // Reorder: remove dragged column, then insert at target position
402
- // When dragging left-to-right (drag_idx < target_idx), removing the dragged
403
- // element shifts all subsequent indices down by 1, so we must adjust target_idx
404
- const new_order = [...column_order]
405
- new_order.splice(drag_idx, 1)
406
- const adjusted_target = drag_idx < target_idx ? target_idx - 1 : target_idx
407
- new_order.splice(adjusted_target, 0, drag_col_id)
408
- column_order = new_order
409
- reset_drag_state()
410
- }
411
-
412
- // Filter data based on search query
413
- let filtered_data = $derived.by(() => {
414
- const base_data = data?.filter?.((row) =>
415
- Object.values(row).some((val) => val !== undefined)
416
- ) ?? []
417
-
418
- if (!search_query.trim()) return base_data
419
-
420
- const query = search_query.toLowerCase().trim()
421
- return base_data.filter((row) =>
422
- Object.values(row).some((val) => {
423
- if (val == null) return false
424
- const clean_val = strip_html(String(val)).toLowerCase()
425
- return clean_val.includes(query)
426
- })
427
- )
428
- })
429
-
430
- let sorted_data = $derived.by(() => {
431
- // Skip client-side sorting when using async onsort callback or sort_data is false
432
- if (onsort || !sort_data) return filtered_data
433
-
434
- if (!sort_state.column && multi_sort.length === 0) return filtered_data
435
-
436
- // Helper to check if value is invalid (null, undefined, NaN)
437
- const is_invalid = (val: unknown) =>
438
- val == null || (typeof val === `number` && Number.isNaN(val))
439
-
440
- // Get sort value from a cell (handles HTML data-sort-value and numbers with errors)
441
- const get_sort_val = (val: CellVal): string | number => {
442
- if (typeof val === `string`) {
443
- // Check for HTML data-sort-value attribute first
444
- const sort_attr_match = val.match(/data-sort-value="([^"]*)"/)
445
- if (sort_attr_match) {
446
- const num = Number(sort_attr_match[1])
447
- return isNaN(num) ? sort_attr_match[1] : num
448
- }
449
- // Handle numbers with error notation: "1.23 ± 0.05" or "1.23 +- 0.05" or "1.23(5)"
450
- // Extract the primary number before the ± or +- or (
451
- // Supports: ± (U+00B1), ASCII +-, Unicode minus − (U+2212), with optional whitespace
452
- const error_match = val.match(
453
- /^([+-−]?\d+\.?\d*(?:[eE][+-−]?\d+)?)\s*(?:[±\u00B1]|[+][−-]|\()/,
454
- )
455
- if (error_match) {
456
- const num = Number(error_match[1])
457
- if (!isNaN(num)) return num
458
- }
459
- // Try parsing as a plain number (handles "1.23" strings)
460
- const plain_num = Number(val)
461
- if (!isNaN(plain_num) && val.trim() !== ``) return plain_num
462
- }
463
- return val as string | number
464
- }
465
-
466
- // Build sort criteria: multi_sort takes precedence, fallback to single sort
467
- const sort_criteria = multi_sort.length > 0
468
- ? multi_sort
469
- : sort_state.column
470
- ? [sort_state]
471
- : []
472
-
473
- if (sort_criteria.length === 0) return filtered_data
474
-
475
- return [...filtered_data].sort((row1, row2) => {
476
- for (const { column, ascending } of sort_criteria) {
477
- const matched_col = ordered_columns.find((c) => get_col_id(c) === column)
478
- if (!matched_col) continue
479
-
480
- const col_id = get_col_id(matched_col)
481
- const val1 = row1[col_id]
482
- const val2 = row2[col_id]
483
-
484
- if (val1 === val2) continue
485
-
486
- // Push invalid values to bottom
487
- if (is_invalid(val1) || is_invalid(val2)) {
488
- return +is_invalid(val1) - +is_invalid(val2)
489
- }
490
-
491
- const sort_val1 = get_sort_val(val1)
492
- const sort_val2 = get_sort_val(val2)
493
- const modifier = ascending ? 1 : -1
494
-
495
- if (typeof sort_val1 === `string` && typeof sort_val2 === `string`) {
496
- const cmp = sort_val1.localeCompare(sort_val2, undefined, {
497
- numeric: true,
498
- sensitivity: `base`,
499
- })
500
- if (cmp !== 0) return cmp * modifier
501
- } else {
502
- if (sort_val1 !== sort_val2) {
503
- return (sort_val1 ?? 0) < (sort_val2 ?? 0) ? -modifier : modifier
504
- }
505
- }
506
- }
507
- return 0
508
- })
509
- })
510
-
511
- // Paginated data
512
- let paginated_data = $derived.by(() => {
513
- if (!pagination_config) return sorted_data
514
- const start = (current_page - 1) * effective_page_size
515
- return sorted_data.slice(start, start + effective_page_size)
516
- })
517
-
518
- let total_pages = $derived(
519
- Math.ceil(sorted_data.length / effective_page_size),
520
- )
521
-
522
- // Track previous values to detect actual changes
523
- let prev_search_query = $state(``)
524
- let prev_data_length = $state(0)
525
-
526
- // Track async sort requests to prevent race conditions
527
- let sort_request_id = 0
528
-
529
- // Reset to page 1 when search query or data length actually changes
530
- $effect(() => {
531
- const query_changed = search_query !== prev_search_query
532
- const data_changed = sorted_data.length !== prev_data_length
533
-
534
- if (query_changed || data_changed) {
535
- current_page = 1
536
- prev_search_query = search_query
537
- prev_data_length = sorted_data.length
538
- } else if (total_pages > 0 && current_page > total_pages) {
539
- // Clamp when total pages decreases (e.g., page size increase)
540
- current_page = total_pages
541
- }
542
- })
543
-
544
- async function sort_rows(
545
- column: string,
546
- group: string | undefined,
547
- event: MouseEvent | KeyboardEvent,
548
- ) {
549
- // Find the column using both label and group if provided
550
- const col = ordered_columns.find(
551
- (c) => c.label === column && c.group === group,
552
- )
553
-
554
- if (!col) return // Skip if column not found
555
- if (col.sortable === false) return // Skip sorting if column marked as unsortable
556
-
557
- const col_id = get_col_id(col)
558
-
559
- // Shift+click for multi-column sort
560
- if (event.shiftKey) {
561
- const existing_idx = multi_sort.findIndex((s) => s.column === col_id)
562
- if (existing_idx >= 0) {
563
- // Toggle direction or remove if clicked again
564
- const existing = multi_sort[existing_idx]
565
- if (existing.ascending === (col.better === `lower`)) {
566
- // Remove from multi-sort
567
- multi_sort = multi_sort.filter((_, idx) => idx !== existing_idx)
568
- } else {
569
- // Toggle direction
570
- multi_sort = multi_sort.map((s, idx) =>
571
- idx === existing_idx ? { ...s, ascending: !s.ascending } : s
572
- )
573
- }
574
- } else {
575
- // Add to multi-sort
576
- multi_sort = [...multi_sort, {
577
- column: col_id,
578
- ascending: col.better === `lower`,
579
- }]
580
- }
581
- // Clear single sort when using multi-sort
582
- sort = { column: ``, dir: `asc` }
583
- } else {
584
- // Regular click - single column sort
585
- multi_sort = [] // Clear multi-sort
586
- // Use sort_state.column for comparison since it includes initial_sort fallback
587
- const new_dir = sort_state.column !== col_id
588
- ? (col.better === `lower` ? `asc` : `desc`)
589
- : (sort_state.ascending ? `desc` : `asc`)
590
-
591
- // Save previous sort state in case we need to revert on error
592
- const prev_sort = { ...sort }
593
- sort = { column: col_id, dir: new_dir }
594
-
595
- // If onsort callback provided, fetch new data from server
596
- if (onsort) {
597
- loading = true
598
- const request_id = ++sort_request_id
599
- try {
600
- const result = await onsort(col_id, new_dir)
601
- // Only update if this is still the most recent request (avoid race condition)
602
- if (request_id === sort_request_id) {
603
- data = result
604
- }
605
- } catch (err) {
606
- console.error(`Sort callback failed:`, err)
607
- // Revert sort state on failure so UI doesn't show wrong direction
608
- if (request_id === sort_request_id) {
609
- sort = prev_sort
610
- onsorterror?.(err, col_id, new_dir)
611
- }
612
- } finally {
613
- // Only clear loading if this is still the most recent request
614
- if (request_id === sort_request_id) {
615
- loading = false
616
- }
617
- }
618
- }
619
- }
620
- }
621
-
622
- // Extract numeric value from strings with uncertainty notation: "1.23 ± 0.05", "1.23 +- 0.05", "1.23(5)"
623
- function parse_numeric_val(val: CellVal): number | null {
624
- if (typeof val === `number`) return Number.isNaN(val) ? null : val
625
- if (typeof val !== `string`) return null
626
-
627
- // Handle numbers with error notation: "1.23 ± 0.05" or "1.23 +- 0.05" or "1.23(5)"
628
- // Supports: ± (U+00B1), ASCII +-, Unicode minus − (U+2212), with optional whitespace
629
- // Note: [-+−] has hyphen first to avoid regex range interpretation
630
- // Pattern allows leading decimals like .5 or -.5 via (?:\d+\.?\d*|\d*\.\d+)
631
- const error_match = val.match(
632
- /^([-+−]?(?:\d+\.?\d*|\d*\.\d+)(?:[eE][-+−]?\d+)?)\s*(?:±|\+[-−]|\()/,
633
- )
634
- if (error_match) {
635
- // Normalize unicode minus (U+2212) to ASCII hyphen for Number()
636
- const normalized = normalize_unicode_minus(error_match[1])
637
- const num = Number(normalized)
638
- if (!isNaN(num)) return num
639
- }
640
- // Try parsing as a plain number (handles "1.23" strings)
641
- // Also normalize unicode minus for plain numbers
642
- const normalized_val = normalize_unicode_minus(val)
643
- const plain_num = Number(normalized_val)
644
- if (!isNaN(plain_num) && val.trim() !== ``) return plain_num
645
- return null
646
- }
647
-
648
- // Memoize parsed column values to avoid O(N²) re-parsing in calc_color
649
- let parsed_column_values = $derived.by(() => {
650
- const result = new SvelteMap<string, (number | null)[]>()
651
- for (const col of ordered_columns) {
652
- if (col.color_scale === null) continue
653
- const col_id = get_col_id(col)
654
- result.set(col_id, sorted_data.map((row) => parse_numeric_val(row[col_id])))
655
- }
656
- return result
657
- })
658
-
659
- function calc_color(val: CellVal, col: Label) {
660
- if (!show_heatmap || col.color_scale === null) {
661
- return { bg: null, text: null }
662
- }
663
-
664
- // Parse numeric value from strings with uncertainty notation
665
- const numeric_val = parse_numeric_val(val)
666
- if (numeric_val === null) return { bg: null, text: null }
667
-
668
- const col_id = get_col_id(col)
669
- // Use memoized parsed values for the column
670
- const numeric_vals = parsed_column_values.get(col_id) ?? []
671
-
672
- const better = better_overrides.get(col_id) ?? col.better
673
- const scale = (color_scale_overrides.get(col_id) ?? col.color_scale ??
674
- `interpolateViridis`) as Parameters<typeof calc_cell_color>[3]
675
- const color = calc_cell_color(
676
- numeric_val,
677
- numeric_vals,
678
- better,
679
- scale,
680
- col.scale_type || `linear`,
681
- )
682
-
683
- // Recompute text contrast against effective bg (cell bg blended with page bg by opacity).
684
- // Approximation: blend luminances directly; accurate enough for black/white text choice.
685
- if (color.bg && heatmap_opacity < 1) {
686
- const blended_lum = luminance(color.bg) * heatmap_opacity +
687
- page_bg_lum * (1 - heatmap_opacity)
688
- color.text = blended_lum > 0.7 ? `black` : `white`
689
- }
690
- return color
691
- }
692
-
693
- let visible_columns = $derived(
694
- ordered_columns.filter((col) =>
695
- col.visible !== false && !hidden_columns.includes(get_col_id(col))
696
- ),
697
- )
698
-
699
- const sort_indicator = (col: Label, sort_state: SortState) => {
700
- const hide_sort_indicator = col.show_sort_indicator === false ||
701
- col.style?.includes(`--hide-sort-indicator`)
702
- if (hide_sort_indicator) return ``
703
-
704
- const col_id = get_col_id(col)
705
-
706
- // Check multi-sort first
707
- const multi_idx = multi_sort.findIndex((s) => s.column === col_id)
708
- if (multi_idx >= 0) {
709
- const arrow = multi_sort[multi_idx].ascending ? `↓` : `↑`
710
- const badge = multi_sort.length > 1 ? `<sup>${multi_idx + 1}</sup>` : ``
711
- return `<span style="font-size: 0.8em;">${arrow}${badge}</span>`
712
- }
713
-
714
- const is_sorted = sort_state.column === col_id
715
- if (!is_sorted) return ``
716
- // Show indicator only for actively sorted columns.
717
- const arrow = sort_state.ascending ? `↓` : `↑`
718
-
719
- return arrow ? `<span style="font-size: 0.8em;">${arrow}</span>` : ``
720
- }
721
-
722
- // Context menu state for column header right-click
723
- let context_menu_col = $state<string | null>(null)
724
- let context_menu_pos = $state({ x: 0, y: 0 })
725
-
726
- const better_sections = [
727
- {
728
- title: `Gradient direction`,
729
- options: [
730
- { value: `higher`, label: `▲ Higher is better` },
731
- { value: `lower`, label: `▼ Lower is better` },
732
- ],
733
- },
734
- ] as const
735
-
736
- // Row selection using WeakMap-based ID lookup instead of O(n) JSON.stringify comparison
737
- function toggle_row_select(row: RowData) {
738
- const row_id = get_row_id(row)
739
- const idx = selected_rows.findIndex((r) => get_row_id(r) === row_id)
740
- if (idx >= 0) {
741
- selected_rows = selected_rows.filter((_, i) => i !== idx)
742
- } else {
743
- selected_rows = [...selected_rows, row]
744
- }
745
- }
746
-
747
- function is_row_selected(row: RowData): boolean {
748
- const row_id = get_row_id(row)
749
- return selected_rows.some((r) => get_row_id(r) === row_id)
750
- }
751
-
752
- // Select-all: checks if every row on the current page is selected
753
- let all_page_selected = $derived(
754
- paginated_data.length > 0 && paginated_data.every((row) => is_row_selected(row)),
755
- )
756
-
757
- function toggle_select_all() {
758
- if (all_page_selected) {
759
- const page_ids = new Set(paginated_data.map(get_row_id))
760
- selected_rows = selected_rows.filter((row) => !page_ids.has(get_row_id(row)))
761
- } else {
762
- const already = new Set(selected_rows.map(get_row_id))
763
- const new_rows = paginated_data.filter((row) => !already.has(get_row_id(row)))
764
- selected_rows = [...selected_rows, ...new_rows]
765
- }
766
- }
767
-
768
- // Data source for exports: selected rows when any are selected, otherwise all sorted data
769
- let export_rows = $derived(
770
- show_row_select && selected_rows.length > 0 ? selected_rows : sorted_data,
771
- )
772
-
773
- // Serialize table as delimited text (shared by CSV export and clipboard copy)
774
- // Per RFC 4180, fields containing commas, double quotes, or newlines must be quoted
775
- function serialize_table(delimiter: string, csv_quote = false): string {
776
- const quote = (str: string) => {
777
- if (!csv_quote) return str
778
- if (str.includes(`,`) || str.includes(`"`) || str.includes(`\n`)) {
779
- return `"${str.replace(/"/g, `""`)}"`
780
- }
781
- return str
782
- }
783
- const headers = visible_columns.map((col) => quote(strip_html(col.label)))
784
- const rows = export_rows.map((row) =>
785
- visible_columns.map((col) => {
786
- const val = row[get_col_id(col)]
787
- if (val == null) return ``
788
- return quote(strip_html(String(val)))
789
- })
790
- )
791
- return [headers.join(delimiter), ...rows.map((r) => r.join(delimiter))].join(`\n`)
792
- }
793
-
794
- function export_csv(filename = `table-export`) {
795
- download_file(serialize_table(`,`, true), `${filename}.csv`, `text/csv`)
796
- }
797
-
798
- function export_json(filename = `table-export`) {
799
- const rows = export_rows.map((row) => {
800
- const clean_row: Record<string, unknown> = {}
801
- for (const col of visible_columns) {
802
- const col_id = get_col_id(col)
803
- const val = row[col_id]
804
- clean_row[strip_html(col.label)] = typeof val === `string`
805
- ? strip_html(val)
806
- : val
807
- }
808
- return clean_row
809
- })
810
- download_file(
811
- JSON.stringify(rows, null, 2),
812
- `${filename}.json`,
813
- `application/json`,
814
- )
815
- }
816
-
817
- function download_file(content: string, filename: string, mime_type: string) {
818
- const blob = new Blob([content], { type: mime_type })
819
- const url = URL.createObjectURL(blob)
820
- const link = document.createElement(`a`)
821
- link.href = url
822
- link.download = filename
823
- document.body.appendChild(link)
824
- link.click()
825
- document.body.removeChild(link)
826
- URL.revokeObjectURL(url)
827
- }
828
-
829
- function copy_to_clipboard() {
830
- navigator.clipboard.writeText(serialize_table(`\t`))
831
- }
832
-
833
- // Column visibility toggle
834
- function toggle_column(col_id: string) {
835
- if (hidden_columns.includes(col_id)) {
836
- hidden_columns = hidden_columns.filter((id) => id !== col_id)
837
- } else {
838
- hidden_columns = [...hidden_columns, col_id]
839
- }
840
- }
841
-
842
- // Column resize handlers
843
- function start_resize(event: MouseEvent, col: Label) {
844
- event.preventDefault()
845
- event.stopPropagation()
846
- resize_col_id = get_col_id(col)
847
- resize_start_x = event.clientX
848
- const th = event.target instanceof Element ? event.target.parentElement : null
849
- resize_start_width = th?.offsetWidth ?? 100
850
-
851
- document.addEventListener(`mousemove`, handle_resize)
852
- document.addEventListener(`mouseup`, stop_resize)
853
- }
854
-
855
- function handle_resize(event: MouseEvent) {
856
- if (!resize_col_id) return
857
- const delta = event.clientX - resize_start_x
858
- const new_width = Math.min(500, Math.max(50, resize_start_width + delta))
859
- column_widths = { ...column_widths, [resize_col_id]: new_width }
860
- }
861
-
862
- function stop_resize() {
863
- resize_col_id = null
864
- document.removeEventListener(`mousemove`, handle_resize)
865
- document.removeEventListener(`mouseup`, stop_resize)
866
- }
867
-
868
- // Normalize sort_hint to a config object with defaults
869
- let hint_config = $derived(
870
- sort_hint
871
- ? {
872
- position: `bottom` as const,
873
- permanent: false,
874
- ...(typeof sort_hint === `string` ? { text: sort_hint } : sort_hint),
875
- }
876
- : null,
877
- )
878
- </script>
879
-
880
- {#snippet sort_hint_element(pos: `top` | `bottom`)}
881
- {#if hint_config?.position === pos}
882
- <div
883
- class="sort-hint {hint_config.class ?? ``}"
884
- class:permanent={hint_config.permanent}
885
- style={hint_config.style}
886
- >
887
- {hint_config.text}
888
- </div>
889
- {/if}
890
- {/snippet}
891
-
892
- <div
893
- {@attach tooltip()}
894
- {...rest_props}
895
- bind:this={container_el}
896
- class="table-container {rest_props.class ?? ``}"
897
- style:--heatmap-opacity="{heatmap_opacity * 100}%"
898
- onmouseleave={() => {
899
- show_column_dropdown = false
900
- show_export_dropdown = false
901
- context_menu_col = null
902
- }}
903
- >
904
- <!-- Floating control buttons -->
905
- <section class="control-buttons">
906
- {#if search_config}
907
- {#if search_expanded || search_query}
908
- <input
909
- type="search"
910
- class="search-input"
911
- placeholder={search_config.placeholder}
912
- bind:value={search_query}
913
- onblur={() => {
914
- if (!search_query) search_expanded = false
915
- }}
916
- />
917
- <button
918
- class="icon-btn"
919
- onclick={() => {
920
- search_query = ``
921
- search_expanded = false
922
- }}
923
- {@attach tooltip({ content: `Clear`, placement: `top` })}
924
- >
925
- <Icon icon="Cross" style="width: 10px" />
926
- </button>
927
- {:else}
928
- <button
929
- class="icon-btn"
930
- onclick={() => search_expanded = true}
931
- {@attach tooltip({ content: `Search`, placement: `top` })}
932
- >
933
- <Icon icon="Search" style="width: 14px" />
934
- </button>
935
- {/if}
936
- {/if}
937
-
938
- {#if show_column_toggle}
939
- <div class="dropdown-wrapper">
940
- <button
941
- class="icon-btn"
942
- class:active={show_column_dropdown}
943
- onclick={() => show_column_dropdown = !show_column_dropdown}
944
- {@attach tooltip({ content: `Columns`, placement: `top` })}
945
- >
946
- <Icon icon="Columns" style="width: 14px" />
947
- </button>
948
- {#if show_column_dropdown}
949
- <div class="dropdown-pane">
950
- {#each ordered_columns as col (get_col_id(col))}
951
- {@const col_id = get_col_id(col)}
952
- <label class="dropdown-option">
953
- <input
954
- type="checkbox"
955
- checked={!hidden_columns.includes(col_id)}
956
- onchange={() => toggle_column(col_id)}
957
- />
958
- {@html sanitize_html(col.label)}
959
- </label>
960
- {/each}
961
- </div>
962
- {/if}
963
- </div>
964
- {/if}
965
-
966
- {#if export_config}
967
- <div class="dropdown-wrapper">
968
- <button
969
- class="icon-btn"
970
- class:active={show_export_dropdown}
971
- onclick={() => show_export_dropdown = !show_export_dropdown}
972
- {@attach tooltip({ content: `Export`, placement: `top` })}
973
- >
974
- <Icon icon="Export" style="width: 14px" />
975
- </button>
976
- {#if show_export_dropdown}
977
- <div class="dropdown-pane">
978
- {#if export_config.formats.includes(`csv`)}
979
- <button
980
- class="dropdown-option"
981
- onclick={() => {
982
- export_csv(export_config.filename)
983
- show_export_dropdown = false
984
- }}
985
- >
986
- <Icon icon="Download" style="width: 12px" /> CSV
987
- </button>
988
- {/if}
989
- {#if export_config.formats.includes(`json`)}
990
- <button
991
- class="dropdown-option"
992
- onclick={() => {
993
- export_json(export_config.filename)
994
- show_export_dropdown = false
995
- }}
996
- >
997
- <Icon icon="Download" style="width: 12px" /> JSON
998
- </button>
999
- {/if}
1000
- <button
1001
- class="dropdown-option"
1002
- onclick={() => {
1003
- copy_to_clipboard()
1004
- show_export_dropdown = false
1005
- }}
1006
- >
1007
- <Icon icon="Copy" style="width: 12px" /> Copy
1008
- </button>
1009
- </div>
1010
- {/if}
1011
- </div>
1012
- {/if}
1013
-
1014
- {#if show_row_select && selected_rows.length > 0}
1015
- <button
1016
- class="icon-btn selection-badge"
1017
- onclick={() => selected_rows = []}
1018
- title="Clear {selected_rows.length} selected rows"
1019
- >
1020
- <span class="badge">{selected_rows.length}</span>
1021
- <Icon icon="Cross" style="width: 10px" />
1022
- </button>
1023
- {/if}
1024
-
1025
- {#if controls}
1026
- {@render controls()}
1027
- {/if}
1028
- </section>
1029
-
1030
- {#if show_controls}
1031
- <DraggablePane
1032
- bind:show={controls_open}
1033
- closed_icon="Settings"
1034
- open_icon="Cross"
1035
- toggle_props={{
1036
- title: `${controls_open ? `Close` : `Open`} table controls`,
1037
- style: `position: absolute; top: 5pt; right: 1ex; z-index: 10`,
1038
- }}
1039
- pane_props={{ style: `max-height: 60vh; overflow-y: auto; font-size: 0.85em` }}
1040
- >
1041
- <SettingsSection
1042
- title="Heatmap"
1043
- current_values={{ show_heatmap, heatmap_opacity }}
1044
- on_reset={() => {
1045
- show_heatmap = true
1046
- heatmap_opacity = 1
1047
- }}
1048
- >
1049
- <label><input type="checkbox" bind:checked={show_heatmap} /> Show heatmap</label>
1050
- {#if show_heatmap}
1051
- <label>
1052
- Opacity
1053
- <input
1054
- type="range"
1055
- min="0"
1056
- max="1"
1057
- step="0.05"
1058
- bind:value={heatmap_opacity}
1059
- />
1060
- <input
1061
- type="number"
1062
- min="0"
1063
- max="1"
1064
- step="0.05"
1065
- bind:value={heatmap_opacity}
1066
- style="width: 3.5em"
1067
- />
1068
- </label>
1069
- {/if}
1070
- </SettingsSection>
1071
-
1072
- <SettingsSection
1073
- title="Display"
1074
- current_values={{ show_row_numbers }}
1075
- on_reset={() => {
1076
- show_row_numbers = false
1077
- }}
1078
- >
1079
- <label><input type="checkbox" bind:checked={show_row_numbers} /> Row
1080
- numbers</label>
1081
- </SettingsSection>
1082
-
1083
- {#if colored_columns.length > 0}
1084
- <SettingsSection
1085
- title="Column Colors"
1086
- current_values={Object.fromEntries([...better_overrides, ...color_scale_overrides])}
1087
- on_reset={() => {
1088
- better_overrides.clear()
1089
- color_scale_overrides.clear()
1090
- }}
1091
- >
1092
- {#each colored_columns as col (get_col_id(col))}
1093
- {@const col_id = get_col_id(col)}
1094
- <div class="col-color-row">
1095
- <span class="col-color-label">{@html sanitize_html(col.label)}</span>
1096
- <select
1097
- value={color_scale_overrides.get(col_id) ?? col.color_scale ??
1098
- `interpolateViridis`}
1099
- onchange={(event) => {
1100
- const val = event.currentTarget.value
1101
- if (
1102
- val === (col.color_scale ?? `interpolateViridis`)
1103
- ) color_scale_overrides.delete(col_id)
1104
- else color_scale_overrides.set(col_id, val)
1105
- }}
1106
- >
1107
- {#each color_scale_options as scale (scale)}
1108
- <option value={scale}>{scale.replace(`interpolate`, ``)}</option>
1109
- {/each}
1110
- </select>
1111
- <select
1112
- value={better_overrides.get(col_id) ?? col.better ?? ``}
1113
- onchange={(event) => {
1114
- const val = event.currentTarget.value
1115
- if (!val) better_overrides.delete(col_id)
1116
- else better_overrides.set(col_id, val as `higher` | `lower`)
1117
- }}
1118
- >
1119
- <option value="">Default</option>
1120
- <option value="higher">▲ High</option>
1121
- <option value="lower">▼ Low</option>
1122
- </select>
1123
- </div>
1124
- {/each}
1125
- </SettingsSection>
1126
- {/if}
1127
- </DraggablePane>
1128
- {/if}
1129
-
1130
- {@render sort_hint_element(`top`)}
1131
-
1132
- <div
1133
- class="table-scroll"
1134
- style={scroll_style}
1135
- class:has-scroll={scroll_style}
1136
- >
1137
- {#if loading}
1138
- <div class="loading-overlay">
1139
- <div class="loading-spinner"></div>
1140
- </div>
1141
- {/if}
1142
- <table class:fixed-header={fixed_header} class={heatmap_class}>
1143
- <thead>
1144
- <!-- Don't add a table row for group headers if there are none -->
1145
- {#if visible_columns.some((col) => col.group)}
1146
- <!-- First level headers -->
1147
- <tr class="group-header">
1148
- {#if show_row_select}
1149
- <th class="select-col"></th>
1150
- {/if}
1151
- {#if show_row_numbers}
1152
- <th class="row-num-col"></th>
1153
- {/if}
1154
- {#each visible_columns as col (get_col_id(col))}
1155
- {#if !col.group}
1156
- <th class:sticky-col={col.sticky}></th>
1157
- {:else}
1158
- {@const group_cols = visible_columns.filter((c) =>
1159
- c.group === col.group
1160
- )}
1161
- <!-- Only render the group header once for each group by checking if this is the first column of this group -->
1162
- {#if visible_columns.findIndex((c) => c.group === col.group) ===
1163
- visible_columns.findIndex((c) =>
1164
- c.group === col.group && c.label === col.label
1165
- )}
1166
- <th title={col.description} colspan={group_cols.length}>
1167
- {@html sanitize_html(col.group)}
1168
- </th>
1169
- {/if}
1170
- {/if}
1171
- {/each}
1172
- </tr>
1173
- {/if}
1174
- <!-- Second level headers -->
1175
- <tr>
1176
- {#if show_row_select}
1177
- <th
1178
- class="select-col"
1179
- title={all_page_selected ? `Deselect all` : `Select all on this page`}
1180
- >
1181
- <input
1182
- type="checkbox"
1183
- checked={all_page_selected}
1184
- onchange={toggle_select_all}
1185
- />
1186
- </th>
1187
- {/if}
1188
- {#if show_row_numbers}
1189
- <th class="row-num-col">#</th>
1190
- {/if}
1191
- {#each visible_columns as col (get_col_id(col))}
1192
- {@const col_id = get_col_id(col)}
1193
- {@const drag_side = drag_over_col_id === col_id
1194
- ? get_drag_side(col_id)
1195
- : null}
1196
- {@const col_width = column_widths[col_id]}
1197
- <th
1198
- title={col.description}
1199
- tabindex={col.sortable === false ? undefined : 0}
1200
- role={col.sortable === false ? undefined : `button`}
1201
- oncontextmenu={(event) => {
1202
- if (
1203
- !allow_better_toggle || col.color_scale === null ||
1204
- col.color_scale === undefined
1205
- ) return
1206
- event.preventDefault()
1207
- event.stopPropagation()
1208
- context_menu_col = col_id
1209
- const rect = container_el?.getBoundingClientRect()
1210
- context_menu_pos = {
1211
- x: event.clientX - (rect?.left ?? 0),
1212
- y: event.clientY - (rect?.top ?? 0),
1213
- }
1214
- }}
1215
- onclick={(event) => {
1216
- if (!drag_col_id && !resize_col_id) {
1217
- sort_rows(
1218
- col.label,
1219
- col.group,
1220
- event,
1221
- )
1222
- }
1223
- }}
1224
- onkeydown={(event) => {
1225
- if (
1226
- (event.key === `Enter` || event.key === ` `) &&
1227
- !drag_col_id && !resize_col_id
1228
- ) {
1229
- event.preventDefault()
1230
- sort_rows(col.label, col.group, event)
1231
- }
1232
- }}
1233
- style={`${col.style ?? ``}${
1234
- col_width
1235
- ? `; width: ${col_width}px; min-width: ${col_width}px`
1236
- : ``
1237
- }`}
1238
- class:sticky-col={col.sticky}
1239
- class:not-sortable={col.sortable === false}
1240
- class:dragging={drag_col_id === col_id}
1241
- class:resizing={resize_col_id === col_id}
1242
- data-drag-side={drag_side}
1243
- draggable="true"
1244
- aria-dropeffect="move"
1245
- aria-sort={sort_state.column === col_id
1246
- ? (sort_state.ascending ? `ascending` : `descending`)
1247
- : `none`}
1248
- ondragstart={(event: DragEvent & { currentTarget: HTMLElement }) => {
1249
- handle_drag_start(event, col)
1250
- event.currentTarget.setAttribute(`aria-grabbed`, `true`)
1251
- }}
1252
- ondragover={(event) => handle_drag_over(event, col)}
1253
- ondragleave={() => (drag_over_col_id = null)}
1254
- ondrop={(event) => handle_drop(event, col)}
1255
- ondragend={(event: DragEvent & { currentTarget: HTMLElement }) => {
1256
- reset_drag_state()
1257
- event.currentTarget.removeAttribute(`aria-grabbed`)
1258
- }}
1259
- >
1260
- {#if header_cell}
1261
- {@render header_cell({ col })}
1262
- {:else}
1263
- {@html sanitize_html(col.label)}
1264
- {/if}
1265
- {@html sanitize_html(sort_indicator(col, sort_state))}
1266
- <!-- Column resize handle -->
1267
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
1268
- <span
1269
- class="resize-handle"
1270
- onmousedown={(event) => start_resize(event, col)}
1271
- role="separator"
1272
- aria-orientation="vertical"
1273
- aria-valuenow={column_widths[get_col_id(col)] ?? 100}
1274
- aria-valuemin={50}
1275
- aria-valuemax={500}
1276
- ></span>
1277
- </th>
1278
- {/each}
1279
- </tr>
1280
- </thead>
1281
- <tbody>
1282
- {#each paginated_data as row, row_idx (get_row_id(row))}
1283
- {@const row_selected = show_row_select && is_row_selected(row)}
1284
- <tr
1285
- animate:flip={{ duration: 500 }}
1286
- style={row.style}
1287
- class={row.class ?? ``}
1288
- class:selected={row_selected}
1289
- tabindex={onrowclick ? 0 : undefined}
1290
- onclick={onrowclick ? (event) => onrowclick(event, row) : undefined}
1291
- ondblclick={onrowdblclick ? (event) => onrowdblclick(event, row) : undefined}
1292
- onkeydown={onrowclick
1293
- ? (event) => {
1294
- if (event.key === `Enter` || event.key === ` `) {
1295
- event.preventDefault()
1296
- onrowclick(event, row)
1297
- } else if (event.key === `ArrowDown`) {
1298
- event.preventDefault()
1299
- const next = event.currentTarget.nextElementSibling
1300
- if (next instanceof HTMLElement) next.focus()
1301
- } else if (event.key === `ArrowUp`) {
1302
- event.preventDefault()
1303
- const prev = event.currentTarget.previousElementSibling
1304
- if (prev instanceof HTMLElement) prev.focus()
1305
- }
1306
- }
1307
- : undefined}
1308
- >
1309
- {#if show_row_select}
1310
- <td class="select-col">
1311
- <input
1312
- type="checkbox"
1313
- checked={row_selected}
1314
- onchange={() => toggle_row_select(row)}
1315
- />
1316
- </td>
1317
- {/if}
1318
- {#if show_row_numbers}
1319
- <td class="row-num-col">
1320
- {(current_page - 1) * effective_page_size + row_idx + 1}
1321
- </td>
1322
- {/if}
1323
- {#each visible_columns as col (get_col_id(col))}
1324
- {@const val = row[get_col_id(col)]}
1325
- {@const color = calc_color(val, col)}
1326
- {@const col_width = column_widths[get_col_id(col)]}
1327
- <td
1328
- data-col={col.label}
1329
- data-sort-value={is_html_str(val) ? null : val}
1330
- class:sticky-col={col.sticky}
1331
- style:--cell-bg={color.bg}
1332
- style:color={color.text}
1333
- style={`${col.cell_style ?? col.style ?? ``}${
1334
- col_width
1335
- ? `; width: ${col_width}px; max-width: ${col_width}px`
1336
- : ``
1337
- }`}
1338
- >
1339
- {#if special_cells?.[col.label]}
1340
- {@render special_cells[col.label]({ row, col, val })}
1341
- {:else if cell}
1342
- {@render cell({ row, col, val })}
1343
- {:else if typeof val === `number` && !Number.isNaN(val)}
1344
- {format_num(val, col.format ?? default_num_format)}
1345
- {:else if val === undefined || val === null || Number.isNaN(val)}
1346
- <span {@attach tooltip({ content: `Not available` })}>
1347
- n/a
1348
- </span>
1349
- {:else}
1350
- {@html sanitize_html(val)}
1351
- {/if}
1352
- </td>
1353
- {/each}
1354
- </tr>
1355
- {:else}
1356
- {#if empty_message}
1357
- <tr class="empty-row">
1358
- <td
1359
- colspan={visible_columns.length + (show_row_select ? 1 : 0) +
1360
- (show_row_numbers ? 1 : 0)}
1361
- >
1362
- {empty_message}
1363
- </td>
1364
- </tr>
1365
- {/if}
1366
- {/each}
1367
- </tbody>
1368
- {#if footer}
1369
- <tfoot>
1370
- {@render footer()}
1371
- </tfoot>
1372
- {/if}
1373
- </table>
1374
- </div>
1375
-
1376
- {@render sort_hint_element(`bottom`)}
1377
-
1378
- {#if pagination_config && total_pages > 1}
1379
- <div class="pagination">
1380
- <button
1381
- class="page-btn"
1382
- disabled={current_page === 1}
1383
- onclick={() => current_page = 1}
1384
- title="First page"
1385
- >
1386
- «
1387
- </button>
1388
- <button
1389
- class="page-btn"
1390
- disabled={current_page === 1}
1391
- onclick={() => current_page--}
1392
- title="Previous page"
1393
- >
1394
-
1395
- </button>
1396
- <span class="page-info">
1397
- Page
1398
- <input
1399
- type="number"
1400
- class="page-input"
1401
- min="1"
1402
- max={total_pages}
1403
- value={current_page}
1404
- onchange={(event) => {
1405
- const val = parseInt(event.currentTarget.value, 10)
1406
- current_page = Math.max(1, Math.min(total_pages, isNaN(val) ? 1 : val))
1407
- event.currentTarget.value = String(current_page)
1408
- }}
1409
- />
1410
- of {total_pages}
1411
- <span class="row-count">({sorted_data.length} rows)</span>
1412
- </span>
1413
- <button
1414
- class="page-btn"
1415
- disabled={current_page === total_pages}
1416
- onclick={() => current_page++}
1417
- title="Next page"
1418
- >
1419
-
1420
- </button>
1421
- <button
1422
- class="page-btn"
1423
- disabled={current_page === total_pages}
1424
- onclick={() => current_page = total_pages}
1425
- title="Last page"
1426
- >
1427
- »
1428
- </button>
1429
- {#if pagination_config.page_sizes}
1430
- <select
1431
- class="page-size-select"
1432
- onchange={(event) => {
1433
- effective_page_size = parseInt(event.currentTarget.value, 10)
1434
- current_page = 1
1435
- }}
1436
- >
1437
- {#each pagination_config.page_sizes as size (size)}
1438
- <option value={size} selected={size === effective_page_size}>
1439
- {size} / page
1440
- </option>
1441
- {/each}
1442
- </select>
1443
- {/if}
1444
- </div>
1445
- {/if}
1446
-
1447
- <ContextMenu
1448
- sections={better_sections}
1449
- selected_values={{ 'Gradient direction': better_overrides.get(context_menu_col ?? ``) ?? `` }}
1450
- position={context_menu_pos}
1451
- visible={context_menu_col !== null}
1452
- on_close={() => context_menu_col = null}
1453
- style={[
1454
- `--surface-bg: light-dark(#fff, #1e1e1e)`,
1455
- `--border-color: light-dark(rgba(0,0,0,0.15), rgba(255,255,255,0.15))`,
1456
- `--text-color: light-dark(#333, #eee)`,
1457
- `--text-color-muted: light-dark(#888, #999)`,
1458
- `--surface-bg-hover: light-dark(rgba(0,0,0,0.06), rgba(255,255,255,0.1))`,
1459
- `--accent-color: light-dark(rgba(0,0,0,0.1), rgba(255,255,255,0.15))`,
1460
- `z-index: 200`,
1461
- ].join(`; `)}
1462
- on_select={(_, option) => {
1463
- if (!context_menu_col) return
1464
- const current = better_overrides.get(context_menu_col)
1465
- if (current === option.value) better_overrides.delete(context_menu_col)
1466
- else better_overrides.set(context_menu_col, option.value as `higher` | `lower`)
1467
- context_menu_col = null
1468
- }}
1469
- />
1470
- </div>
1471
-
1472
- <style>
1473
- .table-container {
1474
- font-size: var(--heatmap-font-size, 0.9em);
1475
- width: fit-content;
1476
- max-width: 100%;
1477
- max-height: inherit;
1478
- margin: 0 auto;
1479
- position: relative;
1480
- display: flex;
1481
- flex-direction: column;
1482
- }
1483
- .table-scroll {
1484
- position: relative;
1485
- overflow: auto;
1486
- }
1487
- .table-scroll.has-scroll {
1488
- border: 1px solid light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.12));
1489
- border-radius: var(--border-radius, 3pt);
1490
- overflow-x: hidden;
1491
- overflow-y: auto;
1492
- }
1493
- table {
1494
- border-collapse: separate;
1495
- border-spacing: 0;
1496
- display: table; /* Override global display: block to enable sticky headers */
1497
- }
1498
- th, td {
1499
- padding: var(--heatmap-cell-padding, 1pt 5pt);
1500
- text-align: var(--heatmap-text-align, left);
1501
- border: var(--heatmap-cell-border, none);
1502
- white-space: nowrap;
1503
- overflow: hidden;
1504
- text-overflow: ellipsis;
1505
- /* --cell-bg is set inline per-cell by calc_color(); --heatmap-opacity is set
1506
- on the container from the heatmap_opacity prop to fade cell backgrounds */
1507
- background-color: color-mix(
1508
- in srgb,
1509
- var(--cell-bg, transparent) var(--heatmap-opacity, 100%),
1510
- transparent
1511
- );
1512
- }
1513
- th {
1514
- background: var(--heatmap-header-bg, var(--page-bg, Canvas));
1515
- position: sticky;
1516
- top: 0;
1517
- z-index: 2;
1518
- cursor: pointer;
1519
- user-select: none;
1520
- }
1521
- th:hover {
1522
- background: var(--heatmap-header-hover-bg, var(--nav-bg));
1523
- }
1524
- th.dragging {
1525
- opacity: 0.4;
1526
- cursor: grabbing;
1527
- }
1528
- th[data-drag-side='left'] {
1529
- border-left: 4px solid var(--highlight, #4a9eff);
1530
- }
1531
- th[data-drag-side='right'] {
1532
- border-right: 4px solid var(--highlight, #4a9eff);
1533
- }
1534
- th[draggable='true'] {
1535
- cursor: grab;
1536
- }
1537
- th.sticky-col {
1538
- position: sticky;
1539
- left: 0;
1540
- top: 0;
1541
- background: var(--heatmap-header-bg, var(--page-bg, Canvas));
1542
- z-index: 4; /* Higher than regular th (2) to stay above when both scroll */
1543
- border-right: 1px solid var(--border, #ddd);
1544
- }
1545
- td.sticky-col {
1546
- position: sticky;
1547
- left: 0;
1548
- background: var(--page-bg, Canvas);
1549
- z-index: 1;
1550
- border-right: 1px solid var(--border, #ddd);
1551
- }
1552
- tbody tr:hover {
1553
- filter: var(--heatmap-row-hover-filter, brightness(1.1));
1554
- }
1555
- tbody tr[tabindex] {
1556
- cursor: pointer;
1557
- }
1558
- tbody tr:focus-visible {
1559
- outline: 2px solid var(--highlight, #4a9eff);
1560
- outline-offset: -2px;
1561
- }
1562
- td[data-sort-value] {
1563
- cursor: default;
1564
- }
1565
- .group-header th {
1566
- text-align: center;
1567
- border-bottom: 1px solid var(--border);
1568
- }
1569
- /* Sticky cells in group header row need higher z-index to clip scrolling group headers */
1570
- .group-header th.sticky-col {
1571
- z-index: 5;
1572
- }
1573
- /* Floating control buttons above the table */
1574
- .control-buttons {
1575
- display: flex;
1576
- justify-content: flex-end;
1577
- align-items: center;
1578
- gap: 2px;
1579
- margin-bottom: 1px;
1580
- opacity: 0;
1581
- pointer-events: none;
1582
- transition: opacity 0.15s;
1583
- }
1584
- .table-container:hover .control-buttons,
1585
- .control-buttons:focus-within {
1586
- opacity: 1;
1587
- pointer-events: auto;
1588
- }
1589
- .icon-btn {
1590
- padding: 2px 4px;
1591
- border: none;
1592
- border-radius: 3px;
1593
- background: light-dark(rgba(0, 0, 0, 0.06), rgba(255, 255, 255, 0.1));
1594
- color: light-dark(#333, #ddd);
1595
- cursor: pointer;
1596
- display: flex;
1597
- align-items: center;
1598
- justify-content: center;
1599
- gap: 2px;
1600
- font-size: 0.8em;
1601
- }
1602
- .icon-btn :global(svg) {
1603
- width: 12px;
1604
- height: 12px;
1605
- }
1606
- .icon-btn:hover {
1607
- background: light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.2));
1608
- }
1609
- .icon-btn.active {
1610
- background: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.25));
1611
- }
1612
- .selection-badge {
1613
- position: relative;
1614
- }
1615
- .selection-badge .badge {
1616
- background: var(--highlight, #4a9eff);
1617
- color: white;
1618
- font-size: 0.7em;
1619
- padding: 1px 4px;
1620
- border-radius: 8px;
1621
- min-width: 14px;
1622
- text-align: center;
1623
- }
1624
- .dropdown-wrapper {
1625
- position: relative;
1626
- }
1627
- .dropdown-pane {
1628
- position: absolute;
1629
- top: 100%;
1630
- right: 0;
1631
- margin-top: 4px;
1632
- padding: 4px 0;
1633
- background: light-dark(rgba(255, 255, 255, 0.98), rgba(30, 30, 30, 0.98));
1634
- border: 1px solid light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.15));
1635
- border-radius: 6px;
1636
- box-shadow: 0 4px 12px light-dark(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.4));
1637
- max-height: 280px;
1638
- overflow-y: auto;
1639
- z-index: 100;
1640
- color: light-dark(#333, #eee);
1641
- font-size: 0.95em;
1642
- }
1643
- .dropdown-option {
1644
- display: flex;
1645
- align-items: center;
1646
- gap: 8px;
1647
- padding: 3px 6px;
1648
- cursor: pointer;
1649
- font-size: 0.95em;
1650
- white-space: nowrap;
1651
- background: transparent;
1652
- border: none;
1653
- color: inherit;
1654
- width: 100%;
1655
- text-align: left;
1656
- }
1657
- .dropdown-option:hover {
1658
- background: light-dark(rgba(0, 0, 0, 0.06), rgba(255, 255, 255, 0.1));
1659
- }
1660
- /* Column toggle labels - more compact */
1661
- label.dropdown-option {
1662
- padding: 4px 10px;
1663
- gap: 6px;
1664
- }
1665
- .search-input {
1666
- padding: 2px 4px;
1667
- border: 1px solid light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.2));
1668
- border-radius: 3px;
1669
- background: light-dark(rgba(255, 255, 255, 0.9), rgba(0, 0, 0, 0.3));
1670
- color: light-dark(#333, #eee);
1671
- font-size: 0.8em;
1672
- width: 110px;
1673
- box-sizing: border-box;
1674
- }
1675
- .search-input:focus {
1676
- outline: 1px solid var(--highlight, #4a9eff);
1677
- }
1678
- .search-input::placeholder {
1679
- color: light-dark(#999, #666);
1680
- }
1681
- .sort-hint {
1682
- text-align: center;
1683
- font-size: 0.75em;
1684
- color: var(--text-muted);
1685
- padding: 4px 0;
1686
- opacity: 0;
1687
- transition: opacity 0.15s;
1688
- }
1689
- .table-container:hover .sort-hint,
1690
- .sort-hint.permanent {
1691
- opacity: 1;
1692
- }
1693
- .not-sortable {
1694
- cursor: default;
1695
- }
1696
- tr.highlight {
1697
- background-color: var(--nav-bg) !important;
1698
- }
1699
- tr.highlight, tr.highlight :global(a) {
1700
- color: var(--highlight) !important;
1701
- }
1702
-
1703
- /* Row selection */
1704
- .select-col {
1705
- width: 30px;
1706
- text-align: center;
1707
- vertical-align: middle;
1708
- padding: 2px !important;
1709
- }
1710
- .select-col :global(svg) {
1711
- display: block;
1712
- margin: auto;
1713
- }
1714
- tr.selected {
1715
- background: var(--highlight-bg, rgba(74, 158, 255, 0.15)) !important;
1716
- }
1717
- tr.selected td {
1718
- border-top: 1px solid var(--highlight, #4a9eff);
1719
- border-bottom: 1px solid var(--highlight, #4a9eff);
1720
- }
1721
- /* Pagination */
1722
- .pagination {
1723
- display: flex;
1724
- align-items: center;
1725
- justify-content: center;
1726
- gap: 8px;
1727
- margin-top: 12px;
1728
- padding-top: 12px;
1729
- border-top: 1px solid var(--border);
1730
- }
1731
- .page-btn {
1732
- padding: 4px 10px;
1733
- border: 1px solid var(--border, #444);
1734
- border-radius: 4px;
1735
- background: var(--page-bg, Canvas);
1736
- color: inherit;
1737
- cursor: pointer;
1738
- font-size: 1em;
1739
- }
1740
- .page-btn:hover:not(:disabled) {
1741
- background: var(--nav-bg, #333);
1742
- }
1743
- .page-btn:disabled {
1744
- opacity: 0.4;
1745
- cursor: not-allowed;
1746
- }
1747
- .page-info {
1748
- font-size: 0.9em;
1749
- display: flex;
1750
- align-items: center;
1751
- gap: 4px;
1752
- }
1753
- .page-input {
1754
- min-width: 1em !important; /* Override global min-width: 40px from app.css */
1755
- padding: 2px 4px;
1756
- border: 1px solid light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
1757
- border-radius: 3px;
1758
- background: light-dark(#fff, #333);
1759
- color: inherit;
1760
- font-size: inherit;
1761
- text-align: center;
1762
- -moz-appearance: textfield;
1763
- appearance: textfield;
1764
- }
1765
- .page-input::-webkit-outer-spin-button,
1766
- .page-input::-webkit-inner-spin-button {
1767
- -webkit-appearance: none;
1768
- appearance: none;
1769
- margin: 0;
1770
- }
1771
- .page-input:focus {
1772
- outline: 1px solid var(--highlight, #4a9eff);
1773
- }
1774
- .row-count {
1775
- color: var(--text-muted);
1776
- font-size: 0.85em;
1777
- }
1778
-
1779
- .col-color-row {
1780
- display: flex;
1781
- align-items: center;
1782
- gap: 4px;
1783
- padding: 2px 0;
1784
- select {
1785
- font-size: 0.85em;
1786
- padding: 1px 2px;
1787
- }
1788
- }
1789
- .col-color-label {
1790
- flex: 1;
1791
- overflow: hidden;
1792
- text-overflow: ellipsis;
1793
- white-space: nowrap;
1794
- min-width: 0;
1795
- }
1796
- /* Column resize */
1797
- .resize-handle {
1798
- position: absolute;
1799
- right: 0;
1800
- top: 0;
1801
- bottom: 0;
1802
- width: 4px;
1803
- cursor: col-resize;
1804
- background: transparent;
1805
- }
1806
- .resize-handle:hover,
1807
- th.resizing .resize-handle {
1808
- background: var(--highlight, #4a9eff);
1809
- }
1810
- /* Loading overlay */
1811
- .loading-overlay {
1812
- position: absolute;
1813
- inset: 0;
1814
- background: light-dark(rgba(255, 255, 255, 0.7), rgba(0, 0, 0, 0.5));
1815
- display: flex;
1816
- align-items: center;
1817
- justify-content: center;
1818
- z-index: 10;
1819
- }
1820
- .loading-spinner {
1821
- width: 24px;
1822
- height: 24px;
1823
- border: 3px solid light-dark(#e5e7eb, #444);
1824
- border-top-color: var(--highlight, #3b82f6);
1825
- border-radius: 50%;
1826
- animation: spin 0.8s linear infinite;
1827
- }
1828
- @keyframes spin {
1829
- to {
1830
- transform: rotate(360deg);
1831
- }
1832
- }
1833
- .empty-row td {
1834
- text-align: center;
1835
- padding: 2em !important;
1836
- color: var(--text-muted, #888);
1837
- font-style: italic;
1838
- }
1839
- .row-num-col {
1840
- text-align: right;
1841
- color: var(--text-muted, #888);
1842
- font-size: 0.85em;
1843
- width: 2em;
1844
- padding-right: 8px !important;
1845
- }
1846
- .page-size-select {
1847
- padding: 2px 4px;
1848
- border: 1px solid light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
1849
- border-radius: 3px;
1850
- background: light-dark(#fff, #333);
1851
- color: inherit;
1852
- font-size: 0.9em;
1853
- }
1854
- </style>