react-cheminfo 0.65.0 → 0.67.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 (466) hide show
  1. package/README.md +33 -17
  2. package/lib/download/ui/FigureDownloadPanel.d.ts +7 -1
  3. package/lib/download/ui/FigureDownloadPanel.d.ts.map +1 -1
  4. package/lib/download/ui/FigureDownloadPanel.js +2 -2
  5. package/lib/download/ui/FigureDownloadPanel.js.map +1 -1
  6. package/lib/ecosystem/core/sites.js +3 -3
  7. package/lib/ecosystem/core/sites.js.map +1 -1
  8. package/lib/ecosystem/core/types.d.ts +1 -1
  9. package/lib/ecosystem/core/types.d.ts.map +1 -1
  10. package/lib/ecosystem/ui/glyphs.js +1 -1
  11. package/lib/ecosystem/ui/glyphs.js.map +1 -1
  12. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  13. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  14. package/lib/i18n/core/messageCatalog.d.ts +2 -2
  15. package/lib/i18n/vite/localeCatalog.d.ts +1 -1
  16. package/lib/ir/core/analysisSpectra.d.ts +23 -6
  17. package/lib/ir/core/analysisSpectra.d.ts.map +1 -1
  18. package/lib/ir/core/analysisSpectra.js.map +1 -1
  19. package/lib/ir/core/bandLabelPlan.d.ts.map +1 -1
  20. package/lib/ir/core/bandLabelPlan.js +11 -6
  21. package/lib/ir/core/bandLabelPlan.js.map +1 -1
  22. package/lib/ir/core/index.d.ts +15 -11
  23. package/lib/ir/core/index.d.ts.map +1 -1
  24. package/lib/ir/core/index.js +9 -6
  25. package/lib/ir/core/index.js.map +1 -1
  26. package/lib/ir/core/irBand.d.ts +45 -14
  27. package/lib/ir/core/irBand.d.ts.map +1 -1
  28. package/lib/ir/core/irBand.js +28 -6
  29. package/lib/ir/core/irBand.js.map +1 -1
  30. package/lib/ir/core/irCommands.d.ts +11 -0
  31. package/lib/ir/core/irCommands.d.ts.map +1 -1
  32. package/lib/ir/core/irCommands.js +11 -1
  33. package/lib/ir/core/irCommands.js.map +1 -1
  34. package/lib/ir/core/irDomain.d.ts +4 -3
  35. package/lib/ir/core/irDomain.d.ts.map +1 -1
  36. package/lib/ir/core/irDomain.js +10 -7
  37. package/lib/ir/core/irDomain.js.map +1 -1
  38. package/lib/ir/core/irEditorApi.d.ts +12 -0
  39. package/lib/ir/core/irEditorApi.d.ts.map +1 -1
  40. package/lib/ir/core/irFormat.d.ts +14 -2
  41. package/lib/ir/core/irFormat.d.ts.map +1 -1
  42. package/lib/ir/core/irFormat.js +33 -4
  43. package/lib/ir/core/irFormat.js.map +1 -1
  44. package/lib/ir/core/irMode.d.ts +35 -8
  45. package/lib/ir/core/irMode.d.ts.map +1 -1
  46. package/lib/ir/core/irMode.js +38 -10
  47. package/lib/ir/core/irMode.js.map +1 -1
  48. package/lib/ir/core/irReducer.d.ts +2 -30
  49. package/lib/ir/core/irReducer.d.ts.map +1 -1
  50. package/lib/ir/core/irReducer.js +1 -24
  51. package/lib/ir/core/irReducer.js.map +1 -1
  52. package/lib/ir/core/irSidePanels.d.ts +7 -1
  53. package/lib/ir/core/irSidePanels.d.ts.map +1 -1
  54. package/lib/ir/core/irSpectrum.d.ts +52 -26
  55. package/lib/ir/core/irSpectrum.d.ts.map +1 -1
  56. package/lib/ir/core/irSpectrum.js +21 -15
  57. package/lib/ir/core/irSpectrum.js.map +1 -1
  58. package/lib/ir/core/irState.d.ts +46 -5
  59. package/lib/ir/core/irState.d.ts.map +1 -1
  60. package/lib/ir/core/irState.js +38 -1
  61. package/lib/ir/core/irState.js.map +1 -1
  62. package/lib/ir/core/irTechnique.d.ts +94 -0
  63. package/lib/ir/core/irTechnique.d.ts.map +1 -0
  64. package/lib/ir/core/irTechnique.js +87 -0
  65. package/lib/ir/core/irTechnique.js.map +1 -0
  66. package/lib/ir/core/irTechniqueCommands.d.ts +26 -0
  67. package/lib/ir/core/irTechniqueCommands.d.ts.map +1 -0
  68. package/lib/ir/core/irTechniqueCommands.js +68 -0
  69. package/lib/ir/core/irTechniqueCommands.js.map +1 -0
  70. package/lib/ir/core/pickBands.d.ts +6 -5
  71. package/lib/ir/core/pickBands.d.ts.map +1 -1
  72. package/lib/ir/core/pickBands.js +49 -26
  73. package/lib/ir/core/pickBands.js.map +1 -1
  74. package/lib/ir/core/ramanBands.d.ts +30 -0
  75. package/lib/ir/core/ramanBands.d.ts.map +1 -0
  76. package/lib/ir/core/ramanBands.js +83 -0
  77. package/lib/ir/core/ramanBands.js.map +1 -0
  78. package/lib/ir/core/spectrumJcamp.d.ts +10 -5
  79. package/lib/ir/core/spectrumJcamp.d.ts.map +1 -1
  80. package/lib/ir/core/spectrumJcamp.js +63 -15
  81. package/lib/ir/core/spectrumJcamp.js.map +1 -1
  82. package/lib/ir/core/toIrSpectrum.d.ts.map +1 -1
  83. package/lib/ir/core/toIrSpectrum.js +17 -2
  84. package/lib/ir/core/toIrSpectrum.js.map +1 -1
  85. package/lib/ir/ui/BandRow.d.ts +30 -0
  86. package/lib/ir/ui/BandRow.d.ts.map +1 -0
  87. package/lib/ir/ui/BandRow.js +42 -0
  88. package/lib/ir/ui/BandRow.js.map +1 -0
  89. package/lib/ir/ui/BandsPanel.d.ts +4 -0
  90. package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
  91. package/lib/ir/ui/BandsPanel.js +14 -59
  92. package/lib/ir/ui/BandsPanel.js.map +1 -1
  93. package/lib/ir/ui/IrAboutDialog.d.ts +7 -0
  94. package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
  95. package/lib/ir/ui/IrAboutDialog.js +16 -3
  96. package/lib/ir/ui/IrAboutDialog.js.map +1 -1
  97. package/lib/ir/ui/IrCanvas.d.ts +7 -0
  98. package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
  99. package/lib/ir/ui/IrCanvas.js +9 -4
  100. package/lib/ir/ui/IrCanvas.js.map +1 -1
  101. package/lib/ir/ui/IrChart.d.ts +2 -1
  102. package/lib/ir/ui/IrChart.d.ts.map +1 -1
  103. package/lib/ir/ui/IrChart.js +22 -21
  104. package/lib/ir/ui/IrChart.js.map +1 -1
  105. package/lib/ir/ui/IrCommandProvider.d.ts +7 -0
  106. package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -1
  107. package/lib/ir/ui/IrCommandProvider.js +2 -2
  108. package/lib/ir/ui/IrCommandProvider.js.map +1 -1
  109. package/lib/ir/ui/IrCommandTooltip.d.ts +7 -0
  110. package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -1
  111. package/lib/ir/ui/IrCommandTooltip.js +3 -2
  112. package/lib/ir/ui/IrCommandTooltip.js.map +1 -1
  113. package/lib/ir/ui/IrDocumentationDialog.d.ts +8 -1
  114. package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -1
  115. package/lib/ir/ui/IrDocumentationDialog.js +30 -7
  116. package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
  117. package/lib/ir/ui/IrEditor.d.ts +25 -5
  118. package/lib/ir/ui/IrEditor.d.ts.map +1 -1
  119. package/lib/ir/ui/IrEditor.js +3 -20
  120. package/lib/ir/ui/IrEditor.js.map +1 -1
  121. package/lib/ir/ui/IrHeader.d.ts.map +1 -1
  122. package/lib/ir/ui/IrHeader.js +5 -1
  123. package/lib/ir/ui/IrHeader.js.map +1 -1
  124. package/lib/ir/ui/IrLogo.d.ts +11 -3
  125. package/lib/ir/ui/IrLogo.d.ts.map +1 -1
  126. package/lib/ir/ui/IrLogo.js +14 -5
  127. package/lib/ir/ui/IrLogo.js.map +1 -1
  128. package/lib/ir/ui/IrShell.d.ts +9 -1
  129. package/lib/ir/ui/IrShell.d.ts.map +1 -1
  130. package/lib/ir/ui/IrShell.js +26 -74
  131. package/lib/ir/ui/IrShell.js.map +1 -1
  132. package/lib/ir/ui/IrSidePanel.d.ts +11 -0
  133. package/lib/ir/ui/IrSidePanel.d.ts.map +1 -1
  134. package/lib/ir/ui/IrSidePanel.js +12 -3
  135. package/lib/ir/ui/IrSidePanel.js.map +1 -1
  136. package/lib/ir/ui/IrStatusBar.d.ts +3 -2
  137. package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
  138. package/lib/ir/ui/IrStatusBar.js +14 -9
  139. package/lib/ir/ui/IrStatusBar.js.map +1 -1
  140. package/lib/ir/ui/IrToolbar.d.ts +3 -0
  141. package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
  142. package/lib/ir/ui/IrToolbar.js +10 -3
  143. package/lib/ir/ui/IrToolbar.js.map +1 -1
  144. package/lib/ir/ui/IrTraces.d.ts +4 -1
  145. package/lib/ir/ui/IrTraces.d.ts.map +1 -1
  146. package/lib/ir/ui/IrTraces.js +2 -0
  147. package/lib/ir/ui/IrTraces.js.map +1 -1
  148. package/lib/ir/ui/RamanEditor.d.ts +64 -0
  149. package/lib/ir/ui/RamanEditor.d.ts.map +1 -0
  150. package/lib/ir/ui/RamanEditor.js +17 -0
  151. package/lib/ir/ui/RamanEditor.js.map +1 -0
  152. package/lib/ir/ui/SpectraPanel.d.ts.map +1 -1
  153. package/lib/ir/ui/SpectraPanel.js +2 -2
  154. package/lib/ir/ui/SpectraPanel.js.map +1 -1
  155. package/lib/ir/ui/SpectrumRow.d.ts +7 -0
  156. package/lib/ir/ui/SpectrumRow.d.ts.map +1 -1
  157. package/lib/ir/ui/SpectrumRow.js +4 -5
  158. package/lib/ir/ui/SpectrumRow.js.map +1 -1
  159. package/lib/ir/ui/VibrationalEditor.d.ts +62 -0
  160. package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -0
  161. package/lib/ir/ui/VibrationalEditor.js +33 -0
  162. package/lib/ir/ui/VibrationalEditor.js.map +1 -0
  163. package/lib/ir/ui/bandsTsv.d.ts +19 -0
  164. package/lib/ir/ui/bandsTsv.d.ts.map +1 -0
  165. package/lib/ir/ui/bandsTsv.js +38 -0
  166. package/lib/ir/ui/bandsTsv.js.map +1 -0
  167. package/lib/ir/ui/index.d.ts +1 -0
  168. package/lib/ir/ui/index.d.ts.map +1 -1
  169. package/lib/ir/ui/index.js.map +1 -1
  170. package/lib/ir/ui/irActions.d.ts +3 -3
  171. package/lib/ir/ui/irActions.d.ts.map +1 -1
  172. package/lib/ir/ui/irChartProps.d.ts +21 -4
  173. package/lib/ir/ui/irChartProps.d.ts.map +1 -1
  174. package/lib/ir/ui/irChartProps.js +3 -2
  175. package/lib/ir/ui/irChartProps.js.map +1 -1
  176. package/lib/ir/ui/irCommandContext.d.ts +8 -0
  177. package/lib/ir/ui/irCommandContext.d.ts.map +1 -1
  178. package/lib/ir/ui/irCommandContext.js +14 -3
  179. package/lib/ir/ui/irCommandContext.js.map +1 -1
  180. package/lib/ir/ui/irHostPanels.d.ts +53 -0
  181. package/lib/ir/ui/irHostPanels.d.ts.map +1 -0
  182. package/lib/ir/ui/irHostPanels.js +41 -0
  183. package/lib/ir/ui/irHostPanels.js.map +1 -0
  184. package/lib/ir/ui/useIrEditor.d.ts +3 -3
  185. package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
  186. package/lib/ir/ui/useIrEditor.js +13 -4
  187. package/lib/ir/ui/useIrEditor.js.map +1 -1
  188. package/lib/ir/ui/useIrHandle.d.ts +14 -0
  189. package/lib/ir/ui/useIrHandle.d.ts.map +1 -0
  190. package/lib/ir/ui/useIrHandle.js +39 -0
  191. package/lib/ir/ui/useIrHandle.js.map +1 -0
  192. package/lib/ir/ui/useIrSide.d.ts +27 -0
  193. package/lib/ir/ui/useIrSide.d.ts.map +1 -0
  194. package/lib/ir/ui/useIrSide.js +42 -0
  195. package/lib/ir/ui/useIrSide.js.map +1 -0
  196. package/lib/ir/ui/useIrText.d.ts +40 -0
  197. package/lib/ir/ui/useIrText.d.ts.map +1 -0
  198. package/lib/ir/ui/useIrText.js +118 -0
  199. package/lib/ir/ui/useIrText.js.map +1 -0
  200. package/lib/ir/ui/useIrZoom.d.ts +15 -0
  201. package/lib/ir/ui/useIrZoom.d.ts.map +1 -1
  202. package/lib/ir/ui/useIrZoom.js +6 -4
  203. package/lib/ir/ui/useIrZoom.js.map +1 -1
  204. package/lib/ir/ui/useValueAxisZoom.d.ts +20 -0
  205. package/lib/ir/ui/useValueAxisZoom.d.ts.map +1 -0
  206. package/lib/ir/ui/useValueAxisZoom.js +54 -0
  207. package/lib/ir/ui/useValueAxisZoom.js.map +1 -0
  208. package/lib/ir.d.ts +3 -0
  209. package/lib/ir.d.ts.map +1 -1
  210. package/lib/ir.js +3 -0
  211. package/lib/ir.js.map +1 -1
  212. package/lib/locales/de.json +29 -2
  213. package/lib/locales/en.json +29 -2
  214. package/lib/locales/es.json +29 -2
  215. package/lib/locales/fr.json +29 -2
  216. package/lib/locales/it.json +29 -2
  217. package/lib/molecule3d/core/animatedPng.d.ts +25 -0
  218. package/lib/molecule3d/core/animatedPng.d.ts.map +1 -0
  219. package/lib/molecule3d/core/animatedPng.js +59 -0
  220. package/lib/molecule3d/core/animatedPng.js.map +1 -0
  221. package/lib/molecule3d/core/file.d.ts +24 -0
  222. package/lib/molecule3d/core/file.d.ts.map +1 -0
  223. package/lib/molecule3d/core/file.js +2 -0
  224. package/lib/molecule3d/core/file.js.map +1 -0
  225. package/lib/molecule3d/core/index.d.ts +4 -1
  226. package/lib/molecule3d/core/index.d.ts.map +1 -1
  227. package/lib/molecule3d/core/index.js +1 -0
  228. package/lib/molecule3d/core/index.js.map +1 -1
  229. package/lib/molecule3d/core/settings.d.ts +0 -7
  230. package/lib/molecule3d/core/settings.d.ts.map +1 -1
  231. package/lib/molecule3d/core/settings.js.map +1 -1
  232. package/lib/molecule3d/ui/Molecule3DExport.d.ts +10 -2
  233. package/lib/molecule3d/ui/Molecule3DExport.d.ts.map +1 -1
  234. package/lib/molecule3d/ui/Molecule3DExport.js +15 -2
  235. package/lib/molecule3d/ui/Molecule3DExport.js.map +1 -1
  236. package/lib/molecule3d/ui/Molecule3DToolbar.js +9 -2
  237. package/lib/molecule3d/ui/Molecule3DToolbar.js.map +1 -1
  238. package/lib/molecule3d/ui/MoleculeCanvas3D.d.ts.map +1 -1
  239. package/lib/molecule3d/ui/MoleculeCanvas3D.js +23 -41
  240. package/lib/molecule3d/ui/MoleculeCanvas3D.js.map +1 -1
  241. package/lib/molecule3d/ui/drawScene.d.ts +2 -1
  242. package/lib/molecule3d/ui/drawScene.d.ts.map +1 -1
  243. package/lib/molecule3d/ui/drawScene.js.map +1 -1
  244. package/lib/molecule3d/ui/exportMoleculeImage.d.ts +15 -1
  245. package/lib/molecule3d/ui/exportMoleculeImage.d.ts.map +1 -1
  246. package/lib/molecule3d/ui/exportMoleculeImage.js +14 -2
  247. package/lib/molecule3d/ui/exportMoleculeImage.js.map +1 -1
  248. package/lib/molecule3d/ui/moleculeFrames.d.ts +47 -0
  249. package/lib/molecule3d/ui/moleculeFrames.d.ts.map +1 -0
  250. package/lib/molecule3d/ui/moleculeFrames.js +65 -0
  251. package/lib/molecule3d/ui/moleculeFrames.js.map +1 -0
  252. package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts +14 -1
  253. package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts.map +1 -1
  254. package/lib/molecule3d/ui/renderMolecule.d.ts +3 -3
  255. package/lib/molecule3d/ui/renderMolecule.d.ts.map +1 -1
  256. package/lib/molecule3d/ui/renderMolecule.js +2 -1
  257. package/lib/molecule3d/ui/renderMolecule.js.map +1 -1
  258. package/lib/molecule3d/ui/sceneDrawer.d.ts +2 -1
  259. package/lib/molecule3d/ui/sceneDrawer.d.ts.map +1 -1
  260. package/lib/molecule3d/ui/sceneDrawer.js +9 -1
  261. package/lib/molecule3d/ui/sceneDrawer.js.map +1 -1
  262. package/lib/molecule3d/ui/useImageExport.d.ts +8 -3
  263. package/lib/molecule3d/ui/useImageExport.d.ts.map +1 -1
  264. package/lib/molecule3d/ui/useImageExport.js +13 -4
  265. package/lib/molecule3d/ui/useImageExport.js.map +1 -1
  266. package/lib/molecule3d/ui/useMoleculeScene.d.ts +2 -1
  267. package/lib/molecule3d/ui/useMoleculeScene.d.ts.map +1 -1
  268. package/lib/molecule3d/ui/useMoleculeScene.js.map +1 -1
  269. package/lib/molecule3d/ui/useMoleculeViewer.d.ts +16 -0
  270. package/lib/molecule3d/ui/useMoleculeViewer.d.ts.map +1 -0
  271. package/lib/molecule3d/ui/useMoleculeViewer.js +37 -0
  272. package/lib/molecule3d/ui/useMoleculeViewer.js.map +1 -0
  273. package/lib/molecule3d/ui/usePolarSurfaceArea.d.ts +3 -3
  274. package/lib/molecule3d/ui/usePolarSurfaceArea.d.ts.map +1 -1
  275. package/lib/molecule3d/ui/usePolarSurfaceArea.js +4 -3
  276. package/lib/molecule3d/ui/usePolarSurfaceArea.js.map +1 -1
  277. package/lib/molecule3d/ui/viewer.d.ts +4 -1
  278. package/lib/molecule3d/ui/viewer.d.ts.map +1 -1
  279. package/lib/molecule3d/ui/viewer.js +21 -19
  280. package/lib/molecule3d/ui/viewer.js.map +1 -1
  281. package/lib/molecule3d/ui/viewerTypes.d.ts +6 -0
  282. package/lib/molecule3d/ui/viewerTypes.d.ts.map +1 -1
  283. package/lib/molstar/core/captureScene.d.ts +19 -1
  284. package/lib/molstar/core/captureScene.d.ts.map +1 -1
  285. package/lib/molstar/core/captureScene.js +57 -2
  286. package/lib/molstar/core/captureScene.js.map +1 -1
  287. package/lib/molstar/core/index.d.ts +5 -2
  288. package/lib/molstar/core/index.d.ts.map +1 -1
  289. package/lib/molstar/core/index.js +4 -2
  290. package/lib/molstar/core/index.js.map +1 -1
  291. package/lib/molstar/core/trajectory.d.ts +56 -0
  292. package/lib/molstar/core/trajectory.d.ts.map +1 -0
  293. package/lib/molstar/core/trajectory.js +96 -0
  294. package/lib/molstar/core/trajectory.js.map +1 -0
  295. package/lib/panel/ui/PanelRail.d.ts.map +1 -1
  296. package/lib/panel/ui/PanelRail.js +1 -1
  297. package/lib/panel/ui/PanelRail.js.map +1 -1
  298. package/lib/raman.d.ts +17 -0
  299. package/lib/raman.d.ts.map +1 -0
  300. package/lib/raman.js +12 -0
  301. package/lib/raman.js.map +1 -0
  302. package/lib/router/core/basePath.d.ts +2 -2
  303. package/lib/router/core/basePath.js +2 -2
  304. package/lib/router/core/siteAddresses.d.ts +1 -1
  305. package/lib/router/core/siteAddresses.js +1 -1
  306. package/lib/seo/core/siteFiles.js +1 -1
  307. package/lib/seo/core/siteFiles.js.map +1 -1
  308. package/lib/server/answerAddresses.d.ts +3 -3
  309. package/lib/server/answerAddresses.js +3 -3
  310. package/lib/structure/core/index.d.ts +2 -0
  311. package/lib/structure/core/index.d.ts.map +1 -1
  312. package/lib/structure/core/index.js +1 -0
  313. package/lib/structure/core/index.js.map +1 -1
  314. package/lib/structure/core/structureTransfer.d.ts +29 -0
  315. package/lib/structure/core/structureTransfer.d.ts.map +1 -0
  316. package/lib/structure/core/structureTransfer.js +26 -0
  317. package/lib/structure/core/structureTransfer.js.map +1 -0
  318. package/lib/structure/ui/EditorImportButton.d.ts +20 -0
  319. package/lib/structure/ui/EditorImportButton.d.ts.map +1 -0
  320. package/lib/structure/ui/EditorImportButton.js +24 -0
  321. package/lib/structure/ui/EditorImportButton.js.map +1 -0
  322. package/lib/structure/ui/EditorImportProblem.d.ts +17 -0
  323. package/lib/structure/ui/EditorImportProblem.d.ts.map +1 -0
  324. package/lib/structure/ui/EditorImportProblem.js +32 -0
  325. package/lib/structure/ui/EditorImportProblem.js.map +1 -0
  326. package/lib/structure/ui/StructureDrop.d.ts +39 -0
  327. package/lib/structure/ui/StructureDrop.d.ts.map +1 -0
  328. package/lib/structure/ui/StructureDrop.js +19 -0
  329. package/lib/structure/ui/StructureDrop.js.map +1 -0
  330. package/lib/structure/ui/StructureDropOverlay.d.ts +16 -0
  331. package/lib/structure/ui/StructureDropOverlay.d.ts.map +1 -0
  332. package/lib/structure/ui/StructureDropOverlay.js +29 -0
  333. package/lib/structure/ui/StructureDropOverlay.js.map +1 -0
  334. package/lib/structure/ui/StructureEditor.d.ts +3 -80
  335. package/lib/structure/ui/StructureEditor.d.ts.map +1 -1
  336. package/lib/structure/ui/StructureEditor.js +21 -33
  337. package/lib/structure/ui/StructureEditor.js.map +1 -1
  338. package/lib/structure/ui/importedStructure.d.ts +25 -0
  339. package/lib/structure/ui/importedStructure.d.ts.map +1 -0
  340. package/lib/structure/ui/importedStructure.js +74 -0
  341. package/lib/structure/ui/importedStructure.js.map +1 -0
  342. package/lib/structure/ui/index.d.ts +2 -0
  343. package/lib/structure/ui/index.d.ts.map +1 -1
  344. package/lib/structure/ui/index.js +1 -0
  345. package/lib/structure/ui/index.js.map +1 -1
  346. package/lib/structure/ui/structureEditorProps.d.ts +98 -0
  347. package/lib/structure/ui/structureEditorProps.d.ts.map +1 -0
  348. package/lib/structure/ui/structureEditorProps.js +2 -0
  349. package/lib/structure/ui/structureEditorProps.js.map +1 -0
  350. package/lib/structure/ui/useDebouncedChange.d.ts +16 -0
  351. package/lib/structure/ui/useDebouncedChange.d.ts.map +1 -0
  352. package/lib/structure/ui/useDebouncedChange.js +30 -0
  353. package/lib/structure/ui/useDebouncedChange.js.map +1 -0
  354. package/lib/structure/ui/useStructureDrop.d.ts +30 -0
  355. package/lib/structure/ui/useStructureDrop.d.ts.map +1 -0
  356. package/lib/structure/ui/useStructureDrop.js +49 -0
  357. package/lib/structure/ui/useStructureDrop.js.map +1 -0
  358. package/lib/structure/ui/useStructureImport.d.ts +45 -0
  359. package/lib/structure/ui/useStructureImport.d.ts.map +1 -0
  360. package/lib/structure/ui/useStructureImport.js +62 -0
  361. package/lib/structure/ui/useStructureImport.js.map +1 -0
  362. package/package.json +5 -1
  363. package/src/download/ui/FigureDownloadPanel.tsx +9 -2
  364. package/src/ecosystem/core/sites.ts +3 -3
  365. package/src/ecosystem/core/types.ts +1 -1
  366. package/src/ecosystem/ui/glyphs.tsx +1 -1
  367. package/src/i18n/core/messageCatalog.ts +2 -2
  368. package/src/i18n/vite/localeCatalog.ts +1 -1
  369. package/src/ir/core/analysisSpectra.ts +26 -10
  370. package/src/ir/core/bandLabelPlan.ts +21 -10
  371. package/src/ir/core/index.ts +31 -7
  372. package/src/ir/core/irBand.ts +52 -14
  373. package/src/ir/core/irCommands.ts +15 -1
  374. package/src/ir/core/irDomain.ts +9 -7
  375. package/src/ir/core/irEditorApi.ts +13 -0
  376. package/src/ir/core/irFormat.ts +39 -6
  377. package/src/ir/core/irMode.ts +42 -10
  378. package/src/ir/core/irReducer.ts +3 -51
  379. package/src/ir/core/irSidePanels.ts +8 -1
  380. package/src/ir/core/irSpectrum.ts +59 -30
  381. package/src/ir/core/irState.ts +73 -5
  382. package/src/ir/core/irTechnique.ts +115 -0
  383. package/src/ir/core/irTechniqueCommands.ts +82 -0
  384. package/src/ir/core/pickBands.ts +63 -28
  385. package/src/ir/core/ramanBands.ts +105 -0
  386. package/src/ir/core/spectrumJcamp.ts +65 -16
  387. package/src/ir/core/toIrSpectrum.ts +20 -2
  388. package/src/ir/ui/BandRow.tsx +107 -0
  389. package/src/ir/ui/BandsPanel.tsx +32 -125
  390. package/src/ir/ui/IrAboutDialog.tsx +69 -28
  391. package/src/ir/ui/IrCanvas.tsx +29 -3
  392. package/src/ir/ui/IrChart.tsx +31 -24
  393. package/src/ir/ui/IrCommandProvider.tsx +10 -3
  394. package/src/ir/ui/IrCommandTooltip.tsx +11 -2
  395. package/src/ir/ui/IrDocumentationDialog.tsx +99 -55
  396. package/src/ir/ui/IrEditor.tsx +27 -40
  397. package/src/ir/ui/IrHeader.tsx +10 -3
  398. package/src/ir/ui/IrLogo.tsx +28 -9
  399. package/src/ir/ui/IrShell.tsx +47 -96
  400. package/src/ir/ui/IrSidePanel.tsx +36 -10
  401. package/src/ir/ui/IrStatusBar.tsx +17 -12
  402. package/src/ir/ui/IrToolbar.tsx +26 -15
  403. package/src/ir/ui/IrTraces.tsx +5 -1
  404. package/src/ir/ui/RamanEditor.tsx +71 -0
  405. package/src/ir/ui/SpectraPanel.tsx +2 -1
  406. package/src/ir/ui/SpectrumRow.tsx +14 -5
  407. package/src/ir/ui/VibrationalEditor.tsx +113 -0
  408. package/src/ir/ui/bandsTsv.ts +46 -0
  409. package/src/ir/ui/index.ts +1 -0
  410. package/src/ir/ui/irActions.ts +3 -3
  411. package/src/ir/ui/irChartProps.ts +21 -4
  412. package/src/ir/ui/irCommandContext.tsx +18 -3
  413. package/src/ir/ui/irHostPanels.ts +76 -0
  414. package/src/ir/ui/useIrEditor.ts +20 -8
  415. package/src/ir/ui/useIrHandle.ts +51 -0
  416. package/src/ir/ui/useIrSide.ts +60 -0
  417. package/src/ir/ui/useIrText.ts +170 -0
  418. package/src/ir/ui/useIrZoom.ts +22 -3
  419. package/src/ir/ui/useValueAxisZoom.ts +67 -0
  420. package/src/ir.ts +3 -0
  421. package/src/locales/de.json +29 -2
  422. package/src/locales/en.json +29 -2
  423. package/src/locales/es.json +29 -2
  424. package/src/locales/fr.json +29 -2
  425. package/src/locales/it.json +29 -2
  426. package/src/molecule3d/core/animatedPng.ts +79 -0
  427. package/src/molecule3d/core/file.ts +23 -0
  428. package/src/molecule3d/core/index.ts +3 -1
  429. package/src/molecule3d/core/settings.ts +0 -8
  430. package/src/molecule3d/ui/Molecule3DExport.tsx +43 -5
  431. package/src/molecule3d/ui/Molecule3DToolbar.tsx +9 -2
  432. package/src/molecule3d/ui/MoleculeCanvas3D.tsx +24 -38
  433. package/src/molecule3d/ui/drawScene.ts +2 -1
  434. package/src/molecule3d/ui/exportMoleculeImage.ts +28 -3
  435. package/src/molecule3d/ui/moleculeFrames.ts +88 -0
  436. package/src/molecule3d/ui/moleculeViewer3DProps.ts +14 -5
  437. package/src/molecule3d/ui/renderMolecule.ts +5 -3
  438. package/src/molecule3d/ui/sceneDrawer.ts +14 -2
  439. package/src/molecule3d/ui/useImageExport.ts +22 -5
  440. package/src/molecule3d/ui/useMoleculeScene.ts +2 -1
  441. package/src/molecule3d/ui/useMoleculeViewer.ts +46 -0
  442. package/src/molecule3d/ui/usePolarSurfaceArea.ts +6 -4
  443. package/src/molecule3d/ui/viewer.ts +34 -27
  444. package/src/molecule3d/ui/viewerTypes.ts +6 -0
  445. package/src/molstar/core/captureScene.ts +85 -2
  446. package/src/molstar/core/index.ts +13 -2
  447. package/src/molstar/core/trajectory.ts +117 -0
  448. package/src/panel/ui/PanelRail.tsx +3 -0
  449. package/src/raman.ts +20 -0
  450. package/src/router/core/basePath.ts +2 -2
  451. package/src/router/core/siteAddresses.ts +1 -1
  452. package/src/seo/core/siteFiles.ts +1 -1
  453. package/src/server/answerAddresses.ts +3 -3
  454. package/src/structure/core/index.ts +8 -0
  455. package/src/structure/core/structureTransfer.ts +37 -0
  456. package/src/structure/ui/EditorImportButton.tsx +59 -0
  457. package/src/structure/ui/EditorImportProblem.tsx +63 -0
  458. package/src/structure/ui/StructureDrop.tsx +66 -0
  459. package/src/structure/ui/StructureDropOverlay.tsx +50 -0
  460. package/src/structure/ui/StructureEditor.tsx +49 -134
  461. package/src/structure/ui/importedStructure.ts +83 -0
  462. package/src/structure/ui/index.ts +2 -0
  463. package/src/structure/ui/structureEditorProps.ts +103 -0
  464. package/src/structure/ui/useDebouncedChange.ts +41 -0
  465. package/src/structure/ui/useStructureDrop.ts +76 -0
  466. package/src/structure/ui/useStructureImport.ts +122 -0
