@tinyweb_dev/oe-exam-sdk 0.1.3 → 0.1.4

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 (289) hide show
  1. package/README.md +58 -4
  2. package/dist/api/contest-rooms.d.ts +13 -0
  3. package/dist/api/contest-rooms.js +1 -0
  4. package/dist/api/contest-rooms.types.d.ts +47 -0
  5. package/dist/api/contest-rooms.types.js +1 -0
  6. package/dist/api/exam-entry.d.ts +14 -0
  7. package/dist/api/exam-entry.js +1 -0
  8. package/dist/api/exam-entry.types.d.ts +93 -0
  9. package/dist/api/exam-entry.types.js +1 -0
  10. package/dist/api/index.d.ts +2 -0
  11. package/dist/api/index.js +1 -1
  12. package/dist/components/exams/entry/EntryRestartDialog.d.ts +12 -0
  13. package/dist/components/exams/entry/EntryRestartDialog.js +1 -0
  14. package/dist/components/exams/entry/StudentExamEntryPageContainer.d.ts +31 -0
  15. package/dist/components/exams/entry/StudentExamEntryPageContainer.js +1 -0
  16. package/dist/components/exams/entry/exam-entry.states.d.ts +22 -0
  17. package/dist/components/exams/entry/exam-entry.states.js +1 -0
  18. package/dist/components/exams/entry/exam-entry.utils.d.ts +16 -0
  19. package/dist/components/exams/entry/exam-entry.utils.js +1 -0
  20. package/dist/components/exams/entry/fullscreen-loading.d.ts +5 -0
  21. package/dist/components/exams/entry/fullscreen-loading.js +1 -0
  22. package/dist/components/exams/entry/index.d.ts +7 -0
  23. package/dist/components/exams/entry/index.js +1 -0
  24. package/dist/components/exams/index.d.ts +8 -0
  25. package/dist/components/exams/index.js +1 -1
  26. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.d.ts +18 -0
  27. package/dist/components/exams/rooms/StudentContestRoomsPageContainer.js +1 -0
  28. package/dist/components/exams/rooms/contest-rooms.utils.d.ts +32 -0
  29. package/dist/components/exams/rooms/contest-rooms.utils.js +1 -0
  30. package/dist/components/exams/rooms/index.d.ts +3 -0
  31. package/dist/components/exams/rooms/index.js +1 -0
  32. package/dist/components/exams/take/ExamTakingApiContext.d.ts +10 -0
  33. package/dist/components/exams/take/ExamTakingApiContext.js +1 -0
  34. package/dist/components/exams/take/ExamTakingPageContainer.d.ts +28 -4
  35. package/dist/components/exams/take/ExamTakingPageContainer.js +1 -1
  36. package/dist/components/exams/take/components/QuestionRenderer.d.ts +25 -0
  37. package/dist/components/exams/take/components/QuestionRenderer.js +1 -0
  38. package/dist/components/exams/take/components/index.d.ts +10 -0
  39. package/dist/components/exams/take/components/index.js +1 -0
  40. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.d.ts +7 -0
  41. package/dist/components/exams/take/components/question-renderers/ArticlesViewer.js +1 -0
  42. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.d.ts +22 -0
  43. package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.js +1 -0
  44. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.d.ts +14 -0
  45. package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.js +1 -0
  46. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.d.ts +2 -0
  47. package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js +1 -0
  48. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.d.ts +3 -0
  49. package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.js +1 -0
  50. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.d.ts +2 -0
  51. package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.js +1 -0
  52. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.d.ts +2 -0
  53. package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.js +1 -0
  54. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.d.ts +2 -0
  55. package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.js +1 -0
  56. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.d.ts +21 -0
  57. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -0
  58. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.d.ts +19 -0
  59. package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.js +1 -0
  60. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.d.ts +2 -0
  61. package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.js +1 -0
  62. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.d.ts +2 -0
  63. package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.js +1 -0
  64. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.d.ts +2 -0
  65. package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.js +1 -0
  66. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.d.ts +20 -0
  67. package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.js +1 -0
  68. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.d.ts +32 -0
  69. package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.js +1 -0
  70. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.d.ts +18 -0
  71. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -0
  72. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.d.ts +19 -0
  73. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.js +1 -0
  74. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.d.ts +22 -0
  75. package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.js +1 -0
  76. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.d.ts +18 -0
  77. package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.js +1 -0
  78. package/dist/components/exams/take/components/question-renderers/index.d.ts +19 -0
  79. package/dist/components/exams/take/components/question-renderers/index.js +1 -0
  80. package/dist/components/exams/take/components/speaking/FindObjectInPicture.module.css +133 -0
  81. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.d.ts +9 -0
  82. package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.js +1 -0
  83. package/dist/components/exams/take/components/speaking/SpeakingCompareImages.module.css +153 -0
  84. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.d.ts +7 -0
  85. package/dist/components/exams/take/components/speaking/SpeakingContentFrame.js +1 -0
  86. package/dist/components/exams/take/components/speaking/SpeakingDragObjects.module.css +238 -0
  87. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.d.ts +27 -0
  88. package/dist/components/exams/take/components/speaking/SpeakingExamLayout.js +1 -0
  89. package/dist/components/exams/take/components/speaking/SpeakingHeader.d.ts +6 -0
  90. package/dist/components/exams/take/components/speaking/SpeakingHeader.js +1 -0
  91. package/dist/components/exams/take/components/speaking/SpeakingInfoExchange.module.css +193 -0
  92. package/dist/components/exams/take/components/speaking/SpeakingInfoExchangeSummerSky.module.css +238 -0
  93. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.d.ts +5 -0
  94. package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.js +1 -0
  95. package/dist/components/exams/take/components/speaking/SpeakingMicButton.d.ts +14 -0
  96. package/dist/components/exams/take/components/speaking/SpeakingMicButton.js +1 -0
  97. package/dist/components/exams/take/components/speaking/SpeakingNavButton.d.ts +7 -0
  98. package/dist/components/exams/take/components/speaking/SpeakingNavButton.js +1 -0
  99. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.d.ts +6 -0
  100. package/dist/components/exams/take/components/speaking/SpeakingPartBadge.js +1 -0
  101. package/dist/components/exams/take/components/speaking/SpeakingReadDisplayedContent.module.css +115 -0
  102. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.d.ts +11 -0
  103. package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.js +1 -0
  104. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.d.ts +1 -0
  105. package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.js +1 -0
  106. package/dist/components/exams/take/components/speaking/SpeakingStoryImages.module.css +231 -0
  107. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.d.ts +13 -0
  108. package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.js +1 -0
  109. package/dist/components/exams/take/components/speaking/index.d.ts +1 -0
  110. package/dist/components/exams/take/components/speaking/index.js +1 -0
  111. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.d.ts +16 -0
  112. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.js +1 -0
  113. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.d.ts +16 -0
  114. package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.js +1 -0
  115. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.d.ts +17 -0
  116. package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.js +1 -0
  117. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.d.ts +16 -0
  118. package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.js +1 -0
  119. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.d.ts +17 -0
  120. package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.js +1 -0
  121. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.d.ts +18 -0
  122. package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.js +1 -0
  123. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.d.ts +16 -0
  124. package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.js +1 -0
  125. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.d.ts +16 -0
  126. package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.js +1 -0
  127. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.d.ts +16 -0
  128. package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.js +1 -0
  129. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.d.ts +16 -0
  130. package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.js +1 -0
  131. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.d.ts +16 -0
  132. package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.js +1 -0
  133. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.d.ts +26 -0
  134. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.js +1 -0
  135. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.d.ts +32 -0
  136. package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.js +1 -0
  137. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.d.ts +34 -0
  138. package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.js +1 -0
  139. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.d.ts +17 -0
  140. package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.js +1 -0
  141. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.d.ts +17 -0
  142. package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.js +1 -0
  143. package/dist/components/exams/take/components/speaking/renderers/index.d.ts +13 -0
  144. package/dist/components/exams/take/components/speaking/renderers/index.js +1 -0
  145. package/dist/components/exams/take/hooks/index.d.ts +2 -0
  146. package/dist/components/exams/take/hooks/index.js +1 -0
  147. package/dist/components/exams/take/hooks/useAnswerAutosave.d.ts +27 -0
  148. package/dist/components/exams/take/hooks/useAnswerAutosave.js +1 -0
  149. package/dist/components/exams/take/hooks/useAttemptSubmit.d.ts +29 -0
  150. package/dist/components/exams/take/hooks/useAttemptSubmit.js +1 -0
  151. package/dist/components/exams/take/hooks/useAutoSave.d.ts +20 -0
  152. package/dist/components/exams/take/hooks/useAutoSave.js +1 -0
  153. package/dist/components/exams/take/hooks/useExamCountdown.d.ts +22 -0
  154. package/dist/components/exams/take/hooks/useExamCountdown.js +1 -0
  155. package/dist/components/exams/take/hooks/useExamTimer.d.ts +21 -0
  156. package/dist/components/exams/take/hooks/useExamTimer.js +1 -0
  157. package/dist/components/exams/take/hooks/useProctoringCamera.d.ts +19 -0
  158. package/dist/components/exams/take/hooks/useProctoringCamera.js +1 -0
  159. package/dist/components/exams/take/hooks/useProctoringSnapshot.d.ts +25 -0
  160. package/dist/components/exams/take/hooks/useProctoringSnapshot.js +1 -0
  161. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.d.ts +19 -0
  162. package/dist/components/exams/take/hooks/useSpeakingConversationAudio.js +1 -0
  163. package/dist/components/exams/take/hooks/useSpeakingNavigation.d.ts +37 -0
  164. package/dist/components/exams/take/hooks/useSpeakingNavigation.js +1 -0
  165. package/dist/components/exams/take/hooks/useSpeakingRecorder.d.ts +45 -5
  166. package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -1
  167. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.d.ts +39 -0
  168. package/dist/components/exams/take/hooks/useSpeakingRendererSetup.js +1 -0
  169. package/dist/components/exams/take/hooks/useToeicAudio.d.ts +17 -0
  170. package/dist/components/exams/take/hooks/useToeicAudio.js +1 -0
  171. package/dist/components/exams/take/index.d.ts +9 -1
  172. package/dist/components/exams/take/index.js +1 -1
  173. package/dist/components/exams/take/types/speaking-cue-card.types.d.ts +10 -0
  174. package/dist/components/exams/take/types/speaking-cue-card.types.js +1 -0
  175. package/dist/components/exams/take/types/speaking.types.d.ts +153 -0
  176. package/dist/components/exams/take/types/speaking.types.js +1 -0
  177. package/dist/components/exams/take/types.d.ts +286 -1
  178. package/dist/components/exams/take/utils/answer-transformers.d.ts +26 -0
  179. package/dist/components/exams/take/utils/answer-transformers.js +1 -0
  180. package/dist/components/exams/take/utils/coloring-assignments.d.ts +5 -0
  181. package/dist/components/exams/take/utils/coloring-assignments.js +1 -0
  182. package/dist/components/exams/take/utils/question-transformers.d.ts +362 -0
  183. package/dist/components/exams/take/utils/question-transformers.js +1 -0
  184. package/dist/components/features/exam-entry/entry-state-cards.d.ts +19 -0
  185. package/dist/components/features/exam-entry/entry-state-cards.js +1 -0
  186. package/dist/components/features/exam-entry/index.d.ts +2 -0
  187. package/dist/components/features/exam-entry/index.js +1 -0
  188. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.d.ts +12 -0
  189. package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.js +1 -0
  190. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.d.ts +14 -0
  191. package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.js +1 -0
  192. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.d.ts +16 -0
  193. package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.js +1 -0
  194. package/dist/components/features/exam-entry/themed/components/CloseButton.d.ts +9 -0
  195. package/dist/components/features/exam-entry/themed/components/CloseButton.js +1 -0
  196. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.d.ts +13 -0
  197. package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.js +1 -0
  198. package/dist/components/features/exam-entry/themed/components/ModeSelector.d.ts +7 -0
  199. package/dist/components/features/exam-entry/themed/components/ModeSelector.js +1 -0
  200. package/dist/components/features/exam-entry/themed/components/StartButton.d.ts +11 -0
  201. package/dist/components/features/exam-entry/themed/components/StartButton.js +1 -0
  202. package/dist/components/features/exam-entry/themed/components/index.d.ts +4 -0
  203. package/dist/components/features/exam-entry/themed/components/index.js +1 -0
  204. package/dist/components/features/exam-entry/themed/index.d.ts +1 -0
  205. package/dist/components/features/exam-entry/themed/index.js +1 -0
  206. package/dist/components/results/ResultReviewPageContainer.d.ts +3 -1
  207. package/dist/components/results/ResultReviewPageContainer.js +1 -1
  208. package/dist/components/results/hooks/useResultReviewPolling.d.ts +27 -0
  209. package/dist/components/results/hooks/useResultReviewPolling.js +1 -0
  210. package/dist/components/results/index.d.ts +3 -0
  211. package/dist/components/results/index.js +1 -1
  212. package/dist/components/results/review-status.utils.d.ts +12 -0
  213. package/dist/components/results/review-status.utils.js +1 -0
  214. package/dist/components/shared/audio/SpeakingAudioPlayer.d.ts +12 -0
  215. package/dist/components/shared/audio/SpeakingAudioPlayer.js +1 -0
  216. package/dist/components/shared/audio/SpeakingAudioPlayer.module.css +115 -0
  217. package/dist/components/shared/audio/assets/fr-image-part1-border.png +0 -0
  218. package/dist/components/shared/audio/assets/ic-speaker.webp +0 -0
  219. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.d.ts +11 -3
  220. package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -1
  221. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.d.ts +5 -1
  222. package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -1
  223. package/dist/components/themes/index.d.ts +11 -0
  224. package/dist/components/themes/index.js +1 -1
  225. package/dist/components/themes/spaceship/SpaceshipAudioPlayer.d.ts +8 -0
  226. package/dist/components/themes/spaceship/SpaceshipAudioPlayer.js +1 -0
  227. package/dist/components/themes/spaceship/SpaceshipLayout.d.ts +2 -0
  228. package/dist/components/themes/spaceship/SpaceshipLayout.js +1 -0
  229. package/dist/components/themes/spaceship/assets/images/X-sunset.png +0 -0
  230. package/dist/components/themes/spaceship/assets/images/X.webp +0 -0
  231. package/dist/components/themes/spaceship/assets/images/audio-bar.webp +0 -0
  232. package/dist/components/themes/spaceship/assets/images/background.webp +0 -0
  233. package/dist/components/themes/spaceship/assets/images/bg_sunset.png +0 -0
  234. package/dist/components/themes/spaceship/assets/images/big-blue-badge-sunset.png +0 -0
  235. package/dist/components/themes/spaceship/assets/images/big-blue-badge.png +0 -0
  236. package/dist/components/themes/spaceship/assets/images/big-blue-badge.webp +0 -0
  237. package/dist/components/themes/spaceship/assets/images/bingo.webp +0 -0
  238. package/dist/components/themes/spaceship/assets/images/blue-badge-sunset.png +0 -0
  239. package/dist/components/themes/spaceship/assets/images/blue-badge.png +0 -0
  240. package/dist/components/themes/spaceship/assets/images/blue-wrapper-sunset.png +0 -0
  241. package/dist/components/themes/spaceship/assets/images/blue-wrapper.webp +0 -0
  242. package/dist/components/themes/spaceship/assets/images/board_red.png +0 -0
  243. package/dist/components/themes/spaceship/assets/images/button_feedback_vi.png +0 -0
  244. package/dist/components/themes/spaceship/assets/images/circle-btn-right-sunset.png +0 -0
  245. package/dist/components/themes/spaceship/assets/images/circle-btn-right.png +0 -0
  246. package/dist/components/themes/spaceship/assets/images/circle-btn-sunset.png +0 -0
  247. package/dist/components/themes/spaceship/assets/images/circle-btn.webp +0 -0
  248. package/dist/components/themes/spaceship/assets/images/focus-vector.webp +0 -0
  249. package/dist/components/themes/spaceship/assets/images/head-phone_red.png +0 -0
  250. package/dist/components/themes/spaceship/assets/images/ic-mute-sunset.png +0 -0
  251. package/dist/components/themes/spaceship/assets/images/ic-mute.png +0 -0
  252. package/dist/components/themes/spaceship/assets/images/ic-play-sunset.png +0 -0
  253. package/dist/components/themes/spaceship/assets/images/ic-play-violet.webp +0 -0
  254. package/dist/components/themes/spaceship/assets/images/ic-play.webp +0 -0
  255. package/dist/components/themes/spaceship/assets/images/micro.png +0 -0
  256. package/dist/components/themes/spaceship/assets/images/next-small.webp +0 -0
  257. package/dist/components/themes/spaceship/assets/images/next-sunset.png +0 -0
  258. package/dist/components/themes/spaceship/assets/images/next.webp +0 -0
  259. package/dist/components/themes/spaceship/assets/images/purple-circle.webp +0 -0
  260. package/dist/components/themes/spaceship/assets/images/question-badge-sunset.png +0 -0
  261. package/dist/components/themes/spaceship/assets/images/question-badge.webp +0 -0
  262. package/dist/components/themes/spaceship/assets/images/red-badge-sunset.png +0 -0
  263. package/dist/components/themes/spaceship/assets/images/red-badge.webp +0 -0
  264. package/dist/components/themes/spaceship/assets/images/red-wrapper-sunset.png +0 -0
  265. package/dist/components/themes/spaceship/assets/images/red-wrapper.webp +0 -0
  266. package/dist/components/themes/spaceship/assets/images/robot-avatar.png +0 -0
  267. package/dist/components/themes/spaceship/assets/images/sound_red.png +0 -0
  268. package/dist/components/themes/spaceship/assets/images/student-avatar.png +0 -0
  269. package/dist/components/themes/spaceship/assets/images/teacher-play-sunset.png +0 -0
  270. package/dist/components/themes/spaceship/assets/images/teacher-play.webp +0 -0
  271. package/dist/components/themes/spaceship/assets/images/timer-badge.png +0 -0
  272. package/dist/components/themes/spaceship/assets/styles/SpaceshipLayout.module.css +347 -0
  273. package/dist/components/themes/spaceship/assets/styles/SpaceshipWaitingRoom.module.css +395 -0
  274. package/dist/components/ui/badge.d.ts +1 -1
  275. package/dist/index.d.ts +4 -4
  276. package/dist/index.js +1 -1
  277. package/dist/shared/lib/stores/examTakingStore.d.ts +54 -0
  278. package/dist/shared/lib/stores/examTakingStore.js +1 -0
  279. package/dist/shared/lib/stores/gradingTransientStore.d.ts +23 -0
  280. package/dist/shared/lib/stores/gradingTransientStore.js +1 -0
  281. package/dist/shared/lib/themes/config/starters.config.d.ts +3 -0
  282. package/dist/shared/lib/themes/config/starters.config.js +1 -0
  283. package/dist/shared/lib/themes/index.d.ts +18 -0
  284. package/dist/shared/lib/themes/index.js +1 -0
  285. package/dist/shared/lib/themes/types.d.ts +39 -0
  286. package/dist/shared/lib/themes/types.js +1 -0
  287. package/dist/shared/lib/toast.d.ts +19 -0
  288. package/dist/shared/lib/toast.js +1 -0
  289. package/package.json +10 -2
