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
@@ -0,0 +1,98 @@
1
+ import type { CSSProperties } from 'react';
2
+ import type { CanvasEditorInputFormat } from 'react-ocl';
3
+ import type { StructureTransfer } from '../core/structureTransfer.ts';
4
+ import type { StructureEditorChange, StructureEditorMode } from './editorChange.ts';
5
+ /** What `StructureEditor` needs. */
6
+ export interface StructureEditorProps {
7
+ /**
8
+ * Called after every edit, once the drawing has been still for `debounce`
9
+ * milliseconds, with every notation read out of the editor.
10
+ */
11
+ onChange: (change: StructureEditorChange) => void;
12
+ /**
13
+ * Draw a query fragment rather than a whole structure, which is what a
14
+ * substructure filter needs.
15
+ * @default false
16
+ */
17
+ fragment?: boolean;
18
+ /**
19
+ * How `value` is written.
20
+ * @default 'idcode'
21
+ */
22
+ inputFormat?: CanvasEditorInputFormat;
23
+ /**
24
+ * What the canvas holds. Read once, when the editor appears and again on
25
+ * every change of `revision`: the editor is uncontrolled, so feeding the
26
+ * drawing back into it would replace the structure and reset every
27
+ * coordinate under the pen.
28
+ * @default ''
29
+ */
30
+ value?: string;
31
+ /**
32
+ * Bumped by the caller to load `value` into the canvas again, which is what
33
+ * an example, a share link or a Clear button does. Changing it discards
34
+ * whatever was being drawn.
35
+ * @default 0
36
+ */
37
+ revision?: number;
38
+ /**
39
+ * How long the drawing has to be still before `onChange` is called, in
40
+ * milliseconds. Long enough that drawing a ring does not publish six
41
+ * structures; `0` reports every stroke.
42
+ * @default 300
43
+ */
44
+ debounce?: number;
45
+ /**
46
+ * Smallest height of the drawing area, in pixels. Raised to whatever the
47
+ * toolbar needs, which is usually more.
48
+ * @default 320
49
+ */
50
+ minHeight?: number;
51
+ /**
52
+ * Whether the editor draws one structure or a reaction. A reaction canvas
53
+ * has its own toolbar and its own arrow.
54
+ * @default 'molecule'
55
+ */
56
+ mode?: StructureEditorMode;
57
+ /**
58
+ * Explain each toolbar button in a tooltip, and put a button in the corner
59
+ * that opens a guide to the mouse and the keyboard, which F1 opens too.
60
+ * @default true
61
+ */
62
+ help?: boolean;
63
+ /**
64
+ * Put a button in the corner that opens every notation of the drawing — its
65
+ * SMILES, its molfiles, its canonical identifiers — and the picture of it,
66
+ * ready to copy or to save. A reaction has none of those, so it is never
67
+ * offered one.
68
+ * @default true
69
+ */
70
+ exportable?: boolean;
71
+ /**
72
+ * Take a structure dropped on the canvas — a molfile, an SDF, a SMILES or
73
+ * an idCode, as a file or as text dragged from another page — and put a
74
+ * button in the corner that opens one from disk. A reaction canvas takes
75
+ * none.
76
+ * @default true
77
+ */
78
+ importable?: boolean;
79
+ /**
80
+ * Take what is dropped or opened yourself instead of letting the editor read
81
+ * it, for a page that reads more than the canvas does — an XYZ, a PDB, a 3D
82
+ * geometry the canvas would flatten. The page then loads the structure back
83
+ * through `value` and `revision`, like any other.
84
+ * @default undefined
85
+ */
86
+ onImport?: (transfer: StructureTransfer) => void;
87
+ /**
88
+ * Class the container carries, so a site can reach it from its stylesheet.
89
+ * @default undefined
90
+ */
91
+ className?: string;
92
+ /**
93
+ * Extra style for the container, merged over the packaged one.
94
+ * @default undefined
95
+ */
96
+ style?: CSSProperties;
97
+ }
98
+ //# sourceMappingURL=structureEditorProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structureEditorProps.d.ts","sourceRoot":"","sources":["../../../src/structure/ui/structureEditorProps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAE3B,oCAAoC;AACpC,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=structureEditorProps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structureEditorProps.js","sourceRoot":"","sources":["../../../src/structure/ui/structureEditorProps.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import type { StructureEditorChange } from './editorChange.ts';
2
+ /**
3
+ * Report the last edit of a burst rather than every one of them.
4
+ *
5
+ * The editor's own event is read out before the wait starts, so what arrives
6
+ * late is a plain object rather than a handle on an editor that has moved on.
7
+ * An editor removed mid-burst — a tab switched, a card folded — still reports
8
+ * its last edit, which would otherwise be lost with the timer.
9
+ * @param onChange - What the caller wants told.
10
+ * @param delay - How long the drawing has to be still, in milliseconds.
11
+ * @param resetKey - Dropped edits: a burst still waiting when the caller
12
+ * replaces the structure describes a canvas that no longer exists.
13
+ * @returns The handler to give the canvas.
14
+ */
15
+ export declare function useDebouncedChange(onChange: (change: StructureEditorChange) => void, delay: number, resetKey: number): (change: StructureEditorChange) => void;
16
+ //# sourceMappingURL=useDebouncedChange.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDebouncedChange.d.ts","sourceRoot":"","sources":["../../../src/structure/ui/useDebouncedChange.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,EACjD,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAiBzC"}
@@ -0,0 +1,30 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { createPendingCall } from "../core/pendingCall.js";
3
+ /**
4
+ * Report the last edit of a burst rather than every one of them.
5
+ *
6
+ * The editor's own event is read out before the wait starts, so what arrives
7
+ * late is a plain object rather than a handle on an editor that has moved on.
8
+ * An editor removed mid-burst — a tab switched, a card folded — still reports
9
+ * its last edit, which would otherwise be lost with the timer.
10
+ * @param onChange - What the caller wants told.
11
+ * @param delay - How long the drawing has to be still, in milliseconds.
12
+ * @param resetKey - Dropped edits: a burst still waiting when the caller
13
+ * replaces the structure describes a canvas that no longer exists.
14
+ * @returns The handler to give the canvas.
15
+ */
16
+ export function useDebouncedChange(onChange, delay, resetKey) {
17
+ const [pending] = useState((createPendingCall));
18
+ const onChangeRef = useRef(onChange);
19
+ useEffect(() => {
20
+ onChangeRef.current = onChange;
21
+ });
22
+ useEffect(() => {
23
+ pending.drop();
24
+ }, [pending, resetKey]);
25
+ useEffect(() => () => pending.flush(), [pending]);
26
+ return useCallback((change) => {
27
+ pending.push(change, delay, (value) => onChangeRef.current(value));
28
+ }, [pending, delay]);
29
+ }
30
+ //# sourceMappingURL=useDebouncedChange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDebouncedChange.js","sourceRoot":"","sources":["../../../src/structure/ui/useDebouncedChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAI3D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAiD,EACjD,KAAa,EACb,QAAgB;IAEhB,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAA,iBAAwC,CAAA,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IACjC,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxB,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAElD,OAAO,WAAW,CAChB,CAAC,MAA6B,EAAE,EAAE;QAChC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC,EACD,CAAC,OAAO,EAAE,KAAK,CAAC,CACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { DragEvent } from 'react';
2
+ import type { StructureTransfer } from '../core/structureTransfer.ts';
3
+ /** The drag handlers of one element. */
4
+ export interface DropHandlers {
5
+ onDragEnter?: (event: DragEvent<HTMLElement>) => void;
6
+ onDragOver?: (event: DragEvent<HTMLElement>) => void;
7
+ onDragLeave?: (event: DragEvent<HTMLElement>) => void;
8
+ onDrop?: (event: DragEvent<HTMLElement>) => void;
9
+ }
10
+ /** A drop target, in two parts: the element and the overlay it raises. */
11
+ export interface StructureDropTarget {
12
+ /** Whether a file or text is being dragged over the target. */
13
+ over: boolean;
14
+ /** Put on the element that takes the drop. */
15
+ targetProps: DropHandlers;
16
+ /**
17
+ * Put on the overlay drawn while `over`. It covers the target and takes
18
+ * every drag event from then on, so moving across the canvas and the buttons
19
+ * underneath never reads as leaving, and leaving the overlay is leaving.
20
+ */
21
+ overlayProps: DropHandlers;
22
+ }
23
+ /**
24
+ * Take a file or text dropped on an element.
25
+ * @param onDrop - Where the drop goes; `undefined` takes none.
26
+ * @returns Whether a drag is over the element, and the handlers to put on it
27
+ * and on its overlay.
28
+ */
29
+ export declare function useStructureDrop(onDrop: ((transfer: StructureTransfer) => void) | undefined): StructureDropTarget;
30
+ //# sourceMappingURL=useStructureDrop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStructureDrop.d.ts","sourceRoot":"","sources":["../../../src/structure/ui/useStructureDrop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAMtE,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACtD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACrD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;CAClD;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,IAAI,EAAE,OAAO,CAAC;IACd,8CAA8C;IAC9C,WAAW,EAAE,YAAY,CAAC;IAC1B;;;;OAIG;IACH,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,GAC1D,mBAAmB,CAoCrB"}
@@ -0,0 +1,49 @@
1
+ import { useMemo, useState } from 'react';
2
+ import { carriesStructure, readStructureTransfer, } from "../core/structureTransfer.js";
3
+ /**
4
+ * Take a file or text dropped on an element.
5
+ * @param onDrop - Where the drop goes; `undefined` takes none.
6
+ * @returns Whether a drag is over the element, and the handlers to put on it
7
+ * and on its overlay.
8
+ */
9
+ export function useStructureDrop(onDrop) {
10
+ const [over, setOver] = useState(false);
11
+ return useMemo(() => {
12
+ if (onDrop === undefined) {
13
+ return { over: false, targetProps: {}, overlayProps: {} };
14
+ }
15
+ const accept = (event) => {
16
+ if (!carriesStructure(event.dataTransfer.types))
17
+ return false;
18
+ event.preventDefault();
19
+ event.dataTransfer.dropEffect = 'copy';
20
+ return true;
21
+ };
22
+ return {
23
+ over,
24
+ targetProps: {
25
+ onDragEnter: (event) => {
26
+ if (accept(event))
27
+ setOver(true);
28
+ },
29
+ onDragOver: accept,
30
+ },
31
+ overlayProps: {
32
+ onDragOver: accept,
33
+ onDragLeave: (event) => {
34
+ if (event.target === event.currentTarget)
35
+ setOver(false);
36
+ },
37
+ onDrop: (event) => {
38
+ setOver(false);
39
+ const transfer = readStructureTransfer(event.dataTransfer);
40
+ if (transfer === null)
41
+ return;
42
+ event.preventDefault();
43
+ onDrop(transfer);
44
+ },
45
+ },
46
+ };
47
+ }, [onDrop, over]);
48
+ }
49
+ //# sourceMappingURL=useStructureDrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStructureDrop.js","sourceRoot":"","sources":["../../../src/structure/ui/useStructureDrop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AAwBtC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA2D;IAE3D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAC5D,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,KAA6B,EAAW,EAAE;YACxD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC9D,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,OAAO;YACL,IAAI;YACJ,WAAW,EAAE;gBACX,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;oBACrB,IAAI,MAAM,CAAC,KAAK,CAAC;wBAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBACnC,CAAC;gBACD,UAAU,EAAE,MAAM;aACnB;YACD,YAAY,EAAE;gBACZ,UAAU,EAAE,MAAM;gBAClB,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;oBACrB,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa;wBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3D,CAAC;gBACD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;oBAChB,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAC3D,IAAI,QAAQ,KAAK,IAAI;wBAAE,OAAO;oBAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACnB,CAAC;aACF;SACF,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACrB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { StructureTransfer } from '../core/structureTransfer.ts';
2
+ import type { StructureEditorMoleculeChange } from './editorChange.ts';
3
+ /** What {@link useStructureImport} needs. */
4
+ export interface StructureImportOptions {
5
+ /** Bumped by the caller to load its own value, which drops any import. */
6
+ revision: number;
7
+ /** Whether the editor draws a query fragment. */
8
+ fragment: boolean;
9
+ /** The caller's own reader, which then takes every drop instead. */
10
+ onImport: ((transfer: StructureTransfer) => void) | undefined;
11
+ /** Where a structure the editor read goes: the path an edit takes. */
12
+ onRead: (change: StructureEditorMoleculeChange) => void;
13
+ }
14
+ /** Why the last drop loaded nothing. */
15
+ export interface StructureImportProblem {
16
+ /** The file that was read, `null` for dragged text. */
17
+ file: string | null;
18
+ }
19
+ /** The editor's imports, as the canvas and its corner need them. */
20
+ export interface StructureImport {
21
+ /**
22
+ * The idCode the canvas loads instead of the caller's value, `null` while it
23
+ * shows that value.
24
+ */
25
+ idCode: string | null;
26
+ /** The canvas's key: a new one per import, which loads it. */
27
+ canvasKey: string;
28
+ /** Read a drop or a chosen file. */
29
+ load: (transfer: StructureTransfer) => void;
30
+ /** Why the last drop loaded nothing, `null` when it did. */
31
+ problem: StructureImportProblem | null;
32
+ /** Forget the problem. */
33
+ dismiss: () => void;
34
+ }
35
+ /**
36
+ * Load what is dropped on the editor, or opened from disk, into its canvas.
37
+ *
38
+ * The canvas is uncontrolled, so a dropped structure — one the editor never
39
+ * produced — remounts it with a new key, and is then reported like an edit.
40
+ * A drop overtaken by a later one is dropped rather than applied late.
41
+ * @param options - See {@link StructureImportOptions}.
42
+ * @returns See {@link StructureImport}.
43
+ */
44
+ export declare function useStructureImport(options: StructureImportOptions): StructureImport;
45
+ //# sourceMappingURL=useStructureImport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStructureImport.d.ts","sourceRoot":"","sources":["../../../src/structure/ui/useStructureImport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAEvE,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9D,sEAAsE;IACtE,MAAM,EAAE,CAAC,MAAM,EAAE,6BAA6B,KAAK,IAAI,CAAC;CACzD;AAED,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACrC,uDAAuD;IACvD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,IAAI,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5C,4DAA4D;IAC5D,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACvC,0BAA0B;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AASD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAyCjB"}
@@ -0,0 +1,62 @@
1
+ import { useCallback, useRef, useState } from 'react';
2
+ /**
3
+ * Load what is dropped on the editor, or opened from disk, into its canvas.
4
+ *
5
+ * The canvas is uncontrolled, so a dropped structure — one the editor never
6
+ * produced — remounts it with a new key, and is then reported like an edit.
7
+ * A drop overtaken by a later one is dropped rather than applied late.
8
+ * @param options - See {@link StructureImportOptions}.
9
+ * @returns See {@link StructureImport}.
10
+ */
11
+ export function useStructureImport(options) {
12
+ const { revision, fragment, onImport, onRead } = options;
13
+ const [imported, setImported] = useState(null);
14
+ const [problem, setProblem] = useState(null);
15
+ const token = useRef(0);
16
+ const load = useCallback((transfer) => {
17
+ setProblem(null);
18
+ if (onImport !== undefined) {
19
+ onImport(transfer);
20
+ return;
21
+ }
22
+ const current = ++token.current;
23
+ void readTransfer(transfer, fragment).then(({ file, change }) => {
24
+ if (current !== token.current)
25
+ return;
26
+ if (change === null) {
27
+ setProblem({ file });
28
+ return;
29
+ }
30
+ setImported((previous) => ({
31
+ revision,
32
+ count: previous?.revision === revision ? previous.count + 1 : 1,
33
+ idCode: change.idCode,
34
+ }));
35
+ onRead(change);
36
+ });
37
+ }, [fragment, onImport, onRead, revision]);
38
+ const dismiss = useCallback(() => setProblem(null), []);
39
+ const current = imported?.revision === revision ? imported : null;
40
+ return {
41
+ idCode: current?.idCode ?? null,
42
+ canvasKey: `${revision}.${current?.count ?? 0}`,
43
+ load,
44
+ problem,
45
+ dismiss,
46
+ };
47
+ }
48
+ async function readTransfer(transfer, fragment) {
49
+ const file = transfer.kind === 'files' ? transfer.files[0] : undefined;
50
+ try {
51
+ const text = transfer.kind === 'text' ? transfer.text : ((await file?.text()) ?? '');
52
+ const { readImportedStructure } = await import("./importedStructure.js");
53
+ return {
54
+ file: file?.name ?? null,
55
+ change: readImportedStructure(text, fragment),
56
+ };
57
+ }
58
+ catch {
59
+ return { file: file?.name ?? null, change: null };
60
+ }
61
+ }
62
+ //# sourceMappingURL=useStructureImport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStructureImport.js","sourceRoot":"","sources":["../../../src/structure/ui/useStructureImport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAgDtD;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA+B;IAE/B,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACzD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAkB,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgC,IAAI,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAExB,MAAM,IAAI,GAAG,WAAW,CACtB,CAAC,QAA2B,EAAE,EAAE;QAC9B,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC;QAChC,KAAK,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;YAC9D,IAAI,OAAO,KAAK,KAAK,CAAC,OAAO;gBAAE,OAAO;YACtC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,WAAW,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACzB,QAAQ;gBACR,KAAK,EAAE,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/D,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,MAAM,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CACvC,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAElE,OAAO;QACL,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI;QAC/B,SAAS,EAAE,GAAG,QAAQ,IAAI,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;QAC/C,IAAI;QACJ,OAAO;QACP,OAAO;KACR,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,QAA2B,EAC3B,QAAiB;IAKjB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,IAAI,GACR,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACzE,OAAO;YACL,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI;YACxB,MAAM,EAAE,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC;SAC9C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-cheminfo",
3
- "version": "0.65.0",
3
+ "version": "0.67.0",
4
4
  "license": "MIT",
