@intellectif/lk-core 1.6.0 → 1.7.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 +20 -0
- package/dist/{ai-i3jwXnpX.d.cts → ai-B1wYrqcB.d.cts} +39 -15
- package/dist/ai-B1wYrqcB.d.cts.map +1 -0
- package/dist/{ai-i3jwXnpX.d.ts → ai-B1wYrqcB.d.ts} +39 -15
- package/dist/ai-B1wYrqcB.d.ts.map +1 -0
- package/dist/ai-check.cjs +13 -6
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +1 -5
- package/dist/ai-check.d.cts.map +1 -1
- package/dist/ai-check.d.ts +1 -5
- package/dist/ai-check.d.ts.map +1 -1
- package/dist/ai-check.js +13 -6
- package/dist/ai-check.js.map +1 -1
- package/dist/{ai-writing-OJ5m_1EB.js → ai-writing-B7oMCt66.js} +46 -43
- package/dist/ai-writing-B7oMCt66.js.map +1 -0
- package/dist/{ai-writing-C4YRVrFi.cjs → ai-writing-DrPTV3R2.cjs} +46 -43
- package/dist/ai-writing-DrPTV3R2.cjs.map +1 -0
- package/dist/{index-DeD8EI1D.d.ts → index-BM8LeDWn.d.cts} +2 -42
- package/dist/index-BM8LeDWn.d.cts.map +1 -0
- package/dist/{index-Uh1u57yq.d.cts → index-BTkMQtws.d.ts} +2 -42
- package/dist/index-BTkMQtws.d.ts.map +1 -0
- package/dist/{index-Dj92T76o.d.ts → index-BU99GFTl.d.ts} +2 -8
- package/dist/index-BU99GFTl.d.ts.map +1 -0
- package/dist/{index-WBHSrIUU.d.ts → index-BdXs4-en.d.ts} +5 -12
- package/dist/index-BdXs4-en.d.ts.map +1 -0
- package/dist/{index-CFRgZLhH.d.cts → index-DP9rvyOz.d.cts} +5 -12
- package/dist/index-DP9rvyOz.d.cts.map +1 -0
- package/dist/{index--U7hHV0s.d.cts → index-XCCoPoTU.d.cts} +2 -8
- package/dist/index-XCCoPoTU.d.cts.map +1 -0
- package/dist/index.cjs +13 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -70
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +4 -70
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -20
- package/dist/index.js.map +1 -1
- package/dist/{item-group-CQRbb8Rx.cjs → item-group-8P3WFuUK.cjs} +4 -6
- package/dist/{item-group-CQRbb8Rx.cjs.map → item-group-8P3WFuUK.cjs.map} +1 -1
- package/dist/{item-group-BbvvH_Ob.js → item-group-CeDk7mfM.js} +4 -6
- package/dist/{item-group-BbvvH_Ob.js.map → item-group-CeDk7mfM.js.map} +1 -1
- package/dist/{registry-B23o9UWh.js → registry-D92hz9iA.js} +60 -89
- package/dist/registry-D92hz9iA.js.map +1 -0
- package/dist/{registry-Ih5n4PVZ.cjs → registry-hzrkTeIT.cjs} +61 -91
- package/dist/registry-hzrkTeIT.cjs.map +1 -0
- package/dist/{schemas-Q2dyOgc2.cjs → schemas-BWeskONy.cjs} +5 -7
- package/dist/{schemas-Q2dyOgc2.cjs.map → schemas-BWeskONy.cjs.map} +1 -1
- package/dist/{schemas-yId-bJhD.js → schemas-C7TViWCg.js} +5 -7
- package/dist/{schemas-yId-bJhD.js.map → schemas-C7TViWCg.js.map} +1 -1
- package/dist/schemas.cjs +3 -3
- package/dist/schemas.d.cts +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +3 -3
- package/dist/{scoring-CaPS6q8b.cjs → scoring-CtkCFyFT.cjs} +22 -42
- package/dist/{scoring-CaPS6q8b.cjs.map → scoring-CtkCFyFT.cjs.map} +1 -1
- package/dist/{scoring-CLMdk8i9.js → scoring-DD1GHcLI.js} +22 -42
- package/dist/{scoring-CLMdk8i9.js.map → scoring-DD1GHcLI.js.map} +1 -1
- package/dist/scoring.cjs +2 -2
- package/dist/scoring.d.cts +2 -2
- package/dist/scoring.d.ts +2 -2
- package/dist/scoring.js +2 -2
- package/dist/{xapi-BX0hvRRB.cjs → xapi-7btSpx6v.cjs} +5 -8
- package/dist/{xapi-BX0hvRRB.cjs.map → xapi-7btSpx6v.cjs.map} +1 -1
- package/dist/{xapi-Cdk9fTvV.js → xapi-Cgicg-zU.js} +5 -8
- package/dist/{xapi-Cdk9fTvV.js.map → xapi-Cgicg-zU.js.map} +1 -1
- package/dist/xapi.cjs +1 -1
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/dist/xapi.js +1 -1
- package/package.json +2 -2
- package/dist/ai-i3jwXnpX.d.cts.map +0 -1
- package/dist/ai-i3jwXnpX.d.ts.map +0 -1
- package/dist/ai-writing-C4YRVrFi.cjs.map +0 -1
- package/dist/ai-writing-OJ5m_1EB.js.map +0 -1
- package/dist/index--U7hHV0s.d.cts.map +0 -1
- package/dist/index-CFRgZLhH.d.cts.map +0 -1
- package/dist/index-DeD8EI1D.d.ts.map +0 -1
- package/dist/index-Dj92T76o.d.ts.map +0 -1
- package/dist/index-Uh1u57yq.d.cts.map +0 -1
- package/dist/index-WBHSrIUU.d.ts.map +0 -1
- package/dist/registry-B23o9UWh.js.map +0 -1
- package/dist/registry-Ih5n4PVZ.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -19,11 +19,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
19
19
|
value: mod,
|
|
20
20
|
enumerable: true
|
|
21
21
|
}) : target, mod));
|
|
22
|
-
//#endregion
|
|
23
22
|
let zod_v4 = require("zod/v4");
|
|
24
23
|
zod_v4 = __toESM(zod_v4, 1);
|
|
25
24
|
let zod_v4_core = require("zod/v4/core");
|
|
26
|
-
|
|
25
|
+
// src/schemas/ai.ts
|
|
27
26
|
/**
|
|
28
27
|
* What an author allows AI to do for one item: see `ActivityAiPermissions`.
|
|
29
28
|
* Loose like every content schema, so a key a later release adds survives an
|
|
@@ -33,8 +32,7 @@ const AiPermissionsSchema = zod_v4.looseObject({
|
|
|
33
32
|
explanations: zod_v4.boolean().optional(),
|
|
34
33
|
hints: zod_v4.boolean().optional()
|
|
35
34
|
});
|
|
36
|
-
|
|
37
|
-
//#region src/schemas/feedback.ts
|
|
35
|
+
// src/schemas/feedback.ts
|
|
38
36
|
/**
|
|
39
37
|
* Optional authored "overall feedback" shown after submission, selected by
|
|
40
38
|
* whether the learner passed (h5p-style overall feedback). Both fields are
|
|
@@ -44,8 +42,7 @@ const FeedbackSchema = zod_v4.looseObject({
|
|
|
44
42
|
correct: zod_v4.string().min(1).optional(),
|
|
45
43
|
incorrect: zod_v4.string().min(1).optional()
|
|
46
44
|
});
|
|
47
|
-
|
|
48
|
-
//#region src/schemas/text-length.ts
|
|
45
|
+
// src/schemas/text-length.ts
|
|
49
46
|
/**
|
|
50
47
|
* `schema`, refusing a string longer than `max` UTF-16 code units — its
|
|
51
48
|
* JavaScript `length`, the unit these limits have always counted in.
|
|
@@ -68,8 +65,7 @@ function maxUnits(schema, max) {
|
|
|
68
65
|
});
|
|
69
66
|
}).meta({ maxLength: max });
|
|
70
67
|
}
|
|
71
|
-
|
|
72
|
-
//#region src/schemas/media.ts
|
|
68
|
+
// src/schemas/media.ts
|
|
73
69
|
/**
|
|
74
70
|
* Optional media attached to an activity, rendered above the question or
|
|
75
71
|
* passage — e.g. a recording to listen to, or an embedded video to watch
|
|
@@ -267,8 +263,7 @@ const RedactedMediaSchema = zod_v4.strictObject({
|
|
|
267
263
|
error: "embed media requires an absolute http(s) provider URL. data:, blob:, and relative URLs are not allowed for embeds — the embed iframe runs with allow-scripts, and a data:/same-origin document there is an XSS vector.",
|
|
268
264
|
path: ["url"]
|
|
269
265
|
}).refine(posterFits, POSTER_FITS).refine(tracksFit, TRACKS_FIT).refine(tracksAreDistinct, TRACKS_DISTINCT);
|
|
270
|
-
|
|
271
|
-
//#region src/schemas/fill-in-the-blanks.ts
|
|
266
|
+
// src/schemas/fill-in-the-blanks.ts
|
|
272
267
|
/**
|
|
273
268
|
* Matches `{{ blank_id }}` placeholders in a passage, capturing the trimmed id.
|
|
274
269
|
* Exported for the draft checks in `authoring/`, which must read a passage
|
|
@@ -276,6 +271,12 @@ const RedactedMediaSchema = zod_v4.strictObject({
|
|
|
276
271
|
*/
|
|
277
272
|
const PLACEHOLDER_RE = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
278
273
|
/**
|
|
274
|
+
* The instructions of an item with a passage: plain text, with no `{{id}}`
|
|
275
|
+
* placeholder. Blanks and gaps live in the passage only, and one written here
|
|
276
|
+
* would be shown to the learner as it stands. Shared by Gap Select.
|
|
277
|
+
*/
|
|
278
|
+
const PassageInstructionsSchema = zod_v4.string().refine((text) => text.match(PLACEHOLDER_RE) === null, { error: "The instructions are plain text: a {{id}} placeholder belongs in the passage, where its blank or gap is." });
|
|
279
|
+
/**
|
|
279
280
|
* Zod schema for a `TextMatchPolicy` — the opt-in matching tolerances a blank
|
|
280
281
|
* may declare. Every default reproduces the v1 trim + case-fold semantics.
|
|
281
282
|
*/
|
|
@@ -323,6 +324,7 @@ const FillInTheBlanksDataSchema = zod_v4.looseObject({
|
|
|
323
324
|
type: zod_v4.literal("fill-in-the-blanks"),
|
|
324
325
|
id: zod_v4.string().min(1),
|
|
325
326
|
title: zod_v4.string().min(1),
|
|
327
|
+
instructions: PassageInstructionsSchema.optional(),
|
|
326
328
|
passage: zod_v4.string().min(1),
|
|
327
329
|
passageHtml: zod_v4.string().optional(),
|
|
328
330
|
blanks: zod_v4.array(BlankConfigSchema).min(1),
|
|
@@ -354,8 +356,7 @@ const FillInTheBlanksDataSchema = zod_v4.looseObject({
|
|
|
354
356
|
error: "Each blank id must appear exactly once in blanks[] and have exactly one matching {{id}} placeholder in the passage, and vice versa.",
|
|
355
357
|
path: ["passage"]
|
|
356
358
|
});
|
|
357
|
-
|
|
358
|
-
//#region src/answer-leak.ts
|
|
359
|
+
// src/answer-leak.ts
|
|
359
360
|
/**
|
|
360
361
|
* Whether a text gives an answer away: the rule an AI hint is held to, and the
|
|
361
362
|
* one the item critic holds an author's own hint, title and passage to.
|
|
@@ -442,8 +443,7 @@ function revealsAnswer(text, answer, passage, position) {
|
|
|
442
443
|
if (before === void 0 && after === void 0) return containsWords(words, needle);
|
|
443
444
|
return before !== void 0 && containsWords(words, [before, ...needle]) || after !== void 0 && containsWords(words, [...needle, after]);
|
|
444
445
|
}
|
|
445
|
-
|
|
446
|
-
//#region src/built-in-types.ts
|
|
446
|
+
// src/built-in-types.ts
|
|
447
447
|
/**
|
|
448
448
|
* The activity types the SDK ships, in one closed list.
|
|
449
449
|
*
|
|
@@ -479,8 +479,7 @@ function isBuiltInActivityType(type) {
|
|
|
479
479
|
* @internal
|
|
480
480
|
*/
|
|
481
481
|
function everyBuiltInTypeHandled(_value) {}
|
|
482
|
-
|
|
483
|
-
//#region src/scoring/dictation/edit-distance.ts
|
|
482
|
+
// src/scoring/dictation/edit-distance.ts
|
|
484
483
|
/**
|
|
485
484
|
* The code points of `text`, as numbers. A surrogate pair is one code point; a
|
|
486
485
|
* lone surrogate iterates as one code point too — deterministic, never thrown.
|
|
@@ -532,8 +531,7 @@ function similarity(a, b) {
|
|
|
532
531
|
const max = Math.max(codePoints(a).length, codePoints(b).length);
|
|
533
532
|
return max === 0 ? 0 : (max - editDistance(a, b)) / max;
|
|
534
533
|
}
|
|
535
|
-
|
|
536
|
-
//#region src/validation-scope.ts
|
|
534
|
+
// src/validation-scope.ts
|
|
537
535
|
/**
|
|
538
536
|
* Work shared for the length of one outermost validation call.
|
|
539
537
|
*
|
|
@@ -572,8 +570,7 @@ function scopeCache(key, create) {
|
|
|
572
570
|
}
|
|
573
571
|
return value;
|
|
574
572
|
}
|
|
575
|
-
|
|
576
|
-
//#region src/scoring/dictation/unicode-joining.ts
|
|
573
|
+
// src/scoring/dictation/unicode-joining.ts
|
|
577
574
|
/**
|
|
578
575
|
* Unicode data the dictation normaliser reads when it decides whether a joiner
|
|
579
576
|
* changes how the text is drawn (see `normalize.ts`): the viramas, and which
|
|
@@ -791,8 +788,7 @@ const JOINS_BACKWARD = [
|
|
|
791
788
|
[69577, 69578],
|
|
792
789
|
[125184, 125251]
|
|
793
790
|
];
|
|
794
|
-
|
|
795
|
-
//#region src/scoring/dictation/normalize.ts
|
|
791
|
+
// src/scoring/dictation/normalize.ts
|
|
796
792
|
/**
|
|
797
793
|
* The longest transcript a dictation accepts, in code points, before and after
|
|
798
794
|
* its equivalences are applied — and its rules may not grow it past twice
|
|
@@ -1752,8 +1748,7 @@ function searchReveal(forms, candidate) {
|
|
|
1752
1748
|
return fields.some((field) => containsPhrase(field, phrase));
|
|
1753
1749
|
});
|
|
1754
1750
|
}
|
|
1755
|
-
|
|
1756
|
-
//#region src/scoring/dictation/align.ts
|
|
1751
|
+
// src/scoring/dictation/align.ts
|
|
1757
1752
|
/**
|
|
1758
1753
|
* The words the scorer can emit a detail for, one list per candidate — index 0
|
|
1759
1754
|
* is the transcript, index n is `acceptedTranscripts[n − 1]` — each word in the
|
|
@@ -1952,8 +1947,7 @@ function alignWords(reference, attempt) {
|
|
|
1952
1947
|
}
|
|
1953
1948
|
return words;
|
|
1954
1949
|
}
|
|
1955
|
-
|
|
1956
|
-
//#region src/errors.ts
|
|
1950
|
+
// src/errors.ts
|
|
1957
1951
|
/** Thrown when activity data fails schema validation at a component boundary. */
|
|
1958
1952
|
var ActivitySchemaError = class extends Error {
|
|
1959
1953
|
activityType;
|
|
@@ -2007,8 +2001,7 @@ var DeferredScoringError = class extends Error {
|
|
|
2007
2001
|
this.name = "DeferredScoringError";
|
|
2008
2002
|
}
|
|
2009
2003
|
};
|
|
2010
|
-
|
|
2011
|
-
//#region src/schemas/after-issues.ts
|
|
2004
|
+
// src/schemas/after-issues.ts
|
|
2012
2005
|
/**
|
|
2013
2006
|
* A check zod runs even when another field was refused. An ordinary check is
|
|
2014
2007
|
* skipped once any issue has been reported, so an author fixing a recording's
|
|
@@ -2045,8 +2038,7 @@ function parsedFields(payload) {
|
|
|
2045
2038
|
refused
|
|
2046
2039
|
};
|
|
2047
2040
|
}
|
|
2048
|
-
|
|
2049
|
-
//#region src/schemas/dictation.ts
|
|
2041
|
+
// src/schemas/dictation.ts
|
|
2050
2042
|
/**
|
|
2051
2043
|
* Zod schema for the slower second recording of a dictation. Loose like every
|
|
2052
2044
|
* content schema (a sidecar survives), audio only, and — deliberately — with no
|
|
@@ -2228,8 +2220,7 @@ function groupCaptionsField(group, written) {
|
|
|
2228
2220
|
}
|
|
2229
2221
|
/** The message every validator gives for {@link groupCaptionsRevealDictation}. */
|
|
2230
2222
|
const 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.";
|
|
2231
|
-
|
|
2232
|
-
//#region src/authoring/issues.ts
|
|
2223
|
+
// src/authoring/issues.ts
|
|
2233
2224
|
/**
|
|
2234
2225
|
* Every issue code the SDK's draft checks can report, with its severity.
|
|
2235
2226
|
*
|
|
@@ -2565,8 +2556,7 @@ function coveredPathsOf(reported) {
|
|
|
2565
2556
|
}
|
|
2566
2557
|
return covered;
|
|
2567
2558
|
}
|
|
2568
|
-
|
|
2569
|
-
//#region src/authoring/dictation.ts
|
|
2559
|
+
// src/authoring/dictation.ts
|
|
2570
2560
|
/**
|
|
2571
2561
|
* Draft support for `dictation`.
|
|
2572
2562
|
*
|
|
@@ -2756,8 +2746,7 @@ function checkTolerance(tolerance) {
|
|
|
2756
2746
|
}
|
|
2757
2747
|
return issues;
|
|
2758
2748
|
}
|
|
2759
|
-
|
|
2760
|
-
//#region src/count-words.ts
|
|
2749
|
+
// src/count-words.ts
|
|
2761
2750
|
/**
|
|
2762
2751
|
* Canonical word counter for written-response bounds: tokens are
|
|
2763
2752
|
* maximal runs of non-whitespace (split on `\s+`), so hyphenated forms
|
|
@@ -2862,8 +2851,7 @@ function levelDistribution(values, count, chosen) {
|
|
|
2862
2851
|
const sum = read.reduce((total, p) => total + p, 0);
|
|
2863
2852
|
return Math.abs(sum - 1) <= 1e-6 && read[chosen] === Math.max(...read) ? read : null;
|
|
2864
2853
|
}
|
|
2865
|
-
|
|
2866
|
-
//#region src/scoring/strategies/all-or-nothing.ts
|
|
2854
|
+
// src/scoring/strategies/all-or-nothing.ts
|
|
2867
2855
|
/**
|
|
2868
2856
|
* All-or-nothing scoring: full credit only when every item is correct.
|
|
2869
2857
|
*
|
|
@@ -2873,8 +2861,7 @@ function levelDistribution(values, count, chosen) {
|
|
|
2873
2861
|
function allOrNothingStrategy(correctItems) {
|
|
2874
2862
|
return correctItems.every((isCorrect) => isCorrect) ? 1 : 0;
|
|
2875
2863
|
}
|
|
2876
|
-
|
|
2877
|
-
//#region src/scoring/strategies/partial.ts
|
|
2864
|
+
// src/scoring/strategies/partial.ts
|
|
2878
2865
|
/**
|
|
2879
2866
|
* Partial-credit scoring for Multiple Choice — balanced/symmetric scheme.
|
|
2880
2867
|
*
|
|
@@ -2914,8 +2901,7 @@ function partialStrategy(correctSelected, incorrectSelected, totalCorrect, total
|
|
|
2914
2901
|
function partialBlankStrategy(correctBlanks, totalBlanks) {
|
|
2915
2902
|
return correctBlanks / totalBlanks;
|
|
2916
2903
|
}
|
|
2917
|
-
|
|
2918
|
-
//#region src/scoring/text-match.ts
|
|
2904
|
+
// src/scoring/text-match.ts
|
|
2919
2905
|
/** Combining marks (any script) removed for diacritic folding after NFD decomposition. */
|
|
2920
2906
|
const COMBINING_MARKS_RE = /\p{M}/gu;
|
|
2921
2907
|
/**
|
|
@@ -3008,8 +2994,7 @@ function matchText(input, accepted, policy = {}) {
|
|
|
3008
2994
|
via: "none"
|
|
3009
2995
|
};
|
|
3010
2996
|
}
|
|
3011
|
-
|
|
3012
|
-
//#region src/scoring/activity-scorers/fill-in-the-blanks.ts
|
|
2997
|
+
// src/scoring/activity-scorers/fill-in-the-blanks.ts
|
|
3013
2998
|
/**
|
|
3014
2999
|
* Resolves the effective match policy for a blank. The legacy
|
|
3015
3000
|
* `caseSensitive` / `trimWhitespace` flags map onto the baseline policy
|
|
@@ -3053,8 +3038,7 @@ function scoreFillInTheBlanks(data, response) {
|
|
|
3053
3038
|
details
|
|
3054
3039
|
};
|
|
3055
3040
|
}
|
|
3056
|
-
|
|
3057
|
-
//#region src/authoring/findings.ts
|
|
3041
|
+
// src/authoring/findings.ts
|
|
3058
3042
|
/**
|
|
3059
3043
|
* Every finding code the SDK's item critic can report, with its severity.
|
|
3060
3044
|
*
|
|
@@ -3107,8 +3091,7 @@ function normaliseFinding(found) {
|
|
|
3107
3091
|
severity: documented ?? (found.severity === "advice" ? "advice" : "warning")
|
|
3108
3092
|
};
|
|
3109
3093
|
}
|
|
3110
|
-
|
|
3111
|
-
//#region src/authoring/critique.ts
|
|
3094
|
+
// src/authoring/critique.ts
|
|
3112
3095
|
/**
|
|
3113
3096
|
* The built-in item critic: what an experienced item writer points out on
|
|
3114
3097
|
* review, as far as a rule can see it without a model.
|
|
@@ -3391,8 +3374,7 @@ function keyPositionFinding(items, path) {
|
|
|
3391
3374
|
if (positions.length < KEY_POSITION_MINIMUM || !positions.every((at) => at === positions[0])) return [];
|
|
3392
3375
|
return [finding("set_key_position_same", path, `In all ${positions.length} single-answer questions the right option is option ${ordinal(positions[0])}. Vary its position, or shuffle the options.`)];
|
|
3393
3376
|
}
|
|
3394
|
-
|
|
3395
|
-
//#region src/authoring/fill-in-the-blanks.ts
|
|
3377
|
+
// src/authoring/fill-in-the-blanks.ts
|
|
3396
3378
|
/**
|
|
3397
3379
|
* Draft support for `fill-in-the-blanks`.
|
|
3398
3380
|
*
|
|
@@ -3524,8 +3506,7 @@ function pairsOneToOne$1(placeholders, blanks) {
|
|
|
3524
3506
|
if (placeholders.size !== blankIds.length) return false;
|
|
3525
3507
|
return blankIds.every((id) => typeof id === "string" && placeholders.get(id) === 1);
|
|
3526
3508
|
}
|
|
3527
|
-
|
|
3528
|
-
//#region src/authoring/gap-select.ts
|
|
3509
|
+
// src/authoring/gap-select.ts
|
|
3529
3510
|
/** Mirrors `GapSelectChoiceSchema` arrays: `.min(2)` on both a gap's own list and a bank. */
|
|
3530
3511
|
const MIN_CHOICES = 2;
|
|
3531
3512
|
/**
|
|
@@ -3723,8 +3704,7 @@ function pairsOneToOne(placeholders, gaps) {
|
|
|
3723
3704
|
if (new Set(ids).size !== ids.length || placeholders.size !== ids.length) return false;
|
|
3724
3705
|
return ids.every((id) => typeof id === "string" && placeholders.get(id) === 1);
|
|
3725
3706
|
}
|
|
3726
|
-
|
|
3727
|
-
//#region src/schemas/multiple-choice.ts
|
|
3707
|
+
// src/schemas/multiple-choice.ts
|
|
3728
3708
|
/**
|
|
3729
3709
|
* Zod schema for a single Multiple Choice option. Loose: unknown keys are
|
|
3730
3710
|
* preserved through validation (forward-compat / consumer sidecars — B7).
|
|
@@ -3788,6 +3768,7 @@ const MultipleChoiceDataSchema = zod_v4.looseObject({
|
|
|
3788
3768
|
type: zod_v4.literal("multiple-choice"),
|
|
3789
3769
|
id: zod_v4.string().min(1),
|
|
3790
3770
|
title: zod_v4.string().min(1),
|
|
3771
|
+
instructions: zod_v4.string().optional(),
|
|
3791
3772
|
question: zod_v4.string().min(1),
|
|
3792
3773
|
questionHtml: zod_v4.string().optional(),
|
|
3793
3774
|
mode: zod_v4.enum(["single", "multi"]),
|
|
@@ -3817,8 +3798,7 @@ const MultipleChoiceDataSchema = zod_v4.looseObject({
|
|
|
3817
3798
|
error: "Option ids must be unique within the activity.",
|
|
3818
3799
|
path: ["options"]
|
|
3819
3800
|
});
|
|
3820
|
-
|
|
3821
|
-
//#region src/authoring/multiple-choice.ts
|
|
3801
|
+
// src/authoring/multiple-choice.ts
|
|
3822
3802
|
/** Mirrors `MultipleChoiceDataSchema`: `options` is `.min(2).max(26)`. */
|
|
3823
3803
|
const MIN_OPTIONS = 2;
|
|
3824
3804
|
const MAX_OPTIONS = 26;
|
|
@@ -3921,8 +3901,7 @@ function checkOptionMedia(media, index, ordinal) {
|
|
|
3921
3901
|
if (kind === "video" || kind === "embed") return [issue("mc_option_media_kind", [...path, "type"], `Option ${ordinal} carries ${kind === "embed" ? "an embedded player" : "a video"}, which cannot be an option: its controls swallow the click that selects the answer. Use a picture or a recording.`)];
|
|
3922
3902
|
return checkMedia(media, path, MultipleChoiceOptionMediaSchema);
|
|
3923
3903
|
}
|
|
3924
|
-
|
|
3925
|
-
//#region src/scoring/speech/limits.ts
|
|
3904
|
+
// src/scoring/speech/limits.ts
|
|
3926
3905
|
/**
|
|
3927
3906
|
* The longest reference text a read-aloud item accepts, in code points, before
|
|
3928
3907
|
* and after normalisation. It is the dictation transcript cap on purpose: the
|
|
@@ -3972,8 +3951,7 @@ const SPEECH_ASSESSMENT_MAX_WORDS = 1e3;
|
|
|
3972
3951
|
* read-aloud item comes near it.
|
|
3973
3952
|
*/
|
|
3974
3953
|
const SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH;
|
|
3975
|
-
|
|
3976
|
-
//#region src/scoring/speech/locale.ts
|
|
3954
|
+
// src/scoring/speech/locale.ts
|
|
3977
3955
|
/**
|
|
3978
3956
|
* A BCP 47 tag in the one spelling read-aloud accepts: a lowercase language of
|
|
3979
3957
|
* two or three letters, an optional title-case script, and a region of two
|
|
@@ -3989,8 +3967,7 @@ const SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH;
|
|
|
3989
3967
|
* Internal: the content schema and the assessment validator share it.
|
|
3990
3968
|
*/
|
|
3991
3969
|
const CANONICAL_LOCALE_RE = /^[a-z]{2,3}(?:-[A-Z][a-z]{3})?-(?:[A-Z]{2}|[0-9]{3})$/;
|
|
3992
|
-
|
|
3993
|
-
//#region src/schemas/read-aloud.ts
|
|
3970
|
+
// src/schemas/read-aloud.ts
|
|
3994
3971
|
/** The dimensions a read-aloud grade can be made of, in the order they are documented. */
|
|
3995
3972
|
const READ_ALOUD_DIMENSIONS = [
|
|
3996
3973
|
"accuracy",
|
|
@@ -4143,8 +4120,7 @@ const ReadAloudDataSchema = zod_v4.looseObject({
|
|
|
4143
4120
|
if (minSeconds !== void 0 && minSeconds >= maxSeconds) report(["recording", "minSeconds"], minSeconds, "The shortest take must be shorter than the longest.");
|
|
4144
4121
|
}
|
|
4145
4122
|
}));
|
|
4146
|
-
|
|
4147
|
-
//#region src/authoring/read-aloud.ts
|
|
4123
|
+
// src/authoring/read-aloud.ts
|
|
4148
4124
|
/**
|
|
4149
4125
|
* Draft support for `read-aloud`.
|
|
4150
4126
|
*
|
|
@@ -4307,8 +4283,7 @@ function checkSlowRecording(draft) {
|
|
|
4307
4283
|
if (typeof slow.url === "string" && slow.url !== "" && slow.url === media.url) issues.push(issue("ra_slow_media_same_recording", ["slowMedia", "url"], "The slow model recording is the same file as the recording. Point it at the slower reading."));
|
|
4308
4284
|
return issues;
|
|
4309
4285
|
}
|
|
4310
|
-
|
|
4311
|
-
//#region src/authoring/written-response.ts
|
|
4286
|
+
// src/authoring/written-response.ts
|
|
4312
4287
|
/**
|
|
4313
4288
|
* Draft support for `written-response`.
|
|
4314
4289
|
*
|
|
@@ -4396,8 +4371,7 @@ function checkCriteria(criteria) {
|
|
|
4396
4371
|
else if (totalWeight === Number.POSITIVE_INFINITY) issues.push(issue("wr_rubric_weights_too_large", ["rubric", "criteria"], "The rubric weights add up to more than can be calculated with. Use smaller weights."));
|
|
4397
4372
|
return issues;
|
|
4398
4373
|
}
|
|
4399
|
-
|
|
4400
|
-
//#region src/schemas/gap-select.ts
|
|
4374
|
+
// src/schemas/gap-select.ts
|
|
4401
4375
|
/**
|
|
4402
4376
|
* Zod schema for one selectable choice. Loose, like every other schema here:
|
|
4403
4377
|
* unknown keys are preserved so a consumer sidecar survives validation.
|
|
@@ -4461,6 +4435,7 @@ const GapSelectDataSchema = zod_v4.looseObject({
|
|
|
4461
4435
|
type: zod_v4.literal("gap-select"),
|
|
4462
4436
|
id: zod_v4.string().min(1),
|
|
4463
4437
|
title: zod_v4.string().min(1),
|
|
4438
|
+
instructions: PassageInstructionsSchema.optional(),
|
|
4464
4439
|
passage: zod_v4.string().min(1),
|
|
4465
4440
|
passageHtml: zod_v4.string().optional(),
|
|
4466
4441
|
gaps: zod_v4.array(GapSelectGapSchema).min(1),
|
|
@@ -4521,8 +4496,7 @@ const GapSelectDataSchema = zod_v4.looseObject({
|
|
|
4521
4496
|
error: "Each gap needs unique choice ids and a `correctChoiceId` that is one of the choices it offers.",
|
|
4522
4497
|
path: ["gaps"]
|
|
4523
4498
|
});
|
|
4524
|
-
|
|
4525
|
-
//#region src/schemas/written-response.ts
|
|
4499
|
+
// src/schemas/written-response.ts
|
|
4526
4500
|
/** Zod schema for a single rubric criterion. Loose: unknown keys preserved. */
|
|
4527
4501
|
const WrittenResponseRubricCriterionSchema = zod_v4.looseObject({
|
|
4528
4502
|
name: zod_v4.string().min(1),
|
|
@@ -4593,8 +4567,7 @@ const WrittenResponseDataSchema = zod_v4.looseObject({
|
|
|
4593
4567
|
error: "maxWords must be greater than or equal to minWords.",
|
|
4594
4568
|
path: ["maxWords"]
|
|
4595
4569
|
});
|
|
4596
|
-
|
|
4597
|
-
//#region src/schemas/redacted.ts
|
|
4570
|
+
// src/schemas/redacted.ts
|
|
4598
4571
|
/**
|
|
4599
4572
|
* Schemas for REDACTED activity data — the learner-safe projection `redact()`
|
|
4600
4573
|
* produces (R7). Deliberately STRICT (`z.strictObject`), the opposite of the
|
|
@@ -4658,6 +4631,7 @@ const RedactedMultipleChoiceOptionSchema = zod_v4.strictObject({
|
|
|
4658
4631
|
const RedactedMultipleChoiceDataSchema = zod_v4.strictObject({
|
|
4659
4632
|
...redactedBase,
|
|
4660
4633
|
type: zod_v4.literal("multiple-choice"),
|
|
4634
|
+
instructions: zod_v4.string().optional(),
|
|
4661
4635
|
question: zod_v4.string().min(1),
|
|
4662
4636
|
questionHtml: zod_v4.string().optional(),
|
|
4663
4637
|
mode: zod_v4.enum(["single", "multi"]),
|
|
@@ -4673,6 +4647,7 @@ const RedactedBlankConfigSchema = zod_v4.strictObject({
|
|
|
4673
4647
|
const RedactedFillInTheBlanksDataSchema = zod_v4.strictObject({
|
|
4674
4648
|
...redactedBase,
|
|
4675
4649
|
type: zod_v4.literal("fill-in-the-blanks"),
|
|
4650
|
+
instructions: zod_v4.string().optional(),
|
|
4676
4651
|
passage: zod_v4.string().min(1),
|
|
4677
4652
|
passageHtml: zod_v4.string().optional(),
|
|
4678
4653
|
blanks: zod_v4.array(RedactedBlankConfigSchema).min(1)
|
|
@@ -4711,6 +4686,7 @@ const RedactedGapSelectGapSchema = zod_v4.strictObject({
|
|
|
4711
4686
|
const RedactedGapSelectDataSchema = zod_v4.strictObject({
|
|
4712
4687
|
...redactedBase,
|
|
4713
4688
|
type: zod_v4.literal("gap-select"),
|
|
4689
|
+
instructions: zod_v4.string().optional(),
|
|
4714
4690
|
passage: zod_v4.string().min(1),
|
|
4715
4691
|
passageHtml: zod_v4.string().optional(),
|
|
4716
4692
|
gaps: zod_v4.array(RedactedGapSelectGapSchema).min(1),
|
|
@@ -4836,8 +4812,7 @@ const RedactedReadAloudDataSchema = zod_v4.strictObject({
|
|
|
4836
4812
|
path: ["slowMedia", "url"]
|
|
4837
4813
|
});
|
|
4838
4814
|
});
|
|
4839
|
-
|
|
4840
|
-
//#region src/scoring/activity-scorers/dictation.ts
|
|
4815
|
+
// src/scoring/activity-scorers/dictation.ts
|
|
4841
4816
|
/**
|
|
4842
4817
|
* Scores a Dictation response: the character-level similarity of what the
|
|
4843
4818
|
* learner typed to the transcript, over the whole sentence.
|
|
@@ -4876,8 +4851,7 @@ function scoreDictation(data, response) {
|
|
|
4876
4851
|
details
|
|
4877
4852
|
};
|
|
4878
4853
|
}
|
|
4879
|
-
|
|
4880
|
-
//#region src/scoring/activity-scorers/gap-select.ts
|
|
4854
|
+
// src/scoring/activity-scorers/gap-select.ts
|
|
4881
4855
|
/**
|
|
4882
4856
|
* The choices a gap offers: its own list, or the bank it names.
|
|
4883
4857
|
*
|
|
@@ -4931,8 +4905,7 @@ function scoreGapSelect(data, response) {
|
|
|
4931
4905
|
details
|
|
4932
4906
|
};
|
|
4933
4907
|
}
|
|
4934
|
-
|
|
4935
|
-
//#region src/scoring/activity-scorers/multiple-choice.ts
|
|
4908
|
+
// src/scoring/activity-scorers/multiple-choice.ts
|
|
4936
4909
|
/**
|
|
4937
4910
|
* Scores a Multiple Choice response. Pure; trusts its typed inputs (validation
|
|
4938
4911
|
* is the component boundary's job). Options are looked up by id; an unknown
|
|
@@ -4976,8 +4949,7 @@ function scoreMultipleChoice(data, response) {
|
|
|
4976
4949
|
details
|
|
4977
4950
|
};
|
|
4978
4951
|
}
|
|
4979
|
-
|
|
4980
|
-
//#region src/registry/define.ts
|
|
4952
|
+
// src/registry/define.ts
|
|
4981
4953
|
/**
|
|
4982
4954
|
* Identity helper that gives full type inference when authoring a descriptor:
|
|
4983
4955
|
*
|
|
@@ -4992,8 +4964,7 @@ function scoreMultipleChoice(data, response) {
|
|
|
4992
4964
|
function defineActivityType(descriptor) {
|
|
4993
4965
|
return descriptor;
|
|
4994
4966
|
}
|
|
4995
|
-
|
|
4996
|
-
//#region src/registry/keep-when.ts
|
|
4967
|
+
// src/registry/keep-when.ts
|
|
4997
4968
|
/**
|
|
4998
4969
|
* A nested field policy that keeps its field only when the field's value
|
|
4999
4970
|
* passes a test. Internal: the symbol is never exported, so no host policy can
|
|
@@ -5018,8 +4989,7 @@ function keepWhen(policy, test) {
|
|
|
5018
4989
|
function guardOf(policy) {
|
|
5019
4990
|
return policy[KEEP_WHEN];
|
|
5020
4991
|
}
|
|
5021
|
-
|
|
5022
|
-
//#region src/registry/builtins.ts
|
|
4992
|
+
// src/registry/builtins.ts
|
|
5023
4993
|
/**
|
|
5024
4994
|
* Where the built-in types keep their files (`mediaSlots`). Every type has its
|
|
5025
4995
|
* `media`; dictation and read-aloud add a slower recording; a multiple-choice
|
|
@@ -5137,6 +5107,7 @@ const TEXT_MATCH_FIELD_POLICY = {
|
|
|
5137
5107
|
};
|
|
5138
5108
|
const MULTIPLE_CHOICE_FIELD_POLICY = {
|
|
5139
5109
|
...SHARED_PUBLIC_FIELDS,
|
|
5110
|
+
instructions: "public",
|
|
5140
5111
|
question: "public",
|
|
5141
5112
|
questionHtml: "public",
|
|
5142
5113
|
mode: "public",
|
|
@@ -5171,6 +5142,7 @@ const MULTIPLE_CHOICE_FIELD_POLICY = {
|
|
|
5171
5142
|
*/
|
|
5172
5143
|
const GAP_SELECT_FIELD_POLICY = {
|
|
5173
5144
|
...SHARED_PUBLIC_FIELDS,
|
|
5145
|
+
instructions: "public",
|
|
5174
5146
|
passage: "public",
|
|
5175
5147
|
passageHtml: "public",
|
|
5176
5148
|
presentation: "public",
|
|
@@ -5197,6 +5169,7 @@ const GAP_SELECT_FIELD_POLICY = {
|
|
|
5197
5169
|
};
|
|
5198
5170
|
const FILL_IN_THE_BLANKS_FIELD_POLICY = {
|
|
5199
5171
|
...SHARED_PUBLIC_FIELDS,
|
|
5172
|
+
instructions: "public",
|
|
5200
5173
|
passage: "public",
|
|
5201
5174
|
passageHtml: "public",
|
|
5202
5175
|
scoringStrategy: "answer-key",
|
|
@@ -5499,8 +5472,7 @@ const BUILT_IN_DESCRIPTORS = {
|
|
|
5499
5472
|
dictation: dictationType,
|
|
5500
5473
|
"read-aloud": readAloudType
|
|
5501
5474
|
};
|
|
5502
|
-
|
|
5503
|
-
//#region src/schemas/read-schema.ts
|
|
5475
|
+
// src/schemas/read-schema.ts
|
|
5504
5476
|
/**
|
|
5505
5477
|
* How every entry point reads a schema — `validateActivity`, `validateDraft`,
|
|
5506
5478
|
* `validateItemGroup`, `redact`, `assertRedacted` — so a schema is read one way
|
|
@@ -5616,8 +5588,7 @@ function standardJsonSchemaOf(schema, target = "draft-07") {
|
|
|
5616
5588
|
const generated = converter.output({ target });
|
|
5617
5589
|
return generated !== null && typeof generated === "object" && !Array.isArray(generated) ? generated : void 0;
|
|
5618
5590
|
}
|
|
5619
|
-
|
|
5620
|
-
//#region src/registry/registry.ts
|
|
5591
|
+
// src/registry/registry.ts
|
|
5621
5592
|
/**
|
|
5622
5593
|
* Module-scoped default registry (deliberate — no registry instances until a
|
|
5623
5594
|
* second consumer exists), created holding the SDK's own types.
|
|
@@ -5663,7 +5634,6 @@ function getActivityTypeDescriptor(type) {
|
|
|
5663
5634
|
function registeredActivityTypes() {
|
|
5664
5635
|
return [...registry.keys()];
|
|
5665
5636
|
}
|
|
5666
|
-
//#endregion
|
|
5667
5637
|
Object.defineProperty(exports, "ActivitySchemaError", {
|
|
5668
5638
|
enumerable: true,
|
|
5669
5639
|
get: function() {
|
|
@@ -6157,4 +6127,4 @@ Object.defineProperty(exports, "writtenResponseType", {
|
|
|
6157
6127
|
}
|
|
6158
6128
|
});
|
|
6159
6129
|
|
|
6160
|
-
//# sourceMappingURL=registry-
|
|
6130
|
+
//# sourceMappingURL=registry-hzrkTeIT.cjs.map
|