@@ -7,7 +7,8 @@
7
7
  * turned inside out, and a bare column of numbers leaves whoever opens it next
8
8
  * to guess which. `##YUNITS=` states it, and `ir-spectrum` reads it back and
9
9
  * derives the other axis from it, so a spectrum written here returns carrying
10
- * both.
10
+ * both. A Raman spectrum is written as its intensity, under a `##DATA TYPE=`
11
+ * that says it is Raman.
11
12
  *
12
13
  * The points are written as an `##PEAK TABLE=` of explicit `x y` pairs rather
13
14
  * than as a compressed `##XYDATA=` record. An XYDATA record states a first
@@ -20,6 +21,7 @@
20
21
  import { fromJSON } from 'convert-to-jcamp';
21
22
 
22
23
  import type { IrMode, IrSpectrum } from './irSpectrum.ts';
24
+ import { IR_TECHNIQUE_RULES, irModeTechnique } from './irTechnique.ts';
23
25
 
24
26
  /** The extension a written spectrum is saved under. */
25
27
  export const JCAMP_EXTENSION = '.jdx';
@@ -27,8 +29,8 @@ export const JCAMP_EXTENSION = '.jdx';
27
29
  /** What a JCAMP-DX file is served as. */
28
30
  export const JCAMP_MIME_TYPE = 'chemical/x-jcamp-dx';
