@intellectif/lk-react 16.1.1 → 17.0.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.
- package/CHANGELOG.md +50 -0
- package/README.md +3 -1
- package/dist/{WrittenResponse-xJ7I_5yq.d.ts → WrittenResponse-B4kY-U0v.d.ts} +1 -1
- package/dist/{WrittenResponse-6tSj6U3G.d.cts → WrittenResponse-Dl3zah22.d.cts} +1 -1
- package/dist/ai/LkAiProvider.cjs +17 -0
- package/dist/ai/LkAiProvider.cjs.map +1 -0
- package/dist/ai/LkAiProvider.d.cts +60 -0
- package/dist/ai/LkAiProvider.d.ts +60 -0
- package/dist/ai/LkAiProvider.js +4 -0
- package/dist/ai/LkAiProvider.js.map +1 -0
- package/dist/{chunk-PXGJHZKJ.cjs → chunk-3FBBP5QR.cjs} +6 -6
- package/dist/{chunk-PXGJHZKJ.cjs.map → chunk-3FBBP5QR.cjs.map} +1 -1
- package/dist/{chunk-3HC3PJTB.cjs → chunk-3TJSFPO4.cjs} +26 -22
- package/dist/chunk-3TJSFPO4.cjs.map +1 -0
- package/dist/chunk-5F4Q6JT7.cjs +289 -0
- package/dist/chunk-5F4Q6JT7.cjs.map +1 -0
- package/dist/{chunk-3UXRX4KU.js → chunk-6DTW5T3Z.js} +39 -7
- package/dist/chunk-6DTW5T3Z.js.map +1 -0
- package/dist/{chunk-ML6L4LJH.cjs → chunk-6RRFH7C4.cjs} +25 -25
- package/dist/{chunk-ML6L4LJH.cjs.map → chunk-6RRFH7C4.cjs.map} +1 -1
- package/dist/{chunk-JPDR6TTA.js → chunk-7K4B2EMU.js} +4 -4
- package/dist/{chunk-JPDR6TTA.js.map → chunk-7K4B2EMU.js.map} +1 -1
- package/dist/{chunk-MQAZJQRE.cjs → chunk-AHGB5HH6.cjs} +13 -2
- package/dist/chunk-AHGB5HH6.cjs.map +1 -0
- package/dist/{chunk-5QHVYOME.js → chunk-ALH6TUX2.js} +39 -7
- package/dist/chunk-ALH6TUX2.js.map +1 -0
- package/dist/{chunk-2S3MK4VX.cjs → chunk-BAKLJKFZ.cjs} +5 -5
- package/dist/{chunk-2S3MK4VX.cjs.map → chunk-BAKLJKFZ.cjs.map} +1 -1
- package/dist/{chunk-ZPCO3CEB.js → chunk-BY4UQH2Y.js} +3 -3
- package/dist/{chunk-ZPCO3CEB.js.map → chunk-BY4UQH2Y.js.map} +1 -1
- package/dist/chunk-GR33G5QM.js +286 -0
- package/dist/chunk-GR33G5QM.js.map +1 -0
- package/dist/{chunk-ZEDMFTKD.js → chunk-H3IRVX7J.js} +10 -10
- package/dist/{chunk-ZEDMFTKD.js.map → chunk-H3IRVX7J.js.map} +1 -1
- package/dist/{chunk-PTJTC6A3.cjs → chunk-H63O5HPW.cjs} +23 -14
- package/dist/chunk-H63O5HPW.cjs.map +1 -0
- package/dist/{chunk-IQI5I2X5.js → chunk-HZMILQYO.js} +25 -7
- package/dist/chunk-HZMILQYO.js.map +1 -0
- package/dist/{chunk-ZSY4VANQ.cjs → chunk-JKMBFHER.cjs} +47 -15
- package/dist/chunk-JKMBFHER.cjs.map +1 -0
- package/dist/{chunk-GUPBIEUA.js → chunk-KP57YCYQ.js} +6 -6
- package/dist/{chunk-GUPBIEUA.js.map → chunk-KP57YCYQ.js.map} +1 -1
- package/dist/{chunk-GDMM2WEG.js → chunk-KWKB74KL.js} +16 -12
- package/dist/chunk-KWKB74KL.js.map +1 -0
- package/dist/{chunk-TRP5Z3XW.cjs → chunk-L7WY5YFQ.cjs} +5 -5
- package/dist/{chunk-TRP5Z3XW.cjs.map → chunk-L7WY5YFQ.cjs.map} +1 -1
- package/dist/{chunk-B6S5ADHR.cjs → chunk-QA42VDTA.cjs} +47 -15
- package/dist/chunk-QA42VDTA.cjs.map +1 -0
- package/dist/{chunk-VC2MPB2Y.js → chunk-QHK6PTUR.js} +39 -7
- package/dist/chunk-QHK6PTUR.js.map +1 -0
- package/dist/{chunk-BI547RIA.js → chunk-QJW3K6JN.js} +4 -4
- package/dist/{chunk-BI547RIA.js.map → chunk-QJW3K6JN.js.map} +1 -1
- package/dist/{chunk-RSQFGF5W.cjs → chunk-RZ52SEYV.cjs} +33 -15
- package/dist/chunk-RZ52SEYV.cjs.map +1 -0
- package/dist/{chunk-2TFNDHJ5.cjs → chunk-TI23GIFM.cjs} +47 -15
- package/dist/chunk-TI23GIFM.cjs.map +1 -0
- package/dist/{chunk-DFMBVA7D.cjs → chunk-UQIRDE52.cjs} +8 -8
- package/dist/{chunk-DFMBVA7D.cjs.map → chunk-UQIRDE52.cjs.map} +1 -1
- package/dist/{chunk-56WAZKPS.js → chunk-UYQBEPNZ.js} +13 -9
- package/dist/chunk-UYQBEPNZ.js.map +1 -0
- package/dist/{chunk-2XNCPLHU.js → chunk-V5BTVGPA.js} +16 -7
- package/dist/chunk-V5BTVGPA.js.map +1 -0
- package/dist/{chunk-FZWWVJE4.cjs → chunk-XEGBGKHV.cjs} +29 -25
- package/dist/chunk-XEGBGKHV.cjs.map +1 -0
- package/dist/chunk-YNDKAYW3.js +17 -0
- package/dist/chunk-YNDKAYW3.js.map +1 -0
- package/dist/{chunk-KSAINXRG.js → chunk-YRNEOBXA.js} +13 -2
- package/dist/chunk-YRNEOBXA.js.map +1 -0
- package/dist/{chunk-DKZWUIQD.js → chunk-YTGRXD23.js} +3 -3
- package/dist/{chunk-DKZWUIQD.js.map → chunk-YTGRXD23.js.map} +1 -1
- package/dist/{chunk-OO24JGYH.cjs → chunk-Z5XY66PO.cjs} +18 -18
- package/dist/{chunk-OO24JGYH.cjs.map → chunk-Z5XY66PO.cjs.map} +1 -1
- package/dist/chunk-ZDYNAWDZ.cjs +20 -0
- package/dist/chunk-ZDYNAWDZ.cjs.map +1 -0
- package/dist/components/ActivityPreview.cjs +14 -12
- package/dist/components/ActivityPreview.d.cts +3 -2
- package/dist/components/ActivityPreview.d.ts +3 -2
- package/dist/components/ActivityPreview.js +13 -11
- package/dist/components/ActivitySequence.cjs +15 -13
- package/dist/components/ActivitySequence.d.cts +12 -3
- package/dist/components/ActivitySequence.d.ts +12 -3
- package/dist/components/ActivitySequence.js +14 -12
- package/dist/components/Dictation.cjs +7 -5
- package/dist/components/Dictation.d.cts +3 -1
- package/dist/components/Dictation.d.ts +3 -1
- package/dist/components/Dictation.js +6 -4
- package/dist/components/FillInTheBlanks.cjs +7 -5
- package/dist/components/FillInTheBlanks.d.cts +3 -1
- package/dist/components/FillInTheBlanks.d.ts +3 -1
- package/dist/components/FillInTheBlanks.js +6 -4
- package/dist/components/GapSelect.cjs +7 -5
- package/dist/components/GapSelect.d.cts +3 -1
- package/dist/components/GapSelect.d.ts +3 -1
- package/dist/components/GapSelect.js +6 -4
- package/dist/components/InteractiveVideo.cjs +14 -12
- package/dist/components/InteractiveVideo.d.cts +16 -2
- package/dist/components/InteractiveVideo.d.ts +16 -2
- package/dist/components/InteractiveVideo.js +12 -10
- package/dist/components/MultipleChoice.cjs +7 -5
- package/dist/components/MultipleChoice.d.cts +3 -1
- package/dist/components/MultipleChoice.d.ts +3 -1
- package/dist/components/MultipleChoice.js +6 -4
- package/dist/components/PronunciationFeedback.cjs +4 -4
- package/dist/components/PronunciationFeedback.d.cts +3 -1
- package/dist/components/PronunciationFeedback.d.ts +3 -1
- package/dist/components/PronunciationFeedback.js +3 -3
- package/dist/components/ReadAloud.cjs +6 -6
- package/dist/components/ReadAloud.d.cts +4 -2
- package/dist/components/ReadAloud.d.ts +4 -2
- package/dist/components/ReadAloud.js +5 -5
- package/dist/components/StimulusPanel.cjs +4 -4
- package/dist/components/StimulusPanel.d.cts +3 -1
- package/dist/components/StimulusPanel.d.ts +3 -1
- package/dist/components/StimulusPanel.js +3 -3
- package/dist/components/WrittenResponse.cjs +5 -5
- package/dist/components/WrittenResponse.d.cts +5 -3
- package/dist/components/WrittenResponse.d.ts +5 -3
- package/dist/components/WrittenResponse.js +4 -4
- package/dist/i18n/LkIntlProvider.cjs +7 -7
- package/dist/i18n/LkIntlProvider.d.cts +4 -2
- package/dist/i18n/LkIntlProvider.d.ts +4 -2
- package/dist/i18n/LkIntlProvider.js +1 -1
- package/dist/index.cjs +47 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +17 -15
- package/dist/index.js.map +1 -1
- package/dist/{strings-C6wM5aUQ.d.cts → strings-BOPKhnS-.d.cts} +30 -0
- package/dist/{strings-Cd_2F-Bw.d.ts → strings-PCYKWCwd.d.ts} +30 -0
- package/dist/theme/skin.css +90 -0
- package/package.json +13 -3
- package/dist/chunk-2TFNDHJ5.cjs.map +0 -1
- package/dist/chunk-2XNCPLHU.js.map +0 -1
- package/dist/chunk-3HC3PJTB.cjs.map +0 -1
- package/dist/chunk-3UXRX4KU.js.map +0 -1
- package/dist/chunk-56WAZKPS.js.map +0 -1
- package/dist/chunk-5QHVYOME.js.map +0 -1
- package/dist/chunk-B6S5ADHR.cjs.map +0 -1
- package/dist/chunk-FZWWVJE4.cjs.map +0 -1
- package/dist/chunk-GDMM2WEG.js.map +0 -1
- package/dist/chunk-IQI5I2X5.js.map +0 -1
- package/dist/chunk-KSAINXRG.js.map +0 -1
- package/dist/chunk-MQAZJQRE.cjs.map +0 -1
- package/dist/chunk-PTJTC6A3.cjs.map +0 -1
- package/dist/chunk-RSQFGF5W.cjs.map +0 -1
- package/dist/chunk-VC2MPB2Y.js.map +0 -1
- package/dist/chunk-ZSY4VANQ.cjs.map +0 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var chunk5F4Q6JT7_cjs = require('./chunk-5F4Q6JT7.cjs');
|
|
5
|
+
var chunkZDYNAWDZ_cjs = require('./chunk-ZDYNAWDZ.cjs');
|
|
4
6
|
var chunkBRPEB43C_cjs = require('./chunk-BRPEB43C.cjs');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
+
var chunkBAKLJKFZ_cjs = require('./chunk-BAKLJKFZ.cjs');
|
|
8
|
+
var chunkL7WY5YFQ_cjs = require('./chunk-L7WY5YFQ.cjs');
|
|
7
9
|
var chunkXOR4MPEN_cjs = require('./chunk-XOR4MPEN.cjs');
|
|
8
|
-
var
|
|
10
|
+
var chunkAHGB5HH6_cjs = require('./chunk-AHGB5HH6.cjs');
|
|
9
11
|
var lkCore = require('@intellectif/lk-core');
|
|
10
12
|
var react = require('react');
|
|
11
13
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -68,13 +70,15 @@ function GapSelect({
|
|
|
68
70
|
theme,
|
|
69
71
|
locale,
|
|
70
72
|
disabled,
|
|
71
|
-
shuffleSeed
|
|
73
|
+
shuffleSeed,
|
|
74
|
+
ai: aiProp
|
|
72
75
|
}) {
|
|
73
76
|
const isExam = renderMode === "exam";
|
|
74
77
|
const isReview = renderMode === "review";
|
|
75
|
-
const s =
|
|
78
|
+
const s = chunkAHGB5HH6_cjs.useLkStrings(strings);
|
|
79
|
+
const ai = chunkZDYNAWDZ_cjs.useLearnerAi(aiProp);
|
|
76
80
|
const devError = react.useMemo(() => {
|
|
77
|
-
if (!
|
|
81
|
+
if (!chunkBAKLJKFZ_cjs.isDevelopment()) {
|
|
78
82
|
return null;
|
|
79
83
|
}
|
|
80
84
|
if (data.redacted === true) {
|
|
@@ -124,7 +128,7 @@ function GapSelect({
|
|
|
124
128
|
const sessionIdRef = react.useRef(null);
|
|
125
129
|
const choicesByGap = react.useMemo(() => {
|
|
126
130
|
const map = /* @__PURE__ */ new Map();
|
|
127
|
-
const seedSource = shuffleSeed ?? (sessionIdRef.current ??=
|
|
131
|
+
const seedSource = shuffleSeed ?? (sessionIdRef.current ??= chunkBAKLJKFZ_cjs.randomSessionId());
|
|
128
132
|
for (const gap of data.gaps) {
|
|
129
133
|
const choices = choicesFor(data.banks, gap);
|
|
130
134
|
map.set(
|
|
@@ -179,9 +183,9 @@ function GapSelect({
|
|
|
179
183
|
complete();
|
|
180
184
|
const timeSpent = getTimeSpent();
|
|
181
185
|
const xapiStatement = lkCore.xAPIBuilder.buildAnsweredStatement({
|
|
182
|
-
actor:
|
|
186
|
+
actor: chunkBAKLJKFZ_cjs.ANONYMOUS_ACTOR,
|
|
183
187
|
object: {
|
|
184
|
-
id:
|
|
188
|
+
id: chunkBAKLJKFZ_cjs.objectIdFor(data.id),
|
|
185
189
|
name: { [data.locale ?? "en-US"]: data.title },
|
|
186
190
|
...lkCore.xapiDefinitionFor(data)
|
|
187
191
|
},
|
|
@@ -243,7 +247,7 @@ function GapSelect({
|
|
|
243
247
|
onSubmit: handleSubmit,
|
|
244
248
|
children: [
|
|
245
249
|
data.media ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
246
|
-
|
|
250
|
+
chunkL7WY5YFQ_cjs.ActivityMedia,
|
|
247
251
|
{
|
|
248
252
|
media: data.media,
|
|
249
253
|
renderMode,
|
|
@@ -294,6 +298,20 @@ function GapSelect({
|
|
|
294
298
|
) : null
|
|
295
299
|
] }, seg.id);
|
|
296
300
|
}) }),
|
|
301
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
302
|
+
chunk5F4Q6JT7_cjs.AiHints,
|
|
303
|
+
{
|
|
304
|
+
ai,
|
|
305
|
+
data,
|
|
306
|
+
renderMode,
|
|
307
|
+
submitted,
|
|
308
|
+
disabled: disabled === true,
|
|
309
|
+
response: { type: "gap-select", selections },
|
|
310
|
+
locale,
|
|
311
|
+
onInteraction,
|
|
312
|
+
strings: s
|
|
313
|
+
}
|
|
314
|
+
),
|
|
297
315
|
isReview ? null : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", disabled: inactive, children: isExam ? s.submitAnswers : s.checkAnswers })
|
|
298
316
|
] }),
|
|
299
317
|
revealing && anyFeedback ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -306,16 +324,30 @@ function GapSelect({
|
|
|
306
324
|
children: feedbackHidden ? s.showFeedback : s.hideFeedback
|
|
307
325
|
}
|
|
308
326
|
) : null,
|
|
309
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunkBRPEB43C_cjs.FeedbackRegion, { id: `${data.id}-feedback`, children: isReview ? reviewSummary : summary })
|
|
327
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkBRPEB43C_cjs.FeedbackRegion, { id: `${data.id}-feedback`, children: isReview ? reviewSummary : summary }),
|
|
328
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
329
|
+
chunk5F4Q6JT7_cjs.AiExplanation,
|
|
330
|
+
{
|
|
331
|
+
ai,
|
|
332
|
+
data,
|
|
333
|
+
renderMode,
|
|
334
|
+
submitted,
|
|
335
|
+
response: { type: "gap-select", selections },
|
|
336
|
+
outcome,
|
|
337
|
+
locale,
|
|
338
|
+
onInteraction,
|
|
339
|
+
strings: s
|
|
340
|
+
}
|
|
341
|
+
)
|
|
310
342
|
]
|
|
311
343
|
}
|
|
312
344
|
);
|
|
313
345
|
}
|
|
314
346
|
function GapSelect2(props) {
|
|
315
|
-
const strings =
|
|
316
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
347
|
+
const strings = chunkAHGB5HH6_cjs.useLkStrings(props.strings);
|
|
348
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkBAKLJKFZ_cjs.ActivityErrorBoundary, { activityTitle: props.data?.title, strings, children: /* @__PURE__ */ jsxRuntime.jsx(GapSelect, { ...props }) });
|
|
317
349
|
}
|
|
318
350
|
|
|
319
351
|
exports.GapSelect = GapSelect2;
|
|
320
|
-
//# sourceMappingURL=chunk-
|
|
321
|
-
//# sourceMappingURL=chunk-
|
|
352
|
+
//# sourceMappingURL=chunk-QA42VDTA.cjs.map
|
|
353
|
+
//# sourceMappingURL=chunk-QA42VDTA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/GapSelect/GapSelect.tsx","../src/components/GapSelect/index.tsx"],"names":["useLkStrings","useLearnerAi","useMemo","isDevelopment","assertRedacted","result","validateActivity","ActivitySchemaError","useActivityState","useState","useRef","useEffect","randomSessionId","seededShuffle","score","xAPIBuilder","ANONYMOUS_ACTOR","objectIdFor","xapiDefinitionFor","jsxs","jsx","ActivityMedia","AiHints","FeedbackRegion","AiExplanation","GapSelect","ActivityErrorBoundary"],"mappings":"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","file":"chunk-QA42VDTA.cjs","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n assertRedacted,\n type GapSelectBank,\n type GapSelectChoice,\n type GapSelectData,\n type GapSelectGap,\n type GapSelectLearnerResponse,\n type LearnerResponse,\n type ScoringDetail,\n type ScoringResult,\n score,\n seededShuffle,\n validateActivity,\n xAPIBuilder,\n xapiDefinitionFor,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useLearnerAi } from '../../ai/LkAiProvider.js';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor, randomSessionId } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { AiExplanation, AiHints } from '../shared/AiHelp.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type { ActivityProps } from '../types.js';\n\nexport interface GapSelectProps extends ActivityProps<GapSelectData> {\n /**\n * Seeds the per-gap choice shuffle when `data.shuffleChoices` is set. Pass\n * the attempt id, exactly as on `<MultipleChoice>`: an order nobody can\n * reproduce cannot be reconciled with the attempt a server recorded. Without\n * one, a random per-mount seed is used — stable within the mount, and\n * deliberately not reproducible.\n */\n shuffleSeed?: string;\n}\n\nconst PLACEHOLDER = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\ntype Segment = { kind: 'text'; value: string } | { kind: 'gap'; id: string; ordinal: number };\n\n/** Splits a passage into literal text and its `{{id}}` gaps, in order. */\nfunction parsePassage(passage: string): Segment[] {\n const segments: Segment[] = [];\n const re = new RegExp(PLACEHOLDER);\n let last = 0;\n let ordinal = 0;\n let match = re.exec(passage);\n while (match !== null) {\n if (match.index > last) {\n segments.push({ kind: 'text', value: passage.slice(last, match.index) });\n }\n ordinal += 1;\n segments.push({ kind: 'gap', id: match[1] as string, ordinal });\n last = match.index + match[0].length;\n match = re.exec(passage);\n }\n if (last < passage.length) {\n segments.push({ kind: 'text', value: passage.slice(last) });\n }\n return segments;\n}\n\nconst NO_SELECTIONS: Record<string, string> = {};\n\n/**\n * The selections out of a `LearnerResponse`. A response of another activity\n * type reads as \"nothing selected\" rather than throwing — a controlled host\n * that has not yet swapped its state on an activity change would otherwise\n * crash the attempt.\n */\nfunction selectionsOf(response: LearnerResponse | undefined): Record<string, string> {\n return response !== undefined && response.type === 'gap-select'\n ? response.selections\n : NO_SELECTIONS;\n}\n\n/** Per-gap correctness keyed by gap id, preferring the unambiguous `outcome`. */\nfunction correctnessByItem(details: readonly ScoringDetail[]): Map<string, boolean> {\n const map = new Map<string, boolean>();\n for (const detail of details) {\n map.set(\n detail.itemId,\n detail.outcome !== undefined ? detail.outcome === 'correct' : detail.correct,\n );\n }\n return map;\n}\n\n/**\n * The choices a gap offers: its own list, or the bank it names.\n *\n * Both survive redaction — they are what the learner picks from — so this is\n * the one resolution that works identically on full and redacted data.\n */\nfunction choicesFor(\n banks: readonly GapSelectBank[] | undefined,\n gap: GapSelectGap,\n): readonly GapSelectChoice[] {\n if (gap.choices !== undefined) {\n return gap.choices;\n }\n return banks?.find((bank) => bank.id === gap.bankId)?.choices ?? [];\n}\n\nexport function GapSelect({\n data,\n onComplete,\n onSubmit,\n onChange,\n onInteraction,\n value,\n defaultValue,\n defaultSubmitted,\n renderMode = 'practice',\n outcome,\n mediaBudget,\n mediaStrings,\n strings,\n theme,\n locale,\n disabled,\n shuffleSeed,\n ai: aiProp,\n}: GapSelectProps) {\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n const s = useLkStrings(strings);\n const ai = useLearnerAi(aiProp);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n if (data.redacted === true) {\n try {\n assertRedacted(data);\n return null;\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n }\n const result = validateActivity('gap-select', data);\n return result.success ? null : new ActivitySchemaError('gap-select', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n const isControlled = value !== undefined;\n const [internalSelections, setInternalSelections] = useState<Record<string, string>>(() =>\n selectionsOf(defaultValue),\n );\n const [result, setResult] = useState<ScoringResult | null>(null);\n const [summary, setSummary] = useState<string | null>(null);\n const [feedbackHidden, setFeedbackHidden] = useState(false);\n\n const selections = isControlled ? selectionsOf(value) : internalSelections;\n\n const defaultValueRef = useRef(defaultValue);\n useEffect(() => {\n defaultValueRef.current = defaultValue;\n }, [defaultValue]);\n\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity-guarded so the mount run is a no-op: without it this fires after\n // the first paint and undoes every seed it was just given (Req 3.7).\n const lastDataRef = useRef(data);\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInternalSelections(selectionsOf(defaultValueRef.current));\n setResult(null);\n setSummary(null);\n setFeedbackHidden(false);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n const segments = useMemo(() => parsePassage(data.passage), [data.passage]);\n const gapById = useMemo(() => new Map(data.gaps.map((gap) => [gap.id, gap])), [data.gaps]);\n\n const sessionIdRef = useRef<string | null>(null);\n /**\n * The choices each gap shows, in the order it shows them.\n *\n * Seeded PER GAP, not once for the activity: two gaps drawing on the same\n * word bank must not be dealt the same order, or the bank's distractors line\n * up column-wise and the second gap becomes easier than the first.\n */\n const choicesByGap = useMemo(() => {\n const map = new Map<string, readonly GapSelectChoice[]>();\n // biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization\n const seedSource = shuffleSeed ?? (sessionIdRef.current ??= randomSessionId());\n for (const gap of data.gaps) {\n const choices = choicesFor(data.banks, gap);\n map.set(\n gap.id,\n data.shuffleChoices === true\n ? seededShuffle(choices, `${seedSource}:${data.id}:${gap.id}`)\n : choices,\n );\n }\n return map;\n }, [data, shuffleSeed]);\n\n // All hooks are called before these throws, so hook order stays stable.\n if (devError) {\n throw devError;\n }\n // Practice grades locally, and a redacted projection has no answer key to\n // grade against — `score()` would throw RedactedScoringError from the submit\n // handler, where no error boundary can reach it and after the learner has\n // answered. Fail at render instead, in production too, exactly as every other\n // built-in does.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Gap Select \"${data.id}\" received redacted activity data in renderMode \"practice\", ` +\n 'which grades locally and has no answer key to grade against. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n\n /**\n * Whether answer-key-derived information may be shown. Never in `exam`; in\n * `practice` only once this component has scored; in `review` only once the\n * caller supplies a SCORED outcome.\n */\n const revealing = isReview ? outcome?.status === 'scored' : !isExam && submitted;\n\n const fireInteraction = (\n type: 'gap-selected' | 'submitted',\n payload: Record<string, unknown>,\n ): void => {\n onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });\n };\n\n const handleSelect = (gapId: string, choiceId: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n const next = { ...selections, [gapId]: choiceId };\n if (!isControlled) {\n setInternalSelections(next);\n }\n onChange?.({ type: 'gap-select', selections: next });\n fireInteraction('gap-selected', { gapId, choiceId });\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive) {\n return;\n }\n const response: GapSelectLearnerResponse = { type: 'gap-select', selections };\n onSubmit?.(response);\n\n if (isExam) {\n // The client neither grades nor reveals: no score(), no read of any\n // answer-key field, no onComplete, and no xAPI statement — its\n // correctResponsesPattern IS the answer key.\n complete();\n setSummary(s.answerSubmitted);\n fireInteraction('submitted', { selections });\n return;\n }\n\n const scoringResult = score('gap-select', data as GapSelectData, response);\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildAnsweredStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n ...xapiDefinitionFor(data),\n },\n scoringResult,\n timeSpentMs: timeSpent,\n response: JSON.stringify(selections),\n });\n setResult(scoringResult);\n onComplete?.({\n score: scoringResult.score,\n maxScore: scoringResult.maxScore,\n passed: scoringResult.passed,\n timeSpent,\n xapiStatement,\n });\n const overall = scoringResult.feedback;\n setSummary(\n `${s.answerSubmitted} ${s.scoreAnnouncement(\n Math.round(scoringResult.score * 100),\n scoringResult.passed,\n )}${overall ? ` ${overall}` : ''}`,\n );\n fireInteraction('submitted', { selections, score: scoringResult.score });\n };\n\n const correctByGap = useMemo(() => {\n if (isExam) {\n return new Map<string, boolean>();\n }\n if (isReview) {\n return outcome?.status === 'scored'\n ? correctnessByItem(outcome.details)\n : new Map<string, boolean>();\n }\n return correctnessByItem(result?.details ?? []);\n }, [isExam, isReview, outcome, result]);\n\n const reviewSummary = useMemo(() => {\n if (!isReview || outcome === undefined) {\n return null;\n }\n if (outcome.status === 'scored') {\n return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n if (outcome.status === 'deferred') {\n return s.notGradedYet;\n }\n if (outcome.status === 'graded') {\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return `${s.scoreAnnouncement(percent, outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n return s.noGradeAvailable;\n }, [isReview, outcome, s]);\n\n const anyFeedback = data.gaps.some((gap) => gap.feedback !== undefined);\n\n return (\n <form\n className=\"lk-gs\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n <fieldset disabled={inactive}>\n <p className=\"lk-gs-passage\">\n {segments.map((seg, i) => {\n if (seg.kind === 'text') {\n // biome-ignore lint/suspicious/noArrayIndexKey: passage segments are positional and static\n return <span key={`t${i}`}>{seg.value}</span>;\n }\n const gap = gapById.get(seg.id);\n if (!gap) {\n return null;\n }\n const choices = choicesByGap.get(seg.id) ?? [];\n const correctness = correctByGap.get(seg.id);\n // Read defensively and never in exam: a redact() projection omits\n // both at runtime while the type still says they are there.\n const gapFeedback = isExam ? undefined : gap.feedback;\n return (\n <span key={seg.id} className=\"lk-gs-gap\">\n <select\n className=\"lk-gs-select\"\n aria-label={s.gapLabel(seg.ordinal)}\n value={selections[seg.id] ?? ''}\n disabled={inactive}\n aria-disabled={inactive || undefined}\n data-correct={\n revealing && correctness !== undefined ? String(correctness) : undefined\n }\n onChange={(e) => handleSelect(seg.id, e.target.value)}\n >\n {/*\n The empty entry is part of the contract, not a decoration.\n It is how a learner leaves a gap alone — and how they take\n an answer back — so \"not answered\" stays distinguishable\n from \"answered wrongly\" all the way into ItemOutcome, where\n the scorer reports it as `incorrect-omission`.\n */}\n <option value=\"\">{s.gapPlaceholder}</option>\n {choices.map((choice) => (\n <option key={choice.id} value={choice.id}>\n {choice.text}\n </option>\n ))}\n </select>\n {revealing && !feedbackHidden && gapFeedback ? (\n <span\n className=\"lk-gs-gap-feedback\"\n role=\"note\"\n data-correct={correctness !== undefined ? String(correctness) : undefined}\n >\n {gapFeedback}\n </span>\n ) : null}\n </span>\n );\n })}\n </p>\n <AiHints\n ai={ai}\n data={data}\n renderMode={renderMode}\n submitted={submitted}\n disabled={disabled === true}\n response={{ type: 'gap-select', selections }}\n locale={locale}\n onInteraction={onInteraction}\n strings={s}\n />\n {isReview ? null : (\n <button type=\"submit\" disabled={inactive}>\n {isExam ? s.submitAnswers : s.checkAnswers}\n </button>\n )}\n </fieldset>\n {revealing && anyFeedback ? (\n <button\n type=\"button\"\n className=\"lk-gs-feedback-toggle\"\n aria-expanded={!feedbackHidden}\n onClick={() => setFeedbackHidden((h) => !h)}\n >\n {feedbackHidden ? s.showFeedback : s.hideFeedback}\n </button>\n ) : null}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? reviewSummary : summary}\n </FeedbackRegion>\n <AiExplanation\n ai={ai}\n data={data}\n renderMode={renderMode}\n submitted={submitted}\n response={{ type: 'gap-select', selections }}\n outcome={outcome}\n locale={locale}\n onInteraction={onInteraction}\n strings={s}\n />\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport { GapSelect as GapSelectCore, type GapSelectProps } from './GapSelect.js';\n\nexport type { GapSelectProps } from './GapSelect.js';\n\n/**\n * Public Gap Select activity: the core wrapped in `ActivityErrorBoundary` so a\n * render failure (including the dev schema-validation throw and the\n * redacted-in-`practice` guard) degrades to an accessible fallback instead of\n * crashing the host.\n */\nexport function GapSelect(props: GapSelectProps) {\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <GapSelectCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import { AiHints, AiExplanation } from './chunk-GR33G5QM.js';
|
|
3
|
+
import { useLearnerAi } from './chunk-YNDKAYW3.js';
|
|
2
4
|
import { FeedbackRegion } from './chunk-RCMYEWBE.js';
|
|
3
|
-
import { ActivityErrorBoundary, isDevelopment, ANONYMOUS_ACTOR, objectIdFor } from './chunk-
|
|
4
|
-
import { ActivityMedia } from './chunk-
|
|
5
|
+
import { ActivityErrorBoundary, isDevelopment, ANONYMOUS_ACTOR, objectIdFor } from './chunk-YTGRXD23.js';
|
|
6
|
+
import { ActivityMedia } from './chunk-BY4UQH2Y.js';
|
|
5
7
|
import { useActivityState } from './chunk-6N43WDVG.js';
|
|
6
|
-
import { useLkStrings } from './chunk-
|
|
8
|
+
import { useLkStrings } from './chunk-YRNEOBXA.js';
|
|
7
9
|
import { assertRedacted, validateActivity, ActivitySchemaError, score, xAPIBuilder, xapiDefinitionFor } from '@intellectif/lk-core';
|
|
8
10
|
import { useMemo, useState, useRef, useEffect } from 'react';
|
|
9
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -61,11 +63,13 @@ function FillInTheBlanks({
|
|
|
61
63
|
theme,
|
|
62
64
|
locale,
|
|
63
65
|
disabled,
|
|
64
|
-
showCorrectAnswers
|
|
66
|
+
showCorrectAnswers,
|
|
67
|
+
ai: aiProp
|
|
65
68
|
}) {
|
|
66
69
|
const isExam = renderMode === "exam";
|
|
67
70
|
const isReview = renderMode === "review";
|
|
68
71
|
const s = useLkStrings(strings);
|
|
72
|
+
const ai = useLearnerAi(aiProp);
|
|
69
73
|
const devError = useMemo(() => {
|
|
70
74
|
if (!isDevelopment()) {
|
|
71
75
|
return null;
|
|
@@ -337,6 +341,20 @@ function FillInTheBlanks({
|
|
|
337
341
|
) : null
|
|
338
342
|
] }, seg.id);
|
|
339
343
|
}) }),
|
|
344
|
+
/* @__PURE__ */ jsx(
|
|
345
|
+
AiHints,
|
|
346
|
+
{
|
|
347
|
+
ai,
|
|
348
|
+
data,
|
|
349
|
+
renderMode,
|
|
350
|
+
submitted,
|
|
351
|
+
disabled: disabled === true,
|
|
352
|
+
response: { type: "fill-in-the-blanks", answers },
|
|
353
|
+
locale,
|
|
354
|
+
onInteraction,
|
|
355
|
+
strings: s
|
|
356
|
+
}
|
|
357
|
+
),
|
|
340
358
|
isReview ? null : /* @__PURE__ */ jsx("button", { type: "submit", disabled: inactive, children: isExam ? s.submitAnswers : s.checkAnswers })
|
|
341
359
|
] }),
|
|
342
360
|
revealing && data.blanks.some((b) => b.feedback) ? /* @__PURE__ */ jsx(
|
|
@@ -349,7 +367,21 @@ function FillInTheBlanks({
|
|
|
349
367
|
children: feedbackHidden ? s.showFeedback : s.hideFeedback
|
|
350
368
|
}
|
|
351
369
|
) : null,
|
|
352
|
-
/* @__PURE__ */ jsx(FeedbackRegion, { id: `${data.id}-feedback`, children: isReview ? reviewSummary : summary })
|
|
370
|
+
/* @__PURE__ */ jsx(FeedbackRegion, { id: `${data.id}-feedback`, children: isReview ? reviewSummary : summary }),
|
|
371
|
+
/* @__PURE__ */ jsx(
|
|
372
|
+
AiExplanation,
|
|
373
|
+
{
|
|
374
|
+
ai,
|
|
375
|
+
data,
|
|
376
|
+
renderMode,
|
|
377
|
+
submitted,
|
|
378
|
+
response: { type: "fill-in-the-blanks", answers },
|
|
379
|
+
outcome,
|
|
380
|
+
locale,
|
|
381
|
+
onInteraction,
|
|
382
|
+
strings: s
|
|
383
|
+
}
|
|
384
|
+
)
|
|
353
385
|
]
|
|
354
386
|
}
|
|
355
387
|
);
|
|
@@ -360,5 +392,5 @@ function FillInTheBlanks2(props) {
|
|
|
360
392
|
}
|
|
361
393
|
|
|
362
394
|
export { FillInTheBlanks2 as FillInTheBlanks };
|
|
363
|
-
//# sourceMappingURL=chunk-
|
|
364
|
-
//# sourceMappingURL=chunk-
|
|
395
|
+
//# sourceMappingURL=chunk-QHK6PTUR.js.map
|
|
396
|
+
//# sourceMappingURL=chunk-QHK6PTUR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/FillInTheBlanks/FillInTheBlanks.tsx","../src/components/FillInTheBlanks/index.tsx"],"names":["result","FillInTheBlanks","jsx"],"mappings":"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","file":"chunk-QHK6PTUR.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n assertRedacted,\n type FillInTheBlanksData,\n type FillInTheBlanksLearnerResponse,\n type LearnerResponse,\n type ScoringDetail,\n type ScoringResult,\n score,\n validateActivity,\n xAPIBuilder,\n xapiDefinitionFor,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useLearnerAi } from '../../ai/LkAiProvider.js';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { AiExplanation, AiHints } from '../shared/AiHelp.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type { ActivityProps } from '../types.js';\n\nexport interface FillInTheBlanksProps extends ActivityProps<FillInTheBlanksData> {\n /**\n * After submission, replace each incorrectly-answered blank with its first\n * accepted answer, styled distinctly (Req 5.7). Component-specific prop: it\n * is presentation, not activity data, and is outside the fixed Req-3.1 set.\n *\n * Ignored in `exam` mode — revealing the key is precisely what an exam must\n * not do, and on a `redact()` projection there is no key to reveal. In\n * `review` mode it applies only to blanks the supplied `outcome` marks\n * incorrect, and only when the caller passed data that still carries the key\n * (e.g. `redact(data, { reveal: 'after-submit' })`).\n */\n showCorrectAnswers?: boolean;\n}\n\nconst PLACEHOLDER = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\ntype Segment = { kind: 'text'; value: string } | { kind: 'blank'; id: string; ordinal: number };\n\nfunction parsePassage(passage: string): Segment[] {\n const segments: Segment[] = [];\n const re = new RegExp(PLACEHOLDER);\n let last = 0;\n let ordinal = 0;\n let match = re.exec(passage);\n while (match !== null) {\n if (match.index > last) {\n segments.push({ kind: 'text', value: passage.slice(last, match.index) });\n }\n ordinal += 1;\n segments.push({ kind: 'blank', id: match[1] as string, ordinal });\n last = match.index + match[0].length;\n match = re.exec(passage);\n }\n if (last < passage.length) {\n segments.push({ kind: 'text', value: passage.slice(last) });\n }\n return segments;\n}\n\n/** Shared empty map: keeps the \"no response supplied\" path allocation-free. */\nconst NO_ANSWERS: Record<string, string> = {};\n\n/**\n * Reads the answer map out of a `LearnerResponse`. A response of another\n * activity type is treated as \"no answers\" rather than throwing: a controlled\n * host that has not yet swapped its state on an activity change would\n * otherwise crash the attempt.\n */\nfunction answersOf(response: LearnerResponse | undefined): Record<string, string> {\n return response !== undefined && response.type === 'fill-in-the-blanks'\n ? response.answers\n : NO_ANSWERS;\n}\n\n/**\n * Per-item correctness keyed by blank id. Prefers the unambiguous `outcome`\n * field (always written by the built-in scorers since lk-core 0.3.0) and\n * falls back to the deprecated `correct` boolean so a 0.2-era\n * consumer-constructed `ItemOutcome` still marks correctly in `review`.\n */\nfunction correctnessByItem(details: readonly ScoringDetail[]): Map<string, boolean> {\n const map = new Map<string, boolean>();\n for (const detail of details) {\n map.set(\n detail.itemId,\n detail.outcome !== undefined ? detail.outcome === 'correct' : detail.correct,\n );\n }\n return map;\n}\n\nexport function FillInTheBlanks({\n data,\n onComplete,\n onSubmit,\n onChange,\n onInteraction,\n value,\n defaultValue,\n defaultSubmitted,\n renderMode = 'practice',\n outcome,\n sanitizeHtml,\n mediaBudget,\n mediaStrings,\n strings,\n theme,\n locale,\n disabled,\n showCorrectAnswers,\n ai: aiProp,\n}: FillInTheBlanksProps) {\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n\n // Dev-only boundary validation (Req 2.3); throws in render so the wrapping\n // ActivityErrorBoundary catches it. Re-runs only when data changes.\n const s = useLkStrings(strings);\n const ai = useLearnerAi(aiProp);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n if (data.redacted === true) {\n // A redact() projection cannot satisfy the full content schema — the\n // answer key is gone by design. Validate it against the STRICT redacted\n // schema instead, which additionally proves the payload is learner-safe.\n try {\n assertRedacted(data);\n return null;\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n }\n const result = validateActivity('fill-in-the-blanks', data);\n return result.success ? null : new ActivitySchemaError('fill-in-the-blanks', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n // Controlled when `value` is supplied: the answers rendered are ALWAYS the\n // caller's, and internal state is never read. Uncontrolled otherwise,\n // seeded from `defaultValue`.\n const isControlled = value !== undefined;\n const [internalAnswers, setInternalAnswers] = useState<Record<string, string>>(() =>\n answersOf(defaultValue),\n );\n const [revealed, setRevealed] = useState<Set<string>>(() => new Set());\n const [result, setResult] = useState<ScoringResult | null>(null);\n const [summary, setSummary] = useState<string | null>(null);\n const [feedbackHidden, setFeedbackHidden] = useState(false);\n\n const answers = isControlled ? answersOf(value) : internalAnswers;\n\n // `defaultValue` is read only by the reset effect, and it is commonly an\n // inline object literal — putting it in that effect's deps would re-seed\n // (and wipe) the learner's typing on every render. Mirror it into a ref in\n // its own effect, which commits before the reset effect below.\n const defaultValueRef = useRef(defaultValue);\n useEffect(() => {\n defaultValueRef.current = defaultValue;\n }, [defaultValue]);\n\n // Mirror `defaultSubmitted` so the reset below returns to the SEEDED state.\n // Resetting unconditionally to idle unlocked an item the learner had already\n // committed — which made `defaultSubmitted` a no-op here, since this effect\n // runs right after the first paint.\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity guard so the MOUNT run is a no-op. Without it this effect fires\n // after the first paint and undoes every seed it was just given; with it,\n // only a real `data` change resets. A parent that rebuilds structurally\n // identical entries in render (`activities={raw.map(redact)}`) must not\n // unlock or revert a restored answer — the pager already remounts a slot\n // whose activity actually changed, via its key.\n const lastDataRef = useRef(data);\n // `data` is an intentional reset trigger (Req 3.7); it is already in the\n // dependency list. The identity guard below skips the mount run.\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInternalAnswers(answersOf(defaultValueRef.current));\n setRevealed(new Set());\n setResult(null);\n setSummary(null);\n setFeedbackHidden(false);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n /*\n * RICH TEXT — deliberate, documented limitation (see `sanitizeHtml`).\n *\n * Every other activity can render its `*Html` field through the caller's\n * sanitiser, because the rich text is a LEAF: the sanitised string is\n * handed to one `dangerouslySetInnerHTML` node and nothing is inserted into\n * it. A fill-in-the-blanks passage is not a leaf — it is the CONTAINER of\n * the React-controlled `<input>`s, one per `{{id}}` placeholder.\n *\n * Placing those inputs inside sanitised HTML means slicing the sanitised\n * string at the placeholders and injecting each slice as its own HTML\n * fragment, which is unsafe and broken on both counts:\n * 1. Broken: the slices are unbalanced. `<p>A {{x}} B</p>` yields `<p>A `\n * and ` B</p>`; the fragment parser auto-closes both, so the input\n * lands OUTSIDE the paragraph and the authored block structure is\n * destroyed.\n * 2. Unsafe: the sanitiser's guarantee covers the document it returned,\n * not arbitrary substrings of it. A placeholder inside an attribute\n * (`<img alt=\"{{x}}\">`) splits mid-attribute, and re-parsing the\n * halves in a fresh context is exactly the mutation (mXSS) class of\n * transformation that voids a sanitiser's output guarantee. An exam\n * runner must never depend on that.\n *\n * The safe alternative — parse the sanitised string once into a detached\n * DOM, split only TEXT nodes at placeholders, and portal the inputs into\n * anchors — needs a DOM at render time (no SSR) and a large imperative\n * subsystem. Until that lands, the plain-text `passage` is rendered (always\n * escaped by React), which is correct, answerable, and safe in every mode.\n * `data.passageHtml` is carried and redacted by lk-core regardless, so no\n * authored content is lost — only this component declines to render it.\n */\n useEffect(() => {\n if (isDevelopment() && sanitizeHtml !== undefined && data.passageHtml !== undefined) {\n console.warn(\n '[lk-react] FillInTheBlanks ignores `passageHtml`: the passage hosts the answer inputs, ' +\n 'so rich HTML cannot be split at {{placeholders}} without voiding the sanitiser. ' +\n 'Rendering the plain `passage` instead.',\n );\n }\n }, [sanitizeHtml, data.passageHtml]);\n\n const segments = useMemo(() => parsePassage(data.passage), [data.passage]);\n const blankById = useMemo(() => new Map(data.blanks.map((b) => [b.id, b])), [data.blanks]);\n\n if (devError) {\n throw devError;\n }\n // Practice grades locally, which a redacted projection cannot support: the\n // submit handler below calls `score()`, which throws RedactedScoringError —\n // from an event handler, where no error boundary can catch it, AFTER the\n // learner has typed their answers. Fail loudly at render instead, in\n // production too. This mirrors the identical guard in MultipleChoice;\n // without it the two built-ins disagreed about the same accident, and\n // wiring an exam item into the self-grading mode is precisely what\n // `renderMode` exists to prevent.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Fill-in-the-Blanks \"${data.id}\" received redacted activity data in renderMode \"practice\", ` +\n 'which grades locally and has no answer key to grade against. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n\n /**\n * Whether the component may show answer-key-derived information (per-blank\n * correctness, authored feedback, correct answers). NEVER in `exam`; in\n * `practice` only after the component scored locally; in `review` only once\n * the caller supplies a SCORED outcome — an item that is still awaiting a\n * grade must not have its key revealed just because it is being read back.\n */\n const revealing = isReview ? outcome?.status === 'scored' : !isExam && submitted;\n\n const fireInteraction = (\n type: 'blank-filled' | 'hint-requested' | 'submitted',\n payload: Record<string, unknown>,\n ): void => {\n onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });\n };\n\n const handleChange = (blankId: string, text: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n const next = { ...answers, [blankId]: text };\n if (!isControlled) {\n setInternalAnswers(next);\n }\n onChange?.({ type: 'fill-in-the-blanks', answers: next });\n fireInteraction('blank-filled', { blankId, value: text });\n };\n\n const toggleHint = (blankId: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n setRevealed((prev) => {\n const next = new Set(prev);\n if (next.has(blankId)) {\n next.delete(blankId);\n return next;\n }\n next.add(blankId);\n return next;\n });\n // Only a reveal is a \"hint requested\"; hiding is not a new request.\n if (!revealed.has(blankId)) {\n fireInteraction('hint-requested', { blankId });\n }\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive) {\n return;\n }\n const response: FillInTheBlanksLearnerResponse = { type: 'fill-in-the-blanks', answers };\n // Fires in every submitting mode and always BEFORE onComplete, so an exam\n // runner can persist the raw response regardless of local grading.\n onSubmit?.(response);\n\n if (isExam) {\n // EXAM: the client neither grades nor reveals. No score()/evaluate(), no\n // read of any answer-key field, no onComplete — and no xAPI statement,\n // because its `correctResponsesPattern` IS the answer key. The server\n // owns the grade; it emits the statement.\n complete();\n setSummary(s.answerSubmitted);\n fireInteraction('submitted', { answers });\n return;\n }\n\n // PRACTICE: unchanged v1 behaviour. `data` carries the key here — exam\n // mode is the only path that may be handed a redact() projection.\n const scoringResult = score('fill-in-the-blanks', data as FillInTheBlanksData, response);\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildAnsweredStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n ...xapiDefinitionFor(data),\n },\n scoringResult,\n timeSpentMs: timeSpent,\n response: JSON.stringify(answers),\n });\n setResult(scoringResult);\n onComplete?.({\n score: scoringResult.score,\n maxScore: scoringResult.maxScore,\n passed: scoringResult.passed,\n timeSpent,\n xapiStatement,\n });\n // Core selects the authored overall feedback on `passed` (B3 fix).\n const overall = scoringResult.feedback;\n setSummary(\n `${s.answerSubmitted} ${s.scoreAnnouncement(\n Math.round(scoringResult.score * 100),\n scoringResult.passed,\n )}${overall ? ` ${overall}` : ''}`,\n );\n fireInteraction('submitted', { answers, score: scoringResult.score });\n };\n\n const correctByBlank = useMemo(() => {\n if (isExam) {\n // Nothing is ever marked client-side in an exam.\n return new Map<string, boolean>();\n }\n if (isReview) {\n // Correctness comes ONLY from the server-computed outcome; the component\n // never scores in review, so an absent/ungraded outcome marks nothing.\n return outcome?.status === 'scored'\n ? correctnessByItem(outcome.details)\n : new Map<string, boolean>();\n }\n return correctnessByItem(result?.details ?? []);\n }, [isExam, isReview, outcome, result]);\n\n /** Review has no local score: its summary is read off `outcome`, or nothing. */\n const reviewSummary = useMemo(() => {\n if (!isReview || outcome === undefined) {\n return null;\n }\n if (outcome.status === 'scored') {\n return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n if (outcome.status === 'deferred') {\n return s.notGradedYet;\n }\n // `graded` used to fall into the arm below and announce \"No grade\n // available.\" over a grade that had come back. Normalised by maxScore so a\n // grader payload of 8.5 / 10 does not read as 850% — same guard as\n // `<WrittenResponse>`.\n if (outcome.status === 'graded') {\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return `${s.scoreAnnouncement(percent, outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n return s.noGradeAvailable;\n }, [isReview, outcome, s]);\n\n return (\n <form\n className=\"lk-fib\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n <fieldset disabled={inactive}>\n <p className=\"lk-fib-passage\">\n {segments.map((seg, i) => {\n if (seg.kind === 'text') {\n // biome-ignore lint/suspicious/noArrayIndexKey: passage segments are positional and static\n return <span key={`t${i}`}>{seg.value}</span>;\n }\n const blank = blankById.get(seg.id);\n if (!blank) {\n return null;\n }\n // `Renderable` only widens `scoringStrategy` at the type level, so\n // the answer-key fields still LOOK required here while a redact()\n // projection omits them at runtime. Read them defensively, and\n // never at all in exam mode.\n const acceptedAnswers: string[] | undefined = isExam\n ? undefined\n : blank.acceptedAnswers;\n const blankFeedback = isExam ? undefined : blank.feedback;\n const correctness = correctByBlank.get(seg.id);\n const hintId = `${data.id}-hint-${seg.id}`;\n const correctAnswer = acceptedAnswers?.[0];\n if (revealing && showCorrectAnswers && correctness === false && correctAnswer) {\n return (\n <span key={seg.id} className=\"lk-fib-answer\" data-correct=\"false\">\n {correctAnswer}\n </span>\n );\n }\n return (\n <span key={seg.id} className=\"lk-fib-blank\">\n <input\n type=\"text\"\n aria-label={s.blankLabel(seg.ordinal)}\n aria-describedby={blank.hint ? hintId : undefined}\n value={answers[seg.id] ?? ''}\n disabled={inactive}\n aria-disabled={inactive || undefined}\n data-correct={\n revealing && correctness !== undefined ? String(correctness) : undefined\n }\n onChange={(e) => handleChange(seg.id, e.target.value)}\n />\n {/*\n Hints stay available in exam mode by design: lk-core's field\n policy classifies `blanks.hint` as `public`, so it survives\n redact() and is not part of the answer key.\n */}\n {blank.hint ? (\n <>\n {/*\n Default affordance is an icon; the accessible NAME stays\n text via aria-label (screen readers + tests rely on it).\n The glyph is restylable/replaceable via .lk-fib-hint-btn.\n */}\n <button\n type=\"button\"\n className=\"lk-fib-hint-btn\"\n aria-controls={hintId}\n aria-expanded={revealed.has(seg.id)}\n aria-label={revealed.has(seg.id) ? s.hideHint : s.showHint}\n disabled={inactive}\n onClick={() => toggleHint(seg.id)}\n >\n <svg\n className=\"lk-fib-hint-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n fill=\"currentColor\"\n d=\"M9 21h6v-1H9v1Zm3-19a7 7 0 0 0-4 12.74V17h8v-2.26A7 7 0 0 0 12 2Z\"\n />\n </svg>\n </button>\n {/*\n Not role=\"tooltip\": a real ARIA tooltip is a named\n hover/focus popup with strict WCAG 1.4.13 constraints.\n This is an accessible click-to-toggle disclosure that is\n the input's aria-describedby target and is announced via\n aria-live; the skin gives it a tooltip-like *visual*\n without the tooltip *semantics*. (Refines Task 15.3.)\n */}\n <span id={hintId} aria-live=\"polite\">\n {revealed.has(seg.id) ? blank.hint : ''}\n </span>\n </>\n ) : null}\n {revealing && !feedbackHidden && blankFeedback ? (\n <span\n className=\"lk-fib-blank-feedback\"\n role=\"note\"\n data-correct={correctness !== undefined ? String(correctness) : undefined}\n >\n {blankFeedback}\n </span>\n ) : null}\n </span>\n );\n })}\n </p>\n <AiHints\n ai={ai}\n data={data}\n renderMode={renderMode}\n submitted={submitted}\n disabled={disabled === true}\n response={{ type: 'fill-in-the-blanks', answers }}\n locale={locale}\n onInteraction={onInteraction}\n strings={s}\n />\n {/* Review is read-only: there is nothing to submit. */}\n {isReview ? null : (\n <button type=\"submit\" disabled={inactive}>\n {isExam ? s.submitAnswers : s.checkAnswers}\n </button>\n )}\n </fieldset>\n {revealing && data.blanks.some((b) => b.feedback) ? (\n <button\n type=\"button\"\n className=\"lk-fib-feedback-toggle\"\n aria-expanded={!feedbackHidden}\n onClick={() => setFeedbackHidden((h) => !h)}\n >\n {feedbackHidden ? s.showFeedback : s.hideFeedback}\n </button>\n ) : null}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? reviewSummary : summary}\n </FeedbackRegion>\n <AiExplanation\n ai={ai}\n data={data}\n renderMode={renderMode}\n submitted={submitted}\n response={{ type: 'fill-in-the-blanks', answers }}\n outcome={outcome}\n locale={locale}\n onInteraction={onInteraction}\n strings={s}\n />\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport {\n FillInTheBlanks as FillInTheBlanksCore,\n type FillInTheBlanksProps,\n} from './FillInTheBlanks.js';\n\nexport type { FillInTheBlanksProps } from './FillInTheBlanks.js';\n\n/**\n * Public Fill-in-the-Blanks activity: the core wrapped in\n * `ActivityErrorBoundary` so a render failure (incl. the dev schema-validation\n * throw) degrades to an accessible fallback instead of crashing the host.\n */\nexport function FillInTheBlanks(props: FillInTheBlanksProps) {\n // Read here rather than in the boundary: a class component cannot call a\n // hook, and the fallback it renders is learner-facing text like any other.\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <FillInTheBlanksCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { localeDirectionOf } from './chunk-YORQQXGO.js';
|
|
3
|
-
import { ActivityErrorBoundary, isDevelopment } from './chunk-
|
|
4
|
-
import { useLkStrings } from './chunk-
|
|
3
|
+
import { ActivityErrorBoundary, isDevelopment } from './chunk-YTGRXD23.js';
|
|
4
|
+
import { useLkStrings } from './chunk-YRNEOBXA.js';
|
|
5
5
|
import { ActivitySchemaError, alignReadAloud, validateSpeechAssessment } from '@intellectif/lk-core';
|
|
6
6
|
import { useState, useCallback, useId, useMemo, useRef, useEffect } from 'react';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -533,5 +533,5 @@ function PronunciationFeedback2(props) {
|
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
export { PronunciationFeedback2 as PronunciationFeedback, VISUALLY_HIDDEN, fractionOfGrade, markSentence, percentOfGrade, readAssessResult, readEvidence, readOutcome, usePlaybackRefusal };
|
|
536
|
-
//# sourceMappingURL=chunk-
|
|
537
|
-
//# sourceMappingURL=chunk-
|
|
536
|
+
//# sourceMappingURL=chunk-QJW3K6JN.js.map
|
|
537
|
+
//# sourceMappingURL=chunk-QJW3K6JN.js.map
|