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
@@ -1,12 +1,20 @@
1
1
  import { Button } from 'react-science/ui';
2
2
 
3
3
  import { SpectrumColorSwatch } from '../../panel/ui/SpectrumColorSwatch.tsx';
4
- import { formatWavenumber } from '../core/irFormat.ts';
4
+ import { formatWavenumberRange } from '../core/irFormat.ts';
5
5
  import type { IrSpectrum } from '../core/irSpectrum.ts';
6
+ import type { IrTechnique } from '../core/irTechnique.ts';
7
+ import { IR_TECHNIQUE_RULES } from '../core/irTechnique.ts';
6
8
 
7
9
  export interface SpectrumRowProps {
8
10
  /** The spectrum the row is about. */
9
11
  spectrum: IrSpectrum;
12
+ /**
13
+ * What it was measured with, which decides the order its range is written
14
+ * in: high to low for infrared, low to high for Raman.
15
+ * @default 'infrared'
16
+ */
17
+ technique?: IrTechnique;
10
18
  /** Whether the panels are about it. */
11
19
  selected: boolean;
12
20
  /** Point the panels at it. */
@@ -31,6 +39,7 @@ export interface SpectrumRowProps {
31
39
  export function SpectrumRow(props: SpectrumRowProps) {
32
40
  const {
33
41
  spectrum,
42
+ technique = 'infrared',
34
43
  selected,
35
44
  onSelect,
36
45
  onToggle,
@@ -40,10 +49,10 @@ export function SpectrumRow(props: SpectrumRowProps) {
40
49
  onRename,
41
50
  } = props;
42
51
 
43
- const range =
44
- spectrum.wavenumber.length === 0
45
- ? ''
46
- : `${formatWavenumber(spectrum.wavenumber.at(-1) as number)}–${formatWavenumber(spectrum.wavenumber[0] as number)} cm⁻¹`;
52
+ const range = formatWavenumberRange(
53
+ spectrum.wavenumber,
54
+ IR_TECHNIQUE_RULES[technique].reverseX,
55
+ );
47
56
 
48
57
  return (
49
58
  <div
@@ -0,0 +1,113 @@
1
+ import type { Ref } from 'react';
2
+ import { RootLayout } from 'react-science/ui';
3
+
4
+ import type { IrEditorHandle, IrPlotClick } from '../core/irEditorApi.ts';
5
+ import type { IrPanelId } from '../core/irSidePanels.ts';
6
+ import type { IrMode, IrSpectrum } from '../core/irSpectrum.ts';
7
+ import type { IrTechnique } from '../core/irTechnique.ts';
8
+
9
+ import { IrShell } from './IrShell.tsx';
10
+ import { IrStateProvider } from './IrStateProvider.tsx';
11
+ import type { IrHostPanel } from './irHostPanels.ts';
12
+ import { useIrEditor } from './useIrEditor.ts';
13
+
14
+ export interface VibrationalEditorProps {
15
+ /**
16
+ * What the spectra were measured with. Read when the viewer opens and fixed
17
+ * from then on: it decides the value axes, the direction and name of the
18
+ * wavenumber axis, and whether the correlation table is asked about a band.
19
+ */
20
+ technique: IrTechnique;
21
+ /**
22
+ * The spectra to open on. Read when the viewer opens and never again.
23
+ * @default []
24
+ */
25
+ data?: IrSpectrum[];
26
+ /**
27
+ * Called whenever the spectra open change, with the spectra now open.
28
+ * @default undefined
29
+ */
30
+ onChange?: (spectra: IrSpectrum[]) => void;
31
+ /**
32
+ * Which value axis to open in; one the technique does not offer opens its
33
+ * first instead.
34
+ * @default the technique's first
35
+ */
36
+ mode?: IrMode;
37
+ /**
38
+ * The side panels open to begin with, the viewer's own or the host's. An id
39
+ * no panel answers to is ignored.
40
+ * @default DEFAULT_SIDE_PANELS
41
+ */
42
+ defaultPanelIds?: readonly IrPanelId[];
43
+ /**
44
+ * Panels the host adds to the viewer's own: their icons come first in the
45
+ * activity bar, in the order given, and each behaves as a built-in panel does.
46
+ * @default []
47
+ */
48
+ panels?: readonly IrHostPanel[];
49
+ /**
50
+ * The plot was clicked at this wavenumber (a press that did not travel, i.e.
51
+ * not a zoom drag), with the spectrum selected at that moment.
52
+ * @default undefined
53
+ */
54
+ onPlotClick?: (click: IrPlotClick) => void;
55
+ /**
56
+ * The handle a host drives the viewer through.
57
+ * @default undefined
58
+ */
59
+ ref?: Ref<IrEditorHandle>;
60
+ }
61
+
62
+ /**
63
+ * The viewer `IrEditor` and `RamanEditor` both are: one shell, one set of
64
+ * panels and gestures, with what differs between the techniques read from
65
+ * `IR_TECHNIQUE_RULES` rather than written into either.
66
+ * @param props - Component props.
67
+ * @returns The viewer.
68
+ */
69
+ export function VibrationalEditor(props: VibrationalEditorProps) {
70
+ const {
71
+ technique,
72
+ data = NO_SPECTRA,
73
+ onChange,
74
+ mode,
75
+ defaultPanelIds,
76
+ panels = NO_PANELS,
77
+ onPlotClick,
78
+ ref,
79
+ } = props;
80
+
81
+ const editor = useIrEditor({
82
+ spectra: data,
83
+ settings: { technique, ...(mode === undefined ? {} : { mode }) },
84
+ panelIds: defaultPanelIds,
85
+ onChange,
86
+ });
87
+
88
+ return (
89
+ <IrStateProvider editor={editor}>
90
+ {/* `react-science`'s own root: it holds the element the browser is asked
91
+ to show full screen, points Blueprint's portals at that element so
92
+ dialogs and tooltips are not left behind in `document.body`, and paints
93
+ the backdrop white. Above the shell rather than inside it, so the shell
94
+ can ask whether it is full screen and offer the way out. */}
95
+ <RootLayout style={rootLayoutStyle}>
96
+ <IrShell handle={ref} panels={panels} onPlotClick={onPlotClick} />
97
+ </RootLayout>
98
+ </IrStateProvider>
99
+ );
100
+ }
101
+
102
+ /**
103
+ * The viewer fills what it is given, and its own children scroll rather than
104
+ * push: `react-science` lays its root out as a column of full width and height,
105
+ * and a flex column with no `minHeight` grows past its parent instead.
106
+ */
107
+ const rootLayoutStyle = { minHeight: 0 } as const;
108
+
109
+ /** What a viewer opens on when it is handed nothing, kept stable for the memo. */
110
+ const NO_SPECTRA: IrSpectrum[] = [];
111
+
112
+ /** What a viewer the host adds no panel to offers, kept stable for the memo. */
113
+ const NO_PANELS: readonly IrHostPanel[] = [];
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The band table as text, for pasting into a notebook.
3
+ */
4
+
5
+ import type { AssignedBand } from '../core/assignBands.ts';
6
+ import { bandValue } from '../core/irBand.ts';
7
+ import { formatIrValue, formatWavenumber } from '../core/irFormat.ts';
8
+ import type { IrMode } from '../core/irSpectrum.ts';
9
+
10
+ /**
11
+ * The table as tab separated text.
12
+ *
13
+ * Every candidate is on its band's row, because the reason to copy a band table
14
+ * is to put it beside a structure and argue about it — and the argument is over
15
+ * the candidates rather than over the wavenumbers. A technique the correlation
16
+ * table does not cover has no such column.
17
+ * @param rows - The bands, as they are shown.
18
+ * @param mode - Which value axis is being read.
19
+ * @param assignments - Whether the table has a column for the candidates.
20
+ * @returns The table, one line per band, with a heading.
21
+ */
22
+ export function bandsToTsv(
23
+ rows: readonly AssignedBand[],
24
+ mode: IrMode,
25
+ assignments: boolean,
26
+ ): string {
27
+ const heading = ['wavenumber', 'strength', mode];
28
+ if (assignments) heading.push('could be');
29
+ const lines = [heading.join('\t')];
30
+ for (const { band, candidates } of rows) {
31
+ const cells = [
32
+ formatWavenumber(band.wavenumber),
33
+ band.strength,
34
+ formatIrValue(bandValue(band, mode) ?? Number.NaN, mode),
35
+ ];
36
+ if (assignments) {
37
+ cells.push(
38
+ candidates
39
+ .map((candidate) => `${candidate.group} ${candidate.vibration}`)
40
+ .join('; '),
41
+ );
42
+ }
43
+ lines.push(cells.join('\t'));
44
+ }
45
+ return lines.join('\n');
46
+ }
@@ -47,6 +47,7 @@ export { createIrActions } from './irActions.ts';
47
47
  export type { IrChartProps } from './irChartProps.ts';
48
48
  export type { IrCommandContextValue } from './irCommandContext.tsx';
49
49
  export { useIrCommand, useIrCommandProps } from './irCommandContext.tsx';
50
+ export type { IrHostPanel } from './irHostPanels.ts';
50
51
  export { useIrActions, useIrEditorState } from './irStateContext.ts';
51
52
  export type { IrEditorApi, UseIrEditorOptions } from './useIrEditor.ts';
52
53
  export { useIrEditor } from './useIrEditor.ts';
@@ -9,7 +9,7 @@
9
9
  import type { Dispatch } from 'react';
10
10
 
11
11
  import type { IrAction } from '../core/irReducer.ts';
12
- import type { IrSidePanelId } from '../core/irSidePanels.ts';
12
+ import type { IrPanelId } from '../core/irSidePanels.ts';
13
13
  import type { IrDomain, IrSpectrum } from '../core/irSpectrum.ts';
14
14
  import type { IrSettings, IrTool, PartialIrState } from '../core/irState.ts';
15
15
 
@@ -35,8 +35,8 @@ export interface IrEditorActions {
35
35
  resetDomain: () => void;
36
36
  /** Run this tool on the next drag. */
37
37
  setTool: (tool: IrTool) => void;
38
- /** Open or close a side panel. */
39
- togglePanel: (panelId: IrSidePanelId) => void;
38
+ /** Open or close a side panel, the viewer's own or one a host added. */
39
+ togglePanel: (panelId: IrPanelId) => void;
40
40
  /** Say why something was refused, or that nothing is wrong any more. */
41
41
  setError: (error: string | null) => void;
42
42
  /** Change how the spectra are drawn and read. */
@@ -7,8 +7,9 @@
7
7
  * of half a dozen layers nobody needs to read in order to mount one.
8
8
  *
9
9
  * Everything arrives as a prop and nothing is reached for: the chart reads no
10
- * context and no store, so the same component serves an editor, a report page
11
- * that only ever draws one spectrum, and a test.
10
+ * store and no context but the language the page is written in, so the same
11
+ * component serves an editor, a report page that only ever draws one spectrum,
12
+ * and a test.
12
13
  */
13
14
 
14
15
  import type { ReactNode } from 'react';
@@ -17,17 +18,26 @@ import type { ZoomDragMode } from '../../chart/core/chartDomain.ts';
17
18
  import type { AssignedBand } from '../core/assignBands.ts';
18
19
  import type { IrBand } from '../core/irBand.ts';
19
20
  import type { IrDomain, IrMode, IrSpectrum } from '../core/irSpectrum.ts';
21
+ import type { IrTechnique } from '../core/irTechnique.ts';
20
22
 
21
23
  export interface IrChartProps {
22
24
  /** The spectra to draw, each saying in itself whether it is drawn. */
23
25
  spectra: readonly IrSpectrum[];
24
26
  /**
25
- * Which value axis to draw them in.
27
+ * What the spectra were measured with, which names the wavenumber axis and
28
+ * decides which way it runs: high to low for infrared, low to high for Raman.
29
+ * @default 'infrared'
30
+ */
31
+ technique?: IrTechnique;
32
+ /**
33
+ * Which value axis to draw them in. One the technique does not offer draws
34
+ * its first instead.
26
35
  *
27
36
  * A prop rather than state, so the switch lives with whoever owns the toolbar
28
37
  * that flips it — and so two charts of the same spectra can be shown side by
29
38
  * side, one in each, which is the clearest way to see what the pair means.
30
- * @default 'transmittance'
39
+ * @default the technique's first: `'transmittance'` for infrared,
40
+ * `'intensity'` for Raman
31
41
  */
32
42
  mode?: IrMode;
33
43
  /**
@@ -84,6 +94,13 @@ export interface IrChartProps {
84
94
  * @default undefined
85
95
  */
86
96
  onDomainChange?: (domain: IrDomain) => void;
97
+ /**
98
+ * Told the wavenumber a click on the plot landed at: a press let go over the
99
+ * plot without travelling. The end of a drag is never one, nor is a press let
100
+ * go over the axis labels, which inverts to a value the chart is not drawing.
101
+ * @default undefined
102
+ */
103
+ onPlotClick?: (wavenumber: number) => void;
87
104
  /**
88
105
  * What a drag across the plot asks for: the wavenumber axis alone, or exactly
89
106
  * the rectangle it sweeps out. A viewer offering a square-zoom tool switches
@@ -12,14 +12,18 @@ import type {
12
12
  IrCommandId,
13
13
  RunIrCommand,
14
14
  } from '../core/irCommands.ts';
15
- import { irCommandLabel } from '../core/irCommands.ts';
15
+ import { irCommandEntryLabel, irCommands } from '../core/irCommands.ts';
16
+ import type { IrTechnique } from '../core/irTechnique.ts';
16
17
 
17
18
  import { IrCommandTooltip } from './IrCommandTooltip.tsx';
19
+ import { useIrText } from './useIrText.ts';
18
20
 
19
21
  /** What the provider holds. */
20
22
  export interface IrCommandContextValue {
21
23
  /** What each command does. */
22
24
  handlers: IrCommandHandlers;
25
+ /** What the spectra were measured with, which words the commands. */
26
+ technique: IrTechnique;
23
27
  /** Run one. */
24
28
  run: RunIrCommand;
25
29
  }
@@ -36,6 +40,14 @@ export function useIrCommand(): RunIrCommand {
36
40
  return value?.run ?? noRun;
37
41
  }
38
42
 
43
+ /**
44
+ * What the spectra were measured with, from anywhere inside the viewer.
45
+ * @returns The technique; infrared outside a provider.
46
+ */
47
+ export function useIrCommandTechnique(): IrTechnique {
48
+ return useContext(commandContext)?.technique ?? 'infrared';
49
+ }
50
+
39
51
  /**
40
52
  * Everything a toolbar item needs to be one command, in one spread.
41
53
  *
@@ -46,10 +58,13 @@ export function useIrCommand(): RunIrCommand {
46
58
  */
47
59
  export function useIrCommandProps() {
48
60
  const run = useIrCommand();
61
+ const technique = useIrCommandTechnique();
62
+ const text = useIrText(technique);
49
63
  return function command(id: IrCommandId) {
64
+ const entry = text.command(id) ?? irCommands[id];
50
65
  return {
51
- tooltip: <IrCommandTooltip id={id} />,
52
- 'aria-label': irCommandLabel(id),
66
+ tooltip: <IrCommandTooltip id={id} technique={technique} />,
67
+ 'aria-label': irCommandEntryLabel(entry),
53
68
  onClick: () => run(id),
54
69
  };
55
70
  };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The panels a host adds to the viewer's own, and the one list both make.
3
+ *
4
+ * A host panel is a panel like any other once it is in the list: the activity
5
+ * bar and the stack read the same list, so it toggles, folds and closes
6
+ * exactly as the spectra or the bands do. The host brings the body and nothing
7
+ * else — the header, its close button and the place in the column are the
8
+ * viewer's, which is what keeps every header reading the same.
9
+ */
10
+
11
+ import type { IconName } from '@blueprintjs/core';
12
+ import type { ReactNode } from 'react';
13
+
14
+ import { irSidePanels } from '../core/irSidePanels.ts';
15
+
16
+ /** A panel the host adds to the editor's own stack. */
17
+ export interface IrHostPanel {
18
+ /**
19
+ * Its identity in the activity bar and in `defaultPanelIds`; never a
20
+ * built-in id. One that is, or that an earlier host panel already took, is
21
+ * left out: one icon cannot open two panels.
22
+ */
23
+ id: string;
24
+ /** What its header and its activity-bar item say. */
25
+ title: string;
26
+ /** Its glyph in the activity bar (a Blueprint IconName). */
27
+ icon: IconName;
28
+ /**
29
+ * Its body. It brings its own toolbar as first row: the header carries the
30
+ * close button only.
31
+ *
32
+ * It is laid out in a column filling the panel's share of the height, so a
33
+ * toolbar row in `panelToolbarStyle` followed by a body in `panelBodyStyle`,
34
+ * both from `react-cheminfo/core`, keeps the toolbar in place while a tall
35
+ * body scrolls under it. It is rendered inside the viewer, so a component in
36
+ * it reaches the viewer it stands in through `useIrEditorState` and
37
+ * `useIrActions` — to overlay a predicted spectrum, say.
38
+ */
39
+ content: ReactNode;
40
+ }
41
+
42
+ /** One panel of the side: one of the viewer's own, or one a host added. */
43
+ export type IrStackPanel = (typeof irSidePanels)[number] | IrHostPanel;
44
+
45
+ /**
46
+ * Every panel the side offers, in the order the activity bar stacks them: the
47
+ * host's first, in the order given, then the viewer's own.
48
+ * @param hostPanels - What the host adds.
49
+ * @returns The panels; the viewer's own list itself when the host adds none.
50
+ */
51
+ export function irStackPanels(
52
+ hostPanels: readonly IrHostPanel[],
53
+ ): readonly IrStackPanel[] {
54
+ if (hostPanels.length === 0) return irSidePanels;
55
+ const taken = new Set<string>(BUILT_IN_IDS);
56
+ const panels: IrStackPanel[] = [];
57
+ for (const panel of hostPanels) {
58
+ if (taken.has(panel.id)) continue;
59
+ taken.add(panel.id);
60
+ panels.push(panel);
61
+ }
62
+ panels.push(...irSidePanels);
63
+ return panels;
64
+ }
65
+
66
+ /**
67
+ * Whether a panel of the side is one a host added, whose body it brings.
68
+ * @param panel - The panel.
69
+ * @returns True for a host's panel.
70
+ */
71
+ export function isIrHostPanel(panel: IrStackPanel): panel is IrHostPanel {
72
+ return 'content' in panel;
73
+ }
74
+
75
+ /** The ids no host panel may take. */
76
+ const BUILT_IN_IDS: readonly string[] = irSidePanels.map((panel) => panel.id);
@@ -17,10 +17,13 @@ import { useEffect, useMemo, useReducer, useRef } from 'react';
17
17
 
18
18
  import type { AssignedBand } from '../core/assignBands.ts';
19
19
  import { assignBands } from '../core/assignBands.ts';
20
- import type { CreateIrStateOptions } from '../core/irReducer.ts';
21
- import { createIrState, irReducer } from '../core/irReducer.ts';
20
+ import type { BandAssignment } from '../core/bandAssignments.ts';
21
+ import { BAND_ASSIGNMENTS } from '../core/bandAssignments.ts';
22
+ import { irReducer } from '../core/irReducer.ts';
22
23
  import type { IrSpectrum } from '../core/irSpectrum.ts';
23
- import type { IrState } from '../core/irState.ts';
24
+ import type { CreateIrStateOptions, IrState } from '../core/irState.ts';
25
+ import { createIrState } from '../core/irState.ts';
26
+ import { IR_TECHNIQUE_RULES } from '../core/irTechnique.ts';
24
27
  import { pickBands } from '../core/pickBands.ts';
25
28
 
26
29
  import type { IrEditorActions } from './irActions.ts';
@@ -46,7 +49,8 @@ export interface IrEditorApi {
46
49
  selectedSpectrum: IrSpectrum | null;
47
50
  /**
48
51
  * The bands of the selected spectrum, with everything each might be. Empty
49
- * while nothing is selected or while picking is switched off.
52
+ * while nothing is selected or while picking is switched off, and every band
53
+ * without a candidate for a technique the correlation table does not cover.
50
54
  */
51
55
  assigned: AssignedBand[];
52
56
  /** Everything to do. */
@@ -67,7 +71,7 @@ export function useIrEditor(options: UseIrEditorOptions = {}): IrEditorApi {
67
71
  const { spectra } = state.data;
68
72
  const { selectedId } = state.view;
69
73
  const { pickBands: picking, picking: pickingOptions } = state.settings;
70
- const { assignmentTolerance } = state.settings;
74
+ const { assignmentTolerance, technique } = state.settings;
71
75
 
72
76
  const visibleSpectra = useMemo(() => {
73
77
  const visible: IrSpectrum[] = [];
@@ -95,10 +99,15 @@ export function useIrEditor(options: UseIrEditorOptions = {}): IrEditorApi {
95
99
 
96
100
  // Assigning is a walk of thirty ranges per band, which is nothing beside the
97
101
  // picking — so it is a memo of its own, and moving the tolerance does not
98
- // re-pick.
102
+ // re-pick. A technique the table does not cover is matched against no table.
103
+ const { assignments } = IR_TECHNIQUE_RULES[technique];
99
104
  const assigned = useMemo(
100
- () => assignBands(bands, { tolerance: assignmentTolerance }),
101
- [bands, assignmentTolerance],
105
+ () =>
106
+ assignBands(bands, {
107
+ tolerance: assignmentTolerance,
108
+ assignments: assignments ? BAND_ASSIGNMENTS : NO_ASSIGNMENTS,
109
+ }),
110
+ [bands, assignmentTolerance, assignments],
102
111
  );
103
112
 
104
113
  // What was reported last, so a host passing a fresh callback on every render
@@ -118,6 +127,9 @@ export function useIrEditor(options: UseIrEditorOptions = {}): IrEditorApi {
118
127
  );
119
128
  }
120
129
 
130
+ /** The table a technique the correlation table does not cover is matched against. */
131
+ const NO_ASSIGNMENTS: readonly BandAssignment[] = [];
132
+
121
133
  /**
122
134
  * Whether two lists hold the same spectra, by identity and in order.
123
135
  * @param current - What was reported last.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The handle a host drives the viewer through, filled in from its state.
3
+ *
4
+ * A hook of its own beside the shell, because every gesture on the handle reads
5
+ * the state the shell already reads — and the shell is long enough without it.
6
+ */
7
+
8
+ import type { Ref } from 'react';
9
+ import { useImperativeHandle } from 'react';
10
+
11
+ import { fullDomain } from '../core/irDomain.ts';
12
+ import type { IrEditorHandle, ZoomToBandOptions } from '../core/irEditorApi.ts';
13
+ import type { IrDomain } from '../core/irSpectrum.ts';
14
+
15
+ import { useIrActions, useIrEditorState } from './irStateContext.ts';
16
+
17
+ /**
18
+ * Fill in a host's handle on the viewer this is called inside.
19
+ * @param handle - The handle to fill in, if the host asked for one.
20
+ */
21
+ export function useIrHandle(handle: Ref<IrEditorHandle> | undefined): void {
22
+ const { state, visibleSpectra } = useIrEditorState();
23
+ const actions = useIrActions();
24
+ const { domain } = state.view;
25
+ const { mode } = state.settings;
26
+
27
+ useImperativeHandle(
28
+ handle,
29
+ (): IrEditorHandle => ({
30
+ getSpectra: () => state.data.spectra,
31
+ setSpectra: (spectra) => actions.setSpectra(spectra),
32
+ addSpectra: (spectra) => actions.addSpectra(spectra),
33
+ clear: () => actions.clear(),
34
+ setDomain: (next) => actions.setDomain(next),
35
+ resetDomain: () => actions.resetDomain(),
36
+ zoomToWavenumber: (wavenumber, options: ZoomToBandOptions = {}) => {
37
+ const { width = DEFAULT_FRAME_WIDTH } = options;
38
+ const shown: IrDomain = domain ?? fullDomain(visibleSpectra, mode);
39
+ actions.setDomain({
40
+ x: [wavenumber - width / 2, wavenumber + width / 2],
41
+ y: shown.y,
42
+ });
43
+ },
44
+ selectSpectrum: (id) => actions.selectSpectrum(id),
45
+ }),
46
+ [state.data.spectra, actions, domain, visibleSpectra, mode],
47
+ );
48
+ }
49
+
50
+ /** How wide a window a host gets when it asks to frame a band without saying. */
51
+ const DEFAULT_FRAME_WIDTH = 200;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The side of the viewer: the panels it offers, whether any of them is open,
3
+ * and what dragging the splitter shut and back open does to them.
4
+ *
5
+ * A hook of its own beside the shell, because the shell lays the side out and
6
+ * this decides what is on it.
7
+ */
8
+
9
+ import { useMemo } from 'react';
10
+
11
+ import { DEFAULT_SIDE_PANEL } from '../core/irState.ts';
12
+
13
+ import type { IrHostPanel, IrStackPanel } from './irHostPanels.ts';
14
+ import { irStackPanels } from './irHostPanels.ts';
15
+ import { useIrActions, useIrEditorState } from './irStateContext.ts';
16
+
17
+ /** The side, as the shell lays it out. */
18
+ export interface IrSide {
19
+ /** Every panel on offer, in the order their icons are stacked. */
20
+ panels: readonly IrStackPanel[];
21
+ /** Whether a panel on offer is open, which is whether the side is. */
22
+ isOpen: boolean;
23
+ /**
24
+ * Open or close the side, as the splitter is dragged shut and back open.
25
+ * @param open - Whether the side is now open.
26
+ */
27
+ setOpen: (open: boolean) => void;
28
+ }
29
+
30
+ /**
31
+ * The side of the viewer this is called inside.
32
+ * @param hostPanels - The panels the host adds to the viewer's own.
33
+ * @returns The panels on offer, whether the side is open, and how to open it.
34
+ */
35
+ export function useIrSide(hostPanels: readonly IrHostPanel[]): IrSide {
36
+ const { state } = useIrEditorState();
37
+ const actions = useIrActions();
38
+ const { openPanelIds } = state.view;
39
+
40
+ const panels = useMemo(() => irStackPanels(hostPanels), [hostPanels]);
41
+ // Read off the panels on offer rather than off the ids: an id no panel
42
+ // answers to opens nothing, and a side open on it alone is an empty column.
43
+ const isOpen = panels.some((panel) => openPanelIds.includes(panel.id));
44
+
45
+ /**
46
+ * Open or close the side.
47
+ * @param open - Whether the side is now open.
48
+ */
49
+ function setOpen(open: boolean): void {
50
+ if (!open) {
51
+ for (const panelId of openPanelIds) actions.togglePanel(panelId);
52
+ return;
53
+ }
54
+ // Dragging the splitter back open must land on something, or it opens on an
55
+ // empty column and reads as broken.
56
+ if (!isOpen) actions.togglePanel(DEFAULT_SIDE_PANEL);
57
+ }
58
+
59
+ return { panels, isOpen, setOpen };
60
+ }