@intellectif/lk-react 23.1.0 → 23.1.2

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 (360) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +9 -5
  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/{chunk-DC4CQCK5.js.map → ReadAloud-C8RhaUqV.js.map} +1 -1
  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-B6DyGqzh.d.cts +62 -0
  64. package/dist/ThemeProvider-B6DyGqzh.d.cts.map +1 -0
  65. package/dist/ThemeProvider-BCrxBaY-.d.ts +62 -0
  66. package/dist/ThemeProvider-BCrxBaY-.d.ts.map +1 -0
  67. package/dist/ThemeProvider-BRN1tj4n.cjs +187 -0
  68. package/dist/ThemeProvider-BRN1tj4n.cjs.map +1 -0
  69. package/dist/ThemeProvider-C7K9iMLX.js +158 -0
  70. package/dist/ThemeProvider-C7K9iMLX.js.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 -83
  78. package/dist/ai/LkAiProvider.d.ts +2 -83
  79. package/dist/ai/LkAiProvider.js +33 -2
  80. package/dist/ai/LkAiProvider.js.map +1 -1
  81. package/dist/ai/useAiHelp.cjs +7 -25
  82. package/dist/ai/useAiHelp.d.cts +175 -177
  83. package/dist/ai/useAiHelp.d.cts.map +1 -0
  84. package/dist/ai/useAiHelp.d.ts +175 -177
  85. package/dist/ai/useAiHelp.d.ts.map +1 -0
  86. package/dist/ai/useAiHelp.js +3 -4
  87. package/dist/components/ActivityPreview.cjs +3 -29
  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 -20
  91. package/dist/components/ActivitySequence.cjs +3 -30
  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 -21
  95. package/dist/components/Dictation.cjs +4 -21
  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 -12
  99. package/dist/components/FillInTheBlanks.cjs +4 -20
  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 -11
  103. package/dist/components/GapSelect.cjs +4 -20
  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 -11
  107. package/dist/components/InteractiveVideo.cjs +5 -32
  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 -19
  111. package/dist/components/MultipleChoice.cjs +4 -20
  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 -11
  115. package/dist/components/PronunciationFeedback.cjs +4 -17
  116. package/dist/components/PronunciationFeedback.d.cts +2 -90
  117. package/dist/components/PronunciationFeedback.d.ts +2 -90
  118. package/dist/components/PronunciationFeedback.js +3 -8
  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 -19
  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 -10
  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-6P4rJHrJ.d.cts +432 -0
  164. package/dist/index-6P4rJHrJ.d.cts.map +1 -0
  165. package/dist/index-90CX504k.d.ts +90 -0
  166. package/dist/index-90CX504k.d.ts.map +1 -0
  167. package/dist/index-B_SgnjsC.d.cts +291 -0
  168. package/dist/index-B_SgnjsC.d.cts.map +1 -0
  169. package/dist/index-BavVW5z5.d.cts +25 -0
  170. package/dist/index-BavVW5z5.d.cts.map +1 -0
  171. package/dist/index-BhHv6Fiu.d.cts +28 -0
  172. package/dist/index-BhHv6Fiu.d.cts.map +1 -0
  173. package/dist/index-Bsu8VciA.d.ts +432 -0
  174. package/dist/index-Bsu8VciA.d.ts.map +1 -0
  175. package/dist/index-C1KGpD1k.d.ts +49 -0
  176. package/dist/index-C1KGpD1k.d.ts.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-CO_SRFJj.d.ts +16 -0
  180. package/dist/index-CO_SRFJj.d.ts.map +1 -0
  181. package/dist/index-CSsuUsP7.d.cts +124 -0
  182. package/dist/index-CSsuUsP7.d.cts.map +1 -0
  183. package/dist/index-CunUyeuN.d.cts +78 -0
  184. package/dist/index-CunUyeuN.d.cts.map +1 -0
  185. package/dist/index-CzfRzks6.d.cts +90 -0
  186. package/dist/index-CzfRzks6.d.cts.map +1 -0
  187. package/dist/index-D14xtpBS.d.cts +24 -0
  188. package/dist/index-D14xtpBS.d.cts.map +1 -0
  189. package/dist/index-DHRPAPZf.d.ts +291 -0
  190. package/dist/index-DHRPAPZf.d.ts.map +1 -0
  191. package/dist/index-DLV6cK26.d.cts +16 -0
  192. package/dist/index-DLV6cK26.d.cts.map +1 -0
  193. package/dist/index-DbCCQ9cP.d.ts +124 -0
  194. package/dist/index-DbCCQ9cP.d.ts.map +1 -0
  195. package/dist/index-DeV5B2m5.d.ts +24 -0
  196. package/dist/index-DeV5B2m5.d.ts.map +1 -0
  197. package/dist/index-TZCJVSge.d.ts +28 -0
  198. package/dist/index-TZCJVSge.d.ts.map +1 -0
  199. package/dist/index-ZVvLHsd3.d.ts +25 -0
  200. package/dist/index-ZVvLHsd3.d.ts.map +1 -0
  201. package/dist/index-eQwBgpSw.d.ts +78 -0
  202. package/dist/index-eQwBgpSw.d.ts.map +1 -0
  203. package/dist/index.cjs +118 -163
  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 -29
  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/tries-CbbtZkdG.cjs +363 -0
  214. package/dist/tries-CbbtZkdG.cjs.map +1 -0
  215. package/dist/tries-DTHSrLCm.js +310 -0
  216. package/dist/tries-DTHSrLCm.js.map +1 -0
  217. package/dist/types-BOQd93x3.d.cts +994 -0
  218. package/dist/types-BOQd93x3.d.cts.map +1 -0
  219. package/dist/types-HIrgF_mS.d.ts +994 -0
  220. package/dist/types-HIrgF_mS.d.ts.map +1 -0
  221. package/dist/useAiHelp-B-ccDL5Q.js +906 -0
  222. package/dist/useAiHelp-B-ccDL5Q.js.map +1 -0
  223. package/dist/useAiHelp-h9yOLFqt.cjs +995 -0
  224. package/dist/useAiHelp-h9yOLFqt.cjs.map +1 -0
  225. package/dist/useSpeechRecorder--O_f-xvt.cjs +720 -0
  226. package/dist/useSpeechRecorder--O_f-xvt.cjs.map +1 -0
  227. package/dist/useSpeechRecorder-DtAYvl02.d.cts +154 -0
  228. package/dist/useSpeechRecorder-DtAYvl02.d.cts.map +1 -0
  229. package/dist/useSpeechRecorder-DtAYvl02.d.ts +154 -0
  230. package/dist/useSpeechRecorder-DtAYvl02.d.ts.map +1 -0
  231. package/dist/useSpeechRecorder-zIi9Dlw8.js +709 -0
  232. package/dist/useSpeechRecorder-zIi9Dlw8.js.map +1 -0
  233. package/package.json +10 -11
  234. package/dist/WrittenResponse-B7A5gHMj.d.ts +0 -115
  235. package/dist/WrittenResponse-BpL9p2Hn.d.cts +0 -115
  236. package/dist/ai/useAiHelp.cjs.map +0 -1
  237. package/dist/ai/useAiHelp.js.map +0 -1
  238. package/dist/chunk-2PNSVBLQ.cjs +0 -54
  239. package/dist/chunk-2PNSVBLQ.cjs.map +0 -1
  240. package/dist/chunk-2TW6WLBC.js +0 -80
  241. package/dist/chunk-2TW6WLBC.js.map +0 -1
  242. package/dist/chunk-4ZZWZSWI.js +0 -61
  243. package/dist/chunk-4ZZWZSWI.js.map +0 -1
  244. package/dist/chunk-6N43WDVG.js +0 -29
  245. package/dist/chunk-6N43WDVG.js.map +0 -1
  246. package/dist/chunk-7ALBSPYR.cjs +0 -436
  247. package/dist/chunk-7ALBSPYR.cjs.map +0 -1
  248. package/dist/chunk-7NFY3M3W.js +0 -234
  249. package/dist/chunk-7NFY3M3W.js.map +0 -1
  250. package/dist/chunk-7SB2MJA4.js +0 -29
  251. package/dist/chunk-7SB2MJA4.js.map +0 -1
  252. package/dist/chunk-ABJJ3LII.js +0 -434
  253. package/dist/chunk-ABJJ3LII.js.map +0 -1
  254. package/dist/chunk-BIGGXHAW.cjs +0 -342
  255. package/dist/chunk-BIGGXHAW.cjs.map +0 -1
  256. package/dist/chunk-C7QZE5BI.js +0 -430
  257. package/dist/chunk-C7QZE5BI.js.map +0 -1
  258. package/dist/chunk-CWTUWNV3.cjs +0 -2937
  259. package/dist/chunk-CWTUWNV3.cjs.map +0 -1
  260. package/dist/chunk-DC4CQCK5.js +0 -915
  261. package/dist/chunk-DS6HN3YR.cjs +0 -496
  262. package/dist/chunk-DS6HN3YR.cjs.map +0 -1
  263. package/dist/chunk-FDQR4GAZ.js +0 -240
  264. package/dist/chunk-FDQR4GAZ.js.map +0 -1
  265. package/dist/chunk-FKGMSOJF.js +0 -394
  266. package/dist/chunk-FKGMSOJF.js.map +0 -1
  267. package/dist/chunk-G6PXJ2SA.js +0 -823
  268. package/dist/chunk-G6PXJ2SA.js.map +0 -1
  269. package/dist/chunk-HNLRVRQR.js +0 -335
  270. package/dist/chunk-HNLRVRQR.js.map +0 -1
  271. package/dist/chunk-J3C72RPK.cjs +0 -31
  272. package/dist/chunk-J3C72RPK.cjs.map +0 -1
  273. package/dist/chunk-K63VPFOV.cjs +0 -134
  274. package/dist/chunk-K63VPFOV.cjs.map +0 -1
  275. package/dist/chunk-KFLIDTDU.cjs +0 -825
  276. package/dist/chunk-KFLIDTDU.cjs.map +0 -1
  277. package/dist/chunk-KHKH5LCT.cjs +0 -250
  278. package/dist/chunk-KHKH5LCT.cjs.map +0 -1
  279. package/dist/chunk-LBEKRN6Y.cjs +0 -664
  280. package/dist/chunk-LBEKRN6Y.cjs.map +0 -1
  281. package/dist/chunk-LPUWXIPR.cjs +0 -578
  282. package/dist/chunk-LPUWXIPR.cjs.map +0 -1
  283. package/dist/chunk-MCO52PV5.js +0 -520
  284. package/dist/chunk-MCO52PV5.js.map +0 -1
  285. package/dist/chunk-MKXEM2C5.cjs +0 -396
  286. package/dist/chunk-MKXEM2C5.cjs.map +0 -1
  287. package/dist/chunk-MXNC5UNO.js +0 -563
  288. package/dist/chunk-MXNC5UNO.js.map +0 -1
  289. package/dist/chunk-NAK55BYU.cjs +0 -859
  290. package/dist/chunk-NAK55BYU.cjs.map +0 -1
  291. package/dist/chunk-NDBMKGQ5.cjs +0 -599
  292. package/dist/chunk-NDBMKGQ5.cjs.map +0 -1
  293. package/dist/chunk-OD65OZIW.cjs +0 -159
  294. package/dist/chunk-OD65OZIW.cjs.map +0 -1
  295. package/dist/chunk-ORT3KLGI.js +0 -50
  296. package/dist/chunk-ORT3KLGI.js.map +0 -1
  297. package/dist/chunk-PNNUPUH4.cjs +0 -82
  298. package/dist/chunk-PNNUPUH4.cjs.map +0 -1
  299. package/dist/chunk-PWHECW6N.js +0 -2934
  300. package/dist/chunk-PWHECW6N.js.map +0 -1
  301. package/dist/chunk-RBS5A2DF.js +0 -857
  302. package/dist/chunk-RBS5A2DF.js.map +0 -1
  303. package/dist/chunk-RPWUDXG5.cjs +0 -63
  304. package/dist/chunk-RPWUDXG5.cjs.map +0 -1
  305. package/dist/chunk-TCDJY3H6.js +0 -494
  306. package/dist/chunk-TCDJY3H6.js.map +0 -1
  307. package/dist/chunk-TP5UMRAU.cjs +0 -918
  308. package/dist/chunk-TP5UMRAU.cjs.map +0 -1
  309. package/dist/chunk-TS7J6DTY.js +0 -597
  310. package/dist/chunk-TS7J6DTY.js.map +0 -1
  311. package/dist/chunk-TUVENMXB.cjs +0 -20
  312. package/dist/chunk-TUVENMXB.cjs.map +0 -1
  313. package/dist/chunk-UDCQTOVU.cjs +0 -523
  314. package/dist/chunk-UDCQTOVU.cjs.map +0 -1
  315. package/dist/chunk-UHKZXOXD.js +0 -128
  316. package/dist/chunk-UHKZXOXD.js.map +0 -1
  317. package/dist/chunk-V6BA44DS.cjs +0 -236
  318. package/dist/chunk-V6BA44DS.cjs.map +0 -1
  319. package/dist/chunk-XO5R73Y4.js +0 -653
  320. package/dist/chunk-XO5R73Y4.js.map +0 -1
  321. package/dist/chunk-XOR4MPEN.cjs +0 -31
  322. package/dist/chunk-XOR4MPEN.cjs.map +0 -1
  323. package/dist/chunk-YORQQXGO.js +0 -155
  324. package/dist/chunk-YORQQXGO.js.map +0 -1
  325. package/dist/chunk-YY4PFR3Z.cjs +0 -432
  326. package/dist/chunk-YY4PFR3Z.cjs.map +0 -1
  327. package/dist/chunk-ZPI6Q42R.js +0 -17
  328. package/dist/chunk-ZPI6Q42R.js.map +0 -1
  329. package/dist/components/ActivityPreview.cjs.map +0 -1
  330. package/dist/components/ActivityPreview.js.map +0 -1
  331. package/dist/components/ActivitySequence.cjs.map +0 -1
  332. package/dist/components/ActivitySequence.js.map +0 -1
  333. package/dist/components/Dictation.cjs.map +0 -1
  334. package/dist/components/Dictation.js.map +0 -1
  335. package/dist/components/FillInTheBlanks.cjs.map +0 -1
  336. package/dist/components/FillInTheBlanks.js.map +0 -1
  337. package/dist/components/GapSelect.cjs.map +0 -1
  338. package/dist/components/GapSelect.js.map +0 -1
  339. package/dist/components/InteractiveVideo.cjs.map +0 -1
  340. package/dist/components/InteractiveVideo.js.map +0 -1
  341. package/dist/components/MultipleChoice.cjs.map +0 -1
  342. package/dist/components/MultipleChoice.js.map +0 -1
  343. package/dist/components/PronunciationFeedback.cjs.map +0 -1
  344. package/dist/components/PronunciationFeedback.js.map +0 -1
  345. package/dist/components/ReadAloud.cjs.map +0 -1
  346. package/dist/components/ReadAloud.js.map +0 -1
  347. package/dist/components/StimulusPanel.cjs.map +0 -1
  348. package/dist/components/StimulusPanel.js.map +0 -1
  349. package/dist/components/WrittenResponse.cjs.map +0 -1
  350. package/dist/components/WrittenResponse.js.map +0 -1
  351. package/dist/hooks/useSpeechRecorder.cjs.map +0 -1
  352. package/dist/hooks/useSpeechRecorder.js.map +0 -1
  353. package/dist/i18n/LkIntlProvider.cjs.map +0 -1
  354. package/dist/i18n/LkIntlProvider.js.map +0 -1
  355. package/dist/machine-CuwKqWXC.d.cts +0 -26
  356. package/dist/machine-CuwKqWXC.d.ts +0 -26
  357. package/dist/theme/ThemeProvider.cjs.map +0 -1
  358. package/dist/theme/ThemeProvider.js.map +0 -1
  359. package/dist/types-C4IsUQsK.d.ts +0 -989
  360. package/dist/types-CJgZWtl4.d.cts +0 -989