29
31
 
30
- /** How the technique is named when the file that was read named nothing. */
31
- export const DEFAULT_DATA_TYPE = 'INFRARED SPECTRUM';
32
+ /** The infrared data type, written when the file that was read named none. */
33
+ export const DEFAULT_DATA_TYPE = IR_TECHNIQUE_RULES.infrared.dataType;
32
34
 
33
35
  /**
34
36
  * Write one spectrum as a JCAMP-DX block.
@@ -37,15 +39,20 @@ export const DEFAULT_DATA_TYPE = 'INFRARED SPECTRUM';
37
39
  * which that was, and only otherwise the one being read. Writing what is on
38
40
  * screen instead would export a spectrum that had been through a logarithm it
39
41
  * was never measured with — and, where a band bottoms out at zero transmittance,
40
- * an absorbance of infinity that no reader can take back.
42
+ * an absorbance of infinity that no reader can take back. A spectrum carrying
43
+ * neither falls back on whichever axis it does carry, so a Raman spectrum is
44
+ * written as its intensity.
41
45
  * @param spectrum - The spectrum.
42
46
  * @param mode - The axis being read, used when the file named none.
43
47
  * @returns The block, `##TITLE=` through `##END=`.
48
+ * @throws {Error} When the spectrum carries no value axis at all.
44
49
  */
