react-cheminfo 0.69.0 → 0.71.0

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 (616) hide show
  1. package/README.md +70 -2
  2. package/lib/about/core/providers.d.ts +6 -0
  3. package/lib/about/core/providers.d.ts.map +1 -1
  4. package/lib/about/core/providers.js +7 -0
  5. package/lib/about/core/providers.js.map +1 -1
  6. package/lib/about/ui/AboutProvidedBy.js +34 -0
  7. package/lib/about/ui/AboutProvidedBy.js.map +1 -1
  8. package/lib/chart/ui/useChartPointer.d.ts +9 -1
  9. package/lib/chart/ui/useChartPointer.d.ts.map +1 -1
  10. package/lib/chart/ui/useChartPointer.js +11 -3
  11. package/lib/chart/ui/useChartPointer.js.map +1 -1
  12. package/lib/credits/core/credits.d.ts +41 -0
  13. package/lib/credits/core/credits.d.ts.map +1 -1
  14. package/lib/credits/core/credits.js +50 -0
  15. package/lib/credits/core/credits.js.map +1 -1
  16. package/lib/download/core/drawingMarkup.d.ts +8 -1
  17. package/lib/download/core/drawingMarkup.d.ts.map +1 -1
  18. package/lib/download/core/drawingMarkup.js +13 -1
  19. package/lib/download/core/drawingMarkup.js.map +1 -1
  20. package/lib/download/core/figurePng.d.ts +14 -0
  21. package/lib/download/core/figurePng.d.ts.map +1 -1
  22. package/lib/download/core/figurePng.js +21 -6
  23. package/lib/download/core/figurePng.js.map +1 -1
  24. package/lib/download/core/figureSvg.d.ts.map +1 -1
  25. package/lib/download/core/figureSvg.js +5 -3
  26. package/lib/download/core/figureSvg.js.map +1 -1
  27. package/lib/download/core/figureTarget.d.ts +13 -0
  28. package/lib/download/core/figureTarget.d.ts.map +1 -1
  29. package/lib/download/core/figureTarget.js +25 -5
  30. package/lib/download/core/figureTarget.js.map +1 -1
  31. package/lib/download/core/svgBounds.d.ts +15 -0
  32. package/lib/download/core/svgBounds.d.ts.map +1 -1
  33. package/lib/download/core/svgBounds.js +20 -0
  34. package/lib/download/core/svgBounds.js.map +1 -1
  35. package/lib/download/core/svgToPng.d.ts.map +1 -1
  36. package/lib/download/core/svgToPng.js +4 -2
  37. package/lib/download/core/svgToPng.js.map +1 -1
  38. package/lib/format/core/relativeTime.d.ts +8 -3
  39. package/lib/format/core/relativeTime.d.ts.map +1 -1
  40. package/lib/format/core/relativeTime.js +19 -7
  41. package/lib/format/core/relativeTime.js.map +1 -1
  42. package/lib/host/core/connectHost.d.ts +25 -34
  43. package/lib/host/core/connectHost.d.ts.map +1 -1
  44. package/lib/host/core/connectHost.js +43 -89
  45. package/lib/host/core/connectHost.js.map +1 -1
  46. package/lib/host/core/hostOutputs.d.ts +58 -0
  47. package/lib/host/core/hostOutputs.d.ts.map +1 -0
  48. package/lib/host/core/hostOutputs.js +151 -0
  49. package/lib/host/core/hostOutputs.js.map +1 -0
  50. package/lib/host/core/index.d.ts +9 -3
  51. package/lib/host/core/index.d.ts.map +1 -1
  52. package/lib/host/core/index.js +4 -1
  53. package/lib/host/core/index.js.map +1 -1
  54. package/lib/host/core/irKinds.d.ts +124 -0
  55. package/lib/host/core/irKinds.d.ts.map +1 -0
  56. package/lib/host/core/irKinds.js +46 -0
  57. package/lib/host/core/irKinds.js.map +1 -0
  58. package/lib/host/core/kinds.d.ts +13 -5
  59. package/lib/host/core/kinds.d.ts.map +1 -1
  60. package/lib/host/core/kinds.js +11 -5
  61. package/lib/host/core/kinds.js.map +1 -1
  62. package/lib/host/core/protocol.d.ts +50 -7
  63. package/lib/host/core/protocol.d.ts.map +1 -1
  64. package/lib/host/core/protocol.js +10 -6
  65. package/lib/host/core/protocol.js.map +1 -1
  66. package/lib/host/core/selectInputs.d.ts +37 -0
  67. package/lib/host/core/selectInputs.d.ts.map +1 -0
  68. package/lib/host/core/selectInputs.js +110 -0
  69. package/lib/host/core/selectInputs.js.map +1 -0
  70. package/lib/host/testing/sciPeaks.d.ts +31 -0
  71. package/lib/host/testing/sciPeaks.d.ts.map +1 -1
  72. package/lib/host/testing/sciPeaks.js +73 -0
  73. package/lib/host/testing/sciPeaks.js.map +1 -1
  74. package/lib/host/testing/standInHost.d.ts +9 -1
  75. package/lib/host/testing/standInHost.d.ts.map +1 -1
  76. package/lib/host/testing/standInHost.js +19 -1
  77. package/lib/host/testing/standInHost.js.map +1 -1
  78. package/lib/host/ui/useHostConnection.d.ts +13 -5
  79. package/lib/host/ui/useHostConnection.d.ts.map +1 -1
  80. package/lib/host/ui/useHostConnection.js +4 -3
  81. package/lib/host/ui/useHostConnection.js.map +1 -1
  82. package/lib/host-testing.d.ts +2 -2
  83. package/lib/host-testing.d.ts.map +1 -1
  84. package/lib/host-testing.js +2 -2
  85. package/lib/host-testing.js.map +1 -1
  86. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  87. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  88. package/lib/ir/core/handPicking.d.ts +58 -0
  89. package/lib/ir/core/handPicking.d.ts.map +1 -0
  90. package/lib/ir/core/handPicking.js +130 -0
  91. package/lib/ir/core/handPicking.js.map +1 -0
  92. package/lib/ir/core/index.d.ts +3 -0
  93. package/lib/ir/core/index.d.ts.map +1 -1
  94. package/lib/ir/core/index.js +3 -0
  95. package/lib/ir/core/index.js.map +1 -1
  96. package/lib/ir/core/irBandState.d.ts +57 -0
  97. package/lib/ir/core/irBandState.d.ts.map +1 -0
  98. package/lib/ir/core/irBandState.js +119 -0
  99. package/lib/ir/core/irBandState.js.map +1 -0
  100. package/lib/ir/core/irCommands.d.ts +11 -0
  101. package/lib/ir/core/irCommands.d.ts.map +1 -1
  102. package/lib/ir/core/irCommands.js +6 -0
  103. package/lib/ir/core/irCommands.js.map +1 -1
  104. package/lib/ir/core/irPeaks.d.ts +28 -0
  105. package/lib/ir/core/irPeaks.d.ts.map +1 -0
  106. package/lib/ir/core/irPeaks.js +66 -0
  107. package/lib/ir/core/irPeaks.js.map +1 -0
  108. package/lib/ir/core/irReducer.d.ts +8 -0
  109. package/lib/ir/core/irReducer.d.ts.map +1 -1
  110. package/lib/ir/core/irReducer.js +15 -32
  111. package/lib/ir/core/irReducer.js.map +1 -1
  112. package/lib/ir/core/irSpectrum.d.ts +15 -0
  113. package/lib/ir/core/irSpectrum.d.ts.map +1 -1
  114. package/lib/ir/core/irSpectrum.js.map +1 -1
  115. package/lib/ir/core/irState.d.ts +9 -6
  116. package/lib/ir/core/irState.d.ts.map +1 -1
  117. package/lib/ir/core/irState.js +10 -6
  118. package/lib/ir/core/irState.js.map +1 -1
  119. package/lib/ir/core/pickBands.d.ts +14 -0
  120. package/lib/ir/core/pickBands.d.ts.map +1 -1
  121. package/lib/ir/core/pickBands.js +39 -33
  122. package/lib/ir/core/pickBands.js.map +1 -1
  123. package/lib/ir/core/ramanBands.d.ts +9 -1
  124. package/lib/ir/core/ramanBands.d.ts.map +1 -1
  125. package/lib/ir/core/ramanBands.js +2 -2
  126. package/lib/ir/core/ramanBands.js.map +1 -1
  127. package/lib/ir/core/spectrumBands.d.ts +46 -0
  128. package/lib/ir/core/spectrumBands.d.ts.map +1 -0
  129. package/lib/ir/core/spectrumBands.js +98 -0
  130. package/lib/ir/core/spectrumBands.js.map +1 -0
  131. package/lib/ir/ui/BandRow.d.ts +5 -0
  132. package/lib/ir/ui/BandRow.d.ts.map +1 -1
  133. package/lib/ir/ui/BandRow.js +4 -3
  134. package/lib/ir/ui/BandRow.js.map +1 -1
  135. package/lib/ir/ui/BandsPanel.d.ts +5 -0
  136. package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
  137. package/lib/ir/ui/BandsPanel.js +36 -16
  138. package/lib/ir/ui/BandsPanel.js.map +1 -1
  139. package/lib/ir/ui/BandsToolbar.d.ts +9 -0
  140. package/lib/ir/ui/BandsToolbar.d.ts.map +1 -0
  141. package/lib/ir/ui/BandsToolbar.js +61 -0
  142. package/lib/ir/ui/BandsToolbar.js.map +1 -0
  143. package/lib/ir/ui/IrCanvas.d.ts +2 -1
  144. package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
  145. package/lib/ir/ui/IrCanvas.js +19 -5
  146. package/lib/ir/ui/IrCanvas.js.map +1 -1
  147. package/lib/ir/ui/IrChart.d.ts.map +1 -1
  148. package/lib/ir/ui/IrChart.js +8 -1
  149. package/lib/ir/ui/IrChart.js.map +1 -1
  150. package/lib/ir/ui/IrDocumentationDialog.js +1 -1
  151. package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
  152. package/lib/ir/ui/IrEditor.d.ts +4 -2
  153. package/lib/ir/ui/IrEditor.d.ts.map +1 -1
  154. package/lib/ir/ui/IrEditor.js.map +1 -1
  155. package/lib/ir/ui/IrShell.d.ts.map +1 -1
  156. package/lib/ir/ui/IrShell.js +6 -0
  157. package/lib/ir/ui/IrShell.js.map +1 -1
  158. package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
  159. package/lib/ir/ui/IrStatusBar.js +1 -1
  160. package/lib/ir/ui/IrStatusBar.js.map +1 -1
  161. package/lib/ir/ui/IrToolbar.d.ts +4 -3
  162. package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
  163. package/lib/ir/ui/IrToolbar.js +5 -4
  164. package/lib/ir/ui/IrToolbar.js.map +1 -1
  165. package/lib/ir/ui/VibrationalEditor.d.ts +2 -1
  166. package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -1
  167. package/lib/ir/ui/VibrationalEditor.js.map +1 -1
  168. package/lib/ir/ui/irActions.d.ts +5 -0
  169. package/lib/ir/ui/irActions.d.ts.map +1 -1
  170. package/lib/ir/ui/irActions.js +6 -0
  171. package/lib/ir/ui/irActions.js.map +1 -1
  172. package/lib/ir/ui/irChartProps.d.ts +4 -1
  173. package/lib/ir/ui/irChartProps.d.ts.map +1 -1
  174. package/lib/ir/ui/useIrEditor.d.ts +5 -11
  175. package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
  176. package/lib/ir/ui/useIrEditor.js +17 -18
  177. package/lib/ir/ui/useIrEditor.js.map +1 -1
  178. package/lib/locales/de.json +63 -0
  179. package/lib/locales/en.json +63 -0
  180. package/lib/locales/es.json +63 -0
  181. package/lib/locales/fr.json +63 -0
  182. package/lib/locales/it.json +63 -0
  183. package/lib/mass/core/analyseSpectrum.d.ts +85 -0
  184. package/lib/mass/core/analyseSpectrum.d.ts.map +1 -0
  185. package/lib/mass/core/analyseSpectrum.js +101 -0
  186. package/lib/mass/core/analyseSpectrum.js.map +1 -0
  187. package/lib/mass/core/ascendingTrace.d.ts +24 -0
  188. package/lib/mass/core/ascendingTrace.d.ts.map +1 -0
  189. package/lib/mass/core/ascendingTrace.js +57 -0
  190. package/lib/mass/core/ascendingTrace.js.map +1 -0
  191. package/lib/mass/core/centroidPeaks.d.ts +77 -0
  192. package/lib/mass/core/centroidPeaks.d.ts.map +1 -0
  193. package/lib/mass/core/centroidPeaks.js +62 -0
  194. package/lib/mass/core/centroidPeaks.js.map +1 -0
  195. package/lib/mass/core/detectMassFormat.d.ts +24 -0
  196. package/lib/mass/core/detectMassFormat.d.ts.map +1 -0
  197. package/lib/mass/core/detectMassFormat.js +105 -0
  198. package/lib/mass/core/detectMassFormat.js.map +1 -0
  199. package/lib/mass/core/downloadSpectra.d.ts +24 -0
  200. package/lib/mass/core/downloadSpectra.d.ts.map +1 -0
  201. package/lib/mass/core/downloadSpectra.js +35 -0
  202. package/lib/mass/core/downloadSpectra.js.map +1 -0
  203. package/lib/mass/core/fromJcamp.d.ts +46 -0
  204. package/lib/mass/core/fromJcamp.d.ts.map +1 -0
  205. package/lib/mass/core/fromJcamp.js +123 -0
  206. package/lib/mass/core/fromJcamp.js.map +1 -0
  207. package/lib/mass/core/fromText.d.ts +30 -0
  208. package/lib/mass/core/fromText.d.ts.map +1 -0
  209. package/lib/mass/core/fromText.js +39 -0
  210. package/lib/mass/core/fromText.js.map +1 -0
  211. package/lib/mass/core/index.d.ts +70 -0
  212. package/lib/mass/core/index.d.ts.map +1 -0
  213. package/lib/mass/core/index.js +42 -0
  214. package/lib/mass/core/index.js.map +1 -0
  215. package/lib/mass/core/jcampTechnique.d.ts +38 -0
  216. package/lib/mass/core/jcampTechnique.d.ts.map +1 -0
  217. package/lib/mass/core/jcampTechnique.js +70 -0
  218. package/lib/mass/core/jcampTechnique.js.map +1 -0
  219. package/lib/mass/core/labelStackBox.d.ts +49 -0
  220. package/lib/mass/core/labelStackBox.d.ts.map +1 -0
  221. package/lib/mass/core/labelStackBox.js +44 -0
  222. package/lib/mass/core/labelStackBox.js.map +1 -0
  223. package/lib/mass/core/labelledPeaks.d.ts +79 -0
  224. package/lib/mass/core/labelledPeaks.d.ts.map +1 -0
  225. package/lib/mass/core/labelledPeaks.js +74 -0
  226. package/lib/mass/core/labelledPeaks.js.map +1 -0
  227. package/lib/mass/core/loadMassSpectra.d.ts +57 -0
  228. package/lib/mass/core/loadMassSpectra.d.ts.map +1 -0
  229. package/lib/mass/core/loadMassSpectra.js +45 -0
  230. package/lib/mass/core/loadMassSpectra.js.map +1 -0
  231. package/lib/mass/core/loadedMassSpectrum.d.ts +42 -0
  232. package/lib/mass/core/loadedMassSpectrum.d.ts.map +1 -0
  233. package/lib/mass/core/loadedMassSpectrum.js +15 -0
  234. package/lib/mass/core/loadedMassSpectrum.js.map +1 -0
  235. package/lib/mass/core/massCommands.d.ts +170 -0
  236. package/lib/mass/core/massCommands.d.ts.map +1 -0
  237. package/lib/mass/core/massCommands.js +95 -0
  238. package/lib/mass/core/massCommands.js.map +1 -0
  239. package/lib/mass/core/massDomain.d.ts +121 -0
  240. package/lib/mass/core/massDomain.d.ts.map +1 -0
  241. package/lib/mass/core/massDomain.js +179 -0
  242. package/lib/mass/core/massDomain.js.map +1 -0
  243. package/lib/mass/core/massEditorApi.d.ts +65 -0
  244. package/lib/mass/core/massEditorApi.d.ts.map +1 -0
  245. package/lib/mass/core/massEditorApi.js +10 -0
  246. package/lib/mass/core/massEditorApi.js.map +1 -0
  247. package/lib/mass/core/massFormat.d.ts +78 -0
  248. package/lib/mass/core/massFormat.d.ts.map +1 -0
  249. package/lib/mass/core/massFormat.js +168 -0
  250. package/lib/mass/core/massFormat.js.map +1 -0
  251. package/lib/mass/core/massMeta.d.ts +85 -0
  252. package/lib/mass/core/massMeta.d.ts.map +1 -0
  253. package/lib/mass/core/massMeta.js +182 -0
  254. package/lib/mass/core/massMeta.js.map +1 -0
  255. package/lib/mass/core/massReducer.d.ts +82 -0
  256. package/lib/mass/core/massReducer.d.ts.map +1 -0
  257. package/lib/mass/core/massReducer.js +163 -0
  258. package/lib/mass/core/massReducer.js.map +1 -0
  259. package/lib/mass/core/massResolution.d.ts +92 -0
  260. package/lib/mass/core/massResolution.d.ts.map +1 -0
  261. package/lib/mass/core/massResolution.js +126 -0
  262. package/lib/mass/core/massResolution.js.map +1 -0
  263. package/lib/mass/core/massSidePanels.d.ts +28 -0
  264. package/lib/mass/core/massSidePanels.d.ts.map +1 -0
  265. package/lib/mass/core/massSidePanels.js +12 -0
  266. package/lib/mass/core/massSidePanels.js.map +1 -0
  267. package/lib/mass/core/massSpectrum.d.ts +206 -0
  268. package/lib/mass/core/massSpectrum.d.ts.map +1 -0
  269. package/lib/mass/core/massSpectrum.js +41 -0
  270. package/lib/mass/core/massSpectrum.js.map +1 -0
  271. package/lib/mass/core/massState.d.ts +145 -0
  272. package/lib/mass/core/massState.d.ts.map +1 -0
  273. package/lib/mass/core/massState.js +102 -0
  274. package/lib/mass/core/massState.js.map +1 -0
  275. package/lib/mass/core/massStateEdits.d.ts +51 -0
  276. package/lib/mass/core/massStateEdits.d.ts.map +1 -0
  277. package/lib/mass/core/massStateEdits.js +90 -0
  278. package/lib/mass/core/massStateEdits.js.map +1 -0
  279. package/lib/mass/core/massSummary.d.ts +77 -0
  280. package/lib/mass/core/massSummary.d.ts.map +1 -0
  281. package/lib/mass/core/massSummary.js +174 -0
  282. package/lib/mass/core/massSummary.js.map +1 -0
  283. package/lib/mass/core/mzDecimalsSetting.d.ts +36 -0
  284. package/lib/mass/core/mzDecimalsSetting.d.ts.map +1 -0
  285. package/lib/mass/core/mzDecimalsSetting.js +42 -0
  286. package/lib/mass/core/mzDecimalsSetting.js.map +1 -0
  287. package/lib/mass/core/nearestPeak.d.ts +75 -0
  288. package/lib/mass/core/nearestPeak.d.ts.map +1 -0
  289. package/lib/mass/core/nearestPeak.js +99 -0
  290. package/lib/mass/core/nearestPeak.js.map +1 -0
  291. package/lib/mass/core/peakLabelLines.d.ts +77 -0
  292. package/lib/mass/core/peakLabelLines.d.ts.map +1 -0
  293. package/lib/mass/core/peakLabelLines.js +54 -0
  294. package/lib/mass/core/peakLabelLines.js.map +1 -0
  295. package/lib/mass/core/peakLabelPlan.d.ts +109 -0
  296. package/lib/mass/core/peakLabelPlan.d.ts.map +1 -0
  297. package/lib/mass/core/peakLabelPlan.js +143 -0
  298. package/lib/mass/core/peakLabelPlan.js.map +1 -0
  299. package/lib/mass/core/peakTable.d.ts +54 -0
  300. package/lib/mass/core/peakTable.d.ts.map +1 -0
  301. package/lib/mass/core/peakTable.js +53 -0
  302. package/lib/mass/core/peakTable.js.map +1 -0
  303. package/lib/mass/core/resolutionOf.d.ts +60 -0
  304. package/lib/mass/core/resolutionOf.d.ts.map +1 -0
  305. package/lib/mass/core/resolutionOf.js +84 -0
  306. package/lib/mass/core/resolutionOf.js.map +1 -0
  307. package/lib/mass/core/scanFilter.d.ts +25 -0
  308. package/lib/mass/core/scanFilter.d.ts.map +1 -0
  309. package/lib/mass/core/scanFilter.js +107 -0
  310. package/lib/mass/core/scanFilter.js.map +1 -0
  311. package/lib/mass/core/spectrumJcamp.d.ts +47 -0
  312. package/lib/mass/core/spectrumJcamp.d.ts.map +1 -0
  313. package/lib/mass/core/spectrumJcamp.js +167 -0
  314. package/lib/mass/core/spectrumJcamp.js.map +1 -0
  315. package/lib/mass/core/toMassSpectrum.d.ts +67 -0
  316. package/lib/mass/core/toMassSpectrum.d.ts.map +1 -0
  317. package/lib/mass/core/toMassSpectrum.js +78 -0
  318. package/lib/mass/core/toMassSpectrum.js.map +1 -0
  319. package/lib/mass/core/traceIcon.d.ts +82 -0
  320. package/lib/mass/core/traceIcon.d.ts.map +1 -0
  321. package/lib/mass/core/traceIcon.js +66 -0
  322. package/lib/mass/core/traceIcon.js.map +1 -0
  323. package/lib/mass/core/writtenResolution.d.ts +40 -0
  324. package/lib/mass/core/writtenResolution.d.ts.map +1 -0
  325. package/lib/mass/core/writtenResolution.js +77 -0
  326. package/lib/mass/core/writtenResolution.js.map +1 -0
  327. package/lib/mass/ui/MassAboutDialog.d.ts +16 -0
  328. package/lib/mass/ui/MassAboutDialog.d.ts.map +1 -0
  329. package/lib/mass/ui/MassAboutDialog.js +44 -0
  330. package/lib/mass/ui/MassAboutDialog.js.map +1 -0
  331. package/lib/mass/ui/MassCanvas.d.ts +46 -0
  332. package/lib/mass/ui/MassCanvas.d.ts.map +1 -0
  333. package/lib/mass/ui/MassCanvas.js +84 -0
  334. package/lib/mass/ui/MassCanvas.js.map +1 -0
  335. package/lib/mass/ui/MassChart.d.ts +21 -0
  336. package/lib/mass/ui/MassChart.d.ts.map +1 -0
  337. package/lib/mass/ui/MassChart.js +139 -0
  338. package/lib/mass/ui/MassChart.js.map +1 -0
  339. package/lib/mass/ui/MassCommandProvider.d.ts +15 -0
  340. package/lib/mass/ui/MassCommandProvider.d.ts.map +1 -0
  341. package/lib/mass/ui/MassCommandProvider.js +14 -0
  342. package/lib/mass/ui/MassCommandProvider.js.map +1 -0
  343. package/lib/mass/ui/MassCommandTooltip.d.ts +16 -0
  344. package/lib/mass/ui/MassCommandTooltip.d.ts.map +1 -0
  345. package/lib/mass/ui/MassCommandTooltip.js +22 -0
  346. package/lib/mass/ui/MassCommandTooltip.js.map +1 -0
  347. package/lib/mass/ui/MassDocumentationDialog.d.ts +18 -0
  348. package/lib/mass/ui/MassDocumentationDialog.d.ts.map +1 -0
  349. package/lib/mass/ui/MassDocumentationDialog.js +70 -0
  350. package/lib/mass/ui/MassDocumentationDialog.js.map +1 -0
  351. package/lib/mass/ui/MassEditor.d.ts +78 -0
  352. package/lib/mass/ui/MassEditor.d.ts.map +1 -0
  353. package/lib/mass/ui/MassEditor.js +42 -0
  354. package/lib/mass/ui/MassEditor.js.map +1 -0
  355. package/lib/mass/ui/MassHeader.d.ts +12 -0
  356. package/lib/mass/ui/MassHeader.d.ts.map +1 -0
  357. package/lib/mass/ui/MassHeader.js +20 -0
  358. package/lib/mass/ui/MassHeader.js.map +1 -0
  359. package/lib/mass/ui/MassLogo.d.ts +21 -0
  360. package/lib/mass/ui/MassLogo.d.ts.map +1 -0
  361. package/lib/mass/ui/MassLogo.js +36 -0
  362. package/lib/mass/ui/MassLogo.js.map +1 -0
  363. package/lib/mass/ui/MassPointerTracker.d.ts +44 -0
  364. package/lib/mass/ui/MassPointerTracker.d.ts.map +1 -0
  365. package/lib/mass/ui/MassPointerTracker.js +29 -0
  366. package/lib/mass/ui/MassPointerTracker.js.map +1 -0
  367. package/lib/mass/ui/MassShell.d.ts +29 -0
  368. package/lib/mass/ui/MassShell.d.ts.map +1 -0
  369. package/lib/mass/ui/MassShell.js +133 -0
  370. package/lib/mass/ui/MassShell.js.map +1 -0
  371. package/lib/mass/ui/MassSidePanel.d.ts +32 -0
  372. package/lib/mass/ui/MassSidePanel.d.ts.map +1 -0
  373. package/lib/mass/ui/MassSidePanel.js +44 -0
  374. package/lib/mass/ui/MassSidePanel.js.map +1 -0
  375. package/lib/mass/ui/MassStateProvider.d.ts +19 -0
  376. package/lib/mass/ui/MassStateProvider.d.ts.map +1 -0
  377. package/lib/mass/ui/MassStateProvider.js +16 -0
  378. package/lib/mass/ui/MassStateProvider.js.map +1 -0
  379. package/lib/mass/ui/MassStatusBar.d.ts +15 -0
  380. package/lib/mass/ui/MassStatusBar.d.ts.map +1 -0
  381. package/lib/mass/ui/MassStatusBar.js +50 -0
  382. package/lib/mass/ui/MassStatusBar.js.map +1 -0
  383. package/lib/mass/ui/MassToolbar.d.ts +24 -0
  384. package/lib/mass/ui/MassToolbar.d.ts.map +1 -0
  385. package/lib/mass/ui/MassToolbar.js +36 -0
  386. package/lib/mass/ui/MassToolbar.js.map +1 -0
  387. package/lib/mass/ui/MetadataPanel.d.ts +35 -0
  388. package/lib/mass/ui/MetadataPanel.d.ts.map +1 -0
  389. package/lib/mass/ui/MetadataPanel.js +100 -0
  390. package/lib/mass/ui/MetadataPanel.js.map +1 -0
  391. package/lib/mass/ui/MzDecimalsMenu.d.ts +28 -0
  392. package/lib/mass/ui/MzDecimalsMenu.d.ts.map +1 -0
  393. package/lib/mass/ui/MzDecimalsMenu.js +40 -0
  394. package/lib/mass/ui/MzDecimalsMenu.js.map +1 -0
  395. package/lib/mass/ui/PeakLabels.d.ts +93 -0
  396. package/lib/mass/ui/PeakLabels.d.ts.map +1 -0
  397. package/lib/mass/ui/PeakLabels.js +91 -0
  398. package/lib/mass/ui/PeakLabels.js.map +1 -0
  399. package/lib/mass/ui/PeakTable.d.ts +34 -0
  400. package/lib/mass/ui/PeakTable.d.ts.map +1 -0
  401. package/lib/mass/ui/PeakTable.js +49 -0
  402. package/lib/mass/ui/PeakTable.js.map +1 -0
  403. package/lib/mass/ui/PeaksPanel.d.ts +31 -0
  404. package/lib/mass/ui/PeaksPanel.d.ts.map +1 -0
  405. package/lib/mass/ui/PeaksPanel.js +53 -0
  406. package/lib/mass/ui/PeaksPanel.js.map +1 -0
  407. package/lib/mass/ui/SpectraPanel.d.ts +17 -0
  408. package/lib/mass/ui/SpectraPanel.d.ts.map +1 -0
  409. package/lib/mass/ui/SpectraPanel.js +76 -0
  410. package/lib/mass/ui/SpectraPanel.js.map +1 -0
  411. package/lib/mass/ui/SpectrumRow.d.ts +26 -0
  412. package/lib/mass/ui/SpectrumRow.d.ts.map +1 -0
  413. package/lib/mass/ui/SpectrumRow.js +141 -0
  414. package/lib/mass/ui/SpectrumRow.js.map +1 -0
  415. package/lib/mass/ui/SpectrumTrace.d.ts +46 -0
  416. package/lib/mass/ui/SpectrumTrace.d.ts.map +1 -0
  417. package/lib/mass/ui/SpectrumTrace.js +68 -0
  418. package/lib/mass/ui/SpectrumTrace.js.map +1 -0
  419. package/lib/mass/ui/index.d.ts +69 -0
  420. package/lib/mass/ui/index.d.ts.map +1 -0
  421. package/lib/mass/ui/index.js +42 -0
  422. package/lib/mass/ui/index.js.map +1 -0
  423. package/lib/mass/ui/massActions.d.ts +52 -0
  424. package/lib/mass/ui/massActions.d.ts.map +1 -0
  425. package/lib/mass/ui/massActions.js +62 -0
  426. package/lib/mass/ui/massActions.js.map +1 -0
  427. package/lib/mass/ui/massChartProps.d.ts +128 -0
  428. package/lib/mass/ui/massChartProps.d.ts.map +1 -0
  429. package/lib/mass/ui/massChartProps.js +14 -0
  430. package/lib/mass/ui/massChartProps.js.map +1 -0
  431. package/lib/mass/ui/massCommandContext.d.ts +36 -0
  432. package/lib/mass/ui/massCommandContext.d.ts.map +1 -0
  433. package/lib/mass/ui/massCommandContext.js +45 -0
  434. package/lib/mass/ui/massCommandContext.js.map +1 -0
  435. package/lib/mass/ui/massHostPanels.d.ts +48 -0
  436. package/lib/mass/ui/massHostPanels.d.ts.map +1 -0
  437. package/lib/mass/ui/massHostPanels.js +41 -0
  438. package/lib/mass/ui/massHostPanels.js.map +1 -0
  439. package/lib/mass/ui/massStateContext.d.ts +26 -0
  440. package/lib/mass/ui/massStateContext.d.ts.map +1 -0
  441. package/lib/mass/ui/massStateContext.js +37 -0
  442. package/lib/mass/ui/massStateContext.js.map +1 -0
  443. package/lib/mass/ui/useIntensityZoom.d.ts +20 -0
  444. package/lib/mass/ui/useIntensityZoom.d.ts.map +1 -0
  445. package/lib/mass/ui/useIntensityZoom.js +42 -0
  446. package/lib/mass/ui/useIntensityZoom.js.map +1 -0
  447. package/lib/mass/ui/useMassEditor.d.ts +52 -0
  448. package/lib/mass/ui/useMassEditor.d.ts.map +1 -0
  449. package/lib/mass/ui/useMassEditor.js +93 -0
  450. package/lib/mass/ui/useMassEditor.js.map +1 -0
  451. package/lib/mass/ui/useMassFiles.d.ts +22 -0
  452. package/lib/mass/ui/useMassFiles.d.ts.map +1 -0
  453. package/lib/mass/ui/useMassFiles.js +71 -0
  454. package/lib/mass/ui/useMassFiles.js.map +1 -0
  455. package/lib/mass/ui/useMassHandle.d.ts +15 -0
  456. package/lib/mass/ui/useMassHandle.d.ts.map +1 -0
  457. package/lib/mass/ui/useMassHandle.js +35 -0
  458. package/lib/mass/ui/useMassHandle.js.map +1 -0
  459. package/lib/mass/ui/useMassPointer.d.ts +70 -0
  460. package/lib/mass/ui/useMassPointer.d.ts.map +1 -0
  461. package/lib/mass/ui/useMassPointer.js +57 -0
  462. package/lib/mass/ui/useMassPointer.js.map +1 -0
  463. package/lib/mass/ui/useMassShortcuts.d.ts +21 -0
  464. package/lib/mass/ui/useMassShortcuts.d.ts.map +1 -0
  465. package/lib/mass/ui/useMassShortcuts.js +66 -0
  466. package/lib/mass/ui/useMassShortcuts.js.map +1 -0
  467. package/lib/mass/ui/useMassSide.d.ts +27 -0
  468. package/lib/mass/ui/useMassSide.d.ts.map +1 -0
  469. package/lib/mass/ui/useMassSide.js +45 -0
  470. package/lib/mass/ui/useMassSide.js.map +1 -0
  471. package/lib/mass/ui/useMassZoom.d.ts +92 -0
  472. package/lib/mass/ui/useMassZoom.d.ts.map +1 -0
  473. package/lib/mass/ui/useMassZoom.js +65 -0
  474. package/lib/mass/ui/useMassZoom.js.map +1 -0
  475. package/lib/mass.d.ts +16 -0
  476. package/lib/mass.d.ts.map +1 -0
  477. package/lib/mass.js +16 -0
  478. package/lib/mass.js.map +1 -0
  479. package/lib/panel/ui/PanelRail.d.ts.map +1 -1
  480. package/lib/panel/ui/PanelRail.js +6 -1
  481. package/lib/panel/ui/PanelRail.js.map +1 -1
  482. package/lib/slides/ui/slideSanitizeSchema.d.ts +3 -2
  483. package/lib/slides/ui/slideSanitizeSchema.d.ts.map +1 -1
  484. package/lib/slides/ui/slideSanitizeSchema.js +82 -2
  485. package/lib/slides/ui/slideSanitizeSchema.js.map +1 -1
  486. package/package.json +6 -1
  487. package/src/about/core/providers.ts +7 -0
  488. package/src/about/ui/AboutProvidedBy.tsx +49 -0
  489. package/src/chart/ui/useChartPointer.ts +18 -4
  490. package/src/credits/core/credits.ts +53 -0
  491. package/src/download/core/drawingMarkup.ts +18 -1
  492. package/src/download/core/figurePng.ts +21 -8
  493. package/src/download/core/figureSvg.ts +5 -2
  494. package/src/download/core/figureTarget.ts +28 -3
  495. package/src/download/core/svgBounds.ts +21 -0
  496. package/src/download/core/svgToPng.ts +3 -4
  497. package/src/format/core/relativeTime.ts +29 -7
  498. package/src/host/core/connectHost.ts +77 -120
  499. package/src/host/core/hostOutputs.ts +197 -0
  500. package/src/host/core/index.ts +13 -7
  501. package/src/host/core/irKinds.ts +92 -0
  502. package/src/host/core/kinds.ts +16 -6
  503. package/src/host/core/protocol.ts +50 -8
  504. package/src/host/core/selectInputs.ts +145 -0
  505. package/src/host/testing/sciPeaks.ts +140 -0
  506. package/src/host/testing/standInHost.ts +30 -5
  507. package/src/host/ui/useHostConnection.ts +17 -8
  508. package/src/host-testing.ts +4 -0
  509. package/src/ir/core/handPicking.ts +154 -0
  510. package/src/ir/core/index.ts +14 -0
  511. package/src/ir/core/irBandState.ts +155 -0
  512. package/src/ir/core/irCommands.ts +7 -0
  513. package/src/ir/core/irPeaks.ts +79 -0
  514. package/src/ir/core/irReducer.ts +27 -34
  515. package/src/ir/core/irSpectrum.ts +16 -0
  516. package/src/ir/core/irState.ts +15 -8
  517. package/src/ir/core/pickBands.ts +46 -39
  518. package/src/ir/core/ramanBands.ts +2 -2
  519. package/src/ir/core/spectrumBands.ts +113 -0
  520. package/src/ir/ui/BandRow.tsx +20 -2
  521. package/src/ir/ui/BandsPanel.tsx +46 -88
  522. package/src/ir/ui/BandsToolbar.tsx +152 -0
  523. package/src/ir/ui/IrCanvas.tsx +22 -11
  524. package/src/ir/ui/IrChart.tsx +10 -1
  525. package/src/ir/ui/IrDocumentationDialog.tsx +7 -0
  526. package/src/ir/ui/IrEditor.tsx +4 -2
  527. package/src/ir/ui/IrShell.tsx +5 -0
  528. package/src/ir/ui/IrStatusBar.tsx +4 -1
  529. package/src/ir/ui/IrToolbar.tsx +14 -5
  530. package/src/ir/ui/VibrationalEditor.tsx +2 -1
  531. package/src/ir/ui/irActions.ts +11 -0
  532. package/src/ir/ui/irChartProps.ts +4 -1
  533. package/src/ir/ui/useIrEditor.ts +21 -21
  534. package/src/locales/de.json +63 -0
  535. package/src/locales/en.json +63 -0
  536. package/src/locales/es.json +63 -0
  537. package/src/locales/fr.json +63 -0
  538. package/src/locales/it.json +63 -0
  539. package/src/mass/core/analyseSpectrum.ts +191 -0
  540. package/src/mass/core/ascendingTrace.ts +62 -0
  541. package/src/mass/core/centroidPeaks.ts +114 -0
  542. package/src/mass/core/detectMassFormat.ts +113 -0
  543. package/src/mass/core/downloadSpectra.ts +52 -0
  544. package/src/mass/core/fromJcamp.ts +151 -0
  545. package/src/mass/core/fromText.ts +58 -0
  546. package/src/mass/core/index.ts +194 -0
  547. package/src/mass/core/jcampTechnique.ts +87 -0
  548. package/src/mass/core/labelStackBox.ts +75 -0
  549. package/src/mass/core/labelledPeaks.ts +135 -0
  550. package/src/mass/core/loadMassSpectra.ts +86 -0
  551. package/src/mass/core/loadedMassSpectrum.ts +43 -0
  552. package/src/mass/core/massCommands.ts +156 -0
  553. package/src/mass/core/massDomain.ts +229 -0
  554. package/src/mass/core/massEditorApi.ts +68 -0
  555. package/src/mass/core/massFormat.ts +187 -0
  556. package/src/mass/core/massMeta.ts +239 -0
  557. package/src/mass/core/massReducer.ts +232 -0
  558. package/src/mass/core/massResolution.ts +169 -0
  559. package/src/mass/core/massSidePanels.ts +27 -0
  560. package/src/mass/core/massSpectrum.ts +220 -0
  561. package/src/mass/core/massState.ts +206 -0
  562. package/src/mass/core/massStateEdits.ts +104 -0
  563. package/src/mass/core/massSummary.ts +213 -0
  564. package/src/mass/core/mzDecimalsSetting.ts +52 -0
  565. package/src/mass/core/nearestPeak.ts +130 -0
  566. package/src/mass/core/peakLabelLines.ts +112 -0
  567. package/src/mass/core/peakLabelPlan.ts +246 -0
  568. package/src/mass/core/peakTable.ts +82 -0
  569. package/src/mass/core/resolutionOf.ts +100 -0
  570. package/src/mass/core/scanFilter.ts +119 -0
  571. package/src/mass/core/spectrumJcamp.ts +186 -0
  572. package/src/mass/core/toMassSpectrum.ts +126 -0
  573. package/src/mass/core/traceIcon.ts +105 -0
  574. package/src/mass/core/writtenResolution.ts +81 -0
  575. package/src/mass/ui/MassAboutDialog.tsx +89 -0
  576. package/src/mass/ui/MassCanvas.tsx +170 -0
  577. package/src/mass/ui/MassChart.tsx +266 -0
  578. package/src/mass/ui/MassCommandProvider.tsx +34 -0
  579. package/src/mass/ui/MassCommandTooltip.tsx +36 -0
  580. package/src/mass/ui/MassDocumentationDialog.tsx +136 -0
  581. package/src/mass/ui/MassEditor.tsx +130 -0
  582. package/src/mass/ui/MassHeader.tsx +38 -0
  583. package/src/mass/ui/MassLogo.tsx +84 -0
  584. package/src/mass/ui/MassPointerTracker.tsx +72 -0
  585. package/src/mass/ui/MassShell.tsx +237 -0
  586. package/src/mass/ui/MassSidePanel.tsx +107 -0
  587. package/src/mass/ui/MassStateProvider.tsx +32 -0
  588. package/src/mass/ui/MassStatusBar.tsx +108 -0
  589. package/src/mass/ui/MassToolbar.tsx +120 -0
  590. package/src/mass/ui/MetadataPanel.tsx +201 -0
  591. package/src/mass/ui/MzDecimalsMenu.tsx +86 -0
  592. package/src/mass/ui/PeakLabels.tsx +242 -0
  593. package/src/mass/ui/PeakTable.tsx +199 -0
  594. package/src/mass/ui/PeaksPanel.tsx +182 -0
  595. package/src/mass/ui/SpectraPanel.tsx +153 -0
  596. package/src/mass/ui/SpectrumRow.tsx +246 -0
  597. package/src/mass/ui/SpectrumTrace.tsx +119 -0
  598. package/src/mass/ui/index.ts +69 -0
  599. package/src/mass/ui/massActions.ts +109 -0
  600. package/src/mass/ui/massChartProps.ts +130 -0
  601. package/src/mass/ui/massCommandContext.tsx +65 -0
  602. package/src/mass/ui/massHostPanels.ts +71 -0
  603. package/src/mass/ui/massStateContext.ts +48 -0
  604. package/src/mass/ui/useIntensityZoom.ts +55 -0
  605. package/src/mass/ui/useMassEditor.ts +156 -0
  606. package/src/mass/ui/useMassFiles.ts +91 -0
  607. package/src/mass/ui/useMassHandle.ts +58 -0
  608. package/src/mass/ui/useMassPointer.ts +120 -0
  609. package/src/mass/ui/useMassShortcuts.ts +85 -0
  610. package/src/mass/ui/useMassSide.ts +63 -0
  611. package/src/mass/ui/useMassZoom.ts +157 -0
  612. package/src/mass.ts +16 -0
  613. package/src/panel/ui/PanelRail.tsx +5 -1
  614. package/src/slides/ui/slideSanitizeSchema.ts +86 -2
  615. package/styles/chrome.css +7 -0
  616. package/styles/slides.css +47 -0
