@intellectif/lk-core 0.14.1 → 0.16.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 +54 -0
- package/README.md +1 -0
- package/dist/{activity-BVkg9VDo.d.cts → activity-DcxtpX7Z.d.cts} +39 -2
- package/dist/{activity-BVkg9VDo.d.ts → activity-DcxtpX7Z.d.ts} +39 -2
- package/dist/{chunk-J5OIRIOW.cjs → chunk-6P6XK2LI.cjs} +31 -31
- package/dist/{chunk-J5OIRIOW.cjs.map → chunk-6P6XK2LI.cjs.map} +1 -1
- package/dist/{chunk-VCXIPLEW.cjs → chunk-F7UOLKWV.cjs} +95 -25
- package/dist/chunk-F7UOLKWV.cjs.map +1 -0
- package/dist/chunk-FJJ2GVBA.cjs +420 -0
- package/dist/chunk-FJJ2GVBA.cjs.map +1 -0
- package/dist/{chunk-NBADQ3JU.js → chunk-GOZGBVJP.js} +203 -10
- package/dist/chunk-GOZGBVJP.js.map +1 -0
- package/dist/{chunk-6RND47QE.js → chunk-IRUD73IQ.js} +95 -25
- package/dist/chunk-IRUD73IQ.js.map +1 -0
- package/dist/{chunk-KTDOZR7Y.js → chunk-OXF7VT7S.js} +2 -2
- package/dist/{chunk-RTIR6R2U.js → chunk-S63IOKFP.js} +2 -2
- package/dist/{chunk-E7LPIZXI.cjs → chunk-VFTVZJO5.cjs} +4 -4
- package/dist/{chunk-E7LPIZXI.cjs.map → chunk-VFTVZJO5.cjs.map} +1 -1
- package/dist/{index-v2_-Fyn3.d.ts → index-BWpwZRQw.d.cts} +367 -2
- package/dist/{index-BE1bM2Wi.d.cts → index-DRJqwO2y.d.ts} +367 -2
- package/dist/index.cjs +399 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +116 -7
- package/dist/index.d.ts +116 -7
- package/dist/index.js +314 -12
- 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-NBADQ3JU.js.map +0 -1
- package/dist/chunk-VCXIPLEW.cjs.map +0 -1
- /package/dist/{chunk-KTDOZR7Y.js.map → chunk-OXF7VT7S.js.map} +0 -0
- /package/dist/{chunk-RTIR6R2U.js.map → chunk-S63IOKFP.js.map} +0 -0
|
@@ -953,11 +953,43 @@ var MediaPlaybackSchema = _v4.z.strictObject({
|
|
|
953
953
|
/** Advisory only. See {@link NativeControlHintSchema}. */
|
|
954
954
|
nativeControlHints: _v4.z.array(NativeControlHintSchema).min(1).max(2).optional()
|
|
955
955
|
});
|
|
956
|
+
var MediaTrackSchema = _v4.z.strictObject({
|
|
957
|
+
kind: _v4.z.enum(["captions", "subtitles"]),
|
|
958
|
+
src: MediaUrlSchema,
|
|
959
|
+
srclang: _v4.z.string().regex(/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/, {
|
|
960
|
+
error: 'srclang must be a BCP 47 language tag, such as "en", "es" or "pt-BR".'
|
|
961
|
+
}),
|
|
962
|
+
label: _v4.z.string().max(60).refine((label) => label.trim().length > 0, { error: "A track label must not be empty." }),
|
|
963
|
+
default: _v4.z.boolean().optional()
|
|
964
|
+
});
|
|
965
|
+
var MAX_TRACKS = 12;
|
|
966
|
+
function posterFits(m) {
|
|
967
|
+
return m.poster === void 0 || m.type === "video";
|
|
968
|
+
}
|
|
969
|
+
function tracksFit(m) {
|
|
970
|
+
return m.tracks === void 0 || m.type === "audio" || m.type === "video";
|
|
971
|
+
}
|
|
972
|
+
function tracksAreDistinct(m) {
|
|
973
|
+
if (m.tracks === void 0) {
|
|
974
|
+
return true;
|
|
975
|
+
}
|
|
976
|
+
const defaults = m.tracks.filter((track) => track.default === true).length;
|
|
977
|
+
const keys = new Set(m.tracks.map((track) => `${track.kind}:${track.srclang.toLowerCase()}`));
|
|
978
|
+
return defaults <= 1 && keys.size === m.tracks.length;
|
|
979
|
+
}
|
|
980
|
+
var POSTER_FITS = { error: "poster is for video media only.", path: ["poster"] };
|
|
981
|
+
var TRACKS_FIT = { error: "tracks are for audio and video media only.", path: ["tracks"] };
|
|
982
|
+
var TRACKS_DISTINCT = {
|
|
983
|
+
error: "tracks: at most one may be the default, and no two may share a kind and a language \u2014 a menu listing one language twice cannot say which one it plays.",
|
|
984
|
+
path: ["tracks"]
|
|
985
|
+
};
|
|
956
986
|
var MediaSchema = _v4.z.looseObject({
|
|
957
987
|
type: _v4.z.enum(["image", "audio", "video", "embed"]),
|
|
958
988
|
url: MediaUrlSchema,
|
|
959
989
|
alt: _v4.z.string().min(1).optional(),
|
|
960
990
|
captionsUrl: MediaUrlSchema.optional(),
|
|
991
|
+
tracks: _v4.z.array(MediaTrackSchema).min(1).max(MAX_TRACKS).optional(),
|
|
992
|
+
poster: MediaUrlSchema.optional(),
|
|
961
993
|
playback: MediaPlaybackSchema.optional()
|
|
962
994
|
}).refine(
|
|
963
995
|
(m) => m.type !== "image" && m.type !== "embed" || typeof m.alt === "string" && m.alt.length > 0,
|
|
@@ -968,7 +1000,7 @@ var MediaSchema = _v4.z.looseObject({
|
|
|
968
1000
|
).refine((m) => m.type !== "embed" || /^https?:\/\//i.test(m.url), {
|
|
969
1001
|
error: "embed media requires an absolute http(s) provider URL. data:, blob:, and relative URLs are not allowed for embeds \u2014 the embed iframe runs with allow-scripts, and a data:/same-origin document there is an XSS vector.",
|
|
970
1002
|
path: ["url"]
|
|
971
|
-
}).refine((m) => m.playback === void 0 || m.type === "audio", {
|
|
1003
|
+
}).refine(posterFits, POSTER_FITS).refine(tracksFit, TRACKS_FIT).refine(tracksAreDistinct, TRACKS_DISTINCT).refine((m) => m.playback === void 0 || m.type === "audio", {
|
|
972
1004
|
error: "playback policy is supported on audio media only. An embed is a provider iframe the SDK cannot control at all (it has no reliable JS API for a third-party player); an image has nothing to play; video is deliberately deferred, because a video transport must also own fullscreen and Picture-in-Picture and the SDK will not pretend to govern those yet.",
|
|
973
1005
|
path: ["playback"]
|
|
974
1006
|
}).refine(
|
|
@@ -998,6 +1030,8 @@ var RedactedMediaSchema = _v4.z.strictObject({
|
|
|
998
1030
|
url: MediaUrlSchema,
|
|
999
1031
|
alt: _v4.z.string().min(1).optional(),
|
|
1000
1032
|
captionsUrl: MediaUrlSchema.optional(),
|
|
1033
|
+
tracks: _v4.z.array(MediaTrackSchema).min(1).max(MAX_TRACKS).optional(),
|
|
1034
|
+
poster: MediaUrlSchema.optional(),
|
|
1001
1035
|
playback: MediaPlaybackSchema.optional()
|
|
1002
1036
|
}).refine(
|
|
1003
1037
|
(m) => m.type !== "image" && m.type !== "embed" || typeof m.alt === "string" && m.alt.length > 0,
|
|
@@ -1008,7 +1042,7 @@ var RedactedMediaSchema = _v4.z.strictObject({
|
|
|
1008
1042
|
).refine((m) => m.type !== "embed" || /^https?:\/\//i.test(m.url), {
|
|
1009
1043
|
error: "embed media requires an absolute http(s) provider URL. data:, blob:, and relative URLs are not allowed for embeds \u2014 the embed iframe runs with allow-scripts, and a data:/same-origin document there is an XSS vector.",
|
|
1010
1044
|
path: ["url"]
|
|
1011
|
-
});
|
|
1045
|
+
}).refine(posterFits, POSTER_FITS).refine(tracksFit, TRACKS_FIT).refine(tracksAreDistinct, TRACKS_DISTINCT);
|
|
1012
1046
|
|
|
1013
1047
|
// src/schemas/dictation.ts
|
|
1014
1048
|
|
|
@@ -1174,10 +1208,10 @@ var DictationDataSchema = DictationDataShape.check(
|
|
|
1174
1208
|
}
|
|
1175
1209
|
for (const field of ["media", "slowMedia"]) {
|
|
1176
1210
|
const recording = data[field];
|
|
1177
|
-
|
|
1211
|
+
for (const captions of captionFieldsOf(recording)) {
|
|
1178
1212
|
report(
|
|
1179
|
-
[field,
|
|
1180
|
-
recording
|
|
1213
|
+
[field, captions],
|
|
1214
|
+
_optionalChain([recording, 'optionalAccess', _48 => _48[captions]]),
|
|
1181
1215
|
"A dictation recording cannot carry captions: the captions are the answer. Offer an accessible alternative as a different item."
|
|
1182
1216
|
);
|
|
1183
1217
|
}
|
|
@@ -1213,17 +1247,32 @@ var DictationDataSchema = DictationDataShape.check(
|
|
|
1213
1247
|
}
|
|
1214
1248
|
})
|
|
1215
1249
|
);
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
if (!isObject(
|
|
1219
|
-
return
|
|
1250
|
+
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1251
|
+
function captionFieldsOf(media, written = (captionsUrl) => captionsUrl !== void 0) {
|
|
1252
|
+
if (!isObject(media)) {
|
|
1253
|
+
return [];
|
|
1220
1254
|
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1255
|
+
const fields = [];
|
|
1256
|
+
if (written(media.captionsUrl)) {
|
|
1257
|
+
fields.push("captionsUrl");
|
|
1258
|
+
}
|
|
1259
|
+
if (Array.isArray(media.tracks) && media.tracks.length > 0) {
|
|
1260
|
+
fields.push("tracks");
|
|
1223
1261
|
}
|
|
1224
|
-
return
|
|
1262
|
+
return fields;
|
|
1263
|
+
}
|
|
1264
|
+
function groupCaptionsField(group, written) {
|
|
1265
|
+
if (!isObject(group) || !isObject(group.stimulus) || !Array.isArray(group.items)) {
|
|
1266
|
+
return void 0;
|
|
1267
|
+
}
|
|
1268
|
+
const [field] = captionFieldsOf(group.stimulus.media, written);
|
|
1269
|
+
if (field === void 0) {
|
|
1270
|
+
return void 0;
|
|
1271
|
+
}
|
|
1272
|
+
const played = group.items.some(
|
|
1225
1273
|
(item) => isObject(item) && item.type === "dictation" && item.media === void 0
|
|
1226
1274
|
);
|
|
1275
|
+
return played ? field : void 0;
|
|
1227
1276
|
}
|
|
1228
1277
|
var GROUP_CAPTIONS_REVEAL_DICTATION = "The stimulus recording carries captions, and a dictation in this group plays that recording: the captions are the answer. Remove the captions, or give the dictation its own recording.";
|
|
1229
1278
|
|
|
@@ -1757,12 +1806,12 @@ var RedactedDictationDataSchema = _v4.z.strictObject({
|
|
|
1757
1806
|
hints: _v4.z.strictObject({ mode: _v4.z.literal("progressive-words") }).optional()
|
|
1758
1807
|
}).check((ctx) => {
|
|
1759
1808
|
const data = ctx.value;
|
|
1760
|
-
|
|
1809
|
+
for (const captions of captionFieldsOf(data.media)) {
|
|
1761
1810
|
ctx.issues.push({
|
|
1762
1811
|
code: "custom",
|
|
1763
|
-
input: data.media
|
|
1812
|
+
input: _optionalChain([data, 'access', _65 => _65.media, 'optionalAccess', _66 => _66[captions]]),
|
|
1764
1813
|
message: "A dictation recording cannot carry captions: the captions are the answer, so this payload is not learner-safe.",
|
|
1765
|
-
path: ["media",
|
|
1814
|
+
path: ["media", captions]
|
|
1766
1815
|
});
|
|
1767
1816
|
}
|
|
1768
1817
|
if (data.slowMedia !== void 0 && _optionalChain([data, 'access', _67 => _67.media, 'optionalAccess', _68 => _68.playback, 'optionalAccess', _69 => _69.maxPlays]) !== void 0) {
|
|
@@ -2203,6 +2252,21 @@ var DRAFT_ISSUE_SEVERITY = {
|
|
|
2203
2252
|
ig_item_type_unknown: "invalid",
|
|
2204
2253
|
ig_item_nested_group: "invalid",
|
|
2205
2254
|
ig_shuffle_invalid: "invalid",
|
|
2255
|
+
// interactive video (an item group with a timeline)
|
|
2256
|
+
ig_timeline_stimulus_kind: "invalid",
|
|
2257
|
+
ig_timeline_shuffle: "invalid",
|
|
2258
|
+
ig_timeline_quiz_id_required: "incomplete",
|
|
2259
|
+
ig_timeline_quiz_id_duplicate: "invalid",
|
|
2260
|
+
ig_timeline_quiz_time_required: "incomplete",
|
|
2261
|
+
ig_timeline_quiz_time_invalid: "invalid",
|
|
2262
|
+
ig_timeline_quiz_empty: "incomplete",
|
|
2263
|
+
ig_timeline_quiz_unknown_item: "invalid",
|
|
2264
|
+
ig_timeline_item_duplicate: "invalid",
|
|
2265
|
+
ig_timeline_item_unplaced: "incomplete",
|
|
2266
|
+
ig_timeline_item_type: "invalid",
|
|
2267
|
+
ig_timeline_dictation_media: "incomplete",
|
|
2268
|
+
ig_timeline_chapter_order: "invalid",
|
|
2269
|
+
ig_timeline_chapter_title: "incomplete",
|
|
2206
2270
|
// gap-select
|
|
2207
2271
|
gs_passage_required: "incomplete",
|
|
2208
2272
|
gs_gaps_required: "incomplete",
|
|
@@ -2607,10 +2671,8 @@ function checkRecording(media) {
|
|
|
2607
2671
|
)
|
|
2608
2672
|
);
|
|
2609
2673
|
}
|
|
2610
|
-
|
|
2611
|
-
issues.push(
|
|
2612
|
-
issue("dc_captions_not_allowed", ["media", "captionsUrl"], CAPTIONS_ARE_THE_ANSWER)
|
|
2613
|
-
);
|
|
2674
|
+
for (const captions of captionFieldsOf(media, (captionsUrl) => !isUnset(captionsUrl))) {
|
|
2675
|
+
issues.push(issue("dc_captions_not_allowed", ["media", captions], CAPTIONS_ARE_THE_ANSWER));
|
|
2614
2676
|
}
|
|
2615
2677
|
return issues;
|
|
2616
2678
|
}
|
|
@@ -2635,10 +2697,8 @@ function checkSlowRecording(draft) {
|
|
|
2635
2697
|
DictationSlowMediaSchema
|
|
2636
2698
|
)
|
|
2637
2699
|
);
|
|
2638
|
-
|
|
2639
|
-
issues.push(
|
|
2640
|
-
issue("dc_captions_not_allowed", ["slowMedia", "captionsUrl"], CAPTIONS_ARE_THE_ANSWER)
|
|
2641
|
-
);
|
|
2700
|
+
for (const captions of captionFieldsOf(slow, (captionsUrl) => !isUnset(captionsUrl))) {
|
|
2701
|
+
issues.push(issue("dc_captions_not_allowed", ["slowMedia", captions], CAPTIONS_ARE_THE_ANSWER));
|
|
2642
2702
|
}
|
|
2643
2703
|
if (slow.playback !== void 0) {
|
|
2644
2704
|
issues.push(
|
|
@@ -3984,6 +4044,15 @@ var MEDIA_FIELD_POLICY = {
|
|
|
3984
4044
|
url: "public",
|
|
3985
4045
|
alt: "public",
|
|
3986
4046
|
captionsUrl: "public",
|
|
4047
|
+
poster: "public",
|
|
4048
|
+
// Applies to every element of the array.
|
|
4049
|
+
tracks: {
|
|
4050
|
+
kind: "public",
|
|
4051
|
+
src: "public",
|
|
4052
|
+
srclang: "public",
|
|
4053
|
+
label: "public",
|
|
4054
|
+
default: "public"
|
|
4055
|
+
},
|
|
3987
4056
|
playback: {
|
|
3988
4057
|
controls: "public",
|
|
3989
4058
|
maxPlays: "public",
|
|
@@ -4367,5 +4436,6 @@ registerActivityType(readAloudType);
|
|
|
4367
4436
|
|
|
4368
4437
|
|
|
4369
4438
|
|
|
4370
|
-
|
|
4371
|
-
|
|
4439
|
+
|
|
4440
|
+
exports.ActivitySchemaError = ActivitySchemaError; exports.UnknownActivityTypeError = UnknownActivityTypeError; exports.RedactedScoringError = RedactedScoringError; exports.DeferredScoringError = DeferredScoringError; exports.withValidationScope = withValidationScope; exports.DICTATION_MAX_TRANSCRIPT_LENGTH = DICTATION_MAX_TRANSCRIPT_LENGTH; exports.DICTATION_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH; exports.DICTATION_MAX_EQUIVALENCE_LENGTH = DICTATION_MAX_EQUIVALENCE_LENGTH; exports.DICTATION_MAX_EQUIVALENCES = DICTATION_MAX_EQUIVALENCES; exports.DICTATION_MAX_ACCEPTED_TRANSCRIPTS = DICTATION_MAX_ACCEPTED_TRANSCRIPTS; exports.codePointLength = codePointLength; exports.normalizeDictationText = normalizeDictationText; exports.FeedbackSchema = FeedbackSchema; exports.MediaUrlSchema = MediaUrlSchema; exports.NativeControlHintSchema = NativeControlHintSchema; exports.MediaPlaybackSchema = MediaPlaybackSchema; exports.MediaTrackSchema = MediaTrackSchema; exports.MediaSchema = MediaSchema; exports.RedactedMediaSchema = RedactedMediaSchema; exports.DictationSlowMediaSchema = DictationSlowMediaSchema; exports.DictationEquivalenceSchema = DictationEquivalenceSchema; exports.DictationToleranceSchema = DictationToleranceSchema; exports.DictationDataSchema = DictationDataSchema; exports.groupCaptionsField = groupCaptionsField; exports.GROUP_CAPTIONS_REVEAL_DICTATION = GROUP_CAPTIONS_REVEAL_DICTATION; exports.DRAFT_ISSUE_SEVERITY = DRAFT_ISSUE_SEVERITY; exports.issue = issue; exports.isRecord = isRecord; exports.refusesEmpty = refusesEmpty; exports.isUnset = isUnset; exports.isUnwritten = isUnwritten; exports.isMissingId = isMissingId; exports.checkMedia = checkMedia; exports.covers = covers; exports.pathKey = pathKey; exports.coveredPathsOf = coveredPathsOf; exports.TextMatchPolicySchema = TextMatchPolicySchema; exports.BlankConfigSchema = BlankConfigSchema; exports.FillInTheBlanksDataSchema = FillInTheBlanksDataSchema; exports.MultipleChoiceOptionMediaSchema = MultipleChoiceOptionMediaSchema; exports.MultipleChoiceOptionSchema = MultipleChoiceOptionSchema; exports.MultipleChoiceDataSchema = MultipleChoiceDataSchema; exports.READ_ALOUD_MAX_REFERENCE_LENGTH = READ_ALOUD_MAX_REFERENCE_LENGTH; exports.READ_ALOUD_MAX_SECONDS = READ_ALOUD_MAX_SECONDS; exports.READ_ALOUD_MAX_TAKES = READ_ALOUD_MAX_TAKES; exports.READ_ALOUD_MAX_DIMENSION_WEIGHT = READ_ALOUD_MAX_DIMENSION_WEIGHT; exports.SPEECH_ASSESSMENT_MAX_WORDS = SPEECH_ASSESSMENT_MAX_WORDS; exports.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = SPEECH_ASSESSMENT_MAX_TEXT_LENGTH; exports.CANONICAL_LOCALE_RE = CANONICAL_LOCALE_RE; exports.ReadAloudSlowMediaSchema = ReadAloudSlowMediaSchema; exports.ReadAloudDataSchema = ReadAloudDataSchema; exports.countWords = countWords; exports.GapSelectChoiceSchema = GapSelectChoiceSchema; exports.GapSelectBankSchema = GapSelectBankSchema; exports.GapSelectGapSchema = GapSelectGapSchema; exports.GapSelectDataSchema = GapSelectDataSchema; exports.WrittenResponseRubricCriterionSchema = WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = WrittenResponseRubricSchema; exports.WrittenResponseDataSchema = WrittenResponseDataSchema; exports.RedactedMultipleChoiceOptionMediaSchema = RedactedMultipleChoiceOptionMediaSchema; exports.RedactedMultipleChoiceOptionSchema = RedactedMultipleChoiceOptionSchema; exports.RedactedMultipleChoiceDataSchema = RedactedMultipleChoiceDataSchema; exports.RedactedBlankConfigSchema = RedactedBlankConfigSchema; exports.RedactedFillInTheBlanksDataSchema = RedactedFillInTheBlanksDataSchema; exports.RedactedGapSelectChoiceSchema = RedactedGapSelectChoiceSchema; exports.RedactedGapSelectBankSchema = RedactedGapSelectBankSchema; exports.RedactedGapSelectGapSchema = RedactedGapSelectGapSchema; exports.RedactedGapSelectDataSchema = RedactedGapSelectDataSchema; exports.RedactedWrittenResponseDataSchema = RedactedWrittenResponseDataSchema; exports.RedactedDictationSlowMediaSchema = RedactedDictationSlowMediaSchema; exports.RedactedDictationDataSchema = RedactedDictationDataSchema; exports.RedactedReadAloudDataSchema = RedactedReadAloudDataSchema; exports.dictationReferenceWords = dictationReferenceWords; exports.alignDictation = alignDictation; exports.STEP = STEP; exports.alignSequences = alignSequences; exports.levenshteinDistance = levenshteinDistance; exports.matchText = matchText; exports.defineActivityType = defineActivityType; exports.registerActivityType = registerActivityType; exports.getActivityTypeDescriptor = getActivityTypeDescriptor; exports.registeredActivityTypes = registeredActivityTypes; exports.MEDIA_FIELD_POLICY = MEDIA_FIELD_POLICY; exports.multipleChoiceType = multipleChoiceType; exports.fillInTheBlanksType = fillInTheBlanksType; exports.writtenResponseType = writtenResponseType; exports.gapSelectType = gapSelectType; exports.dictationType = dictationType; exports.readAloudType = readAloudType;
|
|
4441
|
+
//# sourceMappingURL=chunk-F7UOLKWV.cjs.map
|