react-cheminfo 0.64.1 → 0.66.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 +293 -6
- package/lib/card/core/cardAddress.d.ts +70 -0
- package/lib/card/core/cardAddress.d.ts.map +1 -0
- package/lib/card/core/cardAddress.js +59 -0
- package/lib/card/core/cardAddress.js.map +1 -0
- package/lib/card/core/cardPageUrl.d.ts +49 -0
- package/lib/card/core/cardPageUrl.d.ts.map +1 -0
- package/lib/card/core/cardPageUrl.js +59 -0
- package/lib/card/core/cardPageUrl.js.map +1 -0
- package/lib/card/core/index.d.ts +7 -0
- package/lib/card/core/index.d.ts.map +1 -0
- package/lib/card/core/index.js +4 -0
- package/lib/card/core/index.js.map +1 -0
- package/lib/card/core/panelRoom.d.ts +40 -0
- package/lib/card/core/panelRoom.d.ts.map +1 -0
- package/lib/card/core/panelRoom.js +40 -0
- package/lib/card/core/panelRoom.js.map +1 -0
- package/lib/card/ui/CardDetailsButton.d.ts +38 -0
- package/lib/card/ui/CardDetailsButton.d.ts.map +1 -0
- package/lib/card/ui/CardDetailsButton.js +50 -0
- package/lib/card/ui/CardDetailsButton.js.map +1 -0
- package/lib/card/ui/CardFigure.d.ts +51 -0
- package/lib/card/ui/CardFigure.d.ts.map +1 -0
- package/lib/card/ui/CardFigure.js +27 -0
- package/lib/card/ui/CardFigure.js.map +1 -0
- package/lib/card/ui/CardFrame.d.ts +30 -0
- package/lib/card/ui/CardFrame.d.ts.map +1 -0
- package/lib/card/ui/CardFrame.js +20 -0
- package/lib/card/ui/CardFrame.js.map +1 -0
- package/lib/card/ui/CopyTableButton.d.ts +37 -0
- package/lib/card/ui/CopyTableButton.d.ts.map +1 -0
- package/lib/card/ui/CopyTableButton.js +19 -0
- package/lib/card/ui/CopyTableButton.js.map +1 -0
- package/lib/card/ui/cardTooltip.d.ts +14 -0
- package/lib/card/ui/cardTooltip.d.ts.map +1 -0
- package/lib/card/ui/cardTooltip.js +15 -0
- package/lib/card/ui/cardTooltip.js.map +1 -0
- package/lib/card/ui/embed.d.ts +15 -0
- package/lib/card/ui/embed.d.ts.map +1 -0
- package/lib/card/ui/embed.js +24 -0
- package/lib/card/ui/embed.js.map +1 -0
- package/lib/card/ui/fitCardToFrame.d.ts +31 -0
- package/lib/card/ui/fitCardToFrame.d.ts.map +1 -0
- package/lib/card/ui/fitCardToFrame.js +66 -0
- package/lib/card/ui/fitCardToFrame.js.map +1 -0
- package/lib/card/ui/holdRoomForPanels.d.ts +16 -0
- package/lib/card/ui/holdRoomForPanels.d.ts.map +1 -0
- package/lib/card/ui/holdRoomForPanels.js +76 -0
- package/lib/card/ui/holdRoomForPanels.js.map +1 -0
- package/lib/card/ui/index.d.ts +11 -0
- package/lib/card/ui/index.d.ts.map +1 -0
- package/lib/card/ui/index.js +7 -0
- package/lib/card/ui/index.js.map +1 -0
- package/lib/card/ui/openPanels.d.ts +25 -0
- package/lib/card/ui/openPanels.d.ts.map +1 -0
- package/lib/card/ui/openPanels.js +85 -0
- package/lib/card/ui/openPanels.js.map +1 -0
- package/lib/card.d.ts +13 -0
- package/lib/card.d.ts.map +1 -0
- package/lib/card.js +13 -0
- package/lib/card.js.map +1 -0
- package/lib/conformers.d.ts +1 -0
- package/lib/conformers.d.ts.map +1 -1
- package/lib/conformers.js +1 -0
- package/lib/conformers.js.map +1 -1
- package/lib/core.d.ts +4 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +5 -0
- package/lib/core.js.map +1 -1
- package/lib/fetch/core/apiError.d.ts +56 -0
- package/lib/fetch/core/apiError.d.ts.map +1 -0
- package/lib/fetch/core/apiError.js +43 -0
- package/lib/fetch/core/apiError.js.map +1 -0
- package/lib/fetch/core/fetchJson.d.ts +47 -0
- package/lib/fetch/core/fetchJson.d.ts.map +1 -0
- package/lib/fetch/core/fetchJson.js +109 -0
- package/lib/fetch/core/fetchJson.js.map +1 -0
- package/lib/fetch/core/index.d.ts +5 -0
- package/lib/fetch/core/index.d.ts.map +1 -0
- package/lib/fetch/core/index.js +3 -0
- package/lib/fetch/core/index.js.map +1 -0
- package/lib/formula/core/formulaText.d.ts +46 -0
- package/lib/formula/core/formulaText.d.ts.map +1 -0
- package/lib/formula/core/formulaText.js +74 -0
- package/lib/formula/core/formulaText.js.map +1 -0
- package/lib/formula/core/index.d.ts +6 -0
- package/lib/formula/core/index.d.ts.map +1 -0
- package/lib/formula/core/index.js +4 -0
- package/lib/formula/core/index.js.map +1 -0
- package/lib/formula/core/normalizeFormula.d.ts +22 -0
- package/lib/formula/core/normalizeFormula.d.ts.map +1 -0
- package/lib/formula/core/normalizeFormula.js +46 -0
- package/lib/formula/core/normalizeFormula.js.map +1 -0
- package/lib/formula/core/readFormula.d.ts +73 -0
- package/lib/formula/core/readFormula.d.ts.map +1 -0
- package/lib/formula/core/readFormula.js +132 -0
- package/lib/formula/core/readFormula.js.map +1 -0
- package/lib/formula/ui/CopyableFormula.d.ts +31 -0
- package/lib/formula/ui/CopyableFormula.d.ts.map +1 -0
- package/lib/formula/ui/CopyableFormula.js +19 -0
- package/lib/formula/ui/CopyableFormula.js.map +1 -0
- package/lib/formula/ui/FormulaInput.d.ts +29 -0
- package/lib/formula/ui/FormulaInput.d.ts.map +1 -0
- package/lib/formula/ui/FormulaInput.js +16 -0
- package/lib/formula/ui/FormulaInput.js.map +1 -0
- package/lib/formula/ui/QuestionFormula.d.ts +14 -0
- package/lib/formula/ui/QuestionFormula.d.ts.map +1 -0
- package/lib/formula/ui/QuestionFormula.js +13 -0
- package/lib/formula/ui/QuestionFormula.js.map +1 -0
- package/lib/formula/ui/index.d.ts +7 -0
- package/lib/formula/ui/index.d.ts.map +1 -0
- package/lib/formula/ui/index.js +4 -0
- package/lib/formula/ui/index.js.map +1 -0
- package/lib/formula.d.ts +11 -0
- package/lib/formula.d.ts.map +1 -0
- package/lib/formula.js +11 -0
- package/lib/formula.js.map +1 -0
- package/lib/hooks/ui/index.d.ts +1 -0
- package/lib/hooks/ui/index.d.ts.map +1 -1
- package/lib/hooks/ui/index.js.map +1 -1
- package/lib/hooks/ui/keyTargets.d.ts +4 -2
- package/lib/hooks/ui/keyTargets.d.ts.map +1 -1
- package/lib/hooks/ui/keyTargets.js +5 -3
- package/lib/hooks/ui/keyTargets.js.map +1 -1
- package/lib/hooks/ui/useAsync.d.ts +20 -5
- package/lib/hooks/ui/useAsync.d.ts.map +1 -1
- package/lib/hooks/ui/useAsync.js +29 -14
- package/lib/hooks/ui/useAsync.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/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 +13 -9
- 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/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 +0 -28
- 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/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 +40 -2
- 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.map +1 -1
- package/lib/ir/ui/IrCanvas.js +2 -2
- 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 +18 -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 +3 -1
- 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.map +1 -1
- package/lib/ir/ui/IrShell.js +23 -56
- package/lib/ir/ui/IrShell.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 +46 -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 +48 -0
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -0
- package/lib/ir/ui/VibrationalEditor.js +31 -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/irChartProps.d.ts +14 -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/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/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 +7 -0
- package/lib/ir/ui/useIrZoom.d.ts.map +1 -1
- package/lib/ir/ui/useIrZoom.js +5 -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 +57 -1
- package/lib/locales/en.json +57 -1
- package/lib/locales/es.json +57 -1
- package/lib/locales/fr.json +57 -1
- package/lib/locales/it.json +57 -1
- package/lib/moleculesClient/core/index.d.ts +5 -0
- package/lib/moleculesClient/core/index.d.ts.map +1 -0
- package/lib/moleculesClient/core/index.js +3 -0
- package/lib/moleculesClient/core/index.js.map +1 -0
- package/lib/moleculesClient/core/moleculesClient.d.ts +12 -0
- package/lib/moleculesClient/core/moleculesClient.d.ts.map +1 -0
- package/lib/moleculesClient/core/moleculesClient.js +105 -0
- package/lib/moleculesClient/core/moleculesClient.js.map +1 -0
- package/lib/moleculesClient/core/moleculesClientApi.d.ts +100 -0
- package/lib/moleculesClient/core/moleculesClientApi.d.ts.map +1 -0
- package/lib/moleculesClient/core/moleculesClientApi.js +20 -0
- package/lib/moleculesClient/core/moleculesClientApi.js.map +1 -0
- package/lib/moleculesClient/core/moleculesTypes.d.ts +154 -0
- package/lib/moleculesClient/core/moleculesTypes.d.ts.map +1 -0
- package/lib/moleculesClient/core/moleculesTypes.js +2 -0
- package/lib/moleculesClient/core/moleculesTypes.js.map +1 -0
- package/lib/moleculesClient/core/requestRetry.d.ts +50 -0
- package/lib/moleculesClient/core/requestRetry.d.ts.map +1 -0
- package/lib/moleculesClient/core/requestRetry.js +108 -0
- package/lib/moleculesClient/core/requestRetry.js.map +1 -0
- package/lib/molstar/core/camera.d.ts +2 -1
- package/lib/molstar/core/camera.d.ts.map +1 -1
- package/lib/molstar/core/camera.js +3 -2
- package/lib/molstar/core/camera.js.map +1 -1
- package/lib/molstar/core/framing.d.ts +102 -0
- package/lib/molstar/core/framing.d.ts.map +1 -0
- package/lib/molstar/core/framing.js +120 -0
- package/lib/molstar/core/framing.js.map +1 -0
- package/lib/molstar/core/hover.d.ts +16 -0
- package/lib/molstar/core/hover.d.ts.map +1 -1
- package/lib/molstar/core/hover.js +14 -0
- package/lib/molstar/core/hover.js.map +1 -1
- package/lib/molstar/core/index.d.ts +4 -1
- package/lib/molstar/core/index.d.ts.map +1 -1
- package/lib/molstar/core/index.js +2 -1
- package/lib/molstar/core/index.js.map +1 -1
- package/lib/pedagogy/core/answers.d.ts +46 -0
- package/lib/pedagogy/core/answers.d.ts.map +1 -0
- package/lib/pedagogy/core/answers.js +77 -0
- package/lib/pedagogy/core/answers.js.map +1 -0
- package/lib/pedagogy/core/attempts.d.ts +86 -0
- package/lib/pedagogy/core/attempts.d.ts.map +1 -0
- package/lib/pedagogy/core/attempts.js +117 -0
- package/lib/pedagogy/core/attempts.js.map +1 -0
- package/lib/pedagogy/core/index.d.ts +8 -0
- package/lib/pedagogy/core/index.d.ts.map +1 -1
- package/lib/pedagogy/core/index.js +4 -0
- package/lib/pedagogy/core/index.js.map +1 -1
- package/lib/pedagogy/core/progressController.d.ts +64 -0
- package/lib/pedagogy/core/progressController.d.ts.map +1 -0
- package/lib/pedagogy/core/progressController.js +56 -0
- package/lib/pedagogy/core/progressController.js.map +1 -0
- package/lib/pedagogy/core/seed.d.ts +96 -0
- package/lib/pedagogy/core/seed.d.ts.map +1 -0
- package/lib/pedagogy/core/seed.js +128 -0
- package/lib/pedagogy/core/seed.js.map +1 -0
- package/lib/pedagogy/core/series.d.ts +77 -0
- package/lib/pedagogy/core/series.d.ts.map +1 -0
- package/lib/pedagogy/core/series.js +10 -0
- package/lib/pedagogy/core/series.js.map +1 -0
- package/lib/pedagogy/ui/AnswerFields.d.ts +21 -0
- package/lib/pedagogy/ui/AnswerFields.d.ts.map +1 -0
- package/lib/pedagogy/ui/AnswerFields.js +24 -0
- package/lib/pedagogy/ui/AnswerFields.js.map +1 -0
- package/lib/pedagogy/ui/ExerciseList.d.ts +82 -0
- package/lib/pedagogy/ui/ExerciseList.d.ts.map +1 -0
- package/lib/pedagogy/ui/ExerciseList.js +53 -0
- package/lib/pedagogy/ui/ExerciseList.js.map +1 -0
- package/lib/pedagogy/ui/ExerciseSeries.d.ts +95 -0
- package/lib/pedagogy/ui/ExerciseSeries.d.ts.map +1 -0
- package/lib/pedagogy/ui/ExerciseSeries.js +74 -0
- package/lib/pedagogy/ui/ExerciseSeries.js.map +1 -0
- package/lib/pedagogy/ui/QuestionCard.d.ts +64 -0
- package/lib/pedagogy/ui/QuestionCard.d.ts.map +1 -0
- package/lib/pedagogy/ui/QuestionCard.js +73 -0
- package/lib/pedagogy/ui/QuestionCard.js.map +1 -0
- package/lib/pedagogy/ui/index.d.ts +10 -0
- package/lib/pedagogy/ui/index.d.ts.map +1 -1
- package/lib/pedagogy/ui/index.js +6 -0
- package/lib/pedagogy/ui/index.js.map +1 -1
- package/lib/pedagogy/ui/seriesCounts.d.ts +17 -0
- package/lib/pedagogy/ui/seriesCounts.d.ts.map +1 -0
- package/lib/pedagogy/ui/seriesCounts.js +27 -0
- package/lib/pedagogy/ui/seriesCounts.js.map +1 -0
- package/lib/pedagogy/ui/seriesParts.d.ts +55 -0
- package/lib/pedagogy/ui/seriesParts.d.ts.map +1 -0
- package/lib/pedagogy/ui/seriesParts.js +38 -0
- package/lib/pedagogy/ui/seriesParts.js.map +1 -0
- package/lib/pedagogy/ui/useAttemptRecords.d.ts +10 -0
- package/lib/pedagogy/ui/useAttemptRecords.d.ts.map +1 -0
- package/lib/pedagogy/ui/useAttemptRecords.js +11 -0
- package/lib/pedagogy/ui/useAttemptRecords.js.map +1 -0
- package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
- package/lib/periodic/ui/PeriodicTable.js +6 -3
- package/lib/periodic/ui/PeriodicTable.js.map +1 -1
- package/lib/property/core/copyableText.d.ts +14 -0
- package/lib/property/core/copyableText.d.ts.map +1 -0
- package/lib/property/core/copyableText.js +21 -0
- package/lib/property/core/copyableText.js.map +1 -0
- package/lib/property/core/index.d.ts +2 -0
- package/lib/property/core/index.d.ts.map +1 -0
- package/lib/property/core/index.js +2 -0
- package/lib/property/core/index.js.map +1 -0
- package/lib/property/ui/PropertyTable.d.ts +43 -0
- package/lib/property/ui/PropertyTable.d.ts.map +1 -0
- package/lib/property/ui/PropertyTable.js +19 -0
- package/lib/property/ui/PropertyTable.js.map +1 -0
- package/lib/property/ui/index.d.ts +3 -0
- package/lib/property/ui/index.d.ts.map +1 -0
- package/lib/property/ui/index.js +2 -0
- package/lib/property/ui/index.js.map +1 -0
- package/lib/raman.d.ts +16 -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/history.d.ts +24 -3
- package/lib/router/core/history.d.ts.map +1 -1
- package/lib/router/core/history.js +55 -7
- package/lib/router/core/history.js.map +1 -1
- package/lib/router/core/index.d.ts +3 -3
- package/lib/router/core/index.d.ts.map +1 -1
- package/lib/router/core/index.js +2 -2
- package/lib/router/core/index.js.map +1 -1
- package/lib/router/core/languageRoute.d.ts +61 -0
- package/lib/router/core/languageRoute.d.ts.map +1 -0
- package/lib/router/core/languageRoute.js +96 -0
- package/lib/router/core/languageRoute.js.map +1 -0
- package/lib/router/core/siteAddresses.d.ts +23 -0
- package/lib/router/core/siteAddresses.d.ts.map +1 -1
- package/lib/router/core/siteAddresses.js +26 -0
- package/lib/router/core/siteAddresses.js.map +1 -1
- package/lib/router/core/tabRouter.d.ts +2 -108
- package/lib/router/core/tabRouter.d.ts.map +1 -1
- package/lib/router/core/tabRouter.js +38 -5
- package/lib/router/core/tabRouter.js.map +1 -1
- package/lib/router/core/tabRouterTypes.d.ts +154 -0
- package/lib/router/core/tabRouterTypes.d.ts.map +1 -0
- package/lib/router/core/tabRouterTypes.js +2 -0
- package/lib/router/core/tabRouterTypes.js.map +1 -0
- package/lib/seo/core/fitDescription.d.ts +40 -0
- package/lib/seo/core/fitDescription.d.ts.map +1 -0
- package/lib/seo/core/fitDescription.js +45 -0
- package/lib/seo/core/fitDescription.js.map +1 -0
- package/lib/seo/core/index.d.ts +7 -0
- package/lib/seo/core/index.d.ts.map +1 -1
- package/lib/seo/core/index.js +4 -0
- package/lib/seo/core/index.js.map +1 -1
- package/lib/seo/core/limits.d.ts +24 -0
- package/lib/seo/core/limits.d.ts.map +1 -0
- package/lib/seo/core/limits.js +24 -0
- package/lib/seo/core/limits.js.map +1 -0
- package/lib/seo/core/pageContent.d.ts +25 -0
- package/lib/seo/core/pageContent.d.ts.map +1 -0
- package/lib/seo/core/pageContent.js +25 -0
- package/lib/seo/core/pageContent.js.map +1 -0
- package/lib/seo/core/plainDescription.d.ts.map +1 -1
- package/lib/seo/core/plainDescription.js +3 -2
- package/lib/seo/core/plainDescription.js.map +1 -1
- package/lib/seo/core/routeProblems.d.ts.map +1 -1
- package/lib/seo/core/routeProblems.js +1 -6
- package/lib/seo/core/routeProblems.js.map +1 -1
- package/lib/seo/core/routeTable.d.ts +31 -0
- package/lib/seo/core/routeTable.d.ts.map +1 -0
- package/lib/seo/core/routeTable.js +96 -0
- package/lib/seo/core/routeTable.js.map +1 -0
- package/lib/seo/vite/index.d.ts +2 -0
- package/lib/seo/vite/index.d.ts.map +1 -1
- package/lib/seo/vite/index.js +1 -0
- package/lib/seo/vite/index.js.map +1 -1
- package/lib/seo/vite/prerender.d.ts +10 -0
- package/lib/seo/vite/prerender.d.ts.map +1 -1
- package/lib/seo/vite/prerender.js +12 -1
- package/lib/seo/vite/prerender.js.map +1 -1
- package/lib/seo/vite/routeTable.d.ts +40 -0
- package/lib/seo/vite/routeTable.d.ts.map +1 -0
- package/lib/seo/vite/routeTable.js +44 -0
- package/lib/seo/vite/routeTable.js.map +1 -0
- package/lib/server/answerAddresses.d.ts +51 -0
- package/lib/server/answerAddresses.d.ts.map +1 -0
- package/lib/server/answerAddresses.js +72 -0
- package/lib/server/answerAddresses.js.map +1 -0
- package/lib/server/cardMeta.d.ts +57 -0
- package/lib/server/cardMeta.d.ts.map +1 -0
- package/lib/server/cardMeta.js +52 -0
- package/lib/server/cardMeta.js.map +1 -0
- package/lib/server/config.d.ts +72 -0
- package/lib/server/config.d.ts.map +1 -0
- package/lib/server/config.js +67 -0
- package/lib/server/config.js.map +1 -0
- package/lib/server/envNumber.d.ts +35 -0
- package/lib/server/envNumber.d.ts.map +1 -0
- package/lib/server/envNumber.js +42 -0
- package/lib/server/envNumber.js.map +1 -0
- package/lib/server/healthRoute.d.ts +26 -0
- package/lib/server/healthRoute.d.ts.map +1 -0
- package/lib/server/healthRoute.js +22 -0
- package/lib/server/healthRoute.js.map +1 -0
- package/lib/server/listenSite.d.ts +38 -0
- package/lib/server/listenSite.d.ts.map +1 -0
- package/lib/server/listenSite.js +60 -0
- package/lib/server/listenSite.js.map +1 -0
- package/lib/server/mcpServer.d.ts +8 -0
- package/lib/server/mcpServer.d.ts.map +1 -0
- package/lib/server/mcpServer.js +11 -0
- package/lib/server/mcpServer.js.map +1 -0
- package/lib/server/repositoryVersion.d.ts +16 -0
- package/lib/server/repositoryVersion.d.ts.map +1 -0
- package/lib/server/repositoryVersion.js +33 -0
- package/lib/server/repositoryVersion.js.map +1 -0
- package/lib/server/routeOptions.d.ts +23 -0
- package/lib/server/routeOptions.d.ts.map +1 -0
- package/lib/server/routeOptions.js +20 -0
- package/lib/server/routeOptions.js.map +1 -0
- package/lib/server/routeTable.d.ts +14 -0
- package/lib/server/routeTable.d.ts.map +1 -0
- package/lib/server/routeTable.js +32 -0
- package/lib/server/routeTable.js.map +1 -0
- package/lib/server/siteView.d.ts +29 -0
- package/lib/server/siteView.d.ts.map +1 -0
- package/lib/server/siteView.js +21 -0
- package/lib/server/siteView.js.map +1 -0
- package/lib/server/spaPages.d.ts +32 -0
- package/lib/server/spaPages.d.ts.map +1 -0
- package/lib/server/spaPages.js +126 -0
- package/lib/server/spaPages.js.map +1 -0
- package/lib/server/spaSite.d.ts +30 -0
- package/lib/server/spaSite.d.ts.map +1 -0
- package/lib/server/spaSite.js +170 -0
- package/lib/server/spaSite.js.map +1 -0
- package/lib/server/spaSiteOptions.d.ts +126 -0
- package/lib/server/spaSiteOptions.d.ts.map +1 -0
- package/lib/server/spaSiteOptions.js +2 -0
- package/lib/server/spaSiteOptions.js.map +1 -0
- package/lib/server/staticSite.d.ts +9 -0
- package/lib/server/staticSite.d.ts.map +1 -1
- package/lib/server/staticSite.js +41 -19
- package/lib/server/staticSite.js.map +1 -1
- package/lib/server/toolSiteServer.d.ts +77 -0
- package/lib/server/toolSiteServer.d.ts.map +1 -0
- package/lib/server/toolSiteServer.js +58 -0
- package/lib/server/toolSiteServer.js.map +1 -0
- package/lib/server/trustProxy.d.ts +20 -0
- package/lib/server/trustProxy.d.ts.map +1 -0
- package/lib/server/trustProxy.js +32 -0
- package/lib/server/trustProxy.js.map +1 -0
- package/lib/server/types.d.ts +13 -0
- package/lib/server/types.d.ts.map +1 -0
- package/lib/server/types.js +2 -0
- package/lib/server/types.js.map +1 -0
- package/lib/server.d.ts +22 -0
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +12 -0
- package/lib/server.js.map +1 -1
- package/lib/share/core/config.d.ts +18 -0
- package/lib/share/core/config.d.ts.map +1 -1
- package/lib/share/core/config.js +33 -2
- package/lib/share/core/config.js.map +1 -1
- package/lib/share/core/index.d.ts +3 -1
- package/lib/share/core/index.d.ts.map +1 -1
- package/lib/share/core/index.js +2 -1
- package/lib/share/core/index.js.map +1 -1
- package/lib/share/core/keySetParam.d.ts +40 -0
- package/lib/share/core/keySetParam.d.ts.map +1 -0
- package/lib/share/core/keySetParam.js +60 -0
- package/lib/share/core/keySetParam.js.map +1 -0
- package/lib/share/core/vocabulary.d.ts +8 -0
- package/lib/share/core/vocabulary.d.ts.map +1 -1
- package/lib/shell/ui/ShareControl.d.ts +75 -0
- package/lib/shell/ui/ShareControl.d.ts.map +1 -0
- package/lib/shell/ui/ShareControl.js +40 -0
- package/lib/shell/ui/ShareControl.js.map +1 -0
- package/lib/shell/ui/ShellFrame.d.ts +14 -0
- package/lib/shell/ui/ShellFrame.d.ts.map +1 -0
- package/lib/shell/ui/ShellFrame.js +45 -0
- package/lib/shell/ui/ShellFrame.js.map +1 -0
- package/lib/shell/ui/SiteShell.d.ts +251 -0
- package/lib/shell/ui/SiteShell.d.ts.map +1 -0
- package/lib/shell/ui/SiteShell.js +39 -0
- package/lib/shell/ui/SiteShell.js.map +1 -0
- package/lib/shell/ui/index.d.ts +5 -0
- package/lib/shell/ui/index.d.ts.map +1 -0
- package/lib/shell/ui/index.js +3 -0
- package/lib/shell/ui/index.js.map +1 -0
- package/lib/state/core/index.d.ts +1 -0
- package/lib/state/core/index.d.ts.map +1 -1
- package/lib/state/core/index.js.map +1 -1
- package/lib/state/core/legacyEntries.d.ts +30 -0
- package/lib/state/core/legacyEntries.d.ts.map +1 -0
- package/lib/state/core/legacyEntries.js +51 -0
- package/lib/state/core/legacyEntries.js.map +1 -0
- package/lib/state/core/persistBucket.d.ts +26 -2
- package/lib/state/core/persistBucket.d.ts.map +1 -1
- package/lib/state/core/persistBucket.js +26 -9
- package/lib/state/core/persistBucket.js.map +1 -1
- package/lib/state/core/persistSignalBucket.d.ts +26 -0
- package/lib/state/core/persistSignalBucket.d.ts.map +1 -1
- package/lib/state/core/persistSignalBucket.js +31 -0
- package/lib/state/core/persistSignalBucket.js.map +1 -1
- package/lib/state/core/storageEntry.d.ts +15 -0
- package/lib/state/core/storageEntry.d.ts.map +1 -1
- package/lib/state/core/storageEntry.js +33 -0
- package/lib/state/core/storageEntry.js.map +1 -1
- package/lib/structure/ui/StructureExportButton.d.ts +27 -0
- package/lib/structure/ui/StructureExportButton.d.ts.map +1 -0
- package/lib/structure/ui/StructureExportButton.js +21 -0
- package/lib/structure/ui/StructureExportButton.js.map +1 -0
- package/lib/structure/ui/index.d.ts +4 -0
- package/lib/structure/ui/index.d.ts.map +1 -1
- package/lib/structure/ui/index.js +2 -0
- package/lib/structure/ui/index.js.map +1 -1
- package/lib/structure/ui/useStructureDraft.d.ts +32 -0
- package/lib/structure/ui/useStructureDraft.d.ts.map +1 -0
- package/lib/structure/ui/useStructureDraft.js +20 -0
- package/lib/structure/ui/useStructureDraft.js.map +1 -0
- package/lib/ui.d.ts +2 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +2 -0
- package/lib/ui.js.map +1 -1
- package/lib/worker/core/index.d.ts +1 -1
- package/lib/worker/core/index.d.ts.map +1 -1
- package/lib/worker/core/messages.d.ts +4 -2
- package/lib/worker/core/messages.d.ts.map +1 -1
- package/lib/worker/core/messages.js.map +1 -1
- package/lib/worker/core/oclResourcesUrl.d.ts +16 -0
- package/lib/worker/core/oclResourcesUrl.d.ts.map +1 -0
- package/lib/worker/core/oclResourcesUrl.js +19 -0
- package/lib/worker/core/oclResourcesUrl.js.map +1 -0
- package/lib/worker/core/serveWorkerRequests.d.ts +8 -0
- package/lib/worker/core/serveWorkerRequests.d.ts.map +1 -1
- package/lib/worker/core/serveWorkerRequests.js +15 -2
- package/lib/worker/core/serveWorkerRequests.js.map +1 -1
- package/lib/worker/core/workerChannel.d.ts +3 -4
- package/lib/worker/core/workerChannel.d.ts.map +1 -1
- package/lib/worker/core/workerChannel.js +72 -67
- package/lib/worker/core/workerChannel.js.map +1 -1
- package/lib/worker/core/workerChannelParts.d.ts +17 -6
- package/lib/worker/core/workerChannelParts.d.ts.map +1 -1
- package/lib/worker/core/workerChannelParts.js +20 -4
- package/lib/worker/core/workerChannelParts.js.map +1 -1
- package/lib/worker/core/workerChannelTypes.d.ts +46 -2
- package/lib/worker/core/workerChannelTypes.d.ts.map +1 -1
- package/lib/worker/core/workerSlot.d.ts +66 -0
- package/lib/worker/core/workerSlot.d.ts.map +1 -0
- package/lib/worker/core/workerSlot.js +107 -0
- package/lib/worker/core/workerSlot.js.map +1 -0
- package/package.json +17 -1
- package/src/card/core/cardAddress.ts +100 -0
- package/src/card/core/cardPageUrl.ts +97 -0
- package/src/card/core/index.ts +6 -0
- package/src/card/core/panelRoom.ts +66 -0
- package/src/card/ui/CardDetailsButton.tsx +104 -0
- package/src/card/ui/CardFigure.tsx +86 -0
- package/src/card/ui/CardFrame.tsx +46 -0
- package/src/card/ui/CopyTableButton.tsx +81 -0
- package/src/card/ui/cardTooltip.ts +18 -0
- package/src/card/ui/embed.ts +27 -0
- package/src/card/ui/fitCardToFrame.ts +76 -0
- package/src/card/ui/holdRoomForPanels.ts +83 -0
- package/src/card/ui/index.ts +14 -0
- package/src/card/ui/openPanels.ts +106 -0
- package/src/card.ts +13 -0
- package/src/conformers.ts +4 -0
- package/src/core.ts +5 -0
- package/src/fetch/core/apiError.ts +65 -0
- package/src/fetch/core/fetchJson.ts +129 -0
- package/src/fetch/core/index.ts +4 -0
- package/src/formula/core/formulaText.ts +96 -0
- package/src/formula/core/index.ts +20 -0
- package/src/formula/core/normalizeFormula.ts +50 -0
- package/src/formula/core/readFormula.ts +211 -0
- package/src/formula/ui/CopyableFormula.tsx +51 -0
- package/src/formula/ui/FormulaInput.tsx +50 -0
- package/src/formula/ui/QuestionFormula.tsx +20 -0
- package/src/formula/ui/index.ts +6 -0
- package/src/formula.ts +11 -0
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/keyTargets.ts +5 -3
- package/src/hooks/ui/useAsync.ts +50 -14
- package/src/ir/core/analysisSpectra.ts +26 -10
- package/src/ir/core/bandLabelPlan.ts +21 -10
- package/src/ir/core/index.ts +25 -5
- 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/irFormat.ts +39 -6
- package/src/ir/core/irMode.ts +42 -10
- package/src/ir/core/irReducer.ts +1 -49
- package/src/ir/core/irSpectrum.ts +59 -30
- package/src/ir/core/irState.ts +67 -2
- 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 +2 -1
- package/src/ir/ui/IrChart.tsx +20 -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 +5 -36
- package/src/ir/ui/IrHeader.tsx +10 -3
- package/src/ir/ui/IrLogo.tsx +28 -9
- package/src/ir/ui/IrShell.tsx +27 -75
- 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 +53 -0
- package/src/ir/ui/SpectraPanel.tsx +2 -1
- package/src/ir/ui/SpectrumRow.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +94 -0
- package/src/ir/ui/bandsTsv.ts +46 -0
- package/src/ir/ui/irChartProps.ts +14 -4
- package/src/ir/ui/irCommandContext.tsx +18 -3
- package/src/ir/ui/useIrEditor.ts +20 -8
- package/src/ir/ui/useIrHandle.ts +51 -0
- package/src/ir/ui/useIrText.ts +170 -0
- package/src/ir/ui/useIrZoom.ts +12 -3
- package/src/ir/ui/useValueAxisZoom.ts +67 -0
- package/src/ir.ts +3 -0
- package/src/locales/de.json +57 -1
- package/src/locales/en.json +57 -1
- package/src/locales/es.json +57 -1
- package/src/locales/fr.json +57 -1
- package/src/locales/it.json +57 -1
- package/src/moleculesClient/core/index.ts +19 -0
- package/src/moleculesClient/core/moleculesClient.ts +175 -0
- package/src/moleculesClient/core/moleculesClientApi.ts +120 -0
- package/src/moleculesClient/core/moleculesTypes.ts +163 -0
- package/src/moleculesClient/core/requestRetry.ts +118 -0
- package/src/molstar/core/camera.ts +3 -2
- package/src/molstar/core/framing.ts +200 -0
- package/src/molstar/core/hover.ts +26 -0
- package/src/molstar/core/index.ts +21 -1
- package/src/pedagogy/core/answers.ts +94 -0
- package/src/pedagogy/core/attempts.ts +205 -0
- package/src/pedagogy/core/index.ts +36 -0
- package/src/pedagogy/core/progressController.ts +116 -0
- package/src/pedagogy/core/seed.ts +177 -0
- package/src/pedagogy/core/series.ts +82 -0
- package/src/pedagogy/ui/AnswerFields.tsx +63 -0
- package/src/pedagogy/ui/ExerciseList.tsx +202 -0
- package/src/pedagogy/ui/ExerciseSeries.tsx +250 -0
- package/src/pedagogy/ui/QuestionCard.tsx +231 -0
- package/src/pedagogy/ui/index.ts +18 -0
- package/src/pedagogy/ui/seriesCounts.ts +34 -0
- package/src/pedagogy/ui/seriesParts.tsx +127 -0
- package/src/pedagogy/ui/useAttemptRecords.ts +16 -0
- package/src/periodic/ui/PeriodicTable.tsx +6 -3
- package/src/property/core/copyableText.ts +20 -0
- package/src/property/core/index.ts +1 -0
- package/src/property/ui/PropertyTable.tsx +83 -0
- package/src/property/ui/index.ts +2 -0
- package/src/raman.ts +19 -0
- package/src/router/core/history.ts +61 -7
- package/src/router/core/index.ts +3 -2
- package/src/router/core/languageRoute.ts +136 -0
- package/src/router/core/siteAddresses.ts +38 -0
- package/src/router/core/tabRouter.ts +59 -117
- package/src/router/core/tabRouterTypes.ts +158 -0
- package/src/seo/core/fitDescription.ts +74 -0
- package/src/seo/core/index.ts +17 -0
- package/src/seo/core/limits.ts +27 -0
- package/src/seo/core/pageContent.ts +42 -0
- package/src/seo/core/plainDescription.ts +4 -2
- package/src/seo/core/routeProblems.ts +1 -7
- package/src/seo/core/routeTable.ts +103 -0
- package/src/seo/vite/index.ts +2 -0
- package/src/seo/vite/prerender.ts +26 -1
- package/src/seo/vite/routeTable.ts +79 -0
- package/src/server/answerAddresses.ts +92 -0
- package/src/server/cardMeta.ts +88 -0
- package/src/server/config.ts +125 -0
- package/src/server/envNumber.ts +65 -0
- package/src/server/healthRoute.ts +42 -0
- package/src/server/listenSite.ts +90 -0
- package/src/server/mcpServer.ts +14 -0
- package/src/server/repositoryVersion.ts +33 -0
- package/src/server/routeOptions.ts +26 -0
- package/src/server/routeTable.ts +35 -0
- package/src/server/siteView.ts +42 -0
- package/src/server/spaPages.ts +179 -0
- package/src/server/spaSite.ts +216 -0
- package/src/server/spaSiteOptions.ts +133 -0
- package/src/server/staticSite.ts +65 -35
- package/src/server/toolSiteServer.ts +127 -0
- package/src/server/trustProxy.ts +32 -0
- package/src/server/types.ts +25 -0
- package/src/server.ts +40 -0
- package/src/share/core/config.ts +45 -2
- package/src/share/core/index.ts +4 -0
- package/src/share/core/keySetParam.ts +92 -0
- package/src/share/core/vocabulary.ts +8 -0
- package/src/shell/ui/ShareControl.tsx +150 -0
- package/src/shell/ui/ShellFrame.tsx +180 -0
- package/src/shell/ui/SiteShell.tsx +297 -0
- package/src/shell/ui/index.ts +9 -0
- package/src/state/core/index.ts +1 -0
- package/src/state/core/legacyEntries.ts +76 -0
- package/src/state/core/persistBucket.ts +50 -10
- package/src/state/core/persistSignalBucket.ts +52 -0
- package/src/state/core/storageEntry.ts +32 -0
- package/src/structure/ui/StructureExportButton.tsx +57 -0
- package/src/structure/ui/index.ts +4 -0
- package/src/structure/ui/useStructureDraft.ts +47 -0
- package/src/ui.ts +2 -0
- package/src/worker/core/index.ts +1 -0
- package/src/worker/core/messages.ts +4 -3
- package/src/worker/core/oclResourcesUrl.ts +21 -0
- package/src/worker/core/serveWorkerRequests.ts +30 -2
- package/src/worker/core/workerChannel.ts +74 -74
- package/src/worker/core/workerChannelParts.ts +33 -13
- package/src/worker/core/workerChannelTypes.ts +47 -2
- package/src/worker/core/workerSlot.ts +181 -0
- package/styles/card.css +145 -0
- package/styles/chrome.css +248 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Button, Tooltip } from '@blueprintjs/core';
|
|
2
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { pageLocation } from '../../router/core/pageAddress.ts';
|
|
7
|
+
import { useActionTooltip } from '../../shared/ui/useActionTooltip.ts';
|
|
8
|
+
import type { SitePageOptions } from '../core/cardAddress.ts';
|
|
9
|
+
import { sitePageUrl } from '../core/cardAddress.ts';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
CARD_TOOLTIP_CLASS,
|
|
13
|
+
CARD_TOOLTIP_DELAY,
|
|
14
|
+
CARD_TOOLTIP_MODIFIERS,
|
|
15
|
+
} from './cardTooltip.ts';
|
|
16
|
+
import { loadEmbed, loadedEmbed } from './embed.ts';
|
|
17
|
+
|
|
18
|
+
/** What {@link CardDetailsButton} opens. */
|
|
19
|
+
export interface CardDetailsButtonProps {
|
|
20
|
+
/**
|
|
21
|
+
* Writes the address of the page the button opens, when it is pressed.
|
|
22
|
+
* @default the card's own address without `card`, `embed`, `hide` and
|
|
23
|
+
* what `address` says only the card reads — `sitePageUrl` over the page's
|
|
24
|
+
* address, the one a sealed link holds in memory included
|
|
25
|
+
*/
|
|
26
|
+
page?: () => string;
|
|
27
|
+
/**
|
|
28
|
+
* How the default page is read off the card's address.
|
|
29
|
+
* @default {} - `card`, `embed` and `hide` are left out, and nothing else
|
|
30
|
+
*/
|
|
31
|
+
address?: SitePageOptions;
|
|
32
|
+
/**
|
|
33
|
+
* What the tooltip says the button does.
|
|
34
|
+
* @default the chrome's own line, `Open in a new tab`
|
|
35
|
+
*/
|
|
36
|
+
tooltip?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Value of the `data-testid` attribute of the button.
|
|
39
|
+
* @default 'card-details'
|
|
40
|
+
*/
|
|
41
|
+
testId?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The way from a card to the site's own page it stands for, with its chrome,
|
|
46
|
+
* at the end of the card: a chat keeps the card's top right corner for its own
|
|
47
|
+
* control. Framed by a chat, the page opens in a new tab, so the conversation
|
|
48
|
+
* keeps its place; opened on its own, the card becomes the page. It never
|
|
49
|
+
* prints.
|
|
50
|
+
* @param props - See {@link CardDetailsButtonProps}.
|
|
51
|
+
* @returns The button, with the tooltip saying where the page opens.
|
|
52
|
+
*/
|
|
53
|
+
export function CardDetailsButton(props: CardDetailsButtonProps): ReactElement {
|
|
54
|
+
const { page, address, tooltip, testId = 'card-details' } = props;
|
|
55
|
+
const t = useChromeT();
|
|
56
|
+
const { isOpen, target } = useActionTooltip(false, CARD_TOOLTIP_DELAY);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
loadEmbed().catch(() => undefined);
|
|
59
|
+
}, []);
|
|
60
|
+
return (
|
|
61
|
+
<Tooltip
|
|
62
|
+
content={tooltip ?? t('card.detailsTitle')}
|
|
63
|
+
placement="top-end"
|
|
64
|
+
modifiers={CARD_TOOLTIP_MODIFIERS}
|
|
65
|
+
popoverClassName={CARD_TOOLTIP_CLASS}
|
|
66
|
+
isOpen={isOpen}
|
|
67
|
+
>
|
|
68
|
+
<span className="no-print" style={WRAP_STYLE} {...target}>
|
|
69
|
+
<Button
|
|
70
|
+
variant="minimal"
|
|
71
|
+
size="small"
|
|
72
|
+
icon="share"
|
|
73
|
+
text={t('card.details')}
|
|
74
|
+
aria-label={t('card.detailsLabel')}
|
|
75
|
+
data-testid={testId}
|
|
76
|
+
onClick={() => {
|
|
77
|
+
const url = page === undefined ? cardSitePage(address) : page();
|
|
78
|
+
const embed = loadedEmbed();
|
|
79
|
+
if (embed === undefined) {
|
|
80
|
+
void loadEmbed().then((module) => module.openSitePage(url));
|
|
81
|
+
} else {
|
|
82
|
+
embed.openSitePage(url);
|
|
83
|
+
}
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
86
|
+
</span>
|
|
87
|
+
</Tooltip>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The site's page behind the card on screen, read when the button is
|
|
93
|
+
* pressed: the page's own address — held in memory under a sealed link — on
|
|
94
|
+
* the origin the card is served from.
|
|
95
|
+
* @param address - What only the card reads.
|
|
96
|
+
* @returns The page's absolute address.
|
|
97
|
+
*/
|
|
98
|
+
function cardSitePage(address: SitePageOptions | undefined): string {
|
|
99
|
+
const { origin } = globalThis.location;
|
|
100
|
+
const { pathname, search } = pageLocation() ?? globalThis.location;
|
|
101
|
+
return sitePageUrl({ origin, pathname, search }, address);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const WRAP_STYLE = { display: 'inline-flex' } as const satisfies CSSProperties;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
|
|
4
|
+
import { FigureDownload } from '../../download/ui/FigureDownload.tsx';
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { OverlayLayer } from '../../overlay/ui/OverlayLayer.tsx';
|
|
7
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
8
|
+
|
|
9
|
+
/** What {@link CardFigure} draws and takes away. */
|
|
10
|
+
export interface CardFigureProps {
|
|
11
|
+
/** The drawing: a chart, a structure, a grid of them. */
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
/** What a saved file is called, without its extension. */
|
|
14
|
+
fileName: string;
|
|
15
|
+
/**
|
|
16
|
+
* Glyphs drawn above the one copying the picture: the copy of the data the
|
|
17
|
+
* figure is drawn from, the notations of its structure
|
|
18
|
+
* (`StructureExportButton` of `react-cheminfo/structure`).
|
|
19
|
+
* @default undefined - the picture's glyph alone
|
|
20
|
+
*/
|
|
21
|
+
tools?: ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* Class of the box the drawing is in, which is what the picture holds.
|
|
24
|
+
* @default undefined
|
|
25
|
+
*/
|
|
26
|
+
className?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Take the whole width the card gives, as a grid of structures does.
|
|
29
|
+
* @default false - as wide as the drawing
|
|
30
|
+
*/
|
|
31
|
+
fill?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The drawing is HTML rather than one SVG or canvas — a grid of cells — and
|
|
34
|
+
* the picture saved is painted from it as it is seen.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
html?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* What the picture's glyph is called, for the pointer and a screen reader.
|
|
40
|
+
* @default the chrome's own line, `Copy or save the picture`
|
|
41
|
+
*/
|
|
42
|
+
label?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A figure of a card with the glyphs that take it away: the picture copied as
|
|
47
|
+
* a PNG or saved as a PNG or an SVG, as the chat offers it for its own
|
|
48
|
+
* figures, and whatever else the figure carries.
|
|
49
|
+
*
|
|
50
|
+
* The glyphs stand in a column beside the figure's top right corner rather
|
|
51
|
+
* than over it, so they hide no part of a curve or an atom, and they fade
|
|
52
|
+
* until the figure is pointed at or one of them holds the focus: a card shown
|
|
53
|
+
* in a chat is read far more often than it is copied. `styles/card.css` draws
|
|
54
|
+
* the column.
|
|
55
|
+
* @param props - See {@link CardFigureProps}.
|
|
56
|
+
* @returns The figure, with its column of glyphs.
|
|
57
|
+
*/
|
|
58
|
+
export function CardFigure(props: CardFigureProps): ReactElement {
|
|
59
|
+
const { children, fileName, tools, className, label } = props;
|
|
60
|
+
const { fill = false, html = false } = props;
|
|
61
|
+
const t = useChromeT();
|
|
62
|
+
const id = useId();
|
|
63
|
+
return (
|
|
64
|
+
<div className={joinClassNames('card-figure', fill && 'card-figure--fill')}>
|
|
65
|
+
<div
|
|
66
|
+
id={id}
|
|
67
|
+
className={joinClassNames('card-figure__drawing', className)}
|
|
68
|
+
data-figure={html ? 'html' : undefined}
|
|
69
|
+
>
|
|
70
|
+
{children}
|
|
71
|
+
</div>
|
|
72
|
+
{/* Compact: the glyphs of a figure shown in somebody else's page. */}
|
|
73
|
+
<OverlayLayer density="compact" awake>
|
|
74
|
+
<div className="card-figure__tools" data-testid="figure-tools">
|
|
75
|
+
{tools}
|
|
76
|
+
<FigureDownload
|
|
77
|
+
targetId={id}
|
|
78
|
+
fileName={fileName}
|
|
79
|
+
label={label ?? t('card.copyPicture')}
|
|
80
|
+
testId="card-save-figure"
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
</OverlayLayer>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
4
|
+
|
|
5
|
+
import { fitCardToFrame } from './fitCardToFrame.ts';
|
|
6
|
+
|
|
7
|
+
/** What {@link CardFrame} holds. */
|
|
8
|
+
export interface CardFrameProps {
|
|
9
|
+
/** The card: the answer alone, compactly. */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* Class beside `card`, so a site can reach the card from its stylesheet.
|
|
13
|
+
* @default undefined
|
|
14
|
+
*/
|
|
15
|
+
className?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Value of the `data-testid` attribute.
|
|
18
|
+
* @default 'card'
|
|
19
|
+
*/
|
|
20
|
+
testId?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The page a chat frames inline for one answer: the card, with no header, no
|
|
25
|
+
* footer and no form, as tall as what it shows. Framed, it reports its height
|
|
26
|
+
* so the chat fits the frame to it, and grows while a panel it opened is open
|
|
27
|
+
* so the frame holds that too; opened on its own, it is a page like any other.
|
|
28
|
+
*
|
|
29
|
+
* `react-cheminfo/styles/card.css` draws it: no margin on the page around it,
|
|
30
|
+
* the chat's corner left free by `card__header`, and the row of actions at its
|
|
31
|
+
* end, `card__end`.
|
|
32
|
+
* @param props - See {@link CardFrameProps}.
|
|
33
|
+
* @returns The card's root element.
|
|
34
|
+
*/
|
|
35
|
+
export function CardFrame(props: CardFrameProps): ReactElement {
|
|
36
|
+
const { children, className, testId = 'card' } = props;
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
ref={fitCardToFrame}
|
|
40
|
+
className={joinClassNames('card', className)}
|
|
41
|
+
data-testid={testId}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Tooltip } from '@blueprintjs/core';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
import { CopyButton } from '../../clipboard/ui/CopyButton.tsx';
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
CARD_TOOLTIP_CLASS,
|
|
10
|
+
CARD_TOOLTIP_DELAY,
|
|
11
|
+
CARD_TOOLTIP_MODIFIERS,
|
|
12
|
+
} from './cardTooltip.ts';
|
|
13
|
+
|
|
14
|
+
/** What {@link CopyTableButton} copies. */
|
|
15
|
+
export interface CopyTableButtonProps {
|
|
16
|
+
/**
|
|
17
|
+
* Writes the table, tab-separated and header first, when the button is
|
|
18
|
+
* pressed: a card holding a long table writes nothing until it is asked.
|
|
19
|
+
*/
|
|
20
|
+
table: () => string;
|
|
21
|
+
/**
|
|
22
|
+
* What the tooltip says the button copies, e.g. `Copy the conformers as a
|
|
23
|
+
* table, to paste into a spreadsheet`.
|
|
24
|
+
* @default the chrome's own line, `Copy the table, to paste into a
|
|
25
|
+
* spreadsheet`
|
|
26
|
+
*/
|
|
27
|
+
tooltip?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Show the glyph alone, which is what a heading of a few letters has room
|
|
30
|
+
* for. The label is still the button's accessible name.
|
|
31
|
+
* @default false - the label shows, and gives way to the glyph on a frame
|
|
32
|
+
* narrower than 30rem
|
|
33
|
+
*/
|
|
34
|
+
glyphOnly?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Value of the `data-testid` attribute of the button's box.
|
|
37
|
+
* @default 'card-copy-table'
|
|
38
|
+
*/
|
|
39
|
+
testId?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A card's "Copy as table" action: the table, tab-separated and header first,
|
|
44
|
+
* which a spreadsheet pastes into its cells. A tick says the clipboard took
|
|
45
|
+
* it, a cross that the browser refused. It never prints.
|
|
46
|
+
* @param props - See {@link CopyTableButtonProps}.
|
|
47
|
+
* @returns The button, with the tooltip saying what it copies.
|
|
48
|
+
*/
|
|
49
|
+
export function CopyTableButton(props: CopyTableButtonProps): ReactElement {
|
|
50
|
+
const {
|
|
51
|
+
table,
|
|
52
|
+
tooltip,
|
|
53
|
+
glyphOnly = false,
|
|
54
|
+
testId = 'card-copy-table',
|
|
55
|
+
} = props;
|
|
56
|
+
const t = useChromeT();
|
|
57
|
+
return (
|
|
58
|
+
<Tooltip
|
|
59
|
+
content={tooltip ?? t('card.copyTableTitle')}
|
|
60
|
+
placement="top-end"
|
|
61
|
+
modifiers={CARD_TOOLTIP_MODIFIERS}
|
|
62
|
+
popoverClassName={CARD_TOOLTIP_CLASS}
|
|
63
|
+
hoverOpenDelay={CARD_TOOLTIP_DELAY}
|
|
64
|
+
>
|
|
65
|
+
<span data-testid={testId}>
|
|
66
|
+
<CopyButton
|
|
67
|
+
content={table}
|
|
68
|
+
label={t('card.copyTable')}
|
|
69
|
+
title=""
|
|
70
|
+
icon="th"
|
|
71
|
+
minimal
|
|
72
|
+
small
|
|
73
|
+
className={joinClassNames(
|
|
74
|
+
'card__copy-table',
|
|
75
|
+
glyphOnly && 'card__copy-table--glyph',
|
|
76
|
+
)}
|
|
77
|
+
/>
|
|
78
|
+
</span>
|
|
79
|
+
</Tooltip>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PopoverProps } from '@blueprintjs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The family's help card, at the width of the few words a card's action
|
|
5
|
+
* says: `styles/card.css` lets `card-tooltip` shrink to its text.
|
|
6
|
+
*/
|
|
7
|
+
export const CARD_TOOLTIP_CLASS = 'help-tooltip card-tooltip';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Where a card's tooltip goes when the frame has no room above its control:
|
|
11
|
+
* beside it, rather than cut by the frame's edge.
|
|
12
|
+
*/
|
|
13
|
+
export const CARD_TOOLTIP_MODIFIERS: PopoverProps['modifiers'] = {
|
|
14
|
+
flip: { options: { fallbackPlacements: ['left'] } },
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** How long the pointer rests on an action of a card before it is named. */
|
|
18
|
+
export const CARD_TOOLTIP_DELAY = 300;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type * as Embed from 'cheminfo-mcp-server/embed';
|
|
2
|
+
|
|
3
|
+
let loading: Promise<typeof Embed> | undefined;
|
|
4
|
+
let loaded: typeof Embed | undefined;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Load `cheminfo-mcp-server/embed` once, on first use. It is an optional
|
|
8
|
+
* peer, so `react-cheminfo/card` must import without it; a site that lacks it
|
|
9
|
+
* gets a card that never talks to a frame.
|
|
10
|
+
* @returns The module, once loaded.
|
|
11
|
+
*/
|
|
12
|
+
export function loadEmbed(): Promise<typeof Embed> {
|
|
13
|
+
loading ??= import('cheminfo-mcp-server/embed').then((module) => {
|
|
14
|
+
loaded = module;
|
|
15
|
+
return module;
|
|
16
|
+
});
|
|
17
|
+
return loading;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The module {@link loadEmbed} loaded, read synchronously — a click must open
|
|
22
|
+
* its page in the same task, or the browser blocks the new tab.
|
|
23
|
+
* @returns The module, or undefined while it is still loading.
|
|
24
|
+
*/
|
|
25
|
+
export function loadedEmbed(): typeof Embed | undefined {
|
|
26
|
+
return loaded;
|
|
27
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type * as Embed from 'cheminfo-mcp-server/embed';
|
|
2
|
+
import type { RefObject } from 'react';
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
import { loadEmbed, loadedEmbed } from './embed.ts';
|
|
6
|
+
import { holdRoomForPanels } from './holdRoomForPanels.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Fit the frame a chat shows a card in to the card: report the card's height
|
|
10
|
+
* to the view framing it, now and on every change, so nothing scrolls twice,
|
|
11
|
+
* and grow the card while a panel it opened is open, so the frame holds the
|
|
12
|
+
* panel too. A card opened on its own is the page: there is no frame to tell
|
|
13
|
+
* and none to grow, and nothing is done.
|
|
14
|
+
*
|
|
15
|
+
* Its shape is a React 19 ref callback's — `ref={fitCardToFrame}` — so it
|
|
16
|
+
* starts once the card is mounted and stops when it is removed. The first
|
|
17
|
+
* card waits for `cheminfo-mcp-server/embed` to load; a site without it gets
|
|
18
|
+
* a card that never reports.
|
|
19
|
+
* @param card - The element holding the whole card; none reports nothing.
|
|
20
|
+
* @returns A function that stops both, or undefined when nothing started.
|
|
21
|
+
*/
|
|
22
|
+
export function fitCardToFrame(
|
|
23
|
+
card: HTMLElement | null,
|
|
24
|
+
): (() => void) | undefined {
|
|
25
|
+
if (card === null) return undefined;
|
|
26
|
+
const embed = loadedEmbed();
|
|
27
|
+
if (embed !== undefined) return fitLoaded(embed, card);
|
|
28
|
+
let stop: (() => void) | undefined;
|
|
29
|
+
let stopped = false;
|
|
30
|
+
loadEmbed().then(
|
|
31
|
+
(module) => {
|
|
32
|
+
if (!stopped) stop = fitLoaded(module, card);
|
|
33
|
+
},
|
|
34
|
+
() => undefined,
|
|
35
|
+
);
|
|
36
|
+
return () => {
|
|
37
|
+
stopped = true;
|
|
38
|
+
stop?.();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* {@link fitCardToFrame} for a card held in a ref, from its first render to
|
|
44
|
+
* its last.
|
|
45
|
+
* @param card - The ref of the element holding the whole card.
|
|
46
|
+
*/
|
|
47
|
+
export function useFitCardToFrame(card: RefObject<HTMLElement | null>): void {
|
|
48
|
+
useEffect(() => fitCardToFrame(card.current), [card]);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Keep a card at least as tall as the dialogs and popovers opened over it,
|
|
53
|
+
* framed or not: {@link holdRoomForPanels} for a card held in a ref. A card
|
|
54
|
+
* whose height is reported elsewhere uses this; one that only needs its frame
|
|
55
|
+
* fitted uses {@link useFitCardToFrame}, which does both.
|
|
56
|
+
* @param card - The ref of the element holding the whole card.
|
|
57
|
+
*/
|
|
58
|
+
export function useOverlayRoom(card: RefObject<HTMLElement | null>): void {
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
const element = card.current;
|
|
61
|
+
return element === null ? undefined : holdRoomForPanels(element);
|
|
62
|
+
}, [card]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function fitLoaded(
|
|
66
|
+
embed: typeof Embed,
|
|
67
|
+
card: HTMLElement,
|
|
68
|
+
): (() => void) | undefined {
|
|
69
|
+
if (!embed.isFramed()) return undefined;
|
|
70
|
+
const stopRoom = holdRoomForPanels(card);
|
|
71
|
+
const stopReport = embed.reportEmbedHeight(card);
|
|
72
|
+
return () => {
|
|
73
|
+
stopReport();
|
|
74
|
+
stopRoom();
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { roomForPanels } from '../core/panelRoom.ts';
|
|
2
|
+
|
|
3
|
+
import { anchorBottom, openPanels } from './openPanels.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Keep a card as tall as the dialogs and popovers open over it need, until
|
|
7
|
+
* the returned function is called; the card gives the height back as each
|
|
8
|
+
* closes. A chat frames a card exactly as tall as the card reports, so a
|
|
9
|
+
* panel taller than the card would otherwise be cut at the frame's edge.
|
|
10
|
+
*
|
|
11
|
+
* The room is measured once per animation frame, whenever the document
|
|
12
|
+
* changes — a panel opening, closing or moving changes the tree or a class —
|
|
13
|
+
* and whenever an open panel changes size, which one whose content arrives
|
|
14
|
+
* after it opens does without touching the tree. A card whose view fills the
|
|
15
|
+
* screen holds no room: its frame is not what is on screen then.
|
|
16
|
+
* @param card - The element whose height the frame follows.
|
|
17
|
+
* @returns A function that stops watching and gives the card its height back.
|
|
18
|
+
*/
|
|
19
|
+
export function holdRoomForPanels(card: HTMLElement): () => void {
|
|
20
|
+
let frame = 0;
|
|
21
|
+
const watched = new Set<Element>();
|
|
22
|
+
const sizes =
|
|
23
|
+
typeof ResizeObserver === 'undefined'
|
|
24
|
+
? undefined
|
|
25
|
+
: new ResizeObserver(schedule);
|
|
26
|
+
const mutations = new MutationObserver(schedule);
|
|
27
|
+
|
|
28
|
+
function measure(): void {
|
|
29
|
+
frame = 0;
|
|
30
|
+
const panels = openPanels(card);
|
|
31
|
+
if (sizes !== undefined) watchSizes(sizes, watched, panels.elements);
|
|
32
|
+
const room = document.fullscreenElement
|
|
33
|
+
? 0
|
|
34
|
+
: roomForPanels(panels.found, anchorBottom(card));
|
|
35
|
+
const minHeight = room > 0 ? `${room}px` : '';
|
|
36
|
+
if (card.style.minHeight !== minHeight) card.style.minHeight = minHeight;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function schedule(): void {
|
|
40
|
+
if (frame === 0) frame = requestAnimationFrame(measure);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
mutations.observe(document.body, {
|
|
44
|
+
childList: true,
|
|
45
|
+
subtree: true,
|
|
46
|
+
attributes: true,
|
|
47
|
+
attributeFilter: ['class'],
|
|
48
|
+
});
|
|
49
|
+
document.addEventListener('fullscreenchange', schedule);
|
|
50
|
+
schedule();
|
|
51
|
+
return () => {
|
|
52
|
+
mutations.disconnect();
|
|
53
|
+
sizes?.disconnect();
|
|
54
|
+
document.removeEventListener('fullscreenchange', schedule);
|
|
55
|
+
cancelAnimationFrame(frame);
|
|
56
|
+
card.style.minHeight = '';
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Watch the size of the panels on screen, and of no other element.
|
|
62
|
+
* @param sizes - The observer.
|
|
63
|
+
* @param watched - The elements it watches, kept up to date.
|
|
64
|
+
* @param panels - The panels open now.
|
|
65
|
+
*/
|
|
66
|
+
function watchSizes(
|
|
67
|
+
sizes: ResizeObserver,
|
|
68
|
+
watched: Set<Element>,
|
|
69
|
+
panels: readonly Element[],
|
|
70
|
+
): void {
|
|
71
|
+
for (const element of watched) {
|
|
72
|
+
if (!panels.includes(element)) {
|
|
73
|
+
sizes.unobserve(element);
|
|
74
|
+
watched.delete(element);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const element of panels) {
|
|
78
|
+
if (!watched.has(element)) {
|
|
79
|
+
sizes.observe(element);
|
|
80
|
+
watched.add(element);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type { CardDetailsButtonProps } from './CardDetailsButton.tsx';
|
|
2
|
+
export { CardDetailsButton } from './CardDetailsButton.tsx';
|
|
3
|
+
export type { CardFigureProps } from './CardFigure.tsx';
|
|
4
|
+
export { CardFigure } from './CardFigure.tsx';
|
|
5
|
+
export type { CardFrameProps } from './CardFrame.tsx';
|
|
6
|
+
export { CardFrame } from './CardFrame.tsx';
|
|
7
|
+
export type { CopyTableButtonProps } from './CopyTableButton.tsx';
|
|
8
|
+
export { CopyTableButton } from './CopyTableButton.tsx';
|
|
9
|
+
export {
|
|
10
|
+
fitCardToFrame,
|
|
11
|
+
useFitCardToFrame,
|
|
12
|
+
useOverlayRoom,
|
|
13
|
+
} from './fitCardToFrame.ts';
|
|
14
|
+
export { holdRoomForPanels } from './holdRoomForPanels.ts';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dialogs and popovers Blueprint has open over a card, measured as the
|
|
3
|
+
* room each needs of the card's frame.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Classes } from '@blueprintjs/core';
|
|
7
|
+
|
|
8
|
+
import type { OpenPanel } from '../core/panelRoom.ts';
|
|
9
|
+
|
|
10
|
+
/** The panels on screen, and the elements measured for them. */
|
|
11
|
+
export interface FoundPanels {
|
|
12
|
+
/** What each panel needs. */
|
|
13
|
+
found: OpenPanel[];
|
|
14
|
+
/** The elements whose size the panels are read from. */
|
|
15
|
+
elements: HTMLElement[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const OPEN = `.${Classes.OVERLAY_OPEN}`;
|
|
19
|
+
|
|
20
|
+
/** A tooltip is read in passing and closes as the pointer leaves: no room. */
|
|
21
|
+
const POPOVERS = `${OPEN} .${Classes.POPOVER}:not(.${Classes.TOOLTIP})`;
|
|
22
|
+
|
|
23
|
+
const DIALOGS = `${OPEN} .${Classes.DIALOG}`;
|
|
24
|
+
|
|
25
|
+
/** A dialog's body, which scrolls past 70 % of the frame's height. */
|
|
26
|
+
const SCROLLED = `.${Classes.DIALOG_BODY_SCROLL_CONTAINER}`;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A control whose popover is open: Blueprint marks its own target, and a
|
|
30
|
+
* toolbar that renders its target itself — the 3D view's — says it is
|
|
31
|
+
* expanded.
|
|
32
|
+
*/
|
|
33
|
+
const OPEN_CONTROLS = `.${Classes.POPOVER_OPEN}, [aria-expanded='true']`;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The dialogs and popovers on screen, and the room each needs.
|
|
37
|
+
* @param card - The card they are opened over.
|
|
38
|
+
* @returns The panels, and the elements measured for them.
|
|
39
|
+
*/
|
|
40
|
+
export function openPanels(card: HTMLElement): FoundPanels {
|
|
41
|
+
const found: OpenPanel[] = [];
|
|
42
|
+
const elements: HTMLElement[] = [];
|
|
43
|
+
const top = card.getBoundingClientRect().top;
|
|
44
|
+
for (const dialog of document.querySelectorAll<HTMLElement>(DIALOGS)) {
|
|
45
|
+
const { marginTop, marginBottom } = globalThis.getComputedStyle(dialog);
|
|
46
|
+
const margins =
|
|
47
|
+
(parseLength(marginTop) ?? 0) + (parseLength(marginBottom) ?? 0);
|
|
48
|
+
found.push({ kind: 'dialog', height: unscrolledHeight(dialog) + margins });
|
|
49
|
+
elements.push(dialog);
|
|
50
|
+
}
|
|
51
|
+
for (const popover of document.querySelectorAll<HTMLElement>(POPOVERS)) {
|
|
52
|
+
// The box that places a popover is never scaled while it opens, so it
|
|
53
|
+
// says where the popover ends; the popover itself is, at first.
|
|
54
|
+
const placed = popover.parentElement?.classList.contains(
|
|
55
|
+
Classes.POPOVER_TRANSITION_CONTAINER,
|
|
56
|
+
)
|
|
57
|
+
? popover.parentElement
|
|
58
|
+
: popover;
|
|
59
|
+
const bottom = placed.getBoundingClientRect().bottom - top;
|
|
60
|
+
found.push({
|
|
61
|
+
kind: 'popover',
|
|
62
|
+
height: unscrolledHeight(popover),
|
|
63
|
+
...(bottom > 0 && { bottom }),
|
|
64
|
+
});
|
|
65
|
+
elements.push(popover);
|
|
66
|
+
}
|
|
67
|
+
return { found, elements };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Where the lowest control of the card whose popover is open ends.
|
|
72
|
+
* @param card - The card.
|
|
73
|
+
* @returns Its bottom edge, in pixels from the top of the card; 0 for none.
|
|
74
|
+
*/
|
|
75
|
+
export function anchorBottom(card: HTMLElement): number {
|
|
76
|
+
const top = card.getBoundingClientRect().top;
|
|
77
|
+
let bottom = 0;
|
|
78
|
+
for (const control of card.querySelectorAll(OPEN_CONTROLS)) {
|
|
79
|
+
const edge = control.getBoundingClientRect().bottom - top;
|
|
80
|
+
if (edge > bottom) bottom = edge;
|
|
81
|
+
}
|
|
82
|
+
return bottom;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The panel's height with what its body scrolls away put back.
|
|
87
|
+
* @param panel - The dialog or the popover.
|
|
88
|
+
* @returns Its height, in pixels.
|
|
89
|
+
*/
|
|
90
|
+
function unscrolledHeight(panel: HTMLElement): number {
|
|
91
|
+
let height = panel.offsetHeight;
|
|
92
|
+
for (const body of panel.querySelectorAll<HTMLElement>(SCROLLED)) {
|
|
93
|
+
height += body.scrollHeight - body.clientHeight;
|
|
94
|
+
}
|
|
95
|
+
return height;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A computed length, in pixels.
|
|
100
|
+
* @param value - E.g. `30px`; empty where nothing computes it.
|
|
101
|
+
* @returns The number, or undefined when it is not one.
|
|
102
|
+
*/
|
|
103
|
+
function parseLength(value: string): number | undefined {
|
|
104
|
+
const length = Number.parseFloat(value);
|
|
105
|
+
return Number.isFinite(length) ? length : undefined;
|
|
106
|
+
}
|
package/src/card.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The card an answer is shown as in a chat: a site's own page under
|
|
3
|
+
* `?embed=1&card=1`, framed inline by mcp.cheminfo.org.
|
|
4
|
+
*
|
|
5
|
+
* An entry point of its own, and not part of `react-cheminfo/ui`, because it
|
|
6
|
+
* talks to the frame through `cheminfo-mcp-server/embed`: a site that serves
|
|
7
|
+
* no tools must never be made to install it. The addresses — `CARD_PARAM`,
|
|
8
|
+
* `sitePageUrl`, `cardPageUrl` — need neither React nor the frame, and are in
|
|
9
|
+
* `react-cheminfo/core` too.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export * from './card/core/index.ts';
|
|
13
|
+
export * from './card/ui/index.ts';
|
package/src/conformers.ts
CHANGED