@intellectif/lk-react 23.0.1 → 23.1.1

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 (369) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +13 -9
  3. package/dist/ActivityErrorBoundary-B379hvtL.cjs +39 -0
  4. package/dist/ActivityErrorBoundary-B379hvtL.cjs.map +1 -0
  5. package/dist/ActivityErrorBoundary-Dw6SbWv3.js +34 -0
  6. package/dist/ActivityErrorBoundary-Dw6SbWv3.js.map +1 -0
  7. package/dist/ActivityMedia-CQQTRNl7.cjs +641 -0
  8. package/dist/ActivityMedia-CQQTRNl7.cjs.map +1 -0
  9. package/dist/ActivityMedia-vDiP-Psa.js +636 -0
  10. package/dist/ActivityMedia-vDiP-Psa.js.map +1 -0
  11. package/dist/ActivityPreview-1hhTkYuj.js +240 -0
  12. package/dist/ActivityPreview-1hhTkYuj.js.map +1 -0
  13. package/dist/ActivityPreview-BKr34exz.cjs +245 -0
  14. package/dist/ActivityPreview-BKr34exz.cjs.map +1 -0
  15. package/dist/ActivitySequence-CkX87pfB.js +839 -0
  16. package/dist/ActivitySequence-CkX87pfB.js.map +1 -0
  17. package/dist/ActivitySequence-CmoSyDnp.cjs +844 -0
  18. package/dist/ActivitySequence-CmoSyDnp.cjs.map +1 -0
  19. package/dist/Dictation-BlxRp-3k.js +926 -0
  20. package/dist/Dictation-BlxRp-3k.js.map +1 -0
  21. package/dist/Dictation-jECzL88E.cjs +931 -0
  22. package/dist/Dictation-jECzL88E.cjs.map +1 -0
  23. package/dist/FeedbackRegion-BNNMtTY-.cjs +108 -0
  24. package/dist/FeedbackRegion-BNNMtTY-.cjs.map +1 -0
  25. package/dist/FeedbackRegion-CyPSp8bA.js +85 -0
  26. package/dist/FeedbackRegion-CyPSp8bA.js.map +1 -0
  27. package/dist/FillInTheBlanks-B6xzqYXx.js +474 -0
  28. package/dist/FillInTheBlanks-B6xzqYXx.js.map +1 -0
  29. package/dist/FillInTheBlanks-BpKhdHg2.cjs +479 -0
  30. package/dist/FillInTheBlanks-BpKhdHg2.cjs.map +1 -0
  31. package/dist/GapSelect-DUSiaEQH.js +441 -0
  32. package/dist/GapSelect-DUSiaEQH.js.map +1 -0
  33. package/dist/GapSelect-payTq_Zn.cjs +446 -0
  34. package/dist/GapSelect-payTq_Zn.cjs.map +1 -0
  35. package/dist/InteractiveVideo-BguGv-HA.cjs +2955 -0
  36. package/dist/InteractiveVideo-BguGv-HA.cjs.map +1 -0
  37. package/dist/InteractiveVideo-Cg2jbU3j.js +2944 -0
  38. package/dist/InteractiveVideo-Cg2jbU3j.js.map +1 -0
  39. package/dist/LkAiProvider-DAPpA3PQ.d.cts +84 -0
  40. package/dist/LkAiProvider-DAPpA3PQ.d.cts.map +1 -0
  41. package/dist/LkAiProvider-QdEcIhoo.d.ts +84 -0
  42. package/dist/LkAiProvider-QdEcIhoo.d.ts.map +1 -0
  43. package/dist/LkIntlProvider-D_FdYXjQ.js +375 -0
  44. package/dist/LkIntlProvider-D_FdYXjQ.js.map +1 -0
  45. package/dist/LkIntlProvider-oi57lYB0.cjs +410 -0
  46. package/dist/LkIntlProvider-oi57lYB0.cjs.map +1 -0
  47. package/dist/MultipleChoice-COn5MtKY.cjs +433 -0
  48. package/dist/MultipleChoice-COn5MtKY.cjs.map +1 -0
  49. package/dist/MultipleChoice-Dra0_KYD.js +428 -0
  50. package/dist/MultipleChoice-Dra0_KYD.js.map +1 -0
  51. package/dist/PronunciationFeedback-DlMPGjkR.cjs +831 -0
  52. package/dist/PronunciationFeedback-DlMPGjkR.cjs.map +1 -0
  53. package/dist/PronunciationFeedback-Dxd6XPkO.js +772 -0
  54. package/dist/PronunciationFeedback-Dxd6XPkO.js.map +1 -0
  55. package/dist/ReadAloud-C8RhaUqV.js +1092 -0
  56. package/dist/ReadAloud-C8RhaUqV.js.map +1 -0
  57. package/dist/ReadAloud-akDehitT.cjs +1103 -0
  58. package/dist/ReadAloud-akDehitT.cjs.map +1 -0
  59. package/dist/StimulusPanel-BgzByfkb.js +74 -0
  60. package/dist/StimulusPanel-BgzByfkb.js.map +1 -0
  61. package/dist/StimulusPanel-b66gaN3i.cjs +79 -0
  62. package/dist/StimulusPanel-b66gaN3i.cjs.map +1 -0
  63. package/dist/ThemeProvider-BRN1tj4n.cjs +187 -0
  64. package/dist/ThemeProvider-BRN1tj4n.cjs.map +1 -0
  65. package/dist/ThemeProvider-C7K9iMLX.js +158 -0
  66. package/dist/ThemeProvider-C7K9iMLX.js.map +1 -0
  67. package/dist/ThemeProvider-CocC8ODJ.d.ts +62 -0
  68. package/dist/ThemeProvider-CocC8ODJ.d.ts.map +1 -0
  69. package/dist/ThemeProvider-DS4KOL86.d.cts +62 -0
  70. package/dist/ThemeProvider-DS4KOL86.d.cts.map +1 -0
  71. package/dist/WrittenResponse-Bj3eFmGl.cjs +491 -0
  72. package/dist/WrittenResponse-Bj3eFmGl.cjs.map +1 -0
  73. package/dist/WrittenResponse-Cl8G6nO_.js +486 -0
  74. package/dist/WrittenResponse-Cl8G6nO_.js.map +1 -0
  75. package/dist/ai/LkAiProvider.cjs +34 -14
  76. package/dist/ai/LkAiProvider.cjs.map +1 -1
  77. package/dist/ai/LkAiProvider.d.cts +2 -73
  78. package/dist/ai/LkAiProvider.d.ts +2 -73
  79. package/dist/ai/LkAiProvider.js +33 -2
  80. package/dist/ai/LkAiProvider.js.map +1 -1
  81. package/dist/ai/useAiHelp.cjs +7 -23
  82. package/dist/ai/useAiHelp.d.cts +198 -121
  83. package/dist/ai/useAiHelp.d.cts.map +1 -0
  84. package/dist/ai/useAiHelp.d.ts +198 -121
  85. package/dist/ai/useAiHelp.d.ts.map +1 -0
  86. package/dist/ai/useAiHelp.js +3 -6
  87. package/dist/components/ActivityPreview.cjs +3 -31
  88. package/dist/components/ActivityPreview.d.cts +2 -81
  89. package/dist/components/ActivityPreview.d.ts +2 -81
  90. package/dist/components/ActivityPreview.js +2 -22
  91. package/dist/components/ActivitySequence.cjs +3 -32
  92. package/dist/components/ActivitySequence.d.cts +2 -432
  93. package/dist/components/ActivitySequence.d.ts +2 -432
  94. package/dist/components/ActivitySequence.js +2 -23
  95. package/dist/components/Dictation.cjs +4 -23
  96. package/dist/components/Dictation.d.cts +2 -19
  97. package/dist/components/Dictation.d.ts +2 -19
  98. package/dist/components/Dictation.js +3 -14
  99. package/dist/components/FillInTheBlanks.cjs +4 -22
  100. package/dist/components/FillInTheBlanks.d.cts +2 -30
  101. package/dist/components/FillInTheBlanks.d.ts +2 -30
  102. package/dist/components/FillInTheBlanks.js +3 -13
  103. package/dist/components/GapSelect.cjs +4 -22
  104. package/dist/components/GapSelect.d.cts +2 -27
  105. package/dist/components/GapSelect.d.ts +2 -27
  106. package/dist/components/GapSelect.js +3 -13
  107. package/dist/components/InteractiveVideo.cjs +5 -34
  108. package/dist/components/InteractiveVideo.d.cts +3 -291
  109. package/dist/components/InteractiveVideo.d.ts +3 -291
  110. package/dist/components/InteractiveVideo.js +3 -21
  111. package/dist/components/MultipleChoice.cjs +4 -22
  112. package/dist/components/MultipleChoice.d.cts +2 -26
  113. package/dist/components/MultipleChoice.d.ts +2 -26
  114. package/dist/components/MultipleChoice.js +3 -13
  115. package/dist/components/PronunciationFeedback.cjs +4 -16
  116. package/dist/components/PronunciationFeedback.d.cts +2 -69
  117. package/dist/components/PronunciationFeedback.d.ts +2 -69
  118. package/dist/components/PronunciationFeedback.js +3 -7
  119. package/dist/components/ReadAloud.cjs +4 -22
  120. package/dist/components/ReadAloud.d.cts +7 -11
  121. package/dist/components/ReadAloud.d.cts.map +1 -0
  122. package/dist/components/ReadAloud.d.ts +7 -11
  123. package/dist/components/ReadAloud.d.ts.map +1 -0
  124. package/dist/components/ReadAloud.js +3 -13
  125. package/dist/components/StimulusPanel.cjs +3 -14
  126. package/dist/components/StimulusPanel.d.cts +2 -51
  127. package/dist/components/StimulusPanel.d.ts +2 -51
  128. package/dist/components/StimulusPanel.js +2 -5
  129. package/dist/components/WrittenResponse.cjs +4 -21
  130. package/dist/components/WrittenResponse.d.cts +3 -18
  131. package/dist/components/WrittenResponse.d.ts +3 -18
  132. package/dist/components/WrittenResponse.js +3 -12
  133. package/dist/direction-Dq0_HtA5.js +183 -0
  134. package/dist/direction-Dq0_HtA5.js.map +1 -0
  135. package/dist/direction-K1pj0HCA.cjs +200 -0
  136. package/dist/direction-K1pj0HCA.cjs.map +1 -0
  137. package/dist/hooks/useActivityState.cjs +28 -10
  138. package/dist/hooks/useActivityState.cjs.map +1 -1
  139. package/dist/hooks/useActivityState.d.cts +25 -24
  140. package/dist/hooks/useActivityState.d.cts.map +1 -0
  141. package/dist/hooks/useActivityState.d.ts +25 -24
  142. package/dist/hooks/useActivityState.d.ts.map +1 -0
  143. package/dist/hooks/useActivityState.js +28 -2
  144. package/dist/hooks/useActivityState.js.map +1 -1
  145. package/dist/hooks/useSpeechRecorder.cjs +5 -16
  146. package/dist/hooks/useSpeechRecorder.d.cts +2 -127
  147. package/dist/hooks/useSpeechRecorder.d.ts +2 -127
  148. package/dist/hooks/useSpeechRecorder.js +3 -3
  149. package/dist/hooks/useXAPI.cjs +126 -10
  150. package/dist/hooks/useXAPI.cjs.map +1 -1
  151. package/dist/hooks/useXAPI.d.cts +14 -14
  152. package/dist/hooks/useXAPI.d.cts.map +1 -0
  153. package/dist/hooks/useXAPI.d.ts +14 -14
  154. package/dist/hooks/useXAPI.d.ts.map +1 -0
  155. package/dist/hooks/useXAPI.js +126 -2
  156. package/dist/hooks/useXAPI.js.map +1 -1
  157. package/dist/i18n/LkIntlProvider.cjs +9 -32
  158. package/dist/i18n/LkIntlProvider.d.cts +34 -38
  159. package/dist/i18n/LkIntlProvider.d.cts.map +1 -0
  160. package/dist/i18n/LkIntlProvider.d.ts +34 -38
  161. package/dist/i18n/LkIntlProvider.d.ts.map +1 -0
  162. package/dist/i18n/LkIntlProvider.js +3 -3
  163. package/dist/index-2iDJohip.d.cts +90 -0
  164. package/dist/index-2iDJohip.d.cts.map +1 -0
  165. package/dist/index-BAqT5tXN.d.ts +90 -0
  166. package/dist/index-BAqT5tXN.d.ts.map +1 -0
  167. package/dist/index-BRbEfXgE.d.ts +78 -0
  168. package/dist/index-BRbEfXgE.d.ts.map +1 -0
  169. package/dist/index-BW7aA5eN.d.cts +25 -0
  170. package/dist/index-BW7aA5eN.d.cts.map +1 -0
  171. package/dist/index-BeiVd-qe.d.ts +124 -0
  172. package/dist/index-BeiVd-qe.d.ts.map +1 -0
  173. package/dist/index-C1KGpD1k.d.ts +49 -0
  174. package/dist/index-C1KGpD1k.d.ts.map +1 -0
  175. package/dist/index-C7cCHEze.d.cts +24 -0
  176. package/dist/index-C7cCHEze.d.cts.map +1 -0
  177. package/dist/index-CKTpYTCC.d.cts +49 -0
  178. package/dist/index-CKTpYTCC.d.cts.map +1 -0
  179. package/dist/index-CN3_TwDL.d.ts +28 -0
  180. package/dist/index-CN3_TwDL.d.ts.map +1 -0
  181. package/dist/index-CNoAqj5I.d.ts +16 -0
  182. package/dist/index-CNoAqj5I.d.ts.map +1 -0
  183. package/dist/index-CTlht6OV.d.cts +432 -0
  184. package/dist/index-CTlht6OV.d.cts.map +1 -0
  185. package/dist/index-CmgSzapt.d.cts +124 -0
  186. package/dist/index-CmgSzapt.d.cts.map +1 -0
  187. package/dist/index-D4WYDN_p.d.cts +28 -0
  188. package/dist/index-D4WYDN_p.d.cts.map +1 -0
  189. package/dist/index-DAJ6KK49.d.ts +25 -0
  190. package/dist/index-DAJ6KK49.d.ts.map +1 -0
  191. package/dist/index-DIiacP_z.d.cts +78 -0
  192. package/dist/index-DIiacP_z.d.cts.map +1 -0
  193. package/dist/index-DR0SOJig.d.ts +291 -0
  194. package/dist/index-DR0SOJig.d.ts.map +1 -0
  195. package/dist/index-DRMauOVH.d.ts +432 -0
  196. package/dist/index-DRMauOVH.d.ts.map +1 -0
  197. package/dist/index-bmmRfGad.d.cts +16 -0
  198. package/dist/index-bmmRfGad.d.cts.map +1 -0
  199. package/dist/index-n9PKZm7W.d.cts +291 -0
  200. package/dist/index-n9PKZm7W.d.cts.map +1 -0
  201. package/dist/index-zu9H7owf.d.ts +24 -0
  202. package/dist/index-zu9H7owf.d.ts.map +1 -0
  203. package/dist/index.cjs +118 -161
  204. package/dist/index.cjs.map +1 -1
  205. package/dist/index.d.cts +20 -24
  206. package/dist/index.d.ts +20 -24
  207. package/dist/index.js +84 -31
  208. package/dist/index.js.map +1 -1
  209. package/dist/theme/ThemeProvider.cjs +8 -28
  210. package/dist/theme/ThemeProvider.d.cts +2 -59
  211. package/dist/theme/ThemeProvider.d.ts +2 -59
  212. package/dist/theme/ThemeProvider.js +3 -3
  213. package/dist/theme/skin.css +46 -1
  214. package/dist/tries-CbbtZkdG.cjs +363 -0
  215. package/dist/{chunk-W6UMY7PF.cjs.map → tries-CbbtZkdG.cjs.map} +1 -1
  216. package/dist/tries-DTHSrLCm.js +310 -0
  217. package/dist/tries-DTHSrLCm.js.map +1 -0
  218. package/dist/types-BOQd93x3.d.cts +994 -0
  219. package/dist/types-BOQd93x3.d.cts.map +1 -0
  220. package/dist/types-HIrgF_mS.d.ts +994 -0
  221. package/dist/types-HIrgF_mS.d.ts.map +1 -0
  222. package/dist/useAiHelp-B-ccDL5Q.js +906 -0
  223. package/dist/useAiHelp-B-ccDL5Q.js.map +1 -0
  224. package/dist/useAiHelp-h9yOLFqt.cjs +995 -0
  225. package/dist/useAiHelp-h9yOLFqt.cjs.map +1 -0
  226. package/dist/useSpeechRecorder--O_f-xvt.cjs +720 -0
  227. package/dist/useSpeechRecorder--O_f-xvt.cjs.map +1 -0
  228. package/dist/useSpeechRecorder-DtAYvl02.d.cts +154 -0
  229. package/dist/useSpeechRecorder-DtAYvl02.d.cts.map +1 -0
  230. package/dist/useSpeechRecorder-DtAYvl02.d.ts +154 -0
  231. package/dist/useSpeechRecorder-DtAYvl02.d.ts.map +1 -0
  232. package/dist/useSpeechRecorder-zIi9Dlw8.js +709 -0
  233. package/dist/useSpeechRecorder-zIi9Dlw8.js.map +1 -0
  234. package/package.json +10 -11
  235. package/dist/WrittenResponse-CgRrjM4S.d.ts +0 -115
  236. package/dist/WrittenResponse-D2K1VW_V.d.cts +0 -115
  237. package/dist/ai/useAiHelp.cjs.map +0 -1
  238. package/dist/ai/useAiHelp.js.map +0 -1
  239. package/dist/chunk-2OP5YHRR.js +0 -543
  240. package/dist/chunk-2OP5YHRR.js.map +0 -1
  241. package/dist/chunk-2TW6WLBC.js +0 -80
  242. package/dist/chunk-2TW6WLBC.js.map +0 -1
  243. package/dist/chunk-4MXECBZT.js +0 -888
  244. package/dist/chunk-4MXECBZT.js.map +0 -1
  245. package/dist/chunk-54DX6SLS.cjs +0 -42
  246. package/dist/chunk-54DX6SLS.cjs.map +0 -1
  247. package/dist/chunk-6GQLCCGN.js +0 -858
  248. package/dist/chunk-6GQLCCGN.js.map +0 -1
  249. package/dist/chunk-6N43WDVG.js +0 -29
  250. package/dist/chunk-6N43WDVG.js.map +0 -1
  251. package/dist/chunk-6RIM5EQP.cjs +0 -393
  252. package/dist/chunk-6RIM5EQP.cjs.map +0 -1
  253. package/dist/chunk-7F2YQWMW.cjs +0 -553
  254. package/dist/chunk-7F2YQWMW.cjs.map +0 -1
  255. package/dist/chunk-B4JRBV56.cjs +0 -63
  256. package/dist/chunk-B4JRBV56.cjs.map +0 -1
  257. package/dist/chunk-B7JU52YQ.cjs +0 -437
  258. package/dist/chunk-B7JU52YQ.cjs.map +0 -1
  259. package/dist/chunk-C4PSJ3ZC.js +0 -329
  260. package/dist/chunk-C4PSJ3ZC.js.map +0 -1
  261. package/dist/chunk-CXIP7ERK.js +0 -389
  262. package/dist/chunk-CXIP7ERK.js.map +0 -1
  263. package/dist/chunk-DPNCCWOV.js +0 -395
  264. package/dist/chunk-DPNCCWOV.js.map +0 -1
  265. package/dist/chunk-DXFCYNST.js +0 -35
  266. package/dist/chunk-DXFCYNST.js.map +0 -1
  267. package/dist/chunk-DZ7VLLDQ.cjs +0 -891
  268. package/dist/chunk-DZ7VLLDQ.cjs.map +0 -1
  269. package/dist/chunk-E4UF4XZM.js +0 -29
  270. package/dist/chunk-E4UF4XZM.js.map +0 -1
  271. package/dist/chunk-ERV666AR.js +0 -435
  272. package/dist/chunk-ERV666AR.js.map +0 -1
  273. package/dist/chunk-FISEZBLF.cjs +0 -31
  274. package/dist/chunk-FISEZBLF.cjs.map +0 -1
  275. package/dist/chunk-HYOUMTPW.js +0 -597
  276. package/dist/chunk-HYOUMTPW.js.map +0 -1
  277. package/dist/chunk-HZIT24BK.js +0 -61
  278. package/dist/chunk-HZIT24BK.js.map +0 -1
  279. package/dist/chunk-IYGF7PZY.cjs +0 -2938
  280. package/dist/chunk-IYGF7PZY.cjs.map +0 -1
  281. package/dist/chunk-J2QIHZ3H.cjs +0 -27
  282. package/dist/chunk-J2QIHZ3H.cjs.map +0 -1
  283. package/dist/chunk-JMEZYYCE.js +0 -2935
  284. package/dist/chunk-JMEZYYCE.js.map +0 -1
  285. package/dist/chunk-K63VPFOV.cjs +0 -134
  286. package/dist/chunk-K63VPFOV.cjs.map +0 -1
  287. package/dist/chunk-KI6DJ5ZF.js +0 -495
  288. package/dist/chunk-KI6DJ5ZF.js.map +0 -1
  289. package/dist/chunk-MCO52PV5.js +0 -520
  290. package/dist/chunk-MCO52PV5.js.map +0 -1
  291. package/dist/chunk-MXZHL4U5.cjs +0 -860
  292. package/dist/chunk-MXZHL4U5.cjs.map +0 -1
  293. package/dist/chunk-NFGUJ52G.cjs +0 -336
  294. package/dist/chunk-NFGUJ52G.cjs.map +0 -1
  295. package/dist/chunk-O7MINPKZ.js +0 -431
  296. package/dist/chunk-O7MINPKZ.js.map +0 -1
  297. package/dist/chunk-OD65OZIW.cjs +0 -159
  298. package/dist/chunk-OD65OZIW.cjs.map +0 -1
  299. package/dist/chunk-OJGTJOWI.cjs +0 -20
  300. package/dist/chunk-OJGTJOWI.cjs.map +0 -1
  301. package/dist/chunk-PGAPZ6UE.cjs +0 -497
  302. package/dist/chunk-PGAPZ6UE.cjs.map +0 -1
  303. package/dist/chunk-PNNUPUH4.cjs +0 -82
  304. package/dist/chunk-PNNUPUH4.cjs.map +0 -1
  305. package/dist/chunk-QAZO3ANW.cjs +0 -433
  306. package/dist/chunk-QAZO3ANW.cjs.map +0 -1
  307. package/dist/chunk-RX3A6KIY.js +0 -17
  308. package/dist/chunk-RX3A6KIY.js.map +0 -1
  309. package/dist/chunk-SHDSOOBF.cjs +0 -826
  310. package/dist/chunk-SHDSOOBF.cjs.map +0 -1
  311. package/dist/chunk-SPSKDNEE.js +0 -824
  312. package/dist/chunk-SPSKDNEE.js.map +0 -1
  313. package/dist/chunk-TGTP5DKF.js +0 -234
  314. package/dist/chunk-TGTP5DKF.js.map +0 -1
  315. package/dist/chunk-U4KTOH7C.js +0 -22
  316. package/dist/chunk-U4KTOH7C.js.map +0 -1
  317. package/dist/chunk-U5VFJVQ2.js +0 -241
  318. package/dist/chunk-U5VFJVQ2.js.map +0 -1
  319. package/dist/chunk-UDCQTOVU.cjs +0 -523
  320. package/dist/chunk-UDCQTOVU.cjs.map +0 -1
  321. package/dist/chunk-UHKZXOXD.js +0 -128
  322. package/dist/chunk-UHKZXOXD.js.map +0 -1
  323. package/dist/chunk-UKUHVCZX.cjs +0 -599
  324. package/dist/chunk-UKUHVCZX.cjs.map +0 -1
  325. package/dist/chunk-VPU6UY4O.cjs +0 -55
  326. package/dist/chunk-VPU6UY4O.cjs.map +0 -1
  327. package/dist/chunk-W6UMY7PF.cjs +0 -251
  328. package/dist/chunk-WZ2TBXVB.cjs +0 -236
  329. package/dist/chunk-WZ2TBXVB.cjs.map +0 -1
  330. package/dist/chunk-XOR4MPEN.cjs +0 -31
  331. package/dist/chunk-XOR4MPEN.cjs.map +0 -1
  332. package/dist/chunk-XS6OYYVR.cjs +0 -397
  333. package/dist/chunk-XS6OYYVR.cjs.map +0 -1
  334. package/dist/chunk-XYJBRKBZ.js +0 -51
  335. package/dist/chunk-XYJBRKBZ.js.map +0 -1
  336. package/dist/chunk-YORQQXGO.js +0 -155
  337. package/dist/chunk-YORQQXGO.js.map +0 -1
  338. package/dist/components/ActivityPreview.cjs.map +0 -1
  339. package/dist/components/ActivityPreview.js.map +0 -1
  340. package/dist/components/ActivitySequence.cjs.map +0 -1
  341. package/dist/components/ActivitySequence.js.map +0 -1
  342. package/dist/components/Dictation.cjs.map +0 -1
  343. package/dist/components/Dictation.js.map +0 -1
  344. package/dist/components/FillInTheBlanks.cjs.map +0 -1
  345. package/dist/components/FillInTheBlanks.js.map +0 -1
  346. package/dist/components/GapSelect.cjs.map +0 -1
  347. package/dist/components/GapSelect.js.map +0 -1
  348. package/dist/components/InteractiveVideo.cjs.map +0 -1
  349. package/dist/components/InteractiveVideo.js.map +0 -1
  350. package/dist/components/MultipleChoice.cjs.map +0 -1
  351. package/dist/components/MultipleChoice.js.map +0 -1
  352. package/dist/components/PronunciationFeedback.cjs.map +0 -1
  353. package/dist/components/PronunciationFeedback.js.map +0 -1
  354. package/dist/components/ReadAloud.cjs.map +0 -1
  355. package/dist/components/ReadAloud.js.map +0 -1
  356. package/dist/components/StimulusPanel.cjs.map +0 -1
  357. package/dist/components/StimulusPanel.js.map +0 -1
  358. package/dist/components/WrittenResponse.cjs.map +0 -1
  359. package/dist/components/WrittenResponse.js.map +0 -1
  360. package/dist/hooks/useSpeechRecorder.cjs.map +0 -1
  361. package/dist/hooks/useSpeechRecorder.js.map +0 -1
  362. package/dist/i18n/LkIntlProvider.cjs.map +0 -1
  363. package/dist/i18n/LkIntlProvider.js.map +0 -1
  364. package/dist/machine-CuwKqWXC.d.cts +0 -26
  365. package/dist/machine-CuwKqWXC.d.ts +0 -26
  366. package/dist/theme/ThemeProvider.cjs.map +0 -1
  367. package/dist/theme/ThemeProvider.js.map +0 -1
  368. package/dist/types-CO0XLEN6.d.cts +0 -973
  369. package/dist/types-CrtIcRcK.d.ts +0 -973
