@intellectif/lk-react 16.0.0 → 16.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +3 -3
  3. package/dist/{WrittenResponse-C2zw-1jK.d.cts → WrittenResponse-6tSj6U3G.d.cts} +1 -1
  4. package/dist/{WrittenResponse-CTiNpSCC.d.ts → WrittenResponse-xJ7I_5yq.d.ts} +1 -1
  5. package/dist/{chunk-P5FGJMMI.cjs → chunk-2S3MK4VX.cjs} +5 -5
  6. package/dist/{chunk-P5FGJMMI.cjs.map → chunk-2S3MK4VX.cjs.map} +1 -1
  7. package/dist/{chunk-ZA5QUQ2V.cjs → chunk-2TFNDHJ5.cjs} +13 -13
  8. package/dist/{chunk-ZA5QUQ2V.cjs.map → chunk-2TFNDHJ5.cjs.map} +1 -1
  9. package/dist/{chunk-AEUP63CZ.js → chunk-2XNCPLHU.js} +5 -5
  10. package/dist/{chunk-AEUP63CZ.js.map → chunk-2XNCPLHU.js.map} +1 -1
  11. package/dist/{chunk-4X7NFEDB.js → chunk-3UXRX4KU.js} +5 -5
  12. package/dist/{chunk-4X7NFEDB.js.map → chunk-3UXRX4KU.js.map} +1 -1
  13. package/dist/{chunk-UYRQEIB7.js → chunk-5QHVYOME.js} +5 -5
  14. package/dist/{chunk-UYRQEIB7.js.map → chunk-5QHVYOME.js.map} +1 -1
  15. package/dist/{chunk-RJGCT35F.cjs → chunk-B6S5ADHR.cjs} +13 -13
  16. package/dist/{chunk-RJGCT35F.cjs.map → chunk-B6S5ADHR.cjs.map} +1 -1
  17. package/dist/{chunk-HJLVWZOM.js → chunk-BI547RIA.js} +4 -4
  18. package/dist/{chunk-HJLVWZOM.js.map → chunk-BI547RIA.js.map} +1 -1
  19. package/dist/{chunk-BO64SLHL.cjs → chunk-DFMBVA7D.cjs} +8 -8
  20. package/dist/{chunk-BO64SLHL.cjs.map → chunk-DFMBVA7D.cjs.map} +1 -1
  21. package/dist/{chunk-ICAYWVNF.js → chunk-DKZWUIQD.js} +3 -3
  22. package/dist/{chunk-ICAYWVNF.js.map → chunk-DKZWUIQD.js.map} +1 -1
  23. package/dist/{chunk-3IHVDQRC.js → chunk-DVOPHC2Q.js} +275 -74
  24. package/dist/chunk-DVOPHC2Q.js.map +1 -0
  25. package/dist/{chunk-ALDGRDYD.cjs → chunk-FZWWVJE4.cjs} +24 -24
  26. package/dist/{chunk-ALDGRDYD.cjs.map → chunk-FZWWVJE4.cjs.map} +1 -1
  27. package/dist/{chunk-OOYKKO3V.js → chunk-GDMM2WEG.js} +11 -11
  28. package/dist/{chunk-OOYKKO3V.js.map → chunk-GDMM2WEG.js.map} +1 -1
  29. package/dist/{chunk-W32ND3ZR.js → chunk-GUPBIEUA.js} +6 -6
  30. package/dist/{chunk-W32ND3ZR.js.map → chunk-GUPBIEUA.js.map} +1 -1
  31. package/dist/{chunk-T33AJYLW.js → chunk-IQI5I2X5.js} +5 -5
  32. package/dist/{chunk-T33AJYLW.js.map → chunk-IQI5I2X5.js.map} +1 -1
  33. package/dist/{chunk-NOF6HJDV.js → chunk-JPDR6TTA.js} +4 -4
  34. package/dist/{chunk-NOF6HJDV.js.map → chunk-JPDR6TTA.js.map} +1 -1
  35. package/dist/{chunk-QIA5FAAW.js → chunk-KSAINXRG.js} +3 -2
  36. package/dist/chunk-KSAINXRG.js.map +1 -0
  37. package/dist/{chunk-2WM2KSO7.cjs → chunk-ML6L4LJH.cjs} +25 -25
  38. package/dist/{chunk-2WM2KSO7.cjs.map → chunk-ML6L4LJH.cjs.map} +1 -1
  39. package/dist/{chunk-UISZWFI7.cjs → chunk-MQAZJQRE.cjs} +3 -2
  40. package/dist/chunk-MQAZJQRE.cjs.map +1 -0
  41. package/dist/{chunk-QADR2XMQ.cjs → chunk-OO24JGYH.cjs} +18 -18
  42. package/dist/{chunk-QADR2XMQ.cjs.map → chunk-OO24JGYH.cjs.map} +1 -1
  43. package/dist/{chunk-JYC2VV3Y.cjs → chunk-PTJTC6A3.cjs} +12 -12
  44. package/dist/{chunk-JYC2VV3Y.cjs.map → chunk-PTJTC6A3.cjs.map} +1 -1
  45. package/dist/{chunk-WGIMLXRW.cjs → chunk-PXGJHZKJ.cjs} +6 -6
  46. package/dist/{chunk-WGIMLXRW.cjs.map → chunk-PXGJHZKJ.cjs.map} +1 -1
  47. package/dist/{chunk-2YZZL5FV.cjs → chunk-RSQFGF5W.cjs} +13 -13
  48. package/dist/{chunk-2YZZL5FV.cjs.map → chunk-RSQFGF5W.cjs.map} +1 -1
  49. package/dist/{chunk-OXUUE3HX.cjs → chunk-TRP5Z3XW.cjs} +5 -5
  50. package/dist/{chunk-OXUUE3HX.cjs.map → chunk-TRP5Z3XW.cjs.map} +1 -1
  51. package/dist/{chunk-4AQ4SWJ3.js → chunk-VC2MPB2Y.js} +5 -5
  52. package/dist/{chunk-4AQ4SWJ3.js.map → chunk-VC2MPB2Y.js.map} +1 -1
  53. package/dist/{chunk-A2CPCOJA.cjs → chunk-WOYCT5M6.cjs} +284 -83
  54. package/dist/chunk-WOYCT5M6.cjs.map +1 -0
  55. package/dist/{chunk-WBLRUJ77.js → chunk-ZEDMFTKD.js} +10 -10
  56. package/dist/{chunk-WBLRUJ77.js.map → chunk-ZEDMFTKD.js.map} +1 -1
  57. package/dist/{chunk-UIGSH2XB.js → chunk-ZPCO3CEB.js} +3 -3
  58. package/dist/{chunk-UIGSH2XB.js.map → chunk-ZPCO3CEB.js.map} +1 -1
  59. package/dist/{chunk-DMCFARGP.cjs → chunk-ZSY4VANQ.cjs} +13 -13
  60. package/dist/{chunk-DMCFARGP.cjs.map → chunk-ZSY4VANQ.cjs.map} +1 -1
  61. package/dist/components/ActivityPreview.cjs +12 -12
  62. package/dist/components/ActivityPreview.d.cts +2 -2
  63. package/dist/components/ActivityPreview.d.ts +2 -2
  64. package/dist/components/ActivityPreview.js +11 -11
  65. package/dist/components/ActivitySequence.cjs +13 -13
  66. package/dist/components/ActivitySequence.d.cts +2 -2
  67. package/dist/components/ActivitySequence.d.ts +2 -2
  68. package/dist/components/ActivitySequence.js +12 -12
  69. package/dist/components/Dictation.cjs +5 -5
  70. package/dist/components/Dictation.d.cts +1 -1
  71. package/dist/components/Dictation.d.ts +1 -1
  72. package/dist/components/Dictation.js +4 -4
  73. package/dist/components/FillInTheBlanks.cjs +5 -5
  74. package/dist/components/FillInTheBlanks.d.cts +1 -1
  75. package/dist/components/FillInTheBlanks.d.ts +1 -1
  76. package/dist/components/FillInTheBlanks.js +4 -4
  77. package/dist/components/GapSelect.cjs +5 -5
  78. package/dist/components/GapSelect.d.cts +1 -1
  79. package/dist/components/GapSelect.d.ts +1 -1
  80. package/dist/components/GapSelect.js +4 -4
  81. package/dist/components/InteractiveVideo.cjs +12 -12
  82. package/dist/components/InteractiveVideo.d.cts +117 -6
  83. package/dist/components/InteractiveVideo.d.ts +117 -6
  84. package/dist/components/InteractiveVideo.js +10 -10
  85. package/dist/components/MultipleChoice.cjs +5 -5
  86. package/dist/components/MultipleChoice.d.cts +1 -1
  87. package/dist/components/MultipleChoice.d.ts +1 -1
  88. package/dist/components/MultipleChoice.js +4 -4
  89. package/dist/components/PronunciationFeedback.cjs +4 -4
  90. package/dist/components/PronunciationFeedback.d.cts +1 -1
  91. package/dist/components/PronunciationFeedback.d.ts +1 -1
  92. package/dist/components/PronunciationFeedback.js +3 -3
  93. package/dist/components/ReadAloud.cjs +6 -6
  94. package/dist/components/ReadAloud.d.cts +2 -2
  95. package/dist/components/ReadAloud.d.ts +2 -2
  96. package/dist/components/ReadAloud.js +5 -5
  97. package/dist/components/StimulusPanel.cjs +4 -4
  98. package/dist/components/StimulusPanel.d.cts +1 -1
  99. package/dist/components/StimulusPanel.d.ts +1 -1
  100. package/dist/components/StimulusPanel.js +3 -3
  101. package/dist/components/WrittenResponse.cjs +5 -5
  102. package/dist/components/WrittenResponse.d.cts +3 -3
  103. package/dist/components/WrittenResponse.d.ts +3 -3
  104. package/dist/components/WrittenResponse.js +4 -4
  105. package/dist/i18n/LkIntlProvider.cjs +7 -7
  106. package/dist/i18n/LkIntlProvider.d.cts +2 -2
  107. package/dist/i18n/LkIntlProvider.d.ts +2 -2
  108. package/dist/i18n/LkIntlProvider.js +1 -1
  109. package/dist/index.cjs +32 -32
  110. package/dist/index.d.cts +3 -3
  111. package/dist/index.d.ts +3 -3
  112. package/dist/index.js +14 -14
  113. package/dist/{strings-zY2QQYpU.d.cts → strings-C6wM5aUQ.d.cts} +2 -0
  114. package/dist/{strings-Dgc5-DeA.d.ts → strings-Cd_2F-Bw.d.ts} +2 -0
  115. package/dist/theme/skin.css +16 -0
  116. package/package.json +1 -1
  117. package/dist/chunk-3IHVDQRC.js.map +0 -1
  118. package/dist/chunk-A2CPCOJA.cjs.map +0 -1
  119. package/dist/chunk-QIA5FAAW.js.map +0 -1
  120. package/dist/chunk-UISZWFI7.cjs.map +0 -1
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ItemGroup, MediaProgress, LearnerResponse, ItemOutcome, ActivityResult, InteractionEvent, SpeechAssessment, MediaTrack, ThemeTokens } from '@intellectif/lk-core';
3
- import { g as RenderableActivity, e as RenderMode, i as SequenceRecordingSlot, h as SequenceRecordingBinding, V as VideoPreferences, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-zY2QQYpU.cjs';
4
- export { C as CaptionSize } from '../strings-zY2QQYpU.cjs';
2
+ import { ItemGroup, MediaProgress, LearnerResponse, ItemOutcome, ActivityResult, InteractionEvent, InteractionKind, SpeechAssessment, MediaTrack, ThemeTokens } from '@intellectif/lk-core';
3
+ import { ReactNode } from 'react';
4
+ import { g as RenderableActivity, e as RenderMode, i as SequenceRecordingSlot, h as SequenceRecordingBinding, V as VideoPreferences, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-C6wM5aUQ.cjs';
5
+ export { C as CaptionSize } from '../strings-C6wM5aUQ.cjs';
5
6
  import '../machine-CuwKqWXC.cjs';
6
7
 
7
8
  /** An item group whose items may be `redact()` projections: the client's view of an interactive video. */
@@ -19,6 +20,87 @@ interface InteractiveVideoSummary {
19
20
  status: 'answered' | 'skipped' | 'unreached';
20
21
  }[];
21
22
  }
23
+ /**
24
+ * One question, as `renderQuestion` is handed it: what to draw, and the six
25
+ * calls through which the video learns what the learner did.
26
+ *
27
+ * The calls are the ones the SDK's own components make, so a question the host
28
+ * draws counts exactly as one the SDK draws — in the step dots, in whether a
29
+ * required quiz lets the learner go on, on the end card and in `onFinished`.
30
+ * Each keeps ONE identity per question for the life of the player, so it is
31
+ * safe in an effect's dependencies, and each does nothing once the player has
32
+ * unmounted.
33
+ */
34
+ interface InteractiveVideoQuestion {
35
+ /** The question, as the SDK would have rendered it: full data, or a `redact()` projection. */
36
+ activity: RenderableActivity;
37
+ /** Where it sits: the same object `onSubmit` and `onActivityComplete` are handed, for the life of the player. */
38
+ slot: InteractiveVideoSlot;
39
+ /**
40
+ * Passed through untouched. The SDK cannot enforce a mode for pixels it does
41
+ * not draw: in `exam` the host must not reveal correctness, and in `review`
42
+ * nothing is submittable — `submit`, `complete` and `clear` are ignored there.
43
+ */
44
+ renderMode: RenderMode;
45
+ /**
46
+ * `true` while this question is the one on screen: its quiz is open and it is
47
+ * the current step. `false` from the moment it leaves the screen — another
48
+ * step, the quiz closing, another quiz opening — and `true` again when the
49
+ * learner comes back.
50
+ *
51
+ * WHEN IT TURNS `false`, STOP THE MICROPHONE, ANY TIMER AND ANY SPEECH. The
52
+ * video pauses the `<audio>` and `<video>` elements inside the question and
53
+ * stops the recorders the SDK started, but it cannot reach a recorder it did
54
+ * not create.
55
+ */
56
+ active: boolean;
57
+ locale?: string;
58
+ /** The answer restored from `responses`. A starting value: read it once, as the SDK's components do. */
59
+ defaultValue?: LearnerResponse;
60
+ /** Whether `submittedSlotIds` names this question: it was handed in before this attempt resumed. */
61
+ defaultSubmitted: boolean;
62
+ /** Its stored outcome from `outcomes`: review, or the grade of a question graded later. Read live. */
63
+ outcome?: ItemOutcome;
64
+ /**
65
+ * An element inside the player, for popovers and tooltips. Portal into it
66
+ * rather than into `document.body`: in fullscreen only the player is painted,
67
+ * and anything outside it silently vanishes. It is drawn above the quiz, is
68
+ * the same element for the life of the player — one for every question, so
69
+ * key what you put in it — and is `null` only before the player's first
70
+ * commit.
71
+ */
72
+ portalContainer: HTMLElement | null;
73
+ /**
74
+ * The learner committed an answer: marks the question answered and forwards
75
+ * to `onSubmit(response, slot)`. Latest wins: call it again for a new take or
76
+ * a corrected answer.
77
+ */
78
+ submit(response: LearnerResponse): void;
79
+ /**
80
+ * The answer has a result: marks the question answered, keeps `score / maxScore`
81
+ * for the end card when `maxScore > 0`, and forwards to
82
+ * `onActivityComplete(result, slot)`. Latest wins. Counts as answered on its
83
+ * own, without a `submit`, and forwards exactly what was called — no
84
+ * `onSubmit` is invented for it.
85
+ */
86
+ complete(result: ActivityResult): void;
87
+ /**
88
+ * The learner withdrew the answer — a "Try again". The question is unanswered
89
+ * again and its score forgotten: its step dot empties, a required quiz holds
90
+ * the learner again, and `onFinished` would report it `skipped`. Calls no
91
+ * host callback: the host already knows.
92
+ */
93
+ clear(): void;
94
+ /**
95
+ * Work is on its way for this question — an upload, an assessment. While any
96
+ * question is pending, Finish on the end card waits, and a video that ends
97
+ * does not finish by itself; closing the quiz, paging and seeking do not wait.
98
+ * Call `setPending(false)` however the work ends, a failure included.
99
+ */
100
+ setPending(pending: boolean): void;
101
+ /** Forwards to `onInteraction`, with this question's `activityId` and the time filled in. */
102
+ emit(type: InteractionKind, payload?: Record<string, unknown>): void;
103
+ }
22
104
  interface InteractiveVideoProps {
23
105
  /** An item group with a video stimulus and a timeline. Redacted projections in exam and review. */
24
106
  group: RenderableItemGroup;
@@ -40,10 +122,39 @@ interface InteractiveVideoProps {
40
122
  outcomes?: Readonly<Record<string, ItemOutcome>>;
41
123
  onSubmit?: (response: LearnerResponse, slot: InteractiveVideoSlot) => void;
42
124
  onActivityComplete?: (result: ActivityResult, slot: InteractiveVideoSlot) => void;
43
- /** Once per mount: when the learner presses Finish, or the video ends with every question answered. */
125
+ /**
126
+ * Once per mount: when the learner presses Finish, or the video ends with every
127
+ * question answered — either way, only once no answer is still on its way.
128
+ */
44
129
  onFinished?: (summary: InteractiveVideoSummary) => void;
45
130
  onInteraction?: (event: InteractionEvent) => void;
46
- /** Where read-aloud takes are stored and judged. Required when the video holds a read-aloud, outside review. */
131
+ /**
132
+ * Draws a question yourself. Called for each question once its quiz has
133
+ * opened, and on every render after;
134
+ * return `undefined` for the SDK's own component, so a host can take over one
135
+ * activity type and leave the rest. `null` draws nothing, and is kept.
136
+ *
137
+ * The video still owns everything around the question: when it opens,
138
+ * whether it counts as answered, whether a required quiz lets the learner go
139
+ * on, pausing, resume and the end summary — all through the calls on
140
+ * {@link InteractiveVideoQuestion}. A question the host draws is never
141
+ * treated differently from one the SDK draws.
142
+ *
143
+ * THE HOST MUST STOP ITS MICROPHONE WHEN `active` TURNS `false`: the SDK stops
144
+ * only the recorders it created. And the SDK cannot keep a mode for pixels it
145
+ * does not draw: in `exam` reveal no correctness, and in `review` accept no
146
+ * answer.
147
+ *
148
+ * What you return is keyed by the question's slot and stays mounted for the
149
+ * life of the player, like the SDK's own questions, and sits inside the same
150
+ * error boundary: a throw degrades that one question, never the video.
151
+ */
152
+ renderQuestion?: (question: InteractiveVideoQuestion) => ReactNode | undefined;
153
+ /**
154
+ * Where read-aloud takes are stored and judged. Required for every read-aloud
155
+ * the SDK draws itself, outside review; a video whose read-alouds are all
156
+ * drawn by `renderQuestion` needs none.
157
+ */
47
158
  recordingBinding?: SequenceRecordingBinding;
48
159
  /** Speech assessments by slot id, so `review` shows the marks behind a read-aloud's grade. Read live. */
49
160
  assessments?: Readonly<Record<string, SpeechAssessment>>;
@@ -120,4 +231,4 @@ declare function resolveCaptionTracks(tracks: readonly MediaTrack[], preferences
120
231
  */
121
232
  declare function InteractiveVideo(props: InteractiveVideoProps): react_jsx_runtime.JSX.Element;
122
233
 
123
- export { type CaptionTracks, InteractiveVideo, type InteractiveVideoProps, type InteractiveVideoSlot, type InteractiveVideoSummary, type RenderableItemGroup, VideoPreferences, resolveCaptionTracks };
234
+ export { type CaptionTracks, InteractiveVideo, type InteractiveVideoProps, type InteractiveVideoQuestion, type InteractiveVideoSlot, type InteractiveVideoSummary, type RenderableItemGroup, VideoPreferences, resolveCaptionTracks };
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ItemGroup, MediaProgress, LearnerResponse, ItemOutcome, ActivityResult, InteractionEvent, SpeechAssessment, MediaTrack, ThemeTokens } from '@intellectif/lk-core';
3
- import { g as RenderableActivity, e as RenderMode, i as SequenceRecordingSlot, h as SequenceRecordingBinding, V as VideoPreferences, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-Dgc5-DeA.js';
4
- export { C as CaptionSize } from '../strings-Dgc5-DeA.js';
2
+ import { ItemGroup, MediaProgress, LearnerResponse, ItemOutcome, ActivityResult, InteractionEvent, InteractionKind, SpeechAssessment, MediaTrack, ThemeTokens } from '@intellectif/lk-core';
3
+ import { ReactNode } from 'react';
4
+ import { g as RenderableActivity, e as RenderMode, i as SequenceRecordingSlot, h as SequenceRecordingBinding, V as VideoPreferences, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-Cd_2F-Bw.js';
5
+ export { C as CaptionSize } from '../strings-Cd_2F-Bw.js';
5
6
  import '../machine-CuwKqWXC.js';
6
7
 
7
8
  /** An item group whose items may be `redact()` projections: the client's view of an interactive video. */
@@ -19,6 +20,87 @@ interface InteractiveVideoSummary {
19
20
  status: 'answered' | 'skipped' | 'unreached';
20
21
  }[];
21
22
  }
23
+ /**
24
+ * One question, as `renderQuestion` is handed it: what to draw, and the six
25
+ * calls through which the video learns what the learner did.
26
+ *
27
+ * The calls are the ones the SDK's own components make, so a question the host
28
+ * draws counts exactly as one the SDK draws — in the step dots, in whether a
29
+ * required quiz lets the learner go on, on the end card and in `onFinished`.
30
+ * Each keeps ONE identity per question for the life of the player, so it is
31
+ * safe in an effect's dependencies, and each does nothing once the player has
32
+ * unmounted.
33
+ */
34
+ interface InteractiveVideoQuestion {
35
+ /** The question, as the SDK would have rendered it: full data, or a `redact()` projection. */
36
+ activity: RenderableActivity;
37
+ /** Where it sits: the same object `onSubmit` and `onActivityComplete` are handed, for the life of the player. */
38
+ slot: InteractiveVideoSlot;
39
+ /**
40
+ * Passed through untouched. The SDK cannot enforce a mode for pixels it does
41
+ * not draw: in `exam` the host must not reveal correctness, and in `review`
42
+ * nothing is submittable — `submit`, `complete` and `clear` are ignored there.
43
+ */
44
+ renderMode: RenderMode;
45
+ /**
46
+ * `true` while this question is the one on screen: its quiz is open and it is
47
+ * the current step. `false` from the moment it leaves the screen — another
48
+ * step, the quiz closing, another quiz opening — and `true` again when the
49
+ * learner comes back.
50
+ *
51
+ * WHEN IT TURNS `false`, STOP THE MICROPHONE, ANY TIMER AND ANY SPEECH. The
52
+ * video pauses the `<audio>` and `<video>` elements inside the question and
53
+ * stops the recorders the SDK started, but it cannot reach a recorder it did
54
+ * not create.
55
+ */
56
+ active: boolean;
57
+ locale?: string;
58
+ /** The answer restored from `responses`. A starting value: read it once, as the SDK's components do. */
59
+ defaultValue?: LearnerResponse;
60
+ /** Whether `submittedSlotIds` names this question: it was handed in before this attempt resumed. */
61
+ defaultSubmitted: boolean;
62
+ /** Its stored outcome from `outcomes`: review, or the grade of a question graded later. Read live. */
63
+ outcome?: ItemOutcome;
64
+ /**
65
+ * An element inside the player, for popovers and tooltips. Portal into it
66
+ * rather than into `document.body`: in fullscreen only the player is painted,
67
+ * and anything outside it silently vanishes. It is drawn above the quiz, is
68
+ * the same element for the life of the player — one for every question, so
69
+ * key what you put in it — and is `null` only before the player's first
70
+ * commit.
71
+ */
72
+ portalContainer: HTMLElement | null;
73
+ /**
74
+ * The learner committed an answer: marks the question answered and forwards
75
+ * to `onSubmit(response, slot)`. Latest wins: call it again for a new take or
76
+ * a corrected answer.
77
+ */
78
+ submit(response: LearnerResponse): void;
79
+ /**
80
+ * The answer has a result: marks the question answered, keeps `score / maxScore`
81
+ * for the end card when `maxScore > 0`, and forwards to
82
+ * `onActivityComplete(result, slot)`. Latest wins. Counts as answered on its
83
+ * own, without a `submit`, and forwards exactly what was called — no
84
+ * `onSubmit` is invented for it.
85
+ */
86
+ complete(result: ActivityResult): void;
87
+ /**
88
+ * The learner withdrew the answer — a "Try again". The question is unanswered
89
+ * again and its score forgotten: its step dot empties, a required quiz holds
90
+ * the learner again, and `onFinished` would report it `skipped`. Calls no
91
+ * host callback: the host already knows.
92
+ */
93
+ clear(): void;
94
+ /**
95
+ * Work is on its way for this question — an upload, an assessment. While any
96
+ * question is pending, Finish on the end card waits, and a video that ends
97
+ * does not finish by itself; closing the quiz, paging and seeking do not wait.
98
+ * Call `setPending(false)` however the work ends, a failure included.
99
+ */
100
+ setPending(pending: boolean): void;
101
+ /** Forwards to `onInteraction`, with this question's `activityId` and the time filled in. */
102
+ emit(type: InteractionKind, payload?: Record<string, unknown>): void;
103
+ }
22
104
  interface InteractiveVideoProps {
23
105
  /** An item group with a video stimulus and a timeline. Redacted projections in exam and review. */
24
106
  group: RenderableItemGroup;
@@ -40,10 +122,39 @@ interface InteractiveVideoProps {
40
122
  outcomes?: Readonly<Record<string, ItemOutcome>>;
41
123
  onSubmit?: (response: LearnerResponse, slot: InteractiveVideoSlot) => void;
42
124
  onActivityComplete?: (result: ActivityResult, slot: InteractiveVideoSlot) => void;
43
- /** Once per mount: when the learner presses Finish, or the video ends with every question answered. */
125
+ /**
126
+ * Once per mount: when the learner presses Finish, or the video ends with every
127
+ * question answered — either way, only once no answer is still on its way.
128
+ */
44
129
  onFinished?: (summary: InteractiveVideoSummary) => void;
45
130
  onInteraction?: (event: InteractionEvent) => void;
46
- /** Where read-aloud takes are stored and judged. Required when the video holds a read-aloud, outside review. */
131
+ /**
132
+ * Draws a question yourself. Called for each question once its quiz has
133
+ * opened, and on every render after;
134
+ * return `undefined` for the SDK's own component, so a host can take over one
135
+ * activity type and leave the rest. `null` draws nothing, and is kept.
136
+ *
137
+ * The video still owns everything around the question: when it opens,
138
+ * whether it counts as answered, whether a required quiz lets the learner go
139
+ * on, pausing, resume and the end summary — all through the calls on
140
+ * {@link InteractiveVideoQuestion}. A question the host draws is never
141
+ * treated differently from one the SDK draws.
142
+ *
143
+ * THE HOST MUST STOP ITS MICROPHONE WHEN `active` TURNS `false`: the SDK stops
144
+ * only the recorders it created. And the SDK cannot keep a mode for pixels it
145
+ * does not draw: in `exam` reveal no correctness, and in `review` accept no
146
+ * answer.
147
+ *
148
+ * What you return is keyed by the question's slot and stays mounted for the
149
+ * life of the player, like the SDK's own questions, and sits inside the same
150
+ * error boundary: a throw degrades that one question, never the video.
151
+ */
152
+ renderQuestion?: (question: InteractiveVideoQuestion) => ReactNode | undefined;
153
+ /**
154
+ * Where read-aloud takes are stored and judged. Required for every read-aloud
155
+ * the SDK draws itself, outside review; a video whose read-alouds are all
156
+ * drawn by `renderQuestion` needs none.
157
+ */
47
158
  recordingBinding?: SequenceRecordingBinding;
48
159
  /** Speech assessments by slot id, so `review` shows the marks behind a read-aloud's grade. Read live. */
49
160
  assessments?: Readonly<Record<string, SpeechAssessment>>;
@@ -120,4 +231,4 @@ declare function resolveCaptionTracks(tracks: readonly MediaTrack[], preferences
120
231
  */
121
232
  declare function InteractiveVideo(props: InteractiveVideoProps): react_jsx_runtime.JSX.Element;
122
233
 
123
- export { type CaptionTracks, InteractiveVideo, type InteractiveVideoProps, type InteractiveVideoSlot, type InteractiveVideoSummary, type RenderableItemGroup, VideoPreferences, resolveCaptionTracks };
234
+ export { type CaptionTracks, InteractiveVideo, type InteractiveVideoProps, type InteractiveVideoQuestion, type InteractiveVideoSlot, type InteractiveVideoSummary, type RenderableItemGroup, VideoPreferences, resolveCaptionTracks };
@@ -1,17 +1,17 @@
1
1
  'use client';
2
- export { InteractiveVideo, resolveCaptionTracks } from '../chunk-3IHVDQRC.js';
3
- import '../chunk-4X7NFEDB.js';
4
- import '../chunk-4AQ4SWJ3.js';
5
- import '../chunk-UYRQEIB7.js';
6
- import '../chunk-T33AJYLW.js';
7
- import '../chunk-W32ND3ZR.js';
8
- import '../chunk-HJLVWZOM.js';
2
+ export { InteractiveVideo, resolveCaptionTracks } from '../chunk-DVOPHC2Q.js';
3
+ import '../chunk-3UXRX4KU.js';
4
+ import '../chunk-VC2MPB2Y.js';
5
+ import '../chunk-5QHVYOME.js';
6
+ import '../chunk-IQI5I2X5.js';
7
+ import '../chunk-GUPBIEUA.js';
8
+ import '../chunk-BI547RIA.js';
9
9
  import '../chunk-MCO52PV5.js';
10
10
  import '../chunk-YORQQXGO.js';
11
11
  import '../chunk-RCMYEWBE.js';
12
- import '../chunk-ICAYWVNF.js';
13
- import '../chunk-UIGSH2XB.js';
12
+ import '../chunk-DKZWUIQD.js';
13
+ import '../chunk-ZPCO3CEB.js';
14
14
  import '../chunk-6N43WDVG.js';
15
- import '../chunk-QIA5FAAW.js';
15
+ import '../chunk-KSAINXRG.js';
16
16
  //# sourceMappingURL=InteractiveVideo.js.map
17
17
  //# sourceMappingURL=InteractiveVideo.js.map
@@ -1,18 +1,18 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkDMCFARGP_cjs = require('../chunk-DMCFARGP.cjs');
4
+ var chunkZSY4VANQ_cjs = require('../chunk-ZSY4VANQ.cjs');
5
5
  require('../chunk-BRPEB43C.cjs');
6
- require('../chunk-P5FGJMMI.cjs');
7
- require('../chunk-OXUUE3HX.cjs');
6
+ require('../chunk-2S3MK4VX.cjs');
7
+ require('../chunk-TRP5Z3XW.cjs');
8
8
  require('../chunk-XOR4MPEN.cjs');
9
- require('../chunk-UISZWFI7.cjs');
9
+ require('../chunk-MQAZJQRE.cjs');
10
10
 
11
11
 
12
12
 
13
13
  Object.defineProperty(exports, "MultipleChoice", {
14
14
  enumerable: true,
15
- get: function () { return chunkDMCFARGP_cjs.MultipleChoice; }
15
+ get: function () { return chunkZSY4VANQ_cjs.MultipleChoice; }
16
16
  });
17
17
  //# sourceMappingURL=MultipleChoice.cjs.map
18
18
  //# sourceMappingURL=MultipleChoice.cjs.map
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MultipleChoiceData } from '@intellectif/lk-core';
3
- import { A as ActivityProps } from '../strings-zY2QQYpU.cjs';
3
+ import { A as ActivityProps } from '../strings-C6wM5aUQ.cjs';
4
4
  import '../machine-CuwKqWXC.cjs';
5
5
 
6
6
  interface MultipleChoiceProps extends ActivityProps<MultipleChoiceData> {
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { MultipleChoiceData } from '@intellectif/lk-core';
3
- import { A as ActivityProps } from '../strings-Dgc5-DeA.js';
3
+ import { A as ActivityProps } from '../strings-Cd_2F-Bw.js';
4
4
  import '../machine-CuwKqWXC.js';
5
5
 
6
6
  interface MultipleChoiceProps extends ActivityProps<MultipleChoiceData> {
@@ -1,9 +1,9 @@
1
1
  'use client';
2
- export { MultipleChoice } from '../chunk-4X7NFEDB.js';
2
+ export { MultipleChoice } from '../chunk-3UXRX4KU.js';
3
3
  import '../chunk-RCMYEWBE.js';
4
- import '../chunk-ICAYWVNF.js';
5
- import '../chunk-UIGSH2XB.js';
4
+ import '../chunk-DKZWUIQD.js';
5
+ import '../chunk-ZPCO3CEB.js';
6
6
  import '../chunk-6N43WDVG.js';
7
- import '../chunk-QIA5FAAW.js';
7
+ import '../chunk-KSAINXRG.js';
8
8
  //# sourceMappingURL=MultipleChoice.js.map
9
9
  //# sourceMappingURL=MultipleChoice.js.map
@@ -1,16 +1,16 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkBO64SLHL_cjs = require('../chunk-BO64SLHL.cjs');
4
+ var chunkDFMBVA7D_cjs = require('../chunk-DFMBVA7D.cjs');
5
5
  require('../chunk-OD65OZIW.cjs');
6
- require('../chunk-P5FGJMMI.cjs');
7
- require('../chunk-UISZWFI7.cjs');
6
+ require('../chunk-2S3MK4VX.cjs');
7
+ require('../chunk-MQAZJQRE.cjs');
8
8
 
9
9
 
10
10
 
11
11
  Object.defineProperty(exports, "PronunciationFeedback", {
12
12
  enumerable: true,
13
- get: function () { return chunkBO64SLHL_cjs.PronunciationFeedback; }
13
+ get: function () { return chunkDFMBVA7D_cjs.PronunciationFeedback; }
14
14
  });
15
15
  //# sourceMappingURL=PronunciationFeedback.cjs.map
16
16
  //# sourceMappingURL=PronunciationFeedback.cjs.map
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReadAloudData, SpeechAssessment, GradeRecord, ThemeTokens } from '@intellectif/lk-core';
3
- import { a as LkStringsOverride } from '../strings-zY2QQYpU.cjs';
3
+ import { a as LkStringsOverride } from '../strings-C6wM5aUQ.cjs';
4
4
  import '../machine-CuwKqWXC.cjs';
5
5
 
6
6
  interface PronunciationFeedbackProps {
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReadAloudData, SpeechAssessment, GradeRecord, ThemeTokens } from '@intellectif/lk-core';
3
- import { a as LkStringsOverride } from '../strings-Dgc5-DeA.js';
3
+ import { a as LkStringsOverride } from '../strings-Cd_2F-Bw.js';
4
4
  import '../machine-CuwKqWXC.js';
5
5
 
6
6
  interface PronunciationFeedbackProps {
@@ -1,7 +1,7 @@
1
1
  'use client';
2
- export { PronunciationFeedback } from '../chunk-HJLVWZOM.js';
2
+ export { PronunciationFeedback } from '../chunk-BI547RIA.js';
3
3
  import '../chunk-YORQQXGO.js';
4
- import '../chunk-ICAYWVNF.js';
5
- import '../chunk-QIA5FAAW.js';
4
+ import '../chunk-DKZWUIQD.js';
5
+ import '../chunk-KSAINXRG.js';
6
6
  //# sourceMappingURL=PronunciationFeedback.js.map
7
7
  //# sourceMappingURL=PronunciationFeedback.js.map
@@ -1,21 +1,21 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunk2WM2KSO7_cjs = require('../chunk-2WM2KSO7.cjs');
5
- require('../chunk-BO64SLHL.cjs');
4
+ var chunkML6L4LJH_cjs = require('../chunk-ML6L4LJH.cjs');
5
+ require('../chunk-DFMBVA7D.cjs');
6
6
  require('../chunk-UDCQTOVU.cjs');
7
7
  require('../chunk-OD65OZIW.cjs');
8
8
  require('../chunk-BRPEB43C.cjs');
9
- require('../chunk-P5FGJMMI.cjs');
10
- require('../chunk-OXUUE3HX.cjs');
9
+ require('../chunk-2S3MK4VX.cjs');
10
+ require('../chunk-TRP5Z3XW.cjs');
11
11
  require('../chunk-XOR4MPEN.cjs');
12
- require('../chunk-UISZWFI7.cjs');
12
+ require('../chunk-MQAZJQRE.cjs');
13
13
 
14
14
 
15
15
 
16
16
  Object.defineProperty(exports, "ReadAloud", {
17
17
  enumerable: true,
18
- get: function () { return chunk2WM2KSO7_cjs.ReadAloud; }
18
+ get: function () { return chunkML6L4LJH_cjs.ReadAloud; }
19
19
  });
20
20
  //# sourceMappingURL=ReadAloud.cjs.map
21
21
  //# sourceMappingURL=ReadAloud.cjs.map
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { c as ReadAloudProps } from '../strings-zY2QQYpU.cjs';
3
- export { R as ReadAloudAssessResult, d as RecordingBinding } from '../strings-zY2QQYpU.cjs';
2
+ import { c as ReadAloudProps } from '../strings-C6wM5aUQ.cjs';
3
+ export { R as ReadAloudAssessResult, d as RecordingBinding } from '../strings-C6wM5aUQ.cjs';
4
4
  export { R as RecordedTake } from '../machine-CuwKqWXC.cjs';
5
5
  import '@intellectif/lk-core';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { c as ReadAloudProps } from '../strings-Dgc5-DeA.js';
3
- export { R as ReadAloudAssessResult, d as RecordingBinding } from '../strings-Dgc5-DeA.js';
2
+ import { c as ReadAloudProps } from '../strings-Cd_2F-Bw.js';
3
+ export { R as ReadAloudAssessResult, d as RecordingBinding } from '../strings-Cd_2F-Bw.js';
4
4
  export { R as RecordedTake } from '../machine-CuwKqWXC.js';
5
5
  import '@intellectif/lk-core';
6
6
 
@@ -1,12 +1,12 @@
1
1
  'use client';
2
- export { ReadAloud } from '../chunk-W32ND3ZR.js';
3
- import '../chunk-HJLVWZOM.js';
2
+ export { ReadAloud } from '../chunk-GUPBIEUA.js';
3
+ import '../chunk-BI547RIA.js';
4
4
  import '../chunk-MCO52PV5.js';
5
5
  import '../chunk-YORQQXGO.js';
6
6
  import '../chunk-RCMYEWBE.js';
7
- import '../chunk-ICAYWVNF.js';
8
- import '../chunk-UIGSH2XB.js';
7
+ import '../chunk-DKZWUIQD.js';
8
+ import '../chunk-ZPCO3CEB.js';
9
9
  import '../chunk-6N43WDVG.js';
10
- import '../chunk-QIA5FAAW.js';
10
+ import '../chunk-KSAINXRG.js';
11
11
  //# sourceMappingURL=ReadAloud.js.map
12
12
  //# sourceMappingURL=ReadAloud.js.map
@@ -1,15 +1,15 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkWGIMLXRW_cjs = require('../chunk-WGIMLXRW.cjs');
5
- require('../chunk-OXUUE3HX.cjs');
6
- require('../chunk-UISZWFI7.cjs');
4
+ var chunkPXGJHZKJ_cjs = require('../chunk-PXGJHZKJ.cjs');
5
+ require('../chunk-TRP5Z3XW.cjs');
6
+ require('../chunk-MQAZJQRE.cjs');
7
7
 
8
8
 
9
9
 
10
10
  Object.defineProperty(exports, "StimulusPanel", {
11
11
  enumerable: true,
12
- get: function () { return chunkWGIMLXRW_cjs.StimulusPanel; }
12
+ get: function () { return chunkPXGJHZKJ_cjs.StimulusPanel; }
13
13
  });
14
14
  //# sourceMappingURL=StimulusPanel.cjs.map
15
15
  //# sourceMappingURL=StimulusPanel.cjs.map
@@ -1,5 +1,5 @@
1
1
  import { Stimulus, InteractionEvent } from '@intellectif/lk-core';
2
- import { H as HtmlSanitizer, e as RenderMode, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from '../strings-zY2QQYpU.cjs';
2
+ import { H as HtmlSanitizer, e as RenderMode, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from '../strings-C6wM5aUQ.cjs';
3
3
  import '../machine-CuwKqWXC.cjs';
4
4
 
5
5
  interface StimulusPanelProps {
@@ -1,5 +1,5 @@
1
1
  import { Stimulus, InteractionEvent } from '@intellectif/lk-core';
2
- import { H as HtmlSanitizer, e as RenderMode, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from '../strings-Dgc5-DeA.js';
2
+ import { H as HtmlSanitizer, e as RenderMode, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from '../strings-Cd_2F-Bw.js';
3
3
  import '../machine-CuwKqWXC.js';
4
4
 
5
5
  interface StimulusPanelProps {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
- export { StimulusPanel } from '../chunk-NOF6HJDV.js';
3
- import '../chunk-UIGSH2XB.js';
4
- import '../chunk-QIA5FAAW.js';
2
+ export { StimulusPanel } from '../chunk-JPDR6TTA.js';
3
+ import '../chunk-ZPCO3CEB.js';
4
+ import '../chunk-KSAINXRG.js';
5
5
  //# sourceMappingURL=StimulusPanel.js.map
6
6
  //# sourceMappingURL=StimulusPanel.js.map
@@ -1,18 +1,18 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkJYC2VV3Y_cjs = require('../chunk-JYC2VV3Y.cjs');
4
+ var chunkPTJTC6A3_cjs = require('../chunk-PTJTC6A3.cjs');
5
5
  require('../chunk-BRPEB43C.cjs');
6
- require('../chunk-P5FGJMMI.cjs');
7
- require('../chunk-OXUUE3HX.cjs');
6
+ require('../chunk-2S3MK4VX.cjs');
7
+ require('../chunk-TRP5Z3XW.cjs');
8
8
  require('../chunk-XOR4MPEN.cjs');
9
- require('../chunk-UISZWFI7.cjs');
9
+ require('../chunk-MQAZJQRE.cjs');
10
10
 
11
11
 
12
12
 
13
13
  Object.defineProperty(exports, "WrittenResponse", {
14
14
  enumerable: true,
15
- get: function () { return chunkJYC2VV3Y_cjs.WrittenResponse; }
15
+ get: function () { return chunkPTJTC6A3_cjs.WrittenResponse; }
16
16
  });
17
17
  //# sourceMappingURL=WrittenResponse.cjs.map
18
18
  //# sourceMappingURL=WrittenResponse.cjs.map
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { W as WrittenResponseProps } from '../WrittenResponse-C2zw-1jK.cjs';
3
- export { a as WrittenResponseSubmission } from '../WrittenResponse-C2zw-1jK.cjs';
4
- export { H as HtmlSanitizer, e as RenderMode, f as Renderable } from '../strings-zY2QQYpU.cjs';
2
+ import { W as WrittenResponseProps } from '../WrittenResponse-6tSj6U3G.cjs';
3
+ export { a as WrittenResponseSubmission } from '../WrittenResponse-6tSj6U3G.cjs';
4
+ export { H as HtmlSanitizer, e as RenderMode, f as Renderable } from '../strings-C6wM5aUQ.cjs';
5
5
  import '@intellectif/lk-core';
6
6
  import '../machine-CuwKqWXC.cjs';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { W as WrittenResponseProps } from '../WrittenResponse-CTiNpSCC.js';
3
- export { a as WrittenResponseSubmission } from '../WrittenResponse-CTiNpSCC.js';
4
- export { H as HtmlSanitizer, e as RenderMode, f as Renderable } from '../strings-Dgc5-DeA.js';
2
+ import { W as WrittenResponseProps } from '../WrittenResponse-xJ7I_5yq.js';
3
+ export { a as WrittenResponseSubmission } from '../WrittenResponse-xJ7I_5yq.js';
4
+ export { H as HtmlSanitizer, e as RenderMode, f as Renderable } from '../strings-Cd_2F-Bw.js';
5
5
  import '@intellectif/lk-core';
6
6
  import '../machine-CuwKqWXC.js';
7
7
 
@@ -1,9 +1,9 @@
1
1
  'use client';
2
- export { WrittenResponse } from '../chunk-AEUP63CZ.js';
2
+ export { WrittenResponse } from '../chunk-2XNCPLHU.js';
3
3
  import '../chunk-RCMYEWBE.js';
4
- import '../chunk-ICAYWVNF.js';
5
- import '../chunk-UIGSH2XB.js';
4
+ import '../chunk-DKZWUIQD.js';
5
+ import '../chunk-ZPCO3CEB.js';
6
6
  import '../chunk-6N43WDVG.js';
7
- import '../chunk-QIA5FAAW.js';
7
+ import '../chunk-KSAINXRG.js';
8
8
  //# sourceMappingURL=WrittenResponse.js.map
9
9
  //# sourceMappingURL=WrittenResponse.js.map