45
50
  export function irSpectrumToJcamp(spectrum: IrSpectrum, mode: IrMode): string {
46
- const written = spectrum.origin.recorded ?? mode;
47
- const values =
48
- written === 'absorbance' ? spectrum.absorbance : spectrum.transmittance;
51
+ const written = writtenAxis(spectrum, mode);
52
+ const values = spectrum[written];
53
+ if (values === undefined) {
54
+ throw new Error(`${spectrum.name} carries no value axis to write.`);
55
+ }
49
56
  return fromJSON(
50
57
  { x: spectrum.wavenumber, y: values },
51
58
  { info: infoRecords(spectrum, written), meta: metaRecords(spectrum) },
@@ -67,13 +74,14 @@ export function irSpectrumToJcamp(spectrum: IrSpectrum, mode: IrMode): string {
67
74
  * spectrum would have written.
68
75
  * @param spectra - The spectra, in the order the list holds them.
69
76
  * @param mode - The axis being read, used for a spectrum whose file named none.
70
- * @param title - What to call the file's own outer block.
77
+ * @param title - What to call the file's own outer block. Defaults to the
78
+ * count and the technique that reads `mode`: `2 infrared spectra`.
71
79
  * @returns The file.
72
80
  */
73
81
  export function irSpectraToJcamp(
74
82
  spectra: readonly IrSpectrum[],
75
83
  mode: IrMode,
76
- title = `${spectra.length} infrared spectra`,
84
+ title = `${spectra.length} ${IR_TECHNIQUE_RULES[irModeTechnique(mode)].name} spectra`,
77
85
  ): string {
78
86
  const only = spectra.length === 1 ? spectra[0] : undefined;
79
87
  if (only !== undefined) return irSpectrumToJcamp(only, mode);
@@ -91,6 +99,32 @@ ${blocks.join('\n')}
91
99
  `;
92
100
  }
93
101
 
102
+ /**
103
+ * Which axis of a spectrum is written.
104
+ * @param spectrum - The spectrum.
105
+ * @param mode - The axis being read.
106
+ * @returns The axis its file recorded, else the one being read, else the first
107
+ * it carries; `mode` when it carries none, which the caller refuses.
108
+ */
109
+ function writtenAxis(spectrum: IrSpectrum, mode: IrMode): IrMode {
110
+ const { recorded } = spectrum.origin;
111
+ if (recorded !== undefined && spectrum[recorded] !== undefined) {
112
+ return recorded;
113
+ }
114
+ if (spectrum[mode] !== undefined) return mode;
115
+ for (const axis of WRITTEN_AXES) {
116
+ if (spectrum[axis] !== undefined) return axis;
117
+ }
118
+ return mode;
119
+ }
120
+
121
+ /** The axes a spectrum may carry, in the order one is looked for. */
122
+ const WRITTEN_AXES: readonly IrMode[] = [
123
+ 'transmittance',
124
+ 'absorbance',
125
+ 'intensity',
126
+ ];
127
+
94
128
  /**
95
129
  * The standard records of a block: what it is called, and what its axes are.
96
130
  * @param spectrum - The spectrum.
@@ -103,17 +137,32 @@ function infoRecords(
103
137
  ): Record<string, string> {
104
138
  return {
105
139
  title: recordValue(spectrum.name),
106
- // The technique as the file stated it, so a Raman spectrum that was opened
107
- // here is not written back out claiming to be infrared.
108
- dataType: technique(spectrum) ?? DEFAULT_DATA_TYPE,
140
+ // The technique as the file stated it, and otherwise the one the written
141
+ // axis belongs to, so a Raman spectrum is never written out claiming to be
142
+ // infrared.
143
+ dataType:
144
+ technique(spectrum) ??
145
+ IR_TECHNIQUE_RULES[irModeTechnique(written)].dataType,
109
146
  xUnits: '1/CM',
110
- // Spelled the way `ir-spectrum` reads it: it takes the axis to be
111
- // transmittance when the label says `trans`, and to be a percentage rather
112
- // than a fraction when it carries a `%`.
113
- yUnits: written === 'absorbance' ? 'ABSORBANCE' : 'Transmittance (%)',
147
+ yUnits: Y_UNITS[written],
114
148
  };
115
149
  }
116
150
 
151
+ /**
152
+ * What each axis is called in `##YUNITS=`.
153
+ *
154
+ * Spelled the way `ir-spectrum` reads them: it takes the axis to be
155
+ * transmittance when the label says `trans`, and to be a percentage rather than
156
+ * a fraction when it carries a `%`. A Raman intensity has no unit of its own —
157
+ * counts on one instrument, a fraction of the strongest band on another — so it
158
+ * is named, as Raman instruments write it.
159
+ */
160
+ const Y_UNITS: Record<IrMode, string> = {
161
+ transmittance: 'Transmittance (%)',
162
+ absorbance: 'ABSORBANCE',
163
+ intensity: 'INTENSITY',
164
+ };
165
+
117
166
  /**
118
167
  * The `$`-prefixed records of a block: the acquisition, as the file stated it.
119
168
  *
@@ -64,8 +64,7 @@ export function toIrSpectrum(
64
64
  name: name ?? loaded.name ?? loaded.origin.fileName ?? 'spectrum',
65
65
  color,
66
66
  wavenumber: loaded.wavenumber,
67
- absorbance: loaded.absorbance,
68
- transmittance: loaded.transmittance,
67
+ ...valueAxes(loaded),
69
68
  meta: loaded.meta,
70
69
  origin: loaded.origin,
71
70
  visible,
@@ -100,3 +99,22 @@ export function toIrSpectra(
100
99
  }
101
100
  return spectra;
102
101
  }
102
+
103
+ /**
104
+ * The value axes a loaded spectrum carries, and only those.
105
+ *
106
+ * An absent axis is an absent key, never a key holding `undefined`: the two
107
+ * read the same in a debugger and differently in every structural comparison.
108
+ * @param loaded - What the reader produced.
109
+ * @returns Its absorbance and transmittance, or its intensity.
110
+ */
111
+ function valueAxes(
112
+ loaded: LoadedIrSpectrum,
113
+ ): Pick<IrSpectrum, 'absorbance' | 'transmittance' | 'intensity'> {
114
+ const { absorbance, transmittance, intensity } = loaded;
115
+ return {
116
+ ...(absorbance === undefined ? {} : { absorbance }),
117
+ ...(transmittance === undefined ? {} : { transmittance }),
118
+ ...(intensity === undefined ? {} : { intensity }),
119
+ };
120
+ }
@@ -0,0 +1,107 @@
1
+ import { Icon } from '@blueprintjs/core';
2
+
3
+ import {
4
+ panelCellStyle,
5
+ panelNumberCellStyle,
6
+ } from '../../panel/core/panelStyles.ts';
7
+ import type { AssignedBand } from '../core/assignBands.ts';
8
+ import type { IrBand } from '../core/irBand.ts';
9
+ import { bandValue } from '../core/irBand.ts';
10
+ import { formatIrValue, formatWavenumber } from '../core/irFormat.ts';
11
+ import type { IrMode } from '../core/irSpectrum.ts';
12
+
13
+ export interface BandRowProps {
14
+ /** The band and everything it might be. */
15
+ entry: AssignedBand;
16
+ /** Which value axis is being read. */
17
+ mode: IrMode;
18
+ /** Whether the row has a column for what the band could be. */
19
+ assignments: boolean;
20
+ /** Whether the pointer is on this band, here or on the chart. */
21
+ lit: boolean;
22
+ /**
23
+ * Told when the pointer arrives on this row, and when it leaves.
24
+ * @default undefined
25
+ */
26
+ onHighlight?: (band: IrBand | null) => void;
27
+ }
28
+
29
+ /**
30
+ * One band: where it is, how strong, and every vibration it could be.
31
+ *
32
+ * The candidates are written as one line rather than a list, so a strong band
33
+ * with four of them stays one row of the table and the wavenumbers keep reading
34
+ * down the column. The `title` carries them again with each one's note, which is
35
+ * where the reason to prefer one lives.
36
+ * @param props - Component props.
37
+ * @returns The row.
38
+ */
39
+ export function BandRow(props: BandRowProps) {
40
+ const { entry, mode, assignments, lit, onHighlight } = props;
41
+ const { band } = entry;
42
+
43
+ return (
44
+ <tr
45
+ style={lit ? litRowStyle : undefined}
46
+ onPointerEnter={() => onHighlight?.(band)}
47
+ onPointerLeave={() => onHighlight?.(null)}
48
+ >
49
+ <td style={panelNumberCellStyle}>{formatWavenumber(band.wavenumber)}</td>
50
+ <td style={panelCellStyle} title={STRENGTH_TITLES[band.strength]}>
51
+ {band.strength}
52
+ </td>
53
+ <td style={panelNumberCellStyle}>
54
+ {formatIrValue(bandValue(band, mode) ?? Number.NaN, mode)}
55
+ </td>
56
+ {assignments ? <CandidatesCell entry={entry} /> : null}
57
+ </tr>
58
+ );
59
+ }
60
+
61
+ interface CandidatesCellProps {
62
+ /** The band and everything it might be. */
63
+ entry: AssignedBand;
64
+ }
65
+
66
+ /**
67
+ * What a band could be: the narrowest candidate, and how many more there are.
68
+ * @param props - Component props.
69
+ * @returns The cell.
70
+ */
71
+ function CandidatesCell(props: CandidatesCellProps) {
72
+ const { candidates } = props.entry;
73
+ const detail = candidates
74
+ .map((candidate) =>
75
+ candidate.note === undefined
76
+ ? `${candidate.group} ${candidate.vibration}`
77
+ : `${candidate.group} ${candidate.vibration} — ${candidate.note}`,
78
+ )
79
+ .join('\n');
80
+
81
+ return (
82
+ <td style={panelCellStyle} title={detail}>
83
+ {candidates.length === 0 ? (
84
+ <span style={{ opacity: 0.5 }}>—</span>
85
+ ) : (
86
+ <span style={{ whiteSpace: 'normal' }}>
87
+ {candidates[0]?.group} {candidates[0]?.vibration}
88
+ {candidates.length > 1 ? (
89
+ <span style={{ opacity: 0.6 }}>
90
+ {' '}
91
+ <Icon icon="more" size={10} /> {candidates.length - 1} more
92
+ </span>
93
+ ) : null}
94
+ </span>
95
+ )}
96
+ </td>
97
+ );
98
+ }
99
+
100
+ /** What each strength letter means, for the column that shows only the letter. */
101
+ const STRENGTH_TITLES = {
102
+ w: 'weak, relative to this spectrum',
103
+ m: 'medium, relative to this spectrum',
104
+ S: 'strong, relative to this spectrum',
105
+ } as const;
106
+
107
+ const litRowStyle = { background: '#fff3e0' } as const;
@@ -1,22 +1,21 @@
1
- import { Icon } from '@blueprintjs/core';
2
1
  import { useMemo } from 'react';
3
2
  import { Button, Toolbar } from 'react-science/ui';
4
3
 
5
4
  import {
6
5
  panelBodyStyle,
7
- panelCellStyle,
8
6
  panelEmptyStyle,
9
7
  panelHeaderCellStyle,
10
- panelNumberCellStyle,
11
8
  panelStyle,
12
9
  panelTableStyle,
13
10
  panelToolbarStyle,
14
11
  } from '../../panel/core/panelStyles.ts';
15
- import type { AssignedBand } from '../core/assignBands.ts';
16
12
  import type { IrBand } from '../core/irBand.ts';
17
13
  import { sameIrBand } from '../core/irBand.ts';
18
- import { formatIrValue, formatWavenumber } from '../core/irFormat.ts';
14
+ import { shortModeLabel } from '../core/irFormat.ts';
15
+ import { IR_TECHNIQUE_RULES } from '../core/irTechnique.ts';
19
16
 
17
+ import { BandRow } from './BandRow.tsx';
18
+ import { bandsToTsv } from './bandsTsv.ts';
20
19
  import { useIrActions, useIrEditorState } from './irStateContext.ts';
21
20
 
22
21
  export interface BandsPanelProps {
@@ -45,6 +44,10 @@ export interface BandsPanelProps {
45
44
  * Hovering a row marks the band on the chart and hovering the chart lights the
46
45
  * row, which is the whole reason the highlight is threaded through the shell
47
46
  * rather than held here: the two views are of one thing.
47
+ *
48
+ * For a technique the correlation table does not cover — Raman — the column of
49
+ * candidates and the button naming them are left out, and the table is the
50
+ * bands themselves.
48
51
  * @param props - Component props.
49
52
  * @returns The panel.
50
53
  */
@@ -52,11 +55,16 @@ export function BandsPanel(props: BandsPanelProps) {
52
55
  const { highlight = null, onHighlight } = props;
53
56
  const { state, selectedSpectrum, assigned } = useIrEditorState();
54
57
  const actions = useIrActions();
55
- const { mode, pickBands, showAssignments, picking } = state.settings;
58
+ const { mode, pickBands, showAssignments, picking, technique } =
59
+ state.settings;
60
+ const { assignments } = IR_TECHNIQUE_RULES[technique];
56
61
 
57
62
  const rows = useMemo(() => assigned, [assigned]);
58
63
 
59
- const tsv = useMemo(() => bandsToTsv(rows, mode), [rows, mode]);
64
+ const tsv = useMemo(
65
+ () => bandsToTsv(rows, mode, assignments),
66
+ [rows, mode, assignments],
67
+ );
60
68
 
61
69
  return (
62
70
  <div style={panelStyle}>
@@ -69,16 +77,18 @@ export function BandsPanel(props: BandsPanelProps) {
69
77
  aria-label="Pick the bands"
70
78
  onClick={() => actions.setSettings({ pickBands: !pickBands })}
71
79
  />
72
- <Toolbar.Item
73
- icon="label"
74
- active={showAssignments}
75
- tooltip="Name the assignments on the chart"
76
- aria-label="Name the assignments on the chart"
77
- disabled={!pickBands}
78
- onClick={() =>
79
- actions.setSettings({ showAssignments: !showAssignments })
80
- }
81
- />
80
+ {assignments ? (
81
+ <Toolbar.Item
82
+ icon="label"
83
+ active={showAssignments}
84
+ tooltip="Name the assignments on the chart"
85
+ aria-label="Name the assignments on the chart"
86
+ disabled={!pickBands}
87
+ onClick={() =>
88
+ actions.setSettings({ showAssignments: !showAssignments })
89
+ }
90
+ />
91
+ ) : null}
82
92
  </Toolbar>
83
93
 
84
94
  {/* The threshold is the one picking setting worth reaching for while
@@ -134,9 +144,11 @@ export function BandsPanel(props: BandsPanelProps) {
134
144
  <th style={panelHeaderCellStyle}>cm⁻¹</th>
135
145
  <th style={panelHeaderCellStyle} />
136
146
  <th style={{ ...panelHeaderCellStyle, textAlign: 'right' }}>
137
- {mode === 'absorbance' ? 'A' : '%T'}
147
+ {shortModeLabel(mode)}
138
148
  </th>
139
- <th style={panelHeaderCellStyle}>could be</th>
149
+ {assignments ? (
150
+ <th style={panelHeaderCellStyle}>could be</th>
151
+ ) : null}
140
152
  </tr>
141
153
  </thead>
142
154
  <tbody>
@@ -145,6 +157,7 @@ export function BandsPanel(props: BandsPanelProps) {
145
157
  key={`${entry.band.spectrumId} ${entry.band.wavenumber}`}
146
158
  entry={entry}
147
159
  mode={mode}
160
+ assignments={assignments}
148
161
  lit={sameIrBand(entry.band, highlight)}
149
162
  onHighlight={onHighlight}
150
163
  />
@@ -157,112 +170,6 @@ export function BandsPanel(props: BandsPanelProps) {
157
170
  );
158
171
  }
159
172
 
160
- interface BandRowProps {
161
- /** The band and everything it might be. */
162
- entry: AssignedBand;
163
- /** Which value axis is being read. */
164
- mode: 'absorbance' | 'transmittance';
165
- /** Whether the pointer is on this band, here or on the chart. */
166
- lit: boolean;
167
- /** Told when the pointer arrives on this row, and when it leaves. */
168
- onHighlight?: (band: IrBand | null) => void;
169
- }
170
-
171
- /**
172
- * One band: where it is, how strong, and every vibration it could be.
173
- *
174
- * The candidates are written as one line rather than a list, so a strong band
175
- * with four of them stays one row of the table and the wavenumbers keep reading
176
- * down the column. The `title` carries them again with each one's note, which is
177
- * where the reason to prefer one lives.
178
- * @param props - Component props.
179
- * @returns The row.
180
- */
181
- function BandRow(props: BandRowProps) {
182
- const { entry, mode, lit, onHighlight } = props;
183
- const { band, candidates } = entry;
184
-
185
- const value = mode === 'absorbance' ? band.absorbance : band.transmittance;
186
- const detail = candidates
187
- .map((candidate) =>
188
- candidate.note === undefined
189
- ? `${candidate.group} ${candidate.vibration}`
190
- : `${candidate.group} ${candidate.vibration} — ${candidate.note}`,
191
- )
192
- .join('\n');
193
-
194
- return (
195
- <tr
196
- style={lit ? litRowStyle : undefined}
197
- onPointerEnter={() => onHighlight?.(band)}
198
- onPointerLeave={() => onHighlight?.(null)}
199
- >
200
- <td style={panelNumberCellStyle}>{formatWavenumber(band.wavenumber)}</td>
201
- <td style={panelCellStyle} title={STRENGTH_TITLES[band.strength]}>
202
- {band.strength}
203
- </td>
204
- <td style={panelNumberCellStyle}>{formatIrValue(value, mode)}</td>
205
- <td style={panelCellStyle} title={detail}>
206
- {candidates.length === 0 ? (
207
- <span style={{ opacity: 0.5 }}>—</span>
208
- ) : (
209
- <span style={{ whiteSpace: 'normal' }}>
210
- {candidates[0]?.group} {candidates[0]?.vibration}
211
- {candidates.length > 1 ? (
212
- <span style={{ opacity: 0.6 }}>
213
- {' '}
214
- <Icon icon="more" size={10} /> {candidates.length - 1} more
215
- </span>
216
- ) : null}
217
- </span>
218
- )}
219
- </td>
220
- </tr>
221
- );
222
- }
223
-
224
- /** What each strength letter means, for the column that shows only the letter. */
225
- const STRENGTH_TITLES = {
226
- w: 'weak, relative to this spectrum',
227
- m: 'medium, relative to this spectrum',
228
- S: 'strong, relative to this spectrum',
229
- } as const;
230
-
231
- /**
232
- * The table as text, for pasting into a notebook.
233
- *
234
- * Tab separated with every candidate on the row, because the reason to copy a
235
- * band table is to put it beside a structure and argue about it — and the
236
- * argument is over the candidates rather than over the wavenumbers.
237
- * @param rows - The bands, as they are shown.
238
- * @param mode - Which value axis is being read.
239
- * @returns The table, one line per band, with a heading.
240
- */
241
- function bandsToTsv(
242
- rows: readonly AssignedBand[],
243
- mode: 'absorbance' | 'transmittance',
244
- ): string {
245
- const heading = ['wavenumber', 'strength', mode, 'could be'].join('\t');
246
- const lines = rows.map((entry) =>
247
- [
248
- formatWavenumber(entry.band.wavenumber),
249
- entry.band.strength,
250
- formatIrValue(
251
- mode === 'absorbance'
252
- ? entry.band.absorbance
253
- : entry.band.transmittance,
254
- mode,
255
- ),
256
- entry.candidates
257
- .map((candidate) => `${candidate.group} ${candidate.vibration}`)
258
- .join('; '),
259
- ].join('\t'),
260
- );
261
- return [heading, ...lines].join('\n');
262
- }
263
-
264
- const litRowStyle = { background: '#fff3e0' } as const;
265
-
266
173
  const thresholdStyle = {
267
174
  display: 'inline-flex',
268
175
  alignItems: 'center',
@@ -1,12 +1,24 @@
1
1
  import { Dialog, DialogBody } from '@blueprintjs/core';
2
2
 
3
+ import { Prose } from '../../i18n/ui/Prose.tsx';
4
+ import { useChromeT } from '../../i18n/ui/useT.ts';
5
+ import { irCommands } from '../core/irCommands.ts';
6
+ import type { IrTechnique } from '../core/irTechnique.ts';
7
+
3
8
  import { IrLogo } from './IrLogo.tsx';
9
+ import { useIrText } from './useIrText.ts';
4
10
 
5
11
  export interface IrAboutDialogProps {
6
12
  /** Whether the dialog is open. */
7
13
  isOpen: boolean;
8
14
  /** Close it. */
9
15
  onClose: () => void;
16
+ /**
17
+ * What the spectra were measured with, which decides what the viewer says it
18
+ * does and whom it credits for it.
19
+ * @default 'infrared'
20
+ */
21
+ technique?: IrTechnique;
10
22
  }
11
23
 
12
24
  /**
@@ -20,42 +32,63 @@ export interface IrAboutDialogProps {
20
32
  * @returns The dialog.
21
33
  */
22
34
  export function IrAboutDialog(props: IrAboutDialogProps) {
23
- const { isOpen, onClose } = props;
35
+ const { isOpen, onClose, technique = 'infrared' } = props;
36
+ const t = useChromeT();
37
+ const title = (useIrText(technique).command('about') ?? irCommands.about)
38
+ .title;
39
+ const raman = technique === 'raman';
24
40
 
25
41
  return (
26
42
  <Dialog
27
43
  isOpen={isOpen}
28
44
  onClose={onClose}
29
- title="About the infrared viewer"
30
- icon={<IrLogo size={20} />}
45
+ title={title}
46
+ icon={<IrLogo size={20} technique={technique} />}
31
47
  style={dialogStyle}
32
48
  >
33
49
  <DialogBody>
34
50
  <div style={brandStyle}>
35
- <IrLogo size={64} />
51
+ <IrLogo size={64} technique={technique} />
36
52
  <div>
37
- <p style={leadStyle}>react-cheminfo/ir</p>
38
- <p style={paragraphStyle}>
39
- Draws an infrared spectrum the way infrared is printed, reads it
40
- as absorbance or as percent transmittance, picks its bands and
41
- offers every functional group each band could be.
42
- </p>
53
+ <p style={leadStyle}>{DOORS[technique]}</p>
54
+ {raman ? (
55
+ <p style={paragraphStyle}>{t('ir.raman.aboutLead')}</p>
56
+ ) : (
57
+ <p style={paragraphStyle}>
58
+ Draws an infrared spectrum the way infrared is printed, reads it
59
+ as absorbance or as percent transmittance, picks its bands and
60
+ offers every functional group each band could be.
61
+ </p>
62
+ )}
43
63
  </div>
44
64
  </div>
45
65
 
46
66
  <h4 style={headingStyle}>Credits</h4>
47
67
  <ul style={listStyle}>
48
- <li>
49
- <strong>ir-spectrum</strong> (cheminfo, MIT) reads the JCAMP-DX and
50
- SPC files, derives the absorbance/transmittance pair, and picks the
51
- bands. This package deliberately does none of that arithmetic
52
- itself.
53
- </li>
54
- <li>
55
- <strong>common-spectrum</strong>, <strong>jcampconverter</strong>{' '}
56
- and <strong>spc-parser</strong> (cheminfo, MIT) are what it reads
57
- through.
58
- </li>
68
+ {raman ? (
69
+ <>
70
+ <li>
71
+ <Prose text={t('ir.raman.credit.picking')} />
72
+ </li>
73
+ <li>
74
+ <Prose text={t('ir.raman.credit.jcamp')} />
75
+ </li>
76
+ </>
77
+ ) : (
78
+ <>
79
+ <li>
80
+ <strong>ir-spectrum</strong> (cheminfo, MIT) reads the JCAMP-DX
81
+ and SPC files, derives the absorbance/transmittance pair, and
82
+ picks the bands. This package deliberately does none of that
83
+ arithmetic itself.
84
+ </li>
85
+ <li>
86
+ <strong>common-spectrum</strong>,{' '}
87
+ <strong>jcampconverter</strong> and <strong>spc-parser</strong>{' '}
88
+ (cheminfo, MIT) are what it reads through.
89
+ </li>
90
+ </>
91
+ )}
59
92
  <li>
60
93
  <strong>ml-spectra-processing</strong> (mljs, MIT) for the array
61
94
  work.
@@ -69,13 +102,15 @@ export function IrAboutDialog(props: IrAboutDialogProps) {
69
102
  <strong>react-science</strong> and <strong>BlueprintJS</strong>
70
103
  (zakodium, Palantir) for the shell this viewer is shaped like.
71
104
  </li>
72
- <li>
73
- The <strong>correlation table</strong> is the conventional teaching
74
- set of group frequencies, as any introductory spectroscopy text
75
- tabulates them. The ranges are deliberately the rounded, generous
76
- ones: narrowing them to look precise would rule out assignments that
77
- are genuinely possible.
78
- </li>
105
+ {raman ? null : (
106
+ <li>
107
+ The <strong>correlation table</strong> is the conventional
108
+ teaching set of group frequencies, as any introductory
109
+ spectroscopy text tabulates them. The ranges are deliberately the
110
+ rounded, generous ones: narrowing them to look precise would rule
111
+ out assignments that are genuinely possible.
112
+ </li>
113
+ )}
79
114
  <li>
80
115
  The <strong>colours</strong> are Okabe and Ito&apos;s
81
116
  colour-universal palette, so two traces stay distinguishable for a
@@ -87,6 +122,12 @@ export function IrAboutDialog(props: IrAboutDialogProps) {
87
122
  );
88
123
  }
89
124
 
125
+ /** The entry point each technique's viewer is imported from. */
126
+ const DOORS: Record<IrTechnique, string> = {
127
+ infrared: 'react-cheminfo/ir',
128
+ raman: 'react-cheminfo/raman',
129
+ };
130
+
90
131
  const dialogStyle = { width: 'min(680px, 92vw)' } as const;
91
132
 
92
133
  const brandStyle = {