@@ -0,0 +1,130 @@
1
+ import type { Ref } from 'react';
2
+ import { RootLayout } from 'react-science/ui';
3
+
4
+ import type { MassEditorHandle, MassPlotClick } from '../core/massEditorApi.ts';
5
+ import type { MassPanelId } from '../core/massSidePanels.ts';
6
+ import type { MassSpectrum } from '../core/massSpectrum.ts';
7
+ import type { MassSettings } from '../core/massState.ts';
8
+
9
+ import { MassShell } from './MassShell.tsx';
10
+ import { MassStateProvider } from './MassStateProvider.tsx';
11
+ import type { MassHostPanel } from './massHostPanels.ts';
12
+ import { useMassEditor } from './useMassEditor.ts';
13
+
14
+ export interface MassEditorProps {
15
+ /**
16
+ * The spectra to open on. Read when the viewer opens and never again: what is
17
+ * on the chart belongs to the viewer from then on, so a host re-rendering with
18
+ * another array does not silently replace what somebody is looking at. The
19
+ * `ref` handle is how spectra arrive afterwards.
20
+ * @default []
21
+ */
22
+ data?: MassSpectrum[];
23
+ /**
24
+ * Called whenever the spectra open change — one loaded, one closed, the chart
25
+ * cleared — with the spectra now open.
26
+ *
27
+ * The document only. A zoom, a selection, a rename and a colour change what is
28
+ * being looked at rather than what is loaded, and a host told about those
29
+ * would be told on every drag of the mouse.
30
+ * @default undefined
31
+ */
32
+ onChange?: (spectra: MassSpectrum[]) => void;
33
+ /**
34
+ * How the spectra are drawn to begin with: whether the peaks are labelled,
35
+ * how many, and whether their charges are written.
36
+ * @default DEFAULT_SETTINGS
37
+ */
38
+ settings?: Partial<MassSettings>;
39
+ /**
40
+ * The side panels open to begin with: the viewer's own — `'spectra'`,
41
+ * `'peaks'`, `'metadata'` — or the id of one of `panels`. An id no panel
42
+ * answers to is ignored.
43
+ * @default DEFAULT_SIDE_PANELS
44
+ */
45
+ defaultPanelIds?: readonly MassPanelId[];
46
+ /**
47
+ * Panels the host adds to the viewer's own — a formula to predict an isotopic
48
+ * pattern from, say. Their icons come first in the activity bar, in the order
49
+ * given, and each then behaves as a built-in panel does.
50
+ * @default []
51
+ */
52
+ panels?: readonly MassHostPanel[];
53
+ /**
54
+ * The plot was clicked (a press that did not travel, so not a zoom drag), with
55
+ * the m/z it landed at, the picked peak within reach and the spectrum selected
56
+ * at that moment.
57
+ * @default undefined
58
+ */
59
+ onPlotClick?: (click: MassPlotClick) => void;
60
+ /**
61
+ * The handle a host drives the viewer through: take these spectra, read
62
+ * these files, frame this mass, select that one.
63
+ * @default undefined
64
+ */
65
+ ref?: Ref<MassEditorHandle>;
66
+ }
67
+
68
+ /**
69
+ * A mass spectrum viewer: a header across the top, the chart in the middle, the
70
+ * tools down the left, and the panels that interrogate it down the right.
71
+ *
72
+ * The same shape as the infrared viewer, deliberately — a page may well hold
73
+ * both, and a chemist who has learned one should not have to learn the other.
74
+ * Files are dropped on the chart or opened from the toolbar: JCAMP-DX and two
75
+ * columns of text. A profile is peak picked as it is read, every spectrum is
76
+ * judged high or low resolution, and the peaks of the selected one are labelled
77
+ * as the chart is zoomed.
78
+ *
79
+ * It is sealed the way NMRium is sealed: the spectra go in as `data` and come
80
+ * back through `onChange`, and everything else a host wants is a gesture on the
81
+ * `ref` rather than a prop that has to change to be obeyed.
82
+ * @param props - Component props.
83
+ * @returns The viewer.
84
+ */
85
+ export function MassEditor(props: MassEditorProps) {
86
+ const {
87
+ data = NO_SPECTRA,
88
+ onChange,
89
+ settings,
90
+ defaultPanelIds,
91
+ panels = NO_PANELS,
92
+ onPlotClick,
93
+ ref,
94
+ } = props;
95
+
96
+ const editor = useMassEditor({
97
+ spectra: data,
98
+ ...(settings === undefined ? {} : { settings }),
99
+ ...(defaultPanelIds === undefined ? {} : { panelIds: defaultPanelIds }),
100
+ ...(onChange === undefined ? {} : { onChange }),
101
+ });
102
+
103
+ return (
104
+ <MassStateProvider editor={editor}>
105
+ {/* `react-science`'s own root: it holds the element the browser is asked
106
+ to show full screen, points Blueprint's portals at that element so
107
+ dialogs and tooltips are not left behind in `document.body`, and paints
108
+ the backdrop white. */}
109
+ <RootLayout style={rootLayoutStyle}>
110
+ <MassShell
111
+ handle={ref}
112
+ panels={panels}
113
+ {...(onPlotClick === undefined ? {} : { onPlotClick })}
114
+ />
115
+ </RootLayout>
116
+ </MassStateProvider>
117
+ );
118
+ }
119
+
120
+ /**
121
+ * The viewer fills what it is given, and its own children scroll rather than
122
+ * push: a flex column with no `minHeight` grows past its parent instead.
123
+ */
124
+ const rootLayoutStyle = { minHeight: 0 } as const;
125
+
126
+ /** What a viewer opens on when it is handed nothing, kept stable for the memo. */
127
+ const NO_SPECTRA: MassSpectrum[] = [];
128
+
129
+ /** What a viewer the host adds no panel to offers, kept stable for the memo. */
130
+ const NO_PANELS: readonly MassHostPanel[] = [];
@@ -0,0 +1,38 @@
1
+ import { Header, Toolbar, useFullscreen } from 'react-science/ui';
2
+
3
+ import { MassLogo } from './MassLogo.tsx';
4
+ import { useMassCommandProps } from './massCommandContext.tsx';
5
+
6
+ /**
7
+ * The bar across the top: the mark on the left, the viewer on the right.
8
+ *
9
+ * Nothing that is done to the spectra is here — that is the rail down the left
10
+ * and the panels down the right — only what is asked of the viewer itself. The
11
+ * mark is the About button, in the corner the infrared viewer puts its own, so
12
+ * a chemist switching between the two looks in one place for what they are in;
13
+ * and help then full screen close the bar, hard against the right edge.
14
+ * @returns The header.
15
+ */
16
+ export function MassHeader() {
17
+ const command = useMassCommandProps();
18
+ const { isFullScreen } = useFullscreen();
19
+
20
+ return (
21
+ <Header>
22
+ <Toolbar aria-label="Mass spectrum viewer">
23
+ <Toolbar.Item icon={<MassLogo size={16} />} {...command('about')} />
24
+ </Toolbar>
25
+ <Toolbar aria-label="Mass spectrum viewer help">
26
+ <Toolbar.Item icon="help" {...command('documentation')} />
27
+ {/* Always the last thing in the bar, hard against the right edge: the
28
+ corner a window is made bigger from is the corner it is looked for
29
+ in, whatever else the header grows. */}
30
+ <Toolbar.Item
31
+ icon="fullscreen"
32
+ active={isFullScreen}
33
+ {...command('fullScreen')}
34
+ />
35
+ </Toolbar>
36
+ </Header>
37
+ );
38
+ }
@@ -0,0 +1,84 @@
1
+ import type { ReactElement } from 'react';
2
+
3
+ import { CHART_COLORS } from '../../chart/core/chartTheme.ts';
4
+ import { SPECTRUM_COLORS } from '../../chart/core/spectrumColor.ts';
5
+
6
+ export interface MassLogoProps {
7
+ /**
8
+ * Width and height of the mark, in pixels.
9
+ * @default 16
10
+ */
11
+ size?: number;
12
+ }
13
+
14
+ /**
15
+ * The viewer's mark: a labelled spectrum, drawn the way the chart draws one.
16
+ *
17
+ * Three sticks on a baseline with a triangle on the tallest — the same shapes,
18
+ * the same blue and the same orange the chart itself uses, so the mark is a
19
+ * small piece of the tool's output rather than a picture of it. Three sticks is
20
+ * what survives being shrunk to a toolbar icon; a fourth closes the gaps between
21
+ * them and the mark reads as a solid block at 16 pixels.
22
+ * @param props - Component props.
23
+ * @returns The mark, as SVG.
24
+ */
25
+ export function MassLogo(props: MassLogoProps): ReactElement {
26
+ const { size = 16 } = props;
27
+
28
+ return (
29
+ <svg
30
+ width={size}
31
+ height={size}
32
+ viewBox={VIEW_BOX}
33
+ role="img"
34
+ aria-label="Mass spectrum viewer"
35
+ >
36
+ <line
37
+ x1={2}
38
+ y1={BASELINE}
39
+ x2={30}
40
+ y2={BASELINE}
41
+ strokeWidth={BASELINE_WIDTH}
42
+ style={baselineStyle}
43
+ />
44
+ {STICKS.map((stick) => (
45
+ <line
46
+ key={stick.x}
47
+ x1={stick.x}
48
+ y1={BASELINE}
49
+ x2={stick.x}
50
+ y2={stick.top}
51
+ strokeWidth={STICK_WIDTH}
52
+ strokeLinecap="butt"
53
+ style={stickStyle}
54
+ />
55
+ ))}
56
+ <path d={MARK} style={markStyle} />
57
+ </svg>
58
+ );
59
+ }
60
+
61
+ /** Cropped to the ink: a mark carrying its own margin reads as the smaller one. */
62
+ const VIEW_BOX = '1 0 30 29';
63
+
64
+ /** Where the sticks stand, in the same units. */
65
+ const BASELINE = 27;
66
+
67
+ const BASELINE_WIDTH = 1.4;
68
+ const STICK_WIDTH = 2.6;
69
+
70
+ /** The base peak in the middle, with a shoulder either side of it. */
71
+ const STICKS = [
72
+ { x: 6, top: 15 },
73
+ { x: 16, top: 7 },
74
+ { x: 26, top: 19 },
75
+ ] as const;
76
+
77
+ /** The triangle on the base peak: apex on the tip, body clear of it. */
78
+ const MARK = 'M16 6L12.4 0.6L19.6 0.6Z';
79
+
80
+ const baselineStyle = { stroke: CHART_COLORS.axis } as const;
81
+
82
+ const stickStyle = { stroke: SPECTRUM_COLORS[0] } as const;
83
+
84
+ const markStyle = { fill: CHART_COLORS.highlight } as const;
@@ -0,0 +1,72 @@
1
+ import type { ReactElement } from 'react';
2
+
3
+ import type { PlotRect } from '../../chart/core/chartGeometry.ts';
4
+ import type { ChartPoint } from '../../chart/core/svgPoint.ts';
5
+ import { ChartTracker } from '../../chart/ui/ChartTracker.tsx';
6
+ import { formatIntensity, formatMz } from '../core/massFormat.ts';
7
+
8
+ import type { MassReadout } from './useMassPointer.ts';
9
+
10
+ export interface MassPointerTrackerProps {
11
+ /** Where the pointer is, `null` whenever it is off the plot. */
12
+ position: ChartPoint | null;
13
+ /** What the axes read under it, `null` whenever it is off the plot. */
14
+ readout: MassReadout | null;
15
+ /** Where the plot sits inside the SVG. */
16
+ plot: PlotRect;
17
+ /**
18
+ * How many decimals the masses on screen are written with.
19
+ * @default 4
20
+ */
21
+ mzDecimals?: number;
22
+ /**
23
+ * What one unit of the measured intensity is written as.
24
+ * @default 1
25
+ */
26
+ intensityScale?: number;
27
+ /**
28
+ * The sign that unit carries, `%` on a derived basis. This number stands on
29
+ * its own with nothing beside it to say what it is, so it takes the sign where
30
+ * the axis would otherwise have carried it.
31
+ * @default ''
32
+ */
33
+ suffix?: string;
34
+ }
35
+
36
+ /**
37
+ * The crosshair, and what the axes say where it stands.
38
+ *
39
+ * Two rules rather than one, because both axes are being read: the vertical one
40
+ * answers *what mass is this*, and the horizontal one answers *how tall is that
41
+ * against this*, which is how a peak is judged against its neighbours without
42
+ * counting grid lines. The picked peak within reach is not written here: the
43
+ * guide on its exact m/z and its lit row in the peak table say which it is, and
44
+ * a readout a line longer than the shared chart places would run off the foot
45
+ * of the plot.
46
+ * @param props - Component props.
47
+ * @returns The crosshair, or nothing while the pointer is off the plot.
48
+ */
49
+ export function MassPointerTracker(
50
+ props: MassPointerTrackerProps,
51
+ ): ReactElement | null {
52
+ const {
53
+ position,
54
+ readout,
55
+ plot,
56
+ mzDecimals,
57
+ intensityScale = 1,
58
+ suffix = '',
59
+ } = props;
60
+
61
+ // A magnitude: the lower half of a mirrored pair is a second spectrum drawn
62
+ // downwards, never a negative intensity.
63
+ const lines =
64
+ readout === null
65
+ ? null
66
+ : [
67
+ `m/z ${formatMz(readout.mz, mzDecimals)}`,
68
+ `${formatIntensity(Math.abs(readout.intensity) * intensityScale, mzDecimals)}${suffix}`,
69
+ ];
70
+
71
+ return <ChartTracker position={position} plot={plot} lines={lines} />;
72
+ }
@@ -0,0 +1,237 @@
1
+ import type { ChangeEvent, Ref } from 'react';
2
+ import { useId, useMemo, useRef, useState } from 'react';
3
+ import { SplitPane, useFullscreen } from 'react-science/ui';
4
+
5
+ import { sanitizeFileName } from '../../download/core/sanitizeFileName.ts';
6
+ import { useFigureDownload } from '../../download/ui/useFigureDownload.tsx';
7
+ import { PanelRail } from '../../panel/ui/PanelRail.tsx';
8
+ import type { MassCommandHandlers } from '../core/massCommands.ts';
9
+ import type { MassEditorHandle, MassPlotClick } from '../core/massEditorApi.ts';
10
+ import type { MassSpectrum } from '../core/massSpectrum.ts';
11
+
12
+ import { MassAboutDialog } from './MassAboutDialog.tsx';
13
+ import { MassCanvas } from './MassCanvas.tsx';
14
+ import { MassCommandProvider } from './MassCommandProvider.tsx';
15
+ import { MassDocumentationDialog } from './MassDocumentationDialog.tsx';
16
+ import { MassHeader } from './MassHeader.tsx';
17
+ import { MassSidePanel } from './MassSidePanel.tsx';
18
+ import { MassToolbar } from './MassToolbar.tsx';
19
+ import type { MassHostPanel } from './massHostPanels.ts';
20
+ import { useMassActions, useMassEditorState } from './massStateContext.ts';
21
+ import { useIntensityZoom } from './useIntensityZoom.ts';
22
+ import { useMassFiles } from './useMassFiles.ts';
23
+ import { useMassHandle } from './useMassHandle.ts';
24
+ import { useMassShortcuts } from './useMassShortcuts.ts';
25
+ import { useMassSide } from './useMassSide.ts';
26
+
27
+ export interface MassShellProps {
28
+ /**
29
+ * The handle to fill in, once there is a state for it to act on.
30
+ * @default undefined
31
+ */
32
+ handle?: Ref<MassEditorHandle>;
33
+ /** The panels the host adds to the viewer's own, ahead of them. */
34
+ panels: readonly MassHostPanel[];
35
+ /**
36
+ * Told of a click on the plot, with the spectrum selected at that moment.
37
+ * @default undefined
38
+ */
39
+ onPlotClick?: (click: MassPlotClick) => void;
40
+ }
41
+
42
+ /**
43
+ * The viewer's screen: a header, the rails, and the split between the chart and
44
+ * the panels.
45
+ *
46
+ * Kept apart from `MassEditor` so that the handle, the commands and the
47
+ * highlight — all of which need the state — sit below the providers rather than
48
+ * beside them, and so the sealed component above is nothing but its props.
49
+ * @param props - Component props.
50
+ * @returns The screen.
51
+ */
52
+ export function MassShell(props: MassShellProps) {
53
+ const { handle, panels, onPlotClick } = props;
54
+
55
+ const { state, visibleSpectra, selectedSpectrum } = useMassEditorState();
56
+ const actions = useMassActions();
57
+ const { toggle: toggleFullScreen } = useFullscreen();
58
+ const { openPanelIds, tool } = state.view;
59
+ const { showLabels, showCharges } = state.settings;
60
+ const side = useMassSide(panels);
61
+ const files = useMassFiles();
62
+ const fileInput = useRef<HTMLInputElement>(null);
63
+ const { zoomIn, zoomOut } = useIntensityZoom();
64
+
65
+ const [isAboutOpen, setIsAboutOpen] = useState(false);
66
+ const [isDocumentationOpen, setIsDocumentationOpen] = useState(false);
67
+ // What the pointer is resting on is not part of the document and changes on
68
+ // every move across the chart, so it is held here rather than in the reducer,
69
+ // where every panel's memo would run sixty times a second.
70
+ const [highlightMz, setHighlightMz] = useState<number | null>(null);
71
+
72
+ // The chart is the picture, so the box it is drawn in is what the figure
73
+ // panel is pointed at: the viewer around it is full of SVG icons.
74
+ const chartId = useId();
75
+ const figure = useFigureDownload({
76
+ targetId: chartId,
77
+ fileName: pictureName(visibleSpectra, selectedSpectrum),
78
+ });
79
+ const { isOpen: isFigureOpen, setOpen: setFigureOpen } = figure;
80
+
81
+ const commands = useMemo<MassCommandHandlers>(
82
+ () => ({
83
+ about: () => setIsAboutOpen(true),
84
+ documentation: () => setIsDocumentationOpen(true),
85
+ fullScreen: toggleFullScreen,
86
+ openFiles: () => fileInput.current?.click(),
87
+ readTool: () => actions.setTool('read'),
88
+ boxTool: () => actions.setTool(tool === 'box' ? 'read' : 'box'),
89
+ zoomIn,
90
+ zoomOut,
91
+ resetZoom: () => actions.resetDomain(),
92
+ toggleLabels: () => actions.setSettings({ showLabels: !showLabels }),
93
+ toggleCharges: () => actions.setSettings({ showCharges: !showCharges }),
94
+ exportImage: () => setFigureOpen(!isFigureOpen),
95
+ clear: () => actions.clear(),
96
+ }),
97
+ [
98
+ actions,
99
+ tool,
100
+ showLabels,
101
+ showCharges,
102
+ zoomIn,
103
+ zoomOut,
104
+ toggleFullScreen,
105
+ isFigureOpen,
106
+ setFigureOpen,
107
+ ],
108
+ );
109
+
110
+ // The root is held as state rather than in a ref because the keys are bound to
111
+ // it from an effect: a ref filled in during the commit would leave the effect
112
+ // with nothing to listen on for the first render, and no reason ever to run
113
+ // again.
114
+ const [root, setRoot] = useState<HTMLElement | null>(null);
115
+ useMassShortcuts(root, commands);
116
+ useMassHandle(handle, files.readFiles);
117
+
118
+ return (
119
+ <MassCommandProvider handlers={commands}>
120
+ {/* `tabIndex` so a click anywhere in the viewer makes this the target the
121
+ shortcuts are heard on: keys are delivered to whatever holds the caret,
122
+ and an SVG never does. */}
123
+ <div ref={setRoot} tabIndex={-1} style={rootStyle}>
124
+ <MassHeader />
125
+
126
+ <div style={mainStyle}>
127
+ <div style={railStyle}>
128
+ <MassToolbar figure={figure} />
129
+ </div>
130
+
131
+ <SplitPane
132
+ direction="horizontal"
133
+ controlledSide="end"
134
+ defaultSize="360px"
135
+ open={side.isOpen}
136
+ onOpenChange={side.setOpen}
137
+ >
138
+ <MassCanvas
139
+ highlightMz={highlightMz}
140
+ onHighlight={setHighlightMz}
141
+ chartId={chartId}
142
+ onDropFiles={(dropped) => void files.readFiles(dropped)}
143
+ {...(onPlotClick === undefined ? {} : { onPlotClick })}
144
+ />
145
+
146
+ <MassSidePanel
147
+ panels={panels}
148
+ highlightMz={highlightMz}
149
+ onHighlight={setHighlightMz}
150
+ />
151
+ </SplitPane>
152
+
153
+ {/* Outside the split, so the icons stay put against the right edge
154
+ while the panel beside them is resized or closed. */}
155
+ <div style={railStyle}>
156
+ <PanelRail
157
+ panels={side.panels}
158
+ openIds={openPanelIds}
159
+ onToggle={actions.togglePanel}
160
+ />
161
+ </div>
162
+ </div>
163
+
164
+ <input
165
+ ref={fileInput}
166
+ type="file"
167
+ multiple
168
+ accept={ACCEPTED_FILES}
169
+ style={hiddenStyle}
170
+ aria-label="Open spectra"
171
+ onChange={(event: ChangeEvent<HTMLInputElement>) => {
172
+ const chosen = [...(event.currentTarget.files ?? [])];
173
+ // Emptied so that choosing the same file again is still a change.
174
+ event.currentTarget.value = '';
175
+ if (chosen.length > 0) void files.readFiles(chosen);
176
+ }}
177
+ />
178
+ </div>
179
+
180
+ <MassAboutDialog
181
+ isOpen={isAboutOpen}
182
+ onClose={() => setIsAboutOpen(false)}
183
+ />
184
+ <MassDocumentationDialog
185
+ isOpen={isDocumentationOpen}
186
+ onClose={() => setIsDocumentationOpen(false)}
187
+ />
188
+ </MassCommandProvider>
189
+ );
190
+ }
191
+
192
+ /**
193
+ * What a picture of the chart is called: the spectrum being looked at, since a
194
+ * figure of the chart is a figure of that spectrum, and a chart holding several
195
+ * and pointing at none of them is named after the lot.
196
+ * @param spectra - What is drawn.
197
+ * @param selected - The one being looked at, `null` when none is.
198
+ * @returns The name, without its extension.
199
+ */
200
+ function pictureName(
201
+ spectra: readonly MassSpectrum[],
202
+ selected: MassSpectrum | null,
203
+ ): string {
204
+ const named = selected ?? (spectra.length === 1 ? spectra[0] : undefined);
205
+ return named === undefined
206
+ ? 'spectra'
207
+ : sanitizeFileName(named.name, 'spectrum');
208
+ }
209
+
210
+ /** What the file dialog offers, which is what the readers understand. */
211
+ const ACCEPTED_FILES = '.jdx,.dx,.jcamp,.txt,.csv,.tsv,.xy,.asc,.dat';
212
+
213
+ const rootStyle = {
214
+ display: 'flex',
215
+ flexDirection: 'column',
216
+ flex: '1 1 1px',
217
+ width: '100%',
218
+ height: '100%',
219
+ minHeight: 0,
220
+ outline: 'none',
221
+ } as const;
222
+
223
+ const mainStyle = {
224
+ display: 'flex',
225
+ flex: '1 1 1px',
226
+ minWidth: 0,
227
+ minHeight: 0,
228
+ } as const;
229
+
230
+ /**
231
+ * The rails are chrome of a fixed width, and a flex child shrinks by default: in
232
+ * a narrow viewer the row would take the width it is short of out of them.
233
+ */
234
+ const railStyle = { flex: 'none' } as const;
235
+
236
+ /** The file input is opened by the toolbar, never clicked itself. */
237
+ const hiddenStyle = { display: 'none' } as const;
@@ -0,0 +1,107 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { panelStyle } from '../../panel/core/panelStyles.ts';
4
+ import { SidePanelStack } from '../../panel/ui/SidePanelStack.tsx';
5
+ import type { MassSidePanelId } from '../core/massSidePanels.ts';
6
+
7
+ import { MetadataPanel } from './MetadataPanel.tsx';
8
+ import { PeaksPanel } from './PeaksPanel.tsx';
9
+ import { SpectraPanel } from './SpectraPanel.tsx';
10
+ import type { MassHostPanel } from './massHostPanels.ts';
11
+ import { isMassHostPanel, massStackPanels } from './massHostPanels.ts';
12
+ import { useMassActions, useMassEditorState } from './massStateContext.ts';
13
+
14
+ export interface MassSidePanelProps {
15
+ /**
16
+ * The panels the host adds to the viewer's own, stacked above them in the
17
+ * order given.
18
+ * @default []
19
+ */
20
+ panels?: readonly MassHostPanel[];
21
+ /**
22
+ * The m/z of the peak the pointer is resting on.
23
+ * @default null
24
+ */
25
+ highlightMz?: number | null;
26
+ /**
27
+ * Told when a row of the peak table is hovered.
28
+ * @default undefined
29
+ */
30
+ onHighlight?: (mz: number | null) => void;
31
+ }
32
+
33
+ /**
34
+ * The panels that are open, stacked down the right.
35
+ *
36
+ * Every open panel gets a share of the height rather than a turn, because the
37
+ * things they hold are read together: which spectrum is selected and what its
38
+ * peaks are is one question asked of two panels. The header carries the close
39
+ * button and nothing else — a panel's own actions are a toolbar inside its
40
+ * body, so they travel with it.
41
+ * @param props - Component props.
42
+ * @returns The panel stack.
43
+ */
44
+ export function MassSidePanel(props: MassSidePanelProps) {
45
+ const {
46
+ panels: hostPanels = NO_PANELS,
47
+ highlightMz = null,
48
+ onHighlight,
49
+ } = props;
50
+ const { state } = useMassEditorState();
51
+ const actions = useMassActions();
52
+ const { openPanelIds } = state.view;
53
+ const panels = useMemo(() => massStackPanels(hostPanels), [hostPanels]);
54
+
55
+ return (
56
+ <SidePanelStack
57
+ panels={panels}
58
+ openPanelIds={openPanelIds}
59
+ onClose={actions.togglePanel}
60
+ >
61
+ {(panel) =>
62
+ isMassHostPanel(panel) ? (
63
+ <div style={panelStyle}>{panel.content}</div>
64
+ ) : (
65
+ <PanelBody
66
+ panelId={panel.id}
67
+ highlightMz={highlightMz}
68
+ {...(onHighlight === undefined ? {} : { onHighlight })}
69
+ />
70
+ )
71
+ }
72
+ </SidePanelStack>
73
+ );
74
+ }
75
+
76
+ interface PanelBodyProps {
77
+ /** Which panel to draw. */
78
+ panelId: MassSidePanelId;
79
+ /** The m/z of the peak the pointer is resting on. */
80
+ highlightMz: number | null;
81
+ /**
82
+ * Told when a row of the peak table is hovered.
83
+ * @default undefined
84
+ */
85
+ onHighlight?: (mz: number | null) => void;
86
+ }
87
+
88
+ /**
89
+ * Which panel a panel id is.
90
+ * @param props - Component props.
91
+ * @returns The panel's body.
92
+ */
93
+ function PanelBody(props: PanelBodyProps) {
94
+ const { panelId, highlightMz, onHighlight } = props;
95
+
96
+ if (panelId === 'spectra') return <SpectraPanel />;
97
+ if (panelId === 'metadata') return <MetadataPanel />;
98
+ return (
99
+ <PeaksPanel
100
+ highlightMz={highlightMz}
101
+ {...(onHighlight === undefined ? {} : { onHighlight })}
102
+ />
103
+ );
104
+ }
105
+
106
+ /** What a stack the host adds nothing to holds, kept stable for the memo. */
107
+ const NO_PANELS: readonly MassHostPanel[] = [];