@intellectif/lk-core 0.14.0 → 0.15.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 +31 -0
- package/README.md +1 -0
- package/dist/{activity-BVkg9VDo.d.cts → activity-C7cR8U9n.d.cts} +35 -2
- package/dist/{activity-BVkg9VDo.d.ts → activity-C7cR8U9n.d.ts} +35 -2
- package/dist/{chunk-R7PV3XIC.js → chunk-54XYQ3CS.js} +7 -4
- package/dist/chunk-54XYQ3CS.js.map +1 -0
- package/dist/{chunk-J5OIRIOW.cjs → chunk-5KWF34LJ.cjs} +31 -31
- package/dist/{chunk-J5OIRIOW.cjs.map → chunk-5KWF34LJ.cjs.map} +1 -1
- package/dist/{chunk-CZRUMHKW.cjs → chunk-7ETU6EXQ.cjs} +13 -10
- package/dist/chunk-7ETU6EXQ.cjs.map +1 -0
- package/dist/{chunk-6RND47QE.js → chunk-DPHX4E7X.js} +62 -3
- package/dist/chunk-DPHX4E7X.js.map +1 -0
- package/dist/{chunk-NBADQ3JU.js → chunk-EEMVWBPP.js} +195 -4
- package/dist/chunk-EEMVWBPP.js.map +1 -0
- package/dist/{chunk-RTIR6R2U.js → chunk-L6YBQXSB.js} +2 -2
- package/dist/{chunk-VCXIPLEW.cjs → chunk-QFWEF5ST.cjs} +63 -4
- package/dist/chunk-QFWEF5ST.cjs.map +1 -0
- package/dist/chunk-W7AQP6AV.cjs +418 -0
- package/dist/chunk-W7AQP6AV.cjs.map +1 -0
- package/dist/{index-v2_-Fyn3.d.ts → index-BWyMDlUS.d.cts} +367 -2
- package/dist/{index-BE1bM2Wi.d.cts → index-D10NaztZ.d.ts} +367 -2
- package/dist/index.cjs +397 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -7
- package/dist/index.d.ts +103 -7
- package/dist/index.js +310 -9
- package/dist/index.js.map +1 -1
- package/dist/schemas.cjs +11 -3
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/schemas.js +10 -2
- package/dist/scoring.cjs +3 -3
- package/dist/scoring.d.cts +2 -2
- package/dist/scoring.d.ts +2 -2
- package/dist/scoring.js +2 -2
- package/dist/xapi.cjs +3 -3
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/dist/xapi.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-2NIALQEH.cjs +0 -227
- package/dist/chunk-2NIALQEH.cjs.map +0 -1
- package/dist/chunk-6RND47QE.js.map +0 -1
- package/dist/chunk-CZRUMHKW.cjs.map +0 -1
- package/dist/chunk-NBADQ3JU.js.map +0 -1
- package/dist/chunk-R7PV3XIC.js.map +0 -1
- package/dist/chunk-VCXIPLEW.cjs.map +0 -1
- /package/dist/{chunk-RTIR6R2U.js.map → chunk-L6YBQXSB.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
var
|
|
19
|
+
var _chunk5KWF34LJcjs = require('./chunk-5KWF34LJ.cjs');
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
var
|
|
26
|
+
var _chunk7ETU6EXQcjs = require('./chunk-7ETU6EXQ.cjs');
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
@@ -40,7 +40,6 @@ var _chunkCZRUMHKWcjs = require('./chunk-CZRUMHKW.cjs');
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
var _chunk2NIALQEHcjs = require('./chunk-2NIALQEH.cjs');
|
|
44
43
|
|
|
45
44
|
|
|
46
45
|
|
|
@@ -50,6 +49,7 @@ var _chunk2NIALQEHcjs = require('./chunk-2NIALQEH.cjs');
|
|
|
50
49
|
|
|
51
50
|
|
|
52
51
|
|
|
52
|
+
var _chunkW7AQP6AVcjs = require('./chunk-W7AQP6AV.cjs');
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
|
|
@@ -124,7 +124,17 @@ var _chunk2NIALQEHcjs = require('./chunk-2NIALQEH.cjs');
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
var _chunkQFWEF5STcjs = require('./chunk-QFWEF5ST.cjs');
|
|
128
138
|
|
|
129
139
|
// src/content-hash.ts
|
|
130
140
|
function canonicalJson(value, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -226,6 +236,20 @@ function keyOf(entry) {
|
|
|
226
236
|
}
|
|
227
237
|
return key;
|
|
228
238
|
}
|
|
239
|
+
function inQuizOrder(items, timeline) {
|
|
240
|
+
const placement = /* @__PURE__ */ new Map();
|
|
241
|
+
timeline.cues.forEach((cue, cueIndex) => {
|
|
242
|
+
cue.itemIds.forEach((itemId, position) => {
|
|
243
|
+
if (!placement.has(itemId)) {
|
|
244
|
+
placement.set(itemId, { at: cue.at, cue: cueIndex, position });
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
const unplaced = { at: Number.POSITIVE_INFINITY, cue: Number.POSITIVE_INFINITY, position: 0 };
|
|
249
|
+
return items.map((entry) => ({ entry, place: _nullishCoalesce(placement.get(entry.item.id), () => ( unplaced)) })).sort(
|
|
250
|
+
(a, b) => a.place.at - b.place.at || a.place.cue - b.place.cue || a.place.position - b.place.position || a.entry.itemIndex - b.entry.itemIndex
|
|
251
|
+
).map(({ entry }) => entry);
|
|
252
|
+
}
|
|
229
253
|
function flattenSequence(entries, options = {}) {
|
|
230
254
|
const shuffleEntries = options.shuffleEntries === true;
|
|
231
255
|
const needsSeed = shuffleEntries || entries.some((entry) => isItemGroup(entry) && entry.shuffle === "within-group");
|
|
@@ -249,11 +273,20 @@ function flattenSequence(entries, options = {}) {
|
|
|
249
273
|
`flattenSequence: item group "${entry.id}" has no items. An empty group would silently remove its stimulus and its questions from the presented sequence.`
|
|
250
274
|
);
|
|
251
275
|
}
|
|
276
|
+
const timeline = entry.timeline;
|
|
277
|
+
if (timeline !== void 0 && entry.shuffle === "within-group") {
|
|
278
|
+
throw new Error(
|
|
279
|
+
`flattenSequence: item group "${entry.id}" has a timeline and shuffle: "within-group". An interactive video presents its questions in the order its quizzes open.`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
252
282
|
const items = entry.items.map((item, itemIndex) => ({ item, itemIndex }));
|
|
253
|
-
const presented = entry.shuffle === "within-group" ? seededShuffle(items, `${seed}:group:${entry.id}`) : items;
|
|
283
|
+
const presented = timeline !== void 0 ? inQuizOrder(items, timeline) : entry.shuffle === "within-group" ? seededShuffle(items, `${seed}:group:${entry.id}`) : items;
|
|
254
284
|
const size = presented.length;
|
|
255
285
|
presented.forEach(({ item, itemIndex }, position) => {
|
|
286
|
+
const cue = _optionalChain([timeline, 'optionalAccess', _ => _.cues, 'access', _2 => _2.find, 'call', _3 => _3((candidate) => candidate.itemIds.includes(item.id))]);
|
|
256
287
|
slots.push({
|
|
288
|
+
// Slot ids stay AUTHORED — the item's index or its key — whatever the
|
|
289
|
+
// presented order: moving a quiz must never re-map a stored answer.
|
|
257
290
|
slotId: `${entryKey}.${_nullishCoalesce(keyOf(item), () => ( String(itemIndex)))}`,
|
|
258
291
|
index: slots.length,
|
|
259
292
|
activity: item,
|
|
@@ -262,7 +295,9 @@ function flattenSequence(entries, options = {}) {
|
|
|
262
295
|
...entry.title !== void 0 ? { title: entry.title } : {},
|
|
263
296
|
stimulus: entry.stimulus,
|
|
264
297
|
position,
|
|
265
|
-
size
|
|
298
|
+
size,
|
|
299
|
+
...timeline !== void 0 ? { timeline } : {},
|
|
300
|
+
...cue !== void 0 ? { cue } : {}
|
|
266
301
|
}
|
|
267
302
|
});
|
|
268
303
|
});
|
|
@@ -302,16 +337,16 @@ function stimulusMediaKey(slotId) {
|
|
|
302
337
|
}
|
|
303
338
|
function resolvePlaybackPolicy(media) {
|
|
304
339
|
const p = media.playback;
|
|
305
|
-
const budgeted = typeof _optionalChain([p, 'optionalAccess',
|
|
306
|
-
const seek = _nullishCoalesce(_optionalChain([p, 'optionalAccess',
|
|
307
|
-
const rate = _nullishCoalesce(_optionalChain([p, 'optionalAccess',
|
|
308
|
-
const controls = _nullishCoalesce(_optionalChain([p, 'optionalAccess',
|
|
340
|
+
const budgeted = typeof _optionalChain([p, 'optionalAccess', _4 => _4.maxPlays]) === "number";
|
|
341
|
+
const seek = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _5 => _5.seek]), () => ( (budgeted ? "none" : "allow")));
|
|
342
|
+
const rate = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _6 => _6.rate]), () => ( "allow"));
|
|
343
|
+
const controls = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _7 => _7.controls]), () => ( (budgeted || seek === "none" || rate === "fixed" ? "minimal" : "native")));
|
|
309
344
|
return {
|
|
310
345
|
controls,
|
|
311
|
-
maxPlays: budgeted ? _optionalChain([p, 'optionalAccess',
|
|
346
|
+
maxPlays: budgeted ? _optionalChain([p, 'optionalAccess', _8 => _8.maxPlays]) : null,
|
|
312
347
|
seek,
|
|
313
348
|
rate,
|
|
314
|
-
nativeControlHints: _nullishCoalesce(_optionalChain([p, 'optionalAccess',
|
|
349
|
+
nativeControlHints: _nullishCoalesce(_optionalChain([p, 'optionalAccess', _9 => _9.nativeControlHints]), () => ( []))
|
|
315
350
|
};
|
|
316
351
|
}
|
|
317
352
|
function planMediaBudgets(plan) {
|
|
@@ -326,7 +361,7 @@ function planMediaBudgets(plan) {
|
|
|
326
361
|
function assertEntry(key, entry) {
|
|
327
362
|
if (entry === null || typeof entry !== "object" || !Number.isInteger(entry.plays) || entry.plays < 0) {
|
|
328
363
|
throw new Error(
|
|
329
|
-
`serializeMediaPlayLedger: play count for ${JSON.stringify(key)} is ${JSON.stringify(_optionalChain([entry, 'optionalAccess',
|
|
364
|
+
`serializeMediaPlayLedger: play count for ${JSON.stringify(key)} is ${JSON.stringify(_optionalChain([entry, 'optionalAccess', _10 => _10.plays]))}. A count must be a non-negative integer; Number(a NULL column) is the usual cause.`
|
|
330
365
|
);
|
|
331
366
|
}
|
|
332
367
|
if (entry.at !== void 0 && (!Number.isFinite(entry.at) || entry.at < 0)) {
|
|
@@ -399,7 +434,7 @@ function mediaBudgetsOf(slot) {
|
|
|
399
434
|
budgets.push({ key: slotMediaKey(slot.slotId), maxPlays });
|
|
400
435
|
}
|
|
401
436
|
}
|
|
402
|
-
const stimulusMedia = _optionalChain([slot, 'access',
|
|
437
|
+
const stimulusMedia = _optionalChain([slot, 'access', _11 => _11.group, 'optionalAccess', _12 => _12.stimulus, 'access', _13 => _13.media]);
|
|
403
438
|
if (stimulusMedia !== void 0) {
|
|
404
439
|
const maxPlays = resolvePlaybackPolicy(stimulusMedia).maxPlays;
|
|
405
440
|
if (maxPlays !== null) {
|
|
@@ -445,7 +480,14 @@ function planSlot(slot, points) {
|
|
|
445
480
|
group: {
|
|
446
481
|
id: slot.group.id,
|
|
447
482
|
...slot.group.title !== void 0 ? { title: slot.group.title } : {},
|
|
448
|
-
stimulusHash: contentHash(slot.group.stimulus)
|
|
483
|
+
stimulusHash: contentHash(slot.group.stimulus),
|
|
484
|
+
...slot.group.cue !== void 0 ? {
|
|
485
|
+
cue: {
|
|
486
|
+
id: slot.group.cue.id,
|
|
487
|
+
at: slot.group.cue.at,
|
|
488
|
+
...slot.group.cue.required !== void 0 ? { required: slot.group.cue.required } : {}
|
|
489
|
+
}
|
|
490
|
+
} : {}
|
|
449
491
|
}
|
|
450
492
|
} : {},
|
|
451
493
|
...mediaBudgets !== void 0 ? { mediaBudgets } : {}
|
|
@@ -458,7 +500,7 @@ function planAttempt(entries, options = {}) {
|
|
|
458
500
|
...seed !== void 0 ? { seed } : {}
|
|
459
501
|
});
|
|
460
502
|
assertNoSplitBudgets(slots);
|
|
461
|
-
const planned = slots.map((slot) => planSlot(slot, _nullishCoalesce(_optionalChain([points, 'optionalCall',
|
|
503
|
+
const planned = slots.map((slot) => planSlot(slot, _nullishCoalesce(_optionalChain([points, 'optionalCall', _14 => _14(slot)]), () => ( 1))));
|
|
462
504
|
const totalPoints = planned.reduce((sum, slot) => sum + slot.points, 0);
|
|
463
505
|
return {
|
|
464
506
|
planVersion: "1.0",
|
|
@@ -479,6 +521,7 @@ function verifyAttemptPlan(plan, current) {
|
|
|
479
521
|
const addedSlotIds = current.slots.filter((s) => !before.has(s.slotId)).map((s) => s.slotId);
|
|
480
522
|
const changedSlotIds = [];
|
|
481
523
|
const changedStimulusSlotIds = [];
|
|
524
|
+
const changedCueSlotIds = [];
|
|
482
525
|
const changedPointsSlotIds = [];
|
|
483
526
|
const reorderedSlotIds = [];
|
|
484
527
|
for (const slot of plan.slots) {
|
|
@@ -489,9 +532,12 @@ function verifyAttemptPlan(plan, current) {
|
|
|
489
532
|
if (now.contentHash !== slot.contentHash) {
|
|
490
533
|
changedSlotIds.push(slot.slotId);
|
|
491
534
|
}
|
|
492
|
-
if (_optionalChain([now, 'access',
|
|
535
|
+
if (_optionalChain([now, 'access', _15 => _15.group, 'optionalAccess', _16 => _16.stimulusHash]) !== _optionalChain([slot, 'access', _17 => _17.group, 'optionalAccess', _18 => _18.stimulusHash])) {
|
|
493
536
|
changedStimulusSlotIds.push(slot.slotId);
|
|
494
537
|
}
|
|
538
|
+
if (contentHash(_nullishCoalesce(_optionalChain([now, 'access', _19 => _19.group, 'optionalAccess', _20 => _20.cue]), () => ( null))) !== contentHash(_nullishCoalesce(_optionalChain([slot, 'access', _21 => _21.group, 'optionalAccess', _22 => _22.cue]), () => ( null)))) {
|
|
539
|
+
changedCueSlotIds.push(slot.slotId);
|
|
540
|
+
}
|
|
495
541
|
if (now.points !== slot.points) {
|
|
496
542
|
changedPointsSlotIds.push(slot.slotId);
|
|
497
543
|
}
|
|
@@ -500,11 +546,12 @@ function verifyAttemptPlan(plan, current) {
|
|
|
500
546
|
}
|
|
501
547
|
}
|
|
502
548
|
return {
|
|
503
|
-
matches: missingSlotIds.length === 0 && addedSlotIds.length === 0 && changedSlotIds.length === 0 && changedStimulusSlotIds.length === 0 && changedPointsSlotIds.length === 0 && reorderedSlotIds.length === 0,
|
|
549
|
+
matches: missingSlotIds.length === 0 && addedSlotIds.length === 0 && changedSlotIds.length === 0 && changedStimulusSlotIds.length === 0 && changedCueSlotIds.length === 0 && changedPointsSlotIds.length === 0 && reorderedSlotIds.length === 0,
|
|
504
550
|
missingSlotIds,
|
|
505
551
|
addedSlotIds,
|
|
506
552
|
changedSlotIds,
|
|
507
553
|
changedStimulusSlotIds,
|
|
554
|
+
changedCueSlotIds,
|
|
508
555
|
changedPointsSlotIds,
|
|
509
556
|
reorderedSlotIds
|
|
510
557
|
};
|
|
@@ -652,23 +699,31 @@ function createItemGroupDraft(context) {
|
|
|
652
699
|
items: []
|
|
653
700
|
};
|
|
654
701
|
}
|
|
702
|
+
function createInteractiveVideoDraft(context) {
|
|
703
|
+
const draft = createItemGroupDraft(context);
|
|
704
|
+
return {
|
|
705
|
+
...draft,
|
|
706
|
+
stimulus: { id: draft.stimulus.id, kind: "video", media: { type: "video", url: "" } },
|
|
707
|
+
timeline: { cues: [] }
|
|
708
|
+
};
|
|
709
|
+
}
|
|
655
710
|
function validateItemGroupDraft(draft) {
|
|
656
|
-
return
|
|
711
|
+
return _chunkQFWEF5STcjs.withValidationScope.call(void 0, () => validateItemGroupDraftInScope(draft));
|
|
657
712
|
}
|
|
658
713
|
function validateItemGroupDraftInScope(draft) {
|
|
659
714
|
const issues = [];
|
|
660
|
-
if (!
|
|
715
|
+
if (!_chunkQFWEF5STcjs.isRecord.call(void 0, draft)) {
|
|
661
716
|
issues.push(
|
|
662
|
-
|
|
717
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_not_an_object", [], "A group must be an object with a stimulus and its items.")
|
|
663
718
|
);
|
|
664
719
|
return { status: "invalid", issues };
|
|
665
720
|
}
|
|
666
721
|
issues.push(...checkGroupIdentity(draft));
|
|
667
|
-
if (
|
|
722
|
+
if (_chunkQFWEF5STcjs.isRecord.call(void 0, draft.stimulus)) {
|
|
668
723
|
issues.push(...checkStimulus(draft.stimulus));
|
|
669
|
-
} else if (
|
|
724
|
+
} else if (_chunkQFWEF5STcjs.isUnset.call(void 0, draft.stimulus)) {
|
|
670
725
|
issues.push(
|
|
671
|
-
|
|
726
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
672
727
|
"ig_stimulus_required",
|
|
673
728
|
["stimulus"],
|
|
674
729
|
"Add the passage, recording or image the questions are about."
|
|
@@ -676,25 +731,28 @@ function validateItemGroupDraftInScope(draft) {
|
|
|
676
731
|
);
|
|
677
732
|
}
|
|
678
733
|
issues.push(...checkItems(draft));
|
|
679
|
-
if (
|
|
734
|
+
if (draft.timeline !== void 0 && draft.timeline !== null) {
|
|
735
|
+
issues.push(...checkTimeline(draft));
|
|
736
|
+
}
|
|
737
|
+
if (_chunkQFWEF5STcjs.groupCaptionsRevealDictation.call(void 0, draft, (captionsUrl) => !_chunkQFWEF5STcjs.isUnwritten.call(void 0, captionsUrl))) {
|
|
680
738
|
issues.push(
|
|
681
|
-
|
|
739
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
682
740
|
"dc_captions_not_allowed",
|
|
683
741
|
["stimulus", "media", "captionsUrl"],
|
|
684
|
-
|
|
742
|
+
_chunkQFWEF5STcjs.GROUP_CAPTIONS_REVEAL_DICTATION
|
|
685
743
|
)
|
|
686
744
|
);
|
|
687
745
|
}
|
|
688
|
-
const parsed =
|
|
746
|
+
const parsed = _chunkW7AQP6AVcjs.ItemGroupSchema.safeParse(draft, { reportInput: true });
|
|
689
747
|
if (!parsed.success) {
|
|
690
748
|
for (const schemaIssue of parsed.error.issues) {
|
|
691
749
|
const path = schemaIssue.path.map(String);
|
|
692
|
-
if (issues.some((known) =>
|
|
750
|
+
if (issues.some((known) => _chunkQFWEF5STcjs.covers.call(void 0, known.path, path))) {
|
|
693
751
|
continue;
|
|
694
752
|
}
|
|
695
|
-
if (path.length > 0 &&
|
|
753
|
+
if (path.length > 0 && _chunkQFWEF5STcjs.refusesEmpty.call(void 0, draft, schemaIssue)) {
|
|
696
754
|
issues.push(
|
|
697
|
-
|
|
755
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
698
756
|
"null_not_allowed",
|
|
699
757
|
path,
|
|
700
758
|
"This field cannot be null. Leave it out if it is optional, or give it a value."
|
|
@@ -710,7 +768,7 @@ function validateItemGroupDraftInScope(draft) {
|
|
|
710
768
|
});
|
|
711
769
|
}
|
|
712
770
|
}
|
|
713
|
-
const stored =
|
|
771
|
+
const stored = _chunkW7AQP6AVcjs.validateItemGroup.call(void 0, draft);
|
|
714
772
|
if (issues.length === 0 && stored.success) {
|
|
715
773
|
return { status: "complete", data: stored.data, issues };
|
|
716
774
|
}
|
|
@@ -722,11 +780,188 @@ function validateItemGroupDraftInScope(draft) {
|
|
|
722
780
|
const invalid = issues.some((found) => found.severity !== "incomplete");
|
|
723
781
|
return { status: invalid ? "invalid" : "incomplete", issues };
|
|
724
782
|
}
|
|
783
|
+
function checkTimeline(draft) {
|
|
784
|
+
const issues = [];
|
|
785
|
+
const timeline = draft.timeline;
|
|
786
|
+
if (!_chunkQFWEF5STcjs.isRecord.call(void 0, timeline)) {
|
|
787
|
+
return issues;
|
|
788
|
+
}
|
|
789
|
+
const stimulus = _chunkQFWEF5STcjs.isRecord.call(void 0, draft.stimulus) ? draft.stimulus : void 0;
|
|
790
|
+
if (stimulus !== void 0 && !_chunkQFWEF5STcjs.isUnwritten.call(void 0, stimulus.kind) && stimulus.kind !== "video") {
|
|
791
|
+
issues.push(
|
|
792
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
793
|
+
"ig_timeline_stimulus_kind",
|
|
794
|
+
["stimulus", "kind"],
|
|
795
|
+
"An interactive video needs a video: quizzes open at moments of it."
|
|
796
|
+
)
|
|
797
|
+
);
|
|
798
|
+
} else if (stimulus !== void 0 && _chunkQFWEF5STcjs.isRecord.call(void 0, stimulus.media) && !_chunkQFWEF5STcjs.isUnwritten.call(void 0, stimulus.media.type) && stimulus.media.type !== "video") {
|
|
799
|
+
issues.push(
|
|
800
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
801
|
+
"ig_timeline_stimulus_kind",
|
|
802
|
+
["stimulus", "media", "type"],
|
|
803
|
+
"Upload a video file. An embedded player from another site cannot be paused when a quiz opens."
|
|
804
|
+
)
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
if (draft.shuffle === "within-group") {
|
|
808
|
+
issues.push(
|
|
809
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
810
|
+
"ig_timeline_shuffle",
|
|
811
|
+
["shuffle"],
|
|
812
|
+
"The questions of an interactive video appear in the order their quizzes open, so they cannot be shuffled."
|
|
813
|
+
)
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
const items = Array.isArray(draft.items) ? draft.items : [];
|
|
817
|
+
const itemIndexById = /* @__PURE__ */ new Map();
|
|
818
|
+
items.forEach((item, index) => {
|
|
819
|
+
if (!_chunkQFWEF5STcjs.isRecord.call(void 0, item)) {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
if (typeof item.id === "string" && item.id !== "") {
|
|
823
|
+
itemIndexById.set(item.id, index);
|
|
824
|
+
}
|
|
825
|
+
const type = item.type;
|
|
826
|
+
if (typeof type === "string" && type !== "" && type !== "item-group" && !_chunkW7AQP6AVcjs.isInteractiveVideoItemType.call(void 0, type) && _chunkQFWEF5STcjs.getActivityTypeDescriptor.call(void 0, type) !== void 0) {
|
|
827
|
+
issues.push(
|
|
828
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
829
|
+
"ig_timeline_item_type",
|
|
830
|
+
["items", index, "type"],
|
|
831
|
+
`An interactive video can hold ${_chunkW7AQP6AVcjs.INTERACTIVE_VIDEO_ITEM_TYPES.join(", ")} questions only.`
|
|
832
|
+
)
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
if (type === "dictation" && _chunkQFWEF5STcjs.isUnset.call(void 0, item.media)) {
|
|
836
|
+
issues.push(
|
|
837
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
838
|
+
"ig_timeline_dictation_media",
|
|
839
|
+
["items", index, "media"],
|
|
840
|
+
"Add the recording this dictation plays: inside a video it cannot play the video."
|
|
841
|
+
)
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
const cues = Array.isArray(timeline.cues) ? timeline.cues : [];
|
|
846
|
+
const quizIds = /* @__PURE__ */ new Set();
|
|
847
|
+
const placed = /* @__PURE__ */ new Set();
|
|
848
|
+
cues.forEach((cue, cueIndex) => {
|
|
849
|
+
if (!_chunkQFWEF5STcjs.isRecord.call(void 0, cue)) {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
const at = (field, ...rest) => [
|
|
853
|
+
"timeline",
|
|
854
|
+
"cues",
|
|
855
|
+
cueIndex,
|
|
856
|
+
field,
|
|
857
|
+
...rest
|
|
858
|
+
];
|
|
859
|
+
if (_chunkQFWEF5STcjs.isMissingId.call(void 0, cue.id)) {
|
|
860
|
+
issues.push(_chunkQFWEF5STcjs.issue.call(void 0, "ig_timeline_quiz_id_required", at("id"), "This quiz has no id."));
|
|
861
|
+
} else if (typeof cue.id === "string") {
|
|
862
|
+
if (quizIds.has(cue.id)) {
|
|
863
|
+
issues.push(
|
|
864
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_timeline_quiz_id_duplicate", at("id"), `Two quizzes share the id "${cue.id}".`)
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
quizIds.add(cue.id);
|
|
868
|
+
}
|
|
869
|
+
if (_chunkQFWEF5STcjs.isUnset.call(void 0, cue.at)) {
|
|
870
|
+
issues.push(
|
|
871
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
872
|
+
"ig_timeline_quiz_time_required",
|
|
873
|
+
at("at"),
|
|
874
|
+
"Choose when in the video this quiz opens."
|
|
875
|
+
)
|
|
876
|
+
);
|
|
877
|
+
} else if (typeof cue.at !== "number" || !Number.isFinite(cue.at) || cue.at < 0) {
|
|
878
|
+
issues.push(
|
|
879
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
880
|
+
"ig_timeline_quiz_time_invalid",
|
|
881
|
+
at("at"),
|
|
882
|
+
"A quiz opens at a number of seconds, 0 or more."
|
|
883
|
+
)
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
if (_chunkQFWEF5STcjs.isUnset.call(void 0, cue.itemIds) || Array.isArray(cue.itemIds) && cue.itemIds.length === 0) {
|
|
887
|
+
issues.push(
|
|
888
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_timeline_quiz_empty", at("itemIds"), "Add at least one question to this quiz.")
|
|
889
|
+
);
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
if (!Array.isArray(cue.itemIds)) {
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
cue.itemIds.forEach((itemId, position) => {
|
|
896
|
+
if (typeof itemId !== "string") {
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
if (!itemIndexById.has(itemId)) {
|
|
900
|
+
issues.push(
|
|
901
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
902
|
+
"ig_timeline_quiz_unknown_item",
|
|
903
|
+
at("itemIds", position),
|
|
904
|
+
`This quiz names a question that is not in the video ("${itemId}").`
|
|
905
|
+
)
|
|
906
|
+
);
|
|
907
|
+
} else if (placed.has(itemId)) {
|
|
908
|
+
issues.push(
|
|
909
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
910
|
+
"ig_timeline_item_duplicate",
|
|
911
|
+
at("itemIds", position),
|
|
912
|
+
"This question is already in a quiz: each question belongs to one quiz."
|
|
913
|
+
)
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
placed.add(itemId);
|
|
917
|
+
});
|
|
918
|
+
});
|
|
919
|
+
for (const [itemId, index] of itemIndexById) {
|
|
920
|
+
if (!placed.has(itemId)) {
|
|
921
|
+
issues.push(
|
|
922
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
923
|
+
"ig_timeline_item_unplaced",
|
|
924
|
+
["items", index],
|
|
925
|
+
"Add this question to a quiz, or the video never shows it."
|
|
926
|
+
)
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
const chapters = Array.isArray(timeline.chapters) ? timeline.chapters : [];
|
|
931
|
+
let previousAt;
|
|
932
|
+
chapters.forEach((chapter, index) => {
|
|
933
|
+
if (!_chunkQFWEF5STcjs.isRecord.call(void 0, chapter)) {
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
if (_chunkQFWEF5STcjs.isUnwritten.call(void 0, chapter.title)) {
|
|
937
|
+
issues.push(
|
|
938
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
939
|
+
"ig_timeline_chapter_title",
|
|
940
|
+
["timeline", "chapters", index, "title"],
|
|
941
|
+
"Give this chapter a title."
|
|
942
|
+
)
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
if (typeof chapter.at === "number" && Number.isFinite(chapter.at)) {
|
|
946
|
+
if (previousAt !== void 0 && chapter.at <= previousAt) {
|
|
947
|
+
issues.push(
|
|
948
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
949
|
+
"ig_timeline_chapter_order",
|
|
950
|
+
["timeline", "chapters", index, "at"],
|
|
951
|
+
"Chapters must start in order, each after the one before it."
|
|
952
|
+
)
|
|
953
|
+
);
|
|
954
|
+
}
|
|
955
|
+
previousAt = chapter.at;
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
return issues;
|
|
959
|
+
}
|
|
725
960
|
function checkGroupIdentity(draft) {
|
|
726
961
|
const issues = [];
|
|
727
962
|
if (draft.schemaVersion !== "1.0") {
|
|
728
963
|
issues.push(
|
|
729
|
-
|
|
964
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
730
965
|
"schema_version_invalid",
|
|
731
966
|
["schemaVersion"],
|
|
732
967
|
'The draft must have schemaVersion "1.0". A draft from createItemGroupDraft has it.'
|
|
@@ -734,14 +969,14 @@ function checkGroupIdentity(draft) {
|
|
|
734
969
|
);
|
|
735
970
|
}
|
|
736
971
|
if (draft.type !== "item-group") {
|
|
737
|
-
issues.push(
|
|
972
|
+
issues.push(_chunkQFWEF5STcjs.issue.call(void 0, "type_mismatch", ["type"], `The draft's type must be "item-group".`));
|
|
738
973
|
}
|
|
739
|
-
if (
|
|
740
|
-
issues.push(
|
|
974
|
+
if (_chunkQFWEF5STcjs.isMissingId.call(void 0, draft.id)) {
|
|
975
|
+
issues.push(_chunkQFWEF5STcjs.issue.call(void 0, "id_required", ["id"], "The group has no id."));
|
|
741
976
|
}
|
|
742
|
-
if (!
|
|
977
|
+
if (!_chunkQFWEF5STcjs.isUnset.call(void 0, draft.shuffle) && draft.shuffle !== "none" && draft.shuffle !== "within-group") {
|
|
743
978
|
issues.push(
|
|
744
|
-
|
|
979
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
745
980
|
"ig_shuffle_invalid",
|
|
746
981
|
["shuffle"],
|
|
747
982
|
'Shuffling is either "none" or "within-group". Leave it out to keep the authored order.'
|
|
@@ -760,13 +995,13 @@ var MEDIA_FOR_KIND = {
|
|
|
760
995
|
function checkStimulus(stimulus) {
|
|
761
996
|
const issues = [];
|
|
762
997
|
const at = (...rest) => ["stimulus", ...rest];
|
|
763
|
-
if (
|
|
764
|
-
issues.push(
|
|
998
|
+
if (_chunkQFWEF5STcjs.isMissingId.call(void 0, stimulus.id)) {
|
|
999
|
+
issues.push(_chunkQFWEF5STcjs.issue.call(void 0, "ig_stimulus_id_required", at("id"), "The stimulus has no id."));
|
|
765
1000
|
}
|
|
766
1001
|
const kind = stimulus.kind;
|
|
767
|
-
if (
|
|
1002
|
+
if (_chunkQFWEF5STcjs.isUnwritten.call(void 0, kind)) {
|
|
768
1003
|
issues.push(
|
|
769
|
-
|
|
1004
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
770
1005
|
"ig_stimulus_kind_required",
|
|
771
1006
|
at("kind"),
|
|
772
1007
|
"Choose what the questions are about: a text, a recording, a video, an image, or a mix."
|
|
@@ -775,71 +1010,71 @@ function checkStimulus(stimulus) {
|
|
|
775
1010
|
} else if (typeof kind !== "string" || !KINDS.has(kind)) {
|
|
776
1011
|
if (typeof kind === "string") {
|
|
777
1012
|
issues.push(
|
|
778
|
-
|
|
1013
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
779
1014
|
"ig_stimulus_kind_invalid",
|
|
780
1015
|
at("kind"),
|
|
781
1016
|
`"${kind}" is not a stimulus kind. Use text, audio, video, image or mixed.`
|
|
782
1017
|
)
|
|
783
1018
|
);
|
|
784
1019
|
}
|
|
785
|
-
if (
|
|
786
|
-
issues.push(...
|
|
1020
|
+
if (_chunkQFWEF5STcjs.isRecord.call(void 0, stimulus.media)) {
|
|
1021
|
+
issues.push(..._chunkQFWEF5STcjs.checkMedia.call(void 0, stimulus.media, at("media")));
|
|
787
1022
|
}
|
|
788
1023
|
return issues;
|
|
789
1024
|
}
|
|
790
1025
|
const hasBody = typeof stimulus.body === "string" && stimulus.body.trim() !== "";
|
|
791
|
-
const htmlPresent = !
|
|
1026
|
+
const htmlPresent = !_chunkQFWEF5STcjs.isUnset.call(void 0, stimulus.bodyHtml);
|
|
792
1027
|
if (!hasBody && (kind === "text" || kind === "mixed" || htmlPresent)) {
|
|
793
1028
|
issues.push(
|
|
794
|
-
|
|
1029
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
795
1030
|
"ig_stimulus_body_required",
|
|
796
1031
|
at("body"),
|
|
797
|
-
|
|
1032
|
+
_chunkQFWEF5STcjs.isUnwritten.call(void 0, stimulus.bodyHtml) ? "Write the passage." : "Write the passage as plain text too. The rich-text version is shown only where a sanitiser is supplied."
|
|
798
1033
|
)
|
|
799
1034
|
);
|
|
800
1035
|
}
|
|
801
|
-
if (kind !== "text" &&
|
|
1036
|
+
if (kind !== "text" && _chunkQFWEF5STcjs.isUnset.call(void 0, stimulus.media)) {
|
|
802
1037
|
issues.push(
|
|
803
|
-
|
|
1038
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_stimulus_media_required", at("media"), "Add the recording, video or image.")
|
|
804
1039
|
);
|
|
805
|
-
} else if (
|
|
1040
|
+
} else if (_chunkQFWEF5STcjs.isRecord.call(void 0, stimulus.media)) {
|
|
806
1041
|
const allowed = MEDIA_FOR_KIND[kind];
|
|
807
1042
|
const mediaType = stimulus.media.type;
|
|
808
1043
|
if (allowed !== void 0 && typeof mediaType === "string" && !allowed.includes(mediaType)) {
|
|
809
1044
|
issues.push(
|
|
810
|
-
|
|
1045
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
811
1046
|
"ig_stimulus_media_kind",
|
|
812
1047
|
at("media", "type"),
|
|
813
1048
|
`A "${kind}" stimulus cannot carry ${mediaType} media. Use ${allowed.join(" or ")}.`
|
|
814
1049
|
)
|
|
815
1050
|
);
|
|
816
1051
|
}
|
|
817
|
-
issues.push(...
|
|
1052
|
+
issues.push(..._chunkQFWEF5STcjs.checkMedia.call(void 0, stimulus.media, at("media")));
|
|
818
1053
|
}
|
|
819
1054
|
return issues;
|
|
820
1055
|
}
|
|
821
1056
|
function checkItems(draft) {
|
|
822
1057
|
const issues = [];
|
|
823
|
-
const items =
|
|
1058
|
+
const items = _chunkQFWEF5STcjs.isUnset.call(void 0, draft.items) ? [] : draft.items;
|
|
824
1059
|
if (!Array.isArray(items)) {
|
|
825
1060
|
return issues;
|
|
826
1061
|
}
|
|
827
1062
|
if (items.length === 0) {
|
|
828
1063
|
issues.push(
|
|
829
|
-
|
|
1064
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_items_required", ["items"], "Add at least one question about this material.")
|
|
830
1065
|
);
|
|
831
1066
|
return issues;
|
|
832
1067
|
}
|
|
833
1068
|
const seen = /* @__PURE__ */ new Set();
|
|
834
1069
|
const repeated = /* @__PURE__ */ new Set();
|
|
835
1070
|
for (const [index, item] of items.entries()) {
|
|
836
|
-
if (!
|
|
1071
|
+
if (!_chunkQFWEF5STcjs.isRecord.call(void 0, item)) {
|
|
837
1072
|
continue;
|
|
838
1073
|
}
|
|
839
1074
|
const ordinal = index + 1;
|
|
840
|
-
if (
|
|
1075
|
+
if (_chunkQFWEF5STcjs.isMissingId.call(void 0, item.id)) {
|
|
841
1076
|
issues.push(
|
|
842
|
-
|
|
1077
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_item_id_required", ["items", index, "id"], `Question ${ordinal} has no id.`)
|
|
843
1078
|
);
|
|
844
1079
|
} else if (typeof item.id === "string") {
|
|
845
1080
|
if (seen.has(item.id)) {
|
|
@@ -849,7 +1084,7 @@ function checkItems(draft) {
|
|
|
849
1084
|
}
|
|
850
1085
|
if (item.type === "item-group") {
|
|
851
1086
|
issues.push(
|
|
852
|
-
|
|
1087
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
853
1088
|
"ig_item_nested_group",
|
|
854
1089
|
["items", index, "type"],
|
|
855
1090
|
"Groups do not nest: every item must be an activity."
|
|
@@ -857,9 +1092,9 @@ function checkItems(draft) {
|
|
|
857
1092
|
);
|
|
858
1093
|
continue;
|
|
859
1094
|
}
|
|
860
|
-
if (
|
|
1095
|
+
if (_chunkQFWEF5STcjs.isUnwritten.call(void 0, item.type)) {
|
|
861
1096
|
issues.push(
|
|
862
|
-
|
|
1097
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
863
1098
|
"ig_item_type_required",
|
|
864
1099
|
["items", index, "type"],
|
|
865
1100
|
`Choose what kind of question ${ordinal} is.`
|
|
@@ -874,11 +1109,11 @@ function checkItems(draft) {
|
|
|
874
1109
|
try {
|
|
875
1110
|
result = validateDraft(item.type, item);
|
|
876
1111
|
} catch (error) {
|
|
877
|
-
if (!(error instanceof
|
|
1112
|
+
if (!(error instanceof _chunkQFWEF5STcjs.UnknownActivityTypeError) || error.activityType !== item.type) {
|
|
878
1113
|
throw error;
|
|
879
1114
|
}
|
|
880
1115
|
issues.push(
|
|
881
|
-
|
|
1116
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
882
1117
|
"ig_item_type_unknown",
|
|
883
1118
|
["items", index, "type"],
|
|
884
1119
|
`"${item.type}" is not a registered activity type.`
|
|
@@ -892,7 +1127,7 @@ function checkItems(draft) {
|
|
|
892
1127
|
}
|
|
893
1128
|
for (const id of repeated) {
|
|
894
1129
|
issues.push(
|
|
895
|
-
|
|
1130
|
+
_chunkQFWEF5STcjs.issue.call(void 0, "ig_item_id_duplicate", ["items"], `More than one question has the id "${id}".`)
|
|
896
1131
|
);
|
|
897
1132
|
}
|
|
898
1133
|
return issues;
|
|
@@ -900,30 +1135,30 @@ function checkItems(draft) {
|
|
|
900
1135
|
|
|
901
1136
|
// src/authoring/index.ts
|
|
902
1137
|
function validateDraft(type, draft) {
|
|
903
|
-
return
|
|
1138
|
+
return _chunkQFWEF5STcjs.withValidationScope.call(void 0, () => validateDraftInScope(type, draft));
|
|
904
1139
|
}
|
|
905
1140
|
function validateDraftInScope(type, draft) {
|
|
906
|
-
const descriptor =
|
|
1141
|
+
const descriptor = _chunkQFWEF5STcjs.getActivityTypeDescriptor.call(void 0, type);
|
|
907
1142
|
if (descriptor === void 0) {
|
|
908
|
-
throw new (0,
|
|
1143
|
+
throw new (0, _chunkQFWEF5STcjs.UnknownActivityTypeError)(String(type));
|
|
909
1144
|
}
|
|
910
|
-
const reported =
|
|
1145
|
+
const reported = _chunkQFWEF5STcjs.isRecord.call(void 0, draft) && _optionalChain([descriptor, 'access', _23 => _23.authoring, 'optionalAccess', _24 => _24.checkDraft]) !== void 0 ? descriptor.authoring.checkDraft(draft).map(normalise) : [];
|
|
911
1146
|
const issues = [...reported];
|
|
912
1147
|
const parsed = descriptor.schema.safeParse(draft, { reportInput: true });
|
|
913
1148
|
if (!parsed.success) {
|
|
914
|
-
const covered =
|
|
1149
|
+
const covered = _chunkQFWEF5STcjs.coveredPathsOf.call(void 0, reported);
|
|
915
1150
|
const reportedEmpty = /* @__PURE__ */ new Set();
|
|
916
1151
|
for (const schemaIssue of parsed.error.issues) {
|
|
917
1152
|
const path = schemaIssue.path.map(String);
|
|
918
|
-
if (covered.has(
|
|
1153
|
+
if (covered.has(_chunkQFWEF5STcjs.pathKey.call(void 0, path))) {
|
|
919
1154
|
continue;
|
|
920
1155
|
}
|
|
921
|
-
if (path.length > 0 &&
|
|
1156
|
+
if (path.length > 0 && _chunkQFWEF5STcjs.refusesEmpty.call(void 0, draft, schemaIssue)) {
|
|
922
1157
|
const key = JSON.stringify(path);
|
|
923
1158
|
if (!reportedEmpty.has(key)) {
|
|
924
1159
|
reportedEmpty.add(key);
|
|
925
1160
|
issues.push(
|
|
926
|
-
|
|
1161
|
+
_chunkQFWEF5STcjs.issue.call(void 0,
|
|
927
1162
|
"null_not_allowed",
|
|
928
1163
|
path,
|
|
929
1164
|
typeof schemaIssue.path.at(-1) === "number" ? "This entry has no value. Remove it, or fill it in." : "This field cannot be null. Leave it out if it is optional, or give it a value."
|
|
@@ -947,11 +1182,11 @@ function validateDraftInScope(type, draft) {
|
|
|
947
1182
|
return { status: invalid ? "invalid" : "incomplete", issues };
|
|
948
1183
|
}
|
|
949
1184
|
function createDraft(type, context) {
|
|
950
|
-
const descriptor =
|
|
1185
|
+
const descriptor = _chunkQFWEF5STcjs.getActivityTypeDescriptor.call(void 0, type);
|
|
951
1186
|
if (descriptor === void 0) {
|
|
952
|
-
throw new (0,
|
|
1187
|
+
throw new (0, _chunkQFWEF5STcjs.UnknownActivityTypeError)(String(type));
|
|
953
1188
|
}
|
|
954
|
-
const create = _optionalChain([descriptor, 'access',
|
|
1189
|
+
const create = _optionalChain([descriptor, 'access', _25 => _25.authoring, 'optionalAccess', _26 => _26.createDraft]);
|
|
955
1190
|
if (create === void 0) {
|
|
956
1191
|
throw new Error(
|
|
957
1192
|
`Activity type "${String(type)}" declares no authoring.createDraft, so there is no empty draft to create. Build the draft yourself; validateDraft works for every registered type.`
|
|
@@ -974,7 +1209,7 @@ function createDraft(type, context) {
|
|
|
974
1209
|
return create({ newId });
|
|
975
1210
|
}
|
|
976
1211
|
function normalise(found) {
|
|
977
|
-
const documented = Object.hasOwn(
|
|
1212
|
+
const documented = Object.hasOwn(_chunkQFWEF5STcjs.DRAFT_ISSUE_SEVERITY, found.code) ? _chunkQFWEF5STcjs.DRAFT_ISSUE_SEVERITY[found.code] : void 0;
|
|
978
1213
|
return {
|
|
979
1214
|
...found,
|
|
980
1215
|
path: found.path.map(String),
|
|
@@ -1038,9 +1273,9 @@ function redactValue(value, policy, reveal) {
|
|
|
1038
1273
|
}
|
|
1039
1274
|
function redact(data, options = {}) {
|
|
1040
1275
|
const reveal = _nullishCoalesce(options.reveal, () => ( "none"));
|
|
1041
|
-
const descriptor =
|
|
1276
|
+
const descriptor = _chunkQFWEF5STcjs.getActivityTypeDescriptor.call(void 0, data.type);
|
|
1042
1277
|
if (descriptor === void 0) {
|
|
1043
|
-
throw new (0,
|
|
1278
|
+
throw new (0, _chunkQFWEF5STcjs.UnknownActivityTypeError)(String(data.type));
|
|
1044
1279
|
}
|
|
1045
1280
|
if (descriptor.fieldPolicy === void 0) {
|
|
1046
1281
|
throw new Error(
|
|
@@ -1053,7 +1288,7 @@ function redact(data, options = {}) {
|
|
|
1053
1288
|
if (reveal === "none" && descriptor.redactedSchema !== void 0) {
|
|
1054
1289
|
const parsed = descriptor.redactedSchema.safeParse(result);
|
|
1055
1290
|
if (!parsed.success) {
|
|
1056
|
-
throw new (0,
|
|
1291
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(
|
|
1057
1292
|
descriptor.type,
|
|
1058
1293
|
parsed.error.issues.map((issue2) => ({
|
|
1059
1294
|
path: issue2.path.map(String),
|
|
@@ -1067,13 +1302,13 @@ function redact(data, options = {}) {
|
|
|
1067
1302
|
}
|
|
1068
1303
|
function assertRedacted(data) {
|
|
1069
1304
|
if (typeof data !== "object" || data === null) {
|
|
1070
|
-
throw new (0,
|
|
1305
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)("unknown", [
|
|
1071
1306
|
{ path: [], message: "Redacted activity data must be an object.", code: "invalid_type" }
|
|
1072
1307
|
]);
|
|
1073
1308
|
}
|
|
1074
1309
|
const candidate = data;
|
|
1075
1310
|
if (candidate.redacted !== true) {
|
|
1076
|
-
throw new (0,
|
|
1311
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(String(_nullishCoalesce(candidate.type, () => ( "unknown"))), [
|
|
1077
1312
|
{
|
|
1078
1313
|
path: ["redacted"],
|
|
1079
1314
|
message: "Missing redacted marker \u2014 this payload is not a redact() projection.",
|
|
@@ -1082,12 +1317,12 @@ function assertRedacted(data) {
|
|
|
1082
1317
|
]);
|
|
1083
1318
|
}
|
|
1084
1319
|
const type = typeof candidate.type === "string" ? candidate.type : "";
|
|
1085
|
-
const descriptor =
|
|
1320
|
+
const descriptor = _chunkQFWEF5STcjs.getActivityTypeDescriptor.call(void 0, type);
|
|
1086
1321
|
if (descriptor === void 0) {
|
|
1087
|
-
throw new (0,
|
|
1322
|
+
throw new (0, _chunkQFWEF5STcjs.UnknownActivityTypeError)(type);
|
|
1088
1323
|
}
|
|
1089
1324
|
if (descriptor.redactedSchema === void 0) {
|
|
1090
|
-
throw new (0,
|
|
1325
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(descriptor.type, [
|
|
1091
1326
|
{
|
|
1092
1327
|
path: [],
|
|
1093
1328
|
message: `Activity type "${descriptor.type}" registers no redactedSchema; assertRedacted cannot prove this payload is learner-safe.`,
|
|
@@ -1097,7 +1332,7 @@ function assertRedacted(data) {
|
|
|
1097
1332
|
}
|
|
1098
1333
|
const parsed = descriptor.redactedSchema.safeParse(candidate);
|
|
1099
1334
|
if (!parsed.success) {
|
|
1100
|
-
throw new (0,
|
|
1335
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(
|
|
1101
1336
|
descriptor.type,
|
|
1102
1337
|
parsed.error.issues.map((issue2) => ({
|
|
1103
1338
|
path: issue2.path.map(String),
|
|
@@ -1113,7 +1348,7 @@ var STIMULUS_FIELD_POLICY = {
|
|
|
1113
1348
|
title: "public",
|
|
1114
1349
|
body: "public",
|
|
1115
1350
|
bodyHtml: "public",
|
|
1116
|
-
media:
|
|
1351
|
+
media: _chunkQFWEF5STcjs.MEDIA_FIELD_POLICY,
|
|
1117
1352
|
locale: "public",
|
|
1118
1353
|
attribution: "public",
|
|
1119
1354
|
transcript: "author-only"
|
|
@@ -1127,7 +1362,25 @@ var ITEM_GROUP_FIELD_POLICY = {
|
|
|
1127
1362
|
// and identity has to cross the redaction boundary intact.
|
|
1128
1363
|
slotKey: "public",
|
|
1129
1364
|
shuffle: "public",
|
|
1130
|
-
stimulus: STIMULUS_FIELD_POLICY
|
|
1365
|
+
stimulus: STIMULUS_FIELD_POLICY,
|
|
1366
|
+
// Public, and classified key by key rather than as one leaf: the learner's
|
|
1367
|
+
// player needs every part of it, none of it is a key — and a leaf would hand
|
|
1368
|
+
// over the author's object by reference, with whatever else was parked in it.
|
|
1369
|
+
timeline: {
|
|
1370
|
+
// Applies to every element of the array.
|
|
1371
|
+
cues: {
|
|
1372
|
+
id: "public",
|
|
1373
|
+
at: "public",
|
|
1374
|
+
itemIds: "public",
|
|
1375
|
+
title: "public",
|
|
1376
|
+
required: "public"
|
|
1377
|
+
},
|
|
1378
|
+
chapters: {
|
|
1379
|
+
at: "public",
|
|
1380
|
+
title: "public"
|
|
1381
|
+
},
|
|
1382
|
+
navigation: "public"
|
|
1383
|
+
}
|
|
1131
1384
|
};
|
|
1132
1385
|
function redactItemGroup(group, options = {}) {
|
|
1133
1386
|
const reveal = _nullishCoalesce(options.reveal, () => ( "none"));
|
|
@@ -1139,9 +1392,9 @@ function redactItemGroup(group, options = {}) {
|
|
|
1139
1392
|
redacted: true
|
|
1140
1393
|
};
|
|
1141
1394
|
if (reveal === "none") {
|
|
1142
|
-
const parsed =
|
|
1395
|
+
const parsed = _chunkW7AQP6AVcjs.RedactedItemGroupSchema.safeParse(result);
|
|
1143
1396
|
if (!parsed.success) {
|
|
1144
|
-
throw new (0,
|
|
1397
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(
|
|
1145
1398
|
"item-group",
|
|
1146
1399
|
parsed.error.issues.map((issue2) => ({
|
|
1147
1400
|
path: issue2.path.map(String),
|
|
@@ -1155,13 +1408,13 @@ function redactItemGroup(group, options = {}) {
|
|
|
1155
1408
|
}
|
|
1156
1409
|
function assertRedactedItemGroup(data) {
|
|
1157
1410
|
if (typeof data !== "object" || data === null) {
|
|
1158
|
-
throw new (0,
|
|
1411
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)("item-group", [
|
|
1159
1412
|
{ path: [], message: "Redacted item group must be an object.", code: "invalid_type" }
|
|
1160
1413
|
]);
|
|
1161
1414
|
}
|
|
1162
1415
|
const candidate = data;
|
|
1163
1416
|
if (candidate.redacted !== true) {
|
|
1164
|
-
throw new (0,
|
|
1417
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)("item-group", [
|
|
1165
1418
|
{
|
|
1166
1419
|
path: ["redacted"],
|
|
1167
1420
|
message: "Missing redacted marker \u2014 this payload is not a redactItemGroup() projection.",
|
|
@@ -1169,9 +1422,9 @@ function assertRedactedItemGroup(data) {
|
|
|
1169
1422
|
}
|
|
1170
1423
|
]);
|
|
1171
1424
|
}
|
|
1172
|
-
const parsed =
|
|
1425
|
+
const parsed = _chunkW7AQP6AVcjs.RedactedItemGroupSchema.safeParse(candidate);
|
|
1173
1426
|
if (!parsed.success) {
|
|
1174
|
-
throw new (0,
|
|
1427
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(
|
|
1175
1428
|
"item-group",
|
|
1176
1429
|
parsed.error.issues.map((issue2) => ({
|
|
1177
1430
|
path: issue2.path.map(String),
|
|
@@ -1184,8 +1437,8 @@ function assertRedactedItemGroup(data) {
|
|
|
1184
1437
|
try {
|
|
1185
1438
|
assertRedacted(item);
|
|
1186
1439
|
} catch (error) {
|
|
1187
|
-
if (error instanceof
|
|
1188
|
-
throw new (0,
|
|
1440
|
+
if (error instanceof _chunkQFWEF5STcjs.ActivitySchemaError) {
|
|
1441
|
+
throw new (0, _chunkQFWEF5STcjs.ActivitySchemaError)(
|
|
1189
1442
|
"item-group",
|
|
1190
1443
|
error.errors.map((issue2) => ({
|
|
1191
1444
|
...issue2,
|
|
@@ -1198,6 +1451,54 @@ function assertRedactedItemGroup(data) {
|
|
|
1198
1451
|
});
|
|
1199
1452
|
}
|
|
1200
1453
|
|
|
1454
|
+
// src/timeline.ts
|
|
1455
|
+
function readMediaProgress(value, duration) {
|
|
1456
|
+
let version;
|
|
1457
|
+
let at;
|
|
1458
|
+
let furthest;
|
|
1459
|
+
try {
|
|
1460
|
+
if (typeof value !== "object" || value === null) {
|
|
1461
|
+
return null;
|
|
1462
|
+
}
|
|
1463
|
+
({ progressVersion: version, at, furthest } = value);
|
|
1464
|
+
} catch (e) {
|
|
1465
|
+
return null;
|
|
1466
|
+
}
|
|
1467
|
+
if (version !== "1.0" || typeof at !== "number" || !Number.isFinite(at)) {
|
|
1468
|
+
return null;
|
|
1469
|
+
}
|
|
1470
|
+
const end = typeof duration === "number" && Number.isFinite(duration) && duration >= 0 ? duration : Number.POSITIVE_INFINITY;
|
|
1471
|
+
const clampedAt = Math.min(Math.max(0, at), end);
|
|
1472
|
+
const reached = typeof furthest === "number" && Number.isFinite(furthest) ? furthest : clampedAt;
|
|
1473
|
+
return {
|
|
1474
|
+
progressVersion: "1.0",
|
|
1475
|
+
at: clampedAt,
|
|
1476
|
+
furthest: Math.min(Math.max(clampedAt, reached), end)
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
function composeTimelineScore(entryKey, items, policy) {
|
|
1480
|
+
const own = items.filter((item) => entryKeyOf(item.slotId) === entryKey);
|
|
1481
|
+
if (own.length === 0) {
|
|
1482
|
+
throw new Error(
|
|
1483
|
+
`composeTimelineScore: no scored item belongs to entry "${entryKey}". Pass the video's slotKey (or its position in the sequence), and the items of the attempt that holds it.`
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
return _chunk5KWF34LJcjs.composeAssessmentScore.call(void 0, [{ id: entryKey, weight: 1, items: own }], policy);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
|
|
1201
1502
|
|
|
1202
1503
|
|
|
1203
1504
|
|
|
@@ -1330,5 +1631,5 @@ function assertRedactedItemGroup(data) {
|
|
|
1330
1631
|
|
|
1331
1632
|
|
|
1332
1633
|
|
|
1333
|
-
exports.ActivitySchemaError =
|
|
1634
|
+
exports.ActivitySchemaError = _chunkQFWEF5STcjs.ActivitySchemaError; exports.BlankConfigSchema = _chunkQFWEF5STcjs.BlankConfigSchema; exports.DEFAULT_PASS_THRESHOLD = _chunk5KWF34LJcjs.DEFAULT_PASS_THRESHOLD; exports.DICTATION_MAX_ACCEPTED_TRANSCRIPTS = _chunkQFWEF5STcjs.DICTATION_MAX_ACCEPTED_TRANSCRIPTS; exports.DICTATION_MAX_EQUIVALENCES = _chunkQFWEF5STcjs.DICTATION_MAX_EQUIVALENCES; exports.DICTATION_MAX_EQUIVALENCE_LENGTH = _chunkQFWEF5STcjs.DICTATION_MAX_EQUIVALENCE_LENGTH; exports.DICTATION_MAX_TEXT_LENGTH = _chunkQFWEF5STcjs.DICTATION_MAX_TEXT_LENGTH; exports.DICTATION_MAX_TRANSCRIPT_LENGTH = _chunkQFWEF5STcjs.DICTATION_MAX_TRANSCRIPT_LENGTH; exports.DeferredScoringError = _chunkQFWEF5STcjs.DeferredScoringError; exports.DictationDataSchema = _chunkQFWEF5STcjs.DictationDataSchema; exports.DictationEquivalenceSchema = _chunkQFWEF5STcjs.DictationEquivalenceSchema; exports.DictationSlowMediaSchema = _chunkQFWEF5STcjs.DictationSlowMediaSchema; exports.DictationToleranceSchema = _chunkQFWEF5STcjs.DictationToleranceSchema; exports.FeedbackSchema = _chunkQFWEF5STcjs.FeedbackSchema; exports.FillInTheBlanksDataSchema = _chunkQFWEF5STcjs.FillInTheBlanksDataSchema; exports.GapSelectBankSchema = _chunkQFWEF5STcjs.GapSelectBankSchema; exports.GapSelectChoiceSchema = _chunkQFWEF5STcjs.GapSelectChoiceSchema; exports.GapSelectDataSchema = _chunkQFWEF5STcjs.GapSelectDataSchema; exports.GapSelectGapSchema = _chunkQFWEF5STcjs.GapSelectGapSchema; exports.INTERACTIVE_VIDEO_ITEM_TYPES = _chunkW7AQP6AVcjs.INTERACTIVE_VIDEO_ITEM_TYPES; exports.ItemGroupSchema = _chunkW7AQP6AVcjs.ItemGroupSchema; exports.MediaPlaybackSchema = _chunkQFWEF5STcjs.MediaPlaybackSchema; exports.MediaSchema = _chunkQFWEF5STcjs.MediaSchema; exports.MediaTimelineSchema = _chunkW7AQP6AVcjs.MediaTimelineSchema; exports.MediaTrackSchema = _chunkQFWEF5STcjs.MediaTrackSchema; exports.MediaUrlSchema = _chunkQFWEF5STcjs.MediaUrlSchema; exports.MultipleChoiceDataSchema = _chunkQFWEF5STcjs.MultipleChoiceDataSchema; exports.MultipleChoiceOptionMediaSchema = _chunkQFWEF5STcjs.MultipleChoiceOptionMediaSchema; exports.MultipleChoiceOptionSchema = _chunkQFWEF5STcjs.MultipleChoiceOptionSchema; exports.NativeControlHintSchema = _chunkQFWEF5STcjs.NativeControlHintSchema; exports.READ_ALOUD_MAX_DIMENSION_WEIGHT = _chunkQFWEF5STcjs.READ_ALOUD_MAX_DIMENSION_WEIGHT; exports.READ_ALOUD_MAX_REFERENCE_LENGTH = _chunkQFWEF5STcjs.READ_ALOUD_MAX_REFERENCE_LENGTH; exports.READ_ALOUD_MAX_SECONDS = _chunkQFWEF5STcjs.READ_ALOUD_MAX_SECONDS; exports.READ_ALOUD_MAX_TAKES = _chunkQFWEF5STcjs.READ_ALOUD_MAX_TAKES; exports.ReadAloudDataSchema = _chunkQFWEF5STcjs.ReadAloudDataSchema; exports.ReadAloudSlowMediaSchema = _chunkQFWEF5STcjs.ReadAloudSlowMediaSchema; exports.RedactedBlankConfigSchema = _chunkQFWEF5STcjs.RedactedBlankConfigSchema; exports.RedactedDictationDataSchema = _chunkQFWEF5STcjs.RedactedDictationDataSchema; exports.RedactedDictationSlowMediaSchema = _chunkQFWEF5STcjs.RedactedDictationSlowMediaSchema; exports.RedactedFillInTheBlanksDataSchema = _chunkQFWEF5STcjs.RedactedFillInTheBlanksDataSchema; exports.RedactedGapSelectBankSchema = _chunkQFWEF5STcjs.RedactedGapSelectBankSchema; exports.RedactedGapSelectChoiceSchema = _chunkQFWEF5STcjs.RedactedGapSelectChoiceSchema; exports.RedactedGapSelectDataSchema = _chunkQFWEF5STcjs.RedactedGapSelectDataSchema; exports.RedactedGapSelectGapSchema = _chunkQFWEF5STcjs.RedactedGapSelectGapSchema; exports.RedactedItemGroupSchema = _chunkW7AQP6AVcjs.RedactedItemGroupSchema; exports.RedactedMediaSchema = _chunkQFWEF5STcjs.RedactedMediaSchema; exports.RedactedMultipleChoiceDataSchema = _chunkQFWEF5STcjs.RedactedMultipleChoiceDataSchema; exports.RedactedMultipleChoiceOptionMediaSchema = _chunkQFWEF5STcjs.RedactedMultipleChoiceOptionMediaSchema; exports.RedactedMultipleChoiceOptionSchema = _chunkQFWEF5STcjs.RedactedMultipleChoiceOptionSchema; exports.RedactedReadAloudDataSchema = _chunkQFWEF5STcjs.RedactedReadAloudDataSchema; exports.RedactedScoringError = _chunkQFWEF5STcjs.RedactedScoringError; exports.RedactedStimulusSchema = _chunkW7AQP6AVcjs.RedactedStimulusSchema; exports.RedactedWrittenResponseDataSchema = _chunkQFWEF5STcjs.RedactedWrittenResponseDataSchema; exports.SPEECH_ASSESSMENT_MAX_WORDS = _chunkQFWEF5STcjs.SPEECH_ASSESSMENT_MAX_WORDS; exports.StimulusSchema = _chunkW7AQP6AVcjs.StimulusSchema; exports.TIMELINE_MAX_CHAPTERS = _chunkW7AQP6AVcjs.TIMELINE_MAX_CHAPTERS; exports.TIMELINE_MAX_ITEMS = _chunkW7AQP6AVcjs.TIMELINE_MAX_ITEMS; exports.TIMELINE_MAX_QUIZZES = _chunkW7AQP6AVcjs.TIMELINE_MAX_QUIZZES; exports.TIMELINE_MAX_TITLE_LENGTH = _chunkW7AQP6AVcjs.TIMELINE_MAX_TITLE_LENGTH; exports.TextMatchPolicySchema = _chunkQFWEF5STcjs.TextMatchPolicySchema; exports.TimelineChapterSchema = _chunkW7AQP6AVcjs.TimelineChapterSchema; exports.TimelineCueSchema = _chunkW7AQP6AVcjs.TimelineCueSchema; exports.UnknownActivityTypeError = _chunkQFWEF5STcjs.UnknownActivityTypeError; exports.WrittenResponseDataSchema = _chunkQFWEF5STcjs.WrittenResponseDataSchema; exports.WrittenResponseRubricCriterionSchema = _chunkQFWEF5STcjs.WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = _chunkQFWEF5STcjs.WrittenResponseRubricSchema; exports.XAPIVerb = _chunk7ETU6EXQcjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunk7ETU6EXQcjs.XAPI_VERB_DISPLAY; exports.alignDictation = _chunkQFWEF5STcjs.alignDictation; exports.alignReadAloud = _chunk5KWF34LJcjs.alignReadAloud; exports.assertRedacted = assertRedacted; exports.assertRedactedItemGroup = assertRedactedItemGroup; exports.canonicalJson = canonicalJson; exports.classifyBand = _chunk5KWF34LJcjs.classifyBand; exports.composeAssessmentScore = _chunk5KWF34LJcjs.composeAssessmentScore; exports.composeTimelineScore = composeTimelineScore; exports.computePassThreshold = _chunk5KWF34LJcjs.computePassThreshold; exports.contentHash = contentHash; exports.countWords = _chunkQFWEF5STcjs.countWords; exports.createDraft = createDraft; exports.createInteractiveVideoDraft = createInteractiveVideoDraft; exports.createItemGroupDraft = createItemGroupDraft; exports.defineActivityType = _chunkQFWEF5STcjs.defineActivityType; exports.dictationJsonSchema = _chunkW7AQP6AVcjs.dictationJsonSchema; exports.dictationReferenceWords = _chunkQFWEF5STcjs.dictationReferenceWords; exports.dictationType = _chunkQFWEF5STcjs.dictationType; exports.diffDictationChars = _chunk5KWF34LJcjs.diffDictationChars; exports.diffResponses = diffResponses; exports.entryKeyOf = entryKeyOf; exports.evaluate = _chunk5KWF34LJcjs.evaluate; exports.fillInTheBlanksJsonSchema = _chunkW7AQP6AVcjs.fillInTheBlanksJsonSchema; exports.fillInTheBlanksType = _chunkQFWEF5STcjs.fillInTheBlanksType; exports.fingerprint = fingerprint; exports.flattenSequence = flattenSequence; exports.gapSelectJsonSchema = _chunkW7AQP6AVcjs.gapSelectJsonSchema; exports.gapSelectType = _chunkQFWEF5STcjs.gapSelectType; exports.getActivityTypeDescriptor = _chunkQFWEF5STcjs.getActivityTypeDescriptor; exports.gradeFromRubric = _chunk5KWF34LJcjs.gradeFromRubric; exports.gradeReadAloud = _chunk5KWF34LJcjs.gradeReadAloud; exports.gte = _chunk5KWF34LJcjs.gte; exports.hasGrade = _chunk5KWF34LJcjs.hasGrade; exports.hashSeed = hashSeed; exports.inspectWav = _chunk5KWF34LJcjs.inspectWav; exports.isInteractiveVideoItemType = _chunkW7AQP6AVcjs.isInteractiveVideoItemType; exports.isItemGroup = isItemGroup; exports.itemGroupJsonSchema = _chunkW7AQP6AVcjs.itemGroupJsonSchema; exports.jsonSchemaFor = _chunkW7AQP6AVcjs.jsonSchemaFor; exports.levenshteinDistance = _chunkQFWEF5STcjs.levenshteinDistance; exports.matchText = _chunkQFWEF5STcjs.matchText; exports.multipleChoiceJsonSchema = _chunkW7AQP6AVcjs.multipleChoiceJsonSchema; exports.multipleChoiceType = _chunkQFWEF5STcjs.multipleChoiceType; exports.outcomeFromGrade = _chunk5KWF34LJcjs.outcomeFromGrade; exports.outcomeFromUnscorable = _chunk5KWF34LJcjs.outcomeFromUnscorable; exports.planAttempt = planAttempt; exports.planMediaBudgets = planMediaBudgets; exports.readAloudJsonSchema = _chunkW7AQP6AVcjs.readAloudJsonSchema; exports.readAloudType = _chunkQFWEF5STcjs.readAloudType; exports.readMediaProgress = readMediaProgress; exports.redact = redact; exports.redactItemGroup = redactItemGroup; exports.registerActivityType = _chunkQFWEF5STcjs.registerActivityType; exports.registeredActivityTypes = _chunkQFWEF5STcjs.registeredActivityTypes; exports.resolvePlaybackPolicy = resolvePlaybackPolicy; exports.restoreAttemptState = restoreAttemptState; exports.restoreMediaPlayLedger = restoreMediaPlayLedger; exports.roundGrade = _chunk5KWF34LJcjs.roundGrade; exports.score = _chunk5KWF34LJcjs.score; exports.scoredItemsFromPlan = scoredItemsFromPlan; exports.seededShuffle = seededShuffle; exports.serializeAttemptState = serializeAttemptState; exports.serializeMediaPlayLedger = serializeMediaPlayLedger; exports.slotMediaKey = slotMediaKey; exports.stimulusJsonSchema = _chunkW7AQP6AVcjs.stimulusJsonSchema; exports.stimulusMediaKey = stimulusMediaKey; exports.validateActivity = _chunkW7AQP6AVcjs.validateActivity; exports.validateDraft = validateDraft; exports.validateItemGroup = _chunkW7AQP6AVcjs.validateItemGroup; exports.validateItemGroupDraft = validateItemGroupDraft; exports.validateSpeechAssessment = _chunk5KWF34LJcjs.validateSpeechAssessment; exports.validateXAPIStatement = _chunk7ETU6EXQcjs.validateXAPIStatement; exports.verifyAttemptPlan = verifyAttemptPlan; exports.writtenResponseJsonSchema = _chunkW7AQP6AVcjs.writtenResponseJsonSchema; exports.writtenResponseType = _chunkQFWEF5STcjs.writtenResponseType; exports.xAPIBuilder = _chunk7ETU6EXQcjs.xAPIBuilder; exports.xapiDefinitionFor = _chunk7ETU6EXQcjs.xapiDefinitionFor;
|
|
1334
1635
|
//# sourceMappingURL=index.cjs.map
|