react-cheminfo 0.64.0 → 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.
Files changed (640) hide show
  1. package/README.md +282 -0
  2. package/lib/card/core/cardAddress.d.ts +70 -0
  3. package/lib/card/core/cardAddress.d.ts.map +1 -0
  4. package/lib/card/core/cardAddress.js +59 -0
  5. package/lib/card/core/cardAddress.js.map +1 -0
  6. package/lib/card/core/cardPageUrl.d.ts +49 -0
  7. package/lib/card/core/cardPageUrl.d.ts.map +1 -0
  8. package/lib/card/core/cardPageUrl.js +59 -0
  9. package/lib/card/core/cardPageUrl.js.map +1 -0
  10. package/lib/card/core/index.d.ts +7 -0
  11. package/lib/card/core/index.d.ts.map +1 -0
  12. package/lib/card/core/index.js +4 -0
  13. package/lib/card/core/index.js.map +1 -0
  14. package/lib/card/core/panelRoom.d.ts +40 -0
  15. package/lib/card/core/panelRoom.d.ts.map +1 -0
  16. package/lib/card/core/panelRoom.js +40 -0
  17. package/lib/card/core/panelRoom.js.map +1 -0
  18. package/lib/card/ui/CardDetailsButton.d.ts +38 -0
  19. package/lib/card/ui/CardDetailsButton.d.ts.map +1 -0
  20. package/lib/card/ui/CardDetailsButton.js +50 -0
  21. package/lib/card/ui/CardDetailsButton.js.map +1 -0
  22. package/lib/card/ui/CardFigure.d.ts +51 -0
  23. package/lib/card/ui/CardFigure.d.ts.map +1 -0
  24. package/lib/card/ui/CardFigure.js +27 -0
  25. package/lib/card/ui/CardFigure.js.map +1 -0
  26. package/lib/card/ui/CardFrame.d.ts +30 -0
  27. package/lib/card/ui/CardFrame.d.ts.map +1 -0
  28. package/lib/card/ui/CardFrame.js +20 -0
  29. package/lib/card/ui/CardFrame.js.map +1 -0
  30. package/lib/card/ui/CopyTableButton.d.ts +37 -0
  31. package/lib/card/ui/CopyTableButton.d.ts.map +1 -0
  32. package/lib/card/ui/CopyTableButton.js +19 -0
  33. package/lib/card/ui/CopyTableButton.js.map +1 -0
  34. package/lib/card/ui/cardTooltip.d.ts +14 -0
  35. package/lib/card/ui/cardTooltip.d.ts.map +1 -0
  36. package/lib/card/ui/cardTooltip.js +15 -0
  37. package/lib/card/ui/cardTooltip.js.map +1 -0
  38. package/lib/card/ui/embed.d.ts +15 -0
  39. package/lib/card/ui/embed.d.ts.map +1 -0
  40. package/lib/card/ui/embed.js +24 -0
  41. package/lib/card/ui/embed.js.map +1 -0
  42. package/lib/card/ui/fitCardToFrame.d.ts +31 -0
  43. package/lib/card/ui/fitCardToFrame.d.ts.map +1 -0
  44. package/lib/card/ui/fitCardToFrame.js +66 -0
  45. package/lib/card/ui/fitCardToFrame.js.map +1 -0
  46. package/lib/card/ui/holdRoomForPanels.d.ts +16 -0
  47. package/lib/card/ui/holdRoomForPanels.d.ts.map +1 -0
  48. package/lib/card/ui/holdRoomForPanels.js +76 -0
  49. package/lib/card/ui/holdRoomForPanels.js.map +1 -0
  50. package/lib/card/ui/index.d.ts +11 -0
  51. package/lib/card/ui/index.d.ts.map +1 -0
  52. package/lib/card/ui/index.js +7 -0
  53. package/lib/card/ui/index.js.map +1 -0
  54. package/lib/card/ui/openPanels.d.ts +25 -0
  55. package/lib/card/ui/openPanels.d.ts.map +1 -0
  56. package/lib/card/ui/openPanels.js +85 -0
  57. package/lib/card/ui/openPanels.js.map +1 -0
  58. package/lib/card.d.ts +13 -0
  59. package/lib/card.d.ts.map +1 -0
  60. package/lib/card.js +13 -0
  61. package/lib/card.js.map +1 -0
  62. package/lib/conformers.d.ts +1 -0
  63. package/lib/conformers.d.ts.map +1 -1
  64. package/lib/conformers.js +1 -0
  65. package/lib/conformers.js.map +1 -1
  66. package/lib/core.d.ts +4 -0
  67. package/lib/core.d.ts.map +1 -1
  68. package/lib/core.js +5 -0
  69. package/lib/core.js.map +1 -1
  70. package/lib/fetch/core/apiError.d.ts +56 -0
  71. package/lib/fetch/core/apiError.d.ts.map +1 -0
  72. package/lib/fetch/core/apiError.js +43 -0
  73. package/lib/fetch/core/apiError.js.map +1 -0
  74. package/lib/fetch/core/fetchJson.d.ts +47 -0
  75. package/lib/fetch/core/fetchJson.d.ts.map +1 -0
  76. package/lib/fetch/core/fetchJson.js +109 -0
  77. package/lib/fetch/core/fetchJson.js.map +1 -0
  78. package/lib/fetch/core/index.d.ts +5 -0
  79. package/lib/fetch/core/index.d.ts.map +1 -0
  80. package/lib/fetch/core/index.js +3 -0
  81. package/lib/fetch/core/index.js.map +1 -0
  82. package/lib/formula/core/formulaText.d.ts +46 -0
  83. package/lib/formula/core/formulaText.d.ts.map +1 -0
  84. package/lib/formula/core/formulaText.js +74 -0
  85. package/lib/formula/core/formulaText.js.map +1 -0
  86. package/lib/formula/core/index.d.ts +6 -0
  87. package/lib/formula/core/index.d.ts.map +1 -0
  88. package/lib/formula/core/index.js +4 -0
  89. package/lib/formula/core/index.js.map +1 -0
  90. package/lib/formula/core/normalizeFormula.d.ts +22 -0
  91. package/lib/formula/core/normalizeFormula.d.ts.map +1 -0
  92. package/lib/formula/core/normalizeFormula.js +46 -0
  93. package/lib/formula/core/normalizeFormula.js.map +1 -0
  94. package/lib/formula/core/readFormula.d.ts +73 -0
  95. package/lib/formula/core/readFormula.d.ts.map +1 -0
  96. package/lib/formula/core/readFormula.js +132 -0
  97. package/lib/formula/core/readFormula.js.map +1 -0
  98. package/lib/formula/ui/CopyableFormula.d.ts +31 -0
  99. package/lib/formula/ui/CopyableFormula.d.ts.map +1 -0
  100. package/lib/formula/ui/CopyableFormula.js +19 -0
  101. package/lib/formula/ui/CopyableFormula.js.map +1 -0
  102. package/lib/formula/ui/FormulaInput.d.ts +29 -0
  103. package/lib/formula/ui/FormulaInput.d.ts.map +1 -0
  104. package/lib/formula/ui/FormulaInput.js +16 -0
  105. package/lib/formula/ui/FormulaInput.js.map +1 -0
  106. package/lib/formula/ui/QuestionFormula.d.ts +14 -0
  107. package/lib/formula/ui/QuestionFormula.d.ts.map +1 -0
  108. package/lib/formula/ui/QuestionFormula.js +13 -0
  109. package/lib/formula/ui/QuestionFormula.js.map +1 -0
  110. package/lib/formula/ui/index.d.ts +7 -0
  111. package/lib/formula/ui/index.d.ts.map +1 -0
  112. package/lib/formula/ui/index.js +4 -0
  113. package/lib/formula/ui/index.js.map +1 -0
  114. package/lib/formula.d.ts +11 -0
  115. package/lib/formula.d.ts.map +1 -0
  116. package/lib/formula.js +11 -0
  117. package/lib/formula.js.map +1 -0
  118. package/lib/hooks/ui/index.d.ts +1 -0
  119. package/lib/hooks/ui/index.d.ts.map +1 -1
  120. package/lib/hooks/ui/index.js.map +1 -1
  121. package/lib/hooks/ui/keyTargets.d.ts +4 -2
  122. package/lib/hooks/ui/keyTargets.d.ts.map +1 -1
  123. package/lib/hooks/ui/keyTargets.js +5 -3
  124. package/lib/hooks/ui/keyTargets.js.map +1 -1
  125. package/lib/hooks/ui/useAsync.d.ts +20 -5
  126. package/lib/hooks/ui/useAsync.d.ts.map +1 -1
  127. package/lib/hooks/ui/useAsync.js +29 -14
  128. package/lib/hooks/ui/useAsync.js.map +1 -1
  129. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  130. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  131. package/lib/locales/de.json +37 -0
  132. package/lib/locales/en.json +37 -0
  133. package/lib/locales/es.json +37 -0
  134. package/lib/locales/fr.json +37 -0
  135. package/lib/locales/it.json +37 -0
  136. package/lib/molecule3d/core/highlight.d.ts.map +1 -1
  137. package/lib/molecule3d/core/highlight.js +2 -8
  138. package/lib/molecule3d/core/highlight.js.map +1 -1
  139. package/lib/molecule3d/core/index.d.ts +1 -1
  140. package/lib/molecule3d/core/index.d.ts.map +1 -1
  141. package/lib/molecule3d/core/index.js +1 -1
  142. package/lib/molecule3d/core/index.js.map +1 -1
  143. package/lib/molecule3d/core/measurement.d.ts +17 -0
  144. package/lib/molecule3d/core/measurement.d.ts.map +1 -1
  145. package/lib/molecule3d/core/measurement.js +43 -0
  146. package/lib/molecule3d/core/measurement.js.map +1 -1
  147. package/lib/molecule3d/ui/drawScene.d.ts +4 -2
  148. package/lib/molecule3d/ui/drawScene.d.ts.map +1 -1
  149. package/lib/molecule3d/ui/drawScene.js +1 -1
  150. package/lib/molecule3d/ui/drawScene.js.map +1 -1
  151. package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts +3 -1
  152. package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts.map +1 -1
  153. package/lib/molecule3d/ui/sceneDrawer.d.ts +47 -0
  154. package/lib/molecule3d/ui/sceneDrawer.d.ts.map +1 -0
  155. package/lib/molecule3d/ui/sceneDrawer.js +103 -0
  156. package/lib/molecule3d/ui/sceneDrawer.js.map +1 -0
  157. package/lib/molecule3d/ui/useMoleculeScene.d.ts +2 -1
  158. package/lib/molecule3d/ui/useMoleculeScene.d.ts.map +1 -1
  159. package/lib/molecule3d/ui/useMoleculeScene.js +13 -22
  160. package/lib/molecule3d/ui/useMoleculeScene.js.map +1 -1
  161. package/lib/molecule3d/ui/useSharedCamera.d.ts +1 -3
  162. package/lib/molecule3d/ui/useSharedCamera.d.ts.map +1 -1
  163. package/lib/molecule3d/ui/useSharedCamera.js.map +1 -1
  164. package/lib/moleculesClient/core/index.d.ts +5 -0
  165. package/lib/moleculesClient/core/index.d.ts.map +1 -0
  166. package/lib/moleculesClient/core/index.js +3 -0
  167. package/lib/moleculesClient/core/index.js.map +1 -0
  168. package/lib/moleculesClient/core/moleculesClient.d.ts +12 -0
  169. package/lib/moleculesClient/core/moleculesClient.d.ts.map +1 -0
  170. package/lib/moleculesClient/core/moleculesClient.js +105 -0
  171. package/lib/moleculesClient/core/moleculesClient.js.map +1 -0
  172. package/lib/moleculesClient/core/moleculesClientApi.d.ts +100 -0
  173. package/lib/moleculesClient/core/moleculesClientApi.d.ts.map +1 -0
  174. package/lib/moleculesClient/core/moleculesClientApi.js +20 -0
  175. package/lib/moleculesClient/core/moleculesClientApi.js.map +1 -0
  176. package/lib/moleculesClient/core/moleculesTypes.d.ts +154 -0
  177. package/lib/moleculesClient/core/moleculesTypes.d.ts.map +1 -0
  178. package/lib/moleculesClient/core/moleculesTypes.js +2 -0
  179. package/lib/moleculesClient/core/moleculesTypes.js.map +1 -0
  180. package/lib/moleculesClient/core/requestRetry.d.ts +50 -0
  181. package/lib/moleculesClient/core/requestRetry.d.ts.map +1 -0
  182. package/lib/moleculesClient/core/requestRetry.js +108 -0
  183. package/lib/moleculesClient/core/requestRetry.js.map +1 -0
  184. package/lib/molstar/core/camera.d.ts +2 -1
  185. package/lib/molstar/core/camera.d.ts.map +1 -1
  186. package/lib/molstar/core/camera.js +3 -2
  187. package/lib/molstar/core/camera.js.map +1 -1
  188. package/lib/molstar/core/framing.d.ts +102 -0
  189. package/lib/molstar/core/framing.d.ts.map +1 -0
  190. package/lib/molstar/core/framing.js +120 -0
  191. package/lib/molstar/core/framing.js.map +1 -0
  192. package/lib/molstar/core/hover.d.ts +16 -0
  193. package/lib/molstar/core/hover.d.ts.map +1 -1
  194. package/lib/molstar/core/hover.js +14 -0
  195. package/lib/molstar/core/hover.js.map +1 -1
  196. package/lib/molstar/core/index.d.ts +4 -1
  197. package/lib/molstar/core/index.d.ts.map +1 -1
  198. package/lib/molstar/core/index.js +2 -1
  199. package/lib/molstar/core/index.js.map +1 -1
  200. package/lib/pedagogy/core/answers.d.ts +46 -0
  201. package/lib/pedagogy/core/answers.d.ts.map +1 -0
  202. package/lib/pedagogy/core/answers.js +77 -0
  203. package/lib/pedagogy/core/answers.js.map +1 -0
  204. package/lib/pedagogy/core/attempts.d.ts +86 -0
  205. package/lib/pedagogy/core/attempts.d.ts.map +1 -0
  206. package/lib/pedagogy/core/attempts.js +117 -0
  207. package/lib/pedagogy/core/attempts.js.map +1 -0
  208. package/lib/pedagogy/core/index.d.ts +8 -0
  209. package/lib/pedagogy/core/index.d.ts.map +1 -1
  210. package/lib/pedagogy/core/index.js +4 -0
  211. package/lib/pedagogy/core/index.js.map +1 -1
  212. package/lib/pedagogy/core/progressController.d.ts +64 -0
  213. package/lib/pedagogy/core/progressController.d.ts.map +1 -0
  214. package/lib/pedagogy/core/progressController.js +56 -0
  215. package/lib/pedagogy/core/progressController.js.map +1 -0
  216. package/lib/pedagogy/core/seed.d.ts +96 -0
  217. package/lib/pedagogy/core/seed.d.ts.map +1 -0
  218. package/lib/pedagogy/core/seed.js +128 -0
  219. package/lib/pedagogy/core/seed.js.map +1 -0
  220. package/lib/pedagogy/core/series.d.ts +77 -0
  221. package/lib/pedagogy/core/series.d.ts.map +1 -0
  222. package/lib/pedagogy/core/series.js +10 -0
  223. package/lib/pedagogy/core/series.js.map +1 -0
  224. package/lib/pedagogy/ui/AnswerFields.d.ts +21 -0
  225. package/lib/pedagogy/ui/AnswerFields.d.ts.map +1 -0
  226. package/lib/pedagogy/ui/AnswerFields.js +24 -0
  227. package/lib/pedagogy/ui/AnswerFields.js.map +1 -0
  228. package/lib/pedagogy/ui/ExerciseList.d.ts +82 -0
  229. package/lib/pedagogy/ui/ExerciseList.d.ts.map +1 -0
  230. package/lib/pedagogy/ui/ExerciseList.js +53 -0
  231. package/lib/pedagogy/ui/ExerciseList.js.map +1 -0
  232. package/lib/pedagogy/ui/ExerciseSeries.d.ts +95 -0
  233. package/lib/pedagogy/ui/ExerciseSeries.d.ts.map +1 -0
  234. package/lib/pedagogy/ui/ExerciseSeries.js +74 -0
  235. package/lib/pedagogy/ui/ExerciseSeries.js.map +1 -0
  236. package/lib/pedagogy/ui/QuestionCard.d.ts +64 -0
  237. package/lib/pedagogy/ui/QuestionCard.d.ts.map +1 -0
  238. package/lib/pedagogy/ui/QuestionCard.js +73 -0
  239. package/lib/pedagogy/ui/QuestionCard.js.map +1 -0
  240. package/lib/pedagogy/ui/index.d.ts +10 -0
  241. package/lib/pedagogy/ui/index.d.ts.map +1 -1
  242. package/lib/pedagogy/ui/index.js +6 -0
  243. package/lib/pedagogy/ui/index.js.map +1 -1
  244. package/lib/pedagogy/ui/seriesCounts.d.ts +17 -0
  245. package/lib/pedagogy/ui/seriesCounts.d.ts.map +1 -0
  246. package/lib/pedagogy/ui/seriesCounts.js +27 -0
  247. package/lib/pedagogy/ui/seriesCounts.js.map +1 -0
  248. package/lib/pedagogy/ui/seriesParts.d.ts +55 -0
  249. package/lib/pedagogy/ui/seriesParts.d.ts.map +1 -0
  250. package/lib/pedagogy/ui/seriesParts.js +38 -0
  251. package/lib/pedagogy/ui/seriesParts.js.map +1 -0
  252. package/lib/pedagogy/ui/useAttemptRecords.d.ts +10 -0
  253. package/lib/pedagogy/ui/useAttemptRecords.d.ts.map +1 -0
  254. package/lib/pedagogy/ui/useAttemptRecords.js +11 -0
  255. package/lib/pedagogy/ui/useAttemptRecords.js.map +1 -0
  256. package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
  257. package/lib/periodic/ui/PeriodicTable.js +6 -3
  258. package/lib/periodic/ui/PeriodicTable.js.map +1 -1
  259. package/lib/property/core/copyableText.d.ts +14 -0
  260. package/lib/property/core/copyableText.d.ts.map +1 -0
  261. package/lib/property/core/copyableText.js +21 -0
  262. package/lib/property/core/copyableText.js.map +1 -0
  263. package/lib/property/core/index.d.ts +2 -0
  264. package/lib/property/core/index.d.ts.map +1 -0
  265. package/lib/property/core/index.js +2 -0
  266. package/lib/property/core/index.js.map +1 -0
  267. package/lib/property/ui/PropertyTable.d.ts +43 -0
  268. package/lib/property/ui/PropertyTable.d.ts.map +1 -0
  269. package/lib/property/ui/PropertyTable.js +19 -0
  270. package/lib/property/ui/PropertyTable.js.map +1 -0
  271. package/lib/property/ui/index.d.ts +3 -0
  272. package/lib/property/ui/index.d.ts.map +1 -0
  273. package/lib/property/ui/index.js +2 -0
  274. package/lib/property/ui/index.js.map +1 -0
  275. package/lib/router/core/history.d.ts +24 -3
  276. package/lib/router/core/history.d.ts.map +1 -1
  277. package/lib/router/core/history.js +55 -7
  278. package/lib/router/core/history.js.map +1 -1
  279. package/lib/router/core/index.d.ts +3 -3
  280. package/lib/router/core/index.d.ts.map +1 -1
  281. package/lib/router/core/index.js +2 -2
  282. package/lib/router/core/index.js.map +1 -1
  283. package/lib/router/core/languageRoute.d.ts +61 -0
  284. package/lib/router/core/languageRoute.d.ts.map +1 -0
  285. package/lib/router/core/languageRoute.js +96 -0
  286. package/lib/router/core/languageRoute.js.map +1 -0
  287. package/lib/router/core/siteAddresses.d.ts +23 -0
  288. package/lib/router/core/siteAddresses.d.ts.map +1 -1
  289. package/lib/router/core/siteAddresses.js +26 -0
  290. package/lib/router/core/siteAddresses.js.map +1 -1
  291. package/lib/router/core/tabRouter.d.ts +2 -108
  292. package/lib/router/core/tabRouter.d.ts.map +1 -1
  293. package/lib/router/core/tabRouter.js +38 -5
  294. package/lib/router/core/tabRouter.js.map +1 -1
  295. package/lib/router/core/tabRouterTypes.d.ts +154 -0
  296. package/lib/router/core/tabRouterTypes.d.ts.map +1 -0
  297. package/lib/router/core/tabRouterTypes.js +2 -0
  298. package/lib/router/core/tabRouterTypes.js.map +1 -0
  299. package/lib/seo/core/fitDescription.d.ts +40 -0
  300. package/lib/seo/core/fitDescription.d.ts.map +1 -0
  301. package/lib/seo/core/fitDescription.js +45 -0
  302. package/lib/seo/core/fitDescription.js.map +1 -0
  303. package/lib/seo/core/index.d.ts +7 -0
  304. package/lib/seo/core/index.d.ts.map +1 -1
  305. package/lib/seo/core/index.js +4 -0
  306. package/lib/seo/core/index.js.map +1 -1
  307. package/lib/seo/core/limits.d.ts +24 -0
  308. package/lib/seo/core/limits.d.ts.map +1 -0
  309. package/lib/seo/core/limits.js +24 -0
  310. package/lib/seo/core/limits.js.map +1 -0
  311. package/lib/seo/core/pageContent.d.ts +25 -0
  312. package/lib/seo/core/pageContent.d.ts.map +1 -0
  313. package/lib/seo/core/pageContent.js +25 -0
  314. package/lib/seo/core/pageContent.js.map +1 -0
  315. package/lib/seo/core/plainDescription.d.ts.map +1 -1
  316. package/lib/seo/core/plainDescription.js +3 -2
  317. package/lib/seo/core/plainDescription.js.map +1 -1
  318. package/lib/seo/core/routeProblems.d.ts.map +1 -1
  319. package/lib/seo/core/routeProblems.js +1 -6
  320. package/lib/seo/core/routeProblems.js.map +1 -1
  321. package/lib/seo/core/routeTable.d.ts +31 -0
  322. package/lib/seo/core/routeTable.d.ts.map +1 -0
  323. package/lib/seo/core/routeTable.js +96 -0
  324. package/lib/seo/core/routeTable.js.map +1 -0
  325. package/lib/seo/vite/index.d.ts +2 -0
  326. package/lib/seo/vite/index.d.ts.map +1 -1
  327. package/lib/seo/vite/index.js +1 -0
  328. package/lib/seo/vite/index.js.map +1 -1
  329. package/lib/seo/vite/prerender.d.ts +10 -0
  330. package/lib/seo/vite/prerender.d.ts.map +1 -1
  331. package/lib/seo/vite/prerender.js +12 -1
  332. package/lib/seo/vite/prerender.js.map +1 -1
  333. package/lib/seo/vite/routeTable.d.ts +40 -0
  334. package/lib/seo/vite/routeTable.d.ts.map +1 -0
  335. package/lib/seo/vite/routeTable.js +44 -0
  336. package/lib/seo/vite/routeTable.js.map +1 -0
  337. package/lib/server/answerAddresses.d.ts +51 -0
  338. package/lib/server/answerAddresses.d.ts.map +1 -0
  339. package/lib/server/answerAddresses.js +72 -0
  340. package/lib/server/answerAddresses.js.map +1 -0
  341. package/lib/server/cardMeta.d.ts +57 -0
  342. package/lib/server/cardMeta.d.ts.map +1 -0
  343. package/lib/server/cardMeta.js +52 -0
  344. package/lib/server/cardMeta.js.map +1 -0
  345. package/lib/server/config.d.ts +72 -0
  346. package/lib/server/config.d.ts.map +1 -0
  347. package/lib/server/config.js +67 -0
  348. package/lib/server/config.js.map +1 -0
  349. package/lib/server/envNumber.d.ts +35 -0
  350. package/lib/server/envNumber.d.ts.map +1 -0
  351. package/lib/server/envNumber.js +42 -0
  352. package/lib/server/envNumber.js.map +1 -0
  353. package/lib/server/healthRoute.d.ts +26 -0
  354. package/lib/server/healthRoute.d.ts.map +1 -0
  355. package/lib/server/healthRoute.js +22 -0
  356. package/lib/server/healthRoute.js.map +1 -0
  357. package/lib/server/listenSite.d.ts +38 -0
  358. package/lib/server/listenSite.d.ts.map +1 -0
  359. package/lib/server/listenSite.js +60 -0
  360. package/lib/server/listenSite.js.map +1 -0
  361. package/lib/server/mcpServer.d.ts +8 -0
  362. package/lib/server/mcpServer.d.ts.map +1 -0
  363. package/lib/server/mcpServer.js +11 -0
  364. package/lib/server/mcpServer.js.map +1 -0
  365. package/lib/server/repositoryVersion.d.ts +16 -0
  366. package/lib/server/repositoryVersion.d.ts.map +1 -0
  367. package/lib/server/repositoryVersion.js +33 -0
  368. package/lib/server/repositoryVersion.js.map +1 -0
  369. package/lib/server/routeOptions.d.ts +23 -0
  370. package/lib/server/routeOptions.d.ts.map +1 -0
  371. package/lib/server/routeOptions.js +20 -0
  372. package/lib/server/routeOptions.js.map +1 -0
  373. package/lib/server/routeTable.d.ts +14 -0
  374. package/lib/server/routeTable.d.ts.map +1 -0
  375. package/lib/server/routeTable.js +32 -0
  376. package/lib/server/routeTable.js.map +1 -0
  377. package/lib/server/siteView.d.ts +29 -0
  378. package/lib/server/siteView.d.ts.map +1 -0
  379. package/lib/server/siteView.js +21 -0
  380. package/lib/server/siteView.js.map +1 -0
  381. package/lib/server/spaPages.d.ts +32 -0
  382. package/lib/server/spaPages.d.ts.map +1 -0
  383. package/lib/server/spaPages.js +126 -0
  384. package/lib/server/spaPages.js.map +1 -0
  385. package/lib/server/spaSite.d.ts +30 -0
  386. package/lib/server/spaSite.d.ts.map +1 -0
  387. package/lib/server/spaSite.js +170 -0
  388. package/lib/server/spaSite.js.map +1 -0
  389. package/lib/server/spaSiteOptions.d.ts +126 -0
  390. package/lib/server/spaSiteOptions.d.ts.map +1 -0
  391. package/lib/server/spaSiteOptions.js +2 -0
  392. package/lib/server/spaSiteOptions.js.map +1 -0
  393. package/lib/server/staticSite.d.ts +9 -0
  394. package/lib/server/staticSite.d.ts.map +1 -1
  395. package/lib/server/staticSite.js +41 -19
  396. package/lib/server/staticSite.js.map +1 -1
  397. package/lib/server/toolSiteServer.d.ts +77 -0
  398. package/lib/server/toolSiteServer.d.ts.map +1 -0
  399. package/lib/server/toolSiteServer.js +58 -0
  400. package/lib/server/toolSiteServer.js.map +1 -0
  401. package/lib/server/trustProxy.d.ts +20 -0
  402. package/lib/server/trustProxy.d.ts.map +1 -0
  403. package/lib/server/trustProxy.js +32 -0
  404. package/lib/server/trustProxy.js.map +1 -0
  405. package/lib/server/types.d.ts +13 -0
  406. package/lib/server/types.d.ts.map +1 -0
  407. package/lib/server/types.js +2 -0
  408. package/lib/server/types.js.map +1 -0
  409. package/lib/server.d.ts +22 -0
  410. package/lib/server.d.ts.map +1 -1
  411. package/lib/server.js +12 -0
  412. package/lib/server.js.map +1 -1
  413. package/lib/share/core/config.d.ts +18 -0
  414. package/lib/share/core/config.d.ts.map +1 -1
  415. package/lib/share/core/config.js +33 -2
  416. package/lib/share/core/config.js.map +1 -1
  417. package/lib/share/core/index.d.ts +3 -1
  418. package/lib/share/core/index.d.ts.map +1 -1
  419. package/lib/share/core/index.js +2 -1
  420. package/lib/share/core/index.js.map +1 -1
  421. package/lib/share/core/keySetParam.d.ts +40 -0
  422. package/lib/share/core/keySetParam.d.ts.map +1 -0
  423. package/lib/share/core/keySetParam.js +60 -0
  424. package/lib/share/core/keySetParam.js.map +1 -0
  425. package/lib/share/core/vocabulary.d.ts +8 -0
  426. package/lib/share/core/vocabulary.d.ts.map +1 -1
  427. package/lib/shell/ui/ShareControl.d.ts +75 -0
  428. package/lib/shell/ui/ShareControl.d.ts.map +1 -0
  429. package/lib/shell/ui/ShareControl.js +40 -0
  430. package/lib/shell/ui/ShareControl.js.map +1 -0
  431. package/lib/shell/ui/ShellFrame.d.ts +14 -0
  432. package/lib/shell/ui/ShellFrame.d.ts.map +1 -0
  433. package/lib/shell/ui/ShellFrame.js +45 -0
  434. package/lib/shell/ui/ShellFrame.js.map +1 -0
  435. package/lib/shell/ui/SiteShell.d.ts +251 -0
  436. package/lib/shell/ui/SiteShell.d.ts.map +1 -0
  437. package/lib/shell/ui/SiteShell.js +39 -0
  438. package/lib/shell/ui/SiteShell.js.map +1 -0
  439. package/lib/shell/ui/index.d.ts +5 -0
  440. package/lib/shell/ui/index.d.ts.map +1 -0
  441. package/lib/shell/ui/index.js +3 -0
  442. package/lib/shell/ui/index.js.map +1 -0
  443. package/lib/state/core/index.d.ts +1 -0
  444. package/lib/state/core/index.d.ts.map +1 -1
  445. package/lib/state/core/index.js.map +1 -1
  446. package/lib/state/core/legacyEntries.d.ts +30 -0
  447. package/lib/state/core/legacyEntries.d.ts.map +1 -0
  448. package/lib/state/core/legacyEntries.js +51 -0
  449. package/lib/state/core/legacyEntries.js.map +1 -0
  450. package/lib/state/core/persistBucket.d.ts +26 -2
  451. package/lib/state/core/persistBucket.d.ts.map +1 -1
  452. package/lib/state/core/persistBucket.js +26 -9
  453. package/lib/state/core/persistBucket.js.map +1 -1
  454. package/lib/state/core/persistSignalBucket.d.ts +26 -0
  455. package/lib/state/core/persistSignalBucket.d.ts.map +1 -1
  456. package/lib/state/core/persistSignalBucket.js +31 -0
  457. package/lib/state/core/persistSignalBucket.js.map +1 -1
  458. package/lib/state/core/storageEntry.d.ts +15 -0
  459. package/lib/state/core/storageEntry.d.ts.map +1 -1
  460. package/lib/state/core/storageEntry.js +33 -0
  461. package/lib/state/core/storageEntry.js.map +1 -1
  462. package/lib/structure/ui/StructureExportButton.d.ts +27 -0
  463. package/lib/structure/ui/StructureExportButton.d.ts.map +1 -0
  464. package/lib/structure/ui/StructureExportButton.js +21 -0
  465. package/lib/structure/ui/StructureExportButton.js.map +1 -0
  466. package/lib/structure/ui/index.d.ts +4 -0
  467. package/lib/structure/ui/index.d.ts.map +1 -1
  468. package/lib/structure/ui/index.js +2 -0
  469. package/lib/structure/ui/index.js.map +1 -1
  470. package/lib/structure/ui/useStructureDraft.d.ts +32 -0
  471. package/lib/structure/ui/useStructureDraft.d.ts.map +1 -0
  472. package/lib/structure/ui/useStructureDraft.js +20 -0
  473. package/lib/structure/ui/useStructureDraft.js.map +1 -0
  474. package/lib/ui.d.ts +2 -0
  475. package/lib/ui.d.ts.map +1 -1
  476. package/lib/ui.js +2 -0
  477. package/lib/ui.js.map +1 -1
  478. package/lib/worker/core/index.d.ts +1 -1
  479. package/lib/worker/core/index.d.ts.map +1 -1
  480. package/lib/worker/core/messages.d.ts +4 -2
  481. package/lib/worker/core/messages.d.ts.map +1 -1
  482. package/lib/worker/core/messages.js.map +1 -1
  483. package/lib/worker/core/oclResourcesUrl.d.ts +16 -0
  484. package/lib/worker/core/oclResourcesUrl.d.ts.map +1 -0
  485. package/lib/worker/core/oclResourcesUrl.js +19 -0
  486. package/lib/worker/core/oclResourcesUrl.js.map +1 -0
  487. package/lib/worker/core/serveWorkerRequests.d.ts +8 -0
  488. package/lib/worker/core/serveWorkerRequests.d.ts.map +1 -1
  489. package/lib/worker/core/serveWorkerRequests.js +15 -2
  490. package/lib/worker/core/serveWorkerRequests.js.map +1 -1
  491. package/lib/worker/core/workerChannel.d.ts +3 -4
  492. package/lib/worker/core/workerChannel.d.ts.map +1 -1
  493. package/lib/worker/core/workerChannel.js +72 -67
  494. package/lib/worker/core/workerChannel.js.map +1 -1
  495. package/lib/worker/core/workerChannelParts.d.ts +17 -6
  496. package/lib/worker/core/workerChannelParts.d.ts.map +1 -1
  497. package/lib/worker/core/workerChannelParts.js +20 -4
  498. package/lib/worker/core/workerChannelParts.js.map +1 -1
  499. package/lib/worker/core/workerChannelTypes.d.ts +46 -2
  500. package/lib/worker/core/workerChannelTypes.d.ts.map +1 -1
  501. package/lib/worker/core/workerSlot.d.ts +66 -0
  502. package/lib/worker/core/workerSlot.d.ts.map +1 -0
  503. package/lib/worker/core/workerSlot.js +107 -0
  504. package/lib/worker/core/workerSlot.js.map +1 -0
  505. package/package.json +16 -1
  506. package/src/card/core/cardAddress.ts +100 -0
  507. package/src/card/core/cardPageUrl.ts +97 -0
  508. package/src/card/core/index.ts +6 -0
  509. package/src/card/core/panelRoom.ts +66 -0
  510. package/src/card/ui/CardDetailsButton.tsx +104 -0
  511. package/src/card/ui/CardFigure.tsx +86 -0
  512. package/src/card/ui/CardFrame.tsx +46 -0
  513. package/src/card/ui/CopyTableButton.tsx +81 -0
  514. package/src/card/ui/cardTooltip.ts +18 -0
  515. package/src/card/ui/embed.ts +27 -0
  516. package/src/card/ui/fitCardToFrame.ts +76 -0
  517. package/src/card/ui/holdRoomForPanels.ts +83 -0
  518. package/src/card/ui/index.ts +14 -0
  519. package/src/card/ui/openPanels.ts +106 -0
  520. package/src/card.ts +13 -0
  521. package/src/conformers.ts +4 -0
  522. package/src/core.ts +5 -0
  523. package/src/fetch/core/apiError.ts +65 -0
  524. package/src/fetch/core/fetchJson.ts +129 -0
  525. package/src/fetch/core/index.ts +4 -0
  526. package/src/formula/core/formulaText.ts +96 -0
  527. package/src/formula/core/index.ts +20 -0
  528. package/src/formula/core/normalizeFormula.ts +50 -0
  529. package/src/formula/core/readFormula.ts +211 -0
  530. package/src/formula/ui/CopyableFormula.tsx +51 -0
  531. package/src/formula/ui/FormulaInput.tsx +50 -0
  532. package/src/formula/ui/QuestionFormula.tsx +20 -0
  533. package/src/formula/ui/index.ts +6 -0
  534. package/src/formula.ts +11 -0
  535. package/src/hooks/ui/index.ts +1 -0
  536. package/src/hooks/ui/keyTargets.ts +5 -3
  537. package/src/hooks/ui/useAsync.ts +50 -14
  538. package/src/locales/de.json +37 -0
  539. package/src/locales/en.json +37 -0
  540. package/src/locales/es.json +37 -0
  541. package/src/locales/fr.json +37 -0
  542. package/src/locales/it.json +37 -0
  543. package/src/molecule3d/core/highlight.ts +2 -8
  544. package/src/molecule3d/core/index.ts +1 -0
  545. package/src/molecule3d/core/measurement.ts +47 -0
  546. package/src/molecule3d/ui/drawScene.ts +13 -2
  547. package/src/molecule3d/ui/moleculeViewer3DProps.ts +3 -1
  548. package/src/molecule3d/ui/sceneDrawer.ts +132 -0
  549. package/src/molecule3d/ui/useMoleculeScene.ts +16 -26
  550. package/src/molecule3d/ui/useSharedCamera.ts +1 -3
  551. package/src/moleculesClient/core/index.ts +19 -0
  552. package/src/moleculesClient/core/moleculesClient.ts +175 -0
  553. package/src/moleculesClient/core/moleculesClientApi.ts +120 -0
  554. package/src/moleculesClient/core/moleculesTypes.ts +163 -0
  555. package/src/moleculesClient/core/requestRetry.ts +118 -0
  556. package/src/molstar/core/camera.ts +3 -2
  557. package/src/molstar/core/framing.ts +200 -0
  558. package/src/molstar/core/hover.ts +26 -0
  559. package/src/molstar/core/index.ts +21 -1
  560. package/src/pedagogy/core/answers.ts +94 -0
  561. package/src/pedagogy/core/attempts.ts +205 -0
  562. package/src/pedagogy/core/index.ts +36 -0
  563. package/src/pedagogy/core/progressController.ts +116 -0
  564. package/src/pedagogy/core/seed.ts +177 -0
  565. package/src/pedagogy/core/series.ts +82 -0
  566. package/src/pedagogy/ui/AnswerFields.tsx +63 -0
  567. package/src/pedagogy/ui/ExerciseList.tsx +202 -0
  568. package/src/pedagogy/ui/ExerciseSeries.tsx +250 -0
  569. package/src/pedagogy/ui/QuestionCard.tsx +231 -0
  570. package/src/pedagogy/ui/index.ts +18 -0
  571. package/src/pedagogy/ui/seriesCounts.ts +34 -0
  572. package/src/pedagogy/ui/seriesParts.tsx +127 -0
  573. package/src/pedagogy/ui/useAttemptRecords.ts +16 -0
  574. package/src/periodic/ui/PeriodicTable.tsx +6 -3
  575. package/src/property/core/copyableText.ts +20 -0
  576. package/src/property/core/index.ts +1 -0
  577. package/src/property/ui/PropertyTable.tsx +83 -0
  578. package/src/property/ui/index.ts +2 -0
  579. package/src/router/core/history.ts +61 -7
  580. package/src/router/core/index.ts +3 -2
  581. package/src/router/core/languageRoute.ts +136 -0
  582. package/src/router/core/siteAddresses.ts +38 -0
  583. package/src/router/core/tabRouter.ts +59 -117
  584. package/src/router/core/tabRouterTypes.ts +158 -0
  585. package/src/seo/core/fitDescription.ts +74 -0
  586. package/src/seo/core/index.ts +17 -0
  587. package/src/seo/core/limits.ts +27 -0
  588. package/src/seo/core/pageContent.ts +42 -0
  589. package/src/seo/core/plainDescription.ts +4 -2
  590. package/src/seo/core/routeProblems.ts +1 -7
  591. package/src/seo/core/routeTable.ts +103 -0
  592. package/src/seo/vite/index.ts +2 -0
  593. package/src/seo/vite/prerender.ts +26 -1
  594. package/src/seo/vite/routeTable.ts +79 -0
  595. package/src/server/answerAddresses.ts +92 -0
  596. package/src/server/cardMeta.ts +88 -0
  597. package/src/server/config.ts +125 -0
  598. package/src/server/envNumber.ts +65 -0
  599. package/src/server/healthRoute.ts +42 -0
  600. package/src/server/listenSite.ts +90 -0
  601. package/src/server/mcpServer.ts +14 -0
  602. package/src/server/repositoryVersion.ts +33 -0
  603. package/src/server/routeOptions.ts +26 -0
  604. package/src/server/routeTable.ts +35 -0
  605. package/src/server/siteView.ts +42 -0
  606. package/src/server/spaPages.ts +179 -0
  607. package/src/server/spaSite.ts +216 -0
  608. package/src/server/spaSiteOptions.ts +133 -0
  609. package/src/server/staticSite.ts +65 -35
  610. package/src/server/toolSiteServer.ts +127 -0
  611. package/src/server/trustProxy.ts +32 -0
  612. package/src/server/types.ts +25 -0
  613. package/src/server.ts +40 -0
  614. package/src/share/core/config.ts +45 -2
  615. package/src/share/core/index.ts +4 -0
  616. package/src/share/core/keySetParam.ts +92 -0
  617. package/src/share/core/vocabulary.ts +8 -0
  618. package/src/shell/ui/ShareControl.tsx +150 -0
  619. package/src/shell/ui/ShellFrame.tsx +180 -0
  620. package/src/shell/ui/SiteShell.tsx +297 -0
  621. package/src/shell/ui/index.ts +9 -0
  622. package/src/state/core/index.ts +1 -0
  623. package/src/state/core/legacyEntries.ts +76 -0
  624. package/src/state/core/persistBucket.ts +50 -10
  625. package/src/state/core/persistSignalBucket.ts +52 -0
  626. package/src/state/core/storageEntry.ts +32 -0
  627. package/src/structure/ui/StructureExportButton.tsx +57 -0
  628. package/src/structure/ui/index.ts +4 -0
  629. package/src/structure/ui/useStructureDraft.ts +47 -0
  630. package/src/ui.ts +2 -0
  631. package/src/worker/core/index.ts +1 -0
  632. package/src/worker/core/messages.ts +4 -3
  633. package/src/worker/core/oclResourcesUrl.ts +21 -0
  634. package/src/worker/core/serveWorkerRequests.ts +30 -2
  635. package/src/worker/core/workerChannel.ts +74 -74
  636. package/src/worker/core/workerChannelParts.ts +33 -13
  637. package/src/worker/core/workerChannelTypes.ts +47 -2
  638. package/src/worker/core/workerSlot.ts +181 -0
  639. package/styles/card.css +145 -0
  640. package/styles/chrome.css +248 -0