@@ -1,82 +0,0 @@
1
- 'use client';
2
- 'use strict';
3
-
4
- var react = require('react');
5
-
6
- // src/hooks/useXAPI.ts
7
- var BACKOFF_MS = [1e3, 2e3, 4e3];
8
- function applyIdentity(statement, cfg) {
9
- const isAnonymous = statement.actor?.account?.name === "anonymous" && statement.actor.account.homePage === "https://github.com/intellectif/learning-kit";
10
- const isSdkObjectId = statement.object?.objectType === "Activity" && typeof statement.object.id === "string" && statement.object.id.startsWith("urn:learning-kit:activity:");
11
- if (!isAnonymous && !isSdkObjectId) {
12
- return statement;
13
- }
14
- const mappedId = isSdkObjectId && cfg.activityId ? typeof cfg.activityId === "function" ? cfg.activityId(statement.object.id) : cfg.activityId : void 0;
15
- return {
16
- ...statement,
17
- ...isAnonymous && cfg.actor !== void 0 ? { actor: cfg.actor } : {},
18
- ...mappedId !== void 0 ? { object: { ...statement.object, id: mappedId } } : {}
19
- };
20
- }
21
- function toBase64Utf8(input) {
22
- const bytes = new TextEncoder().encode(input);
23
- let binary = "";
24
- for (const byte of bytes) {
25
- binary += String.fromCharCode(byte);
26
- }
27
- return btoa(binary);
28
- }
29
- function authHeader(auth) {
30
- return auth.type === "basic" ? `Basic ${toBase64Utf8(`${auth.username}:${auth.password}`)}` : `Bearer ${auth.token}`;
31
- }
32
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
33
- function useXAPI(config) {
34
- const configRef = react.useRef(config);
35
- configRef.current = config;
36
- const sendStatement = react.useCallback(async (rawStatement) => {
37
- const cfg = configRef.current;
38
- const statement = applyIdentity(rawStatement, cfg);
39
- const maxAttempts = 1 + BACKOFF_MS.length;
40
- for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
41
- let statusCode;
42
- let message = "Request failed";
43
- try {
44
- const response = await fetch(cfg.endpoint, {
45
- method: "POST",
46
- headers: {
47
- "Content-Type": "application/json",
48
- "X-Experience-API-Version": "1.0.3",
49
- Authorization: authHeader(cfg.auth)
50
- },
51
- body: JSON.stringify(statement)
52
- });
53
- if (response.ok) {
54
- return;
55
- }
56
- statusCode = response.status;
57
- message = `LRS responded with ${response.status}`;
58
- if (response.status < 500) {
59
- cfg.onError?.({ statement, attempt, statusCode, message });
60
- return;
61
- }
62
- } catch (error) {
63
- message = error instanceof Error ? error.message : "Network error";
64
- }
65
- if (attempt === maxAttempts) {
66
- cfg.onError?.({
67
- statement,
68
- attempt,
69
- ...statusCode !== void 0 ? { statusCode } : {},
70
- message
71
- });
72
- return;
73
- }
74
- await sleep(BACKOFF_MS[attempt - 1]);
75
- }
76
- }, []);
77
- return { sendStatement };
78
- }
79
-
80
- exports.useXAPI = useXAPI;
81
- //# sourceMappingURL=chunk-PNNUPUH4.cjs.map
82
- //# sourceMappingURL=chunk-PNNUPUH4.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/useXAPI.ts"],"names":["useRef","useCallback"],"mappings":"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","file":"chunk-PNNUPUH4.cjs","sourcesContent":["'use client';\n\nimport type { XAPIConfig, XAPIStatement } from '@intellectif/lk-core';\nimport { useCallback, useRef } from 'react';\n\n/** Backoff before retry 1 / 2 / 3 (Req 10.4). */\nconst BACKOFF_MS = [1000, 2000, 4000] as const;\n\n/**\n * Applies the configured learner identity to a statement built by an activity\n * component. Components emit an anonymous placeholder actor and a\n * `urn:learning-kit:activity:*` object id (they cannot know identity — Req\n * 3.1); this hook is the documented place where `XAPIConfig.actor` and\n * `XAPIConfig.activityId` take over. Conservative on purpose: the actor is\n * replaced only when the statement still carries the SDK's anonymous\n * placeholder, and the object id only when it is still the SDK URN — a\n * consumer that already rewrote either keeps its own values.\n */\nfunction applyIdentity(statement: XAPIStatement, cfg: XAPIConfig): XAPIStatement {\n const isAnonymous =\n statement.actor?.account?.name === 'anonymous' &&\n statement.actor.account.homePage === 'https://github.com/intellectif/learning-kit';\n const isSdkObjectId =\n statement.object?.objectType === 'Activity' &&\n typeof statement.object.id === 'string' &&\n statement.object.id.startsWith('urn:learning-kit:activity:');\n\n if (!isAnonymous && !isSdkObjectId) {\n return statement;\n }\n const mappedId =\n isSdkObjectId && cfg.activityId\n ? typeof cfg.activityId === 'function'\n ? cfg.activityId(statement.object.id)\n : cfg.activityId\n : undefined;\n return {\n ...statement,\n ...(isAnonymous && cfg.actor !== undefined ? { actor: cfg.actor } : {}),\n ...(mappedId !== undefined ? { object: { ...statement.object, id: mappedId } } : {}),\n };\n}\n\n/** UTF-8-safe base64 (`btoa` is Latin1-only and breaks on non-ASCII creds). */\nfunction toBase64Utf8(input: string): string {\n const bytes = new TextEncoder().encode(input);\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nfunction authHeader(auth: XAPIConfig['auth']): string {\n return auth.type === 'basic'\n ? `Basic ${toBase64Utf8(`${auth.username}:${auth.password}`)}`\n : `Bearer ${auth.token}`;\n}\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport interface UseXAPIResult {\n /**\n * Sends a statement to the configured LRS. **Never rejects** — xAPI is\n * fire-and-forget telemetry that must not break the learner's activity\n * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,\n * up to 3 retries); a 4xx fails immediately. Any final failure is delivered\n * to `config.onError`.\n */\n sendStatement: (statement: XAPIStatement) => Promise<void>;\n}\n\n/**\n * Delivers xAPI statements to a Learning Record Store, fire-and-forget.\n *\n * Telemetry must never break the learner's attempt, so\n * {@link UseXAPIResult.sendStatement} **never rejects**: network errors and 5xx\n * responses are retried (backoff 1s / 2s / 4s, up to 3 retries), a 4xx fails\n * immediately, and any final failure is reported to `config.onError` instead of\n * throwing. See `XAPIConfig` in `@intellectif/lk-core` for the options.\n *\n * The hook is also where learner identity is applied. Activity components\n * cannot know who the learner is, so they emit an anonymous placeholder actor\n * and a `urn:learning-kit:activity:*` object id; this hook substitutes\n * `config.actor` and `config.activityId` on the way out — and only while those\n * placeholders are still in place, so a statement you rewrote yourself is left\n * alone.\n *\n * `sendStatement` keeps a stable identity across renders even when `config` is\n * an inline object, so it is safe in a dependency array.\n *\n * ```tsx\n * const { sendStatement } = useXAPI({\n * endpoint: 'https://your-lrs.example/xapi/statements',\n * auth: { type: 'bearer', token: 'YOUR_TOKEN' },\n * activityId: 'https://your-app.example/quiz/capital-jp',\n * actor: { objectType: 'Agent', mbox: 'mailto:learner@example.com' },\n * onError: (e) => console.error('xAPI send failed', e),\n * });\n *\n * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />\n * ```\n */\nexport function useXAPI(config: XAPIConfig): UseXAPIResult {\n // Keep the latest config without changing `sendStatement`'s identity when\n // callers pass an inline config object.\n const configRef = useRef(config);\n configRef.current = config;\n\n const sendStatement = useCallback(async (rawStatement: XAPIStatement): Promise<void> => {\n const cfg = configRef.current;\n const statement = applyIdentity(rawStatement, cfg);\n const maxAttempts = 1 + BACKOFF_MS.length;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n let statusCode: number | undefined;\n let message = 'Request failed';\n\n try {\n const response = await fetch(cfg.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Experience-API-Version': '1.0.3',\n Authorization: authHeader(cfg.auth),\n },\n body: JSON.stringify(statement),\n });\n\n if (response.ok) {\n return;\n }\n\n statusCode = response.status;\n message = `LRS responded with ${response.status}`;\n\n // Only network errors and 5xx are retryable (Req 10.4). A 4xx is a\n // client error — fail immediately rather than waste retries.\n if (response.status < 500) {\n cfg.onError?.({ statement, attempt, statusCode, message });\n return;\n }\n } catch (error) {\n message = error instanceof Error ? error.message : 'Network error';\n }\n\n if (attempt === maxAttempts) {\n cfg.onError?.({\n statement,\n attempt,\n ...(statusCode !== undefined ? { statusCode } : {}),\n message,\n });\n return;\n }\n\n await sleep(BACKOFF_MS[attempt - 1]);\n }\n }, []);\n\n return { sendStatement };\n}\n"]}
@@ -1,433 +0,0 @@
1
- 'use client';
2
- 'use strict';
3
-
4
- var chunkW6UMY7PF_cjs = require('./chunk-W6UMY7PF.cjs');
5
- var chunkOJGTJOWI_cjs = require('./chunk-OJGTJOWI.cjs');
6
- var chunkVPU6UY4O_cjs = require('./chunk-VPU6UY4O.cjs');
7
- var chunkJ2QIHZ3H_cjs = require('./chunk-J2QIHZ3H.cjs');
8
- var chunkFISEZBLF_cjs = require('./chunk-FISEZBLF.cjs');
9
- var chunk54DX6SLS_cjs = require('./chunk-54DX6SLS.cjs');
10
- var chunkUKUHVCZX_cjs = require('./chunk-UKUHVCZX.cjs');
11
- var chunkXOR4MPEN_cjs = require('./chunk-XOR4MPEN.cjs');
12
- var chunkNFGUJ52G_cjs = require('./chunk-NFGUJ52G.cjs');
13
- var lkCore = require('@intellectif/lk-core');
14
- var react = require('react');
15
- var jsxRuntime = require('react/jsx-runtime');
16
-
17
- function selectionOf(response) {
18
- return response?.type === "multiple-choice" ? response.selectedOptionIds : [];
19
- }
20
- function isAnswerOption(detail, wasSelected) {
21
- switch (detail.outcome) {
22
- case "correct":
23
- case "incorrect-omission":
24
- return true;
25
- case "incorrect":
26
- case "correct-omission":
27
- return false;
28
- default:
29
- return wasSelected ? chunk54DX6SLS_cjs.legacyCorrect(detail) === true : chunk54DX6SLS_cjs.legacyCorrect(detail) !== true;
30
- }
31
- }
32
- function reviewAnnouncement(outcome, s) {
33
- if (outcome === void 0) {
34
- return null;
35
- }
36
- if (outcome.status === "scored") {
37
- const overall = outcome.feedback;
38
- return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${overall ? ` ${overall}` : ""}`;
39
- }
40
- if (outcome.status === "deferred") {
41
- return s.notGradedYet;
42
- }
43
- if (outcome.status === "unscorable") {
44
- return s.noGradeAvailable;
45
- }
46
- return null;
47
- }
48
- function MultipleChoice({
49
- data,
50
- onComplete,
51
- onSubmit,
52
- value,
53
- defaultValue,
54
- defaultSubmitted,
55
- onChange,
56
- renderMode = "practice",
57
- outcome,
58
- sanitizeHtml,
59
- mediaBudget,
60
- mediaStrings,
61
- onInteraction,
62
- theme,
63
- locale,
64
- disabled,
65
- shuffleSeed,
66
- strings,
67
- ai: aiProp,
68
- delivery,
69
- scoring
70
- }) {
71
- const s = chunkNFGUJ52G_cjs.useLkStrings(strings);
72
- const ai = chunkOJGTJOWI_cjs.useLearnerAi(aiProp);
73
- const policy = chunkVPU6UY4O_cjs.useDeliveryPolicy(delivery);
74
- const scoringPolicy = chunkW6UMY7PF_cjs.useItemScoringPolicy(scoring);
75
- const devError = react.useMemo(() => {
76
- if (!chunk54DX6SLS_cjs.isDevelopment()) {
77
- return null;
78
- }
79
- if (data.redacted === true) {
80
- return null;
81
- }
82
- const result = lkCore.validateActivity("multiple-choice", data);
83
- return result.success ? null : new lkCore.ActivitySchemaError("multiple-choice", result.errors);
84
- }, [data]);
85
- const sessionIdRef = react.useRef(null);
86
- const { state, start, complete, getTimeSpent, reset } = chunkXOR4MPEN_cjs.useActivityState(
87
- defaultSubmitted === true ? "completed" : "idle"
88
- );
89
- const tries = chunkW6UMY7PF_cjs.useTries({
90
- policy: scoringPolicy,
91
- graded: renderMode === "practice" && policy.feedback,
92
- submitted: state === "completed",
93
- disabled: disabled === true
94
- });
95
- const resetTries = tries.reset;
96
- const closeQuestion = tries.close;
97
- const [internalSelection, setInternalSelection] = react.useState(
98
- () => selectionOf(defaultValue)
99
- );
100
- const [summary, setSummary] = react.useState(null);
101
- const [overall, setOverall] = react.useState(null);
102
- const seedHintsRef = react.useRef(chunkW6UMY7PF_cjs.hintsOf(value ?? defaultValue));
103
- const rootRef = react.useRef(null);
104
- const feedbackRef = react.useRef(null);
105
- const focusAfterRef = react.useRef(null);
106
- const defaultValueRef = react.useRef(defaultValue);
107
- react.useEffect(() => {
108
- defaultValueRef.current = defaultValue;
109
- }, [defaultValue]);
110
- const defaultSubmittedRef = react.useRef(defaultSubmitted);
111
- react.useEffect(() => {
112
- defaultSubmittedRef.current = defaultSubmitted;
113
- }, [defaultSubmitted]);
114
- const lastDataRef = react.useRef(data);
115
- react.useEffect(() => {
116
- if (lastDataRef.current === data) {
117
- return;
118
- }
119
- lastDataRef.current = data;
120
- setInternalSelection(selectionOf(defaultValueRef.current));
121
- setSummary(null);
122
- setOverall(null);
123
- seedHintsRef.current = chunkW6UMY7PF_cjs.hintsOf(defaultValueRef.current);
124
- resetTries();
125
- reset(defaultSubmittedRef.current === true ? "completed" : "idle");
126
- }, [data, reset, resetTries]);
127
- const displayedOptions = react.useMemo(() => {
128
- if (!data.shuffle) {
129
- return [...data.options];
130
- }
131
- const seedSource = shuffleSeed ?? (sessionIdRef.current ??= chunk54DX6SLS_cjs.randomSessionId());
132
- return lkCore.seededShuffle(data.options, `${seedSource}:${data.id}`);
133
- }, [data, shuffleSeed]);
134
- const reviewDetails = react.useMemo(() => {
135
- if (renderMode !== "review" || outcome === void 0 || outcome.status !== "scored") {
136
- return null;
137
- }
138
- return new Map(outcome.details.map((detail) => [detail.itemId, detail]));
139
- }, [renderMode, outcome]);
140
- const answered = state === "completed";
141
- const chosen = value !== void 0 ? selectionOf(value) : internalSelection;
142
- const aiHints = chunkW6UMY7PF_cjs.useComponentAiHints({
143
- ai,
144
- data,
145
- renderMode,
146
- submitted: answered,
147
- disabled: disabled === true,
148
- response: { type: "multiple-choice", selectedOptionIds: chosen },
149
- locale,
150
- onInteraction,
151
- strings: s,
152
- delivery: policy
153
- });
154
- const hintsRevealed = renderMode === "practice" ? seedHintsRef.current + aiHints.used : 0;
155
- const responseOf = (selectedOptionIds) => ({
156
- type: "multiple-choice",
157
- selectedOptionIds,
158
- ...hintsRevealed > 0 ? { hintsRevealed } : {}
159
- });
160
- const hintsSeenRef = react.useRef(aiHints.used);
161
- react.useEffect(() => {
162
- if (hintsSeenRef.current === aiHints.used) {
163
- return;
164
- }
165
- hintsSeenRef.current = aiHints.used;
166
- if (aiHints.used > 0) {
167
- onChange?.(responseOf(chosen));
168
- }
169
- }, [aiHints.used]);
170
- react.useEffect(() => {
171
- const target = focusAfterRef.current;
172
- if (target === null) {
173
- return;
174
- }
175
- focusAfterRef.current = null;
176
- if (target === "answer") {
177
- rootRef.current?.querySelector("input:not(:disabled)")?.focus();
178
- } else {
179
- feedbackRef.current?.focus();
180
- }
181
- });
182
- if (devError) {
183
- throw devError;
184
- }
185
- if (data.redacted === true && renderMode === "practice") {
186
- throw new Error(
187
- `Multiple Choice "${data.id}" received redacted activity data in renderMode "practice", which grades locally and has no answer key to grade against. Render redacted data with renderMode="exam" (server grades) or "review" (pass \`outcome\`).`
188
- );
189
- }
190
- const isSingle = data.mode === "single";
191
- const isExam = renderMode === "exam";
192
- const isReview = renderMode === "review";
193
- const submitted = state === "completed";
194
- const inactive = disabled === true || submitted || isReview;
195
- const isControlled = value !== void 0;
196
- const selected = isControlled ? selectionOf(value) : internalSelection;
197
- const reveal = isReview || renderMode === "practice" && submitted;
198
- const marks = reveal && policy.feedback;
199
- const solutions = marks && policy.solutions && !tries.open;
200
- const fireInteraction = (type, payload) => {
201
- onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });
202
- };
203
- const emitChange = (selectedOptionIds) => {
204
- if (!isControlled) {
205
- setInternalSelection(selectedOptionIds);
206
- }
207
- onChange?.(responseOf(selectedOptionIds));
208
- };
209
- const selectSingle = (optionId) => {
210
- if (inactive) {
211
- return;
212
- }
213
- if (state === "idle") {
214
- start();
215
- }
216
- emitChange([optionId]);
217
- fireInteraction("option-selected", { optionId });
218
- };
219
- const toggleMulti = (optionId, checked) => {
220
- if (inactive) {
221
- return;
222
- }
223
- if (state === "idle") {
224
- start();
225
- }
226
- emitChange(checked ? [...selected, optionId] : selected.filter((id) => id !== optionId));
227
- fireInteraction(checked ? "option-selected" : "option-deselected", { optionId });
228
- };
229
- const handleSubmit = (event) => {
230
- event.preventDefault();
231
- if (inactive) {
232
- return;
233
- }
234
- const response = responseOf(selected);
235
- onSubmit?.(response);
236
- if (isExam) {
237
- complete();
238
- setSummary(s.answerSubmitted);
239
- fireInteraction("submitted", { selectedOptionIds: selected });
240
- return;
241
- }
242
- const answer = lkCore.score("multiple-choice", data, response);
243
- complete();
244
- const timeSpent = getTimeSpent();
245
- const counted = tries.record({
246
- score: answer.score,
247
- maxScore: answer.maxScore,
248
- hintsRevealed
249
- });
250
- const mine = counted.tries[counted.tries.length - 1];
251
- const costed = mine === void 0 ? answer.score : mine.scored;
252
- const scoringResult = costed === answer.score ? answer : {
253
- ...answer,
254
- score: costed,
255
- passed: lkCore.computePassThreshold(data, costed)
256
- };
257
- const passed = counted.score === scoringResult.score ? scoringResult.passed : lkCore.computePassThreshold(data, counted.score);
258
- const xapiStatement = lkCore.xAPIBuilder.buildAnsweredStatement({
259
- actor: chunk54DX6SLS_cjs.ANONYMOUS_ACTOR,
260
- object: {
261
- id: chunk54DX6SLS_cjs.objectIdFor(data.id),
262
- name: { [data.locale ?? "en-US"]: data.title },
263
- // Activity-type IRI, interaction type and correct-responses pattern
264
- // come from the REGISTERED descriptor, so a consumer-registered type
265
- // gets correct interop without touching this component.
266
- ...lkCore.xapiDefinitionFor(data),
267
- choices: data.options.map((option) => ({
268
- id: option.id,
269
- description: { [data.locale ?? "en-US"]: option.text }
270
- }))
271
- },
272
- scoringResult,
273
- timeSpentMs: timeSpent,
274
- response: selected.join(",")
275
- });
276
- onComplete?.(
277
- chunkJ2QIHZ3H_cjs.stampTake(
278
- {
279
- score: counted.score,
280
- maxScore: counted.maxScore,
281
- passed,
282
- timeSpent,
283
- xapiStatement
284
- },
285
- chunkJ2QIHZ3H_cjs.mintTake()
286
- )
287
- );
288
- setOverall(answer.feedback);
289
- setSummary(
290
- `${s.answerSubmitted} ${s.scoreAnnouncement(Math.round(counted.score * 100), passed)}`
291
- );
292
- fireInteraction("submitted", {
293
- selectedOptionIds: selected,
294
- score: scoringResult.score
295
- });
296
- };
297
- const retry = () => {
298
- reset("idle");
299
- setSummary(null);
300
- setOverall(null);
301
- focusAfterRef.current = "answer";
302
- };
303
- const closeTries = () => {
304
- closeQuestion();
305
- focusAfterRef.current = "feedback";
306
- };
307
- const questionId = `${data.id}-question`;
308
- const questionHtml = sanitizeHtml !== void 0 && data.questionHtml !== void 0 ? sanitizeHtml(data.questionHtml) : null;
309
- const optionList = displayedOptions.map((option) => {
310
- const checked = selected.includes(option.id);
311
- let correctness;
312
- const markable = marks && (solutions || checked);
313
- if (isReview) {
314
- const detail = reviewDetails?.get(option.id);
315
- correctness = !markable || detail === void 0 ? void 0 : String(isAnswerOption(detail, checked));
316
- } else if (markable) {
317
- correctness = String(option.isCorrect);
318
- }
319
- const media = option.media;
320
- const picture = media?.type === "image" ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: "lk-mc-option-image", src: media.url, alt: media.alt ?? "" }) : null;
321
- const label = /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "lk-mc-option", "data-correct": correctness, children: [
322
- /* @__PURE__ */ jsxRuntime.jsx(
323
- "input",
324
- {
325
- type: isSingle ? "radio" : "checkbox",
326
- name: isSingle ? `${data.id}-options` : void 0,
327
- value: option.id,
328
- checked,
329
- disabled: inactive,
330
- "aria-disabled": inactive || void 0,
331
- onChange: (e) => isSingle ? selectSingle(option.id) : toggleMulti(option.id, e.target.checked)
332
- }
333
- ),
334
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.text }),
335
- picture,
336
- markable && option.feedback ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-mc-option-feedback", role: "note", children: option.feedback }) : null
337
- ] });
338
- if (media?.type !== "audio") {
339
- return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: label }, option.id);
340
- }
341
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-mc-option-media", children: [
342
- label,
343
- /* @__PURE__ */ jsxRuntime.jsx(
344
- "audio",
345
- {
346
- className: "lk-mc-option-audio",
347
- src: media.url,
348
- controls: true,
349
- preload: "none",
350
- "aria-label": media.alt ?? option.text,
351
- children: media.captionsUrl ? /* @__PURE__ */ jsxRuntime.jsx("track", { kind: "captions", src: media.captionsUrl, label: media.alt ?? option.text }) : null
352
- }
353
- )
354
- ] }, option.id);
355
- });
356
- const extra = !isReview && policy.feedback && submitted && tries.counted !== null ? chunkW6UMY7PF_cjs.triesSummary(s, scoringPolicy, tries.counted, tries.open) : "";
357
- const announced = summary === null ? null : `${summary}${extra ? ` ${extra}` : ""}${overall ? ` ${overall}` : ""}`;
358
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-mc", lang: locale, style: theme, ref: rootRef, children: [
359
- data.media ? /* @__PURE__ */ jsxRuntime.jsx(
360
- chunkUKUHVCZX_cjs.ActivityMedia,
361
- {
362
- media: data.media,
363
- renderMode,
364
- ...mediaBudget !== void 0 ? { mediaBudget } : {},
365
- ...mediaStrings !== void 0 ? { mediaStrings } : {},
366
- ...strings !== void 0 ? { strings } : {},
367
- ...onInteraction !== void 0 ? { onInteraction } : {},
368
- ...locale !== void 0 ? { locale } : {}
369
- }
370
- ) : null,
371
- /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { disabled: inactive, children: [
372
- questionHtml === null ? /* @__PURE__ */ jsxRuntime.jsx("legend", { id: questionId, children: data.question }) : /* @__PURE__ */ jsxRuntime.jsx(
373
- "legend",
374
- {
375
- id: questionId,
376
- dangerouslySetInnerHTML: { __html: questionHtml }
377
- }
378
- ),
379
- isSingle ? /* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-labelledby": questionId, children: optionList }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: optionList }),
380
- aiHints.offered && renderMode === "practice" ? /* @__PURE__ */ jsxRuntime.jsx(chunkW6UMY7PF_cjs.HintCost, { policy: scoringPolicy, strings: s }) : null,
381
- /* @__PURE__ */ jsxRuntime.jsx(chunkW6UMY7PF_cjs.AiHints, { help: aiHints, ai, strings: s }),
382
- isReview ? null : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", disabled: inactive, children: s.submit })
383
- ] }) }),
384
- /* @__PURE__ */ jsxRuntime.jsx(
385
- chunkVPU6UY4O_cjs.FeedbackRegion,
386
- {
387
- id: `${data.id}-feedback`,
388
- ...scoringPolicy.retries > 0 ? { ref: feedbackRef } : {},
389
- children: isReview ? (
390
- // A grade read back is feedback; "not graded yet" is not.
391
- policy.feedback || !chunkVPU6UY4O_cjs.outcomeShowsMarks(outcome) ? reviewAnnouncement(outcome, s) : null
392
- ) : (
393
- // Without feedback a submit says only that it was received, as
394
- // an exam's does — the score still reaches `onComplete`.
395
- policy.feedback || summary === "" ? announced : s.answerSubmitted
396
- )
397
- }
398
- ),
399
- /* @__PURE__ */ jsxRuntime.jsx(
400
- chunkW6UMY7PF_cjs.TryActions,
401
- {
402
- tries,
403
- solutions: policy.solutions,
404
- strings: s,
405
- onRetry: retry,
406
- onClose: closeTries
407
- }
408
- ),
409
- /* @__PURE__ */ jsxRuntime.jsx(
410
- chunkW6UMY7PF_cjs.AiExplanation,
411
- {
412
- ai,
413
- data,
414
- renderMode,
415
- submitted,
416
- response: { type: "multiple-choice", selectedOptionIds: selected },
417
- outcome,
418
- locale,
419
- onInteraction,
420
- strings: s,
421
- delivery: tries.open ? { ...policy, solutions: false } : policy
422
- }
423
- )
424
- ] });
425
- }
426
- function MultipleChoice2(props) {
427
- const strings = chunkNFGUJ52G_cjs.useLkStrings(props.strings);
428
- return /* @__PURE__ */ jsxRuntime.jsx(chunkFISEZBLF_cjs.ActivityErrorBoundary, { activityTitle: props.data?.title, strings, children: /* @__PURE__ */ jsxRuntime.jsx(MultipleChoice, { ...props }) });
429
- }
430
-
431
- exports.MultipleChoice = MultipleChoice2;
432
- //# sourceMappingURL=chunk-QAZO3ANW.cjs.map
433
- //# sourceMappingURL=chunk-QAZO3ANW.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/MultipleChoice/MultipleChoice.tsx","../src/components/MultipleChoice/index.tsx"],"names":["legacyCorrect","useLkStrings","useLearnerAi","useDeliveryPolicy","useItemScoringPolicy","useMemo","isDevelopment","validateActivity","ActivitySchemaError","useRef","useActivityState","useTries","useState","hintsOf","useEffect","randomSessionId","seededShuffle","useComponentAiHints","score","computePassThreshold","xAPIBuilder","ANONYMOUS_ACTOR","objectIdFor","xapiDefinitionFor","stampTake","mintTake","jsxs","jsx","Fragment","triesSummary","ActivityMedia","HintCost","AiHints","FeedbackRegion","outcomeShowsMarks","TryActions","AiExplanation","MultipleChoice","ActivityErrorBoundary"],"mappings":"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","file":"chunk-QAZO3ANW.cjs","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n computePassThreshold,\n type ItemOutcome,\n type LearnerResponse,\n type MultipleChoiceData,\n type MultipleChoiceLearnerResponse,\n type MultipleChoiceOption,\n type ScoringDetail,\n score,\n seededShuffle,\n validateActivity,\n xAPIBuilder,\n xapiDefinitionFor,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, Fragment, useEffect, useMemo, useRef, useState } from 'react';\nimport { useLearnerAi } from '../../ai/LkAiProvider.js';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport type { LkStrings } from '../../i18n/strings.js';\nimport {\n ANONYMOUS_ACTOR,\n isDevelopment,\n legacyCorrect,\n objectIdFor,\n randomSessionId,\n} from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { AiExplanation, AiHints, useComponentAiHints } from '../shared/AiHelp.js';\nimport { outcomeShowsMarks, useDeliveryPolicy } from '../shared/delivery.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport { mintTake, stampTake } from '../shared/sequence-slot.js';\nimport {\n HintCost,\n hintsOf,\n TryActions,\n triesSummary,\n useItemScoringPolicy,\n useTries,\n} from '../shared/tries.js';\nimport type { ActivityProps } from '../types.js';\n\n/**\n * Selected option ids carried by a learner response. Any other response shape\n * (a caller wiring the wrong item's state through `value`) reads as \"nothing\n * selected\" rather than throwing mid-exam.\n */\nfunction selectionOf(response: LearnerResponse | undefined): string[] {\n return response?.type === 'multiple-choice' ? response.selectedOptionIds : [];\n}\n\n/**\n * Whether an option is part of the correct answer, derived from the SERVER's\n * outcome — review mode never holds an answer key of its own.\n * {@link ScoringDetail.outcome} states this unambiguously. A detail stored\n * before lk-core 0.3 carries only a `correct` flag, which means \"the learner\n * ACTED correctly on this option\", not \"this option is the answer\"; the fact is\n * still recoverable, because we know whether the learner selected it:\n * `isCorrect = wasSelected ? correct : !correct`.\n */\nfunction isAnswerOption(detail: ScoringDetail, wasSelected: boolean): boolean {\n switch (detail.outcome) {\n case 'correct':\n case 'incorrect-omission':\n return true;\n case 'incorrect':\n case 'correct-omission':\n return false;\n default:\n return wasSelected ? legacyCorrect(detail) === true : legacyCorrect(detail) !== true;\n }\n}\n\n/**\n * Announcement for `review` mode, built only from the server-supplied outcome.\n *\n * The authored overall feedback is appended by this function rather than being\n * baked into the score sentence, so a translation of \"Score 80%. Passed.\" never\n * has to carry the author's words with it.\n */\nfunction reviewAnnouncement(outcome: ItemOutcome | undefined, s: LkStrings): string | null {\n if (outcome === undefined) {\n return null;\n }\n if (outcome.status === 'scored') {\n const overall = outcome.feedback;\n return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${\n overall ? ` ${overall}` : ''\n }`;\n }\n if (outcome.status === 'deferred') {\n // Never \"0%\": ungraded is not the same as wrong.\n return s.notGradedYet;\n }\n if (outcome.status === 'unscorable') {\n return s.noGradeAvailable;\n }\n // `graded` is left silent here deliberately: a returned GradeRecord on a\n // multiple-choice item has no rubric to render, and announcing a bare\n // percentage would duplicate what the marking already shows.\n return null;\n}\n\nexport interface MultipleChoiceProps extends ActivityProps<MultipleChoiceData> {\n /**\n * Seed for the deterministic option shuffle. Supply one (e.g. the attempt\n * id) to make the shuffled order reproducible server-side, stable across\n * page reloads, and identical between SSR and hydration. When absent, a\n * random per-mount session seed is used (order stable within the mount\n * only — the behaviour before `shuffleSeed` existed).\n */\n shuffleSeed?: string;\n}\n\nexport function MultipleChoice({\n data,\n onComplete,\n onSubmit,\n value,\n defaultValue,\n defaultSubmitted,\n onChange,\n renderMode = 'practice',\n outcome,\n sanitizeHtml,\n mediaBudget,\n mediaStrings,\n onInteraction,\n theme,\n locale,\n disabled,\n shuffleSeed,\n strings,\n ai: aiProp,\n delivery,\n scoring,\n}: MultipleChoiceProps) {\n const s = useLkStrings(strings);\n const ai = useLearnerAi(aiProp);\n const policy = useDeliveryPolicy(delivery);\n const scoringPolicy = useItemScoringPolicy(scoring);\n\n // Dev-only boundary validation (Req 2.3). Throwing during render lets\n // ActivityErrorBoundary catch it. Memoised so it only re-runs on data change.\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n // A `redact()` projection cannot satisfy the full content schema — the\n // answer key is gone by design — and must not be checked against the\n // strict redacted schema either, since a `reveal: 'after-submit'`\n // projection legitimately carries answer-key fields for review renders.\n if (data.redacted === true) {\n return null;\n }\n const result = validateActivity('multiple-choice', data);\n return result.success ? null : new ActivitySchemaError('multiple-choice', result.errors);\n }, [data]);\n\n // Lazily created only when shuffling without a caller seed: avoids calling\n // crypto.randomUUID (absent on non-secure http origins) unless needed.\n const sessionIdRef = useRef<string | null>(null);\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n // Before anything that resets them: a new question starts with no tries.\n const tries = useTries({\n policy: scoringPolicy,\n graded: renderMode === 'practice' && policy.feedback,\n submitted: state === 'completed',\n disabled: disabled === true,\n });\n const resetTries = tries.reset;\n const closeQuestion = tries.close;\n // Uncontrolled state. `defaultValue` seeds the mount only (React convention);\n // to re-seed later, remount with a `key` or drive the component with `value`.\n const [internalSelection, setInternalSelection] = useState<string[]>(() =>\n selectionOf(defaultValue),\n );\n const [summary, setSummary] = useState<string | null>(null);\n // The authored overall feedback on the last graded answer, said after the\n // score and what the policy made of it.\n const [overall, setOverall] = useState<string | null>(null);\n // Hints the learner had been shown before this mount: a restored answer's\n // count stands, and the hints shown here add to it.\n const seedHintsRef = useRef(hintsOf(value ?? defaultValue));\n const rootRef = useRef<HTMLDivElement>(null);\n const feedbackRef = useRef<HTMLDivElement>(null);\n const focusAfterRef = useRef<'answer' | 'feedback' | null>(null);\n\n // Reset on data-prop CHANGE (Req 3.7). The identity guard makes the mount\n // run a no-op, which it always was before `defaultValue` existed — without\n // it this effect would wipe the seed immediately after the first render.\n // (It also makes the reset StrictMode-safe: a remount with unchanged data\n // no longer discards the learner's selection.)\n // Resets back to `defaultValue`, not to empty. Clearing looked safer — it\n // cannot carry a stale answer into a different question — but `data`\n // identity is a poor proxy for \"different question\": a parent that builds\n // entries in render (`activities={raw.map(redact)}`, the documented exam\n // pattern) hands over a new object every render, and clearing wiped every\n // RESTORED answer on the first unrelated re-render, silently. `defaultValue`\n // is by definition the caller's seed for the CURRENT data, which is what\n // FillInTheBlanks already reset to; the two now agree.\n const defaultValueRef = useRef(defaultValue);\n useEffect(() => {\n defaultValueRef.current = defaultValue;\n }, [defaultValue]);\n // A data change must return the item to its SEED, submitted state included —\n // resetting to idle unlocked work the learner had already committed.\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n const lastDataRef = useRef(data);\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInternalSelection(selectionOf(defaultValueRef.current));\n setSummary(null);\n setOverall(null);\n seedHintsRef.current = hintsOf(defaultValueRef.current);\n resetTries();\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset, resetTries]);\n\n const displayedOptions = useMemo<MultipleChoiceOption[]>(() => {\n if (!data.shuffle) {\n return [...data.options];\n }\n // biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization\n const seedSource = shuffleSeed ?? (sessionIdRef.current ??= randomSessionId());\n // The seed string is unchanged from when the algorithm lived in this file,\n // so an order a consumer recorded against a seed still reproduces.\n return seededShuffle(data.options, `${seedSource}:${data.id}`);\n }, [data, shuffleSeed]);\n\n // Per-option correctness for `review`, indexed by option id. Null unless the\n // caller supplied a SCORED outcome — the only source of truth this mode has.\n const reviewDetails = useMemo(() => {\n if (renderMode !== 'review' || outcome === undefined || outcome.status !== 'scored') {\n return null;\n }\n return new Map(outcome.details.map((detail) => [detail.itemId, detail]));\n }, [renderMode, outcome]);\n\n // Hints are a hook, so they are read here, before the throws below.\n const answered = state === 'completed';\n const chosen = value !== undefined ? selectionOf(value) : internalSelection;\n const aiHints = useComponentAiHints({\n ai,\n data,\n renderMode,\n submitted: answered,\n disabled: disabled === true,\n response: { type: 'multiple-choice', selectedOptionIds: chosen },\n locale,\n onInteraction,\n strings: s,\n delivery: policy,\n });\n // Every hint the learner has been shown on this question, counted from its\n // start: what a scoring policy charges for. Hints exist only in practice.\n const hintsRevealed = renderMode === 'practice' ? seedHintsRef.current + aiHints.used : 0;\n const responseOf = (selectedOptionIds: string[]): MultipleChoiceLearnerResponse => ({\n type: 'multiple-choice',\n selectedOptionIds,\n ...(hintsRevealed > 0 ? { hintsRevealed } : {}),\n });\n // A hint shown is part of the answer's record, so a host that restores an\n // answer restores what it cost: say so as it happens, not at the next click.\n const hintsSeenRef = useRef(aiHints.used);\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new hint is the trigger, and the response it reports is this render's\n useEffect(() => {\n if (hintsSeenRef.current === aiHints.used) {\n return;\n }\n hintsSeenRef.current = aiHints.used;\n if (aiHints.used > 0) {\n onChange?.(responseOf(chosen));\n }\n }, [aiHints.used]);\n // After \"Try again\" the learner is back at their answer; after \"Show answer\"\n // the buttons they pressed are gone, and the result is what is left.\n useEffect(() => {\n const target = focusAfterRef.current;\n if (target === null) {\n return;\n }\n focusAfterRef.current = null;\n if (target === 'answer') {\n rootRef.current?.querySelector<HTMLElement>('input:not(:disabled)')?.focus();\n } else {\n feedbackRef.current?.focus();\n }\n });\n\n // All hooks are called before these throws, so hook order stays stable.\n if (devError) {\n throw devError;\n }\n // Practice grades locally, which a redacted projection cannot support:\n // `score()` would throw from the submit handler — where no error boundary\n // can catch it — AFTER the learner has answered. Fail loudly at render\n // instead, in production too. Wiring an exam item into the self-grading\n // mode is precisely the accident `renderMode` exists to prevent.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Multiple Choice \"${data.id}\" received redacted activity data in renderMode \"practice\", ` +\n 'which grades locally and has no answer key to grade against. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const isSingle = data.mode === 'single';\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n const isControlled = value !== undefined;\n const selected = isControlled ? selectionOf(value) : internalSelection;\n /**\n * Whether correctness and authored feedback may be shown. Practice earns it\n * by grading locally after submit; review shows what the server already\n * graded. Exam never reveals anything — not before, not after submit.\n */\n const reveal = isReview || (renderMode === 'practice' && submitted);\n /**\n * What the delivery policy lets that reveal show. `marks`: right and wrong at\n * all, and the author's feedback. `solutions`: the right answer where the\n * learner did not choose it — without it, only the options the learner chose\n * are marked, so a missed correct option is not given away.\n */\n const marks = reveal && policy.feedback;\n // While the learner is offered another try, the right answer stays hidden:\n // the next try is for finding it.\n const solutions = marks && policy.solutions && !tries.open;\n\n const fireInteraction = (\n type: 'option-selected' | 'option-deselected' | 'submitted',\n payload: Record<string, unknown>,\n ): void => {\n onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });\n };\n\n /** Single funnel for every response change: owns state only when uncontrolled. */\n const emitChange = (selectedOptionIds: string[]): void => {\n if (!isControlled) {\n setInternalSelection(selectedOptionIds);\n }\n onChange?.(responseOf(selectedOptionIds));\n };\n\n const selectSingle = (optionId: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n emitChange([optionId]);\n fireInteraction('option-selected', { optionId });\n };\n\n const toggleMulti = (optionId: string, checked: boolean): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n emitChange(checked ? [...selected, optionId] : selected.filter((id) => id !== optionId));\n fireInteraction(checked ? 'option-selected' : 'option-deselected', { optionId });\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive) {\n return;\n }\n const response = responseOf(selected);\n // Always first, and before anything that can throw: an exam runner must be\n // able to persist the raw response no matter what happens after.\n onSubmit?.(response);\n\n if (isExam) {\n // No score(), no answer key read, no onComplete, no xAPI — the server\n // grades. The announcement deliberately carries no correctness signal.\n complete();\n setSummary(s.answerSubmitted);\n fireInteraction('submitted', { selectedOptionIds: selected });\n return;\n }\n\n const answer = score('multiple-choice', data as MultipleChoiceData, response);\n complete();\n const timeSpent = getTimeSpent();\n // The question's score under the policy: this try's answer, less what its\n // hints and the tries before it cost, or an earlier try's. With no policy\n // it is exactly what the answer scored.\n const counted = tries.record({\n score: answer.score,\n maxScore: answer.maxScore,\n hintsRevealed,\n });\n const mine = counted.tries[counted.tries.length - 1];\n const costed = mine === undefined ? answer.score : mine.scored;\n // The statement records this try, at what it scored after its costs.\n const scoringResult =\n costed === answer.score\n ? answer\n : {\n ...answer,\n score: costed,\n passed: computePassThreshold(data as MultipleChoiceData, costed),\n };\n const passed =\n counted.score === scoringResult.score\n ? scoringResult.passed\n : computePassThreshold(data as MultipleChoiceData, counted.score);\n const xapiStatement = xAPIBuilder.buildAnsweredStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n // Activity-type IRI, interaction type and correct-responses pattern\n // come from the REGISTERED descriptor, so a consumer-registered type\n // gets correct interop without touching this component.\n ...xapiDefinitionFor(data),\n choices: data.options.map((option) => ({\n id: option.id,\n description: { [data.locale ?? 'en-US']: option.text },\n })),\n },\n scoringResult,\n timeSpentMs: timeSpent,\n response: selected.join(','),\n });\n // Stamped, so a set this question sits in knows a later try replaces it.\n onComplete?.(\n stampTake(\n {\n score: counted.score,\n maxScore: counted.maxScore,\n passed,\n timeSpent,\n xapiStatement,\n },\n mintTake(),\n ),\n );\n // Core selects the authored overall feedback on `passed` (B3 fix): it is\n // the answer's, so it follows the answer's own grade.\n setOverall(answer.feedback);\n setSummary(\n `${s.answerSubmitted} ${s.scoreAnnouncement(Math.round(counted.score * 100), passed)}`,\n );\n fireInteraction('submitted', {\n selectedOptionIds: selected,\n score: scoringResult.score,\n });\n };\n\n /** \"Try again\": the answer stays, to be changed; the marks go. */\n const retry = (): void => {\n reset('idle');\n setSummary(null);\n setOverall(null);\n focusAfterRef.current = 'answer';\n };\n\n /** \"Show answer\": no more tries; the question shows what a finished one shows. */\n const closeTries = (): void => {\n closeQuestion();\n focusAfterRef.current = 'feedback';\n };\n\n const questionId = `${data.id}-question`;\n // Rich text renders ONLY through a caller-supplied sanitiser; without one we\n // fall back to the plain-text field, escaped by React (types.ts HtmlSanitizer).\n const questionHtml =\n sanitizeHtml !== undefined && data.questionHtml !== undefined\n ? sanitizeHtml(data.questionHtml)\n : null;\n\n const optionList = displayedOptions.map((option) => {\n const checked = selected.includes(option.id);\n // `data-correct` means \"this option is part of the correct answer\".\n let correctness: string | undefined;\n // An option the learner did not choose is marked only where solutions\n // show: marking the right one they missed would hand them the answer.\n const markable = marks && (solutions || checked);\n if (isReview) {\n const detail = reviewDetails?.get(option.id);\n correctness =\n !markable || detail === undefined ? undefined : String(isAnswerOption(detail, checked));\n } else if (markable) {\n correctness = String(option.isCorrect);\n }\n const media = option.media;\n // A picture goes INSIDE the label: it has no controls of its own, clicking\n // it is how a learner picks that option, and its `alt` joins the option's\n // accessible name. A recording cannot — see below.\n const picture =\n media?.type === 'image' ? (\n <img className=\"lk-mc-option-image\" src={media.url} alt={media.alt ?? ''} />\n ) : null;\n\n const label = (\n <label className=\"lk-mc-option\" data-correct={correctness}>\n <input\n type={isSingle ? 'radio' : 'checkbox'}\n name={isSingle ? `${data.id}-options` : undefined}\n value={option.id}\n checked={checked}\n disabled={inactive}\n aria-disabled={inactive || undefined}\n onChange={(e) =>\n isSingle ? selectSingle(option.id) : toggleMulti(option.id, e.target.checked)\n }\n />\n <span>{option.text}</span>\n {picture}\n {markable && option.feedback ? (\n <span className=\"lk-mc-option-feedback\" role=\"note\">\n {option.feedback}\n </span>\n ) : null}\n </label>\n );\n\n if (media?.type !== 'audio') {\n return <Fragment key={option.id}>{label}</Fragment>;\n }\n\n // A recording sits OUTSIDE the label, deliberately. A <label> activates its\n // control for any click inside it, so an <audio> nested in one would select\n // the option the moment the learner pressed play — and a listening item is\n // answered by comparing all the recordings before choosing any of them.\n // Selecting an option must stay something the learner does on purpose.\n return (\n <div className=\"lk-mc-option-media\" key={option.id}>\n {label}\n {/* biome-ignore lint/a11y/useMediaCaption: captions are optional in the data contract — a <track> is rendered when captionsUrl is provided; absence is the author's documented choice (Req 14.5) */}\n <audio\n className=\"lk-mc-option-audio\"\n src={media.url}\n controls\n preload=\"none\"\n aria-label={media.alt ?? option.text}\n >\n {media.captionsUrl ? (\n <track kind=\"captions\" src={media.captionsUrl} label={media.alt ?? option.text} />\n ) : null}\n </audio>\n </div>\n );\n });\n\n const extra =\n !isReview && policy.feedback && submitted && tries.counted !== null\n ? triesSummary(s, scoringPolicy, tries.counted, tries.open)\n : '';\n const announced =\n summary === null\n ? null\n : `${summary}${extra ? ` ${extra}` : ''}${overall ? ` ${overall}` : ''}`;\n\n return (\n <div className=\"lk-mc\" lang={locale} style={theme as CSSProperties | undefined} ref={rootRef}>\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n <form onSubmit={handleSubmit}>\n <fieldset disabled={inactive}>\n {questionHtml === null ? (\n <legend id={questionId}>{data.question}</legend>\n ) : (\n <legend\n id={questionId}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: HTML is the output of the caller-supplied sanitizeHtml (types.ts HtmlSanitizer contract)\n dangerouslySetInnerHTML={{ __html: questionHtml }}\n />\n )}\n {/*\n single: an explicit radiogroup is meaningful (fieldset's implicit\n role is `group`, not `radiogroup`). multi: the fieldset + legend\n already provide a named group — an explicit role=\"group\" here would\n be a redundant, duplicate same-named group in the a11y tree, so we\n use a plain layout div. (Refines the design ARIA sketch.)\n */}\n {isSingle ? (\n <div role=\"radiogroup\" aria-labelledby={questionId}>\n {optionList}\n </div>\n ) : (\n <div>{optionList}</div>\n )}\n {aiHints.offered && renderMode === 'practice' ? (\n <HintCost policy={scoringPolicy} strings={s} />\n ) : null}\n <AiHints help={aiHints} ai={ai} strings={s} />\n {/* review is read-only: there is nothing left to submit. */}\n {isReview ? null : (\n <button type=\"submit\" disabled={inactive}>\n {s.submit}\n </button>\n )}\n </fieldset>\n </form>\n <FeedbackRegion\n id={`${data.id}-feedback`}\n {...(scoringPolicy.retries > 0 ? { ref: feedbackRef } : {})}\n >\n {isReview\n ? // A grade read back is feedback; \"not graded yet\" is not.\n policy.feedback || !outcomeShowsMarks(outcome)\n ? reviewAnnouncement(outcome, s)\n : null\n : // Without feedback a submit says only that it was received, as\n // an exam's does — the score still reaches `onComplete`.\n policy.feedback || summary === ''\n ? announced\n : s.answerSubmitted}\n </FeedbackRegion>\n <TryActions\n tries={tries}\n solutions={policy.solutions}\n strings={s}\n onRetry={retry}\n onClose={closeTries}\n />\n <AiExplanation\n ai={ai}\n data={data}\n renderMode={renderMode}\n submitted={submitted}\n response={{ type: 'multiple-choice', selectedOptionIds: selected }}\n outcome={outcome}\n locale={locale}\n onInteraction={onInteraction}\n strings={s}\n // An explanation all but always names the answer: not while another\n // try is on offer.\n delivery={tries.open ? { ...policy, solutions: false } : policy}\n />\n </div>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport {\n MultipleChoice as MultipleChoiceCore,\n type MultipleChoiceProps,\n} from './MultipleChoice.js';\n\nexport type { MultipleChoiceProps } from './MultipleChoice.js';\n\n/**\n * Public Multiple Choice activity: the core component wrapped in\n * `ActivityErrorBoundary` so a render failure (incl. the dev schema-validation\n * throw) degrades to an accessible fallback instead of crashing the host.\n */\nexport function MultipleChoice(props: MultipleChoiceProps) {\n // Read here rather than in the boundary: a class component cannot call a\n // hook, and the fallback it renders is learner-facing text like any other.\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <MultipleChoiceCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
@@ -1,17 +0,0 @@
1
- 'use client';
2
- import { createContext, useContext } from 'react';
3
- import { jsx } from 'react/jsx-runtime';
4
-
5
- // src/ai/LkAiProvider.tsx
6
- var LkAiContext = createContext(null);
7
- function LkAiProvider({ ai, children }) {
8
- return /* @__PURE__ */ jsx(LkAiContext.Provider, { value: ai, children });
9
- }
10
- function useLearnerAi(override) {
11
- const context = useContext(LkAiContext);
12
- return override ?? context ?? void 0;
13
- }
14
-
15
- export { LkAiProvider, useLearnerAi };
16
- //# sourceMappingURL=chunk-RX3A6KIY.js.map
17
- //# sourceMappingURL=chunk-RX3A6KIY.js.map