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.
- package/README.md +33 -17
- package/lib/download/ui/FigureDownloadPanel.d.ts +7 -1
- package/lib/download/ui/FigureDownloadPanel.d.ts.map +1 -1
- package/lib/download/ui/FigureDownloadPanel.js +2 -2
- package/lib/download/ui/FigureDownloadPanel.js.map +1 -1
- package/lib/ecosystem/core/sites.js +3 -3
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/core/types.d.ts +1 -1
- package/lib/ecosystem/core/types.d.ts.map +1 -1
- package/lib/ecosystem/ui/glyphs.js +1 -1
- package/lib/ecosystem/ui/glyphs.js.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/i18n/core/messageCatalog.d.ts +2 -2
- package/lib/i18n/vite/localeCatalog.d.ts +1 -1
- package/lib/ir/core/analysisSpectra.d.ts +23 -6
- package/lib/ir/core/analysisSpectra.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.js.map +1 -1
- package/lib/ir/core/bandLabelPlan.d.ts.map +1 -1
- package/lib/ir/core/bandLabelPlan.js +11 -6
- package/lib/ir/core/bandLabelPlan.js.map +1 -1
- package/lib/ir/core/index.d.ts +15 -11
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +9 -6
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBand.d.ts +45 -14
- package/lib/ir/core/irBand.d.ts.map +1 -1
- package/lib/ir/core/irBand.js +28 -6
- package/lib/ir/core/irBand.js.map +1 -1
- package/lib/ir/core/irCommands.d.ts +11 -0
- package/lib/ir/core/irCommands.d.ts.map +1 -1
- package/lib/ir/core/irCommands.js +11 -1
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irDomain.d.ts +4 -3
- package/lib/ir/core/irDomain.d.ts.map +1 -1
- package/lib/ir/core/irDomain.js +10 -7
- package/lib/ir/core/irDomain.js.map +1 -1
- package/lib/ir/core/irEditorApi.d.ts +12 -0
- package/lib/ir/core/irEditorApi.d.ts.map +1 -1
- package/lib/ir/core/irFormat.d.ts +14 -2
- package/lib/ir/core/irFormat.d.ts.map +1 -1
- package/lib/ir/core/irFormat.js +33 -4
- package/lib/ir/core/irFormat.js.map +1 -1
- package/lib/ir/core/irMode.d.ts +35 -8
- package/lib/ir/core/irMode.d.ts.map +1 -1
- package/lib/ir/core/irMode.js +38 -10
- package/lib/ir/core/irMode.js.map +1 -1
- package/lib/ir/core/irReducer.d.ts +2 -30
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +1 -24
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSidePanels.d.ts +7 -1
- package/lib/ir/core/irSidePanels.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +52 -26
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js +21 -15
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +46 -5
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +38 -1
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/irTechnique.d.ts +94 -0
- package/lib/ir/core/irTechnique.d.ts.map +1 -0
- package/lib/ir/core/irTechnique.js +87 -0
- package/lib/ir/core/irTechnique.js.map +1 -0
- package/lib/ir/core/irTechniqueCommands.d.ts +26 -0
- package/lib/ir/core/irTechniqueCommands.d.ts.map +1 -0
- package/lib/ir/core/irTechniqueCommands.js +68 -0
- package/lib/ir/core/irTechniqueCommands.js.map +1 -0
- package/lib/ir/core/pickBands.d.ts +6 -5
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +49 -26
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +30 -0
- package/lib/ir/core/ramanBands.d.ts.map +1 -0
- package/lib/ir/core/ramanBands.js +83 -0
- package/lib/ir/core/ramanBands.js.map +1 -0
- package/lib/ir/core/spectrumJcamp.d.ts +10 -5
- package/lib/ir/core/spectrumJcamp.d.ts.map +1 -1
- package/lib/ir/core/spectrumJcamp.js +63 -15
- package/lib/ir/core/spectrumJcamp.js.map +1 -1
- package/lib/ir/core/toIrSpectrum.d.ts.map +1 -1
- package/lib/ir/core/toIrSpectrum.js +17 -2
- package/lib/ir/core/toIrSpectrum.js.map +1 -1
- package/lib/ir/ui/BandRow.d.ts +30 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -0
- package/lib/ir/ui/BandRow.js +42 -0
- package/lib/ir/ui/BandRow.js.map +1 -0
- package/lib/ir/ui/BandsPanel.d.ts +4 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +14 -59
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/IrAboutDialog.d.ts +7 -0
- package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrAboutDialog.js +16 -3
- package/lib/ir/ui/IrAboutDialog.js.map +1 -1
- package/lib/ir/ui/IrCanvas.d.ts +7 -0
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +9 -4
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts +2 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +22 -21
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrCommandProvider.d.ts +7 -0
- package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandProvider.js +2 -2
- package/lib/ir/ui/IrCommandProvider.js.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.d.ts +7 -0
- package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.js +3 -2
- package/lib/ir/ui/IrCommandTooltip.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts +8 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +30 -7
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +25 -5
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js +3 -20
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrHeader.d.ts.map +1 -1
- package/lib/ir/ui/IrHeader.js +5 -1
- package/lib/ir/ui/IrHeader.js.map +1 -1
- package/lib/ir/ui/IrLogo.d.ts +11 -3
- package/lib/ir/ui/IrLogo.d.ts.map +1 -1
- package/lib/ir/ui/IrLogo.js +14 -5
- package/lib/ir/ui/IrLogo.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts +9 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +26 -74
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrSidePanel.d.ts +11 -0
- package/lib/ir/ui/IrSidePanel.d.ts.map +1 -1
- package/lib/ir/ui/IrSidePanel.js +12 -3
- package/lib/ir/ui/IrSidePanel.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts +3 -2
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +14 -9
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +3 -0
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +10 -3
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/IrTraces.d.ts +4 -1
- package/lib/ir/ui/IrTraces.d.ts.map +1 -1
- package/lib/ir/ui/IrTraces.js +2 -0
- package/lib/ir/ui/IrTraces.js.map +1 -1
- package/lib/ir/ui/RamanEditor.d.ts +64 -0
- package/lib/ir/ui/RamanEditor.d.ts.map +1 -0
- package/lib/ir/ui/RamanEditor.js +17 -0
- package/lib/ir/ui/RamanEditor.js.map +1 -0
- package/lib/ir/ui/SpectraPanel.d.ts.map +1 -1
- package/lib/ir/ui/SpectraPanel.js +2 -2
- package/lib/ir/ui/SpectraPanel.js.map +1 -1
- package/lib/ir/ui/SpectrumRow.d.ts +7 -0
- package/lib/ir/ui/SpectrumRow.d.ts.map +1 -1
- package/lib/ir/ui/SpectrumRow.js +4 -5
- package/lib/ir/ui/SpectrumRow.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +62 -0
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -0
- package/lib/ir/ui/VibrationalEditor.js +33 -0
- package/lib/ir/ui/VibrationalEditor.js.map +1 -0
- package/lib/ir/ui/bandsTsv.d.ts +19 -0
- package/lib/ir/ui/bandsTsv.d.ts.map +1 -0
- package/lib/ir/ui/bandsTsv.js +38 -0
- package/lib/ir/ui/bandsTsv.js.map +1 -0
- package/lib/ir/ui/index.d.ts +1 -0
- package/lib/ir/ui/index.d.ts.map +1 -1
- package/lib/ir/ui/index.js.map +1 -1
- package/lib/ir/ui/irActions.d.ts +3 -3
- package/lib/ir/ui/irActions.d.ts.map +1 -1
- package/lib/ir/ui/irChartProps.d.ts +21 -4
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/irChartProps.js +3 -2
- package/lib/ir/ui/irChartProps.js.map +1 -1
- package/lib/ir/ui/irCommandContext.d.ts +8 -0
- package/lib/ir/ui/irCommandContext.d.ts.map +1 -1
- package/lib/ir/ui/irCommandContext.js +14 -3
- package/lib/ir/ui/irCommandContext.js.map +1 -1
- package/lib/ir/ui/irHostPanels.d.ts +53 -0
- package/lib/ir/ui/irHostPanels.d.ts.map +1 -0
- package/lib/ir/ui/irHostPanels.js +41 -0
- package/lib/ir/ui/irHostPanels.js.map +1 -0
- package/lib/ir/ui/useIrEditor.d.ts +3 -3
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +13 -4
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/ir/ui/useIrHandle.d.ts +14 -0
- package/lib/ir/ui/useIrHandle.d.ts.map +1 -0
- package/lib/ir/ui/useIrHandle.js +39 -0
- package/lib/ir/ui/useIrHandle.js.map +1 -0
- package/lib/ir/ui/useIrSide.d.ts +27 -0
- package/lib/ir/ui/useIrSide.d.ts.map +1 -0
- package/lib/ir/ui/useIrSide.js +42 -0
- package/lib/ir/ui/useIrSide.js.map +1 -0
- package/lib/ir/ui/useIrText.d.ts +40 -0
- package/lib/ir/ui/useIrText.d.ts.map +1 -0
- package/lib/ir/ui/useIrText.js +118 -0
- package/lib/ir/ui/useIrText.js.map +1 -0
- package/lib/ir/ui/useIrZoom.d.ts +15 -0
- package/lib/ir/ui/useIrZoom.d.ts.map +1 -1
- package/lib/ir/ui/useIrZoom.js +6 -4
- package/lib/ir/ui/useIrZoom.js.map +1 -1
- package/lib/ir/ui/useValueAxisZoom.d.ts +20 -0
- package/lib/ir/ui/useValueAxisZoom.d.ts.map +1 -0
- package/lib/ir/ui/useValueAxisZoom.js +54 -0
- package/lib/ir/ui/useValueAxisZoom.js.map +1 -0
- package/lib/ir.d.ts +3 -0
- package/lib/ir.d.ts.map +1 -1
- package/lib/ir.js +3 -0
- package/lib/ir.js.map +1 -1
- package/lib/locales/de.json +29 -2
- package/lib/locales/en.json +29 -2
- package/lib/locales/es.json +29 -2
- package/lib/locales/fr.json +29 -2
- package/lib/locales/it.json +29 -2
- package/lib/molecule3d/core/animatedPng.d.ts +25 -0
- package/lib/molecule3d/core/animatedPng.d.ts.map +1 -0
- package/lib/molecule3d/core/animatedPng.js +59 -0
- package/lib/molecule3d/core/animatedPng.js.map +1 -0
- package/lib/molecule3d/core/file.d.ts +24 -0
- package/lib/molecule3d/core/file.d.ts.map +1 -0
- package/lib/molecule3d/core/file.js +2 -0
- package/lib/molecule3d/core/file.js.map +1 -0
- package/lib/molecule3d/core/index.d.ts +4 -1
- package/lib/molecule3d/core/index.d.ts.map +1 -1
- package/lib/molecule3d/core/index.js +1 -0
- package/lib/molecule3d/core/index.js.map +1 -1
- package/lib/molecule3d/core/settings.d.ts +0 -7
- package/lib/molecule3d/core/settings.d.ts.map +1 -1
- package/lib/molecule3d/core/settings.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DExport.d.ts +10 -2
- package/lib/molecule3d/ui/Molecule3DExport.d.ts.map +1 -1
- package/lib/molecule3d/ui/Molecule3DExport.js +15 -2
- package/lib/molecule3d/ui/Molecule3DExport.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DToolbar.js +9 -2
- package/lib/molecule3d/ui/Molecule3DToolbar.js.map +1 -1
- package/lib/molecule3d/ui/MoleculeCanvas3D.d.ts.map +1 -1
- package/lib/molecule3d/ui/MoleculeCanvas3D.js +23 -41
- package/lib/molecule3d/ui/MoleculeCanvas3D.js.map +1 -1
- package/lib/molecule3d/ui/drawScene.d.ts +2 -1
- package/lib/molecule3d/ui/drawScene.d.ts.map +1 -1
- package/lib/molecule3d/ui/drawScene.js.map +1 -1
- package/lib/molecule3d/ui/exportMoleculeImage.d.ts +15 -1
- package/lib/molecule3d/ui/exportMoleculeImage.d.ts.map +1 -1
- package/lib/molecule3d/ui/exportMoleculeImage.js +14 -2
- package/lib/molecule3d/ui/exportMoleculeImage.js.map +1 -1
- package/lib/molecule3d/ui/moleculeFrames.d.ts +47 -0
- package/lib/molecule3d/ui/moleculeFrames.d.ts.map +1 -0
- package/lib/molecule3d/ui/moleculeFrames.js +65 -0
- package/lib/molecule3d/ui/moleculeFrames.js.map +1 -0
- package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts +14 -1
- package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts.map +1 -1
- package/lib/molecule3d/ui/renderMolecule.d.ts +3 -3
- package/lib/molecule3d/ui/renderMolecule.d.ts.map +1 -1
- package/lib/molecule3d/ui/renderMolecule.js +2 -1
- package/lib/molecule3d/ui/renderMolecule.js.map +1 -1
- package/lib/molecule3d/ui/sceneDrawer.d.ts +2 -1
- package/lib/molecule3d/ui/sceneDrawer.d.ts.map +1 -1
- package/lib/molecule3d/ui/sceneDrawer.js +9 -1
- package/lib/molecule3d/ui/sceneDrawer.js.map +1 -1
- package/lib/molecule3d/ui/useImageExport.d.ts +8 -3
- package/lib/molecule3d/ui/useImageExport.d.ts.map +1 -1
- package/lib/molecule3d/ui/useImageExport.js +13 -4
- package/lib/molecule3d/ui/useImageExport.js.map +1 -1
- package/lib/molecule3d/ui/useMoleculeScene.d.ts +2 -1
- package/lib/molecule3d/ui/useMoleculeScene.d.ts.map +1 -1
- package/lib/molecule3d/ui/useMoleculeScene.js.map +1 -1
- package/lib/molecule3d/ui/useMoleculeViewer.d.ts +16 -0
- package/lib/molecule3d/ui/useMoleculeViewer.d.ts.map +1 -0
- package/lib/molecule3d/ui/useMoleculeViewer.js +37 -0
- package/lib/molecule3d/ui/useMoleculeViewer.js.map +1 -0
- package/lib/molecule3d/ui/usePolarSurfaceArea.d.ts +3 -3
- package/lib/molecule3d/ui/usePolarSurfaceArea.d.ts.map +1 -1
- package/lib/molecule3d/ui/usePolarSurfaceArea.js +4 -3
- package/lib/molecule3d/ui/usePolarSurfaceArea.js.map +1 -1
- package/lib/molecule3d/ui/viewer.d.ts +4 -1
- package/lib/molecule3d/ui/viewer.d.ts.map +1 -1
- package/lib/molecule3d/ui/viewer.js +21 -19
- package/lib/molecule3d/ui/viewer.js.map +1 -1
- package/lib/molecule3d/ui/viewerTypes.d.ts +6 -0
- package/lib/molecule3d/ui/viewerTypes.d.ts.map +1 -1
- package/lib/molstar/core/captureScene.d.ts +19 -1
- package/lib/molstar/core/captureScene.d.ts.map +1 -1
- package/lib/molstar/core/captureScene.js +57 -2
- package/lib/molstar/core/captureScene.js.map +1 -1
- package/lib/molstar/core/index.d.ts +5 -2
- package/lib/molstar/core/index.d.ts.map +1 -1
- package/lib/molstar/core/index.js +4 -2
- package/lib/molstar/core/index.js.map +1 -1
- package/lib/molstar/core/trajectory.d.ts +56 -0
- package/lib/molstar/core/trajectory.d.ts.map +1 -0
- package/lib/molstar/core/trajectory.js +96 -0
- package/lib/molstar/core/trajectory.js.map +1 -0
- package/lib/panel/ui/PanelRail.d.ts.map +1 -1
- package/lib/panel/ui/PanelRail.js +1 -1
- package/lib/panel/ui/PanelRail.js.map +1 -1
- package/lib/raman.d.ts +17 -0
- package/lib/raman.d.ts.map +1 -0
- package/lib/raman.js +12 -0
- package/lib/raman.js.map +1 -0
- package/lib/router/core/basePath.d.ts +2 -2
- package/lib/router/core/basePath.js +2 -2
- package/lib/router/core/siteAddresses.d.ts +1 -1
- package/lib/router/core/siteAddresses.js +1 -1
- package/lib/seo/core/siteFiles.js +1 -1
- package/lib/seo/core/siteFiles.js.map +1 -1
- package/lib/server/answerAddresses.d.ts +3 -3
- package/lib/server/answerAddresses.js +3 -3
- package/lib/structure/core/index.d.ts +2 -0
- package/lib/structure/core/index.d.ts.map +1 -1
- package/lib/structure/core/index.js +1 -0
- package/lib/structure/core/index.js.map +1 -1
- package/lib/structure/core/structureTransfer.d.ts +29 -0
- package/lib/structure/core/structureTransfer.d.ts.map +1 -0
- package/lib/structure/core/structureTransfer.js +26 -0
- package/lib/structure/core/structureTransfer.js.map +1 -0
- package/lib/structure/ui/EditorImportButton.d.ts +20 -0
- package/lib/structure/ui/EditorImportButton.d.ts.map +1 -0
- package/lib/structure/ui/EditorImportButton.js +24 -0
- package/lib/structure/ui/EditorImportButton.js.map +1 -0
- package/lib/structure/ui/EditorImportProblem.d.ts +17 -0
- package/lib/structure/ui/EditorImportProblem.d.ts.map +1 -0
- package/lib/structure/ui/EditorImportProblem.js +32 -0
- package/lib/structure/ui/EditorImportProblem.js.map +1 -0
- package/lib/structure/ui/StructureDrop.d.ts +39 -0
- package/lib/structure/ui/StructureDrop.d.ts.map +1 -0
- package/lib/structure/ui/StructureDrop.js +19 -0
- package/lib/structure/ui/StructureDrop.js.map +1 -0
- package/lib/structure/ui/StructureDropOverlay.d.ts +16 -0
- package/lib/structure/ui/StructureDropOverlay.d.ts.map +1 -0
- package/lib/structure/ui/StructureDropOverlay.js +29 -0
- package/lib/structure/ui/StructureDropOverlay.js.map +1 -0
- package/lib/structure/ui/StructureEditor.d.ts +3 -80
- package/lib/structure/ui/StructureEditor.d.ts.map +1 -1
- package/lib/structure/ui/StructureEditor.js +21 -33
- package/lib/structure/ui/StructureEditor.js.map +1 -1
- package/lib/structure/ui/importedStructure.d.ts +25 -0
- package/lib/structure/ui/importedStructure.d.ts.map +1 -0
- package/lib/structure/ui/importedStructure.js +74 -0
- package/lib/structure/ui/importedStructure.js.map +1 -0
- package/lib/structure/ui/index.d.ts +2 -0
- package/lib/structure/ui/index.d.ts.map +1 -1
- package/lib/structure/ui/index.js +1 -0
- package/lib/structure/ui/index.js.map +1 -1
- package/lib/structure/ui/structureEditorProps.d.ts +98 -0
- package/lib/structure/ui/structureEditorProps.d.ts.map +1 -0
- package/lib/structure/ui/structureEditorProps.js +2 -0
- package/lib/structure/ui/structureEditorProps.js.map +1 -0
- package/lib/structure/ui/useDebouncedChange.d.ts +16 -0
- package/lib/structure/ui/useDebouncedChange.d.ts.map +1 -0
- package/lib/structure/ui/useDebouncedChange.js +30 -0
- package/lib/structure/ui/useDebouncedChange.js.map +1 -0
- package/lib/structure/ui/useStructureDrop.d.ts +30 -0
- package/lib/structure/ui/useStructureDrop.d.ts.map +1 -0
- package/lib/structure/ui/useStructureDrop.js +49 -0
- package/lib/structure/ui/useStructureDrop.js.map +1 -0
- package/lib/structure/ui/useStructureImport.d.ts +45 -0
- package/lib/structure/ui/useStructureImport.d.ts.map +1 -0
- package/lib/structure/ui/useStructureImport.js +62 -0
- package/lib/structure/ui/useStructureImport.js.map +1 -0
- package/package.json +5 -1
- package/src/download/ui/FigureDownloadPanel.tsx +9 -2
- package/src/ecosystem/core/sites.ts +3 -3
- package/src/ecosystem/core/types.ts +1 -1
- package/src/ecosystem/ui/glyphs.tsx +1 -1
- package/src/i18n/core/messageCatalog.ts +2 -2
- package/src/i18n/vite/localeCatalog.ts +1 -1
- package/src/ir/core/analysisSpectra.ts +26 -10
- package/src/ir/core/bandLabelPlan.ts +21 -10
- package/src/ir/core/index.ts +31 -7
- package/src/ir/core/irBand.ts +52 -14
- package/src/ir/core/irCommands.ts +15 -1
- package/src/ir/core/irDomain.ts +9 -7
- package/src/ir/core/irEditorApi.ts +13 -0
- package/src/ir/core/irFormat.ts +39 -6
- package/src/ir/core/irMode.ts +42 -10
- package/src/ir/core/irReducer.ts +3 -51
- package/src/ir/core/irSidePanels.ts +8 -1
- package/src/ir/core/irSpectrum.ts +59 -30
- package/src/ir/core/irState.ts +73 -5
- package/src/ir/core/irTechnique.ts +115 -0
- package/src/ir/core/irTechniqueCommands.ts +82 -0
- package/src/ir/core/pickBands.ts +63 -28
- package/src/ir/core/ramanBands.ts +105 -0
- package/src/ir/core/spectrumJcamp.ts +65 -16
- package/src/ir/core/toIrSpectrum.ts +20 -2
- package/src/ir/ui/BandRow.tsx +107 -0
- package/src/ir/ui/BandsPanel.tsx +32 -125
- package/src/ir/ui/IrAboutDialog.tsx +69 -28
- package/src/ir/ui/IrCanvas.tsx +29 -3
- package/src/ir/ui/IrChart.tsx +31 -24
- package/src/ir/ui/IrCommandProvider.tsx +10 -3
- package/src/ir/ui/IrCommandTooltip.tsx +11 -2
- package/src/ir/ui/IrDocumentationDialog.tsx +99 -55
- package/src/ir/ui/IrEditor.tsx +27 -40
- package/src/ir/ui/IrHeader.tsx +10 -3
- package/src/ir/ui/IrLogo.tsx +28 -9
- package/src/ir/ui/IrShell.tsx +47 -96
- package/src/ir/ui/IrSidePanel.tsx +36 -10
- package/src/ir/ui/IrStatusBar.tsx +17 -12
- package/src/ir/ui/IrToolbar.tsx +26 -15
- package/src/ir/ui/IrTraces.tsx +5 -1
- package/src/ir/ui/RamanEditor.tsx +71 -0
- package/src/ir/ui/SpectraPanel.tsx +2 -1
- package/src/ir/ui/SpectrumRow.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +113 -0
- package/src/ir/ui/bandsTsv.ts +46 -0
- package/src/ir/ui/index.ts +1 -0
- package/src/ir/ui/irActions.ts +3 -3
- package/src/ir/ui/irChartProps.ts +21 -4
- package/src/ir/ui/irCommandContext.tsx +18 -3
- package/src/ir/ui/irHostPanels.ts +76 -0
- package/src/ir/ui/useIrEditor.ts +20 -8
- package/src/ir/ui/useIrHandle.ts +51 -0
- package/src/ir/ui/useIrSide.ts +60 -0
- package/src/ir/ui/useIrText.ts +170 -0
- package/src/ir/ui/useIrZoom.ts +22 -3
- package/src/ir/ui/useValueAxisZoom.ts +67 -0
- package/src/ir.ts +3 -0
- package/src/locales/de.json +29 -2
- package/src/locales/en.json +29 -2
- package/src/locales/es.json +29 -2
- package/src/locales/fr.json +29 -2
- package/src/locales/it.json +29 -2
- package/src/molecule3d/core/animatedPng.ts +79 -0
- package/src/molecule3d/core/file.ts +23 -0
- package/src/molecule3d/core/index.ts +3 -1
- package/src/molecule3d/core/settings.ts +0 -8
- package/src/molecule3d/ui/Molecule3DExport.tsx +43 -5
- package/src/molecule3d/ui/Molecule3DToolbar.tsx +9 -2
- package/src/molecule3d/ui/MoleculeCanvas3D.tsx +24 -38
- package/src/molecule3d/ui/drawScene.ts +2 -1
- package/src/molecule3d/ui/exportMoleculeImage.ts +28 -3
- package/src/molecule3d/ui/moleculeFrames.ts +88 -0
- package/src/molecule3d/ui/moleculeViewer3DProps.ts +14 -5
- package/src/molecule3d/ui/renderMolecule.ts +5 -3
- package/src/molecule3d/ui/sceneDrawer.ts +14 -2
- package/src/molecule3d/ui/useImageExport.ts +22 -5
- package/src/molecule3d/ui/useMoleculeScene.ts +2 -1
- package/src/molecule3d/ui/useMoleculeViewer.ts +46 -0
- package/src/molecule3d/ui/usePolarSurfaceArea.ts +6 -4
- package/src/molecule3d/ui/viewer.ts +34 -27
- package/src/molecule3d/ui/viewerTypes.ts +6 -0
- package/src/molstar/core/captureScene.ts +85 -2
- package/src/molstar/core/index.ts +13 -2
- package/src/molstar/core/trajectory.ts +117 -0
- package/src/panel/ui/PanelRail.tsx +3 -0
- package/src/raman.ts +20 -0
- package/src/router/core/basePath.ts +2 -2
- package/src/router/core/siteAddresses.ts +1 -1
- package/src/seo/core/siteFiles.ts +1 -1
- package/src/server/answerAddresses.ts +3 -3
- package/src/structure/core/index.ts +8 -0
- package/src/structure/core/structureTransfer.ts +37 -0
- package/src/structure/ui/EditorImportButton.tsx +59 -0
- package/src/structure/ui/EditorImportProblem.tsx +63 -0
- package/src/structure/ui/StructureDrop.tsx +66 -0
- package/src/structure/ui/StructureDropOverlay.tsx +50 -0
- package/src/structure/ui/StructureEditor.tsx +49 -134
- package/src/structure/ui/importedStructure.ts +83 -0
- package/src/structure/ui/index.ts +2 -0
- package/src/structure/ui/structureEditorProps.ts +103 -0
- package/src/structure/ui/useDebouncedChange.ts +41 -0
- package/src/structure/ui/useStructureDrop.ts +76 -0
- package/src/structure/ui/useStructureImport.ts +122 -0
|
@@ -5,6 +5,7 @@ import type { FigureNotice } from '../../download/core/copyFigure.ts';
|
|
|
5
5
|
import { copyFigure } from '../../download/core/copyFigure.ts';
|
|
6
6
|
import type { FigureFormat } from '../../download/core/downloadFigure.ts';
|
|
7
7
|
import type { FigurePixels } from '../../download/core/figureScale.ts';
|
|
8
|
+
import { DEFAULT_FRAMES_PER_SECOND } from '../core/animatedPng.ts';
|
|
8
9
|
|
|
9
10
|
import type { SceneCapture } from './exportMoleculeImage.ts';
|
|
10
11
|
import {
|
|
@@ -16,8 +17,15 @@ import {
|
|
|
16
17
|
export interface ImageExport {
|
|
17
18
|
/** Size of the canvas on screen, or `null` before it is laid out. */
|
|
18
19
|
canvasSize: () => FigurePixels | null;
|
|
19
|
-
/**
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Render the scene at `scale` and download it as `format` — every frame of
|
|
22
|
+
* it, as an animated PNG, when `animated` is set and the format is PNG.
|
|
23
|
+
*/
|
|
24
|
+
exportImage: (
|
|
25
|
+
format: FigureFormat,
|
|
26
|
+
scale: number,
|
|
27
|
+
animated?: boolean,
|
|
28
|
+
) => Promise<void>;
|
|
21
29
|
/**
|
|
22
30
|
* Render the scene at `scale` and put it on the clipboard as a PNG. Call it
|
|
23
31
|
* from the click itself: Safari only allows a write the click started.
|
|
@@ -30,12 +38,15 @@ export interface ImageExport {
|
|
|
30
38
|
* @param container - The element molstar draws into.
|
|
31
39
|
* @param viewerRef - The viewer, once created.
|
|
32
40
|
* @param fileName - File name without its extension.
|
|
41
|
+
* @param framesPerSecond - How fast an animated PNG plays its frames.
|
|
42
|
+
* @default 25
|
|
33
43
|
* @returns See {@link ImageExport}.
|
|
34
44
|
*/
|
|
35
45
|
export function useImageExport(
|
|
36
46
|
container: HTMLDivElement | null,
|
|
37
47
|
viewerRef: RefObject<SceneCapture | null>,
|
|
38
48
|
fileName: string,
|
|
49
|
+
framesPerSecond = DEFAULT_FRAMES_PER_SECOND,
|
|
39
50
|
): ImageExport {
|
|
40
51
|
const canvasSize = useCallback((): FigurePixels | null => {
|
|
41
52
|
if (container === null) return null;
|
|
@@ -45,15 +56,21 @@ export function useImageExport(
|
|
|
45
56
|
}, [container]);
|
|
46
57
|
|
|
47
58
|
const exportImage = useCallback(
|
|
48
|
-
async (format: FigureFormat, scale: number) => {
|
|
59
|
+
async (format: FigureFormat, scale: number, animated = false) => {
|
|
49
60
|
const viewer = viewerRef.current;
|
|
50
61
|
const size = canvasSize();
|
|
51
62
|
if (viewer === null || size === null) {
|
|
52
63
|
throw new Error('There is no picture to export yet.');
|
|
53
64
|
}
|
|
54
|
-
await exportMoleculeImage(viewer, {
|
|
65
|
+
await exportMoleculeImage(viewer, {
|
|
66
|
+
format,
|
|
67
|
+
scale,
|
|
68
|
+
size,
|
|
69
|
+
fileName,
|
|
70
|
+
framesPerSecond: animated ? framesPerSecond : undefined,
|
|
71
|
+
});
|
|
55
72
|
},
|
|
56
|
-
[canvasSize, viewerRef, fileName],
|
|
73
|
+
[canvasSize, viewerRef, fileName, framesPerSecond],
|
|
57
74
|
);
|
|
58
75
|
|
|
59
76
|
const copyImage = useCallback(
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
import type { RefObject } from 'react';
|
|
13
13
|
import { useCallback, useEffect, useRef } from 'react';
|
|
14
14
|
|
|
15
|
+
import type { Molecule3DFile } from '../core/file.ts';
|
|
15
16
|
import type { Measurement } from '../core/measurement.ts';
|
|
16
|
-
import type {
|
|
17
|
+
import type { Molecule3DSettings } from '../core/settings.ts';
|
|
17
18
|
|
|
18
19
|
import type { MoleculeViewer3DProps } from './moleculeViewer3DProps.ts';
|
|
19
20
|
import { SceneDrawer } from './sceneDrawer.ts';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The molstar viewer of one canvas: created once its element exists, kept to
|
|
3
|
+
* the element's size, and disposed with it.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { RefObject } from 'react';
|
|
7
|
+
import { useEffect, useRef } from 'react';
|
|
8
|
+
|
|
9
|
+
import { createMolecule3DViewer } from './createViewer.ts';
|
|
10
|
+
import type { Molecule3DViewer } from './viewer.ts';
|
|
11
|
+
import type { Molecule3DViewerOptions } from './viewerTypes.ts';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Mount a viewer in `container` for as long as it exists.
|
|
15
|
+
* @param container - The element molstar draws in, or `null` before it exists.
|
|
16
|
+
* @param options - Read when the viewer is created; a later change is ignored,
|
|
17
|
+
* so a callback reads what it needs from a ref of its own.
|
|
18
|
+
* @returns The viewer, holding `null` while there is none.
|
|
19
|
+
*/
|
|
20
|
+
export function useMoleculeViewer(
|
|
21
|
+
container: HTMLElement | null,
|
|
22
|
+
options: Molecule3DViewerOptions,
|
|
23
|
+
): RefObject<Molecule3DViewer | null> {
|
|
24
|
+
const viewerRef = useRef<Molecule3DViewer | null>(null);
|
|
25
|
+
const latestOptions = useRef(options);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
latestOptions.current = options;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (container === null) return;
|
|
32
|
+
const viewer = createMolecule3DViewer(container, latestOptions.current);
|
|
33
|
+
viewerRef.current = viewer;
|
|
34
|
+
const observer = new ResizeObserver(() => {
|
|
35
|
+
viewer.handleResize();
|
|
36
|
+
});
|
|
37
|
+
observer.observe(container);
|
|
38
|
+
return () => {
|
|
39
|
+
observer.disconnect();
|
|
40
|
+
viewerRef.current = null;
|
|
41
|
+
viewer.dispose();
|
|
42
|
+
};
|
|
43
|
+
}, [container]);
|
|
44
|
+
|
|
45
|
+
return viewerRef;
|
|
46
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import type { Molecule3DFile } from '../core/
|
|
3
|
+
import type { Molecule3DFile } from '../core/file.ts';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Ertl's topological polar surface area of the molecule, from openchemlib,
|
|
7
7
|
* loaded only once a caller asks for it.
|
|
8
8
|
* @param molfile - The molecule, or `null`.
|
|
9
9
|
* @param enabled - Whether to compute it at all.
|
|
10
|
-
* @returns The area in Ų, or `null` while unknown, disabled,
|
|
11
|
-
* openchemlib is not installed or cannot read the molfile.
|
|
10
|
+
* @returns The area in Ų, or `null` while unknown, disabled, for an XYZ
|
|
11
|
+
* file, or when openchemlib is not installed or cannot read the molfile.
|
|
12
12
|
*/
|
|
13
13
|
export function usePolarSurfaceArea(
|
|
14
14
|
molfile: Molecule3DFile | null,
|
|
@@ -18,7 +18,9 @@ export function usePolarSurfaceArea(
|
|
|
18
18
|
data: string;
|
|
19
19
|
area: number | null;
|
|
20
20
|
} | null>(null);
|
|
21
|
-
|
|
21
|
+
// An XYZ file has no bonds for openchemlib to find the polar atoms by.
|
|
22
|
+
const data =
|
|
23
|
+
enabled && molfile?.format !== 'xyz' ? (molfile?.data ?? null) : null;
|
|
22
24
|
|
|
23
25
|
useEffect(() => {
|
|
24
26
|
if (data === null) return;
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* is the component's.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { PluginContext } from 'molstar/lib/mol-plugin/context.js';
|
|
12
11
|
import { Color } from 'molstar/lib/mol-util/color/color.js';
|
|
13
12
|
|
|
14
13
|
import {
|
|
@@ -24,11 +23,12 @@ import {
|
|
|
24
23
|
} from '../../molstar/core/index.ts';
|
|
25
24
|
import type { Molecule3DCamera } from '../core/camera.ts';
|
|
26
25
|
import type { ImageSize } from '../core/exportImage.ts';
|
|
26
|
+
import type { Molecule3DFile } from '../core/file.ts';
|
|
27
27
|
import type { Molecule3DHighlight } from '../core/highlight.ts';
|
|
28
28
|
import type { Measurement, MeasurementKind } from '../core/measurement.ts';
|
|
29
|
-
import type { Molecule3DFile } from '../core/settings.ts';
|
|
30
29
|
|
|
31
30
|
import { applyCamera, resetCamera, watchCamera } from './camera.ts';
|
|
31
|
+
import { MoleculeFrames } from './moleculeFrames.ts';
|
|
32
32
|
import {
|
|
33
33
|
MODEL_REPRESENTATION_REF,
|
|
34
34
|
clearMolecule,
|
|
@@ -54,16 +54,24 @@ export class Molecule3DViewer {
|
|
|
54
54
|
/** Resolves once the canvas exists; every method awaits it internally. */
|
|
55
55
|
readonly ready: Promise<void>;
|
|
56
56
|
|
|
57
|
+
/** The frames of the file on screen: playing them, and their pictures. */
|
|
58
|
+
readonly frames: MoleculeFrames;
|
|
59
|
+
|
|
57
60
|
/**
|
|
58
61
|
* Mount the canvas and start initialising the plugin.
|
|
59
62
|
* @param container - A positioned element.
|
|
60
63
|
* @param options - See {@link Molecule3DViewerOptions}.
|
|
61
64
|
*/
|
|
62
65
|
constructor(container: HTMLElement, options: Molecule3DViewerOptions = {}) {
|
|
63
|
-
const {
|
|
66
|
+
const {
|
|
67
|
+
background,
|
|
68
|
+
onMeasure = ignore,
|
|
69
|
+
onFrameCountChange = ignore,
|
|
70
|
+
} = options;
|
|
64
71
|
this.#plugin = new MolstarPlugin(container, { background });
|
|
65
72
|
this.ready = this.#plugin.ready;
|
|
66
|
-
|
|
73
|
+
this.frames = new MoleculeFrames(this.#plugin, onFrameCountChange);
|
|
74
|
+
// Registered before any other `run`, so the picker exists by the time one runs.
|
|
67
75
|
void this.#plugin
|
|
68
76
|
.run((plugin) => {
|
|
69
77
|
this.#picker = new MeasurementPicker(
|
|
@@ -84,10 +92,12 @@ export class Molecule3DViewer {
|
|
|
84
92
|
* @throws {Error} When the file parses to zero atoms.
|
|
85
93
|
*/
|
|
86
94
|
showMolecule(molfile: Molecule3DFile, style?: MoleculeStyle): Promise<void> {
|
|
87
|
-
return this.#run(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
return this.#plugin.run((plugin) =>
|
|
96
|
+
this.frames.redraw(plugin, async () => {
|
|
97
|
+
await clearMeasurements(plugin);
|
|
98
|
+
return renderMolecule(plugin, molfile, style);
|
|
99
|
+
}),
|
|
100
|
+
);
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
/**
|
|
@@ -95,10 +105,13 @@ export class Molecule3DViewer {
|
|
|
95
105
|
* @returns Nothing; resolves once the scene is empty.
|
|
96
106
|
*/
|
|
97
107
|
hideMolecule(): Promise<void> {
|
|
98
|
-
return this.#run(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
return this.#plugin.run((plugin) =>
|
|
109
|
+
this.frames.redraw(plugin, async () => {
|
|
110
|
+
await clearMeasurements(plugin);
|
|
111
|
+
await clearMolecule(plugin);
|
|
112
|
+
return 0;
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
102
115
|
}
|
|
103
116
|
|
|
104
117
|
/**
|
|
@@ -107,7 +120,7 @@ export class Molecule3DViewer {
|
|
|
107
120
|
* @returns Nothing; resolves once the surface is on screen.
|
|
108
121
|
*/
|
|
109
122
|
showSurface(style?: SurfaceStyle): Promise<void> {
|
|
110
|
-
return this.#run((plugin) => renderSurface(plugin, style));
|
|
123
|
+
return this.#plugin.run((plugin) => renderSurface(plugin, style));
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
/**
|
|
@@ -115,7 +128,7 @@ export class Molecule3DViewer {
|
|
|
115
128
|
* @returns Nothing; resolves once the surface is gone.
|
|
116
129
|
*/
|
|
117
130
|
hideSurface(): Promise<void> {
|
|
118
|
-
return this.#run((plugin) => clearSurface(plugin));
|
|
131
|
+
return this.#plugin.run((plugin) => clearSurface(plugin));
|
|
119
132
|
}
|
|
120
133
|
|
|
121
134
|
/**
|
|
@@ -124,7 +137,7 @@ export class Molecule3DViewer {
|
|
|
124
137
|
* @returns Nothing; resolves once the labels are on screen.
|
|
125
138
|
*/
|
|
126
139
|
showMeasurements(measurements: readonly Measurement[]): Promise<void> {
|
|
127
|
-
return this.#run((plugin) =>
|
|
140
|
+
return this.#plugin.run((plugin) =>
|
|
128
141
|
renderMeasurements(plugin, measurements, moleculeStructure),
|
|
129
142
|
);
|
|
130
143
|
}
|
|
@@ -140,7 +153,7 @@ export class Molecule3DViewer {
|
|
|
140
153
|
highlights: readonly Molecule3DHighlight[],
|
|
141
154
|
color: string,
|
|
142
155
|
): Promise<void> {
|
|
143
|
-
return this.#run(() => {
|
|
156
|
+
return this.#plugin.run(() => {
|
|
144
157
|
this.#painter?.set(highlights, Color.fromHexStyle(color));
|
|
145
158
|
});
|
|
146
159
|
}
|
|
@@ -151,7 +164,7 @@ export class Molecule3DViewer {
|
|
|
151
164
|
* @returns Nothing; resolves once the plugin has switched mode.
|
|
152
165
|
*/
|
|
153
166
|
setMeasureKind(kind: MeasurementKind | null): Promise<void> {
|
|
154
|
-
return this.#run(() => {
|
|
167
|
+
return this.#plugin.run(() => {
|
|
155
168
|
this.#picker?.setKind(kind);
|
|
156
169
|
});
|
|
157
170
|
}
|
|
@@ -164,7 +177,7 @@ export class Molecule3DViewer {
|
|
|
164
177
|
* @throws {Error} When the plugin has no screenshot helper.
|
|
165
178
|
*/
|
|
166
179
|
captureImage(size: ImageSize): Promise<string | undefined> {
|
|
167
|
-
return this.#run((plugin) => captureScene(plugin, size));
|
|
180
|
+
return this.#plugin.run((plugin) => captureScene(plugin, size));
|
|
168
181
|
}
|
|
169
182
|
|
|
170
183
|
/**
|
|
@@ -177,7 +190,7 @@ export class Molecule3DViewer {
|
|
|
177
190
|
durationMilliseconds = DEFAULT_CAMERA_DURATION,
|
|
178
191
|
fromFront = false,
|
|
179
192
|
): Promise<void> {
|
|
180
|
-
return this.#run((plugin) => {
|
|
193
|
+
return this.#plugin.run((plugin) => {
|
|
181
194
|
resetCamera(plugin, durationMilliseconds, fromFront);
|
|
182
195
|
});
|
|
183
196
|
}
|
|
@@ -189,7 +202,7 @@ export class Molecule3DViewer {
|
|
|
189
202
|
* @returns Nothing; resolves once the move has been ordered.
|
|
190
203
|
*/
|
|
191
204
|
setCamera(camera: Molecule3DCamera, durationMilliseconds = 0): Promise<void> {
|
|
192
|
-
return this.#run((plugin) => {
|
|
205
|
+
return this.#plugin.run((plugin) => {
|
|
193
206
|
applyCamera(plugin, camera, durationMilliseconds);
|
|
194
207
|
});
|
|
195
208
|
}
|
|
@@ -211,7 +224,7 @@ export class Molecule3DViewer {
|
|
|
211
224
|
* @returns Nothing; resolves once the trackball has been reconfigured.
|
|
212
225
|
*/
|
|
213
226
|
setSpin(spinning: boolean, speed = DEFAULT_SPIN_SPEED): Promise<void> {
|
|
214
|
-
return this.#run((plugin) => {
|
|
227
|
+
return this.#plugin.run((plugin) => {
|
|
215
228
|
setSpin(plugin, spinning, speed);
|
|
216
229
|
});
|
|
217
230
|
}
|
|
@@ -227,12 +240,6 @@ export class Molecule3DViewer {
|
|
|
227
240
|
this.#painter?.dispose();
|
|
228
241
|
this.#plugin.dispose();
|
|
229
242
|
}
|
|
230
|
-
|
|
231
|
-
#run<Result>(
|
|
232
|
-
action: (plugin: PluginContext) => Result | Promise<Result>,
|
|
233
|
-
): Promise<Result | undefined> {
|
|
234
|
-
return this.#plugin.run(action);
|
|
235
|
-
}
|
|
236
243
|
}
|
|
237
244
|
|
|
238
245
|
function ignore(): void {
|
|
@@ -19,6 +19,12 @@ export interface Molecule3DViewerOptions {
|
|
|
19
19
|
* @default undefined
|
|
20
20
|
*/
|
|
21
21
|
onMeasure?: (measurement: Measurement) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Called with how many frames the file on screen holds, each time a file is
|
|
24
|
+
* drawn, and with 0 once the scene is emptied.
|
|
25
|
+
* @default undefined
|
|
26
|
+
*/
|
|
27
|
+
onFrameCountChange?: (frameCount: number) => void;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
/** How to draw the model. */
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A picture of the scene, rendered off screen at a size of its own
|
|
2
|
+
* A picture of the scene, rendered off screen at a size of its own — one
|
|
3
|
+
* frame, or every frame of the trajectory on screen.
|
|
3
4
|
*/
|
|
4
5
|
|
|
5
6
|
import type { PluginContext } from 'molstar/lib/mol-plugin/context.js';
|
|
7
|
+
import type { ViewportScreenshotHelper } from 'molstar/lib/mol-plugin/util/viewport-screenshot.js';
|
|
8
|
+
import { Task } from 'molstar/lib/mol-task/index.js';
|
|
6
9
|
|
|
7
10
|
import type { ImageSize } from '../../molecule3d/core/exportImage.ts';
|
|
8
11
|
|
|
12
|
+
import {
|
|
13
|
+
setTrajectoryPlayback,
|
|
14
|
+
showTrajectoryFrame,
|
|
15
|
+
shownTrajectoryFrame,
|
|
16
|
+
stopTrajectory,
|
|
17
|
+
trajectoryFrameCount,
|
|
18
|
+
} from './trajectory.ts';
|
|
19
|
+
|
|
9
20
|
/**
|
|
10
21
|
* Render the scene without its selection highlights or its axes.
|
|
11
22
|
* @param plugin - The molstar context.
|
|
@@ -17,6 +28,78 @@ export async function captureScene(
|
|
|
17
28
|
plugin: PluginContext,
|
|
18
29
|
size: ImageSize,
|
|
19
30
|
): Promise<string> {
|
|
31
|
+
return pictureHelper(plugin, size).getImageDataUri();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** How a series of frames is played, so it can be resumed once captured. */
|
|
35
|
+
export interface FramePlayback {
|
|
36
|
+
playing: boolean;
|
|
37
|
+
framesPerSecond: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Render every frame of the trajectory on screen, in order, as the scene shows
|
|
42
|
+
* it: the model, its surface and the measurements over it, each at that frame.
|
|
43
|
+
* The animation is stopped while the frames are taken and resumed afterwards,
|
|
44
|
+
* and the scene is left on the frame it showed.
|
|
45
|
+
* @param plugin - The molstar context.
|
|
46
|
+
* @param size - Pixel size of each picture.
|
|
47
|
+
* @param playback - What to resume once the frames are taken.
|
|
48
|
+
* @returns One picture per frame; a scene of one model gives one.
|
|
49
|
+
* @throws {Error} When the plugin has no screenshot helper.
|
|
50
|
+
*/
|
|
51
|
+
export async function captureFrames(
|
|
52
|
+
plugin: PluginContext,
|
|
53
|
+
size: ImageSize,
|
|
54
|
+
playback: FramePlayback,
|
|
55
|
+
): Promise<ImageData[]> {
|
|
56
|
+
const pass = pictureHelper(plugin, size).imagePass;
|
|
57
|
+
const loop = plugin.animationLoop;
|
|
58
|
+
const shown = shownTrajectoryFrame(plugin);
|
|
59
|
+
const count = Math.max(1, trajectoryFrameCount(plugin));
|
|
60
|
+
await stopTrajectory(plugin);
|
|
61
|
+
loop.stop({ noDraw: true });
|
|
62
|
+
try {
|
|
63
|
+
await pass.updateBackground();
|
|
64
|
+
const frames: ImageData[] = [];
|
|
65
|
+
for (let index = 0; index < count; index++) {
|
|
66
|
+
// eslint-disable-next-line no-await-in-loop -- each frame is a commit of the state tree, and commits must not interleave
|
|
67
|
+
if (count > 1) await showTrajectoryFrame(plugin, index);
|
|
68
|
+
// The scene is otherwise committed on the next animation frame, after
|
|
69
|
+
// the picture has been taken of the previous one.
|
|
70
|
+
plugin.canvas3d?.commit(true);
|
|
71
|
+
// eslint-disable-next-line no-await-in-loop -- one render at a time on the one image pass
|
|
72
|
+
const image = await plugin.runTask(
|
|
73
|
+
Task.create('Render a frame', (runtime) =>
|
|
74
|
+
pass.getImageData(runtime, size.width, size.height),
|
|
75
|
+
),
|
|
76
|
+
);
|
|
77
|
+
frames.push(image);
|
|
78
|
+
}
|
|
79
|
+
return frames;
|
|
80
|
+
} finally {
|
|
81
|
+
if (count > 1) await showTrajectoryFrame(plugin, shown);
|
|
82
|
+
loop.start({ immediate: true });
|
|
83
|
+
await setTrajectoryPlayback(
|
|
84
|
+
plugin,
|
|
85
|
+
playback.playing,
|
|
86
|
+
playback.framesPerSecond,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The screenshot helper, set to draw a picture of `size` with no axes and an
|
|
93
|
+
* opaque background.
|
|
94
|
+
* @param plugin - The molstar context.
|
|
95
|
+
* @param size - Pixel size of the picture.
|
|
96
|
+
* @returns The helper.
|
|
97
|
+
* @throws {Error} When the plugin has no screenshot helper.
|
|
98
|
+
*/
|
|
99
|
+
function pictureHelper(
|
|
100
|
+
plugin: PluginContext,
|
|
101
|
+
size: ImageSize,
|
|
102
|
+
): ViewportScreenshotHelper {
|
|
20
103
|
const helper = plugin.helpers.viewportScreenshot;
|
|
21
104
|
if (helper === undefined) {
|
|
22
105
|
throw new Error('This viewer cannot take a picture of its scene.');
|
|
@@ -27,5 +110,5 @@ export async function captureScene(
|
|
|
27
110
|
axes: { name: 'off', params: {} },
|
|
28
111
|
transparent: false,
|
|
29
112
|
});
|
|
30
|
-
return helper
|
|
113
|
+
return helper;
|
|
31
114
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The molstar layer under the 3D views: the plugin lifecycle, the camera, the
|
|
3
|
-
* hover labels, the measurements, the highlights
|
|
3
|
+
* hover labels, the measurements, the highlights, the frames of a trajectory
|
|
4
|
+
* and the picture of a scene.
|
|
4
5
|
*
|
|
5
6
|
* Three of our sites mount a headless molstar canvas — the molecule viewer
|
|
6
7
|
* here, lcao's orbitals and symmetry's crystals — and each of them had its own
|
|
@@ -49,7 +50,8 @@ export {
|
|
|
49
50
|
} from './hover.ts';
|
|
50
51
|
export type { MolstarPluginOptions } from './plugin.ts';
|
|
51
52
|
export { MolstarPlugin } from './plugin.ts';
|
|
52
|
-
export {
|
|
53
|
+
export type { FramePlayback } from './captureScene.ts';
|
|
54
|
+
export { captureFrames, captureScene } from './captureScene.ts';
|
|
53
55
|
export type { MoleculeStructureSource } from './measurements.ts';
|
|
54
56
|
export {
|
|
55
57
|
MeasurementPicker,
|
|
@@ -57,3 +59,12 @@ export {
|
|
|
57
59
|
clearMeasurements,
|
|
58
60
|
renderMeasurements,
|
|
59
61
|
} from './measurements.ts';
|
|
62
|
+
export {
|
|
63
|
+
PLAYBACK_FPS_RANGE,
|
|
64
|
+
clampFramesPerSecond,
|
|
65
|
+
setTrajectoryPlayback,
|
|
66
|
+
showTrajectoryFrame,
|
|
67
|
+
shownTrajectoryFrame,
|
|
68
|
+
stopTrajectory,
|
|
69
|
+
trajectoryFrameCount,
|
|
70
|
+
} from './trajectory.ts';
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frames of a trajectory: how many there are, which one is shown, and
|
|
3
|
+
* playing them in a loop.
|
|
4
|
+
*
|
|
5
|
+
* molstar keeps a trajectory as one data node and shows one of its frames
|
|
6
|
+
* through a `ModelFromTrajectory` node whose `modelIndex` says which. Playing
|
|
7
|
+
* is molstar's own model-index animation, which steps that index; showing one
|
|
8
|
+
* frame sets it.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { PluginContext } from 'molstar/lib/mol-plugin/context.js';
|
|
12
|
+
import { AnimateModelIndex } from 'molstar/lib/mol-plugin-state/animation/built-in/model-index.js';
|
|
13
|
+
import { PluginStateObject } from 'molstar/lib/mol-plugin-state/objects.js';
|
|
14
|
+
import { ModelFromTrajectory } from 'molstar/lib/mol-plugin-state/transforms/model.js';
|
|
15
|
+
import { StateSelection } from 'molstar/lib/mol-state/index.js';
|
|
16
|
+
|
|
17
|
+
/** How fast molstar's model-index animation can step, frames per second. */
|
|
18
|
+
export const PLAYBACK_FPS_RANGE = { minimum: 5, maximum: 60 } as const;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* How many frames the trajectory on screen holds.
|
|
22
|
+
* @param plugin - The molstar context.
|
|
23
|
+
* @returns The most frames of any trajectory shown; 0 when none is.
|
|
24
|
+
*/
|
|
25
|
+
export function trajectoryFrameCount(plugin: PluginContext): number {
|
|
26
|
+
const state = plugin.state.data;
|
|
27
|
+
let count = 0;
|
|
28
|
+
for (const model of modelCells(plugin)) {
|
|
29
|
+
const trajectory = StateSelection.findAncestorOfType(
|
|
30
|
+
state.tree,
|
|
31
|
+
state.cells,
|
|
32
|
+
model.transform.ref,
|
|
33
|
+
PluginStateObject.Molecule.Trajectory,
|
|
34
|
+
);
|
|
35
|
+
count = Math.max(count, trajectory?.obj?.data.frameCount ?? 0);
|
|
36
|
+
}
|
|
37
|
+
return count;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Show one frame of every trajectory on screen, and everything built on it:
|
|
42
|
+
* the drawn model, its surface and the measurements over it.
|
|
43
|
+
* @param plugin - The molstar context.
|
|
44
|
+
* @param index - The frame, from 0.
|
|
45
|
+
* @returns Nothing; resolves once the state tree is updated.
|
|
46
|
+
*/
|
|
47
|
+
export async function showTrajectoryFrame(
|
|
48
|
+
plugin: PluginContext,
|
|
49
|
+
index: number,
|
|
50
|
+
): Promise<void> {
|
|
51
|
+
const update = plugin.build();
|
|
52
|
+
for (const model of modelCells(plugin)) {
|
|
53
|
+
update.to(model).update({ modelIndex: index });
|
|
54
|
+
}
|
|
55
|
+
await update.commit();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The frame on screen.
|
|
60
|
+
* @param plugin - The molstar context.
|
|
61
|
+
* @returns The index of the frame the first trajectory shows; 0 when none is.
|
|
62
|
+
*/
|
|
63
|
+
export function shownTrajectoryFrame(plugin: PluginContext): number {
|
|
64
|
+
return modelCells(plugin)[0]?.transform.params?.modelIndex ?? 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Play the frames in a loop, or stop them where they stand.
|
|
69
|
+
* @param plugin - The molstar context.
|
|
70
|
+
* @param playing - Whether to play. A trajectory of one frame never plays.
|
|
71
|
+
* @param framesPerSecond - How fast, clamped into {@link PLAYBACK_FPS_RANGE}.
|
|
72
|
+
* @returns Nothing; resolves once the animation is started or stopped.
|
|
73
|
+
*/
|
|
74
|
+
export async function setTrajectoryPlayback(
|
|
75
|
+
plugin: PluginContext,
|
|
76
|
+
playing: boolean,
|
|
77
|
+
framesPerSecond: number,
|
|
78
|
+
): Promise<void> {
|
|
79
|
+
if (!playing || trajectoryFrameCount(plugin) < 2) {
|
|
80
|
+
await stopTrajectory(plugin);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
await plugin.managers.animation.play(AnimateModelIndex, {
|
|
84
|
+
mode: { name: 'loop', params: { direction: 'forward' } },
|
|
85
|
+
duration: {
|
|
86
|
+
name: 'sequential',
|
|
87
|
+
params: { maxFps: clampFramesPerSecond(framesPerSecond) },
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Stop the frames where they stand.
|
|
94
|
+
* @param plugin - The molstar context.
|
|
95
|
+
* @returns Nothing; resolves once the animation is stopped.
|
|
96
|
+
*/
|
|
97
|
+
export async function stopTrajectory(plugin: PluginContext): Promise<void> {
|
|
98
|
+
const animation = plugin.managers.animation;
|
|
99
|
+
if (animation.isAnimating) await animation.stop();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A frame rate molstar's model-index animation accepts.
|
|
104
|
+
* @param framesPerSecond - Any rate.
|
|
105
|
+
* @returns The rate, rounded and clamped into {@link PLAYBACK_FPS_RANGE}.
|
|
106
|
+
*/
|
|
107
|
+
export function clampFramesPerSecond(framesPerSecond: number): number {
|
|
108
|
+
const { minimum, maximum } = PLAYBACK_FPS_RANGE;
|
|
109
|
+
if (!Number.isFinite(framesPerSecond)) return minimum;
|
|
110
|
+
return Math.min(maximum, Math.max(minimum, Math.round(framesPerSecond)));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function modelCells(plugin: PluginContext) {
|
|
114
|
+
return plugin.state.data.select(
|
|
115
|
+
StateSelection.Generators.ofTransformer(ModelFromTrajectory),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -55,6 +55,9 @@ export function PanelRail<TId extends string>(
|
|
|
55
55
|
id={panel.id}
|
|
56
56
|
icon={panel.icon}
|
|
57
57
|
tooltip={panel.title}
|
|
58
|
+
// A tooltip is not an accessible name: without this every toggle is
|
|
59
|
+
// an icon-only button with no name at all.
|
|
60
|
+
aria-label={panel.title}
|
|
58
61
|
active={openIds.includes(panel.id)}
|
|
59
62
|
onClick={() => onToggle(panel.id)}
|
|
60
63
|
/>
|
package/src/raman.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Displaying Raman spectra: the infrared viewer, read for Raman.
|
|
3
|
+
*
|
|
4
|
+
* A door of its own so a page showing Raman spectra imports a Raman viewer by
|
|
5
|
+
* name. What it opens is the same code as `react-cheminfo/ir` — one shell, one
|
|
6
|
+
* set of panels — and the same spectrum model, which a host fills with an
|
|
7
|
+
* `intensity` array where an infrared spectrum carries absorbance and
|
|
8
|
+
* transmittance.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type { LoadedIrSpectrum } from './ir/core/analysisSpectra.ts';
|
|
12
|
+
export type { IrEditorHandle, IrPlotClick } from './ir/core/irEditorApi.ts';
|
|
13
|
+
export type { IrSpectrum } from './ir/core/irSpectrum.ts';
|
|
14
|
+
export { toIrSpectra } from './ir/core/toIrSpectrum.ts';
|
|
15
|
+
export type { IrHostPanel } from './ir/ui/irHostPanels.ts';
|
|
16
|
+
export type {
|
|
17
|
+
RamanEditorHandle,
|
|
18
|
+
RamanEditorProps,
|
|
19
|
+
} from './ir/ui/RamanEditor.tsx';
|
|
20
|
+
export { RamanEditor } from './ir/ui/RamanEditor.tsx';
|
|
@@ -4,8 +4,8 @@ import { trimTrailingSlash } from './address.ts';
|
|
|
4
4
|
* Where a site is mounted, read off the page rather than off the build.
|
|
5
5
|
*
|
|
6
6
|
* The build is mount-agnostic — vite is given a relative base, so the same
|
|
7
|
-
* `dist` serves `https://
|
|
8
|
-
* `https://www.cheminfo.org/
|
|
7
|
+
* `dist` serves `https://isomers.cheminfo.org/` and
|
|
8
|
+
* `https://www.cheminfo.org/isomers/`. What tells the two apart is the `<base>`
|
|
9
9
|
* the deployment stamps into the page it hands out, and `document.baseURI`
|
|
10
10
|
* resolves it against the address actually opened. So this answers correctly
|
|
11
11
|
* whether or not a slash closes the address, and on an address the SPA
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
*
|
|
17
17
|
* The mount is read off the page, not off the build: the build carries no
|
|
18
18
|
* mount, and the `<base>` a deployment stamps into its pages is what tells
|
|
19
|
-
* `https://
|
|
19
|
+
* `https://isomers.cheminfo.org/` from `https://www.cheminfo.org/isomers/`. Under
|
|
20
20
|
* Node there is no page, and the mount is the root.
|
|
21
21
|
* @param siteId - The site, as `ECOSYSTEM_SITES` names it.
|
|
22
22
|
* @param options - A mount path to use instead of the one read off the page.
|
|
@@ -130,7 +130,7 @@ export function originOf(options: SiteOrigin): string {
|
|
|
130
130
|
const origin = options.origin ?? `https://${resolveSite(options.site).host}`;
|
|
131
131
|
if (!HTTP_ORIGIN.test(origin) || !URL.canParse(origin)) {
|
|
132
132
|
throw new Error(
|
|
133
|
-
`an origin is an absolute address, e.g. https://
|
|
133
|
+
`an origin is an absolute address, e.g. https://isomers.cheminfo.org: ${JSON.stringify(origin)}`,
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
return trimTrailingSlash(origin);
|