@@ -0,0 +1,3 @@
1
+ export { StudentContestRoomsPageContainer } from './StudentContestRoomsPageContainer';
2
+ export type { StudentContestRoomsPageContainerProps } from './StudentContestRoomsPageContainer';
3
+ export { canCancelRegistration, canEnterRoom, canRetakeRoom, getCountdownParts, getRoomSortPriority, hasRegistrationStatus, isUserEngaged, needsRegisterAndEnter, needsRegistration, unwrap, } from './contest-rooms.utils';
@@ -0,0 +1 @@
1
+ export{StudentContestRoomsPageContainer}from"./StudentContestRoomsPageContainer";export{canCancelRegistration,canEnterRoom,canRetakeRoom,getCountdownParts,getRoomSortPriority,hasRegistrationStatus,isUserEngaged,needsRegisterAndEnter,needsRegistration,unwrap}from"./contest-rooms.utils";
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { ExamTakingSdkApi } from '../../../api/exam-taking';
3
+ export declare function ExamTakingApiProvider({ api, children }: {
4
+ api: ExamTakingSdkApi;
5
+ children: ReactNode;
6
+ }): import("react").JSX.Element;
7
+ /** Returns the injected API, or `null` when rendered outside a provider. */
8
+ export declare function useExamTakingApiOptional(): ExamTakingSdkApi | null;
9
+ /** Returns the injected API; throws when rendered outside a provider. */
10
+ export declare function useExamTakingApi(): ExamTakingSdkApi;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as r}from"react/jsx-runtime";import{createContext as i,useContext as n}from"react";const e=i(null);export function ExamTakingApiProvider({api:i,children:n}){return r(e.Provider,{value:i,children:n})}export function useExamTakingApiOptional(){return n(e)}export function useExamTakingApi(){const r=n(e);if(!r)throw new Error("useExamTakingApi must be used within an <ExamTakingApiProvider>.");return r}
@@ -1,9 +1,33 @@
1
1
  import type { ExamTakingSdkApi } from '../../../api/exam-taking';
2
2
  export interface ExamTakingPageContainerProps {
3
- examId: string;
3
+ /** Exam room id from the route (`/student/exams/:roomId/take`). */
4
+ roomId: string;
5
+ /** API adapter; create one via `createExamTakingApi`. */
4
6
  api: ExamTakingSdkApi;
5
- exitPath?: string;
7
+ /** Navigation callback; falls back to `window.location.href` when omitted. */
6
8
  onNavigate?: (href: string) => void;
7
- onSubmitted?: (attemptId: string) => void;
9
+ /** Build the results page path from an attemptId. */
10
+ resultPath?: (attemptId: string) => string;
11
+ /** Path to navigate to when loading/close fails (e.g. discover page). */
12
+ fallbackPath?: string;
13
+ /** Enable periodic webcam proctoring snapshots (requires camera permission). */
14
+ proctoringEnabled?: boolean;
15
+ /**
16
+ * Exam title that gates the AI-teacher intro video. The host app previously
17
+ * gated on `NEXT_PUBLIC_ACHIEVERS_EXAM_TITLE`; pass it here so the SDK does
18
+ * not read host env vars. The intro plays only when the loaded exam's title
19
+ * matches this value.
20
+ */
21
+ achieversExamTitle?: string;
22
+ /** Called after a successful submit with the pending grading context. */
23
+ onSubmitted?: (result: {
24
+ attemptId: string;
25
+ pendingAnswerIds: string[];
26
+ }) => void;
8
27
  }