5
5
  "description": "React components, hooks and framework-free helpers shared by the cheminfo sites: site chrome, citations, sharing, routing, pedagogy, charts, and the structure, orbital and 3D molecule viewers",
6
6
  "author": "Luc Patiny",
@@ -27,6 +27,7 @@
27
27
  "./molstar/*": "./lib/molstar/*/index.js",
28
28
  "./orbital": "./lib/orbital.js",
29
29
  "./pages": "./lib/pages.js",
30
+ "./raman": "./lib/raman.js",
30
31
  "./server": "./lib/server.js",
31
32
  "./slides": "./lib/slides.js",
32
33
  "./spectra": "./lib/spectra.js",
@@ -70,6 +71,7 @@
70
71
  },
71
72
  "dependencies": {
72
73
  "@formatjs/icu-messageformat-parser": "^3.5.20",
74
+ "@pdf-lib/upng": "^1.0.1",
73
75
  "@tanstack/react-virtual": "^3.14.13",
74
76
  "ajv": "^8.20.0",
75
77
  "cheminfo-font": "^1.28.0",
@@ -96,6 +98,7 @@
96
98
  "@playwright/test": "^1.62.1",
97
99
  "@storybook/addon-docs": "^10.5.8",
98
100
  "@storybook/react-vite": "^10.5.8",
101
+ "@testing-library/dom": "^10.4.2",
99
102
  "@types/node": "^26.2.0",
100
103
  "@types/react": "^19.2.18",
101
104
  "@types/react-dom": "^19.2.4",
@@ -108,6 +111,7 @@
108
111
  "eslint": "^9.39.5",
109
112
  "eslint-config-cheminfo-react": "^20.1.0",
110
113
  "eslint-config-cheminfo-typescript": "^22.1.0",
114
+ "fast-png": "^8.0.0",
111
115
  "fastify": "^5.12.7",
112
116
  "jsdom": "^30.1.1",
113
117
  "ml-dataset-iris": "^1.2.1",
@@ -1,4 +1,4 @@
1
- import type { ReactElement } from 'react';
1
+ import type { ReactElement, ReactNode } from 'react';
2
2
 
3
3
  import { useChromeT } from '../../i18n/ui/useT.ts';
4
4
  import { OverlayAction } from '../../overlay/ui/OverlayAction.tsx';
@@ -67,6 +67,12 @@ export interface FigureDownloadPanelProps {
67
67
  * @default undefined
68
68
  */
69
69
  sizing?: FigureSizing;
70
+ /**
71
+ * Rows of the figure's own, shown after the format: what else decides the
72
+ * file, such as which frames of an animation go into it.
73
+ * @default undefined
74
+ */
75
+ children?: ReactNode;
70
76
  }
71
77
 
72
78
  /**
@@ -93,7 +99,7 @@ export function FigureDownloadPanel(
93
99
  ): ReactElement {
94
100
  const { title, format, scale, scales, size, failure, saving } = props;
95
101
  const { onFormatChange, onScaleChange, onSave, rasterSvg = false } = props;
96
- const { sizing, onCopy, notice = null } = props;
102
+ const { sizing, onCopy, notice = null, children } = props;
97
103
  const t = useChromeT();
98
104
 
99
105
  // What the file is drawn at: the figure on screen, or the shape picked.
@@ -142,6 +148,7 @@ export function FigureDownloadPanel(
142
148
  options={FORMAT_CHOICES}
143
149
  onChange={onFormatChange}
144
150
  />
151
+ {children}
145
152
  {sizing === undefined ? null : (
146
153
  <FigureSizeRows sizing={sizing} size={size} />
147
154
  )}
@@ -141,9 +141,9 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
141
141
  mark: { plate: '#1e293b', accent: '#127ba3' },
142
142
  },
143
143
  {
144
- id: 'surge',
145
- name: { lead: 'surge', alt: 'cheminfo', dot: true },
146
- host: 'surge.cheminfo.org',
144
+ id: 'isomers',
145
+ name: { lead: 'isomers', alt: 'cheminfo', dot: true },
146
+ host: 'isomers.cheminfo.org',
147
147
  tagline: 'Every constitutional isomer of a molecular formula.',
148
148
  group: 'structures',
149
149
  brand: '#4338ca',
@@ -13,7 +13,7 @@ export type SiteId =
13
13
  | 'nmrium'
14
14
  | 'metabo'
15
15
  | 'derepflow'
16
- | 'surge'
16
+ | 'isomers'
17
17
  | 'tex'
18
18
  | 'lcao'
19
19
  | 'regexp'
@@ -216,7 +216,7 @@ export const GLYPHS: Record<SiteId, (alt: string) => ReactNode> = {
216
216
  </>
217
217
  ),
218
218
  // One formula branching into every structure it can be.
219
- surge: (alt) => (
219
+ isomers: (alt) => (
220
220
  <>
221
221
  <g
222
222
  fill="none"
@@ -26,7 +26,7 @@ export type MessagesLoader = () => Promise<{ default: Messages }>;
26
26
  /**
27
27
  * A key the catalog declares, or any other string.
28
28
  *
29
- * Many keys are built from the data — `site.surge.tagline`, `element.Fe.name`
29
+ * Many keys are built from the data — `site.isomers.tagline`, `element.Fe.name`
30
30
  * — so a row added before the catalogs have caught up must read as itself
31
31
  * rather than fail to compile.
32
32
  */
@@ -51,7 +51,7 @@ export interface TranslateOptions {
51
51
  export interface MessageCatalogOptions<TKey extends string> {
52
52
  /**
53
53
  * The name the page knows the catalog by, unique on the page, e.g.
54
- * `react-cheminfo` or `surge.cheminfo.org`.
54
+ * `react-cheminfo` or `isomers.cheminfo.org`.
55
55
  */
56
56
  id: string;
57
57
  /** The GitHub repository the files live in, written `owner/repo`. */
@@ -38,7 +38,7 @@ import { DEFAULT_LANGUAGE, LANGUAGES, MessageCatalog } from '../core/index.ts';
38
38
  export interface LocaleCatalogSource {
39
39
  /**
40
40
  * The name the page knows the catalog by, which is the site's host, e.g.
41
- * `surge.cheminfo.org`. A translator's edit is routed back to the right
41
+ * `isomers.cheminfo.org`. A translator's edit is routed back to the right
42
42
  * repository with it, so the build and the page must agree on it.
43
43
  */
44
44
  id: string;
@@ -14,14 +14,31 @@ import { xySortX } from 'ml-spectra-processing';
14
14
 
15
15
  import type { IrMeta, IrMode, IrOrigin } from './irSpectrum.ts';
16
16
 
17
- /** One spectrum as a reader produced it, before it is named and coloured. */
17
+ /**
18
+ * One spectrum as a reader produced it, before it is named and coloured.
19
+ *
20
+ * The readers of this package produce infrared spectra, which carry absorbance
21
+ * and transmittance; a host reading a Raman file builds one carrying its
22
+ * intensity instead.
23
+ */
18
24
  export interface LoadedIrSpectrum {
19
- /** The wavenumbers, ascending. */
25
+ /** The wavenumbers — or, for a Raman spectrum, the Raman shifts — ascending. */
20
26
  wavenumber: Float64Array;
21
- /** Absorbance at each. */
22
- absorbance: Float64Array;
23
- /** Percent transmittance at each. */
24
- transmittance: Float64Array;
27
+ /**
28
+ * Absorbance at each, for an infrared spectrum.
29
+ * @default undefined
30
+ */
31
+ absorbance?: Float64Array;
32
+ /**
33
+ * Percent transmittance at each, for an infrared spectrum.
34
+ * @default undefined
35
+ */
36
+ transmittance?: Float64Array;
37
+ /**
38
+ * Intensity at each, for a Raman spectrum.
39
+ * @default undefined
40
+ */
41
+ intensity?: Float64Array;
25
42
  /** What the file said about the acquisition, `null` when it said nothing. */
26
43
  meta: IrMeta | null;
27
44
  /** Where it came from. */
@@ -96,10 +113,9 @@ export function analysisSpectra(
96
113
  return spectra;
97
114
  }
98
115
 
99
- /** The three arrays of one spectrum, in ascending wavenumber. */
100
- type SortedTraces = Pick<
101
- LoadedIrSpectrum,
102
- 'wavenumber' | 'absorbance' | 'transmittance'
116
+ /** The three arrays of one infrared spectrum, in ascending wavenumber. */
117
+ type SortedTraces = Required<
118
+ Pick<LoadedIrSpectrum, 'wavenumber' | 'absorbance' | 'transmittance'>
103
119
  >;
104
120
 
105
121
  /**
@@ -18,6 +18,7 @@ import { labelStackBaselines } from '../../chart/core/labelStack.ts';
18
18
  import type { AssignedBand } from './assignBands.ts';
19
19
  import { bandLabel } from './assignBands.ts';
20
20
  import type { IrBand } from './irBand.ts';
21
+ import { bandHeight, bandValue } from './irBand.ts';
21
22
  import { formatWavenumber } from './irFormat.ts';
22
23
  import { bandsPointDown } from './irMode.ts';
23
24
  import type { IrMode } from './irSpectrum.ts';
@@ -99,12 +100,15 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
99
100
  limit = 12,
100
101
  } = options;
101
102
 
102
- const inside: AssignedBand[] = [];
103
+ const inside: NamedBand[] = [];
103
104
  for (const entry of assigned) {
105
+ // A band with no value on the axis being read has no tip to hang from.
106
+ const value = bandValue(entry.band, mode);
107
+ if (value === undefined) continue;
104
108
  const pixelX = chartPixel(xScale, entry.band.wavenumber);
105
109
  if (!Number.isFinite(pixelX)) continue;
106
110
  if (pixelX < plot.left || pixelX > plot.right) continue;
107
- inside.push(entry);
111
+ inside.push({ entry, value });
108
112
  }
109
113
 
110
114
  const named =
@@ -112,18 +116,20 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
112
116
  ? inside
113
117
  : inside
114
118
  .toSorted(
115
- (first, second) => second.band.absorbance - first.band.absorbance,
119
+ (first, second) =>
120
+ bandHeight(second.entry.band) - bandHeight(first.entry.band),
116
121
  )
117
122
  .slice(0, limit)
118
123
  .toSorted(
119
- (first, second) => first.band.wavenumber - second.band.wavenumber,
124
+ (first, second) =>
125
+ first.entry.band.wavenumber - second.entry.band.wavenumber,
120
126
  );
121
127
 
122
128
  const centres = new Float64Array(named.length);
123
129
  for (let index = 0; index < named.length; index++) {
124
130
  centres[index] = chartPixel(
125
131
  xScale,
126
- (named[index] as AssignedBand).band.wavenumber,
132
+ (named[index] as NamedBand).entry.band.wavenumber,
127
133
  );
128
134
  }
129
135
  const placed = layoutAnnotationBoxes(
@@ -136,12 +142,9 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
136
142
  const down = bandsPointDown(mode);
137
143
  const plans: BandLabelPlan[] = new Array<BandLabelPlan>(named.length);
138
144
  for (let index = 0; index < named.length; index++) {
139
- const entry = named[index] as AssignedBand;
145
+ const { entry, value } = named[index] as NamedBand;
140
146
  const lines = labelLines(entry, showAssignments);
141
- const tipY = chartPixel(
142
- yScale,
143
- mode === 'absorbance' ? entry.band.absorbance : entry.band.transmittance,
144
- );
147
+ const tipY = chartPixel(yScale, value);
145
148
  plans[index] = {
146
149
  band: entry.band,
147
150
  tipX: centres[index] as number,
@@ -161,6 +164,14 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
161
164
  return plans;
162
165
  }
163
166
 
167
+ /** A band inside the window, with its value on the axis being read. */
168
+ interface NamedBand {
169
+ /** The band and whatever the table said about it. */
170
+ entry: AssignedBand;
171
+ /** Where its tip is, on the value axis. */
172
+ value: number;
173
+ }
174
+
164
175
  /**
165
176
  * How wide a label is taken to be while it is being spaced out.
166
177
  *