react-cheminfo 0.64.1 → 0.65.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 +282 -0
- 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/locales/de.json +37 -0
- package/lib/locales/en.json +37 -0
- package/lib/locales/es.json +37 -0
- package/lib/locales/fr.json +37 -0
- package/lib/locales/it.json +37 -0
- 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/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 +16 -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/locales/de.json +37 -0
- package/src/locales/en.json +37 -0
- package/src/locales/es.json +37 -0
- package/src/locales/fr.json +37 -0
- package/src/locales/it.json +37 -0
- 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/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,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framing a scene: the sphere everything on screen fits in, the camera moved
|
|
3
|
+
* to show it whole, and the zoom onto one point of it.
|
|
4
|
+
*
|
|
5
|
+
* What is on screen is measured rather than read off molstar: a canvas's own
|
|
6
|
+
* `boundingSphereVisible` is read once when the canvas is built, a
|
|
7
|
+
* ball-and-stick representation pads its sphere by the largest ball it could
|
|
8
|
+
* ever draw, and an isosurface reports the whole sampled box. So a site hands
|
|
9
|
+
* the spheres it measured itself, and names which render objects are worth
|
|
10
|
+
* their own sphere — a mesh it built, whose sphere is exactly its vertices.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { GraphicsRenderObject } from 'molstar/lib/mol-gl/render-object.js';
|
|
14
|
+
import { BoundaryHelper } from 'molstar/lib/mol-math/geometry/boundary-helper.js';
|
|
15
|
+
import { Sphere3D } from 'molstar/lib/mol-math/geometry.js';
|
|
16
|
+
import { Vec3 } from 'molstar/lib/mol-math/linear-algebra.js';
|
|
17
|
+
import type { PluginContext } from 'molstar/lib/mol-plugin/context.js';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
DEFAULT_CAMERA_DURATION,
|
|
21
|
+
FRAMING_MARGIN,
|
|
22
|
+
MINIMUM_FRAMING_RADIUS,
|
|
23
|
+
framedRadius,
|
|
24
|
+
} from './camera.ts';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Frame everything on screen.
|
|
28
|
+
*
|
|
29
|
+
* Without an orientation the camera keeps the direction it already points in,
|
|
30
|
+
* which is what a reframe after a reader turned the scene must do. A scene with
|
|
31
|
+
* nothing measured is framed by molstar's own reset.
|
|
32
|
+
* @param plugin - The molstar context.
|
|
33
|
+
* @param options - What to frame, from where, and how fast.
|
|
34
|
+
*/
|
|
35
|
+
export function resetCamera(
|
|
36
|
+
plugin: PluginContext,
|
|
37
|
+
options: ResetCameraOptions = {},
|
|
38
|
+
): void {
|
|
39
|
+
const { durationMs = DEFAULT_CAMERA_DURATION, margin = FRAMING_MARGIN } =
|
|
40
|
+
options;
|
|
41
|
+
const { sphere, orientation } = options;
|
|
42
|
+
plugin.canvas3d?.commit(true);
|
|
43
|
+
const scene = sphere === undefined ? sceneSphere(plugin, options) : sphere;
|
|
44
|
+
if (scene === null || scene.radius <= 0) {
|
|
45
|
+
plugin.managers.camera.reset(undefined, durationMs);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const { center, radius } = scene;
|
|
49
|
+
const [x = 0, y = 0, z = 0] = center;
|
|
50
|
+
focusPoint(plugin, [x, y, z], framedRadius(radius, margin), {
|
|
51
|
+
durationMs,
|
|
52
|
+
orientation,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Frame one ball of the scene: an atom picked, the centre of a bond, the
|
|
58
|
+
* whole scene.
|
|
59
|
+
*
|
|
60
|
+
* The canvas is committed first — `add()` only queues, and a queued object
|
|
61
|
+
* belongs to no bounding sphere yet — and the ball is framed with no padding
|
|
62
|
+
* of molstar's own, whose 4 Å default leaves water a twentieth of the canvas.
|
|
63
|
+
* @param plugin - The molstar context.
|
|
64
|
+
* @param centre - What to frame, Cartesian ångström.
|
|
65
|
+
* @param radius - Radius of the ball to fit, ångström.
|
|
66
|
+
* @param options - From where, and how fast.
|
|
67
|
+
*/
|
|
68
|
+
export function focusPoint(
|
|
69
|
+
plugin: PluginContext,
|
|
70
|
+
centre: Point3,
|
|
71
|
+
radius: number,
|
|
72
|
+
options: FocusOptions = {},
|
|
73
|
+
): void {
|
|
74
|
+
const { durationMs = DEFAULT_CAMERA_DURATION, orientation } = options;
|
|
75
|
+
plugin.canvas3d?.commit(true);
|
|
76
|
+
const target = Vec3.create(centre[0], centre[1], centre[2]);
|
|
77
|
+
const camera = plugin.canvas3d?.camera;
|
|
78
|
+
if (orientation !== undefined && camera !== undefined) {
|
|
79
|
+
// `getFocus` only matches the sign of a direction against the current
|
|
80
|
+
// camera; `getInvariantFocus` takes the direction and the up as given.
|
|
81
|
+
const { eye, up } = orientation;
|
|
82
|
+
plugin.managers.camera.setSnapshot(
|
|
83
|
+
camera.getInvariantFocus(
|
|
84
|
+
target,
|
|
85
|
+
Math.max(radius, MINIMUM_FRAMING_RADIUS),
|
|
86
|
+
Vec3.create(up[0], up[1], up[2]),
|
|
87
|
+
Vec3.create(-eye[0], -eye[1], -eye[2]),
|
|
88
|
+
),
|
|
89
|
+
durationMs,
|
|
90
|
+
);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
plugin.managers.camera.focusSphere(Sphere3D.create(target, radius), {
|
|
94
|
+
extraRadius: 0,
|
|
95
|
+
minRadius: MINIMUM_FRAMING_RADIUS,
|
|
96
|
+
durationMs,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The one sphere everything worth framing fits in: the spheres a site
|
|
102
|
+
* measured itself, and those of the render objects it names.
|
|
103
|
+
* @param plugin - The molstar context.
|
|
104
|
+
* @param options - The measured spheres, and which render objects count.
|
|
105
|
+
* @returns The sphere, or `null` when nothing was measured.
|
|
106
|
+
*/
|
|
107
|
+
export function sceneSphere(
|
|
108
|
+
plugin: PluginContext,
|
|
109
|
+
options: SceneSphereOptions = {},
|
|
110
|
+
): Sphere3D | null {
|
|
111
|
+
const spheres: Sphere3D[] = [];
|
|
112
|
+
for (const sphere of options.spheres ?? []) {
|
|
113
|
+
if (sphere.radius > 0) spheres.push(sphere);
|
|
114
|
+
}
|
|
115
|
+
const { include } = options;
|
|
116
|
+
const canvas3d = plugin.canvas3d;
|
|
117
|
+
if (include !== undefined && canvas3d !== undefined) {
|
|
118
|
+
canvas3d.commit(true);
|
|
119
|
+
for (const object of canvas3d.getRenderObjects()) {
|
|
120
|
+
if (!include(object)) continue;
|
|
121
|
+
const sphere = object.values.boundingSphere.ref.value;
|
|
122
|
+
if (sphere.radius > 0) spheres.push(sphere);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return unionSphere(spheres);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The smallest sphere holding a set of spheres, as molstar's own camera
|
|
130
|
+
* manager computes it.
|
|
131
|
+
* @param spheres - The spheres to hold.
|
|
132
|
+
* @returns It, the one sphere itself when there is one, `null` when there is none.
|
|
133
|
+
*/
|
|
134
|
+
export function unionSphere(spheres: readonly Sphere3D[]): Sphere3D | null {
|
|
135
|
+
const first = spheres[0];
|
|
136
|
+
if (first === undefined) return null;
|
|
137
|
+
if (spheres.length === 1) return first;
|
|
138
|
+
boundary.reset();
|
|
139
|
+
for (const sphere of spheres) boundary.includeSphere(sphere);
|
|
140
|
+
boundary.finishedIncludeStep();
|
|
141
|
+
for (const sphere of spheres) boundary.radiusSphere(sphere);
|
|
142
|
+
return boundary.getSphere();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** A point in Cartesian ångström. */
|
|
146
|
+
export type Point3 = readonly [x: number, y: number, z: number];
|
|
147
|
+
|
|
148
|
+
/** Where the camera stands to look at a scene. */
|
|
149
|
+
export interface ViewOrientation {
|
|
150
|
+
/** The direction from what is looked at to the eye. */
|
|
151
|
+
eye: Point3;
|
|
152
|
+
/** The direction that is up on screen. */
|
|
153
|
+
up: Point3;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** How {@link focusPoint} moves the camera. */
|
|
157
|
+
export interface FocusOptions {
|
|
158
|
+
/**
|
|
159
|
+
* Transition length, in milliseconds; 0 jumps.
|
|
160
|
+
* @default 250
|
|
161
|
+
*/
|
|
162
|
+
durationMs?: number;
|
|
163
|
+
/**
|
|
164
|
+
* Where to look from.
|
|
165
|
+
* @default undefined — the direction the camera already points in
|
|
166
|
+
*/
|
|
167
|
+
orientation?: ViewOrientation;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** What {@link sceneSphere} measures. */
|
|
171
|
+
export interface SceneSphereOptions {
|
|
172
|
+
/**
|
|
173
|
+
* Spheres the site measured itself: a model from its own atoms, a part of
|
|
174
|
+
* the scene registered as it was drawn.
|
|
175
|
+
* @default []
|
|
176
|
+
*/
|
|
177
|
+
spheres?: readonly Sphere3D[];
|
|
178
|
+
/**
|
|
179
|
+
* Which render objects of the canvas count with their own sphere.
|
|
180
|
+
* @default undefined — none does
|
|
181
|
+
*/
|
|
182
|
+
include?: (object: GraphicsRenderObject) => boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** What {@link resetCamera} frames, and how. */
|
|
186
|
+
export interface ResetCameraOptions extends SceneSphereOptions, FocusOptions {
|
|
187
|
+
/**
|
|
188
|
+
* The sphere to frame, measured by the caller, instead of the scene's.
|
|
189
|
+
* @default undefined — the sphere `sceneSphere` measures
|
|
190
|
+
*/
|
|
191
|
+
sphere?: Sphere3D | null;
|
|
192
|
+
/**
|
|
193
|
+
* Fraction of the radius kept as breathing room around the scene.
|
|
194
|
+
* @default 0.08
|
|
195
|
+
*/
|
|
196
|
+
margin?: number;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Reused across calls, as molstar's own camera manager does.
|
|
200
|
+
const boundary = new BoundaryHelper('98');
|
|
@@ -38,6 +38,32 @@ export function subscribeHover(
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/** What the pointer rests on, in a line, and the loci it names. */
|
|
42
|
+
export interface HoverLabel {
|
|
43
|
+
/** `O 1`, `Si 4 — O 8`, or the label a drawing of the site carries. */
|
|
44
|
+
label: string;
|
|
45
|
+
/** The loci, for a site that wants more of it — the atom it holds, say. */
|
|
46
|
+
loci: Loci;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Report the label of whatever the pointer rests on: an atom named as a
|
|
51
|
+
* reader would name it, anything else by the label it was drawn with.
|
|
52
|
+
* @param plugin - The molstar context.
|
|
53
|
+
* @param listener - Called with the label and its loci, or `null` when the
|
|
54
|
+
* pointer leaves everything or rests on something with nothing to say.
|
|
55
|
+
* @returns The unsubscribe function.
|
|
56
|
+
*/
|
|
57
|
+
export function subscribeHoverLabel(
|
|
58
|
+
plugin: PluginContext,
|
|
59
|
+
listener: (hover: HoverLabel | null) => void,
|
|
60
|
+
): () => void {
|
|
61
|
+
return subscribeHover(plugin, (loci) => {
|
|
62
|
+
const label = loci === null ? null : (atomText(loci) ?? lociText(loci));
|
|
63
|
+
listener(label === null || loci === null ? null : { label, loci });
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
41
67
|
/**
|
|
42
68
|
* The one line a loci is worth, in molstar's own words.
|
|
43
69
|
* @param loci - What the pointer is over.
|
|
@@ -25,8 +25,28 @@ export {
|
|
|
25
25
|
framedRadius,
|
|
26
26
|
setSpin,
|
|
27
27
|
} from './camera.ts';
|
|
28
|
+
export type {
|
|
29
|
+
FocusOptions,
|
|
30
|
+
Point3,
|
|
31
|
+
ResetCameraOptions,
|
|
32
|
+
SceneSphereOptions,
|
|
33
|
+
ViewOrientation,
|
|
34
|
+
} from './framing.ts';
|
|
35
|
+
export {
|
|
36
|
+
focusPoint,
|
|
37
|
+
resetCamera,
|
|
38
|
+
sceneSphere,
|
|
39
|
+
unionSphere,
|
|
40
|
+
} from './framing.ts';
|
|
28
41
|
export { HighlightPainter, highlightOverpaint } from './highlights.ts';
|
|
29
|
-
export {
|
|
42
|
+
export type { HoverLabel } from './hover.ts';
|
|
43
|
+
export {
|
|
44
|
+
atomName,
|
|
45
|
+
atomText,
|
|
46
|
+
lociText,
|
|
47
|
+
subscribeHover,
|
|
48
|
+
subscribeHoverLabel,
|
|
49
|
+
} from './hover.ts';
|
|
30
50
|
export type { MolstarPluginOptions } from './plugin.ts';
|
|
31
51
|
export { MolstarPlugin } from './plugin.ts';
|
|
32
52
|
export { captureScene } from './captureScene.ts';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading what a student typed into an answer box, and the verdicts a grader
|
|
3
|
+
* gives a box it cannot grade.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { CHROME_CATALOG } from '../../i18n/core/chromeCatalog.ts';
|
|
7
|
+
import type { Language } from '../../i18n/core/languages.ts';
|
|
8
|
+
import { DEFAULT_LANGUAGE } from '../../i18n/core/languages.ts';
|
|
9
|
+
import { catalogTranslate } from '../../i18n/core/translate.ts';
|
|
10
|
+
import { readNumber } from '../../number/core/numberText.ts';
|
|
11
|
+
|
|
12
|
+
import type { FieldCase } from './series.ts';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Read a number the way a student types it: `42`, `+5`, `−3` with a real minus
|
|
16
|
+
* sign, `1,5` with a decimal comma, `75.8 %`, `1 000`.
|
|
17
|
+
*
|
|
18
|
+
* What a typed answer carries beyond a number box — a typographic minus, a
|
|
19
|
+
* percent sign, a space between thousands — is taken off first; the number
|
|
20
|
+
* itself is read by `readNumber`, as every box of the family reads one.
|
|
21
|
+
* @param text - What was typed.
|
|
22
|
+
* @param integer - Whether only a whole number is an answer.
|
|
23
|
+
* @default integer false
|
|
24
|
+
* @returns The number, or undefined when the text is not one.
|
|
25
|
+
*/
|
|
26
|
+
export function readAnswerNumber(
|
|
27
|
+
text: string,
|
|
28
|
+
integer = false,
|
|
29
|
+
): number | undefined {
|
|
30
|
+
const cleaned = text
|
|
31
|
+
.trim()
|
|
32
|
+
.replaceAll(/[−–]/gu, '-')
|
|
33
|
+
.replace(/\s*%$/u, '')
|
|
34
|
+
.replaceAll(/\s/gu, '');
|
|
35
|
+
return readNumber(cleaned, integer);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Write a signed whole number the way an oxidation state or a charge is
|
|
40
|
+
* written: `+5`, `−2`, `0`.
|
|
41
|
+
* @param value - The number.
|
|
42
|
+
* @returns The number with its sign, and a true minus sign.
|
|
43
|
+
*/
|
|
44
|
+
export function formatSigned(value: number): string {
|
|
45
|
+
if (value > 0) return `+${value}`;
|
|
46
|
+
if (value < 0) return `−${-value}`;
|
|
47
|
+
return '0';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The verdict on a field left empty.
|
|
52
|
+
* @param label - The field, as its box labels it.
|
|
53
|
+
* @param what - What the box asks for, e.g. `a number of electrons`.
|
|
54
|
+
* @param language - The language the reason is written in.
|
|
55
|
+
* @default language 'en'
|
|
56
|
+
* @returns A failed case that says what to type.
|
|
57
|
+
*/
|
|
58
|
+
export function emptyCase(
|
|
59
|
+
label: string,
|
|
60
|
+
what: string,
|
|
61
|
+
language: Language = DEFAULT_LANGUAGE,
|
|
62
|
+
): FieldCase {
|
|
63
|
+
const t = catalogTranslate(CHROME_CATALOG, language);
|
|
64
|
+
return {
|
|
65
|
+
label,
|
|
66
|
+
passed: false,
|
|
67
|
+
reason: t('pedagogy.answerEmpty', { what }),
|
|
68
|
+
actual: null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The verdict on a field that does not read as the kind of value it asks for.
|
|
74
|
+
* @param label - The field, as its box labels it.
|
|
75
|
+
* @param typed - What was typed.
|
|
76
|
+
* @param what - What the box asks for, e.g. `a whole number`.
|
|
77
|
+
* @param language - The language the reason is written in.
|
|
78
|
+
* @default language 'en'
|
|
79
|
+
* @returns A failed case quoting what was typed.
|
|
80
|
+
*/
|
|
81
|
+
export function unreadableCase(
|
|
82
|
+
label: string,
|
|
83
|
+
typed: string,
|
|
84
|
+
what: string,
|
|
85
|
+
language: Language = DEFAULT_LANGUAGE,
|
|
86
|
+
): FieldCase {
|
|
87
|
+
const t = catalogTranslate(CHROME_CATALOG, language);
|
|
88
|
+
return {
|
|
89
|
+
label,
|
|
90
|
+
passed: false,
|
|
91
|
+
reason: t('pedagogy.answerUnreadable', { typed: typed.trim(), what }),
|
|
92
|
+
actual: typed,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far a student has got on a graded series, kept in this browser.
|
|
3
|
+
*
|
|
4
|
+
* Best effort and never a precondition: a framed page whose storage is
|
|
5
|
+
* partitioned still works, it just forgets. An attempt is keyed by tool, series
|
|
6
|
+
* and question, so a new series starts clean and a shared link reopens its own.
|
|
7
|
+
* The store is a plain subscribable value, so a page reads it with React's
|
|
8
|
+
* `useSyncExternalStore` or from a signal of its own, and the series components
|
|
9
|
+
* re-render on it without knowing which.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { persistBucket } from '../../state/core/persistBucket.ts';
|
|
13
|
+
|
|
14
|
+
import type { ProgressRecords, ProgressStore } from './progress.ts';
|
|
15
|
+
import { localStorageProgressStore } from './progress.ts';
|
|
16
|
+
import type { ExerciseStatus } from './types.ts';
|
|
17
|
+
|
|
18
|
+
/** One question as the student left it. */
|
|
19
|
+
export interface Attempt {
|
|
20
|
+
/** Where the student stands on it. */
|
|
21
|
+
status: ExerciseStatus;
|
|
22
|
+
/** What was typed, or drawn, field by field. */
|
|
23
|
+
answers: Record<string, string>;
|
|
24
|
+
/** The answers as they were when last checked, so a change hides the verdict. */
|
|
25
|
+
checked: string | null;
|
|
26
|
+
/** How many hints of the ladder are open. */
|
|
27
|
+
hintsRevealed: number;
|
|
28
|
+
/** Whether the worked answer is on screen. */
|
|
29
|
+
showSolution: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* What a question looks like before anything is typed into it.
|
|
34
|
+
* @returns A fresh attempt.
|
|
35
|
+
*/
|
|
36
|
+
export function emptyAttempt(): Attempt {
|
|
37
|
+
return {
|
|
38
|
+
status: 'idle',
|
|
39
|
+
answers: {},
|
|
40
|
+
checked: null,
|
|
41
|
+
hintsRevealed: 0,
|
|
42
|
+
showSolution: false,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The key an attempt is kept under.
|
|
48
|
+
* @param tool - The tool.
|
|
49
|
+
* @param seed - The series.
|
|
50
|
+
* @param question - The question's key in the tool's pool.
|
|
51
|
+
* @returns `tool/seed/question`.
|
|
52
|
+
*/
|
|
53
|
+
export function attemptKey(
|
|
54
|
+
tool: string,
|
|
55
|
+
seed: number,
|
|
56
|
+
question: string,
|
|
57
|
+
): string {
|
|
58
|
+
return `${tool}/${seed}/${question}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** What {@link createAttemptStore} is built from. */
|
|
62
|
+
export interface AttemptStoreOptions {
|
|
63
|
+
/**
|
|
64
|
+
* The site, which namespaces both entries: `atoms` keeps its attempts under
|
|
65
|
+
* `atoms:attempts:v1` and the series each tool was last on under
|
|
66
|
+
* `atoms:seeds:v1`.
|
|
67
|
+
*/
|
|
68
|
+
key: string;
|
|
69
|
+
/**
|
|
70
|
+
* Where the attempts are kept, for a course that keeps them itself.
|
|
71
|
+
* @default the browser's `localStorage`, under `<key>:attempts:v1`
|
|
72
|
+
*/
|
|
73
|
+
binding?: ProgressStore<Attempt>;
|
|
74
|
+
/**
|
|
75
|
+
* Called when a save was refused because the store is full.
|
|
76
|
+
* @default undefined
|
|
77
|
+
*/
|
|
78
|
+
onQuotaExceeded?: (error: unknown) => void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The attempts of a site, and the series each of its tools was last on. */
|
|
82
|
+
export interface AttemptStore {
|
|
83
|
+
/** Every attempt this browser remembers; a new object after each change. */
|
|
84
|
+
records: () => ProgressRecords<Attempt>;
|
|
85
|
+
/** Be told after each change; returns the function that stops it. */
|
|
86
|
+
subscribe: (listener: () => void) => () => void;
|
|
87
|
+
/** One question's attempt, or a fresh one. */
|
|
88
|
+
attemptFor: (key: string) => Attempt;
|
|
89
|
+
/** Change one attempt and keep it. */
|
|
90
|
+
updateAttempt: (key: string, change: Partial<Attempt>) => void;
|
|
91
|
+
/** Forget the attempts of some questions. */
|
|
92
|
+
clearAttempts: (keys: readonly string[]) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Forget every series of a tool but one, so storage does not grow with every
|
|
95
|
+
* new series drawn.
|
|
96
|
+
*/
|
|
97
|
+
forgetOtherSeries: (tool: string, seed: number) => void;
|
|
98
|
+
/** The series a tool was last on in this browser, or null. */
|
|
99
|
+
storedSeed: (tool: string) => number | null;
|
|
100
|
+
/** Remember the series a tool is on. */
|
|
101
|
+
storeSeed: (tool: string, seed: number) => void;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The attempts of a site's graded series, kept in this browser.
|
|
106
|
+
* @param options - The site's namespace, and where else to keep them.
|
|
107
|
+
* @returns The store.
|
|
108
|
+
*/
|
|
109
|
+
export function createAttemptStore(options: AttemptStoreOptions): AttemptStore {
|
|
110
|
+
const { key, onQuotaExceeded } = options;
|
|
111
|
+
const binding =
|
|
112
|
+
options.binding ??
|
|
113
|
+
localStorageProgressStore<Attempt>({
|
|
114
|
+
key: `${key}:attempts`,
|
|
115
|
+
version: 1,
|
|
116
|
+
defaults: emptyAttempt(),
|
|
117
|
+
onQuotaExceeded,
|
|
118
|
+
});
|
|
119
|
+
const seeds = persistBucket<Record<string, number>>({
|
|
120
|
+
key: `${key}:seeds`,
|
|
121
|
+
version: 1,
|
|
122
|
+
defaults: {},
|
|
123
|
+
onQuotaExceeded,
|
|
124
|
+
});
|
|
125
|
+
const listeners = new Set<() => void>();
|
|
126
|
+
let current: ProgressRecords<Attempt> = {};
|
|
127
|
+
// Kept in memory as well, so a framed page whose storage is blocked still
|
|
128
|
+
// reopens the series it is on for as long as it stays open.
|
|
129
|
+
let seedsByTool = seeds.read().value;
|
|
130
|
+
|
|
131
|
+
function publish(next: ProgressRecords<Attempt>, save: boolean): void {
|
|
132
|
+
current = next;
|
|
133
|
+
if (save) void binding.save(next);
|
|
134
|
+
for (const listener of listeners) listener();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const loaded = binding.load();
|
|
138
|
+
if (loaded instanceof Promise) {
|
|
139
|
+
void loaded.then(
|
|
140
|
+
(records) => {
|
|
141
|
+
publish(records, false);
|
|
142
|
+
},
|
|
143
|
+
() => {
|
|
144
|
+
// A binding that cannot answer leaves the page working from nothing.
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
} else {
|
|
148
|
+
current = loaded;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function attemptFor(attempt: string): Attempt {
|
|
152
|
+
return current[attempt] ?? emptyAttempt();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
records: () => current,
|
|
157
|
+
subscribe(listener) {
|
|
158
|
+
listeners.add(listener);
|
|
159
|
+
return () => {
|
|
160
|
+
listeners.delete(listener);
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
attemptFor,
|
|
164
|
+
updateAttempt(attempt, change) {
|
|
165
|
+
publish(
|
|
166
|
+
{ ...current, [attempt]: { ...attemptFor(attempt), ...change } },
|
|
167
|
+
true,
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
clearAttempts(keys) {
|
|
171
|
+
const cleared = new Set(keys);
|
|
172
|
+
publish(
|
|
173
|
+
keep(current, (attempt) => !cleared.has(attempt)),
|
|
174
|
+
true,
|
|
175
|
+
);
|
|
176
|
+
},
|
|
177
|
+
forgetOtherSeries(tool, seed) {
|
|
178
|
+
const kept = `${tool}/${seed}/`;
|
|
179
|
+
publish(
|
|
180
|
+
keep(
|
|
181
|
+
current,
|
|
182
|
+
(attempt) =>
|
|
183
|
+
!attempt.startsWith(`${tool}/`) || attempt.startsWith(kept),
|
|
184
|
+
),
|
|
185
|
+
true,
|
|
186
|
+
);
|
|
187
|
+
},
|
|
188
|
+
storedSeed: (tool) => seedsByTool[tool] ?? null,
|
|
189
|
+
storeSeed(tool, seed) {
|
|
190
|
+
seedsByTool = { ...seedsByTool, [tool]: seed };
|
|
191
|
+
seeds.write(seedsByTool);
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function keep(
|
|
197
|
+
records: ProgressRecords<Attempt>,
|
|
198
|
+
wanted: (key: string) => boolean,
|
|
199
|
+
): ProgressRecords<Attempt> {
|
|
200
|
+
const next: ProgressRecords<Attempt> = {};
|
|
201
|
+
for (const [key, attempt] of Object.entries(records)) {
|
|
202
|
+
if (wanted(key)) next[key] = attempt;
|
|
203
|
+
}
|
|
204
|
+
return next;
|
|
205
|
+
}
|
|
@@ -40,3 +40,39 @@ export type {
|
|
|
40
40
|
ValidationResult,
|
|
41
41
|
} from './validation.ts';
|
|
42
42
|
export { failedValidation, finishValidation } from './validation.ts';
|
|
43
|
+
export {
|
|
44
|
+
emptyCase,
|
|
45
|
+
formatSigned,
|
|
46
|
+
readAnswerNumber,
|
|
47
|
+
unreadableCase,
|
|
48
|
+
} from './answers.ts';
|
|
49
|
+
export type { Attempt, AttemptStore, AttemptStoreOptions } from './attempts.ts';
|
|
50
|
+
export { attemptKey, createAttemptStore, emptyAttempt } from './attempts.ts';
|
|
51
|
+
export type {
|
|
52
|
+
ControlledProgress,
|
|
53
|
+
ProgressController,
|
|
54
|
+
ProgressControllerOptions,
|
|
55
|
+
ProgressSignal,
|
|
56
|
+
} from './progressController.ts';
|
|
57
|
+
export { createProgressController } from './progressController.ts';
|
|
58
|
+
export type {
|
|
59
|
+
PickSeededOptions,
|
|
60
|
+
SeedDraw,
|
|
61
|
+
SeedRange,
|
|
62
|
+
SeedValue,
|
|
63
|
+
} from './seed.ts';
|
|
64
|
+
export {
|
|
65
|
+
EACH_SEED,
|
|
66
|
+
LARGEST_SEED,
|
|
67
|
+
freshSeed,
|
|
68
|
+
parseSeed,
|
|
69
|
+
pickSeeded,
|
|
70
|
+
seedParam,
|
|
71
|
+
} from './seed.ts';
|
|
72
|
+
export type {
|
|
73
|
+
AnswerCheck,
|
|
74
|
+
AnswerField,
|
|
75
|
+
Answers,
|
|
76
|
+
FieldCase,
|
|
77
|
+
SeriesTool,
|
|
78
|
+
} from './series.ts';
|