9
- export declare function ExamTakingPageContainer({ examId, api, exitPath, onNavigate, onSubmitted }: ExamTakingPageContainerProps): import("react").JSX.Element;
28
+ /**
29
+ * SDK container for the student exam-taking screen. Wraps the orchestration in an
30
+ * {@link ExamTakingApiProvider} so descendants (e.g. the speaking recorder) can
31
+ * reach the injected API without prop-drilling.
32
+ */
33
+ export declare function ExamTakingPageContainer(props: ExamTakingPageContainerProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useEffect as n,useMemo as i,useState as s}from"react";import{ArrowLeft as a,ArrowRight as r,Loader2 as o,Send as l}from"lucide-react";import{Button as u}from"../../../components/ui/button";import{CambridgeYleExamLayout as c,EnglishCertificationExamLayout as m,SummerSkyLayout as d}from"../../../components/themes";import{useToast as h}from"../../../shared/lib/hooks/useToast";import{GenericQuestionRenderer as p}from"./GenericQuestionRenderer";import{groupQuestions as x,unwrap as g,unwrapAttempt as f}from"./exam-taking.utils";export function ExamTakingPageContainer({examId:t,api:a,exitPath:r="/student/exams",onNavigate:o,onSubmitted:l}){const{error:u,success:p}=h(),[S,E]=s(null),[P,_]=s([]),[M,A]=s(null),[k,Q]=s(0),[T,G]=s({}),[L,j]=s(!0),[R,D]=s(!1);n(()=>{let e=!1;return j(!0),async function(e,t){const n=g(await e.getActiveAttempt(t));return n||f(g(await e.startAttempt(t)))}(a,t).then(async t=>{const n=g(await a.getQuestions(t.id));e||(E(t),A(n),_(x(n)))}).catch(e=>u({message:"Không tải được bài thi",description:e instanceof Error?e.message:void 0})).finally(()=>{e||j(!1)}),()=>{e=!0}},[a,t,u]);const F=P[k],U=i(()=>P.flatMap(e=>e.questions),[P]),K=i(()=>U.findIndex(e=>F?.questions[0]?.id===e.id),[F?.questions,U]),Y=i(()=>Object.values(T).filter(e=>""!==e&&null!=e).length,[T]),B=U.length,O=function(e){return"ENGLISH_CERTIFICATION"===e||"CAMBRIDGE_YLE"===e||"SUMMER_SKY"===e?e:"DEFAULT"}(M?.examTemplate?.theme),H=M?.examTemplate?.title??"Làm bài thi",$=function(e){if(!e)return 0;const t=new Date(e.startedAt).getTime()+6e4*e.durationMinutes;return Math.max(0,Math.floor((t-Date.now())/1e3))}(S),z=e=>{o?o(e):"undefined"!=typeof window&&(window.location.href=e)},J=async()=>{if(S){D(!0);try{await a.submitAttempt(S.id),p({message:"Đã nộp bài"}),l?.(S.id)}catch(e){u({message:"Không nộp được bài",description:e instanceof Error?e.message:void 0})}finally{D(!1)}}};if(L)return e(q,{});if(!S||!F)return e(I,{onExit:()=>z(r)});const V=e(b,{part:F,answers:T,onAnswerChange:async(e,t)=>{G(n=>({...n,[e]:t})),S&&a.saveAnswers&&await a.saveAnswers({attemptId:S.id,answers:[{questionId:e,answer:t}]})}}),W=()=>Q(e=>Math.max(0,e-1)),X=()=>Q(e=>Math.min(P.length-1,e+1)),Z=0===k,ee=k>=P.length-1;return"ENGLISH_CERTIFICATION"===O?e(m,{headerProps:{examName:H,remainingSeconds:$,totalQuestions:B,answeredCount:Y,isSubmitting:R,onSubmit:J,onClose:()=>z(r),lastSavedAt:null,isSaving:!1,partLabel:F.name,questionRange:N(F)},navigationProps:{parts:v(P),questions:(te=U,te.map(e=>({id:e.id,question_type:e.question_type,content:e.content??{},is_example:Boolean(e.is_example),total_points:String(e.total_points??0),part_id:e.part_id??"",part_no:e.part_no??0,question_number:e.question_number}))),answers:T,flaggedQuestions:new Set,currentIndex:Math.max(0,K),onQuestionClick:e=>Q(C(P,e)),onPartClick:Q},footerProps:{onPrevious:W,onNext:X,onClear:()=>{},onToggleMark:()=>{},isPreviousDisabled:Z,isNextDisabled:ee,isMarked:!1},children:V}):"CAMBRIDGE_YLE"===O?e(c,{onPrevious:W,onNext:X,onClose:()=>z(r),isFirstQuestion:Z,isLastQuestion:ee,headerProps:{examName:H,examType:"Exam",totalQuestions:B,answeredCount:Y,remainingSeconds:$,isSubmitting:R,onSubmit:J},sidebarProps:y(P,T,Math.max(0,K),Q),children:V}):"SUMMER_SKY"===O?e(d,{onExit:()=>z(r),partName:F.name,instruction:F.instructions??"",onPrev:W,onNext:X,canGoPrev:!Z,canGoNext:!ee,audioUrl:F.audioUrl??"",questionNumber:k+1,recorder:null,children:V}):e(w,{title:H,answeredCount:Y,totalQuestions:B,onExit:()=>z(r),onPrev:W,onNext:X,isFirst:Z,isLast:ee,currentPart:F,onSubmit:J,isSubmitting:R,children:V});var te}function b({part:t,answers:n,onAnswerChange:i}){return e("div",{className:"space-y-4",children:t.questions.map(t=>e(p,{question:t,value:n[t.id],onChange:i},t.id))})}function w({title:n,answeredCount:i,totalQuestions:s,onExit:c,onPrev:m,onNext:d,isFirst:h,isLast:p,currentPart:x,onSubmit:g,isSubmitting:f,children:b}){return t("div",{className:"min-h-screen bg-slate-50",children:[e("header",{className:"sticky top-0 z-10 border-b bg-white px-4 py-3 shadow-sm",children:t("div",{className:"mx-auto flex max-w-5xl items-center justify-between gap-4",children:[t("div",{children:[e("h1",{className:"font-semibold text-gray-900",children:n}),t("p",{className:"text-sm text-gray-500",children:["Đã trả lời ",i,"/",s]})]}),e(u,{variant:"outline",onClick:c,children:"Thoát"})]})}),t("main",{className:"mx-auto max-w-5xl space-y-4 p-4",children:[t("div",{className:"flex items-center justify-between rounded-lg bg-white p-4 shadow-sm",children:[t(u,{variant:"outline",disabled:h,onClick:m,children:[e(a,{className:"mr-2 h-4 w-4"}),"Phần trước"]}),e("div",{className:"text-center",children:e("h2",{className:"font-medium",children:x.name})}),t(u,{variant:"outline",disabled:p,onClick:d,children:["Phần sau",e(r,{className:"ml-2 h-4 w-4"})]})]}),b,e("div",{className:"flex justify-end",children:t(u,{onClick:g,disabled:f,className:"bg-blue-600 hover:bg-blue-700",children:[f?e(o,{className:"mr-2 h-4 w-4 animate-spin"}):e(l,{className:"mr-2 h-4 w-4"}),"Nộp bài"]})})]})]})}function N(e){const t=e.questions.map(e=>e.question_number).filter(e=>Number.isFinite(e));return 0===t.length?"":`${Math.min(...t)}–${Math.max(...t)}`}function v(e){let t=0;return e.map(e=>{const n=t;return t+=e.questions.length,{id:e.id,name:e.name,category:e.template?.category,startIndex:n,endIndex:t-1,questionCount:e.questions.length,audioUrl:e.audioUrl,isGroup:e.isGroup}})}function C(e,t){let n=0;for(let i=0;i<e.length;i+=1)if(n+=e[i].questions.length,t<n)return i;return 0}function y(e,t,n,i){const s=e.flatMap((n,i)=>n.questions.map((n,s)=>({globalIndex:e.slice(0,i).reduce((e,t)=>e+t.questions.length,0)+s,partIndex:i,questionNumber:n.question_number,isAnswered:void 0!==t[n.id]&&""!==t[n.id]})));return{parts:e.map((e,n)=>({partIndex:n,partNo:e.partNo??n+1,name:e.name,category:e.template?.category,totalQuestions:e.questions.length,answeredCount:e.questions.filter(e=>void 0!==t[e.id]&&""!==t[e.id]).length})),questions:s,currentQuestionGlobalIndex:n,onPartClick:i,onQuestionClick:t=>i(C(e,t))}}function q(){return e("div",{className:"flex h-screen items-center justify-center",children:e(o,{className:"h-8 w-8 animate-spin text-blue-600"})})}function I({onExit:n}){return t("div",{className:"flex h-screen flex-col items-center justify-center gap-4",children:[e("p",{children:"Không có câu hỏi."}),e(u,{onClick:n,children:"Quay lại"})]})}
1
+ "use client";import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import{useEffect as i,useRef as s,useState as r,useMemo as a,useCallback as o}from"react";import d from"next/image";import l from"../../../components/themes/summer-sky/assets/images/clock.png";import m from"../../../components/themes/summer-sky/assets/images/submit.png";import c from"../../../components/themes/summer-sky/assets/images/has_answered.png";import{toast as p}from"sonner";import{Loader2 as u}from"lucide-react";import{t as g}from"../../../shared/lib/i18n";import{transformAnswersForSubmission as h}from"./utils/answer-transformers";import{getThemeForLevel as x,normalizeExamTheme as b}from"../../../shared/lib/themes";import{useExamTakingStore as I}from"../../../shared/lib/stores/examTakingStore";import{useGradingTransientStore as f}from"../../../shared/lib/stores/gradingTransientStore";import{AlertDialog as w,AlertDialogAction as S,AlertDialogCancel as E,AlertDialogContent as y,AlertDialogDescription as _,AlertDialogFooter as v,AlertDialogHeader as N,AlertDialogTitle as A}from"../../../components/ui/alert-dialog";import{useExamTimer as C}from"./hooks/useExamTimer";import{useAutoSave as T}from"./hooks/useAutoSave";import{useProctoringCamera as k}from"./hooks/useProctoringCamera";import{getStandardExamTheme as P}from"../../../components/themes";import{QuestionRenderer as q}from"./components/QuestionRenderer";import{FullscreenLoading as M}from"../entry/fullscreen-loading";import{SummerSkySubmitModal as R}from"../../../components/themes/summer-sky/SummerSkySubmitModal";import{EnglishCertificationExamLayout as L,EnglishCertificationQuestionRenderer as G,englishCertQuestionDomId as D}from"../../../components/themes/english-certification";import{groupQuestionsByPart as Q}from"./utils/question-transformers";import{unwrap as B,unwrapAttempt as O}from"./exam-taking.utils";import{ExamTakingApiProvider as F}from"./ExamTakingApiContext";function Y({roomId:F,api:Y,onNavigate:K,resultPath:U=e=>`/student/results/${e}`,fallbackPath:V="/student/contests/discover",proctoringEnabled:$=!1,achieversExamTitle:H,onSubmitted:j}){const z=I(),W=s(!1),J=o(e=>{K?K(e):"undefined"!=typeof window&&(window.location.href=e)},[K]),{isCameraActive:X}=k({api:Y,attemptId:z.attemptId,intervalMs:1e4,enabled:$}),[Z,ee]=r(!0),te=z.currentPartIndex,ne=z.currentQuestionGlobalIndex,ie=o(e=>{const t=I.getState().currentPartIndex,n="function"==typeof e?e(t):e;I.getState().setCurrentPartIndex(n)},[]),se=o(e=>{const t=I.getState().currentQuestionGlobalIndex,n="function"==typeof e?e(t):e;I.getState().setCurrentQuestionGlobalIndex(n)},[]),[re,ae]=r([]),[oe,de]=r("SUMMER_SKY"),[le,me]=r(""),[ce,pe]=r(!1),[ue,ge]=r(null),[he,xe]=r(""),be=o(e=>{I.getState().markIntroPlayed(e)},[]),Ie="TOEIC"===z.examType||"ENGLISH_CERTIFICATION"===le,fe=a(()=>{if(!Ie||0===z.parts.length)return te;const e=z.currentIndex;for(let t=0;t<z.parts.length;t++){const n=z.parts[t],i=n.startIndex??0,s=n.endIndex??i;if(e>=i&&e<=s)return t}return 0},[Ie,z.currentIndex,z.parts,te]);i(()=>{(async()=>{try{ee(!0);let e=B(await Y.getActiveAttempt(F));e||(e=O(B(await Y.startAttempt(F))));let t=null;try{t=Y.getRoom?B(await Y.getRoom(F)):null,t&&ge(t)}catch{}const{examTemplate:n,questions:i}=B(await Y.getQuestions(e.id));n?.title&&xe(n.title);const s=n?.parts??e.exam?.template?.parts,r=Q(i,s),a=n?.subTitle??null,o=(r.every(e=>e.questions.every(e=>"SPEAKING"===e.question_skill_type)),r.some(e=>"SPEAKING"===e.category||e.questions.every(e=>"SPEAKING"===e.question_skill_type)));ae(r);const d=n?.theme||e?.exam?.template?.theme||e?.exam?.theme||t?.exam?.template?.theme||t?.exam?.theme||"",l=b(d);if(o){const e=["SPACESHIP","SUMMER_SKY"].includes(d);de(e?d:"SUMMER_SKY")}const m=new Date(e.startedAt),c=60*e.durationMinutes*1e3,u=m.getTime()+c,h=Date.now();if(0===Math.max(0,u-h)){p.info(g("student.exam.take.timeExpired"));try{await Y.submitAttempt(e.id)}catch{}return I.persist.clearStorage(),void J(U(e.id))}z.hydrateFromServer({attemptId:e.id,examRoomId:F,questions:i.map(e=>({id:e.id,question_type:e.question_type,content:e.content,is_example:e.is_example,total_points:e.total_points,part_id:e.part_id,part_no:e.part_no,question_number:e.question_number})),durationMinutes:e.durationMinutes,startedAt:e.startedAt,examType:a??void 0,examTitle:n?.title??void 0,parts:s}),a&&z.setExamType(a),me(l),s&&z.setParts(s),ee(!1)}catch(e){console.error("Failed to load exam data:",e),p.error(g("student.exam.take.loadError")),J(V)}})()},[F]);const we=a(()=>re.length>0&&re.every(e=>e.questions.every(e=>"SPEAKING"===e.question_skill_type)),[re]),Se=a(()=>{const e=re[te];return!!e&&(("SPEAKING_DESCRIBE_IMAGE"!==e.questionType&&"SPONTANEOUS_QA"!==e.questionType&&"SPEAKING_CUE_CARD"!==e.questionType||"CAMBRIDGE_YLE"!==le)&&("SPEAKING"===e.category||e.questions.every(e=>"SPEAKING"===e.question_skill_type)))},[re,te,le]),{remainingSeconds:Ee,warningLevel:ye}=C({onTimeExpired:async()=>{p.info(g("student.exam.take.autoSubmit")),await Ae()},onWarningThreshold:we||Ie?void 0:()=>{p.warning(g("student.exam.take.timeWarning"))},warningThresholdSeconds:we||Ie?void 0:300,warningThresholds:Ie?[{seconds:900,level:"warning",callback:()=>p.warning("Còn 15 phút!",{duration:3e3})},{seconds:300,level:"critical",callback:()=>p.warning("Còn 5 phút! Hãy nộp bài ngay!",{duration:5e3})}]:we?[{seconds:300,level:"warning",callback:()=>p.warning("Còn 5 phút! Hãy hoàn thành bài thi.",{duration:5e3})},{seconds:120,level:"critical",callback:()=>p.warning("Còn 2 phút! Bài thi sẽ được tự động nộp.",{duration:5e3})}]:void 0}),_e=T({api:Y,attemptId:z.attemptId||"",parts:re,intervalMs:Ie?15e3:3e4,onSaveError:e=>{console.error("Save error:",e)}}),ve=s(_e.saveNow),Ne=s(re);i(()=>{ve.current=_e.saveNow,Ne.current=re}),i(()=>{const e=()=>{const e=I.getState();if(!e.attemptId||!e.isDirty||e.isSubmitting)return;const t=h(e.answers,Ne.current);if(0!==t.length)try{Y.saveAnswers?.({attemptId:e.attemptId,answers:t,keepalive:!0})}catch{}},t=()=>{"hidden"===document.visibilityState&&e()},n=()=>{const e=I.getState();e.isDirty&&!e.isSubmitting&&ve.current()};return document.addEventListener("visibilitychange",t),window.addEventListener("pagehide",e),window.addEventListener("online",n),()=>{document.removeEventListener("visibilitychange",t),window.removeEventListener("pagehide",e),window.removeEventListener("online",n)}},[]),i(()=>{we||ve.current()},[z.currentIndex,te,ne,we]);const Ae=async()=>{if(!W.current){W.current=!0,z.setIsSubmitting(!0),pe(!1);try{z.isDirty&&await _e.saveNow();const e=B(await Y.submitAttempt(z.attemptId)),t=e?.pendingAnswerIds??[];z.attemptId&&(f.getState().setPending(z.attemptId,t),j?.({attemptId:z.attemptId,pendingAnswerIds:t})),0===t.length?p.success(g("student.exam.take.submitSuccess")):p.success(g("student.exam.take.submittedAIGradingInProgress")),I.persist.clearStorage(),J(U(z.attemptId))}catch(e){console.error("Failed to submit exam:",e);const t=e?.response?.data?.errorCode;if("ATTEMPT_ALREADY_SUBMITTED"===t)return I.persist.clearStorage(),void J(U(z.attemptId));p.warning(g("student.exam.take.submitError")),W.current=!1,z.setIsSubmitting(!1)}}},Ce=o(()=>{pe(!0)},[]),Te=s(new Map),ke=s([]),Pe=o((e,t)=>{z.setAnswer(e,t);const n=Te.current.get(e)||e,i=ke.current.findIndex(e=>e.questionId===n);-1!==i&&se(e=>e!==i?i:e)},[]),qe=s("forward"),Me=e=>{if("CAMBRIDGE_YLE"!==le)return!1;const t=re[e];return"SPEAKING_DESCRIBE_IMAGE"===t?.questionType||"SPONTANEOUS_QA"===t?.questionType||"SPEAKING_CUE_CARD"===t?.questionType},Re=()=>{const e=()=>{window.scrollTo({top:0,behavior:"smooth"});const e=document.getElementById("exam-main-scroll-area");if(e){e.scrollTo({top:0,behavior:"smooth"});e.querySelectorAll(".overflow-y-auto").forEach(e=>{e.scrollTo({top:0,behavior:"smooth"})})}};requestAnimationFrame(e),setTimeout(e,100),setTimeout(e,250)},Le=()=>{if("ENGLISH_CERTIFICATION"===le){const e=z.parts[fe+1];e&&z.goToQuestion(e.startIndex??0)}else if(Ie)z.goToQuestion(Math.min(z.currentIndex+1,z.questions.length-1));else if("CAMBRIDGE_YLE"===le&&Me(te)){const e=ne+1,t=Ve[e];t&&(t.partIndex!==te&&(qe.current="forward",ie(t.partIndex)),se(e))}else qe.current="forward",ie(e=>{const t=Math.min(e+1,re.length-1);if("CAMBRIDGE_YLE"===le){const e=Ve.find(e=>e.partIndex===t);e&&se(e.globalIndex)}return t});Re()},Ge=()=>{if("ENGLISH_CERTIFICATION"===le){const e=z.parts[fe-1];e&&z.goToQuestion(e.startIndex??0)}else if(Ie)z.goToQuestion(Math.max(z.currentIndex-1,0));else if("CAMBRIDGE_YLE"===le&&Me(te)){const e=ne-1,t=Ve[e];t&&(t.partIndex!==te&&(qe.current="backward",ie(t.partIndex)),se(e))}else qe.current="backward",ie(e=>{const t=Math.max(e-1,0);if("CAMBRIDGE_YLE"===le){const e=Ve.find(e=>e.partIndex===t);e&&se(e.globalIndex)}return t});Re()},De=()=>{J(V)},Qe=a(()=>re.reduce((e,t)=>e+("CAMBRIDGE_YLE"===le?t.questions.length:t.questions.filter(e=>!e.is_example).length),0),[re,le]),Be=a(()=>{const e=new Map;return re.forEach(t=>{t.questions.forEach(n=>{if(n.is_example)return;const i=n.content;if("FILL_MISSING_WORDS_IN_GRID"===t.questionType&&i?.grid&&i.grid.forEach((t,i)=>{t.forEach((t,s)=>{e.set(`${i}-${s}`,n.id)})}),"LABEL_THE_PICTURE"===t.questionType&&i?.labels&&i.labels.forEach(t=>{t.id&&e.set(t.id,n.id)}),"READ_AND_COLOR_OBJECTS"===t.questionType){const t=i?.regions||i?.regionNodes;t?.forEach(t=>{t.id&&e.set(t.id,n.id)})}if("IMAGE_OBJECT_MATCHING"===t.questionType){const t=i?.regions||i?.regionNodes;t?.forEach(t=>{t.id&&e.set(t.id,n.id)})}if("LOOK_PICTURE_FILL_WORD_HINT"===t.questionType){const t=i?.word;if(t&&"string"==typeof t){const i=/\{(\d+)\}/g;let s;for(;null!==(s=i.exec(t));){const t=s[1];e.set(`${n.id}-blank-${t}`,n.id)}}}})}),e},[re]);i(()=>{Te.current=Be},[Be]);const Oe=a(()=>{if(!z.answers)return new Set;const e=new Set(re.flatMap(e=>e.questions.filter(e=>!e.is_example).map(e=>e.id))),t=new Set;return Object.keys(z.answers).forEach(n=>{const i=z.answers[n];if(void 0===i||""===i)return;if(e.has(n))return void t.add(n);const s=Be.get(n);s&&e.has(s)&&t.add(s)}),t},[z.answers,re,Be]),Fe=Oe.size+("CAMBRIDGE_YLE"===le?re.reduce((e,t)=>e+t.questions.filter(e=>e.is_example).length,0):0),Ye=a(()=>ue?.exam?.name||ue?.name||(Ie?"TOEIC Listening and Reading Test":"Bài thi"),[ue,Ie]),Ke=a(()=>x(ue?.exam?.level).displayName,[ue?.exam?.level]),{sidebarParts:Ue,sidebarQuestions:Ve}=a(()=>{const e=[],t=[];let n=0;return re.forEach((i,s)=>{const r="CAMBRIDGE_YLE"===le?i.questions:i.questions.filter(e=>!e.is_example);let a=0;r.forEach(e=>{const r=!("CAMBRIDGE_YLE"!==le||!e.is_example)||Oe.has(e.id);r&&a++;const o=i.questions.findIndex(t=>t.id===e.id);t.push({globalIndex:n,partIndex:s,indexInPart:o,questionNumber:e.question_number,isAnswered:r,questionId:e.id,isExample:e.is_example}),n++}),e.push({partIndex:s,partNo:i.partNo,name:i.name,category:i.category,totalQuestions:"CAMBRIDGE_YLE"===le?i.questions.length:i.questions.filter(e=>!e.is_example).length,answeredCount:a})}),{sidebarParts:e,sidebarQuestions:t}},[re,Oe,le]);if(i(()=>{ke.current=Ve},[Ve]),Z)return e(M,{});const $e=te,He=re[$e];if(!He)return e("div",{className:"flex min-h-screen items-center justify-center",children:t("div",{className:"text-center",children:[e("p",{className:"text-lg font-semibold text-red-500",children:"Không tìm thấy câu hỏi"}),e("button",{type:"button",onClick:()=>J(V),className:"mt-4 rounded-lg bg-blue-500 px-4 py-2 text-white hover:bg-blue-600",children:"Quay lại"})]})});if(Se)return t(n,{children:[e(q,{part:He,answers:z.answers||{},onAnswerChange:Pe,isReviewMode:!1,onExit:De,onPartComplete:$e<re.length-1?Le:Ce,onPartBack:$e>0?Ge:void 0,speakingTheme:oe,initialQuestionIndex:"backward"===qe.current?He.questions.length-1:0,skipTeacherVideo:z.playedIntroParts.has($e)||he!==H,onTeacherIntroPlayed:()=>be($e)},`${He.partId}-${$e}`),"SUMMER_SKY"===oe?ce&&e(R,{onClose:()=>pe(!1),onSubmit:Ae,isSubmitting:z.isSubmitting}):e(w,{open:ce,onOpenChange:pe,children:t(y,{children:[t(N,{children:[e(A,{children:"Nộp bài thi"}),e(_,{children:"Bạn có chắc chắn muốn nộp bài không? Sau khi nộp, bạn sẽ không thể thay đổi câu trả lời."})]}),t(v,{children:[e(E,{disabled:z.isSubmitting,children:"Quay lại"}),e(S,{onClick:Ae,disabled:z.isSubmitting,children:z.isSubmitting?t(n,{children:[e(u,{className:"mr-2 h-4 w-4 animate-spin"}),"Đang nộp..."]}):"Nộp bài"})]})]})}),t("div",{className:"fixed top-8 right-6 z-[100] flex flex-col items-end gap-4 sm:gap-6 lg:top-10 lg:right-16",children:[t("div",{className:"flex items-center gap-4 sm:gap-6",children:[Ee>0&&t("div",{className:"flex items-center w-[130px] sm:w-[170px] h-[40px] sm:h-[50px] rounded-[33.5px] backdrop-blur-[8px] transition-all duration-300 ease-in-out border-none shadow-[0_4px_20px_rgba(0,0,0,0.25)] "+("critical"===ye?"bg-[rgba(220,38,38,0.85)] shadow-[0_0_24px_rgba(220,38,38,0.5)] animate-pulse":"warning"===ye?"bg-[rgba(180,120,0,0.85)]":"bg-[#001590]"),children:[e(d,{src:l,alt:"clock",width:75,height:75,className:"w-[50px] h-[50px] sm:w-[75px] sm:h-[75px] -ml-[5px] sm:-ml-[10px] -mt-[10px] sm:-mt-[15px] shrink-0 drop-shadow-[0_2px_6px_rgba(0,0,0,0.2)] pointer-events-none z-10"}),t("span",{className:"flex-1 text-center font-bold text-[18px] sm:text-[25px] leading-none tracking-[-0.03em] uppercase text-white pr-[10px] sm:pr-[16px]",style:{fontFamily:"'SVN-Volte Rounded', 'Quicksand', sans-serif",textShadow:"0 2px 4px rgba(0, 0, 0, 0.2)"},children:[Math.floor(Ee/60).toString().padStart(2,"0"),":",(Ee%60).toString().padStart(2,"0")]})]}),t("div",{className:"flex items-center w-[130px] sm:w-[170px] h-[40px] sm:h-[50px] rounded-[33.5px] bg-[#FF9900] shadow-[0_4px_20px_rgba(0,0,0,0.25)] border-none shrink-0",title:"Số câu hỏi đã hoàn thành",children:[e(d,{src:c,alt:"Progress",width:75,height:75,className:"w-[50px] h-[50px] sm:w-[75px] sm:h-[75px] -ml-[5px] sm:-ml-[10px] -mt-[10px] sm:-mt-[15px] shrink-0 drop-shadow-[0_2px_6px_rgba(0,0,0,0.2)] pointer-events-none z-10"}),t("span",{className:"flex-1 text-center font-bold text-[18px] sm:text-[25px] leading-none tracking-[-0.03em] uppercase text-white pr-[10px] sm:pr-[16px]",style:{fontFamily:'"SVN-Volte Rounded", "Quicksand", sans-serif',textShadow:"0 2px 4px rgba(0,0,0,0.2)"},children:[Fe,"/",Qe]})]})]}),t("button",{onClick:Ce,disabled:z.isSubmitting,className:"group cursor-pointer flex items-center h-[40px] sm:h-[50px] w-[130px] sm:w-[170px] rounded-[33.5px] shadow-[0_4px_20px_rgba(0,0,0,0.25)] transition-all duration-300 hover:scale-105 active:scale-95 disabled:pointer-events-none disabled:opacity-60 border-none "+(z.isSubmitting?"bg-slate-400":"bg-[#16CA3B] hover:bg-[#15b736]"),children:[e(d,{src:m,alt:"Submit",width:75,height:75,className:"w-[50px] h-[50px] sm:w-[75px] sm:h-[75px] -ml-[5px] sm:-ml-[10px] -mt-[10px] sm:-mt-[15px] shrink-0 drop-shadow-[0_2px_6px_rgba(0,0,0,0.2)] pointer-events-none transition-transform duration-300 group-hover:scale-110 z-10"}),z.isSubmitting?e("div",{className:"flex-1 flex justify-center pr-[10px] sm:pr-[16px]",children:e(u,{className:"h-6 w-6 animate-spin text-white"})}):e("span",{className:"flex-1 text-center font-bold text-[18px] sm:text-[25px] leading-none tracking-[-0.03em] uppercase text-white pr-[10px] sm:pr-[16px]",style:{fontFamily:'"SVN-Volte Rounded", "Quicksand", sans-serif',textShadow:"0 2px 4px rgba(0,0,0,0.2)"},children:"Nộp bài"})]})]}),z.isSubmitting&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm",children:t("div",{className:"rounded-xl bg-white p-8 text-center shadow-2xl",children:[e(u,{className:"mx-auto h-12 w-12 animate-spin text-green-500"}),e("p",{className:"mt-4 text-lg font-semibold text-gray-700",children:"Đang nộp bài..."}),e("p",{className:"mt-2 text-sm text-gray-500",children:"Vui lòng đợi trong giây lát"})]})})]});if(Ie){const i=re[fe],s=z.parts[fe],r=s?Math.max(0,z.currentIndex-(s.startIndex??0)):0,a=(s?.startIndex??0)+1,o=(s?.endIndex??a-1)+1,d={examName:Ye,remainingSeconds:z.remainingSeconds,totalQuestions:Qe,answeredCount:Fe,isSubmitting:z.isSubmitting,onSubmit:Ae,onClose:De,lastSavedAt:z.lastSavedAt,isSaving:_e.isSaving,partLabel:(s?.name||i?.name||"").toUpperCase()||void 0,partSubLabel:s?.category||void 0,questionRange:`${a}–${o}`},l=i?.questions?.[r],m="ENGLISH_CERTIFICATION"===le,c={onPrevious:Ge,onClear:m?void 0:()=>{l&&Pe(l.id,{optionId:null})},onToggleMark:m?void 0:()=>{l&&z.toggleFlag(l.id)},onNext:Le,isMarked:!!l&&z.flaggedQuestions.has(l.id),showSecondaryActions:!m,isPreviousDisabled:m?fe<=0:z.currentIndex<=0,isNextDisabled:m?fe>=z.parts.length-1:z.currentIndex>=z.questions.length-1},p={parts:z.parts,questions:z.questions,answers:z.answers,flaggedQuestions:z.flaggedQuestions,currentIndex:z.currentIndex,onQuestionClick:e=>{z.goToQuestion(e);const t=z.questions[e];t&&setTimeout(()=>{document.getElementById(D(t.id))?.scrollIntoView({behavior:"smooth",block:"start"})},80)},onPartClick:e=>{const t=z.parts[e];t&&(z.goToQuestion(t.startIndex??0),z.setCurrentPartIndex(e))}};if(i&&s)return t(n,{children:[e(L,{headerProps:d,navigationProps:p,footerProps:c,children:e(G,{part:i,partConfig:s,currentQuestionIndex:r,answers:z.answers,flaggedQuestions:z.flaggedQuestions,onAnswerChange:Pe,onToggleFlag:e=>z.toggleFlag(e),isReviewMode:!1,isAudioPlayed:z.playedListeningAudioParts.has(i.partId),onAudioFirstPlay:()=>z.markListeningAudioPlayed(i.partId)})}),z.isSubmitting&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",children:t("div",{className:"rounded-xl bg-white p-8 text-center shadow-2xl",children:[e(u,{className:"mx-auto h-12 w-12 animate-spin text-green-500"}),e("p",{className:"mt-4 text-lg font-semibold text-gray-700",children:"Đang nộp bài..."}),e("p",{className:"mt-2 text-sm text-gray-500",children:"Vui lòng đợi trong giây lát"})]})})]})}return t(n,{children:[(()=>{const{Layout:n,QuestionCard:i}=P(le),s={headerProps:{examName:Ye,examType:"EXAM",levelLabel:Ke,totalQuestions:Qe,answeredCount:Fe,remainingSeconds:z.remainingSeconds,isSubmitting:z.isSubmitting,isCameraActive:X,onSubmit:Ce},onPrevious:Ge,onNext:Le,onClose:De,isNavDisabled:z.isNavDisabled,partName:He?.name||(He?.partNo?`PART ${He.partNo}`:void 0)};if("CAMBRIDGE_YLE"===le){const e=Me($e);s.isFirstQuestion=e?0===ne:0===$e,s.isLastQuestion=e?ne===Ve.length-1:$e===re.length-1,s.sidebarProps={parts:Ue,questions:Ve,currentQuestionGlobalIndex:ne,isNavDisabled:z.isNavDisabled,onPartClick:e=>{if(z.isNavDisabled)return;qe.current=e>$e?"forward":"backward",ie(e);const t=Ve.find(t=>t.partIndex===e);t&&se(t.globalIndex),Re()},onQuestionClick:e=>{if(z.isNavDisabled)return;const t=Ve[e];t&&t.partIndex!==$e&&(qe.current=t.partIndex>$e?"forward":"backward",ie(t.partIndex)),se(e),t&&setTimeout(()=>{const e=document.getElementById(`question-${t.questionId}`);e&&e.scrollIntoView({behavior:"smooth",block:"center"})},100)}}}else s.isFirstQuestion=0===$e,s.isLastQuestion=$e===re.length-1;const r="CAMBRIDGE_YLE"===le&&("SPEAKING_DESCRIBE_IMAGE"===He?.questionType||"SPONTANEOUS_QA"===He?.questionType||"SPEAKING_CUE_CARD"===He?.questionType),a=Ve[ne],o=r&&a?.partIndex===$e?a.indexInPart:void 0;return t(n,{...s,children:[e(i,{partName:He?.name||(He?.partNo?`PART ${He.partNo}`:void 0),children:e(q,{part:He,answers:z.answers||{},onAnswerChange:Pe,isReviewMode:!1,currentQuestionIndex:o,onExit:De,onPartComplete:$e<re.length-1?Le:Ce,onPartBack:$e>0?Ge:void 0,speakingTheme:"CAMBRIDGE_YLE"===le?"CAMBRIDGE_YLE":oe,initialQuestionIndex:"backward"===qe.current?He?.questions.length-1:0,skipTeacherVideo:z.playedIntroParts.has($e)||he!==H,onTeacherIntroPlayed:()=>be($e)})}),z.isSubmitting&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",children:t("div",{className:"rounded-xl bg-white p-8 text-center shadow-2xl",children:[e(u,{className:"mx-auto h-12 w-12 animate-spin text-green-500"}),e("p",{className:"mt-4 text-lg font-semibold text-gray-700",children:"Đang nộp bài..."}),e("p",{className:"mt-2 text-sm text-gray-500",children:"Vui lòng đợi trong giây lát"})]})})]})})(),"CAMBRIDGE_YLE"===le?ce&&e(R,{onClose:()=>pe(!1),onSubmit:Ae,isSubmitting:z.isSubmitting}):e(w,{open:ce,onOpenChange:pe,children:t(y,{children:[t(N,{children:[e(A,{children:"Nộp bài thi"}),e(_,{children:"Bạn có chắc chắn muốn nộp bài không? Sau khi nộp, bạn sẽ không thể thay đổi câu trả lời."})]}),t(v,{children:[e(E,{disabled:z.isSubmitting,children:"Quay lại"}),e(S,{onClick:Ae,disabled:z.isSubmitting,children:z.isSubmitting?t(n,{children:[e(u,{className:"mr-2 h-4 w-4 animate-spin"}),"Đang nộp..."]}):"Nộp bài"})]})]})})]})}export function ExamTakingPageContainer(t){return e(F,{api:t.api,children:e(Y,{...t})})}
@@ -0,0 +1,25 @@
1
+ import { type QuestionPart } from '../utils/question-transformers';
2
+ interface QuestionRendererProps {
3
+ part: QuestionPart;
4
+ answers: Record<string, any>;
5
+ onAnswerChange: (questionId: string, value: any) => void;
6
+ isReviewMode?: boolean;
7
+ /** Override the exit/close action for speaking renderers. Defaults to router.back(). */
8
+ onExit?: () => void;
9
+ /** Called when the last question of this part is navigated past (speaking exams only). */
10
+ onPartComplete?: () => void;
11
+ /** Called when the first question of this part is navigated back from (speaking exams only). */
12
+ onPartBack?: () => void;
13
+ /** Speaking theme string. */
14
+ speakingTheme?: string;
15
+ /** Initial question index within the part (useful when navigating backward). */
16
+ initialQuestionIndex?: number;
17
+ /** Skip teacher intro video (already played for this part). */
18
+ skipTeacherVideo?: boolean;
19
+ /** Callback when teacher intro video finishes playing. */
20
+ onTeacherIntroPlayed?: () => void;
21
+ /** Index of the question to render within the part (for Cambridge YLE 1-by-1 navigation) */
22
+ currentQuestionIndex?: number;
23
+ }
24
+ export declare function QuestionRenderer({ part, answers, onAnswerChange, isReviewMode, onExit, onPartComplete, onPartBack, speakingTheme, initialQuestionIndex, skipTeacherVideo, onTeacherIntroPlayed, currentQuestionIndex, }: QuestionRendererProps): import("react").JSX.Element;
25
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as n}from"react/jsx-runtime";import{MoversListenAndWriteRenderer as t,MoversChooseBestAnswerRenderer as s,MoversChooseAdjectiveRenderer as i,MoversWritingRenderer as r,MoversColoringRenderer as o,MoversPictureChooseRenderer as a,MoversPictureFillBlankChooseRenderer as u,MoversReadingPassageRenderer as c,MoversLabelThePictureRenderer as m,MoversFillWordHintRenderer as l,MoversGridFillRenderer as g,MoversTrueFalseRenderer as p,MoversAnswerTheQuestionRenderer as _,MoversWriteSentencesRenderer as N,MoversWordOrderingRenderer as E,MoversWordFillParagraphRenderer as d,MoversMatchByWritingAnswerRenderer as C,MoversWordFillStructuredFormRenderer as A}from"./question-renderers";import{SpeakingQuestionRenderer as I}from"./speaking/renderers";import{transformFillInBlank as w,transformWriteCorrectVerbForm as R,transformChooseCorrectAnswer as T,transformChooseCorrectAdjective as h,transformWriteShortLetter as S,transformColorObjects as O,transformPictureChoose as U,transformPictureFillBlankChoose as q,transformReadingPassage as M,transformLabelPicture as b,transformFillWordHint as L,transformGridFill as x,transformAnswerTheQuestion as v,transformTrueFalse as D,transformWordOrdering as f,transformWordFillParagraph as P,transformMatchByWritingAnswer as W,transformWriteSentences as G,transformWordFillStructuredForm as H}from"../utils/question-transformers";import{normalizeColoringAssignments as B}from"../utils/coloring-assignments";export function QuestionRenderer({part:K,answers:Q,onAnswerChange:F,isReviewMode:k=!1,onExit:j,onPartComplete:y,onPartBack:V,speakingTheme:J,initialQuestionIndex:Y,skipTeacherVideo:X,onTeacherIntroPlayed:z,currentQuestionIndex:Z}){const{partNo:$,questionType:ee,questions:ne}=K,te=ne.filter(e=>!e.is_example).length,se=e=>{if(void 0!==Z&&Z>=0){if(e.length>0&&"isExample"in e[0]){const n=e.filter(e=>e.isExample),t=e.filter(e=>!e.isExample);if(Z<t.length)return 0===Z&&n.length>0?[...n,t[Z]]:[t[Z]]}else if(Z<e.length)return[e[Z]]}return e};switch(ee){case"FILL_IN_BLANK":{const n=w(ne);return e(t,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,title:n.title,imageUrl:n.groupImageUrl||n.imageUrl,audioUrl:n.audioUrl||K.audioUrl,exampleText:n.exampleText,exampleHighlight:n.exampleHighlight,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k,showHints:n.showHints,groupContent:n.groupContent,groupTitle:n.groupTitle})}case"WRITE_CORRECT_VERB_FORM":{const n=R(ne);return e(t,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,title:n.title,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"CHOOSE_THE_CORRECT_ANSWER":{const n=T(ne);return e(s,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,imageUrl:n.groupImageUrl,groupTitle:n.groupTitle,groupContent:n.groupContent,articles:n.articles,audioUrl:n.audioUrl||K.audioUrl,example:n.example,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"CHOOSE_CORRECT_ADJECTIVE":{const n=h(ne);return e(i,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"WRITE_A_SHORT_LETTER":{const n=ne[0],t=S(n),s=Q[n.id]||"";return e(r,{partNumber:$,partName:K.name,instruction:K.instructions,prompt:t.prompt,requirements:t.requirements,minWords:t.minWords,maxWords:t.maxWords,answer:s,onAnswerChange:e=>F(n.id,e),isReviewMode:k,guideImages:t.guideImages})}case"READ_AND_COLOR_OBJECTS":{const n=O(ne),t=new Set(n.regions.map(e=>e.id)),s=Object.fromEntries(Object.entries(Q).filter(([e])=>t.has(e))),i=B(s,n.hintItems);return e(o,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,instructions:n.instructions,imageUrl:n.imageUrl,audioUrl:n.audioUrl||K.audioUrl,hintItems:n.hintItems,regions:n.regions,assignments:i,onAssignmentChange:(e,t)=>{if(t){const s=n.hintItems.find(e=>e.id===t);if(s&&s.color)return void F(e,s.color)}F(e,t)},isReviewMode:k})}case"LOOK_PICTURE_CHOOSE_CORRECT_ANSWER":{const n=U(ne);return e(a,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,subQuestions:n.subQuestions,answers:Q,onAnswerChange:F,isReviewMode:k})}case"LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER":{const n=q(ne);return e(u,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,subQuestions:n.subQuestions,answers:Q,onAnswerChange:F,isReviewMode:k})}case"READ_PASSAGE_AND_ANSWER_QUESTIONS":{const n=M(ne);return e(c,{partNumber:$,partName:K.name,questionCount:n.questions.length,instruction:K.instructions||n.instruction,passageTitle:n.passageTitle,passage:n.passage,passageImageUrl:n.passageImageUrl,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"LABEL_THE_PICTURE":{const n=b(ne);return e(m,{partNumber:$,partName:K.name,questionCount:n.labels.length,instruction:K.instructions||n.instruction,imageUrl:n.imageUrl,wordBank:n.wordBank,labels:n.labels,answers:Q,onAnswerChange:F,isReviewMode:k})}case"LOOK_PICTURE_FILL_WORD_HINT":{const n=L(ne);return e(l,{partNumber:$,partName:K.name,questionCount:n.subQuestions.length,instruction:K.instructions||n.instruction,hintLetters:n.hintLetters,subQuestions:n.subQuestions,answers:Q,onAnswerChange:F,isReviewMode:k})}case"FILL_MISSING_WORDS_IN_GRID":{const n=x(ne);return e(g,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,grid:n.grid,rows:n.rows,columns:n.columns,cellAnswers:{},answers:Q,onAnswerChange:F,isReviewMode:k,disabledCells:n.disabledCells})}case"IMAGE_OBJECT_MATCHING":{const n=O(ne),t=new Set(n.regions.map(e=>e.id)),s=Object.fromEntries(Object.entries(Q).filter(([e])=>t.has(e))),i=B(s,n.hintItems);return e(o,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,instructions:n.instructions,imageUrl:n.imageUrl,audioUrl:n.audioUrl||K.audioUrl,hintItems:n.hintItems,regions:n.regions,assignments:i,onAssignmentChange:(e,t)=>{if(t){const s=n.hintItems.find(e=>e.id===t);if(s&&s.color)return void F(e,s.color)}F(e,t)},isReviewMode:k})}case"ANSWER_THE_QUESTION":{const n=v(ne);return e(_,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,imageUrl:n.imageUrl,audioUrl:K.audioUrl,title:n.title,groupContent:n.groupContent,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"TRUE_FALSE":{const n=D(ne);return e(p,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,imageUrl:n.imageUrl,groupContent:n.groupContent,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"WORD_ORDERING":{const n=f(ne);return e(E,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"WORD_FILL_PARAGRAPH":{const n=P(ne),t=n.wordBank.filter(e=>e.isExample).length,s=n.paragraph.match(/\{\d+\}/g),i=s?s.length:0,r=Math.max(1,i-t);let o=K.instructions||n.instruction;return o=o.replace(/\{FROM\}/gi,"1").replace(/\{TO\}/gi,String(r)),e(d,{partNumber:$,partName:K.name,questionCount:te,instruction:o,questionId:n.questionId,paragraph:n.paragraph,title:n.title,imageUrl:n.imageUrl,wordBank:n.wordBank,viewMode:n.viewMode,answers:Q,onAnswerChange:F,exampleAnswer:n.exampleAnswer,isReviewMode:k,emailFrom:n.emailFrom,emailTo:n.emailTo})}case"MATCH_BY_WRITING_ANSWER":{const n=W(ne);return e(C,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,audioUrl:K.audioUrl,options:n.options,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k,viewMode:n.viewMode,groupImageUrl:n.groupImageUrl})}case"WORD_FILL_STRUCTURED_FORM":{const n=H(ne);return e(A,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,audioUrl:n.audioUrl||K.audioUrl,groupTitle:n.groupTitle,groupContent:n.groupContent,groupImageUrl:n.groupImageUrl,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"WRITE_SENTENCES":{const n=G(ne);return e(N,{partNumber:$,partName:K.name,questionCount:te,instruction:K.instructions||n.instruction,imageUrl:n.imageUrl,title:n.title,groupContent:n.groupContent,questions:se(n.questions),answers:Q,onAnswerChange:F,isReviewMode:k})}case"LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE":case"LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP":case"LISTEN_AND_DRAG_OBJECTS_INTO_SCENE":case"LISTEN_AND_SPEAK_ANSWER":case"LISTEN_AND_SPEAK_COMPARE_IMAGES":case"LISTEN_AND_SPEAK_WITH_STORY_IMAGES":case"LISTEN_AND_SPEAK_IMAGE_GROUP":case"LISTEN_AND_SPEAK_ODD_ONE_OUT":case"LISTEN_AND_SPEAK_QUESTION_LIST":case"LISTEN_AND_SPEAK_INFO_EXCHANGE":case"SPEAKING_DESCRIBE_IMAGE":case"READ_DISPLAYED_CONTENT":case"SPONTANEOUS_QA":case"SPEAKING_CONVERSATION":case"GN_SPEAKING_INTERVIEW":case"SPEAKING_CUE_CARD":return e(I,{part:K,answers:Q,onAnswerChange:F,isReviewMode:k,onExit:j,onPartComplete:y,onPartBack:V,speakingTheme:J,initialQuestionIndex:Y,skipTeacherVideo:X,onTeacherIntroPlayed:z,currentQuestionIndex:Z});default:return e("div",{className:"flex h-full items-center justify-center",children:n("div",{className:"text-center",children:[e("p",{className:"text-lg font-semibold text-red-500",children:"Unsupported question type"}),e("p",{className:"mt-2 text-gray-500",children:ee})]})})}}
@@ -0,0 +1,10 @@
1
+ export { CambridgeYleExamLayout as MoversExamLayout } from '../../../../components/themes/cambridge-yle/CambridgeYleExamLayout';
2
+ export { CambridgeYleHeader as MoversHeader } from '../../../../components/themes/cambridge-yle/CambridgeYleHeader';
3
+ export { CambridgeYleNavButton as MoversNavButton } from '../../../../components/themes/cambridge-yle/CambridgeYleNavButton';
4
+ export { CambridgeYleProgressBar as MoversProgressBar } from '../../../../components/themes/cambridge-yle/CambridgeYleProgressBar';
5
+ export { CambridgeYleTimer as MoversTimer } from '../../../../components/themes/cambridge-yle/CambridgeYleTimer';
6
+ export { default as MoversQuestionCard } from '../../../../components/themes/cambridge-yle/CambridgeYleQuestionCard';
7
+ export { default as MoversPartBanner } from '../../../../components/themes/cambridge-yle/CambridgeYlePartBanner';
8
+ export { default as MoversInstructionBanner } from '../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner';
9
+ export { default as MoversAudioPlayer } from '../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer';
10
+ export { default as MoversExampleText } from '../../../../components/themes/cambridge-yle/CambridgeYleExampleText';
@@ -0,0 +1 @@
1
+ export{CambridgeYleExamLayout as MoversExamLayout}from"../../../../components/themes/cambridge-yle/CambridgeYleExamLayout";export{CambridgeYleHeader as MoversHeader}from"../../../../components/themes/cambridge-yle/CambridgeYleHeader";export{CambridgeYleNavButton as MoversNavButton}from"../../../../components/themes/cambridge-yle/CambridgeYleNavButton";export{CambridgeYleProgressBar as MoversProgressBar}from"../../../../components/themes/cambridge-yle/CambridgeYleProgressBar";export{CambridgeYleTimer as MoversTimer}from"../../../../components/themes/cambridge-yle/CambridgeYleTimer";export{default as MoversQuestionCard}from"../../../../components/themes/cambridge-yle/CambridgeYleQuestionCard";export{default as MoversPartBanner}from"../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";export{default as MoversInstructionBanner}from"../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";export{default as MoversAudioPlayer}from"../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";export{default as MoversExampleText}from"../../../../components/themes/cambridge-yle/CambridgeYleExampleText";
@@ -0,0 +1,7 @@
1
+ import type { ArticleItem } from '../../types';
2
+ interface ArticlesViewerProps {
3
+ articles: ArticleItem[];
4
+ title?: string;
5
+ }
6
+ export declare function ArticlesViewer({ articles, title }: ArticlesViewerProps): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import{ResolvedImage as r}from"../../../../../components/common/ResolvedImage";export function ArticlesViewer({articles:t,title:a}){return t&&0!==t.length?l("div",{className:"flex flex-col gap-3",children:[a&&e("h3",{className:"text-center text-lg font-bold text-gray-800",children:a}),e("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",children:t.map((t,a)=>l("div",{className:"rounded-lg border border-gray-200 bg-white p-3 shadow-sm",children:[t.imageUrl&&e("div",{className:"mb-2 flex justify-center",children:e(r,{src:t.imageUrl,alt:t.name,className:"h-24 w-24 rounded-full object-cover"})}),e("h4",{className:"mb-1 text-center text-base font-bold text-gray-900",children:t.name}),e("p",{className:"text-sm leading-relaxed text-gray-700",children:t.content})]},a))})]}):null}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ANSWER_THE_QUESTION Renderer - Text input per question with optional prefix/suffix
3
+ * Used in Starters P2/P6/P9, Movers P2/P11
4
+ */
5
+ import type { AnswerTheQuestionQuestion } from '../../utils/question-transformers';
6
+ interface MoversAnswerTheQuestionRendererProps {
7
+ partNumber: number;
8
+ partName?: string;
9
+ questionCount: number;
10
+ instruction: string;
11
+ imageUrl?: string;
12
+ audioUrl?: string;
13
+ title?: string;
14
+ groupContent?: string;
15
+ questions: AnswerTheQuestionQuestion[];
16
+ answers: Record<string, string>;
17
+ onAnswerChange: (questionId: string, value: string) => void;
18
+ isReviewMode?: boolean;
19
+ correctAnswerTextMap?: Record<string, string>;
20
+ }
21
+ export declare function MoversAnswerTheQuestionRenderer({ partNumber, partName, questionCount, instruction, imageUrl, audioUrl, groupContent, questions, answers, onAnswerChange, isReviewMode, correctAnswerTextMap, }: MoversAnswerTheQuestionRendererProps): import("react").JSX.Element;
22
+ export {};
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import{ResolvedImage as s}from"../../../../../components/common/ResolvedImage";import a from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import t from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import n from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";function i({question:a,answer:t,onAnswerChange:n,isReviewMode:i,correctAnswerTextMap:o,id:l}){const d=a.isExample,m=i||d,c=o[a.id],g=t||"",p=d&&a.exampleAnswer?a.exampleAnswer:g,x=i&&void 0!==c,u=x&&g.trim().toLowerCase()===c.trim().toLowerCase(),b=x&&!!g&&!u;return r("div",{id:l,className:"flex items-start gap-3 rounded-lg p-3 "+(d?"border-2 border-orange-200 bg-orange-50":""),children:[e("span",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full text-sm font-bold text-white "+(d?"bg-orange-400":u?"bg-green-500":b?"bg-red-500":"bg-blue-500"),children:a.questionNumber}),r("div",{className:"flex flex-1 flex-col gap-2",children:[a.imageUrl&&e(s,{src:a.imageUrl,alt:`Q${a.questionNumber}`,className:"max-h-[120px] rounded-lg object-contain"}),r("div",{className:"flex flex-wrap items-baseline gap-2",children:[e("span",{className:"font-medium text-gray-800",children:a.question}),a.prefixText&&e("span",{className:"text-gray-600",children:a.prefixText}),e("input",{type:"text",value:p,onChange:e=>n(a.id,e.target.value),disabled:m,placeholder:d?"":"Type your answer...",className:"min-w-[140px] flex-1 border-b-2 bg-transparent px-1 py-1 text-center outline-none focus:border-blue-500 disabled:cursor-default "+(d?"border-orange-400 font-semibold text-orange-700 disabled:opacity-100":u?"border-green-500 text-green-700":b?"border-red-500 text-red-700":"border-gray-400 disabled:opacity-60")}),a.suffixText&&e("span",{className:"text-gray-600",children:a.suffixText}),d&&e("span",{className:"rounded bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600",children:"Example"})]}),!d&&b&&x&&r("p",{className:"text-sm text-green-600",children:["Đáp án đúng: ",c]}),!d&&x&&!g&&r("p",{className:"text-sm text-green-600",children:["Đáp án đúng: ",c]}),a.suggestedAnswers&&a.suggestedAnswers.length>0&&!m&&e("div",{className:"flex flex-wrap gap-2",children:a.suggestedAnswers.map((r,s)=>e("button",{type:"button",onClick:()=>n(a.id,r),className:"rounded-full border border-blue-300 bg-blue-50 px-3 py-1 text-sm text-blue-700 transition-colors hover:bg-blue-100",children:r},s))})]})]})}export function MoversAnswerTheQuestionRenderer({partNumber:o,partName:l,questionCount:d,instruction:m,imageUrl:c,audioUrl:g,groupContent:p,questions:x,answers:u,onAnswerChange:b,isReviewMode:h=!1,correctAnswerTextMap:f={}}){const w=x.filter(e=>e.isExample),N=x.filter(e=>!e.isExample);return r("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar",children:[r("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-2",children:[e(a,{partNumber:o,questionCount:d,partName:l,isReviewMode:h}),e(t,{instruction:m,isReviewMode:h}),g&&e("div",{className:"relative z-10",children:e(n,{audioSrc:g,compact:!0})}),c&&e("div",{className:"relative z-0 flex items-center justify-center",children:e(s,{src:c,alt:"Shared illustration",className:"max-h-[450px] rounded-lg object-contain shadow-md"})}),p&&e("div",{className:"rounded-lg bg-amber-50 p-4 text-base leading-relaxed text-gray-800",dangerouslySetInnerHTML:{__html:p}}),w.length>0&&e("div",{className:"flex flex-col gap-4 mt-2",children:w.map(r=>e(i,{id:`question-${r.id}`,question:r,answer:u[r.id],onAnswerChange:b,isReviewMode:h,correctAnswerTextMap:f},r.id))})]}),w.length>0&&N.length>0&&e("div",{className:"px-3 sm:px-6",children:e("hr",{className:"border-t border-slate-200/60 my-1"})}),e("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-5 p-3 sm:px-6 sm:pb-6",children:N.map(r=>e("div",{id:`question-${r.id}`,className:"w-full rounded-xl border border-gray-200 bg-white shadow-sm transition-all hover:border-indigo-200 hover:shadow-md",children:e(i,{question:r,answer:u[r.id],onAnswerChange:b,isReviewMode:h,correctAnswerTextMap:f})},r.id))})]})}
@@ -0,0 +1,14 @@
1
+ import type { ChooseAdjectiveQuestion } from '../../utils/question-transformers';
2
+ interface MoversChooseAdjectiveRendererProps {
3
+ partNumber: number;
4
+ partName?: string;
5
+ questionCount: number;
6
+ instruction: string;
7
+ questions: ChooseAdjectiveQuestion[];
8
+ answers: Record<string, string>;
9
+ onAnswerChange: (questionId: string, optionId: string) => void;
10
+ isReviewMode?: boolean;
11
+ correctAnswers?: Record<string, number>;
12
+ }
13
+ export declare function MoversChooseAdjectiveRenderer({ partNumber, partName, questionCount, instruction, questions, answers, onAnswerChange, isReviewMode, correctAnswers, }: MoversChooseAdjectiveRendererProps): import("react").JSX.Element;
14
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import t from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import n from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function i({question:t,selectedOptionId:n,onSelect:i,isReviewMode:o,correctOptionIndex:s,id:d}){const l=function(e,r){if(!r)return null;const t=e.options.find(e=>e.id===r);return t?.text||null}(t,n),a=void 0!==s?`${t.id}-opt-${s}`:void 0,c=e=>{const r=n===e.id,t=e.id===a;return o?t?"border-green-500 bg-green-50 text-green-700":r&&!t?"border-red-500 bg-red-50 text-red-700":"border-gray-300 bg-white text-gray-500":r?"border-blue-500 bg-blue-50 text-blue-700":"border-gray-300 bg-white hover:border-blue-300 text-gray-700"};return r("div",{id:d,className:"mb-6",children:[r("div",{className:"mb-3 flex items-baseline gap-2",children:[e("span",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-blue-500 text-sm font-bold text-white",children:t.questionNumber}),r("div",{className:"flex-1 text-base leading-relaxed text-gray-800",children:[e("span",{children:t.sentenceBefore}),e("span",{className:`mx-1 inline-block min-w-[100px] border-b-2 px-2 text-center font-semibold ${(()=>{if(!o)return l?"text-blue-600":"text-gray-400";if(!n)return"text-gray-400";return n===a?"text-green-600":"text-red-600"})()} ${(()=>{if(!o)return l?"border-blue-500":"border-gray-300";if(!n)return"border-gray-300";return n===a?"border-green-500":"border-red-500"})()}`,children:l||"_______"}),e("span",{children:t.sentenceAfter}),r("span",{className:"ml-2 text-sm italic text-gray-500",children:["(",t.options.map(e=>e.text).join(" / "),")"]})]})]}),e("div",{className:"flex flex-wrap gap-2 pl-9",children:t.options.map(e=>r("button",{type:"button",onClick:()=>!o&&i(e.id),disabled:o,className:`rounded-lg border-2 px-4 py-2 text-sm font-medium transition-colors ${c(e)} ${o?"cursor-default":"cursor-pointer"}`,children:[e.label,". ",e.text]},e.id))}),o&&n&&n!==a&&void 0!==s&&r("div",{className:"mt-2 pl-9 text-sm text-green-600",children:[e("span",{className:"font-semibold",children:"Đáp án đúng: "}),t.options[s]?.text]})]})}export function MoversChooseAdjectiveRenderer({partNumber:o,partName:s,questionCount:d,instruction:l,questions:a,answers:c,onAnswerChange:m,isReviewMode:u=!1,correctAnswers:p={}}){return r("div",{className:"grid h-full grid-cols-1 gap-4 sm:gap-6 "+(u?"":"lg:grid-cols-2"),children:[r("div",{className:"flex flex-col gap-4 overflow-y-auto p-3 sm:pb-6 sm:pr-6 sm:pt-6",children:[e(t,{partNumber:o,questionCount:d,partName:s,isReviewMode:u}),e(n,{instruction:l,isReviewMode:u})]}),e("div",{className:"flex flex-col gap-4 overflow-y-auto p-3 sm:pb-6 sm:pl-2 sm:pt-6",children:a.map(r=>e(i,{id:`question-${r.id}`,question:r,selectedOptionId:c[r.id],onSelect:e=>m(r.id,e),isReviewMode:u,correctOptionIndex:p[r.id]},r.id))})]})}
@@ -0,0 +1,2 @@
1
+ import type { MoversChooseBestAnswerRendererProps } from '../../types';
2
+ export declare function MoversChooseBestAnswerRenderer({ partNumber, partName, questionCount, instruction, imageUrl, groupTitle, groupContent, articles, audioUrl, example, questions, answers, onAnswerChange, isReviewMode, }: MoversChooseBestAnswerRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import{ZoomIn as n}from"lucide-react";import{useState as l}from"react";import{cn as o}from"../../../../../shared/lib/utils";import{ResolvedImage as i}from"../../../../../components/common/ResolvedImage";import s from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import a from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";function c(e){if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return String(e);if(Array.isArray(e))return e.map(e=>c(e)).filter(Boolean).join(" ");if(e&&"object"==typeof e){const t=e;if("string"==typeof t.content)return t.content;if("string"==typeof t.question)return t.question;if("string"==typeof t.text)return t.text;const r=Object.entries(t).filter(([e,t])=>/^\d+$/.test(e)&&"string"==typeof t).sort(([e],[t])=>Number(e)-Number(t)).map(([,e])=>e);if(r.length>0)return r.join("")}return""}function m({imageUrl:o}){const[s,a]=l(!1);return t(r,{children:[t("div",{className:"relative flex items-center justify-center",children:[e(i,{src:o,alt:"Question illustration",className:"max-h-[250px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>a(!0)}),e("button",{type:"button",onClick:()=>a(!0),className:"absolute right-2 top-2 rounded-full bg-white/80 p-1.5 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(n,{className:"h-4 w-4 text-gray-600"})})]}),s&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>a(!1),children:e(i,{src:o,alt:"Question illustration (zoomed)",className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function u({example:r}){return t("div",{className:"rounded-lg border-2 border-orange-300 bg-white p-4",children:[e("p",{className:"mb-3 text-sm font-semibold text-gray-700",children:"Example:"}),t("p",{className:"mb-3 text-[19px] font-bold text-[#001590]",children:[r.questionNumber,". ",c(r.questionText)]}),r.imageUrl&&e("div",{className:"mb-3",children:e(m,{imageUrl:r.imageUrl})}),"image"===r.optionType?e("div",{className:"grid gap-3 px-2",style:{gridTemplateColumns:`repeat(${r.options.length}, minmax(0, 1fr))`},children:r.options.map(n=>{const l=n.id===r.correctOptionId;return t("div",{className:"relative flex flex-col items-center gap-1 rounded-[16px] border-[3px] p-4 pt-6 mt-3 transition-colors "+(l?"border-green-500 bg-green-50":"border-blue-200 bg-white"),children:[e("div",{className:"absolute -top-[14px] left-1/2 -translate-x-1/2 bg-blue-600 text-white w-[28px] h-[28px] rounded-full flex items-center justify-center font-bold text-[15px] shadow-sm",children:n.label}),e(i,{src:n.text,alt:`Option ${n.label}`,className:"w-40 rounded object-contain mb-2"}),e("div",{className:o("w-7 h-7 rounded-full flex items-center justify-center border-[3px] transition-all mt-auto",l?"bg-green-500 border-green-500 text-white":"border-gray-300 bg-white text-transparent"),children:e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})})]},n.id)})}):e("div",{className:"flex flex-col gap-2 pl-2",children:r.options.map(n=>{const l=n.id===r.correctOptionId;return t("div",{className:"flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors "+(l?"border-green-500 bg-green-50":"border-blue-200 bg-white"),children:[t("span",{className:"text-sm font-medium text-gray-600",children:[n.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:c(n.text)}),e("div",{className:"flex h-5 w-5 items-center justify-center border-2 rounded-full "+(l?"border-green-500 bg-green-500":"border-gray-300 bg-white"),children:l&&e("div",{className:"h-2 w-2 rounded-full bg-white"})})]},n.id)})})]})}function p({question:r,selectedOptionIds:n,onSelect:l,isReviewMode:s,id:a}){const d=Boolean(r.multipleAnswers||r.correctOptionIds?.length),u=r.correctOptionIds?.length?r.correctOptionIds:r.correctOptionId?[r.correctOptionId]:[],p=e=>{const t=n.includes(e),r=u.includes(e);return s?r?"border-green-500 bg-green-50":t&&!r?"border-red-500 bg-red-50":"border-blue-200 bg-white":t?"border-blue-500 bg-[#f4f9ff]":"border-blue-200 bg-white hover:border-blue-300 hover:bg-blue-50/30"},b=e=>{const t=n.includes(e),r=u.includes(e);return s?r?"border-green-500 bg-green-500":t&&!r?"border-red-500 bg-red-500":"border-gray-300 bg-white":t?"border-blue-500 bg-blue-500":"border-gray-300 bg-white"},g=e=>s?n.includes(e)||u.includes(e):n.includes(e);return t("div",{id:a,className:"mb-6",children:[t("p",{className:"mb-3 text-[19px] font-bold text-[#001590]",children:[r.questionNumber,". ",c(r.questionText)]}),d&&e("p",{className:"mb-3 pl-2 text-sm font-medium text-blue-600",children:"Chọn nhiều đáp án"}),r.imageUrl&&e("div",{className:"mb-3",children:e(m,{imageUrl:r.imageUrl})}),"image"===r.optionType?e("div",{className:"grid gap-3 px-2",style:{gridTemplateColumns:`repeat(${r.options.length}, minmax(0, 1fr))`},children:r.options.map(r=>t("button",{type:"button",onClick:()=>!s&&l(r.id),disabled:s,className:`relative flex flex-col items-center gap-1 rounded-[16px] border-[3px] p-4 pt-6 mt-3 transition-colors ${p(r.id)} ${s?"cursor-default":"cursor-pointer"}`,children:[e("div",{className:"absolute -top-[14px] left-1/2 -translate-x-1/2 bg-blue-600 text-white w-[28px] h-[28px] rounded-full flex items-center justify-center font-bold text-[15px] shadow-sm",children:r.label}),e(i,{src:r.text,alt:`Option ${r.label}`,className:"w-35 rounded object-contain mb-2"}),e("div",{className:o("w-7 h-7 rounded-full flex items-center justify-center border-[3px] transition-all mt-auto",g(r.id)?"bg-blue-600 border-blue-600 text-white":"border-gray-300 bg-white text-transparent"),children:e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})})]},r.id))}):e("div",{className:"flex flex-col gap-2 pl-2",children:r.options.map(r=>t("button",{type:"button",onClick:()=>!s&&l(r.id),disabled:s,className:`flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors ${p(r.id)} ${s?"cursor-default":"cursor-pointer"}`,children:[t("span",{className:"text-sm font-medium text-gray-600",children:[r.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:c(r.text)}),e("div",{className:`flex h-5 w-5 items-center justify-center border-2 ${d?"rounded-md":"rounded-full"} ${b(r.id)}`,children:g(r.id)&&e("div",{className:(d?"h-2.5 w-2.5 rounded-sm":"h-2 w-2 rounded-full")+" bg-white"})})]},r.id))})]})}function b({article:r,label:n}){return t("div",{className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[t("div",{className:"mb-2 flex items-center gap-2",children:[e("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-teal-500 text-xs font-bold text-white",children:n}),e("h3",{className:"text-sm font-bold text-gray-900",children:r.name})]}),r.imageUrl&&e("div",{className:"mb-2",children:e(i,{src:r.imageUrl,alt:r.name,className:"max-h-48 w-full rounded-md object-contain"})}),e("div",{className:"article-content text-sm leading-relaxed text-gray-700",dangerouslySetInnerHTML:{__html:r.content}})]})}export function MoversChooseBestAnswerRenderer({partNumber:r,partName:n,questionCount:l,instruction:o,imageUrl:c,groupTitle:m,groupContent:g,articles:x,audioUrl:h,example:f,questions:w,answers:y,onAnswerChange:N,isReviewMode:v=!1}){const j=!!(h||c||x&&x.length>0||g||f);return t("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-2",children:[e(s,{partNumber:r,questionCount:l,partName:n,isReviewMode:v}),e(a,{instruction:o,isReviewMode:v}),m&&!(x&&x.length>0)&&e("h2",{className:"text-center text-xl font-bold uppercase text-coral-500",children:m})]}),j&&t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:[h&&e(d,{audioSrc:h,compact:!0}),c&&e("div",{className:"flex items-center justify-center",children:e(i,{src:c,alt:"Shared illustration",className:"max-h-[250px] rounded-lg object-contain shadow-md"})}),x&&x.length>0?e("div",{className:"flex flex-col gap-3 max-h-[35vh] overflow-y-auto custom-scrollbar pr-2",children:x.map((t,r)=>e(b,{article:t,label:String.fromCharCode(65+r)},r))}):g?e("div",{className:"article-content rounded-lg bg-amber-50 p-3 sm:p-4 text-sm leading-relaxed text-gray-700 max-h-[35vh] overflow-y-auto pr-2 custom-scrollbar shadow-inner",dangerouslySetInnerHTML:{__html:g}}):null,f&&e(u,{example:f})]}),e("div",{className:"p-3 sm:pb-6 sm:px-6 "+(v?"grid grid-cols-1 md:grid-cols-2 gap-6":"flex flex-col gap-4"),children:w.map(t=>{const r=y[t.id],n=Array.isArray(r)?r:"string"==typeof r&&r?[r]:[];return e(p,{id:`question-${t.id}`,question:t,selectedOptionIds:n,onSelect:e=>{const r=t.multipleAnswers?n.includes(e)?n.filter(t=>t!==e):[...n,e]:e;N(t.id,r)},isReviewMode:v},t.id)})})]})}
@@ -0,0 +1,3 @@
1
+ import '@xyflow/react/dist/style.css';
2
+ import type { MoversColoringRendererProps } from '../../types';
3
+ export declare function MoversColoringRenderer(props: MoversColoringRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useState as i,useRef as n,useEffect as r,useCallback as o,useMemo as d}from"react";import{ReactFlow as l,useNodesState as s,useEdgesState as a,ReactFlowProvider as c,useReactFlow as h}from"@xyflow/react";import"@xyflow/react/dist/style.css";import{usePresignedFileUrl as u}from"../../../../../shared/lib/hooks/usePresignedFileUrl";import g from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import f from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";import m from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";const p={coloringHintNode:function({data:t}){const{hintItem:i,isAssigned:n,highlightStyle:r,isHighlighted:o}=t,d=!!i.color,l=n?"flex h-full w-full items-center justify-center overflow-hidden rounded-xl transition-all duration-200":"flex h-full w-full items-center justify-center overflow-hidden rounded-full border-2 transition-all duration-200 cursor-move hover:shadow-lg",s=o?"transparent":d?"rgba(0,0,0,0.2)":"#9ca3af",a=!!i.label?i.label:"";return e("div",{className:l,style:{...r,backgroundColor:d?i.color:"#ffffff",borderColor:n?"transparent":s,padding:n?0:void 0},children:a&&e("span",{className:"px-2 py-5 text-[10px] font-bold uppercase tracking-wide pointer-events-none drop-shadow-md font-[family-name:var(--font-nunito)] md:text-xs",style:{color:(e=>{if(!e)return"#333";if(!e.startsWith("#"))return"#fff";const t=e.replace("#","");return(.299*parseInt(t.substr(0,2),16)+.587*parseInt(t.substr(2,2),16)+.114*parseInt(t.substr(4,2),16))/255>.5?"#000":"#fff"})(i.color),textShadow:d?"0 1px 2px rgba(0,0,0,0.3)":"none"},children:a})})},coloringRegionNode:function({data:t}){const{assignedHint:i,isHighlighted:n,isCorrect:r,isReviewMode:o}=t;return e("div",{className:"flex h-full w-full items-center justify-center rounded-xl transition-all "+(o?i?r?"border-2 border-solid border-green-500":"border-2 border-solid border-red-500":"border-2 border-solid border-blue-500":n?"border-2 border-solid border-blue-500":i?"":"border-2 border-dashed border-red-400"),style:{backgroundColor:i?.color||(n?"rgba(59,130,246,0.1)":"rgba(0,0,0,0.1)"),minWidth:"60px",minHeight:"40px"},children:i?.label&&e("span",{className:"px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide pointer-events-none drop-shadow-md font-[family-name:var(--font-nunito)] md:text-xs",style:{color:(e=>{if(!e)return"#333";const t=e.replace("#","");return(.299*parseInt(t.substr(0,2),16)+.587*parseInt(t.substr(2,2),16)+.114*parseInt(t.substr(4,2),16))/255>.5?"#000":"#fff"})(i.color)},children:i.label})})}};function x({partNumber:c,partName:x,questionCount:b,instruction:w,instructions:y,hasExample:v=!1,imageUrl:N,audioUrl:I,hintItems:M,regions:C,assignments:H,onAssignmentChange:j,isReviewMode:O=!1}){const{previewUrl:$}=u(N),[z,R]=i(!1),[k,S]=i({width:0,height:0}),[E,D]=i({width:0,height:0}),A=n(null),P=n(null),[U,W,L]=s([]),[,,Y]=a([]),[q,B]=i(null),V=n(!1),F=n(null),{getIntersectingNodes:K}=h(),Q=E.width>0&&E.width<640,T=Q?60:100,G=Q?32:40,J=Q?10:16,X=Math.max(E.width-32,T),Z=Math.max(1,Math.floor((X+J)/(T+J))),_=M.filter(e=>!Object.values(H).includes(e.id)).length,ee=20+Math.max(1,Math.ceil(_/Z))*(G+8)+(Q?20:10),te=ee+20;r(()=>{const e=()=>{P.current&&D({width:P.current.clientWidth,height:P.current.clientHeight})};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[]);const ie=o(()=>{if(A.current&&E.width>0){const e=E.width-20,t=E.height-te-10,i=A.current.naturalWidth||800,n=A.current.naturalHeight||600,r=e/i,o=t/n,d=Math.min(r,o,2);S({width:i*d,height:n*d}),R(!0)}},[E,te]);r(()=>{E.width>0&&A.current?.complete&&ie()},[E,ie]);const ne=d(()=>!z||k.width<=0||E.width<=0?10:Math.max(10,(E.width-k.width)/2),[z,k.width,E.width]),re=o((e,t)=>{if("coloringHintNode"!==t.type)return;V.current=!0;const i=t.data,n=i.hintItem?.id;if(!n)return;const r=i.regionId||Object.keys(H).find(e=>H[e]===n);F.current=r||null,r&&j(r,null)},[H,j]),oe=o((e,t)=>{if("coloringHintNode"!==t.type)return;const i=K(t,!0).filter(e=>"coloringRegionNode"===e.type),n=t.position.y,r=n>=0&&n<=ee;i.length>0?B(i[0].id):B(r?"hint-area":null)},[K,ee]),de=o((e,t)=>{if("coloringHintNode"!==t.type)return;const i=t.data,n=i.hintItem?.id;if(!n)return B(null),void(V.current=!1);const r=K(t,!0).filter(e=>"coloringRegionNode"===e.type);if(B(null),r.length>0){const e=r[0],t=F.current,i=H[e.id];i&&i!==n?(j(e.id,n),t&&j(t,i)):j(e.id,n)}else{if(M.find(e=>e.id===n)){const e=F.current?Object.fromEntries(Object.entries(H).filter(([e])=>e!==F.current)):H,i=M.filter(t=>!Object.values(e).includes(t.id)||t.id===n).findIndex(e=>e.id===n),r=i%Z,o=Math.floor(i/Z),d={x:16+r*(T+J),y:20+o*(G+8)};W(e=>e.map(e=>e.id===t.id?{...e,position:d}:e))}}F.current=null,V.current=!1},[K,H,j,M,W,Z,T,J,G]),le=d(()=>M.filter(e=>!Object.values(H).includes(e.id)).map((e,t)=>{const i=t%Z,n=Math.floor(t/Z);return{id:`hint-${e.id}`,type:"coloringHintNode",position:{x:16+i*(T+J),y:20+n*(G+8)},data:{hintItem:e,isAssigned:!1},draggable:!O,style:{width:`${T}px`,height:`${G}px`}}}),[M,H,O,Z,16,T,J,20,G,8]),se=d(()=>!z||k.width<=0?[]:C.filter(e=>H[e.id]).map(e=>{const t=H[e.id],i=M.find(e=>e.id===t);if(!i)return null;const n=ne+e.x/100*k.width,r=te+e.y/100*k.height,o=Math.max(e.width/100*k.width,60),d=Math.max(e.height/100*k.height,40);return{id:`hint-in-region-${e.id}`,type:"coloringHintNode",position:{x:n,y:r},data:{hintItem:i,isAssigned:!0,regionId:e.id},draggable:!O,style:{width:`${o}px`,height:`${d}px`}}}).filter(e=>null!==e),[z,k,ne,C,H,M,O,te]),ae=d(()=>!z||k.width<=0?[]:C.map(e=>{const t=H[e.id],i=t?M.find(e=>e.id===t):void 0,n=O&&t===e.correctHintId;return{id:e.id,type:"coloringRegionNode",position:{x:ne+e.x/100*k.width,y:te+e.y/100*k.height},data:{region:e,assignedHint:i,isHighlighted:q===e.id,isCorrect:n,isReviewMode:O},draggable:!1,style:{width:`${Math.max(e.width/100*k.width,60)}px`,height:`${Math.max(e.height/100*k.height,40)}px`,pointerEvents:i?"none":"auto"},zIndex:0}}),[z,k,ne,C,H,M,q,O,te]);return r(()=>{if(V.current)return;const e=[...ae,...le,...se];W(e)},[ae,le,se,W]),t("div",{className:"flex h-full w-full flex-col gap-3",children:[e(m,{partNumber:c,questionCount:b,partName:x,isReviewMode:O}),e("div",{className:"shrink-0",children:e(g,{instruction:w,instructions:y,hasExample:v,isReviewMode:O,children:I&&e("div",{className:"shrink-0",children:e(f,{audioSrc:I,compact:!0})})})}),t("div",{ref:P,className:"relative flex-1 overflow-x-auto overflow-y-hidden rounded-xl bg-gray-100",style:{minHeight:"1000px"},children:[e("div",{className:"pointer-events-none absolute left-0 right-0 z-20 flex items-center justify-center sm:justify-end sm:pr-4",style:{top:Q?ee-40+"px":"20px",height:"40px"},children:e("span",{className:"rounded-full bg-white/80 px-3 py-1 text-xs font-medium text-gray-500 shadow-sm",children:"Kéo màu vào vị trí tương ứng"})}),e("div",{className:"pointer-events-none absolute",style:{left:`${ne}px`,top:`${te}px`,width:k.width?`${k.width}px`:"auto",height:k.height?`${k.height}px`:"auto",zIndex:0},children:e("img",{ref:A,src:$||N,alt:"Question illustration",className:"h-full w-full rounded-lg object-contain shadow-md",onLoad:ie,onError:()=>R(!1)})}),e("div",{className:"absolute inset-0 z-10",children:e(l,{nodes:U,edges:[],onNodesChange:L,onNodeDragStart:re,onNodeDrag:oe,onNodeDragStop:de,onEdgesChange:Y,nodeTypes:p,defaultViewport:{x:0,y:0,zoom:1},fitView:!1,nodesDraggable:!O,nodesConnectable:!1,elementsSelectable:!1,panOnDrag:!1,panOnScroll:!1,zoomOnScroll:!1,zoomOnDoubleClick:!1,zoomOnPinch:!1,preventScrolling:!0,autoPanOnNodeDrag:!1,autoPanOnConnect:!1,proOptions:{hideAttribution:!0}})})]})]})}export function MoversColoringRenderer(t){return e(c,{children:e(x,{...t})})}
@@ -0,0 +1,2 @@
1
+ import type { MoversFillWordHintRendererProps } from '../../types';
2
+ export declare function MoversFillWordHintRenderer({ partNumber, partName, questionCount, instruction, hintLetters, subQuestions, answers, onAnswerChange, isReviewMode, }: MoversFillWordHintRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useState as s}from"react";import{ZoomIn as o,Check as n}from"lucide-react";import{ResolvedImage as a}from"../../../../../components/common/ResolvedImage";import i from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import l from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function c({imageUrl:n,alt:i}){const[l,c]=s(!1);return n?r(t,{children:[r("div",{className:"relative flex items-center justify-center",children:[e(a,{src:n,alt:i,className:"h-24 w-24 cursor-pointer rounded-lg object-cover shadow-md",onClick:()=>c(!0)}),e("button",{type:"button",onClick:()=>c(!0),className:"absolute -right-1 -top-1 rounded-full bg-white/80 p-1 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(o,{className:"h-3 w-3 text-gray-600"})})]}),l&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>c(!1),children:e(a,{src:n,alt:`${i} (zoomed)`,className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]}):null}function d({letters:t}){return r("div",{className:"rounded-lg border-2 border-amber-200 bg-amber-50 p-4",children:[e("p",{className:"mb-3 text-sm font-semibold text-amber-800",children:"Available Letters:"}),e("div",{className:"flex flex-wrap gap-2",children:t.map((r,t)=>e("span",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-white text-lg font-bold text-amber-700 shadow-sm",children:r},t))})]})}function m({word:t,answer:s,isReviewMode:o,correctAnswer:n}){const a=t.indexOf("_"),i=t.slice(0,a),l=t.slice(a+1),c=o&&s.toLowerCase()===n?.toLowerCase(),d=o&&s&&s.toLowerCase()!==n?.toLowerCase(),m=o&&!s,u=m?n:s||"_";return r("div",{className:"flex items-center justify-center text-2xl font-bold tracking-wider text-gray-700",children:[e("span",{children:i}),e("span",{className:"mx-0.5 inline-flex h-8 w-8 items-center justify-center rounded border-2 "+(o?c?"border-green-500 bg-green-100 text-green-600":d?"border-red-500 bg-red-100 text-red-600":m?"border-blue-500 bg-blue-50 text-blue-600":"border-gray-300 bg-gray-50 text-gray-400":"border-blue-400 bg-blue-50 text-blue-600"),children:u}),e("span",{children:l})]})}function u({subQuestion:t,answer:s,onChange:o,isReviewMode:a,hintLetters:i,id:l}){const d=a&&s.toLowerCase()===t.correctAnswer?.toLowerCase(),u=a&&s&&s.toLowerCase()!==t.correctAnswer?.toLowerCase(),b=a&&!s;return r("div",{id:l,className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[r("div",{className:"mb-3 flex items-start gap-3",children:[e("span",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-blue-500 text-sm font-bold text-white",children:t.questionNumber}),e(c,{imageUrl:t.imageUrl,alt:`Question ${t.questionNumber}`})]}),e("div",{className:"mb-3",children:e(m,{word:t.word,answer:s,isReviewMode:a,correctAnswer:t.correctAnswer})}),e("div",{className:"flex flex-wrap justify-center gap-2",children:i.map((r,n)=>{const i=s.toLowerCase()===r.toLowerCase(),l=t.correctAnswer?.toLowerCase()===r.toLowerCase(),c=!s,d=s&&s.toLowerCase()!==t.correctAnswer?.toLowerCase();let m="border-gray-300 bg-white hover:border-blue-300",u="text-gray-700";return a?l?(m=c||d?"border-blue-500 bg-blue-50":"border-green-500 bg-green-100",u="text-gray-800 font-bold"):i&&!l?(m="border-red-500 bg-red-100",u="text-gray-800 font-bold"):u="text-gray-600":i&&(m="border-blue-500 bg-blue-100"),e("button",{type:"button",onClick:()=>!a&&o(r),disabled:a,className:`flex h-10 w-10 items-center justify-center rounded-lg border-2 text-lg transition-colors ${m} ${u} ${a?"cursor-default":"cursor-pointer"}`,children:r},n)})}),a&&r("div",{className:"mt-2 flex items-center justify-center gap-2",children:[d&&r("span",{className:"flex items-center gap-1 text-sm font-medium text-green-600",children:[e(n,{className:"h-4 w-4"})," Correct"]}),u&&r("span",{className:"text-sm font-medium text-blue-600",children:["Correct answer: ",t.correctAnswer]}),b&&r("span",{className:"flex items-center gap-1 text-sm font-medium text-blue-600",children:["Correct answer: ",t.correctAnswer]})]})]})}function b({subQuestion:t,answer:s,onChange:o,isReviewMode:a,hintLetters:i,id:l}){const c=a&&s.toLowerCase()===t.correctAnswer?.toLowerCase(),d=a&&s&&s.toLowerCase()!==t.correctAnswer?.toLowerCase(),u=a&&!s;return r("div",{id:l,className:"flex flex-col items-center gap-2 rounded-lg border border-gray-200 bg-white p-4",children:[e(m,{word:t.word,answer:s,isReviewMode:a,correctAnswer:t.correctAnswer}),e("div",{className:"flex flex-wrap justify-center gap-1",children:i.map((r,n)=>{const i=s.toLowerCase()===r.toLowerCase(),l=t.correctAnswer?.toLowerCase()===r.toLowerCase(),c=!s,d=s&&s.toLowerCase()!==t.correctAnswer?.toLowerCase();let m="border-gray-300 bg-white hover:border-blue-300",u="text-gray-700";return a?l?(m=c||d?"border-blue-500 bg-blue-50":"border-green-500 bg-green-100",u="text-gray-800 font-bold"):i&&!l?(m="border-red-500 bg-red-100",u="text-gray-800 font-bold"):u="text-gray-600":i&&(m="border-blue-500 bg-blue-100"),e("button",{type:"button",onClick:()=>!a&&o(r),disabled:a,className:`flex h-8 w-8 items-center justify-center rounded-lg border-2 text-base transition-colors ${m} ${u} ${a?"cursor-default":"cursor-pointer"}`,children:r},n)})}),a&&r("div",{className:"flex items-center justify-center gap-2",children:[c&&r("span",{className:"flex items-center gap-1 text-xs font-medium text-green-600",children:[e(n,{className:"h-3 w-3"})," Correct"]}),(d||u)&&r("span",{className:"text-xs font-medium text-blue-600",children:["Correct answer: ",t.correctAnswer]})]})]})}export function MoversFillWordHintRenderer({partNumber:t,partName:s,questionCount:o,instruction:n,hintLetters:a,subQuestions:m,answers:g,onAnswerChange:w,isReviewMode:f=!1}){const h=m.length>0&&void 0!==m[0].blankIndex&&m.every(e=>e.imageUrl===m[0].imageUrl);return r("div",h?{className:"flex h-full flex-col gap-4 overflow-y-auto p-6",children:[r("div",{className:"flex flex-col gap-4",children:[e(i,{partNumber:t,questionCount:o,partName:s,isReviewMode:f}),e(l,{instruction:n,isReviewMode:f}),e(d,{letters:a})]}),r("div",{className:"rounded-lg border border-gray-200 bg-white p-6 shadow-sm",children:[e("div",{className:"mb-6 flex justify-center",children:e(c,{imageUrl:m[0].imageUrl,alt:"Question image"})}),e("div",{className:"flex flex-wrap justify-center gap-4",children:m.map(r=>e(b,{id:`question-${r.id}`,subQuestion:r,answer:g[r.id]||"",onChange:e=>w(r.id,e),isReviewMode:f,hintLetters:a},r.id))})]})]}:{className:"flex h-full flex-col gap-4 overflow-y-auto p-6",children:[r("div",{className:"flex flex-col gap-4",children:[e(i,{partNumber:t,questionCount:o,partName:s,isReviewMode:f}),e(l,{instruction:n,isReviewMode:f}),e(d,{letters:a})]}),e("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",children:m.map(r=>e(u,{id:`question-${r.id}`,subQuestion:r,answer:g[r.id]||"",onChange:e=>w(r.id,e),isReviewMode:f,hintLetters:a},r.id))})]})}
@@ -0,0 +1,2 @@
1
+ import type { MoversGridFillRendererProps } from '../../types';
2
+ export declare function MoversGridFillRenderer({ partNumber, partName, questionCount, instruction, grid, rows, columns, cellAnswers, answers, onAnswerChange, isReviewMode, caseSensitive, disabledCells, }: MoversGridFillRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as s}from"react/jsx-runtime";import{Check as n,X as a}from"lucide-react";import t from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import l from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function d({value:s,isEditable:t,cellKey:l,userAnswer:d,correctAnswer:i,onChange:o,isReviewMode:c,caseSensitive:m=!1}){const g="h-10 w-10 text-lg sm:h-12 sm:w-12 sm:text-xl md:h-14 md:w-14 md:text-2xl lg:h-16 lg:w-16";if(!t)return e("div",{className:`flex items-center justify-center rounded-lg border-2 border-gray-300 bg-gray-100 font-bold text-gray-700 ${g}`,children:s});const h=d||"",u=c&&(m?h===i:h.toLowerCase()===i?.toLowerCase()),b=c&&h&&(m?h!==i:h.toLowerCase()!==i?.toLowerCase());return r("div",{className:"relative",children:[e("input",{type:"text",value:h,onChange:e=>!c&&o(e.target.value.slice(0,2)),disabled:c,maxLength:2,className:`flex items-center justify-center rounded-lg border-2 text-center font-bold outline-none transition-colors ${g} ${c?u?"border-green-500 bg-green-100":b?"border-red-500 bg-red-100":"border-dashed border-gray-400 bg-yellow-50":h?"border-blue-500 bg-blue-50":"border-dashed border-gray-400 bg-white"} ${c?u?"text-green-600":b?"text-red-600":"text-gray-800":"text-gray-800"} ${c?"cursor-default":"cursor-text"}`,placeholder:"?"}),c&&u&&e("span",{className:"absolute -right-1 -top-1 rounded-full bg-green-500 p-0.5",children:e(n,{className:"h-3 w-3 text-white"})}),c&&b&&e("span",{className:"absolute -right-1 -top-1 rounded-full bg-red-500 p-0.5",children:e(a,{className:"h-3 w-3 text-white"})})]})}function i({grid:r,rows:s,columns:n,cellAnswers:a,answers:t,onAnswerChange:l,isReviewMode:i,caseSensitive:o=!1,disabledCells:c=[]}){return e("div",{className:"inline-grid gap-1 sm:gap-1.5 md:gap-2",style:{gridTemplateColumns:`repeat(${n}, minmax(0, 1fr))`},children:r.map((r,s)=>r.map((r,n)=>{const m=`${s+1}-${n+1}`,g=null===r,h=a[m];return c?.includes(m)?e("div",{className:"h-10 w-10 sm:h-12 sm:w-12 md:h-14 md:w-14 lg:h-16 lg:w-16"},m):e(d,{value:r,isEditable:g,cellKey:m,userAnswer:t[m],correctAnswer:h?.correctAnswer,onChange:e=>l(m,e),isReviewMode:i,caseSensitive:o},m)}))})}function o({isReviewMode:n}){return r("div",{className:"flex flex-wrap gap-4 text-sm text-gray-600",children:[r("div",{className:"flex items-center gap-2",children:[e("div",{className:"h-6 w-6 rounded border-2 border-gray-300 bg-gray-100"}),e("span",{children:"Pre-filled"})]}),r("div",{className:"flex items-center gap-2",children:[e("div",{className:"h-6 w-6 rounded border-2 border-dashed border-gray-400 bg-white"}),e("span",{children:"Fill in"})]}),n&&r(s,{children:[r("div",{className:"flex items-center gap-2",children:[e("div",{className:"h-6 w-6 rounded border-2 border-green-500 bg-green-100"}),e("span",{children:"Correct"})]}),r("div",{className:"flex items-center gap-2",children:[e("div",{className:"h-6 w-6 rounded border-2 border-red-500 bg-red-100"}),e("span",{children:"Incorrect"})]})]})]})}function c({cellAnswers:n,answers:a,caseSensitive:t=!1}){const l=Object.entries(n);return r("div",{className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[e("p",{className:"mb-3 text-sm font-semibold text-gray-700",children:"Answer Summary:"}),e("div",{className:"grid grid-cols-2 gap-2",children:l.map(([n,{correctAnswer:l}])=>{const d=a[n]||"",i=t?d===l:d.toLowerCase()===l.toLowerCase();return r("div",{className:"flex items-center justify-between rounded px-3 py-1.5 "+(i?"bg-green-50":"bg-red-50"),children:[r("span",{className:"text-sm font-medium text-gray-600",children:["Cell ",n,":"]}),e("div",{className:"flex items-center gap-2",children:i?e("span",{className:"text-sm font-semibold text-green-600",children:d}):r(s,{children:[e("span",{className:"text-sm font-semibold text-red-600 line-through",children:d||"—"}),r("span",{className:"text-sm text-blue-600",children:["→ ",l]})]})})]},n)})})]})}export function MoversGridFillRenderer({partNumber:s,partName:n,questionCount:a,instruction:d,grid:m,rows:g,columns:h,cellAnswers:u,answers:b,onAnswerChange:w,isReviewMode:p=!1,caseSensitive:x=!1,disabledCells:v=[]}){return r("div",{className:"flex h-full flex-col gap-4 overflow-y-auto p-3 sm:gap-5 sm:p-4 md:gap-6 md:p-6",children:[r("div",{className:"flex flex-col gap-4",children:[e(t,{partNumber:s,questionCount:a,partName:n,isReviewMode:p}),e(l,{instruction:d,isReviewMode:p})]}),r("div",{className:"flex flex-col items-center gap-6",children:[e(o,{isReviewMode:p}),e("div",{className:"rounded-xl border-2 border-gray-200 bg-gray-50 p-3 shadow-sm sm:p-4 md:p-6",children:e(i,{grid:m,rows:g,columns:h,cellAnswers:u,answers:b,onAnswerChange:w,isReviewMode:p,caseSensitive:x,disabledCells:v})}),p&&e(c,{cellAnswers:u,answers:b,caseSensitive:x})]})]})}
@@ -0,0 +1,2 @@
1
+ import type { MoversLabelThePictureRendererProps } from '../../types';
2
+ export declare function MoversLabelThePictureRenderer({ partNumber, partName, questionCount, instruction, imageUrl, wordBank, labels, answers, onAnswerChange, isReviewMode, }: MoversLabelThePictureRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useState as a}from"react";import{ZoomIn as o,Check as s,X as l}from"lucide-react";import{ResolvedImage as n}from"../../../../../components/common/ResolvedImage";import i from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function c({imageUrl:s}){const[l,i]=a(!1);return r(t,{children:[r("div",{className:"relative flex items-center justify-center",children:[e(n,{src:s,alt:"Picture to label",className:"max-h-[350px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>i(!0)}),e("button",{type:"button",onClick:()=>i(!0),className:"absolute right-2 top-2 rounded-full bg-white/80 p-1.5 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(o,{className:"h-4 w-4 text-gray-600"})})]}),l&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>i(!1),children:e(n,{src:s,alt:"Picture to label (zoomed)",className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function m({words:t,usedWords:a}){return r("div",{className:"rounded-lg border-2 border-purple-200 bg-purple-50 p-4",children:[e("p",{className:"mb-3 text-sm font-semibold text-purple-800",children:"Word Bank:"}),e("div",{className:"flex flex-wrap gap-2",children:t.map((r,t)=>{const o=a.has(r);return e("span",{className:"rounded-full px-3 py-1.5 text-sm font-medium "+(o?"bg-gray-200 text-gray-400 line-through":"bg-white text-purple-700 shadow-sm"),children:r},t)})})]})}function u({label:t,value:a,onChange:o,isReviewMode:n,wordBank:i}){const d=t.isPreFilled,c=n&&(d||a.toLowerCase()===t.correctAnswer?.toLowerCase()),m=n&&!d&&a&&a.toLowerCase()!==t.correctAnswer?.toLowerCase(),u=n&&!d&&!a;return r("div",{className:"flex items-center gap-3",children:[e("span",{className:"flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full text-sm font-bold text-white "+(d?"bg-green-500":"bg-blue-500"),children:t.number}),r("div",{className:"relative flex-1 rounded-lg border-2 "+(n?d||c?"border-green-500 bg-green-50":m?"border-red-500 bg-red-50":u?"border-blue-500 bg-blue-50":"border-gray-300":d?"border-gray-400 bg-gray-100":"border-gray-300 focus-within:border-blue-500"),children:[e("input",{type:"text",value:d||u?t.correctAnswer||"":a,onChange:e=>!n&&!d&&o(e.target.value),disabled:n||d,placeholder:"Type your answer...",className:"w-full rounded-lg bg-transparent px-3 py-2 text-sm outline-none disabled:cursor-default "+(d?"text-green-700 font-medium":u?"text-blue-600 font-medium":"text-gray-700"),list:`wordbank-${t.id}`}),e("datalist",{id:`wordbank-${t.id}`,children:i.map((r,t)=>e("option",{value:r},t))}),n&&c&&e("span",{className:"absolute right-2 top-1/2 -translate-y-1/2",children:e(s,{className:"h-5 w-5 text-green-500"})}),n&&m&&e("span",{className:"absolute right-2 top-1/2 -translate-y-1/2",children:e(l,{className:"h-5 w-5 text-red-500"})})]}),n&&!d&&(m||u)&&t.correctAnswer&&r("span",{className:"text-sm font-medium text-blue-600",children:["→ ",t.correctAnswer]})]})}export function MoversLabelThePictureRenderer({partNumber:t,partName:a,questionCount:o,instruction:s,imageUrl:l,wordBank:n,labels:p,answers:g,onAnswerChange:b,isReviewMode:h=!1}){const w=new Set(Object.values(g).filter(Boolean).map(e=>"string"==typeof e?e.toLowerCase():"").filter(Boolean)),f=n.map(e=>e.toLowerCase()),x=new Set([...w].filter(e=>f.includes(e)));return r("div",{className:"grid h-full grid-cols-1 gap-4 sm:gap-6 "+(h?"":"lg:grid-cols-2"),children:[r("div",{className:"flex flex-col gap-4 overflow-y-auto p-3 sm:pb-6 sm:pr-6 sm:pt-6 lg:pr-6",children:[e(i,{partNumber:t,questionCount:o,partName:a,isReviewMode:h}),e(d,{instruction:s,isReviewMode:h}),e(c,{imageUrl:l}),e(m,{words:n,usedWords:new Set(n.filter(e=>x.has(e.toLowerCase())))})]}),e("div",{className:"flex flex-col gap-4 overflow-y-auto p-3 sm:pb-6 sm:pl-2 sm:pt-6",children:r("div",{className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[e("p",{className:"mb-4 text-sm font-semibold text-gray-700",children:"Write the correct word for each number:"}),e("div",{className:"flex flex-col gap-4",children:p.map(r=>e(u,{label:r,value:g[r.id]||"",onChange:e=>b(r.id,e),isReviewMode:h,wordBank:n},r.id))})]})})]})}
@@ -0,0 +1,21 @@
1
+ import type { FillBlankQuestion } from '../../types';
2
+ interface MoversListenAndWriteRendererProps {
3
+ partNumber: number;
4
+ partName?: string;
5
+ questionCount: number;
6
+ instruction: string;
7
+ imageUrl?: string;
8
+ audioUrl?: string;
9
+ title: string;
10
+ exampleText?: string;
11
+ exampleHighlight?: string;
12
+ questions: FillBlankQuestion[];
13
+ answers: Record<string, string>;
14
+ onAnswerChange: (questionId: string, value: string) => void;
15
+ isReviewMode?: boolean;
16
+ showHints?: boolean;
17
+ groupContent?: string;
18
+ groupTitle?: string;
19
+ }
20
+ export declare function MoversListenAndWriteRenderer({ partNumber, partName, questionCount, instruction, imageUrl, audioUrl, title, exampleText, exampleHighlight, questions, answers, onAnswerChange, isReviewMode, showHints, groupContent, groupTitle, }: MoversListenAndWriteRendererProps): import("react").JSX.Element;
21
+ export {};
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import{ResolvedImage as r}from"../../../../../components/common/ResolvedImage";import a from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import l from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import s from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";import n from"../../../../../components/themes/cambridge-yle/CambridgeYleExampleText";export function MoversListenAndWriteRenderer({partNumber:o,partName:i,questionCount:c,instruction:m,imageUrl:d,audioUrl:p,title:x,exampleText:b,exampleHighlight:g,questions:h,answers:u,onAnswerChange:f,isReviewMode:N=!1,showHints:v=!1,groupContent:w,groupTitle:y}){const C=e=>{if(N){const t=h.find(t=>t.id===e),r=u[e]?.trim().toLowerCase(),a=t?.correctAnswer?.trim().toLowerCase();return r===a?"#22c55e":"#ef4444"}return"#9ca3af"},A=!!(p||d||w||b);return t("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-4",children:[e(a,{partNumber:o,questionCount:c,partName:i,isReviewMode:N}),e(l,{instruction:m,hasExample:!!b,isReviewMode:N})]}),A&&t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:[p&&e(s,{audioSrc:p,compact:!0}),t("div",{className:"max-h-[35vh] overflow-y-auto custom-scrollbar pr-2 flex flex-col gap-3",children:[d&&e("div",{className:"flex items-center justify-center",children:e(r,{src:d,alt:"Shared illustration",className:"max-h-[200px] rounded-lg object-contain shadow-md"})}),w&&t("div",{className:"rounded-lg bg-amber-50 p-3 text-sm leading-relaxed text-gray-700 shadow-inner",children:[y&&e("h3",{className:"mb-2 font-semibold text-gray-800",children:y}),w]})]}),b&&e(n,{text:b,highlightedWord:g||""})]}),t("div",{className:"flex flex-col gap-4 p-3 sm:gap-6 sm:pb-6 sm:px-6",children:[e("h2",{className:"text-center text-3xl font-bold uppercase text-coral-500",children:x}),e("div",{className:"flex flex-col gap-4",children:h.map(a=>{const l=a.isExample||!1,s=N||l,n=l&&a.correctAnswer?a.correctAnswer:u[a.id]||"";return t("div",{id:`question-${a.id}`,className:"flex flex-col gap-2 "+(l?"rounded-lg border-2 border-orange-200 bg-orange-50 p-2":""),children:[a.imageUrl&&e("div",{className:"flex items-center justify-center",children:e(r,{src:a.imageUrl,alt:`Question ${a.questionNumber} illustration`,className:"max-h-[150px] rounded-lg object-contain shadow-md"})}),t("div",{className:"flex items-baseline gap-2",children:[e("span",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full text-sm font-bold text-white "+(l?"bg-orange-400":"bg-blue-500"),children:a.questionNumber}),t("div",{className:"flex-1 text-base leading-relaxed text-gray-800",children:[a.textBefore&&e("span",{className:"mr-2",children:a.textBefore}),e("span",{className:"inline-block min-w-[120px]",style:{borderBottom:`2px solid ${l?"#fb923c":C(a.id)}`},children:e("input",{type:"text",value:n,onChange:e=>f(a.id,e.target.value),disabled:s,placeholder:"",className:"w-full bg-transparent text-center outline-none "+(l?"font-semibold text-orange-700 disabled:opacity-100":"disabled:opacity-60"),style:{border:"none",boxShadow:"none",appearance:"none",WebkitAppearance:"none"}})}),a.textAfter&&e("span",{className:"ml-2",children:a.textAfter}),l&&e("span",{className:"ml-2 rounded bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600",children:"Example"}),a.verbHint&&t("span",{className:"ml-2 italic text-gray-500",children:["(",a.verbHint,")"]}),v&&a.hints&&a.hints.length>0&&!N&&e("div",{className:"mt-2 flex flex-wrap gap-2",children:a.hints.map((t,r)=>e("button",{type:"button",onClick:()=>f(a.id,t),className:"rounded-full border border-blue-300 bg-blue-50 px-3 py-1 text-sm text-blue-700 transition-colors hover:bg-blue-100",children:t},r))}),N&&a.correctAnswer&&e("div",{className:"mt-1 text-sm",children:t("span",{className:"font-semibold text-green-600",children:["Đáp án đúng: ",a.correctAnswer]})})]})]})]},a.id)})})]})]})}
@@ -0,0 +1,19 @@
1
+ import type { MatchByWritingAnswerQuestion, MatchByWritingAnswerOption } from '../../utils/question-transformers';
2
+ interface MoversMatchByWritingAnswerRendererProps {
3
+ partNumber: number;
4
+ partName?: string;
5
+ questionCount: number;
6
+ instruction: string;
7
+ audioUrl?: string;
8
+ options: MatchByWritingAnswerOption[];
9
+ questions: MatchByWritingAnswerQuestion[];
10
+ answers: Record<string, string>;
11
+ onAnswerChange: (questionId: string, value: string) => void;
12
+ isReviewMode?: boolean;
13
+ viewMode?: 'DEFAULT' | 'CONVERSATION';
14
+ groupImageUrl?: string;
15
+ correctAnswerTextMap?: Record<string, string>;
16
+ isCorrectMap?: Record<string, boolean | null>;
17
+ }
18
+ export declare function MoversMatchByWritingAnswerRenderer({ partNumber, partName, questionCount, instruction, audioUrl, options, questions, answers, onAnswerChange, isReviewMode, viewMode, groupImageUrl, correctAnswerTextMap, isCorrectMap, }: MoversMatchByWritingAnswerRendererProps): import("react").JSX.Element;
19
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,Fragment as r,jsxs as t}from"react/jsx-runtime";import{Check as s,ChevronDown as a,X as n}from"lucide-react";import{ResolvedImage as i}from"../../../../../components/common/ResolvedImage";import o from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import l from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleAudioPlayer";function c({opt:s,isUsed:a}){const n=Boolean(s.imageUrl?.trim()),o=Boolean(s.content?.trim()),l=!n&&!o,d=o?s.content:s.answer;return l?e("div",{className:["group relative flex min-h-[56px] items-center rounded-xl border-2 px-4 py-3 shadow-sm transition-all duration-300",a?"border-emerald-400 bg-emerald-50/50 opacity-60 scale-[0.98] shadow-emerald-100/50":"border-slate-200 bg-white hover:border-indigo-300 hover:shadow-md hover:shadow-indigo-100/50"].join(" "),children:e("span",{className:"min-w-0 flex-1 text-sm font-semibold leading-snug break-words transition-colors "+(a?"text-emerald-700":"text-slate-700"),children:s.answer})}):t("div",{className:["group relative flex min-h-[180px] flex-col gap-3 rounded-2xl border-2 p-3 shadow-sm transition-all duration-300",a?"border-emerald-400 bg-emerald-50/40 opacity-60 scale-[0.98] shadow-emerald-100/50":"border-slate-200 bg-white/95 hover:-translate-y-1 hover:border-indigo-300 hover:shadow-lg hover:shadow-indigo-100/50"].join(" "),children:[s.answer!==d&&e("div",{className:"flex items-start justify-start gap-2",children:e("div",{className:"relative inline-flex min-h-[40px] min-w-[40px] items-center justify-center rounded-xl px-3 py-1.5 font-extrabold text-white shadow-sm transition-all duration-300 "+(a?"bg-gradient-to-br from-emerald-400 to-emerald-600":"bg-gradient-to-br from-indigo-500 to-violet-600"),children:e("span",{className:"text-sm text-center leading-tight break-words line-clamp-2",children:s.answer})})}),n?t(r,{children:[e("div",{className:"flex flex-1 items-center justify-center overflow-hidden rounded-xl border p-2 transition-all duration-300 "+(a?"border-emerald-200/50 bg-emerald-100/30 grayscale-[40%]":"border-slate-100 bg-gradient-to-br from-slate-50 to-white"),children:e(i,{src:s.imageUrl,alt:s.answer,className:"h-28 w-full rounded-xl object-contain sm:h-32"})}),e("div",{className:"min-w-0",children:e("div",{className:"truncate text-center text-sm font-semibold transition-colors "+(a?"text-emerald-700":"text-slate-700"),children:d||`Picture ${s.answer}`})})]}):e("div",{className:"flex flex-1 items-center justify-center rounded-xl border border-slate-100 bg-gradient-to-br from-slate-50 to-white px-4 py-5 text-center",children:e("span",{className:"text-sm font-semibold leading-snug "+(a?"text-emerald-700":"text-slate-700"),children:d})})]})}function m({value:r,onChange:s,disabled:n,options:i}){const o=r.trim().toUpperCase();return t("div",{className:"group relative min-w-[160px] sm:min-w-[210px]",children:[t("select",{value:o,onChange:e=>s(e.target.value),disabled:n,className:"h-[48px] w-full appearance-none rounded-2xl border border-slate-200 bg-white px-4 pr-11 text-sm font-semibold text-slate-700 shadow-sm outline-none transition-all duration-200 hover:border-indigo-300 focus:border-indigo-500 focus:ring-4 focus:ring-indigo-100/50 disabled:cursor-not-allowed disabled:opacity-60","aria-label":"Chọn đáp án đúng",children:[e("option",{value:"",children:"Chọn đáp án"}),i.map(r=>e("option",{value:r.answer.toUpperCase(),children:r.content||r.answer},r.answer))]}),e("div",{className:"pointer-events-none absolute right-2.5 top-1/2 flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded-full bg-slate-100 text-slate-500 transition-colors group-focus-within:bg-indigo-100 group-focus-within:text-indigo-600",children:e(a,{className:"h-3.5 w-3.5",strokeWidth:2.5})})]})}function p({question:r,rawAnswer:s,displayValue:a,isDisabled:n,isExampleQ:o,onAnswerChange:l,isReviewMode:d,correctAnswer:c,answerStatus:p,options:u}){return t("div",{className:["group relative overflow-hidden rounded-[14px] border p-4 shadow-sm transition-all duration-200 flex flex-col gap-4",o?"border-amber-200 bg-gradient-to-br from-amber-50 to-orange-50/50 shadow-amber-100/40":"border-slate-200/80 bg-white hover:-translate-y-0.5 hover:border-indigo-200 hover:shadow-md hover:shadow-indigo-100/50"].join(" "),children:[t("div",{className:"flex items-start gap-4",children:[e("span",{className:"flex h-[38px] w-[38px] shrink-0 items-center justify-center rounded-[10px] text-[15px] font-extrabold text-white shadow-sm "+(o?"bg-gradient-to-br from-amber-400 to-orange-500":"bg-gradient-to-br from-indigo-500 to-violet-600"),children:r.questionNumber}),t("div",{className:"flex flex-1 flex-col gap-2 pt-1",children:[o&&e("span",{className:"w-fit rounded-full border border-amber-300 bg-amber-100 px-2.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-amber-700",children:"Example"}),e("div",{className:"text-[15px] font-medium leading-relaxed text-slate-800 break-words",children:r.question})]})]}),r.imageUrl&&e("div",{className:"flex w-full justify-center",children:e(i,{src:r.imageUrl,alt:`Q${r.questionNumber}`,className:"h-30 w-auto min-w-[5rem] rounded-xl border border-slate-100 bg-slate-50 object-contain p-1.5 shadow-sm sm:h-30"})}),e("div",{className:"mt-1 flex w-full items-center justify-end border-t border-slate-100/80 pt-3",children:d&&!o?e(h,{userAnswer:a,correctAnswer:c,status:p??"unanswered"}):e("div",{className:"w-full sm:w-auto",children:e(m,{value:s,onChange:e=>l(r.id,e),disabled:n,options:u})})})]})}function h({userAnswer:a,correctAnswer:i,status:o}){return t("div",{className:`flex w-full sm:w-auto items-center justify-center gap-2 rounded-xl border px-5 py-2 text-[15px] shadow-sm transition-colors ${"correct"===o?"border-emerald-200 bg-emerald-50 text-emerald-700":"incorrect"===o?"border-red-200 bg-red-50 text-red-700":"border-slate-200 bg-slate-50 text-slate-700"}`,children:["correct"===o&&t(r,{children:[e(s,{className:"h-4 w-4 shrink-0",strokeWidth:3}),e("span",{className:"font-medium opacity-90",children:"Đáp án:"}),e("span",{className:"ml-1 rounded-md bg-white px-2.5 py-0.5 border border-emerald-100 font-bold shadow-sm",children:a||"Trống"})]}),"unanswered"===o&&t("div",{className:"flex items-center gap-2",children:[e("span",{className:"font-medium opacity-80",children:"Đáp án:"}),e("span",{className:"rounded-md bg-white px-2.5 py-0.5 border border-slate-200 font-bold shadow-sm",children:i})]}),"incorrect"===o&&t("div",{className:"flex items-center gap-2",children:[e(n,{className:"h-4 w-4 shrink-0",strokeWidth:3}),e("span",{className:"font-medium opacity-90",children:"Đáp án:"}),e("span",{className:"line-through decoration-red-400/80 decoration-2 rounded-md bg-white/60 px-2 py-0.5 border border-red-100/50 font-semibold opacity-70",children:a||"Trống"}),e("span",{className:"text-red-400 font-bold",children:"→"}),e("span",{className:"rounded-md bg-white px-2.5 py-0.5 border border-red-200 font-bold shadow-sm",children:i})]})]})}export function MoversMatchByWritingAnswerRenderer({partNumber:a,partName:m,questionCount:h,instruction:u,audioUrl:x,options:g,questions:b,answers:w,onAnswerChange:f,isReviewMode:v=!1,viewMode:N="DEFAULT",groupImageUrl:y,correctAnswerTextMap:C={},isCorrectMap:j={}}){const A=e=>{if(!w[e])return"unanswered";const r=j[e];return!0===r?"correct":!1===r?"incorrect":"unanswered"},k=e=>{if(!e)return"";const r=e.trim().toUpperCase(),t=g.find(e=>e.answer.toUpperCase()===r);return t?t.content||t.answer:e};if("CONVERSATION"===N)return t("div",{className:"flex h-full flex-col gap-4 overflow-y-auto p-3 sm:gap-6 sm:p-6",children:[e(o,{partNumber:a,questionCount:h,partName:m,isReviewMode:v}),e(l,{instruction:u,isReviewMode:v}),x&&e("div",{className:"shrink-0",children:e(d,{audioSrc:x,compact:!0})}),y&&e(i,{src:y,alt:"Group illustration",className:"max-h-[200px] rounded-lg object-contain shadow-md"}),g.length>0&&e("div",{className:"grid grid-cols-2 gap-2 rounded-xl border border-slate-200 bg-slate-50 p-3 sm:grid-cols-4",children:g.map((r,s)=>t("div",{className:"flex items-center gap-2 rounded-lg border border-slate-200 bg-white p-2",children:[e("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-indigo-500 to-violet-600 text-xs font-bold text-white",children:r.answer}),e("span",{className:"flex-1 text-sm text-slate-700",children:r.content||r.answer})]},s))}),e("div",{className:"flex flex-col gap-3",children:b.filter(e=>!e.isExample).map(a=>{const i=A(a.id),o=w[a.id]||"",l=k(o),d=C[a.id];return t("div",{id:`question-${a.id}`,className:"flex flex-col gap-2",children:[t("div",{className:"flex items-start gap-2",children:[t("span",{className:"w-12 shrink-0 text-xs font-semibold text-slate-500",children:[a.askerName,":"]}),e("div",{className:"max-w-[80%] rounded-2xl rounded-tl-none bg-slate-100 px-4 py-2 text-sm text-slate-800",children:a.question})]}),e("div",{className:"flex items-center justify-end gap-2",children:t("div",{className:"flex max-w-[80%] items-center gap-2 rounded-2xl rounded-tr-none border border-indigo-200 bg-indigo-50 px-4 py-2",children:[t("span",{className:"shrink-0 text-xs font-semibold text-indigo-600",children:[a.answererName,":"]}),v?t("span",{className:"flex items-center gap-1 text-sm font-bold",children:["correct"===i&&e("span",{className:"text-slate-800",children:l}),"unanswered"===i&&e("span",{className:"text-indigo-600",children:d}),"incorrect"===i&&t(r,{children:[e("span",{className:"text-red-500 line-through",children:l}),e("span",{className:"text-slate-400",children:"→"}),e("span",{className:"text-indigo-600",children:d})]}),e("div",{className:"flex h-5 w-5 items-center justify-center rounded-full text-white "+("correct"===i?"bg-emerald-500":"incorrect"===i?"bg-red-500":"bg-indigo-500"),children:e("incorrect"===i?n:s,{className:"h-3 w-3",strokeWidth:3})})]}):t("select",{value:o.trim().toUpperCase(),onChange:e=>f(a.id,e.target.value),disabled:v,className:"min-w-[140px] rounded-lg border border-indigo-300 bg-white px-3 py-2 text-sm font-bold text-slate-700 outline-none focus:border-indigo-500",children:[e("option",{value:"",children:"Chọn đáp án"}),g.map(r=>e("option",{value:r.answer.toUpperCase(),children:r.content||r.answer},r.answer))]})]})})]},a.id)})})]});const U=new Set(Object.values(w).filter(e=>"string"==typeof e&&Boolean(e)).map(e=>e.trim().toUpperCase()));b.forEach(e=>{e.isExample&&e.exampleAnswer&&U.add(e.exampleAnswer.trim().toUpperCase())});const q=b.filter(e=>e.isExample),M=b.filter(e=>!e.isExample);return t("div",{className:"flex flex-col h-full gap-5 sm:gap-6 overflow-y-auto custom-scrollbar",children:[t("div",{className:"flex flex-col gap-4 sm:gap-5 p-3 sm:px-6 sm:pt-2",children:[e(o,{partNumber:a,questionCount:h,partName:m,isReviewMode:v}),e(l,{instruction:u,isReviewMode:v}),x&&e("div",{className:"shrink-0",children:e(d,{audioSrc:x,compact:!0})}),y&&e("div",{className:"flex items-center justify-center rounded-2xl border border-slate-200/80 bg-white p-3 shadow-sm",children:e(i,{src:y,alt:"Group illustration",className:"max-h-[300px] rounded-xl object-contain shadow-md"})}),g.length>0&&t("div",{className:"rounded-[20px] border border-slate-200/80 bg-gradient-to-br from-white via-white to-slate-50 p-4 sm:p-5 shadow-lg shadow-slate-100/70",children:[e("div",{className:"mb-4 flex items-center justify-between gap-3",children:e("div",{children:e("h3",{className:"text-sm font-bold uppercase tracking-[0.18em] text-slate-500",children:"Answer bank"})})}),e("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4",children:g.map((r,t)=>e(c,{opt:r,isUsed:U.has(r.answer.toUpperCase())},t))})]}),q.length>0&&e("div",{className:"flex flex-col gap-4 mt-2",children:q.map(r=>{const t=w[r.id]||"",s=r.exampleAnswer||k(t);return e("div",{id:`question-${r.id}`,className:"w-full",children:e(p,{question:r,rawAnswer:t,displayValue:s,isDisabled:!0,isExampleQ:!0,onAnswerChange:f,isReviewMode:v,correctAnswer:C[r.id],answerStatus:void 0,options:g})},r.id)})})]}),q.length>0&&M.length>0&&e("div",{className:"px-3 sm:px-6",children:e("hr",{className:"border-t border-slate-200/60 my-2"})}),e("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-5 p-3 sm:px-6 sm:pb-6",children:M.map(r=>{const t=v,s=w[r.id]||"",a=k(s);return e("div",{id:`question-${r.id}`,className:"w-full",children:e(p,{question:r,rawAnswer:s,displayValue:a,isDisabled:t,isExampleQ:!1,onAnswerChange:f,isReviewMode:v,correctAnswer:C[r.id],answerStatus:v?A(r.id):void 0,options:g})},r.id)})})]})}
@@ -0,0 +1,2 @@
1
+ import type { MoversPictureChooseRendererProps } from '../../types';
2
+ export declare function MoversPictureChooseRenderer({ partNumber, partName, questionCount, instruction, subQuestions, answers, onAnswerChange, isReviewMode, }: MoversPictureChooseRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useState as o}from"react";import{ZoomIn as i,Check as n,X as s}from"lucide-react";import{ResolvedImage as l}from"../../../../../components/common/ResolvedImage";import d from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import a from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function c({imageUrl:n,alt:s}){const[d,a]=o(!1);return r(t,{children:[r("div",{className:"relative flex items-center justify-center",children:[e(l,{src:n,alt:s,className:"max-h-[180px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>a(!0)}),e("button",{type:"button",onClick:()=>a(!0),className:"absolute right-2 top-2 rounded-full bg-white/80 p-1.5 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(i,{className:"h-4 w-4 text-gray-600"})})]}),d&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>a(!1),children:e(l,{src:n,alt:`${s} (zoomed)`,className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function m({subQuestion:t,selectedOptionId:o,onSelect:i,isReviewMode:l,id:d}){const a=l&&o===t.correctOptionId,m=e=>{if(!l)return o===e?"border-blue-500 bg-[#f4f9ff]":"border-blue-200 bg-white hover:border-blue-300 hover:bg-blue-50/30";const r=o===e,i=t.correctOptionId===e;return i?a?"border-green-500 bg-green-50":"border-blue-500 bg-blue-50":r&&!i?"border-red-500 bg-red-50":"border-blue-200 bg-white"},u=e=>{if(!l)return o===e?"border-blue-500 bg-blue-500":"border-gray-300 bg-white";const r=o===e,i=t.correctOptionId===e;return i?a?"border-green-500 bg-green-500":"border-blue-500 bg-blue-500":r&&!i?"border-red-500 bg-red-500":"border-gray-300 bg-white"},b=r=>{if(!l)return null;const i=o===r,d=t.correctOptionId===r;return d?e(n,{className:"h-4 w-4 text-white"}):i&&!d?e(s,{className:"h-4 w-4 text-white"}):null};return r("div",{id:d,className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[r("div",{className:"mb-3 flex items-start gap-3",children:[e("span",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-blue-500 text-sm font-bold text-white",children:t.questionNumber}),e(c,{imageUrl:t.imageUrl,alt:`Question ${t.questionNumber}`})]}),t.questionText&&e("p",{className:"mb-3 text-[17px] font-bold text-[#001590]",children:t.questionText}),e("div",{className:"flex flex-col gap-2",children:t.options.map(t=>r("button",{type:"button",onClick:()=>!l&&i(t.id),disabled:l,className:`flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors ${m(t.id)} ${l?"cursor-default":"cursor-pointer"}`,children:[r("span",{className:"text-sm font-medium text-gray-600",children:[t.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:t.text}),e("div",{className:`flex h-5 w-5 items-center justify-center rounded-full border-2 ${u(t.id)}`,children:l?b(t.id):o===t.id&&e("div",{className:"h-2 w-2 rounded-full bg-white"})})]},t.id))})]})}export function MoversPictureChooseRenderer({partNumber:t,partName:o,questionCount:i,instruction:n,subQuestions:s,answers:l,onAnswerChange:c,isReviewMode:u=!1}){return r("div",{className:"flex h-full flex-col gap-4 overflow-y-auto p-6",children:[r("div",{className:"flex flex-col gap-4",children:[e(d,{partNumber:t,questionCount:i,partName:o,isReviewMode:u}),e(a,{instruction:n,isReviewMode:u})]}),e("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2",children:s.map(r=>e(m,{id:`question-${r.id}`,subQuestion:r,selectedOptionId:l[r.id],onSelect:e=>c(r.id,e),isReviewMode:u},r.id))})]})}
@@ -0,0 +1,2 @@
1
+ import type { MoversPictureFillBlankChooseRendererProps } from '../../types';
2
+ export declare function MoversPictureFillBlankChooseRenderer({ partNumber, partName, questionCount, instruction, subQuestions, answers, onAnswerChange, isReviewMode, }: MoversPictureFillBlankChooseRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useState as o}from"react";import{ZoomIn as i}from"lucide-react";import{ResolvedImage as n}from"../../../../../components/common/ResolvedImage";import s from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function l({imageUrl:s,alt:d}){const[l,a]=o(!1);return r(t,{children:[r("div",{className:"relative flex items-center justify-center",children:[e(n,{src:s,alt:d,className:"max-h-[150px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>a(!0)}),e("button",{type:"button",onClick:()=>a(!0),className:"absolute right-1 top-1 rounded-full bg-white/80 p-1 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(i,{className:"h-3 w-3 text-gray-600"})})]}),l&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>a(!1),children:e(n,{src:s,alt:`${d} (zoomed)`,className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function a({question:t,selectedAnswer:o,isReviewMode:i,isCorrect:n}){const s=t.split("{0}");return r("p",{className:"text-sm font-medium text-gray-700",children:[s[0],e("span",{className:"mx-1 inline-block min-w-[60px] border-b-2 border-dashed px-2 text-center font-semibold "+(i&&o?n?"border-green-500 text-green-600":"border-red-500 text-red-600":"border-blue-400 text-blue-600"),children:o||"______"}),s[1]]})}function c({subQuestion:t,selectedOptionId:o,onSelect:i,isReviewMode:n,id:s}){const d=t.options.find(e=>e.id===o),c=n&&o===t.correctOptionId,m=e=>{if(!n)return o===e?"border-blue-500 bg-blue-50":"border-gray-300 bg-white hover:border-blue-300";const r=o===e,i=t.correctOptionId===e;return i?c?"border-green-500 bg-green-50":"border-blue-500 bg-blue-50":r&&!i?"border-red-500 bg-red-50":"border-gray-300 bg-white"},u=e=>{if(!n)return"text-gray-700";const r=o===e;return t.correctOptionId===e||r?"text-gray-800 font-bold":"text-gray-600"};return r("div",{id:s,className:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm",children:[r("div",{className:"mb-3 flex items-start gap-3",children:[e("span",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-blue-500 text-sm font-bold text-white",children:t.questionNumber}),e(l,{imageUrl:t.imageUrl,alt:`Question ${t.questionNumber}`})]}),e("div",{className:"mb-3",children:e(a,{question:t.question,selectedAnswer:d?.text,isReviewMode:n,isCorrect:o===t.correctOptionId})}),e("div",{className:"flex flex-wrap gap-2",children:t.options.map(e=>r("button",{type:"button",onClick:()=>!n&&i(e.id),disabled:n,className:`rounded-lg border-2 px-3 py-1.5 text-sm transition-colors ${m(e.id)} ${u(e.id)} ${n?"cursor-default":"cursor-pointer"}`,children:[e.label,". ",e.text]},e.id))})]})}export function MoversPictureFillBlankChooseRenderer({partNumber:t,partName:o,questionCount:i,instruction:n,subQuestions:l,answers:a,onAnswerChange:m,isReviewMode:u=!1}){return r("div",{className:"flex h-full flex-col gap-4 overflow-y-auto p-6",children:[r("div",{className:"flex flex-col gap-4",children:[e(s,{partNumber:t,questionCount:i,partName:o,isReviewMode:u}),e(d,{instruction:n,isReviewMode:u})]}),e("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2",children:l.map(r=>e(c,{id:`question-${r.id}`,subQuestion:r,selectedOptionId:a[r.id],onSelect:e=>m(r.id,e),isReviewMode:u},r.id))})]})}
@@ -0,0 +1,2 @@
1
+ import type { MoversReadingPassageRendererProps } from '../../types';
2
+ export declare function MoversReadingPassageRenderer({ partNumber, partName, questionCount, instruction, passageTitle, passage, passageImageUrl, questions, answers, onAnswerChange, isReviewMode, correctOptionIdMap, }: MoversReadingPassageRendererProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useState as s}from"react";import{Check as a,X as i,ZoomIn as l}from"lucide-react";import{ResolvedImage as o}from"../../../../../components/common/ResolvedImage";import n from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";function c({imageUrl:a}){const[i,n]=s(!1);return r(t,{children:[r("div",{className:"relative flex items-center justify-center",children:[e(o,{src:a,alt:"Passage illustration",className:"max-h-[200px] cursor-pointer rounded-lg object-contain shadow-md",onClick:()=>n(!0)}),e("button",{type:"button",onClick:()=>n(!0),className:"absolute right-2 top-2 rounded-full bg-white/80 p-1.5 shadow-md hover:bg-white","aria-label":"Zoom image",children:e(l,{className:"h-4 w-4 text-gray-600"})})]}),i&&e("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70",onClick:()=>n(!1),children:e(o,{src:a,alt:"Passage illustration (zoomed)",className:"max-h-[90vh] max-w-[90vw] rounded-lg object-contain",showLoadingState:!1})})]})}function m({title:t,passage:s,imageUrl:a}){return r("div",{className:"rounded-lg border-2 border-amber-200 bg-amber-50 p-4",children:[t&&e("h3",{className:"mb-3 text-center text-lg font-bold text-amber-800",children:t}),a&&e("div",{className:"mb-3",children:e(c,{imageUrl:a})}),e("div",{className:"prose prose-sm max-w-none text-gray-700",children:s.split("\n").map((r,t)=>e("p",{className:"mb-2 last:mb-0",children:r},t))})]})}function u({question:t,selectedOptionId:s,onSelect:l,isReviewMode:o,correctOptionId:n,id:d}){const c=n||t.correctOptionId,m=!!s,u=s===c,b=e=>{if(!o)return s===e?"border-blue-500 bg-blue-50":"border-gray-300 bg-white hover:border-blue-300";const r=s===e;return r&&u?"border-green-500 bg-green-50":r&&!u?"border-red-500 bg-red-50":!(c===e)||u&&m?"border-gray-300 bg-white":"border-blue-500 bg-blue-50"};return r("div",{id:d,className:"mb-4",children:[r("p",{className:"mb-2 text-base font-semibold text-gray-800",children:[t.questionNumber,". ",t.questionText]}),e("div",{className:"flex flex-col gap-2 pl-2",children:t.options.map(t=>{const n=s===t.id,d=c===t.id,p=o&&n&&u,g=o&&n&&!u,h=o&&d&&(!u||!m);return r("button",{type:"button",onClick:()=>!o&&l(t.id),disabled:o,className:`flex items-center gap-3 rounded-lg border-2 px-3 py-2 text-left transition-colors ${b(t.id)} ${o?"cursor-default":"cursor-pointer"}`,children:[r("span",{className:"text-sm font-medium text-gray-600",children:[t.label,"."]}),e("span",{className:"flex-1 text-sm text-gray-700",children:t.text}),p&&e("div",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-green-500",children:e(a,{className:"h-4 w-4 text-white",strokeWidth:3})}),g&&e("div",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-red-500",children:e(i,{className:"h-4 w-4 text-white",strokeWidth:3})}),h&&e("div",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-blue-500",children:e(a,{className:"h-4 w-4 text-white",strokeWidth:3})}),!o&&e("div",{className:"flex h-5 w-5 items-center justify-center rounded-full border-2 "+(n?"border-blue-500 bg-blue-500":"border-gray-300 bg-white"),children:n&&e("div",{className:"h-2 w-2 rounded-full bg-white"})}),o&&!p&&!g&&!h&&e("div",{className:"flex h-5 w-5 items-center justify-center rounded-full border-2 border-gray-300 bg-white"})]},t.id)})})]})}export function MoversReadingPassageRenderer({partNumber:t,partName:s,questionCount:a,instruction:i,passageTitle:l,passage:o,passageImageUrl:c,questions:b,answers:p,onAnswerChange:g,isReviewMode:h=!1,correctOptionIdMap:f}){return r("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[r("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-4",children:[e(n,{partNumber:t,questionCount:a,partName:s,isReviewMode:h}),e(d,{instruction:i,isReviewMode:h})]}),e("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:e("div",{className:"max-h-[35vh] overflow-y-auto custom-scrollbar pr-2",children:e(m,{title:l,passage:o,imageUrl:c})})}),e("div",{className:"flex flex-col gap-4 p-3 sm:pb-6 sm:px-6",children:b.map(r=>e(u,{id:`question-${r.id}`,question:r,selectedOptionId:p[r.id],onSelect:e=>g(r.id,e),isReviewMode:h,correctOptionId:f?.[r.id]},r.id))})]})}