@@ -1,918 +0,0 @@
1
- 'use client';
2
- 'use strict';
3
-
4
- var chunkLBEKRN6Y_cjs = require('./chunk-LBEKRN6Y.cjs');
5
- var chunkUDCQTOVU_cjs = require('./chunk-UDCQTOVU.cjs');
6
- var chunkOD65OZIW_cjs = require('./chunk-OD65OZIW.cjs');
7
- var chunk2PNSVBLQ_cjs = require('./chunk-2PNSVBLQ.cjs');
8
- var chunkJ3C72RPK_cjs = require('./chunk-J3C72RPK.cjs');
9
- var chunkLPUWXIPR_cjs = require('./chunk-LPUWXIPR.cjs');
10
- var chunkNDBMKGQ5_cjs = require('./chunk-NDBMKGQ5.cjs');
11
- var chunkXOR4MPEN_cjs = require('./chunk-XOR4MPEN.cjs');
12
- var chunkBIGGXHAW_cjs = require('./chunk-BIGGXHAW.cjs');
13
- var lkCore = require('@intellectif/lk-core');
14
- var react = require('react');
15
- var jsxRuntime = require('react/jsx-runtime');
16
-
17
- // src/components/shared/capture-registry.ts
18
- var groups = /* @__PURE__ */ new Map();
19
- function joinCaptureGroup(group, stop) {
20
- let members = groups.get(group);
21
- if (members === void 0) {
22
- members = /* @__PURE__ */ new Set();
23
- groups.set(group, members);
24
- }
25
- members.add(stop);
26
- return () => {
27
- const current = groups.get(group);
28
- if (current === void 0) {
29
- return;
30
- }
31
- current.delete(stop);
32
- if (current.size === 0) {
33
- groups.delete(group);
34
- }
35
- };
36
- }
37
- function stopCaptureGroup(group) {
38
- const members = groups.get(group);
39
- if (members === void 0) {
40
- return;
41
- }
42
- for (const stop of [...members]) {
43
- stop();
44
- }
45
- }
46
- var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
47
- function readRecordingBounds(recording) {
48
- const bounds = typeof recording === "object" && recording !== null ? recording : {};
49
- const maxSeconds = isNumber(bounds.maxSeconds) && bounds.maxSeconds > 0 ? Math.min(bounds.maxSeconds, lkCore.READ_ALOUD_MAX_SECONDS) : lkCore.READ_ALOUD_MAX_SECONDS;
50
- const minSeconds = isNumber(bounds.minSeconds) && bounds.minSeconds >= 0 && bounds.minSeconds < maxSeconds ? bounds.minSeconds : void 0;
51
- const takes = bounds.maxTakes;
52
- const maxTakes = takes === void 0 || takes === null ? void 0 : isNumber(takes) ? Math.min(Math.max(1, Math.floor(takes)), lkCore.READ_ALOUD_MAX_TAKES) : lkCore.READ_ALOUD_MAX_TAKES;
53
- return { maxSeconds, minSeconds, maxTakes };
54
- }
55
- function secondsWithin(milliseconds, maxSeconds, rounding) {
56
- const seconds = milliseconds / 1e3;
57
- const whole = rounding === "nearest" ? Math.round(seconds) : Math.floor(seconds);
58
- return Math.min(Math.max(0, whole), maxSeconds);
59
- }
60
- var modelsGroupCount = 0;
61
- var VISIBLE_TEXT_RE = /[^\p{White_Space}\p{Cc}\p{Cf}\p{Default_Ignorable_Code_Point}]/u;
62
- var MARK_ID_RE = /^w\d+$/;
63
- var STORED_STATES = [
64
- "correct",
65
- "mispronounced",
66
- "omitted"
67
- ];
68
- var LEVEL_STEPS = 10;
69
- function offersRetry(phase, uploaded) {
70
- return phase.kind === "upload-failed" || phase.kind === "assess-failed" && phase.retryable && uploaded !== null;
71
- }
72
- function takeStateOf(phase, uploaded) {
73
- if (phase.kind === "uploading" || phase.kind === "assessing") {
74
- return "in-flight";
75
- }
76
- return offersRetry(phase, uploaded) ? "retryable" : "settled";
77
- }
78
- function capturing(status) {
79
- return status === "recording" || status === "requesting-permission";
80
- }
81
- function readingKeyOf(data, bounds) {
82
- const text = (value) => typeof value === "string" ? value : null;
83
- return JSON.stringify([
84
- text(data.id),
85
- text(data.referenceText),
86
- text(data.locale),
87
- String(bounds.maxSeconds),
88
- String(bounds.minSeconds),
89
- String(bounds.maxTakes)
90
- ]);
91
- }
92
- function slowMediaFor(data, label) {
93
- const slow = data.slowMedia;
94
- if (slow === void 0) {
95
- return void 0;
96
- }
97
- const policy = data.media?.playback ?? {};
98
- const { maxPlays: _budget, ...inherited } = policy;
99
- const hasPolicy = Object.values(inherited).some((value) => value !== void 0);
100
- return {
101
- type: "audio",
102
- url: slow.url,
103
- alt: slow.alt ?? label,
104
- ...hasPolicy ? { playback: inherited } : {}
105
- };
106
- }
107
- function marksFromDetails(details) {
108
- if (details.length === 0 || !details.every((detail) => MARK_ID_RE.test(detail.itemId))) {
109
- return null;
110
- }
111
- return details.map((detail) => {
112
- const heard = Array.isArray(detail.learnerResponse) ? detail.learnerResponse.join(" ") : detail.learnerResponse;
113
- const reference = Array.isArray(detail.correctResponse) ? detail.correctResponse.join(" ") : detail.correctResponse;
114
- const correct = chunkLPUWXIPR_cjs.detailIsRight(detail);
115
- const state = correct ? "correct" : detail.outcome === "incorrect-omission" ? "omitted" : "mispronounced";
116
- return {
117
- itemId: detail.itemId,
118
- reference,
119
- heard,
120
- state,
121
- // `ScoringDetail.score` is the word's accuracy divided by 100; the marks
122
- // carry it back in the units the assessment used.
123
- ...typeof detail.score === "number" ? { accuracy: detail.score * 100 } : {}
124
- };
125
- });
126
- }
127
- function recordingOf(response) {
128
- return response !== void 0 && response.type === "read-aloud" ? response.recording : null;
129
- }
130
- function responseOf(recording, takes) {
131
- return { type: "read-aloud", recording, ...takes > 0 ? { takes } : {} };
132
- }
133
- function unscorableMessage(code, s) {
134
- return code === "no_speech" || code === "insufficient_voiced_time" ? s.readAloudNotHeard : s.readAloudNotAssessed;
135
- }
136
- function AnnouncementText({ announcement }) {
137
- if (announcement === null) {
138
- return null;
139
- }
140
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
141
- announcement.text,
142
- announcement.feedback ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
143
- " ",
144
- /* @__PURE__ */ jsxRuntime.jsx("span", { dir: "auto", children: announcement.feedback })
145
- ] }) : null
146
- ] });
147
- }
148
- function OutcomeSummary({
149
- reading,
150
- s,
151
- scoreShown
152
- }) {
153
- switch (reading.kind) {
154
- case "graded":
155
- return /* @__PURE__ */ jsxRuntime.jsx(
156
- "div",
157
- {
158
- className: "lk-ra-outcome",
159
- "data-status": reading.status,
160
- "data-passed": String(reading.grade.passed),
161
- children: scoreShown ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
162
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.scoreAnnouncement(chunkLBEKRN6Y_cjs.percentOfGrade(reading.grade), reading.grade.passed) }),
163
- reading.grade.feedback ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade-feedback", dir: "auto", children: reading.grade.feedback }) : null
164
- ] })
165
- }
166
- );
167
- case "deferred":
168
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lk-ra-outcome", "data-status": "deferred", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.awaitingGrade }) });
169
- case "unscorable":
170
- return /* @__PURE__ */ jsxRuntime.jsx(
171
- "div",
172
- {
173
- className: "lk-ra-outcome",
174
- "data-status": "unscorable",
175
- ...reading.code !== void 0 ? { "data-code": reading.code } : {},
176
- children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.couldNotBeGraded })
177
- }
178
- );
179
- default:
180
- return /* @__PURE__ */ jsxRuntime.jsx(
181
- "div",
182
- {
183
- className: "lk-ra-outcome",
184
- ...reading.status !== void 0 ? { "data-status": reading.status } : {},
185
- children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.couldNotBeGraded })
186
- }
187
- );
188
- }
189
- }
190
- function ReadAloud({
191
- data,
192
- onComplete,
193
- onSubmit,
194
- onInteraction,
195
- value,
196
- defaultValue,
197
- defaultSubmitted,
198
- renderMode = "practice",
199
- outcome,
200
- mediaBudget,
201
- mediaStrings,
202
- strings,
203
- theme,
204
- locale,
205
- disabled,
206
- recordingBinding,
207
- assessment,
208
- breakThreshold,
209
- monotoneThreshold,
210
- workletUrl,
211
- delivery,
212
- ai
213
- }) {
214
- const isExam = renderMode === "exam";
215
- const policy = chunk2PNSVBLQ_cjs.useDeliveryPolicy(delivery);
216
- const isReview = renderMode === "review";
217
- const s = chunkBIGGXHAW_cjs.useLkStrings(strings);
218
- const slot = react.useContext(chunkLPUWXIPR_cjs.SequenceSlotContext);
219
- const captureGroup = slot?.captureGroup;
220
- const devError = react.useMemo(() => {
221
- if (!chunkLPUWXIPR_cjs.isDevelopment()) {
222
- return null;
223
- }
224
- if (data.redacted === true) {
225
- try {
226
- lkCore.assertRedacted(data);
227
- return null;
228
- } catch (error) {
229
- return error instanceof Error ? error : new Error(String(error));
230
- }
231
- }
232
- const result = lkCore.validateActivity("read-aloud", data);
233
- return result.success ? null : new lkCore.ActivitySchemaError("read-aloud", result.errors);
234
- }, [data]);
235
- const { maxSeconds, minSeconds, maxTakes } = readRecordingBounds(data.recording);
236
- const readingKey = readingKeyOf(data, { maxSeconds, minSeconds, maxTakes });
237
- const recorder = chunkUDCQTOVU_cjs.useSpeechRecorder(
238
- react.useMemo(
239
- () => ({
240
- maxDurationMs: maxSeconds * 1e3,
241
- ...minSeconds !== void 0 ? { minDurationMs: minSeconds * 1e3 } : {},
242
- ...maxTakes !== void 0 ? { maxTakes } : {},
243
- // Forwarded, never defaulted: without it the recorder mints its own
244
- // `blob:` module, which is the one a strict policy refuses.
245
- ...workletUrl !== void 0 ? { workletUrl } : {}
246
- }),
247
- [maxSeconds, minSeconds, maxTakes, workletUrl]
248
- )
249
- );
250
- const { state, start, complete, getTimeSpent, reset } = chunkXOR4MPEN_cjs.useActivityState(
251
- defaultSubmitted === true ? "completed" : "idle"
252
- );
253
- const [phase, setPhase] = react.useState({ kind: "idle" });
254
- const [uploaded, setUploaded] = react.useState(null);
255
- const [takeUrl, setTakeUrl] = react.useState(null);
256
- const [playbackUrl, setPlaybackUrl] = react.useState(null);
257
- const [errorNonce, setErrorNonce] = react.useState(0);
258
- const ids = react.useId();
259
- const titleId = `${ids}-title`;
260
- const [modelsGroup] = react.useState(() => {
261
- modelsGroupCount += 1;
262
- return `lk-ra-models-${modelsGroupCount}`;
263
- });
264
- const interactionRef = react.useRef(onInteraction);
265
- interactionRef.current = onInteraction;
266
- const bindingRef = react.useRef(recordingBinding);
267
- bindingRef.current = recordingBinding;
268
- const submittingRef = react.useRef(false);
269
- const runRef = react.useRef(0);
270
- const slotRef = react.useRef(slot);
271
- slotRef.current = slot;
272
- const reportedTakeRef = react.useRef(null);
273
- react.useEffect(
274
- () => () => {
275
- runRef.current += 1;
276
- const take2 = reportedTakeRef.current;
277
- if (take2 !== null) {
278
- slotRef.current?.takeState(take2, "settled");
279
- }
280
- },
281
- []
282
- );
283
- const fire = react.useCallback(
284
- (type, payload) => {
285
- interactionRef.current?.({ type, activityId: data.id, timestamp: Date.now(), payload });
286
- },
287
- [data.id]
288
- );
289
- const lastStatusRef = react.useRef(recorder.status);
290
- react.useEffect(() => {
291
- if (lastStatusRef.current === recorder.status) {
292
- return;
293
- }
294
- lastStatusRef.current = recorder.status;
295
- if (recorder.status === "recording") {
296
- fire("recording-started", { takes: recorder.takesUsed, durationMs: 0 });
297
- } else if (recorder.status === "recorded" && recorder.take !== null) {
298
- fire("recording-stopped", {
299
- takes: recorder.takesUsed,
300
- durationMs: recorder.take.durationMs
301
- });
302
- }
303
- }, [recorder.status, recorder.take, recorder.takesUsed, fire]);
304
- react.useEffect(() => {
305
- if (recorder.error !== null) {
306
- setErrorNonce((nonce) => nonce + 1);
307
- }
308
- }, [recorder.error]);
309
- const take = recorder.take;
310
- react.useEffect(() => {
311
- if (take === null || typeof URL.createObjectURL !== "function") {
312
- return;
313
- }
314
- const url = URL.createObjectURL(take.blob);
315
- setTakeUrl(url);
316
- return () => {
317
- URL.revokeObjectURL(url);
318
- setTakeUrl(null);
319
- };
320
- }, [take]);
321
- const restored = recordingOf(value ?? defaultValue);
322
- const restoredKey = restored?.key ?? null;
323
- react.useEffect(() => {
324
- const binding = bindingRef.current;
325
- if (!isReview || restored === null || binding?.playbackUrl === void 0) {
326
- return;
327
- }
328
- let live = true;
329
- void Promise.resolve(binding.playbackUrl(restored)).then(
330
- (url) => {
331
- if (live) {
332
- setPlaybackUrl(url);
333
- }
334
- },
335
- () => {
336
- }
337
- );
338
- return () => {
339
- live = false;
340
- };
341
- }, [isReview, restoredKey, readingKey]);
342
- const statusRef = react.useRef(recorder.status);
343
- statusRef.current = recorder.status;
344
- const releaseMicrophone = react.useCallback(() => {
345
- if (capturing(statusRef.current)) {
346
- recorder.discard();
347
- }
348
- }, [recorder.discard]);
349
- react.useEffect(() => {
350
- if (captureGroup === void 0) {
351
- return;
352
- }
353
- return joinCaptureGroup(captureGroup, releaseMicrophone);
354
- }, [captureGroup, releaseMicrophone]);
355
- const defaultSubmittedRef = react.useRef(defaultSubmitted);
356
- react.useEffect(() => {
357
- defaultSubmittedRef.current = defaultSubmitted;
358
- }, [defaultSubmitted]);
359
- const lastReadingRef = react.useRef(readingKey);
360
- react.useEffect(() => {
361
- if (lastReadingRef.current === readingKey) {
362
- return;
363
- }
364
- lastReadingRef.current = readingKey;
365
- submittingRef.current = false;
366
- runRef.current += 1;
367
- setPhase({ kind: "idle" });
368
- setUploaded(null);
369
- setPlaybackUrl(null);
370
- recorder.reset();
371
- reset(defaultSubmittedRef.current === true ? "completed" : "idle");
372
- }, [readingKey, reset, recorder.reset]);
373
- const phaseTake = phase.kind === "idle" ? null : phase.take;
374
- const phaseTakeState = takeStateOf(phase, uploaded);
375
- react.useEffect(() => {
376
- const take2 = phaseTake ?? reportedTakeRef.current;
377
- if (slot === null || take2 === null) {
378
- return;
379
- }
380
- reportedTakeRef.current = take2;
381
- slot.takeState(take2, phaseTakeState);
382
- }, [slot, phaseTake, phaseTakeState]);
383
- const modelsRef = react.useRef(null);
384
- const isCapturing = capturing(recorder.status);
385
- react.useEffect(() => {
386
- if (!isCapturing) {
387
- return;
388
- }
389
- const node = modelsRef.current;
390
- if (node === null) {
391
- return;
392
- }
393
- const hush = () => {
394
- for (const media of node.querySelectorAll("audio, video")) {
395
- const element = media;
396
- if (!element.paused) {
397
- element.pause();
398
- }
399
- }
400
- };
401
- hush();
402
- node.addEventListener("play", hush, true);
403
- return () => {
404
- node.removeEventListener("play", hush, true);
405
- };
406
- }, [isCapturing]);
407
- const slowMedia = react.useMemo(
408
- () => slowMediaFor(data, s.readAloudSlowRecording),
409
- [data, s.readAloudSlowRecording]
410
- );
411
- const takeAudio = isReview ? playbackUrl : takeUrl;
412
- const playback = chunkLBEKRN6Y_cjs.usePlaybackRefusal(takeAudio);
413
- const submitRef = react.useRef(null);
414
- if (devError) {
415
- throw devError;
416
- }
417
- if (!isReview && recordingBinding?.upload === void 0) {
418
- throw new Error(
419
- `ReadAloud "${data.id}" was rendered in renderMode "${renderMode}" without \`recordingBinding.upload\`. The learner could record a take that is stored nowhere and submitted as nothing, which looks like a working activity the whole way through. Pass a \`recordingBinding\` whose \`upload\` puts the take in your storage and returns its key. \`assess\` is optional: without it the take is still recorded, uploaded and submitted, and a notice replaces the feedback.`
420
- );
421
- }
422
- const submitted = state === "completed";
423
- const inactive = disabled === true || submitted || isReview;
424
- const busy = phase.kind === "uploading" || phase.kind === "assessing";
425
- const takesLeft = maxTakes === void 0 ? void 0 : Math.max(0, maxTakes - recorder.takesUsed);
426
- const raise = (next) => {
427
- setErrorNonce((nonce) => nonce + 1);
428
- setPhase(next);
429
- };
430
- const beginTakeReport = (take2) => {
431
- reportedTakeRef.current = take2;
432
- slot?.takeState(take2, "in-flight");
433
- };
434
- const runAssess = async (ref, current, take2) => {
435
- const assess = bindingRef.current?.assess;
436
- const durationMs = current?.durationMs ?? 0;
437
- const takes = recorder.takesUsed;
438
- const run = runRef.current;
439
- if (assess === void 0) {
440
- setPhase({ kind: "unassessed", take: take2 });
441
- return;
442
- }
443
- setPhase({ kind: "assessing", take: take2 });
444
- fire("assessment-requested", { takes, durationMs });
445
- let answer;
446
- try {
447
- answer = await assess(ref);
448
- } catch {
449
- if (run !== runRef.current) {
450
- return;
451
- }
452
- raise({ kind: "assess-failed", take: take2, retryable: true });
453
- fire("assessment-failed", { takes, durationMs, retryable: true });
454
- return;
455
- }
456
- if (run !== runRef.current) {
457
- return;
458
- }
459
- const result = chunkLBEKRN6Y_cjs.readAssessResult(answer);
460
- if (result.status === "failed") {
461
- raise({ kind: "assess-failed", take: take2, retryable: result.retryable });
462
- fire("assessment-failed", { takes, durationMs, retryable: result.retryable });
463
- return;
464
- }
465
- if (result.status === "unscorable") {
466
- setPhase({ kind: "unscorable", take: take2, code: result.code });
467
- fire("assessment-failed", {
468
- takes,
469
- durationMs,
470
- retryable: true,
471
- ...result.code !== void 0 ? { code: result.code } : {}
472
- });
473
- return;
474
- }
475
- const timeSpent = getTimeSpent();
476
- setPhase({ kind: "graded", take: take2, assessment: result.assessment, grade: result.grade });
477
- const grade = result.grade;
478
- if (grade === null) {
479
- fire("assessment-failed", { takes, durationMs, retryable: true });
480
- return;
481
- }
482
- onComplete?.(
483
- chunkLPUWXIPR_cjs.stampTake(
484
- {
485
- score: grade.score,
486
- maxScore: grade.maxScore,
487
- passed: grade.passed,
488
- timeSpent,
489
- xapiStatement: lkCore.xAPIBuilder.buildAnsweredStatement({
490
- actor: chunkLPUWXIPR_cjs.ANONYMOUS_ACTOR,
491
- object: {
492
- id: chunkLPUWXIPR_cjs.objectIdFor(data.id),
493
- name: { [data.locale ?? "en-US"]: data.title },
494
- ...lkCore.xapiDefinitionFor(data)
495
- },
496
- timeSpentMs: timeSpent,
497
- response: result.recognizedText ?? "",
498
- // `ScoringResult.details` is required where `GradeRecord.details` is
499
- // optional, and an empty list is the honest reading of "no per-word
500
- // marks were stored" — never a mark of its own.
501
- scoringResult: {
502
- score: chunkLBEKRN6Y_cjs.fractionOfGrade(grade),
503
- maxScore: 1,
504
- passed: grade.passed,
505
- feedback: grade.feedback,
506
- details: grade.details ?? []
507
- }
508
- })
509
- },
510
- take2
511
- )
512
- );
513
- };
514
- const submitTake = async (current) => {
515
- const binding = bindingRef.current;
516
- if (inactive || submittingRef.current || binding === void 0) {
517
- return;
518
- }
519
- submittingRef.current = true;
520
- const takes = recorder.takesUsed;
521
- const run = runRef.current;
522
- const take2 = chunkLPUWXIPR_cjs.mintTake();
523
- beginTakeReport(take2);
524
- try {
525
- let ref = null;
526
- if (current !== null) {
527
- setPhase({ kind: "uploading", take: take2 });
528
- try {
529
- ref = await binding.upload(current);
530
- } catch {
531
- if (run !== runRef.current) {
532
- return;
533
- }
534
- raise({ kind: "upload-failed", take: take2 });
535
- fire("recording-upload-failed", {
536
- takes,
537
- durationMs: current.durationMs,
538
- retryable: true
539
- });
540
- return;
541
- }
542
- if (run !== runRef.current) {
543
- return;
544
- }
545
- setUploaded(ref);
546
- fire("recording-uploaded", { takes, durationMs: current.durationMs });
547
- }
548
- onSubmit?.(chunkLPUWXIPR_cjs.stampTake(responseOf(ref, takes), take2));
549
- fire("submitted", { takes, durationMs: current?.durationMs ?? 0 });
550
- if (isExam || ref === null) {
551
- complete();
552
- setPhase({ kind: "submitted", take: take2 });
553
- return;
554
- }
555
- await runAssess(ref, current, take2);
556
- } finally {
557
- submittingRef.current = false;
558
- }
559
- };
560
- const retryAssess = async (ref, take2) => {
561
- if (submittingRef.current) {
562
- return;
563
- }
564
- submittingRef.current = true;
565
- beginTakeReport(take2);
566
- try {
567
- await runAssess(ref, recorder.take, take2);
568
- } finally {
569
- submittingRef.current = false;
570
- }
571
- };
572
- const handleSubmit = (event) => {
573
- event.preventDefault();
574
- if (inactive || busy || recorder.take === null || phase.kind !== "idle") {
575
- return;
576
- }
577
- void submitTake(recorder.take);
578
- };
579
- const beginTake = () => {
580
- if (inactive || busy || !recorder.canRecord) {
581
- return;
582
- }
583
- if (recorder.take !== null) {
584
- fire("recording-discarded", {
585
- takes: recorder.takesUsed,
586
- durationMs: recorder.take.durationMs
587
- });
588
- }
589
- setPhase({ kind: "idle" });
590
- setUploaded(null);
591
- start();
592
- void recorder.start();
593
- };
594
- const contentLang = typeof data.locale === "string" ? data.locale : void 0;
595
- const contentDir = chunkOD65OZIW_cjs.localeDirectionOf(data.locale);
596
- const coachingItem = {
597
- id: data.id,
598
- title: data.title,
599
- referenceText: data.referenceText,
600
- locale: data.locale,
601
- ...data.instructions !== void 0 ? { instructions: data.instructions } : {},
602
- ...data.ai !== void 0 ? { ai: data.ai } : {}
603
- };
604
- const outcomeReading = react.useMemo(() => chunkLBEKRN6Y_cjs.readOutcome(outcome), [outcome]);
605
- const keptEvidence = react.useMemo(() => chunkLBEKRN6Y_cjs.readEvidence(assessment), [assessment]);
606
- const storedGrade = outcomeReading?.kind === "graded" && outcomeReading.status === "graded" ? outcomeReading.grade : null;
607
- const storedMarks = react.useMemo(
608
- () => policy.feedback && isReview && keptEvidence === null && storedGrade?.details !== void 0 ? marksFromDetails(storedGrade.details) : null,
609
- [policy.feedback, isReview, keptEvidence, storedGrade]
610
- );
611
- const feedbackAssessment = !policy.feedback ? null : isReview ? keptEvidence : phase.kind === "graded" ? phase.assessment : null;
612
- const feedbackGrade = isReview ? storedGrade : phase.kind === "graded" ? phase.grade : null;
613
- const feedbackAudio = playback.refused ? null : takeAudio;
614
- const rootRef = react.useRef(null);
615
- const [panelLostTheGrade, setPanelLostTheGrade] = react.useState(false);
616
- const panelHasGrade = feedbackAssessment !== null && feedbackGrade !== null;
617
- const gradeShownInPanel = panelHasGrade && !panelLostTheGrade;
618
- react.useEffect(() => {
619
- const root = rootRef.current;
620
- const lost = panelHasGrade && (root === null || root.querySelector(".lk-pf-grade") === null);
621
- setPanelLostTheGrade((was) => was === lost ? was : lost);
622
- });
623
- const announcement = react.useMemo(() => {
624
- if (isReview) {
625
- return null;
626
- }
627
- if (recorder.status === "recording") {
628
- return { text: s.readAloudRecordingStarted, feedback: null };
629
- }
630
- const stopped = recorder.status === "recorded" && take !== null ? {
631
- text: s.readAloudRecordingStopped(
632
- secondsWithin(take.durationMs, maxSeconds, "nearest"),
633
- maxSeconds
634
- ),
635
- feedback: null
636
- } : null;
637
- if (isExam) {
638
- if (phase.kind === "submitted" || submitted) {
639
- return { text: s.answerSubmitted, feedback: null };
640
- }
641
- return phase.kind === "idle" ? stopped : null;
642
- }
643
- switch (phase.kind) {
644
- case "graded": {
645
- const grade = phase.grade;
646
- if (grade === null) {
647
- return { text: `${s.answerSubmitted} ${s.couldNotBeGraded}`, feedback: null };
648
- }
649
- if (!policy.feedback) {
650
- return { text: s.answerSubmitted, feedback: null };
651
- }
652
- return {
653
- text: `${s.answerSubmitted} ${s.scoreAnnouncement(chunkLBEKRN6Y_cjs.percentOfGrade(grade), grade.passed)}`,
654
- feedback: grade.feedback
655
- };
656
- }
657
- case "unscorable":
658
- return { text: unscorableMessage(phase.code, s), feedback: null };
659
- case "unassessed":
660
- return { text: s.readAloudAssessmentUnavailable, feedback: null };
661
- case "idle":
662
- return stopped;
663
- default:
664
- return null;
665
- }
666
- }, [isReview, isExam, phase, submitted, s, recorder.status, take, maxSeconds, policy.feedback]);
667
- const alertText = recorder.error !== null ? s.readAloudRecorderError(recorder.error) : phase.kind === "upload-failed" ? s.readAloudUploadFailed : phase.kind === "assess-failed" ? s.readAloudAssessmentFailed : null;
668
- return /* @__PURE__ */ jsxRuntime.jsxs(
669
- "form",
670
- {
671
- className: "lk-ra",
672
- ref: rootRef,
673
- "aria-labelledby": VISIBLE_TEXT_RE.test(data.title) ? titleId : void 0,
674
- lang: locale,
675
- "data-render-mode": renderMode,
676
- style: theme,
677
- onSubmit: handleSubmit,
678
- children: [
679
- /* @__PURE__ */ jsxRuntime.jsx("p", { id: titleId, className: "lk-ra-title", dir: contentDir ?? "auto", lang: contentLang, children: data.title }),
680
- typeof data.instructions === "string" && data.instructions !== "" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-instructions", dir: contentDir ?? "auto", lang: contentLang, children: data.instructions }) : null,
681
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-reference", dir: contentDir ?? "auto", lang: contentLang, children: data.referenceText }),
682
- data.media !== void 0 || slowMedia !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-ra-models", ref: modelsRef, children: [
683
- data.media !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "lk-ra-model", children: [
684
- /* @__PURE__ */ jsxRuntime.jsx("legend", { className: "lk-ra-model-label", children: s.readAloudModelRecording }),
685
- /* @__PURE__ */ jsxRuntime.jsx(
686
- chunkNDBMKGQ5_cjs.ActivityMedia,
687
- {
688
- media: data.media,
689
- renderMode,
690
- playbackGroup: modelsGroup,
691
- ...mediaBudget !== void 0 ? { mediaBudget } : {},
692
- ...mediaStrings !== void 0 ? { mediaStrings } : {},
693
- ...strings !== void 0 ? { strings } : {},
694
- ...onInteraction !== void 0 ? { onInteraction } : {},
695
- ...locale !== void 0 ? { locale } : {},
696
- ...disabled === true || isCapturing ? { disabled: true } : {}
697
- }
698
- )
699
- ] }) : null,
700
- slowMedia !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "lk-ra-model", "data-slow": "true", children: [
701
- /* @__PURE__ */ jsxRuntime.jsx("legend", { className: "lk-ra-model-label", children: s.readAloudSlowRecording }),
702
- /* @__PURE__ */ jsxRuntime.jsx(
703
- chunkNDBMKGQ5_cjs.ActivityMedia,
704
- {
705
- media: slowMedia,
706
- renderMode,
707
- playbackGroup: modelsGroup,
708
- ...mediaStrings !== void 0 ? { mediaStrings } : {},
709
- ...strings !== void 0 ? { strings } : {},
710
- ...locale !== void 0 ? { locale } : {},
711
- ...disabled === true || isCapturing ? { disabled: true } : {}
712
- }
713
- )
714
- ] }) : null
715
- ] }) : null,
716
- isReview || submitted ? null : /* @__PURE__ */ jsxRuntime.jsxs(
717
- "div",
718
- {
719
- className: "lk-ra-recorder",
720
- "data-status": recorder.status,
721
- "data-level": recorder.status === "recording" ? Math.min(LEVEL_STEPS, Math.round(recorder.level * LEVEL_STEPS)) : void 0,
722
- children: [
723
- recorder.status === "recording" ? /* @__PURE__ */ jsxRuntime.jsx(
724
- "button",
725
- {
726
- type: "button",
727
- className: "lk-ra-stop",
728
- disabled: inactive,
729
- onClick: () => recorder.stop(),
730
- children: s.readAloudStop
731
- }
732
- ) : (
733
- // aria-disabled, never disabled, once the takes are spent: a
734
- // natively disabled button drops keyboard focus to the page body,
735
- // and this is the control a learner comes back to.
736
- /* @__PURE__ */ jsxRuntime.jsx(
737
- "button",
738
- {
739
- type: "button",
740
- className: "lk-ra-record",
741
- disabled: inactive,
742
- "aria-disabled": !recorder.canRecord || busy || void 0,
743
- onClick: beginTake,
744
- children: recorder.take === null ? s.readAloudRecord : s.readAloudRerecord
745
- }
746
- )
747
- ),
748
- recorder.status === "recording" ? (
749
- // Visible, and hidden from assistive technology, beside the level
750
- // meter the recorder's `data-level` drives. Its text changes every
751
- // whole second, so as a live region it announced ten times in a
752
- // ten-second take — into the microphone. What a screen-reader
753
- // learner needs instead is said once each, below.
754
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-progress", "aria-hidden": "true", children: s.readAloudRecordingProgress(
755
- secondsWithin(recorder.elapsedMs, maxSeconds, "down"),
756
- maxSeconds
757
- ) })
758
- ) : null,
759
- takesLeft !== void 0 && maxTakes !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-takes", children: s.readAloudTakesRemaining(takesLeft, maxTakes) }) : null
760
- ]
761
- }
762
- ),
763
- takeAudio === null ? null : playback.refused ? (
764
- // In the player's place, not beside it: a player the page will not
765
- // load looks exactly like one that works until it is pressed, and then
766
- // does nothing. A note rather than an alert — the learner can still
767
- // submit, and nothing here asks them to act.
768
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-take-unavailable", role: "note", children: s.readAloudPlaybackUnavailable })
769
- ) : (
770
- // biome-ignore lint/a11y/useMediaCaption: the learner's own take has no caption track to offer; its accessible name says whose recording it is
771
- /* @__PURE__ */ jsxRuntime.jsx(
772
- "audio",
773
- {
774
- className: "lk-ra-take",
775
- controls: true,
776
- src: takeAudio,
777
- "aria-label": s.readAloudYourRecording,
778
- onError: (event) => playback.refuse(event.currentTarget),
779
- ...isReview ? {} : { "data-take": recorder.takesUsed }
780
- }
781
- )
782
- ),
783
- isReview || submitted ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-ra-actions", children: [
784
- /* @__PURE__ */ jsxRuntime.jsx(
785
- "button",
786
- {
787
- ref: submitRef,
788
- type: "submit",
789
- className: "lk-ra-submit",
790
- disabled: disabled === true,
791
- "aria-disabled": recorder.take === null || phase.kind !== "idle" || void 0,
792
- "aria-busy": busy || void 0,
793
- children: s.submit
794
- }
795
- ),
796
- isExam ? (
797
- // Explicit, and only here: an exam answer with no recording is a
798
- // decision a learner takes, never something a failed upload does
799
- // for them.
800
- /* @__PURE__ */ jsxRuntime.jsx(
801
- "button",
802
- {
803
- type: "button",
804
- className: "lk-ra-submit-blank",
805
- disabled: inactive,
806
- "aria-disabled": busy || void 0,
807
- onClick: () => {
808
- if (!busy) {
809
- void submitTake(null);
810
- }
811
- },
812
- children: s.readAloudSubmitWithoutRecording
813
- }
814
- )
815
- ) : null,
816
- offersRetry(phase, uploaded) ? /* @__PURE__ */ jsxRuntime.jsx(
817
- "button",
818
- {
819
- type: "button",
820
- className: "lk-ra-retry",
821
- onClick: () => {
822
- submitRef.current?.focus();
823
- if (phase.kind === "upload-failed") {
824
- void submitTake(recorder.take);
825
- } else if (phase.kind === "assess-failed" && uploaded !== null) {
826
- void retryAssess(uploaded, phase.take);
827
- }
828
- },
829
- children: s.readAloudTryAgain
830
- }
831
- ) : null
832
- ] }),
833
- busy ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-pending", role: "status", "aria-busy": "true", children: phase.kind === "uploading" ? s.readAloudUploading : s.readAloudAssessing }) : null,
834
- alertText !== null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-alert", role: "alert", children: alertText }, errorNonce) : null,
835
- feedbackAssessment !== null ? /* @__PURE__ */ jsxRuntime.jsx(
836
- chunkLBEKRN6Y_cjs.PronunciationFeedback,
837
- {
838
- data: coachingItem,
839
- assessment: feedbackAssessment,
840
- ...feedbackGrade !== null ? { grade: feedbackGrade } : {},
841
- ...feedbackAudio !== null ? { audioUrl: feedbackAudio } : {},
842
- ...breakThreshold !== void 0 ? { breakThreshold } : {},
843
- ...monotoneThreshold !== void 0 ? { monotoneThreshold } : {},
844
- ...locale !== void 0 ? { locale } : {},
845
- ...strings !== void 0 ? { strings } : {},
846
- ...ai !== void 0 ? { ai } : {},
847
- ...onInteraction !== void 0 ? { onInteraction } : {},
848
- renderMode,
849
- delivery: policy
850
- }
851
- ) : null,
852
- storedMarks !== null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-ra-marks", children: [
853
- /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "lk-ra-words", "aria-label": s.pronunciationWordsLabel, dir: contentDir, children: storedMarks.map((entry, index) => {
854
- const sentence = chunkLBEKRN6Y_cjs.markSentence(entry, s);
855
- return /* @__PURE__ */ jsxRuntime.jsxs(
856
- "li",
857
- {
858
- className: "lk-ra-word",
859
- "data-state": entry.state,
860
- children: [
861
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style: chunkLBEKRN6Y_cjs.VISUALLY_HIDDEN, children: sentence }),
862
- /* @__PURE__ */ jsxRuntime.jsx(
863
- "span",
864
- {
865
- className: "lk-ra-word-text",
866
- "aria-hidden": "true",
867
- dir: contentDir ?? "auto",
868
- lang: contentLang,
869
- children: entry.reference
870
- }
871
- )
872
- ]
873
- },
874
- index
875
- );
876
- }) }),
877
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "lk-ra-legend", children: STORED_STATES.map((state2) => /* @__PURE__ */ jsxRuntime.jsx("li", { "data-state": state2, children: s.pronunciationLegend(state2) }, state2)) }),
878
- /* @__PURE__ */ jsxRuntime.jsx(
879
- chunkLBEKRN6Y_cjs.ReadingCoaching,
880
- {
881
- data: coachingItem,
882
- grade: storedGrade,
883
- renderMode,
884
- delivery: policy,
885
- ...ai !== void 0 ? { ai } : {},
886
- ...locale !== void 0 ? { locale } : {},
887
- ...onInteraction !== void 0 ? { onInteraction } : {},
888
- strings: s,
889
- contentLang,
890
- contentDir
891
- }
892
- )
893
- ] }) : null,
894
- /* @__PURE__ */ jsxRuntime.jsx(chunk2PNSVBLQ_cjs.FeedbackRegion, { id: `${data.id}-feedback`, children: isReview ? (
895
- // A grade read back is feedback; "not graded yet" and a grade that
896
- // could not be read are not.
897
- outcomeReading !== void 0 && (policy.feedback || outcomeReading.kind !== "graded") ? /* @__PURE__ */ jsxRuntime.jsx(OutcomeSummary, { reading: outcomeReading, s, scoreShown: gradeShownInPanel }) : null
898
- ) : gradeShownInPanel ? (
899
- // Announced, not repeated. A grade the feedback panel is already
900
- // showing would otherwise be read on screen twice, feedback and all —
901
- // but a live region is the only thing that TELLS a screen-reader
902
- // learner a grade arrived, since nothing takes focus. Clipped rather
903
- // than `display: none`, which would stop it being announced at all.
904
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style: chunkLBEKRN6Y_cjs.VISUALLY_HIDDEN, children: /* @__PURE__ */ jsxRuntime.jsx(AnnouncementText, { announcement }) })
905
- ) : /* @__PURE__ */ jsxRuntime.jsx(AnnouncementText, { announcement }) })
906
- ]
907
- }
908
- );
909
- }
910
- function ReadAloud2(props) {
911
- const strings = chunkBIGGXHAW_cjs.useLkStrings(props.strings);
912
- return /* @__PURE__ */ jsxRuntime.jsx(chunkJ3C72RPK_cjs.ActivityErrorBoundary, { activityTitle: props.data?.title, strings, children: /* @__PURE__ */ jsxRuntime.jsx(ReadAloud, { ...props }) });
913
- }
914
-
915
- exports.ReadAloud = ReadAloud2;
916
- exports.stopCaptureGroup = stopCaptureGroup;
917
- //# sourceMappingURL=chunk-TP5UMRAU.cjs.map
918
- //# sourceMappingURL=chunk-TP5UMRAU.cjs.map