@@ -0,0 +1,163 @@
1
+ /** One molecule a source sends: its identifier, and exactly one notation. */
2
+ export interface MoleculeInput {
3
+ /** The source's identifier for it, which its address is written with. */
4
+ id: string;
5
+ /**
6
+ * The structure as SMILES.
7
+ * @default undefined - another notation is given
8
+ */
9
+ smiles?: string;
10
+ /**
11
+ * The structure as a molfile.
12
+ * @default undefined - another notation is given
13
+ */
14
+ molfile?: string;
15
+ /**
16
+ * The structure as an OpenChemLib idCode.
17
+ * @default undefined - another notation is given
18
+ */
19
+ idCode?: string;
20
+ }
21
+
22
+ /** What molecules.cheminfo.org computed for a structure. */
23
+ export interface MoleculeInfo {
24
+ mf: string;
25
+ mw: number;
26
+ em: number;
27
+ charge: number;
28
+ idCode: string;
29
+ noStereoID: string;
30
+ noStereoTautomerID: string;
31
+ failedTautomerID: number;
32
+ /** The 512-bit FragFp, sixteen signed 32-bit words. */
33
+ ssIndex: number[];
34
+ logS: number;
35
+ logP: number;
36
+ acceptorCount: number;
37
+ donorCount: number;
38
+ stereoCenterCount: number;
39
+ rotatableBondCount: number;
40
+ polarSurfaceArea: number;
41
+ nbFragments: number;
42
+ /**
43
+ * The degree of unsaturation, when the formula has one.
44
+ * @default undefined
45
+ */
46
+ unsaturation?: number;
47
+ atoms: Record<string, number>;
48
+ /** The hashes, as 16 hex digits: never JSON numbers, which would round them. */
49
+ idCodeHash: string;
50
+ noStereoHash: string;
51
+ noStereoTautomerHash: string;
52
+ createdAt: number | null;
53
+ }
54
+
55
+ /** What became of one molecule a source sent. */
56
+ export interface SubmitResult {
57
+ id: string | null;
58
+ /**
59
+ * The structure it was read as.
60
+ * @default undefined - it could not be read
61
+ */
62
+ idCode?: string;
63
+ /**
64
+ * Whether molecules.cheminfo.org held the structure already.
65
+ * @default undefined - it could not be read
66
+ */
67
+ molecule?: 'created' | 'existing';
68
+ /**
69
+ * What became of the source's entry.
70
+ * @default undefined - it could not be read
71
+ */
72
+ link?: 'added' | 'unchanged' | 'moved';
73
+ /**
74
+ * The computed properties, when they were asked for.
75
+ * @default undefined
76
+ */
77
+ info?: MoleculeInfo;
78
+ /**
79
+ * Why the molecule was refused.
80
+ * @default undefined - it was taken
81
+ */
82
+ error?: string;
83
+ }
84
+
85
+ /** How a batch was taken. */
86
+ export interface SubmitSummary {
87
+ total: number;
88
+ /** Molecules new to molecules.cheminfo.org. */
89
+ created: number;
90
+ /** Entries new to the source. */
91
+ added: number;
92
+ /** Identifiers moved to another structure. */
93
+ moved: number;
94
+ unchanged: number;
95
+ failed: number;
96
+ }
97
+
98
+ /** What `POST /v1/submit` answers: one result per molecule, in their order. */
99
+ export interface SubmitResponse {
100
+ source: string;
101
+ results: SubmitResult[];
102
+ summary: SubmitSummary;
103
+ }
104
+
105
+ /** What `POST /v1/imports` answers: the start of a full import. */
106
+ export interface ImportStarted {
107
+ source: string;
108
+ importKey: number;
109
+ importStartedAt: number;
110
+ }
111
+
112
+ /** What `GET /v1/imports` answers: where the source's import stands. */
113
+ export interface ImportState {
114
+ source: string;
115
+ importKey: number;
116
+ importStartedAt: number | null;
117
+ updatedAt: number | null;
118
+ entries: number;
119
+ stale: number;
120
+ }
121
+
122
+ /** What a purge answers. */
123
+ export interface PurgeResponse {
124
+ source: string;
125
+ importKey: number;
126
+ dryRun: boolean;
127
+ /** The entries the import did not send again, removed or to be removed. */
128
+ removed: number;
129
+ /** The entries the source holds after. */
130
+ remaining: number;
131
+ }
132
+
133
+ /** One answer of `POST /v1/batch`: the molecule a query reads as, or why not. */
134
+ export interface LookupResult {
135
+ query: string;
136
+ result: MoleculeInfo | null;
137
+ /** Whether molecules.cheminfo.org lists it, rather than computing it now. */
138
+ cached: boolean;
139
+ /**
140
+ * Why the query could not be read.
141
+ * @default undefined - it was read
142
+ */
143
+ error?: string;
144
+ }
145
+
146
+ /** What `POST /v1/batch` answers: one result per query, in their order. */
147
+ export interface LookupResponse {
148
+ results: LookupResult[];
149
+ }
150
+
151
+ /** Why a request is tried again, and when. */
152
+ export interface RetryDetails {
153
+ method: string;
154
+ path: string;
155
+ attempt: number;
156
+ /**
157
+ * The status that was answered.
158
+ * @default undefined - nothing was answered
159
+ */
160
+ status?: number;
161
+ reason: string;
162
+ delayMs: number;
163
+ }
@@ -0,0 +1,118 @@
1
+ import { toError } from '../../error/core/toError.ts';
2
+
3
+ /**
4
+ * The pieces of a request that is tried again: its deadline, the pause the
5
+ * server asks for, what an error answer says, and what a failed fetch says.
6
+ * Browser-safe: no Node module is read.
7
+ */
8
+
9
+ /**
10
+ * The signal one attempt runs under: the caller's, and its own deadline.
11
+ * @param signal - The caller's, if any.
12
+ * @param timeoutMs - How long the attempt may take.
13
+ * @returns The signal.
14
+ */
15
+ export function requestSignal(
16
+ signal: AbortSignal | undefined,
17
+ timeoutMs: number,
18
+ ): AbortSignal {
19
+ const timeout = AbortSignal.timeout(timeoutMs);
20
+ return signal === undefined ? timeout : AbortSignal.any([signal, timeout]);
21
+ }
22
+
23
+ /**
24
+ * How long a `Retry-After` header asks to wait.
25
+ * @param header - Its value: seconds, or an HTTP date.
26
+ * @param now - The current instant, in epoch milliseconds.
27
+ * @returns The pause in milliseconds, or `undefined` when there is none to read.
28
+ */
29
+ export function retryAfter(
30
+ header: string | null,
31
+ now: number,
32
+ ): number | undefined {
33
+ if (header === null || header.trim() === '') return undefined;
34
+ const seconds = Number(header);
35
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);
36
+ const date = Date.parse(header);
37
+ return Number.isNaN(date) ? undefined : Math.max(0, date - now);
38
+ }
39
+
40
+ /**
41
+ * The message of an error body Fastify wrote, or the body itself.
42
+ * @param text - The body.
43
+ * @returns The message, or `undefined` when the body is empty.
44
+ */
45
+ export function messageOf(text: string): string | undefined {
46
+ if (text.trim() === '') return undefined;
47
+ try {
48
+ const body = JSON.parse(text) as { message?: unknown } | null;
49
+ if (typeof body?.message === 'string') return body.message;
50
+ } catch {
51
+ return text.slice(0, 500);
52
+ }
53
+ return text.slice(0, 500);
54
+ }
55
+
56
+ /**
57
+ * What a failed fetch says, its cause included: undici reports a refused
58
+ * connection as `fetch failed` with the reason in `cause` — and when several
59
+ * addresses were tried, in the first error of an AggregateError whose own
60
+ * message is empty.
61
+ * @param error - What was thrown.
62
+ * @returns The message, e.g. `fetch failed: connect ECONNREFUSED 127.0.0.1:11980`.
63
+ */
64
+ export function causeOf(error: unknown): string {
65
+ if (!(error instanceof Error)) return String(error);
66
+ const { cause, message } = error;
67
+ if (!(cause instanceof Error)) return message;
68
+ const first: unknown =
69
+ cause instanceof AggregateError ? cause.errors[0] : undefined;
70
+ const code = (cause as { code?: unknown }).code;
71
+ const detail =
72
+ cause.message ||
73
+ (first instanceof Error ? first.message : '') ||
74
+ (typeof code === 'string' ? code : '') ||
75
+ cause.name;
76
+ return `${message}: ${detail}`;
77
+ }
78
+
79
+ /**
80
+ * A request body gzipped, as HTTP's `Content-Encoding: gzip` carries it: a
81
+ * batch of molfiles shrinks several times over.
82
+ * @param text - The body, written out.
83
+ * @returns The gzipped bytes.
84
+ */
85
+ export async function gzipBody(text: string): Promise<Uint8Array<ArrayBuffer>> {
86
+ const stream = new Blob([text])
87
+ .stream()
88
+ .pipeThrough(new CompressionStream('gzip'));
89
+ return new Uint8Array(await new Response(stream).arrayBuffer());
90
+ }
91
+
92
+ /**
93
+ * Wait, unless the signal stops the wait first.
94
+ * @param milliseconds - How long.
95
+ * @param signal - What stops it, if anything.
96
+ * @returns When the time has passed.
97
+ * @throws {unknown} The signal's reason, when it aborts first.
98
+ */
99
+ export function pause(
100
+ milliseconds: number,
101
+ signal: AbortSignal | undefined,
102
+ ): Promise<void> {
103
+ return new Promise((done, fail) => {
104
+ if (signal?.aborted) {
105
+ fail(toError(signal.reason));
106
+ return;
107
+ }
108
+ const abort = () => {
109
+ clearTimeout(timer);
110
+ fail(toError(signal?.reason));
111
+ };
112
+ const timer = setTimeout(() => {
113
+ signal?.removeEventListener('abort', abort);
114
+ done();
115
+ }, milliseconds);
116
+ signal?.addEventListener('abort', abort, { once: true });
117
+ });
118
+ }
@@ -34,10 +34,11 @@ const SPIN_AXIS = Vec3.create(0, 1, 0);
34
34
  * measured against — so reading a camera and applying it are the same move in
35
35
  * opposite directions.
36
36
  * @param radius - Radius of the scene's visible bounding sphere.
37
+ * @param margin - Fraction of the radius kept as breathing room.
37
38
  * @returns The framed radius.
38
39
  */
39
- export function framedRadius(radius: number): number {
40
- return Math.max(radius * (1 + FRAMING_MARGIN), MINIMUM_FRAMING_RADIUS);
40
+ export function framedRadius(radius: number, margin = FRAMING_MARGIN): number {
41
+ return Math.max(radius * (1 + margin), MINIMUM_FRAMING_RADIUS);
41
42
  }
42
43
 
43
44
  /**
@@ -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 { atomName, atomText, lociText, subscribeHover } from './hover.ts';
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
+ }