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,242 @@
1
+ import type { CSSProperties, ReactElement } from 'react';
2
+ import { useMemo } from 'react';
3
+
4
+ import type { PlotRect } from '../../chart/core/chartGeometry.ts';
5
+ import type { ChartScale } from '../../chart/core/chartScale.ts';
6
+ import {
7
+ CHART_COLORS,
8
+ CHART_FONT,
9
+ LABEL_HALO,
10
+ LABEL_QUIET,
11
+ PEAK_LABEL,
12
+ } from '../../chart/core/chartTheme.ts';
13
+ import type { HoveredPeak } from '../core/labelStackBox.ts';
14
+ import type { MassSpectrum } from '../core/massSpectrum.ts';
15
+ import type { PeakLabelLineKind } from '../core/peakLabelLines.ts';
16
+ import { planPeakLabels } from '../core/peakLabelPlan.ts';
17
+
18
+ export interface PeakLabelsProps {
19
+ /**
20
+ * The spectrum whose peaks are labelled. Hand it the same one that was drawn:
21
+ * a mirrored half is drawn normalised, and labels computed from the spectrum
22
+ * as measured would float above sticks of another height.
23
+ */
24
+ spectrum: MassSpectrum;
25
+ /** Where the plot sits, which is what a stack may not be pushed out of. */
26
+ plot: PlotRect;
27
+ /** The m/z axis as it is currently zoomed. */
28
+ xScale: ChartScale;
29
+ /**
30
+ * The intensity axis as it is currently zoomed. Reflect it and the labels
31
+ * follow the sticks downwards — together with `below`, which turns the stacks
32
+ * over.
33
+ */
34
+ yScale: ChartScale;
35
+ /**
36
+ * How many peaks are labelled at most, the most intense first.
37
+ * @default DEFAULT_LABEL_LIMIT
38
+ */
39
+ limit?: number;
40
+ /**
41
+ * Whether a peak whose charge was established says so.
42
+ * @default false
43
+ */
44
+ showCharges?: boolean;
45
+ /**
46
+ * How many decimals the masses on screen are written with.
47
+ * @default 4
48
+ */
49
+ mzDecimals?: number;
50
+ /**
51
+ * What explains each peak, keyed as `peakKey` keys it — the name a host
52
+ * writes on top of a stack.
53
+ * @default undefined
54
+ */
55
+ annotationLabels?: ReadonlyMap<string, string>;
56
+ /**
57
+ * Whether the stacks hang under the sticks rather than standing over them,
58
+ * which is what the lower half of a mirrored pair wants.
59
+ * @default false
60
+ */
61
+ below?: boolean;
62
+ /**
63
+ * The ink the stacks are written in — worth passing the spectrum's own colour
64
+ * on a chart holding several, where an unattributed m/z belongs to any of them.
65
+ * @default the theme's label colour
66
+ */
67
+ color?: string;
68
+ /**
69
+ * What one unit of the measured intensity is written as.
70
+ * @default 1
71
+ */
72
+ intensityScale?: number;
73
+ /**
74
+ * Called with the peak whose stack the pointer is resting on, `null` when it
75
+ * leaves. Without it the stacks answer no pointer at all.
76
+ * @default undefined
77
+ */
78
+ onHover?: (peak: HoveredPeak | null) => void;
79
+ }
80
+
81
+ /**
82
+ * The tops of the best peaks of one spectrum, and what each of them reads.
83
+ *
84
+ * Two things drawn together because they are one claim: a short mark on the tip
85
+ * of the picked peak, and the numbers written over it. The mark is the half that
86
+ * matters when the continuous trace is the one on screen — the centroid is then
87
+ * not drawn at all, and a stack of numbers floating over a peak shape says which
88
+ * region was picked but never which point of it, which is the number the stack
89
+ * is quoting. With the mark on the tip the two agree by construction.
90
+ *
91
+ * Which peaks are labelled is `planPeakLabels`'s to decide, and it follows the
92
+ * zoom: a survey of the whole spectrum labels its base peak and a few others,
93
+ * and the same spectrum zoomed onto one cluster labels every line in it. Every
94
+ * line is haloed and none of them is boxed: a number over a peak is written
95
+ * over whatever the plot has there, and the halo clears a hairline of chart from
96
+ * around each glyph, where a filled box would hide the very data it is about.
97
+ *
98
+ * The numbers take no pointer event; the room they occupy does, as one
99
+ * transparent rectangle per stack, and only when somebody asked for it — so a
100
+ * stack can be interrogated without becoming a control, while the crosshair
101
+ * underneath goes on following the pointer.
102
+ * @param props - Component props.
103
+ * @returns The marks and the labels, as SVG.
104
+ */
105
+ export function PeakLabels(props: PeakLabelsProps): ReactElement {
106
+ const {
107
+ spectrum,
108
+ plot,
109
+ xScale,
110
+ yScale,
111
+ limit,
112
+ showCharges = false,
113
+ mzDecimals,
114
+ annotationLabels,
115
+ below = false,
116
+ color = CHART_COLORS.labelText,
117
+ intensityScale = 1,
118
+ onHover,
119
+ } = props;
120
+
121
+ const plans = useMemo(
122
+ () =>
123
+ planPeakLabels({
124
+ spectrum,
125
+ plot,
126
+ xScale,
127
+ yScale,
128
+ showCharges,
129
+ below,
130
+ intensityScale,
131
+ ...(limit === undefined ? {} : { limit }),
132
+ ...(mzDecimals === undefined ? {} : { mzDecimals }),
133
+ ...(annotationLabels === undefined ? {} : { annotationLabels }),
134
+ }),
135
+ [
136
+ spectrum,
137
+ plot,
138
+ xScale,
139
+ yScale,
140
+ limit,
141
+ showCharges,
142
+ mzDecimals,
143
+ annotationLabels,
144
+ below,
145
+ intensityScale,
146
+ ],
147
+ );
148
+
149
+ // Every picked peak is marked; only the ones that kept their room are
150
+ // written, since a stack over a peak whose neighbour took the room would be
151
+ // written across that neighbour's.
152
+ const written = useMemo(
153
+ () => plans.filter((plan) => Number.isFinite(plan.labelX)),
154
+ [plans],
155
+ );
156
+
157
+ const stackStyle = useMemo(
158
+ () => ({ fill: color, fontSize: CHART_FONT.label, ...LABEL_HALO }),
159
+ [color],
160
+ );
161
+ const markStyle = useMemo(() => ({ stroke: color }), [color]);
162
+
163
+ return (
164
+ <g>
165
+ {/* Its own group, because the stroke that draws a mark would outline every
166
+ glyph of a label sharing the group with it. */}
167
+ <g pointerEvents="none" style={markStyle}>
168
+ {plans.map((plan) => (
169
+ <line
170
+ key={plan.key}
171
+ x1={plan.tipX}
172
+ y1={plan.tipY}
173
+ x2={plan.tipX}
174
+ y2={
175
+ below
176
+ ? plan.tipY - PEAK_LABEL.topMark
177
+ : plan.tipY + PEAK_LABEL.topMark
178
+ }
179
+ />
180
+ ))}
181
+ </g>
182
+ <g pointerEvents="none" style={stackStyle}>
183
+ {written.map((plan) => (
184
+ <text key={plan.key} textAnchor="middle">
185
+ {plan.lines.map((line, index) => (
186
+ <tspan
187
+ key={line.kind}
188
+ x={plan.labelX}
189
+ y={plan.baselines[index]}
190
+ style={LINE_STYLES[line.kind]}
191
+ >
192
+ {line.text}
193
+ </tspan>
194
+ ))}
195
+ </text>
196
+ ))}
197
+ </g>
198
+ {onHover === undefined
199
+ ? null
200
+ : written.map((plan) => (
201
+ <rect
202
+ key={plan.key}
203
+ x={plan.box.x}
204
+ y={plan.box.y}
205
+ width={plan.box.width}
206
+ height={plan.box.height}
207
+ fill="transparent"
208
+ onPointerEnter={() =>
209
+ onHover({
210
+ key: plan.key,
211
+ mz: plan.peak.x,
212
+ intensity: plan.peak.y,
213
+ charge: plan.peak.charge,
214
+ x: plan.labelX,
215
+ // A card hangs off the edge of the stack facing away from the
216
+ // stick, so it never covers the peak it is about.
217
+ y: below ? plan.box.y + plan.box.height : plan.box.y,
218
+ })
219
+ }
220
+ onPointerLeave={() => onHover(null)}
221
+ />
222
+ ))}
223
+ </g>
224
+ );
225
+ }
226
+
227
+ /**
228
+ * How each line of a stack is set.
229
+ *
230
+ * Four numbers in one ink and one weight are four things said at once, and the
231
+ * eye has to read all of them to find the one it came for. So the stack is
232
+ * graded instead: the name of what the peak is carries the weight, because it is
233
+ * the only line that is an answer rather than a measurement; the m/z is written
234
+ * plain, which is what a chemist is nearly always reading; and the charge and
235
+ * the intensity are let back towards the paper.
236
+ */
237
+ const LINE_STYLES: Record<PeakLabelLineKind, CSSProperties> = {
238
+ annotation: { fontWeight: 600 },
239
+ charge: { fillOpacity: LABEL_QUIET },
240
+ mz: {},
241
+ intensity: { fillOpacity: LABEL_QUIET },
242
+ };
@@ -0,0 +1,199 @@
1
+ import { memo, useMemo, useRef } from 'react';
2
+
3
+ import {
4
+ panelCellStyle,
5
+ panelColumnButtonStyle,
6
+ panelNumberCellStyle,
7
+ panelScrollAreaStyle,
8
+ panelStickyHeaderStyle,
9
+ panelTableStyle,
10
+ } from '../../panel/core/panelStyles.ts';
11
+ import { useVirtualRows } from '../../panel/ui/useVirtualRows.ts';
12
+ import type { MassPeakObject } from '../core/centroidPeaks.ts';
13
+ import { formatIntensity, formatMz } from '../core/massFormat.ts';
14
+
15
+ /** Which column the rows are read in the order of. */
16
+ export type PeakSortKey = 'mz' | 'intensity';
17
+
18
+ export interface PeakTableProps {
19
+ /** The peaks to list, in increasing m/z. */
20
+ peaks: readonly MassPeakObject[];
21
+ /** How many decimals the masses are written with. */
22
+ mzDecimals: number;
23
+ /**
24
+ * Which column the rows are in the order of: m/z ascending, which is how a
25
+ * spectrum is read, or intensity descending, which is how its base peak and
26
+ * its neighbours are found.
27
+ */
28
+ sortKey: PeakSortKey;
29
+ /** Order the rows by a column. */
30
+ onSort: (key: PeakSortKey) => void;
31
+ /** The m/z of the peak the pointer is resting on, `null` for none. */
32
+ highlightMz: number | null;
33
+ /** Told which peak a row the pointer rests on is, `null` when it leaves. */
34
+ onHighlight: (mz: number | null) => void;
35
+ /** Frame a peak on the chart. */
36
+ onPick: (mz: number) => void;
37
+ }
38
+
39
+ /**
40
+ * The peaks, one row each, under a header that sorts them.
41
+ *
42
+ * Only the rows in view are drawn: a table opened onto a whole Orbitrap scan is
43
+ * a thousand rows, and every one of them would otherwise be laid out again on
44
+ * every hover of the chart beside it.
45
+ * @param props - Component props.
46
+ * @returns The table.
47
+ */
48
+ export function PeakTable(props: PeakTableProps) {
49
+ const {
50
+ peaks,
51
+ mzDecimals,
52
+ sortKey,
53
+ onSort,
54
+ highlightMz,
55
+ onHighlight,
56
+ onPick,
57
+ } = props;
58
+ const scrollRef = useRef<HTMLDivElement>(null);
59
+
60
+ const ordered = useMemo(
61
+ () =>
62
+ sortKey === 'mz'
63
+ ? peaks
64
+ : peaks.toSorted((first, second) => second.y - first.y),
65
+ [peaks, sortKey],
66
+ );
67
+ const rows = useVirtualRows(scrollRef, ordered.length, ROW_HEIGHT);
68
+ const showsCharge = useMemo(
69
+ () => peaks.some((peak) => peak.charge !== 0),
70
+ [peaks],
71
+ );
72
+
73
+ return (
74
+ <div ref={scrollRef} style={panelScrollAreaStyle}>
75
+ <table style={panelTableStyle}>
76
+ <thead>
77
+ <tr>
78
+ <th style={panelStickyHeaderStyle}>
79
+ <button
80
+ type="button"
81
+ style={panelColumnButtonStyle}
82
+ onClick={() => onSort('mz')}
83
+ >
84
+ m/z{sortKey === 'mz' ? ' ▲' : ''}
85
+ </button>
86
+ </th>
87
+ <th style={panelStickyHeaderStyle}>
88
+ <button
89
+ type="button"
90
+ style={panelColumnButtonStyle}
91
+ onClick={() => onSort('intensity')}
92
+ >
93
+ intensity{sortKey === 'intensity' ? ' ▼' : ''}
94
+ </button>
95
+ </th>
96
+ {showsCharge ? (
97
+ <th style={panelStickyHeaderStyle}>
98
+ <span style={panelColumnButtonStyle}>z</span>
99
+ </th>
100
+ ) : null}
101
+ </tr>
102
+ </thead>
103
+ <tbody onPointerLeave={() => onHighlight(null)}>
104
+ {rows.before > 0 ? <tr style={{ height: rows.before }} /> : null}
105
+ {rows.indices.map((index) => {
106
+ const peak = ordered[index] as MassPeakObject;
107
+ return (
108
+ <PeakRow
109
+ key={peak.x}
110
+ index={index}
111
+ peak={peak}
112
+ mzDecimals={mzDecimals}
113
+ showsCharge={showsCharge}
114
+ isHighlighted={peak.x === highlightMz}
115
+ measure={rows.measure}
116
+ onHighlight={onHighlight}
117
+ onPick={onPick}
118
+ />
119
+ );
120
+ })}
121
+ {rows.after > 0 ? <tr style={{ height: rows.after }} /> : null}
122
+ </tbody>
123
+ </table>
124
+ </div>
125
+ );
126
+ }
127
+
128
+ interface PeakRowProps {
129
+ /** Where the row sits in the list, which is how its height is found again. */
130
+ index: number;
131
+ /** The peak. */
132
+ peak: MassPeakObject;
133
+ /** How many decimals the mass is written with. */
134
+ mzDecimals: number;
135
+ /** Whether the charge column is drawn. */
136
+ showsCharge: boolean;
137
+ /** Whether the pointer is resting on this peak, here or on the chart. */
138
+ isHighlighted: boolean;
139
+ /** Reports the row's height. */
140
+ measure: (node: HTMLElement | null) => void;
141
+ /** Told the peak's m/z when the pointer comes to rest on the row. */
142
+ onHighlight: (mz: number | null) => void;
143
+ /** Frames the peak on the chart. */
144
+ onPick: (mz: number) => void;
145
+ }
146
+
147
+ /**
148
+ * One peak. Memoised, because a hover on the chart moves the highlight and only
149
+ * the row it left and the row it reached have anything new to draw.
150
+ */
151
+ const PeakRow = memo(function PeakRow(props: PeakRowProps) {
152
+ const {
153
+ index,
154
+ peak,
155
+ mzDecimals,
156
+ showsCharge,
157
+ isHighlighted,
158
+ measure,
159
+ onHighlight,
160
+ onPick,
161
+ } = props;
162
+ return (
163
+ <tr
164
+ ref={measure}
165
+ data-index={index}
166
+ style={isHighlighted ? highlightedRowStyle : rowStyle}
167
+ title="Click to frame this peak on the chart"
168
+ // Reachable by Tab as well as by the pointer: framing a peak is the one
169
+ // thing a row does, and a keyboard has to be able to ask for it.
170
+ tabIndex={0}
171
+ onPointerEnter={() => onHighlight(peak.x)}
172
+ onFocus={() => onHighlight(peak.x)}
173
+ onClick={() => onPick(peak.x)}
174
+ onKeyDown={(event) => {
175
+ if (event.key !== 'Enter' && event.key !== ' ') return;
176
+ event.preventDefault();
177
+ onPick(peak.x);
178
+ }}
179
+ >
180
+ <td style={panelCellStyle}>{formatMz(peak.x, mzDecimals)}</td>
181
+ <td style={panelNumberCellStyle}>
182
+ {formatIntensity(peak.y, mzDecimals)}
183
+ </td>
184
+ {showsCharge ? (
185
+ <td style={panelNumberCellStyle}>
186
+ {peak.charge === 0 ? '' : peak.charge}
187
+ </td>
188
+ ) : null}
189
+ </tr>
190
+ );
191
+ });
192
+
193
+ /** What one row is worth before one has been measured. */
194
+ const ROW_HEIGHT = 18;
195
+
196
+ const rowStyle = { cursor: 'pointer' } as const;
197
+
198
+ /** The row of the peak being looked at, wherever it was pointed at. */
199
+ const highlightedRowStyle = { ...rowStyle, background: '#e8f1fb' } as const;
@@ -0,0 +1,182 @@
1
+ import { useCallback, useMemo, useState } from 'react';
2
+ import { SelectedTotal, Toolbar } from 'react-science/ui';
3
+
4
+ import { useCopyToClipboard } from '../../clipboard/ui/useCopyToClipboard.ts';
5
+ import {
6
+ panelBodyStyle,
7
+ panelEmptyStyle,
8
+ panelStyle,
9
+ panelToolbarCountStyle,
10
+ panelToolbarStyle,
11
+ } from '../../panel/core/panelStyles.ts';
12
+ import { mzFrame } from '../core/massDomain.ts';
13
+ import {
14
+ PEAK_TABLE_LIMIT,
15
+ PEAK_TABLE_THRESHOLD,
16
+ peakTableRows,
17
+ peakTableToTsv,
18
+ } from '../core/peakTable.ts';
19
+
20
+ import { MzDecimalsMenu } from './MzDecimalsMenu.tsx';
21
+ import type { PeakSortKey } from './PeakTable.tsx';
22
+ import { PeakTable } from './PeakTable.tsx';
23
+ import { useMassCommandProps } from './massCommandContext.tsx';
24
+ import { useMassActions, useMassEditorState } from './massStateContext.ts';
25
+
26
+ export interface PeaksPanelProps {
27
+ /**
28
+ * The m/z of the peak the pointer is resting on, wherever it was hovered.
29
+ * @default null
30
+ */
31
+ highlightMz?: number | null;
32
+ /**
33
+ * Told which peak a row the pointer rests on is, `null` when it leaves.
34
+ * @default undefined
35
+ */
36
+ onHighlight?: (mz: number | null) => void;
37
+ }
38
+
39
+ /**
40
+ * What is actually in the selected spectrum, peak by peak.
41
+ *
42
+ * The centroid rather than the profile, because the centroid is what every
43
+ * number downstream is computed from — a profile lists the dozens of points one
44
+ * ion's peak shape covers, and none of them is the ion. For a profile these are
45
+ * the peaks the picking found in it.
46
+ *
47
+ * The window is the chart's by default: zoom into a cluster and the question
48
+ * becomes what is in *that* cluster, and a table that went on listing every row
49
+ * would have to be searched for the answer the chart is already pointing at. A
50
+ * floor of a hundredth of the base peak leaves the baseline out, and both are a
51
+ * toggle away. Resting on a row lights the peak on the chart, and clicking one
52
+ * frames it there.
53
+ * @param props - Component props.
54
+ * @returns The panel.
55
+ */
56
+ export function PeaksPanel(props: PeaksPanelProps) {
57
+ const { highlightMz = null, onHighlight } = props;
58
+ const {
59
+ state,
60
+ visibleSpectra,
61
+ selectedSpectrum,
62
+ mzDecimals,
63
+ autoMzDecimals,
64
+ } = useMassEditorState();
65
+ const actions = useMassActions();
66
+ const command = useMassCommandProps();
67
+ const { domain } = state.view;
68
+ const { showLabels, showCharges } = state.settings;
69
+
70
+ const [inWindow, setInWindow] = useState(true);
71
+ const [withFloor, setWithFloor] = useState(true);
72
+ const [sortKey, setSortKey] = useState<PeakSortKey>('mz');
73
+ const { copied, copy } = useCopyToClipboard();
74
+
75
+ const peaks = useMemo(
76
+ () =>
77
+ selectedSpectrum === null
78
+ ? []
79
+ : peakTableRows(selectedSpectrum, {
80
+ domain: inWindow ? domain : null,
81
+ threshold: withFloor ? PEAK_TABLE_THRESHOLD : 0,
82
+ }),
83
+ [selectedSpectrum, inWindow, domain, withFloor],
84
+ );
85
+
86
+ // Stable across a pointer move, so the memoised rows survive one.
87
+ const onPick = useCallback(
88
+ (mz: number) => actions.setDomain(mzFrame(mz, visibleSpectra, domain)),
89
+ [actions, visibleSpectra, domain],
90
+ );
91
+ const highlight = useCallback(
92
+ (mz: number | null) => onHighlight?.(mz),
93
+ [onHighlight],
94
+ );
95
+
96
+ const total = selectedSpectrum?.centroid.x.length ?? 0;
97
+
98
+ return (
99
+ <div style={panelStyle}>
100
+ <div style={panelToolbarStyle}>
101
+ <Toolbar aria-label="Peaks">
102
+ <Toolbar.Item
103
+ icon="zoom-to-fit"
104
+ active={inWindow}
105
+ tooltip="Only the peaks the chart is showing"
106
+ aria-label="Only the peaks the chart is showing"
107
+ onClick={() => setInWindow(!inWindow)}
108
+ />
109
+ <Toolbar.Item
110
+ icon="filter"
111
+ active={withFloor}
112
+ tooltip="Leave out the peaks under 1 % of the base peak"
113
+ aria-label="Leave out the peaks under 1 % of the base peak"
114
+ onClick={() => setWithFloor(!withFloor)}
115
+ />
116
+ <Toolbar.Item
117
+ icon="label"
118
+ active={showLabels}
119
+ {...command('toggleLabels')}
120
+ />
121
+ <Toolbar.Item
122
+ icon="numerical"
123
+ active={showCharges}
124
+ {...command('toggleCharges')}
125
+ />
126
+ <MzDecimalsMenu
127
+ setting={state.settings.mzDecimals}
128
+ autoDecimals={autoMzDecimals}
129
+ onChange={(setting) => actions.setSettings({ mzDecimals: setting })}
130
+ />
131
+ <Toolbar.Item
132
+ icon={copied ? 'tick' : 'duplicate'}
133
+ tooltip="Copy the rows as tab-separated text"
134
+ aria-label="Copy the rows as tab-separated text"
135
+ disabled={peaks.length === 0}
136
+ onClick={() => void copy(peakTableToTsv(peaks, mzDecimals))}
137
+ />
138
+ </Toolbar>
139
+ <div
140
+ style={panelToolbarCountStyle}
141
+ title={`${peaks.length} of the ${total} peaks of this spectrum listed`}
142
+ >
143
+ <SelectedTotal count={peaks.length} total={total} />
144
+ </div>
145
+ </div>
146
+
147
+ <div style={panelBodyStyle}>
148
+ {selectedSpectrum === null ? (
149
+ <p style={panelEmptyStyle}>
150
+ No spectrum is selected. Click one in the Spectra panel and its
151
+ peaks are listed here.
152
+ </p>
153
+ ) : peaks.length === 0 ? (
154
+ <p style={panelEmptyStyle}>
155
+ No peak stands in the window above the floor. Zoom out, or switch
156
+ the window or the floor off in the toolbar.
157
+ </p>
158
+ ) : (
159
+ <>
160
+ {peaks.length === PEAK_TABLE_LIMIT ? (
161
+ <p style={noteStyle}>
162
+ The {PEAK_TABLE_LIMIT} most intense peaks are listed. Zoom in to
163
+ list the rest.
164
+ </p>
165
+ ) : null}
166
+ <PeakTable
167
+ peaks={peaks}
168
+ mzDecimals={mzDecimals}
169
+ sortKey={sortKey}
170
+ onSort={setSortKey}
171
+ highlightMz={highlightMz}
172
+ onHighlight={highlight}
173
+ onPick={onPick}
174
+ />
175
+ </>
176
+ )}
177
+ </div>
178
+ </div>
179
+ );
180
+ }
181
+
182
+ const noteStyle = { margin: 0, fontSize: 11, opacity: 0.7 } as const;