@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
@@ -0,0 +1,931 @@
1
+ 'use client';
2
+ const require_ai_LkAiProvider = require("./ai/LkAiProvider.cjs");
3
+ const require_useAiHelp = require("./useAiHelp-h9yOLFqt.cjs");
4
+ const require_LkIntlProvider = require("./LkIntlProvider-oi57lYB0.cjs");
5
+ const require_ActivityErrorBoundary = require("./ActivityErrorBoundary-B379hvtL.cjs");
6
+ const require_hooks_useActivityState = require("./hooks/useActivityState.cjs");
7
+ const require_direction = require("./direction-K1pj0HCA.cjs");
8
+ const require_ActivityMedia = require("./ActivityMedia-CQQTRNl7.cjs");
9
+ const require_tries = require("./tries-CbbtZkdG.cjs");
10
+ const require_FeedbackRegion = require("./FeedbackRegion-BNNMtTY-.cjs");
11
+ let react = require("react");
12
+ let react_jsx_runtime = require("react/jsx-runtime");
13
+ let _intellectif_lk_core = require("@intellectif/lk-core");
14
+ //#region src/components/Dictation/Dictation.tsx
15
+ /** How long the learner has to stop typing before one `text-changed` is emitted. */
16
+ const TEXT_CHANGED_DEBOUNCE_MS = 500;
17
+ /**
18
+ * Present for assistive technology, invisible on screen. Inline rather than
19
+ * left to the optional skin: the per-word sentences are the marks' only
20
+ * channel for a screen reader, and without this a page that does not load the
21
+ * skin would show every one of them beside its word.
22
+ */
23
+ const VISUALLY_HIDDEN = {
24
+ position: "absolute",
25
+ width: 1,
26
+ height: 1,
27
+ margin: -1,
28
+ padding: 0,
29
+ overflow: "hidden",
30
+ clip: "rect(0 0 0 0)",
31
+ clipPath: "inset(50%)",
32
+ whiteSpace: "nowrap",
33
+ border: 0
34
+ };
35
+ /**
36
+ * Names playback groups. Per mount and never derived from `useId`: two
37
+ * separately hydrated roots derive the same id for the same tree position, and
38
+ * their recordings would pause each other. The name never reaches the DOM.
39
+ */
40
+ let recordingsGroupCount = 0;
41
+ /**
42
+ * A token with nothing spelled in it, as the scorer reads it once composed:
43
+ * only punctuation, control, format and default-ignorable characters, the acute
44
+ * accent, grave accent (and its fullwidth form) and modifier apostrophe the
45
+ * scorer folds into an apostrophe, and the Arabic tatweel and N'Ko lajanyalan
46
+ * it removes.
47
+ */
48
+ const UNSPELLED_RE = new RegExp(`^[\\p{P}\\p{Cc}\\p{Cf}\\p{Default_Ignorable_Code_Point}${String.fromCodePoint(180, 96, 65344, 700, 1600, 2042)}]*$`, "u");
49
+ /**
50
+ * Spacing as the scorer reads it: whitespace and NEXT LINE — but not the
51
+ * byte-order mark, which JavaScript counts as whitespace and the scorer
52
+ * removes as a format character, joining the letters on either side.
53
+ */
54
+ const HINT_SPACE_RE = new RegExp(`(?:(?!${String.fromCodePoint(65279)})\\s|${String.fromCodePoint(133)})+`, "u");
55
+ /** A title with something in it a screen reader can say. */
56
+ const VISIBLE_TEXT_RE = /[^\p{White_Space}\p{Cc}\p{Cf}\p{Default_Ignorable_Code_Point}]/u;
57
+ const BULLET = "•";
58
+ const LEFT_TO_RIGHT_MARK = String.fromCodePoint(8206);
59
+ const RIGHT_TO_LEFT_MARK = String.fromCodePoint(8207);
60
+ /**
61
+ * Code points a font draws onto the character before them rather than beside
62
+ * it — combining marks (variation selectors among them), the joiners, emoji
63
+ * skin tones, tag characters, the vowel and final jamo of an old Hangul
64
+ * syllable, and the Thai and Lao SARA AM, whose ring the font sets on the
65
+ * consonant before — so their own span can have no width to decorate.
66
+ */
67
+ const EXTENDING_RE = new RegExp(`^[\\p{M}${String.fromCodePoint(8204, 8205, 3635, 3763)}${String.fromCodePoint(127995)}-${String.fromCodePoint(127999)}${String.fromCodePoint(917536)}-${String.fromCodePoint(917631)}${String.fromCodePoint(4448)}-${String.fromCodePoint(4607)}${String.fromCodePoint(55216)}-${String.fromCodePoint(55295)}]$`, "u");
68
+ /**
69
+ * Viramas that stack the letter after them into one glyph without asking —
70
+ * Devanagari, Bengali, Gujarati, Oriya, Telugu, Kannada and Malayalam, the
71
+ * Burmese stacker, the Khmer coeng, and the Tai Tham, Balinese, Javanese,
72
+ * Chakma and Brahmi signs. Not the Tamil, Gurmukhi or Sinhala virama, which is
73
+ * drawn visibly and leaves most letters after it on their own.
74
+ */
75
+ const STACKING_VIRAMAS = new Set([
76
+ 2381,
77
+ 2509,
78
+ 2765,
79
+ 2893,
80
+ 3149,
81
+ 3277,
82
+ 3405,
83
+ 4153,
84
+ 6098,
85
+ 6752,
86
+ 6980,
87
+ 43456,
88
+ 69702,
89
+ 69939
90
+ ].map((point) => String.fromCodePoint(point)));
91
+ /**
92
+ * The letters a visible virama still draws into the letter before it: the
93
+ * Gurmukhi RA, YA and VA, which fonts set under the consonant, and the Tamil
94
+ * conjuncts KSSA (க்ஷ) and SHRII (ஸ்ரீ), which fonts draw as one glyph —
95
+ * each keyed by its letter, virama and the letter before the virama.
96
+ */
97
+ const SUBJOINED_AFTER = new Map([
98
+ ...[
99
+ 2608,
100
+ 2607,
101
+ 2613
102
+ ].map((point) => [String.fromCodePoint(point), (before) => before.at(-1) === String.fromCodePoint(2637)]),
103
+ [String.fromCodePoint(2999), (before) => before.at(-1) === String.fromCodePoint(3021) && before.at(-2) === String.fromCodePoint(2965)],
104
+ [String.fromCodePoint(2992), (before) => before.at(-1) === String.fromCodePoint(3021) && before.at(-2) === String.fromCodePoint(3e3)]
105
+ ]);
106
+ /** Viramas after which a zero-width joiner asks for a conjunct: every stacking one, and the Sinhala. */
107
+ const JOINABLE_VIRAMAS = /* @__PURE__ */ new Set([...STACKING_VIRAMAS, String.fromCodePoint(3530)]);
108
+ const ZERO_WIDTH_JOINER = String.fromCodePoint(8205);
109
+ /**
110
+ * Characters the font draws into the letter after them: MALAYALAM LETTER DOT
111
+ * REPH, set on the consonant after it, and the MONGOLIAN VOWEL SEPARATOR, which
112
+ * has no width of its own and changes the shape of the vowel after it.
113
+ */
114
+ const PREPENDED = /* @__PURE__ */ new Set([String.fromCodePoint(3406), String.fromCodePoint(6158)]);
115
+ const ARABIC_LAM = String.fromCodePoint(1604);
116
+ /** The alefs a lam before them fuses with into one glyph, in every Arabic font. */
117
+ const LIGATING_ALEFS = new Set([
118
+ 1570,
119
+ 1571,
120
+ 1573,
121
+ 1575,
122
+ 1649,
123
+ 1650,
124
+ 1651,
125
+ 1653
126
+ ].map((point) => String.fromCodePoint(point)));
127
+ const REGIONAL_INDICATOR_RE = /^[\u{1f1e6}-\u{1f1ff}]$/u;
128
+ const LETTER_RE = /^\p{L}$/u;
129
+ /** A letter of any script but Latin, Greek or Cyrillic, whose common ligatures are only decorative. */
130
+ const LETTER_WITH_REQUIRED_LIGATURES_RE = /(?![\p{Script=Latin}\p{Script=Greek}\p{Script=Cyrillic}])\p{L}/u;
131
+ const DIGIT_RE = /^\p{Nd}$/u;
132
+ /**
133
+ * Signs laid out with the European number beside them (bidirectional class
134
+ * ET): the currency signs, the degree, plus-minus and per-mille signs.
135
+ */
136
+ const NUMBER_SIGN_RE = new RegExp(`^[\\p{Sc}${String.fromCodePoint(176, 177, 8240, 8241, 8494, 8723)}]$`, "u");
137
+ /** Letters of the Arabic, Syriac and Thaana blocks and their presentation forms: before them, a European number is not one. */
138
+ const ARABIC_LETTER_BLOCKS = [
139
+ [1536, 1983],
140
+ [2144, 2303],
141
+ [64336, 65023],
142
+ [65136, 65279]
143
+ ];
144
+ /**
145
+ * The text out of a `LearnerResponse`. A response of another activity type
146
+ * reads as nothing typed rather than throwing — a controlled host that has not
147
+ * yet swapped its state on an activity change would otherwise crash the attempt.
148
+ */
149
+ function textOf(response) {
150
+ return response !== void 0 && response.type === "dictation" ? response.text : "";
151
+ }
152
+ /** The hint count out of a `LearnerResponse`; absent or another type reads as none. */
153
+ function hintsOf(response) {
154
+ if (response === void 0 || response.type !== "dictation") return 0;
155
+ const revealed = response.hintsRevealed;
156
+ return typeof revealed === "number" && Number.isInteger(revealed) && revealed > 0 ? revealed : 0;
157
+ }
158
+ /** The response this component emits; `hintsRevealed` is written only when there is one. */
159
+ function responseOf(text, hintsRevealed) {
160
+ return {
161
+ type: "dictation",
162
+ text,
163
+ ...hintsRevealed > 0 ? { hintsRevealed } : {}
164
+ };
165
+ }
166
+ /**
167
+ * The slower recording as an `ActivityMedia`: it follows the recording's
168
+ * playback policy minus `maxPlays` (`controls`, `seek`, `rate`, the native
169
+ * hints), so a locked scrubber or a fixed speed binds both files — and it never
170
+ * carries a budget of its own, so `<ActivityMedia>` never demands a binding
171
+ * for it. `undefined` when there is no slow recording.
172
+ */
173
+ function slowMediaFor(data, label) {
174
+ const slow = data.slowMedia;
175
+ if (slow === void 0) return;
176
+ const { maxPlays: _budget, ...inherited } = data.media?.playback ?? {};
177
+ const hasPolicy = Object.values(inherited).some((value) => value !== void 0);
178
+ return {
179
+ type: "audio",
180
+ url: slow.url,
181
+ alt: slow.alt ?? label,
182
+ ...hasPolicy ? { playback: inherited } : {}
183
+ };
184
+ }
185
+ /**
186
+ * The transcript's words as a learner would read them: raw, in order, split at
187
+ * whitespace. A token with nothing in it that is spelled — a dash, an ellipsis
188
+ * — is joined to the word before it (or to the first word, when it leads), so
189
+ * every reveal shows a word. A script written without spaces is one token, so
190
+ * one reveal shows the whole sentence.
191
+ */
192
+ function hintWordsOf(transcript) {
193
+ const words = [];
194
+ let leading = "";
195
+ for (const token of transcript.split(HINT_SPACE_RE)) {
196
+ if (token === "") continue;
197
+ const last = words.length - 1;
198
+ if (!UNSPELLED_RE.test(token.normalize("NFC"))) {
199
+ words.push(leading === "" ? token : `${leading} ${token}`);
200
+ leading = "";
201
+ } else if (last >= 0) words[last] = `${words[last]} ${token}`;
202
+ else leading = leading === "" ? token : `${leading} ${token}`;
203
+ }
204
+ return words;
205
+ }
206
+ /**
207
+ * Word marks rebuilt from stored scoring details — a server-recorded mark
208
+ * shown after an exam, with no transcript on the client. Extras are not in the
209
+ * details (the scorer writes one per transcript word), so none appear.
210
+ */
211
+ function wordsFromDetails(details) {
212
+ if (details.length === 0 || !details.every((detail) => /^w\d+$/.test(detail.itemId))) return null;
213
+ return details.map((detail) => {
214
+ const attempt = Array.isArray(detail.learnerResponse) ? detail.learnerResponse.join(" ") : detail.learnerResponse;
215
+ const reference = Array.isArray(detail.correctResponse) ? detail.correctResponse.join(" ") : detail.correctResponse;
216
+ const correct = require_useAiHelp.detailIsRight(detail);
217
+ const missing = detail.outcome === "incorrect-omission" || !correct && attempt === "";
218
+ return {
219
+ itemId: detail.itemId,
220
+ reference,
221
+ attempt,
222
+ similarity: detail.score ?? (correct ? 1 : 0),
223
+ status: correct ? "correct" : missing ? "missing" : "incorrect"
224
+ };
225
+ });
226
+ }
227
+ /**
228
+ * Whether `shown`, the character an operation displays, is drawn into the
229
+ * cluster whose characters so far are `before`: a mark, a joiner or a skin tone
230
+ * onto its base, a letter stacked under a virama, an alef fused with the lam
231
+ * before it, the second half of a flag.
232
+ */
233
+ function extendsCluster(before, shown) {
234
+ const previous = before.at(-1);
235
+ if (EXTENDING_RE.test(shown)) return true;
236
+ if (LETTER_RE.test(shown)) {
237
+ if (STACKING_VIRAMAS.has(previous) || PREPENDED.has(previous) || SUBJOINED_AFTER.get(shown)?.(before) === true) return true;
238
+ if (previous === ZERO_WIDTH_JOINER && JOINABLE_VIRAMAS.has(before.at(-2))) return true;
239
+ }
240
+ if (previous === ARABIC_LAM && LIGATING_ALEFS.has(shown)) return true;
241
+ return REGIONAL_INDICATOR_RE.test(shown) && before.length % 2 === 1 && before.every((character) => REGIONAL_INDICATOR_RE.test(character));
242
+ }
243
+ /** The character an operation stands for: what should have been typed, or what was typed in excess. */
244
+ function characterOf(op) {
245
+ return op.reference === "" ? op.attempt : op.reference;
246
+ }
247
+ function isArabicLetter(character) {
248
+ const point = character?.codePointAt(0);
249
+ return point !== void 0 && LETTER_RE.test(character) && ARABIC_LETTER_BLOCKS.some(([first, last]) => point >= first && point <= last);
250
+ }
251
+ /**
252
+ * The directions missing characters' bullets are laid out in, by operation
253
+ * index, worked out in two passes over the operations rather than a search
254
+ * per bullet: a word of 2,000 emoji missing its letters took seconds to draw.
255
+ *
256
+ * A bullet takes the character's own direction when it has one — a digit runs
257
+ * left to right, unless it is a digit of a right-to-left script. A currency,
258
+ * degree or per-mille sign beside a digit is laid out with that number, left to
259
+ * right, unless an Arabic letter comes before it, after which the number is not
260
+ * a European one. Otherwise, for a space or a punctuation mark, it takes the
261
+ * direction of the characters on both sides when they agree, and the content's
262
+ * when they do not. A bare bullet is a neutral, which the bidirectional
263
+ * algorithm would otherwise attach to the wrong side of a number or a word of
264
+ * the other direction.
265
+ */
266
+ function bulletDirections(ops, contentDir) {
267
+ const own = ops.map((op) => require_direction.characterDirectionOf(characterOf(op)));
268
+ const before = [];
269
+ const arabicBefore = [];
270
+ let lastDirection;
271
+ let lastLetterArabic = false;
272
+ ops.forEach((op, index) => {
273
+ before[index] = lastDirection;
274
+ arabicBefore[index] = lastLetterArabic;
275
+ lastDirection = own[index] ?? lastDirection;
276
+ if (LETTER_RE.test(characterOf(op))) lastLetterArabic = isArabicLetter(characterOf(op));
277
+ });
278
+ const after = [];
279
+ let nextDirection;
280
+ for (let index = ops.length - 1; index >= 0; index -= 1) {
281
+ after[index] = nextDirection;
282
+ nextDirection = own[index] ?? nextDirection;
283
+ }
284
+ const directions = /* @__PURE__ */ new Map();
285
+ ops.forEach((op, index) => {
286
+ if (op.op !== "missing") return;
287
+ const neighbourIsDigit = [ops[index - 1], ops[index + 1]].some((neighbour) => neighbour !== void 0 && DIGIT_RE.test(characterOf(neighbour)));
288
+ directions.set(index, own[index] ?? (NUMBER_SIGN_RE.test(characterOf(op)) && neighbourIsDigit && !arabicBefore[index] ? "ltr" : before[index] !== void 0 && before[index] === after[index] ? before[index] : contentDir ?? before[index] ?? after[index]));
289
+ });
290
+ return directions;
291
+ }
292
+ /**
293
+ * How a cluster is marked. One led by a missing character's bullet is missing,
294
+ * whatever marks sit on the bullet: the character they belong to is not there.
295
+ * Otherwise a cluster is marked as its wrong operations are when they agree —
296
+ * a correct letter with an extra mark is `extra` — and as a substitution when
297
+ * they do not.
298
+ */
299
+ function clusterOpOf(ops) {
300
+ if (ops[0].op === "missing") return "missing";
301
+ const wrong = new Set(ops.map((op) => op.op).filter((kind) => kind !== "equal"));
302
+ if (wrong.size === 0) return "equal";
303
+ return wrong.size === 1 ? [...wrong][0] : "substitute";
304
+ }
305
+ /**
306
+ * Character operations grouped into what is drawn as one cluster, so a wrong
307
+ * combining mark, joiner or stacked letter marks the glyph it is drawn into —
308
+ * alone, its span has no width, and its underline or strike would not be
309
+ * painted at all. A missing character's bullet carries only the marks drawn
310
+ * onto it, never a letter that is drawn apart. A missing character's bullet is
311
+ * wrapped in the direction mark of the character it stands for. Consecutive
312
+ * correct clusters are one run: an engine that shapes each element on its own
313
+ * would otherwise draw a correctly typed conjunct or a joined Mongolian word
314
+ * broken apart.
315
+ */
316
+ function clustersOf(ops, contentDir) {
317
+ const bullets = bulletDirections(ops, contentDir);
318
+ const groups = [];
319
+ ops.forEach((op, index) => {
320
+ const shown = op.op === "missing" ? BULLET : op.attempt;
321
+ const current = groups.at(-1);
322
+ if (current !== void 0 && op.op !== "missing" && (current.ops[0].op === "missing" ? EXTENDING_RE.test(shown) : extendsCluster(current.shown, shown))) {
323
+ current.ops.push(op);
324
+ current.shown.push(shown);
325
+ return;
326
+ }
327
+ const direction = bullets.get(index);
328
+ groups.push({
329
+ ops: [op],
330
+ shown: [shown],
331
+ ...direction !== void 0 ? { bullet: direction } : {}
332
+ });
333
+ });
334
+ const clusters = [];
335
+ for (const group of groups) {
336
+ const mark = group.bullet === void 0 ? "" : group.bullet === "rtl" ? RIGHT_TO_LEFT_MARK : LEFT_TO_RIGHT_MARK;
337
+ const cluster = {
338
+ op: clusterOpOf(group.ops),
339
+ text: `${mark}${group.shown.join("")}${mark}`
340
+ };
341
+ const previous = clusters.at(-1);
342
+ if (previous !== void 0 && previous.op === "equal" && cluster.op === "equal") previous.text += cluster.text;
343
+ else clusters.push(cluster);
344
+ }
345
+ return clusters;
346
+ }
347
+ /**
348
+ * Character-level edit operations as decoration. Hidden from assistive
349
+ * technology as a whole: a screen reader must never verbalise surrogate or
350
+ * combining fragments one by one, and the word list already carries the
351
+ * meaning. Sighted colour-blind and forced-colors users still get one
352
+ * decoration per state, which the skin draws and the legend explains.
353
+ */
354
+ function CharOps({ ops, contentDir }) {
355
+ return clustersOf(ops, contentDir).map((cluster, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
356
+ className: "lk-dc-op",
357
+ "data-op": cluster.op,
358
+ ...LETTER_WITH_REQUIRED_LIGATURES_RE.test(cluster.text) ? {} : { "data-ligatures": "decorative" },
359
+ "aria-hidden": "true",
360
+ children: cluster.text
361
+ }, index));
362
+ }
363
+ /**
364
+ * The announcement, with authored feedback in its own isolated span: its
365
+ * direction is its own, so an English "Well heard." in an Arabic interface
366
+ * keeps its full stop at its end. Its language is not guessed — feedback may be
367
+ * written in the interface's language or the dictation's.
368
+ */
369
+ function AnnouncementText({ announcement }) {
370
+ if (announcement === null) return null;
371
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [announcement.text, announcement.feedback ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [" ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
372
+ dir: "auto",
373
+ children: announcement.feedback
374
+ })] }) : null] });
375
+ }
376
+ function Dictation$1({ data, onComplete, onSubmit, onChange, onInteraction, value, defaultValue, defaultSubmitted, renderMode = "practice", outcome, mediaBudget, mediaStrings, strings, theme, locale, disabled, ai: aiProp, delivery, scoring }) {
377
+ const isExam = renderMode === "exam";
378
+ const isReview = renderMode === "review";
379
+ const s = require_LkIntlProvider.useLkStrings(strings);
380
+ const ai = require_ai_LkAiProvider.useLearnerAi(aiProp);
381
+ const policy = require_FeedbackRegion.useDeliveryPolicy(delivery);
382
+ const scoringPolicy = require_tries.useItemScoringPolicy(scoring);
383
+ const hasKey = typeof data.transcript === "string";
384
+ const devError = (0, react.useMemo)(() => {
385
+ if (!require_useAiHelp.isDevelopment()) return null;
386
+ if (data.redacted === true) {
387
+ if (hasKey) {
388
+ const shape = data;
389
+ return shape.type === "dictation" && typeof shape.id === "string" && typeof shape.title === "string" ? null : /* @__PURE__ */ new Error("Dictation received a revealed projection (redacted: true with a transcript) that is not a dictation: `type`, `id` and `title` are required.");
390
+ }
391
+ try {
392
+ (0, _intellectif_lk_core.assertRedacted)(data);
393
+ return null;
394
+ } catch (error) {
395
+ return error instanceof Error ? error : new Error(String(error));
396
+ }
397
+ }
398
+ const result = (0, _intellectif_lk_core.validateActivity)("dictation", data);
399
+ return result.success ? null : new _intellectif_lk_core.ActivitySchemaError("dictation", result.errors);
400
+ }, [data, hasKey]);
401
+ const { state, start, complete, getTimeSpent, reset } = require_hooks_useActivityState.useActivityState(defaultSubmitted === true ? "completed" : "idle");
402
+ const tries = require_tries.useTries({
403
+ policy: scoringPolicy,
404
+ graded: renderMode === "practice" && policy.feedback,
405
+ submitted: state === "completed",
406
+ disabled: disabled === true
407
+ });
408
+ const resetTries = tries.reset;
409
+ const isControlled = value !== void 0;
410
+ const [internalText, setInternalText] = (0, react.useState)(() => textOf(defaultValue));
411
+ const [internalRevealed, setInternalRevealed] = (0, react.useState)(() => hintsOf(defaultValue));
412
+ const [result, setResult] = (0, react.useState)(null);
413
+ const [summary, setSummary] = (0, react.useState)(null);
414
+ const [solutionShown, setSolutionShown] = (0, react.useState)(false);
415
+ const formRef = (0, react.useRef)(null);
416
+ const feedbackRef = (0, react.useRef)(null);
417
+ const focusAfterRef = (0, react.useRef)(null);
418
+ const text = isControlled ? textOf(value) : internalText;
419
+ const revealed = isControlled ? hintsOf(value) : internalRevealed;
420
+ const defaultValueRef = (0, react.useRef)(defaultValue);
421
+ (0, react.useEffect)(() => {
422
+ defaultValueRef.current = defaultValue;
423
+ }, [defaultValue]);
424
+ const defaultSubmittedRef = (0, react.useRef)(defaultSubmitted);
425
+ (0, react.useEffect)(() => {
426
+ defaultSubmittedRef.current = defaultSubmitted;
427
+ }, [defaultSubmitted]);
428
+ const lastDataRef = (0, react.useRef)(data);
429
+ (0, react.useEffect)(() => {
430
+ if (lastDataRef.current === data) return;
431
+ lastDataRef.current = data;
432
+ setInternalText(textOf(defaultValueRef.current));
433
+ setInternalRevealed(hintsOf(defaultValueRef.current));
434
+ setResult(null);
435
+ setSummary(null);
436
+ setSolutionShown(false);
437
+ resetTries();
438
+ reset(defaultSubmittedRef.current === true ? "completed" : "idle");
439
+ }, [
440
+ data,
441
+ reset,
442
+ resetTries
443
+ ]);
444
+ const textChangedRef = (0, react.useRef)(null);
445
+ (0, react.useEffect)(() => () => {
446
+ if (textChangedRef.current !== null) clearTimeout(textChangedRef.current.timer);
447
+ }, []);
448
+ const revealButtonRef = (0, react.useRef)(null);
449
+ const ids = (0, react.useId)();
450
+ const hintId = `${ids}-hint`;
451
+ const titleId = `${ids}-title`;
452
+ const solutionId = `${ids}-solution`;
453
+ const [recordingsGroup] = (0, react.useState)(() => {
454
+ recordingsGroupCount += 1;
455
+ return `lk-dc-recordings-${recordingsGroupCount}`;
456
+ });
457
+ const slowMedia = (0, react.useMemo)(() => slowMediaFor(data, s.dictationSlowRecording), [data, s.dictationSlowRecording]);
458
+ (0, react.useEffect)(() => {
459
+ const target = focusAfterRef.current;
460
+ if (target === null) return;
461
+ focusAfterRef.current = null;
462
+ if (target === "answer") formRef.current?.querySelector("textarea")?.focus();
463
+ else feedbackRef.current?.focus();
464
+ });
465
+ if (devError) throw devError;
466
+ if (data.redacted === true && renderMode === "practice") throw new Error(`Dictation "${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\`).`);
467
+ const submitted = state === "completed";
468
+ const inactive = disabled === true || submitted || isReview;
469
+ const marking = (isReview ? outcome?.status === "scored" : !isExam && submitted) && policy.feedback;
470
+ const solutionsShown = policy.solutions && !tries.open;
471
+ const transcript = isExam || !hasKey ? void 0 : data.transcript;
472
+ const hintWords = (0, react.useMemo)(() => transcript === void 0 ? [] : hintWordsOf(transcript), [transcript]);
473
+ const hintsOffered = policy.hints && data.hints?.mode === "progressive-words" && !isExam && !isReview && transcript !== void 0;
474
+ const hintsEnabled = hintsOffered && !submitted;
475
+ const hintTotal = hintWords.length;
476
+ const hintsShown = Math.min(revealed, hintTotal);
477
+ const reportedHints = hintsOffered ? hintsShown : 0;
478
+ const fireInteraction = (type, payload) => {
479
+ onInteraction?.({
480
+ type,
481
+ activityId: data.id,
482
+ timestamp: Date.now(),
483
+ payload
484
+ });
485
+ };
486
+ const flushTextChanged = () => {
487
+ const pending = textChangedRef.current;
488
+ if (pending === null) return;
489
+ clearTimeout(pending.timer);
490
+ textChangedRef.current = null;
491
+ fireInteraction("text-changed", { length: pending.length });
492
+ };
493
+ const handleTextChange = (next) => {
494
+ if (inactive) return;
495
+ if (state === "idle") start();
496
+ if (!isControlled) setInternalText(next);
497
+ onChange?.(responseOf(next, reportedHints));
498
+ if (onInteraction === void 0) return;
499
+ if (textChangedRef.current !== null) clearTimeout(textChangedRef.current.timer);
500
+ textChangedRef.current = {
501
+ length: next.length,
502
+ timer: setTimeout(() => {
503
+ const pending = textChangedRef.current;
504
+ textChangedRef.current = null;
505
+ if (pending !== null) fireInteraction("text-changed", { length: pending.length });
506
+ }, TEXT_CHANGED_DEBOUNCE_MS)
507
+ };
508
+ };
509
+ const setRevealed = (next) => {
510
+ if (!isControlled) setInternalRevealed(next);
511
+ onChange?.(responseOf(text, next));
512
+ };
513
+ const revealNextHint = () => {
514
+ if (inactive || hintsShown >= hintTotal) return;
515
+ if (state === "idle") start();
516
+ const next = hintsShown + 1;
517
+ setRevealed(next);
518
+ fireInteraction("hint-requested", {
519
+ revealed: next,
520
+ total: hintTotal
521
+ });
522
+ };
523
+ const resetHints = () => {
524
+ if (inactive || hintsShown === 0 || scoringPolicy.hintPenalty > 0) return;
525
+ revealButtonRef.current?.focus();
526
+ setRevealed(0);
527
+ };
528
+ const handleSubmit = (event) => {
529
+ event.preventDefault();
530
+ if (inactive) return;
531
+ const response = responseOf(text, reportedHints);
532
+ onSubmit?.(response);
533
+ flushTextChanged();
534
+ if (isExam) {
535
+ complete();
536
+ setSummary({
537
+ text: s.answerSubmitted,
538
+ feedback: null
539
+ });
540
+ fireInteraction("submitted", {
541
+ length: text.length,
542
+ hintsRevealed: reportedHints
543
+ });
544
+ return;
545
+ }
546
+ const answer = (0, _intellectif_lk_core.score)("dictation", data, response);
547
+ complete();
548
+ const timeSpent = getTimeSpent();
549
+ const counted = tries.record({
550
+ score: answer.score,
551
+ maxScore: answer.maxScore,
552
+ hintsRevealed: reportedHints
553
+ });
554
+ const mine = counted.tries[counted.tries.length - 1];
555
+ const costed = mine === void 0 ? answer.score : mine.scored;
556
+ const scoringResult = costed === answer.score ? answer : {
557
+ ...answer,
558
+ score: costed,
559
+ passed: (0, _intellectif_lk_core.computePassThreshold)(data, costed)
560
+ };
561
+ const passed = counted.score === scoringResult.score ? scoringResult.passed : (0, _intellectif_lk_core.computePassThreshold)(data, counted.score);
562
+ const xapiStatement = _intellectif_lk_core.xAPIBuilder.buildAnsweredStatement({
563
+ actor: require_useAiHelp.ANONYMOUS_ACTOR,
564
+ object: {
565
+ id: require_useAiHelp.objectIdFor(data.id),
566
+ name: { [data.locale ?? "en-US"]: data.title },
567
+ ...(0, _intellectif_lk_core.xapiDefinitionFor)(data)
568
+ },
569
+ scoringResult,
570
+ timeSpentMs: timeSpent,
571
+ response: response.text
572
+ });
573
+ setResult(answer);
574
+ onComplete?.(require_useAiHelp.stampTake({
575
+ score: counted.score,
576
+ maxScore: counted.maxScore,
577
+ passed,
578
+ timeSpent,
579
+ xapiStatement
580
+ }, require_useAiHelp.mintTake()));
581
+ const correctWords = answer.details.filter(require_useAiHelp.detailIsRight).length;
582
+ setSolutionShown(false);
583
+ setSummary({
584
+ text: `${s.answerSubmitted} ${s.scoreAnnouncement(Math.round(counted.score * 100), passed)} ${s.dictationWordsSummary(correctWords, answer.details.length)}`,
585
+ feedback: answer.feedback
586
+ });
587
+ fireInteraction("submitted", {
588
+ length: text.length,
589
+ hintsRevealed: reportedHints,
590
+ score: scoringResult.score
591
+ });
592
+ };
593
+ /** "Try again": the text stays, to be corrected; the marks go. Hints shown stay shown. */
594
+ const retry = () => {
595
+ reset("idle");
596
+ setSummary(null);
597
+ focusAfterRef.current = "answer";
598
+ };
599
+ /** "Show answer": no more tries; the question shows what a finished one shows. */
600
+ const closeTries = () => {
601
+ tries.close();
602
+ focusAfterRef.current = "feedback";
603
+ };
604
+ const given = isControlled ? value : defaultValue;
605
+ const hasResponse = given !== void 0 && given.type === "dictation";
606
+ const contentLang = typeof data.locale === "string" ? data.locale.replaceAll("_", "-") : void 0;
607
+ const localeDir = require_direction.localeDirectionOf(data.locale);
608
+ const alignment = (0, react.useMemo)(() => marking && transcript !== void 0 && (!isReview || hasResponse) ? (0, _intellectif_lk_core.alignDictation)(data, text) : null, [
609
+ marking,
610
+ transcript,
611
+ isReview,
612
+ hasResponse,
613
+ data,
614
+ text
615
+ ]);
616
+ const sentenceDiff = (0, react.useMemo)(() => alignment !== null && alignment.attempt !== "" && solutionsShown ? (0, _intellectif_lk_core.diffDictationChars)(alignment.reference, alignment.attempt) : null, [alignment, solutionsShown]);
617
+ const detailWords = (0, react.useMemo)(() => isReview && alignment === null && outcome?.status === "scored" ? wordsFromDetails(outcome.details) : null, [
618
+ isReview,
619
+ alignment,
620
+ outcome
621
+ ]);
622
+ const words = alignment?.words ?? detailWords;
623
+ const marksShown = marking && words !== null;
624
+ const contentDir = localeDir ?? require_direction.textDirectionOf(transcript ?? words?.map((word) => word.reference).join(" ") ?? "");
625
+ const nothingTyped = alignment !== null ? alignment.attempt === "" : words?.every((word) => word.attempt === "") ?? false;
626
+ const passed = isReview ? outcome?.status === "scored" || outcome?.status === "graded" ? outcome.passed : void 0 : result?.passed;
627
+ const reviewSummary = (0, react.useMemo)(() => {
628
+ if (!isReview || outcome === void 0) return null;
629
+ if (outcome.status === "scored") return {
630
+ text: s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed),
631
+ feedback: outcome.feedback
632
+ };
633
+ if (outcome.status === "deferred") return {
634
+ text: s.notGradedYet,
635
+ feedback: null
636
+ };
637
+ if (outcome.status === "graded") {
638
+ const percent = outcome.maxScore > 0 ? Math.round(outcome.score / outcome.maxScore * 100) : Math.round(outcome.score * 100);
639
+ return {
640
+ text: s.scoreAnnouncement(percent, outcome.passed),
641
+ feedback: outcome.feedback ?? null
642
+ };
643
+ }
644
+ return {
645
+ text: s.noGradeAvailable,
646
+ feedback: null
647
+ };
648
+ }, [
649
+ isReview,
650
+ outcome,
651
+ s
652
+ ]);
653
+ const sentenceFor = (word) => {
654
+ switch (word.status) {
655
+ case "correct": return s.dictationWordCorrect(word.attempt);
656
+ case "incorrect": return solutionsShown ? s.dictationWordWrong(word.attempt, word.reference) : s.dictationWordWrongUnnamed(word.attempt);
657
+ case "missing": return solutionsShown ? s.dictationWordMissing(word.reference) : s.dictationWordMissingUnnamed;
658
+ default: return s.dictationWordExtra(word.attempt);
659
+ }
660
+ };
661
+ const acceptedTranscripts = transcript === void 0 || !Array.isArray(data.acceptedTranscripts) ? void 0 : data.acceptedTranscripts.filter((entry) => typeof entry === "string");
662
+ const extra = !isReview && policy.feedback && submitted && tries.counted !== null ? require_tries.triesSummary(s, scoringPolicy, tries.counted, tries.open) : "";
663
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
664
+ ref: formRef,
665
+ className: "lk-dc",
666
+ "aria-labelledby": VISIBLE_TEXT_RE.test(data.title) ? titleId : void 0,
667
+ lang: locale,
668
+ "data-render-mode": renderMode,
669
+ style: theme,
670
+ onSubmit: handleSubmit,
671
+ children: [
672
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
673
+ id: titleId,
674
+ className: "lk-dc-title",
675
+ dir: localeDir ?? "auto",
676
+ lang: contentLang,
677
+ children: data.title
678
+ }),
679
+ data.media !== void 0 || slowMedia !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
680
+ className: "lk-dc-recordings",
681
+ children: [data.media !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
682
+ className: "lk-dc-recording",
683
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
684
+ className: "lk-dc-recording-label",
685
+ children: s.dictationRecording
686
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ActivityMedia.ActivityMedia, {
687
+ media: data.media,
688
+ renderMode,
689
+ playbackGroup: recordingsGroup,
690
+ ...mediaBudget !== void 0 ? { mediaBudget } : {},
691
+ ...mediaStrings !== void 0 ? { mediaStrings } : {},
692
+ ...strings !== void 0 ? { strings } : {},
693
+ ...onInteraction !== void 0 ? { onInteraction } : {},
694
+ ...locale !== void 0 ? { locale } : {},
695
+ ...disabled !== void 0 ? { disabled } : {}
696
+ })]
697
+ }) : null, slowMedia !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
698
+ className: "lk-dc-recording",
699
+ "data-slow": "true",
700
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
701
+ className: "lk-dc-recording-label",
702
+ children: s.dictationSlowRecording
703
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ActivityMedia.ActivityMedia, {
704
+ media: slowMedia,
705
+ renderMode,
706
+ playbackGroup: recordingsGroup,
707
+ ...mediaStrings !== void 0 ? { mediaStrings } : {},
708
+ ...strings !== void 0 ? { strings } : {},
709
+ ...locale !== void 0 ? { locale } : {},
710
+ ...disabled !== void 0 ? { disabled } : {}
711
+ })]
712
+ }) : null]
713
+ }) : null,
714
+ hintsEnabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
715
+ className: "lk-dc-hints",
716
+ children: [
717
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
718
+ ref: revealButtonRef,
719
+ type: "button",
720
+ className: "lk-dc-hint-btn",
721
+ disabled: inactive,
722
+ "aria-disabled": hintsShown >= hintTotal || void 0,
723
+ onClick: revealNextHint,
724
+ children: s.dictationRevealNextWord(hintsShown, hintTotal)
725
+ }),
726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_tries.HintCost, {
727
+ policy: scoringPolicy,
728
+ strings: s
729
+ }),
730
+ hintsShown > 0 && scoringPolicy.hintPenalty <= 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
731
+ type: "button",
732
+ className: "lk-dc-hint-reset",
733
+ disabled: inactive,
734
+ onClick: resetHints,
735
+ children: s.dictationResetHints
736
+ }) : null,
737
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
738
+ id: hintId,
739
+ className: "lk-dc-hint",
740
+ role: "status",
741
+ dir: contentDir,
742
+ lang: contentLang,
743
+ children: hintsShown > 0 ? `${hintWords.slice(0, hintsShown).join(" ")}${hintsShown < hintTotal ? " …" : ""}` : ""
744
+ })
745
+ ]
746
+ }) : null,
747
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
748
+ disabled: inactive,
749
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
750
+ className: "lk-dc-input",
751
+ "aria-label": s.dictationInputLabel,
752
+ "aria-describedby": hintsEnabled && hintsShown > 0 ? hintId : void 0,
753
+ dir: "auto",
754
+ rows: 3,
755
+ maxLength: _intellectif_lk_core.DICTATION_MAX_TEXT_LENGTH,
756
+ autoComplete: "off",
757
+ autoCapitalize: "none",
758
+ autoCorrect: "off",
759
+ spellCheck: false,
760
+ value: text,
761
+ disabled: inactive,
762
+ "aria-disabled": inactive || void 0,
763
+ "data-correct": marking && passed !== void 0 && (!isReview || hasResponse) ? String(passed) : void 0,
764
+ onChange: (event) => handleTextChange(event.target.value)
765
+ }), isReview ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
766
+ type: "submit",
767
+ disabled: inactive,
768
+ children: isExam ? s.submitAnswers : s.checkAnswers
769
+ })]
770
+ }),
771
+ marksShown ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
772
+ className: "lk-dc-result",
773
+ children: [nothingTyped ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
774
+ className: "lk-dc-nothing",
775
+ role: "note",
776
+ children: s.dictationNothingTyped
777
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
778
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
779
+ className: "lk-dc-words",
780
+ "aria-label": s.dictationMarksLabel,
781
+ dir: contentDir,
782
+ children: words?.map((word, index) => {
783
+ const sentence = sentenceFor(word);
784
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
785
+ className: "lk-dc-word",
786
+ "data-state": word.status,
787
+ title: sentence,
788
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
789
+ className: "lk-visually-hidden",
790
+ style: VISUALLY_HIDDEN,
791
+ children: sentence
792
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
793
+ className: "lk-dc-word-text",
794
+ "aria-hidden": "true",
795
+ dir: contentDir ?? "auto",
796
+ lang: contentLang,
797
+ ...word.status === "incorrect" && alignment !== null && solutionsShown ? { "data-marks": "characters" } : {},
798
+ children: word.status === "incorrect" && alignment !== null && solutionsShown ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharOps, {
799
+ ops: (0, _intellectif_lk_core.diffDictationChars)(word.reference, word.attempt),
800
+ contentDir
801
+ }) : word.status === "missing" ? solutionsShown ? word.reference : "…" : word.attempt
802
+ })]
803
+ }, index);
804
+ })
805
+ }),
806
+ sentenceDiff !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
807
+ className: "lk-dc-diff",
808
+ "aria-hidden": "true",
809
+ dir: contentDir,
810
+ lang: contentLang,
811
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharOps, {
812
+ ops: sentenceDiff,
813
+ contentDir
814
+ })
815
+ }) : null,
816
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
817
+ className: "lk-dc-legend",
818
+ children: [
819
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
820
+ "data-state": "correct",
821
+ children: s.dictationLegendCorrect
822
+ }),
823
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
824
+ "data-state": "incorrect",
825
+ children: s.dictationLegendWrong
826
+ }),
827
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
828
+ "data-state": "missing",
829
+ children: s.dictationLegendMissing
830
+ }),
831
+ alignment !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
832
+ "data-state": "extra",
833
+ children: s.dictationLegendExtra
834
+ }) : null
835
+ ]
836
+ }),
837
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
838
+ className: "lk-dc-diff-note",
839
+ children: s.dictationDiffNote
840
+ })
841
+ ] }), transcript !== void 0 && solutionsShown ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
842
+ type: "button",
843
+ className: "lk-dc-solution-toggle",
844
+ "aria-expanded": solutionShown,
845
+ "aria-controls": solutionId,
846
+ onClick: () => setSolutionShown((shown) => !shown),
847
+ children: solutionShown ? s.hideSolution : s.showSolution
848
+ }), solutionShown ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("blockquote", {
849
+ id: solutionId,
850
+ className: "lk-dc-solution",
851
+ "aria-label": s.dictationSolutionLabel,
852
+ dir: contentDir,
853
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
854
+ lang: contentLang,
855
+ children: transcript
856
+ }), acceptedTranscripts !== void 0 && acceptedTranscripts.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
857
+ className: "lk-dc-solution-alternatives",
858
+ lang: contentLang,
859
+ children: acceptedTranscripts.map((alternative) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: alternative }, alternative))
860
+ }) : null]
861
+ }) : null] }) : null]
862
+ }) : null,
863
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FeedbackRegion.FeedbackRegion, {
864
+ id: `${data.id}-feedback`,
865
+ ...scoringPolicy.retries > 0 ? { ref: feedbackRef } : {},
866
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnnouncementText, { announcement: require_FeedbackRegion.feedbackAnnouncement({
867
+ review: isReview,
868
+ feedback: policy.feedback,
869
+ outcome,
870
+ readBack: reviewSummary,
871
+ submitted: summary !== null,
872
+ result: summary === null || extra === "" ? summary : {
873
+ ...summary,
874
+ text: `${summary.text} ${extra}`
875
+ },
876
+ received: {
877
+ text: s.answerSubmitted,
878
+ feedback: null
879
+ }
880
+ }) })
881
+ }),
882
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_tries.TryActions, {
883
+ tries,
884
+ solutions: policy.solutions && transcript !== void 0,
885
+ strings: s,
886
+ onRetry: retry,
887
+ onClose: closeTries
888
+ }),
889
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_tries.AiExplanation, {
890
+ ai,
891
+ data,
892
+ renderMode,
893
+ submitted,
894
+ response: responseOf(text, reportedHints),
895
+ outcome,
896
+ locale,
897
+ onInteraction,
898
+ strings: s,
899
+ delivery: tries.open ? {
900
+ ...policy,
901
+ solutions: false
902
+ } : policy
903
+ })
904
+ ]
905
+ });
906
+ }
907
+ //#endregion
908
+ //#region src/components/Dictation/index.tsx
909
+ /**
910
+ * Public Dictation activity: the core wrapped in `ActivityErrorBoundary` so a
911
+ * render failure (including the dev schema-validation throw and the
912
+ * redacted-in-`practice` guard) degrades to an accessible fallback instead of
913
+ * crashing the host.
914
+ */
915
+ function Dictation(props) {
916
+ const strings = require_LkIntlProvider.useLkStrings(props.strings);
917
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ActivityErrorBoundary.ActivityErrorBoundary, {
918
+ activityTitle: props.data?.title,
919
+ strings,
920
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dictation$1, { ...props })
921
+ });
922
+ }
923
+ //#endregion
924
+ Object.defineProperty(exports, "Dictation", {
925
+ enumerable: true,
926
+ get: function() {
927
+ return Dictation;
928
+ }
929
+ });
930
+
931
+ //# sourceMappingURL=Dictation-jECzL88E.cjs.map