@intellectif/lk-core 1.2.0 → 1.4.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 +29 -0
- package/README.md +2 -2
- package/dist/ai-CnmLPMzd.d.cts +2417 -0
- package/dist/ai-CnmLPMzd.d.cts.map +1 -0
- package/dist/ai-CnmLPMzd.d.ts +2417 -0
- package/dist/ai-CnmLPMzd.d.ts.map +1 -0
- package/dist/ai-check.cjs +845 -620
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +82 -80
- package/dist/ai-check.d.cts.map +1 -0
- package/dist/ai-check.d.ts +82 -80
- package/dist/ai-check.d.ts.map +1 -0
- package/dist/ai-check.js +843 -621
- package/dist/ai-check.js.map +1 -1
- package/dist/ai-writing-CPpH9Qxq.js +2601 -0
- package/dist/ai-writing-CPpH9Qxq.js.map +1 -0
- package/dist/ai-writing-G6tnCGzw.cjs +2846 -0
- package/dist/ai-writing-G6tnCGzw.cjs.map +1 -0
- package/dist/index-2nigSf4N.d.cts +339 -0
- package/dist/index-2nigSf4N.d.cts.map +1 -0
- package/dist/index-B54baFUA.d.ts +339 -0
- package/dist/index-B54baFUA.d.ts.map +1 -0
- package/dist/index-BAfEHCnD.d.cts +1071 -0
- package/dist/index-BAfEHCnD.d.cts.map +1 -0
- package/dist/index-BqMXWuNC.d.cts +153 -0
- package/dist/index-BqMXWuNC.d.cts.map +1 -0
- package/dist/index-CVWvymVb.d.ts +1071 -0
- package/dist/index-CVWvymVb.d.ts.map +1 -0
- package/dist/index-CcHDTxIZ.d.ts +153 -0
- package/dist/index-CcHDTxIZ.d.ts.map +1 -0
- package/dist/index.cjs +1211 -1146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +941 -861
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +941 -861
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1063 -1147
- package/dist/index.js.map +1 -1
- package/dist/item-group-DXiR8nOr.js +445 -0
- package/dist/item-group-DXiR8nOr.js.map +1 -0
- package/dist/item-group-DroFXgLb.cjs +505 -0
- package/dist/item-group-DroFXgLb.cjs.map +1 -0
- package/dist/registry-DVi0LR_i.cjs +5915 -0
- package/dist/registry-DVi0LR_i.cjs.map +1 -0
- package/dist/registry-Dsx9mNsS.js +5449 -0
- package/dist/registry-Dsx9mNsS.js.map +1 -0
- package/dist/schemas-Bdw0nGPo.js +152 -0
- package/dist/schemas-Bdw0nGPo.js.map +1 -0
- package/dist/schemas-DVbAOrtd.cjs +224 -0
- package/dist/schemas-DVbAOrtd.cjs.map +1 -0
- package/dist/schemas.cjs +16 -34
- package/dist/schemas.d.cts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/schemas.js +3 -34
- package/dist/scoring-B2_HEhMT.cjs +1748 -0
- package/dist/scoring-B2_HEhMT.cjs.map +1 -0
- package/dist/scoring-BZqUkuDF.js +1604 -0
- package/dist/scoring-BZqUkuDF.js.map +1 -0
- package/dist/scoring.cjs +37 -75
- package/dist/scoring.d.cts +3 -1103
- package/dist/scoring.d.ts +3 -1103
- package/dist/scoring.js +3 -75
- package/dist/xapi-CMTph7wG.js +332 -0
- package/dist/xapi-CMTph7wG.js.map +1 -0
- package/dist/xapi-DNzkSJ0S.cjs +362 -0
- package/dist/xapi-DNzkSJ0S.cjs.map +1 -0
- package/dist/xapi.cjs +7 -16
- package/dist/xapi.d.cts +2 -150
- package/dist/xapi.d.ts +2 -150
- package/dist/xapi.js +2 -16
- package/package.json +4 -4
- package/dist/activity-D705CXng.d.cts +0 -2162
- package/dist/activity-D705CXng.d.ts +0 -2162
- package/dist/chunk-46BXIGLG.cjs +0 -272
- package/dist/chunk-46BXIGLG.cjs.map +0 -1
- package/dist/chunk-4YANYTFN.cjs +0 -1256
- package/dist/chunk-4YANYTFN.cjs.map +0 -1
- package/dist/chunk-7KOWU4RO.js +0 -2207
- package/dist/chunk-7KOWU4RO.js.map +0 -1
- package/dist/chunk-7THXD7AN.cjs +0 -5057
- package/dist/chunk-7THXD7AN.cjs.map +0 -1
- package/dist/chunk-CYCTIXUN.cjs +0 -118
- package/dist/chunk-CYCTIXUN.cjs.map +0 -1
- package/dist/chunk-CYPA5BW5.js +0 -118
- package/dist/chunk-CYPA5BW5.js.map +0 -1
- package/dist/chunk-JTNDIBZO.js +0 -272
- package/dist/chunk-JTNDIBZO.js.map +0 -1
- package/dist/chunk-MV2N2WNS.js +0 -352
- package/dist/chunk-MV2N2WNS.js.map +0 -1
- package/dist/chunk-MXI26H62.cjs +0 -2207
- package/dist/chunk-MXI26H62.cjs.map +0 -1
- package/dist/chunk-QS7B42ZR.js +0 -5057
- package/dist/chunk-QS7B42ZR.js.map +0 -1
- package/dist/chunk-QX2ERL72.js +0 -1256
- package/dist/chunk-QX2ERL72.js.map +0 -1
- package/dist/chunk-ZWXQSKCX.cjs +0 -352
- package/dist/chunk-ZWXQSKCX.cjs.map +0 -1
- package/dist/index-BChYtrEe.d.ts +0 -548
- package/dist/index-VXt_v3YI.d.cts +0 -548
- package/dist/schemas.cjs.map +0 -1
- package/dist/schemas.js.map +0 -1
- package/dist/scoring.cjs.map +0 -1
- package/dist/scoring.js.map +0 -1
- package/dist/xapi.cjs.map +0 -1
- package/dist/xapi.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { $ as AiWritingFeedbackRequest, $t as ReadAloudDimension, A as AiGapSelectFacts, An as InlineCorrection, At as DictationLearnerResponse, B as AiReadingFacts, Bt as InteractionEvent, C as AiDraftsCall, Cn as XAPIVerbObject, Ct as ActivityResult, D as AiFeature, Dn as GraderKind, Dt as DeferredScoringPartial, E as AiExplanationRequest, En as Grader, Et as DeferredReason, F as AiItemFacts, Ft as GapSelectBank, G as AiSupportedActivityType, Gt as MediaPlaybackPolicy, H as AiRefusal, Ht as ItemOutcome, I as AiMaterialFacts, It as GapSelectChoice, J as AiVideoDraft, Jt as MultipleChoiceLearnerResponse, K as AiTextResult, Kt as MediaTrack, L as AiMultipleChoiceFacts, Lt as GapSelectData, M as AiGrade, Mn as TextMatchResult, Mt as DictationTolerance, N as AiGroupInput, Nn as levenshteinDistance, Nt as FillInTheBlanksData, O as AiFillInTheBlanksFacts, On as GraderUsage, Ot as DictationData, P as AiHintRequest, Pn as matchText, Pt as FillInTheBlanksLearnerResponse, Q as AiWritingFeedback, Qt as ReadAloudData, R as AiOptionFact, Rt as GapSelectGap, S as AiDrafts, Sn as XAPIStatement, St as ActivityMedia, T as AiDraftsRun, Tn as GradeRecord, Tt as BlankConfig, U as AiRubricCriterionFact, Ut as LearnerResponse, V as AiReadingWordFact, Vt as InteractionKind, W as AiSoundFact, Wt as LearnerResponseMap, X as AiWritingCorrection, Xt as MultipleChoiceOptionMedia, Y as AiWordFact, Yt as MultipleChoiceOption, Z as AiWritingFacts, Zt as NativeControlHint, _ as AiDraftCaption, _n as XAPIContextActivities, _t as ItemFinding, a as AiCoachingRequest, an as ScoringDetail, at as SequenceSlot, b as AiDraftSource, bn as XAPIResult, bt as ActivityDataMap, c as AiCriterionJudgement, cn as ValidationError, ct as StimulusKind, d as AiCritiqueFinding, dn as WrittenResponseLearnerResponse, dt as DraftComplete, en as ReadAloudDimensionWeight, et as AiWritingFeedbackResult, f as AiCritiqueFindingResult, fn as WrittenResponseRubric, ft as DraftContext, g as AiDictationFacts, gn as XAPIContext, gt as DraftValidationResult, h as AiCritiqueResult, hn as XAPIConfig, ht as DraftSeverity, i as AiCoaching, in as RecordingRef, it as SequenceEntry, j as AiGeneratedDraft, jn as TextMatchPolicy, jt as DictationSlowMedia, k as AiGapFact, kn as GradingState, kt as DictationEquivalence, l as AiCritique, ln as ValidationResult, lt as TimelineChapter, m as AiCritiqueRequest, mn as XAPIActor, mt as DraftNotComplete, n as AiActivityInput, nn as ReadAloudSlowMedia, nt as MediaProgress, o as AiCoachingResult, on as ScoringOutcome, ot as SequenceSlotGroup, p as AiCritiqueKind, pn as WrittenResponseRubricCriterion, pt as DraftIssue, q as AiVerdict, qt as MultipleChoiceData, r as AiBlankFact, rn as RecordingBounds, rt as MediaTimeline, s as AiCoachingWord, sn as ScoringResult, st as Stimulus, t as ActivityAiPermissions, tn as ReadAloudLearnerResponse, tt as ItemGroup, u as AiCritiqueField, un as WrittenResponseData, ut as TimelineCue, v as AiDraftProblem, vn as XAPIError, vt as ItemFindingSeverity, w as AiDraftsRequest, wn as CriterionScore, wt as ActivityType, x as AiDraftType, xn as XAPIScore, xt as ActivityFeedback, y as AiDraftSettings, yn as XAPIObject, yt as ActivityData, z as AiProvenance, zt as GapSelectLearnerResponse } from "./ai-CnmLPMzd.js";
|
|
2
|
+
import { $ as SpeechAssessment, A as diffDictationChars, B as ItemTry, C as validateItemScoringPolicy, D as DICTATION_MAX_TEXT_LENGTH, E as DICTATION_MAX_EQUIVALENCE_LENGTH, F as dictationReferenceWords, G as CompositionPolicy, H as ResolvedItemScoringPolicy, I as ItemScoringCount, J as SectionScore, K as PassFailureReason, L as ItemScoringPolicy, M as DictationReference, N as DictationWordAlignment, O as DICTATION_MAX_TRANSCRIPT_LENGTH, P as alignDictation, Q as ReadAloudWordState, R as ItemScoringPolicyIssue, S as scoreTries, T as DICTATION_MAX_EQUIVALENCES, U as AssessmentScore, V as ItemTryScore, W as AssessmentSectionInput, X as GradeReadAloudOptions, Y as composeAssessmentScore, Z as ReadAloudWordAlignment, _ as DEFAULT_PASS_THRESHOLD, a as evaluateTries, at as SpeechUnscorable, b as ITEM_SCORING_MAX_RETRIES, c as inspectWav, ct as SpeechWordError, d as READ_ALOUD_MAX_SECONDS, dt as Band, et as SpeechMeasurement, f as READ_ALOUD_MAX_TAKES, ft as RoundingMode, g as alignReadAloud, gt as roundGrade, h as validateSpeechAssessment, ht as gte, i as evaluate, it as SpeechSyllable, j as DictationAlignment, k as DictationCharOp, l as READ_ALOUD_MAX_DIMENSION_WEIGHT, lt as WavInspection, m as gradeReadAloud, mt as classifyBand, n as ItemTriesOutcome, nt as SpeechPhonemeCandidate, o as score, ot as SpeechUnscorableCode, p as SPEECH_ASSESSMENT_MAX_WORDS, pt as RoundingPolicy, q as ScoredItem, r as ScoringOptions, rt as SpeechPlausibilityPolicy, s as outcomeFromUnscorable, st as SpeechWord, t as EvaluateOptions, tt as SpeechPhoneme, u as READ_ALOUD_MAX_REFERENCE_LENGTH, ut as WavInspectionPolicy, v as computePassThreshold, w as DICTATION_MAX_ACCEPTED_TRANSCRIPTS, x as resolveItemScoringPolicy, y as DEFAULT_ITEM_SCORING_POLICY, z as ItemTriesScore } from "./index-CVWvymVb.js";
|
|
3
|
+
import { C as RedactedMultipleChoiceData, D as RedactedStimulus, E as RedactedReadAloudData, O as RedactedWrittenResponseData, S as RedactedGapSelectGap, T as RedactedMultipleChoiceOptionMedia, _ as RedactedDictationSlowMedia, a as fillInTheBlanksJsonSchema, b as RedactedGapSelectChoice, c as jsonSchemaFor, d as stimulusJsonSchema, f as writtenResponseJsonSchema, g as RedactedDictationData, h as RedactedBlankConfig, i as dictationJsonSchema, l as multipleChoiceJsonSchema, m as RedactedActivity, n as validateMedia, o as gapSelectJsonSchema, p as validateItemGroup, r as validateOptionMedia, s as itemGroupJsonSchema, t as validateActivity, u as readAloudJsonSchema, v as RedactedFillInTheBlanksData, w as RedactedMultipleChoiceOption, x as RedactedGapSelectData, y as RedactedGapSelectBank } from "./index-B54baFUA.js";
|
|
4
|
+
import { a as XAPIObjectParams, c as xapiDefinitionFor, d as XAPI_VERB_DISPLAY, i as SubmittedStatementParams, l as XAPIVerb, n as AnsweredStatementParams, o as XAPIStatementParams, r as CompletedStatementParams, s as xAPIBuilder, t as validateXAPIStatement, u as XAPIVerbKey } from "./index-CcHDTxIZ.js";
|
|
5
|
+
//#region src/ai-material.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* What a model is told about the group a question sits in: the material the
|
|
8
|
+
* learner reads and sees beside it.
|
|
9
|
+
*
|
|
10
|
+
* Internal: the request builders in `ai.ts` and `ai-writing.ts` are its public
|
|
11
|
+
* face, through their `group` input.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The longest material text a model is given, in code points. A longer one is
|
|
15
|
+
* cut and marked `truncated`: a long reading passage on an exam paper runs to
|
|
16
|
+
* 4,000–7,000.
|
|
17
|
+
*/
|
|
18
|
+
export declare const AI_MATERIAL_MAX_LENGTH = 12000;
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/ai.d.ts
|
|
9
21
|
/**
|
|
10
22
|
* The activity types the SDK builds facts for, and which of them take hints.
|
|
11
23
|
* A dictation takes none: its answer is the whole sentence, and it has
|
|
12
24
|
* word-by-word hints of its own.
|
|
13
25
|
*/
|
|
14
|
-
declare const AI_EXPLANATION_TYPES: readonly AiSupportedActivityType[];
|
|
15
|
-
declare const AI_HINT_TYPES: readonly AiSupportedActivityType[];
|
|
26
|
+
export declare const AI_EXPLANATION_TYPES: readonly AiSupportedActivityType[];
|
|
27
|
+
export declare const AI_HINT_TYPES: readonly AiSupportedActivityType[];
|
|
16
28
|
/** The longest AI text shown, in code points. Longer is refused, not cut. */
|
|
17
|
-
declare const AI_TEXT_MAX_LENGTH = 2000;
|
|
29
|
+
export declare const AI_TEXT_MAX_LENGTH = 2000;
|
|
18
30
|
/**
|
|
19
31
|
* Whether the SDK supports `feature` for this activity type: explanations and
|
|
20
32
|
* hints for the types it builds facts for, and writing feedback for a written
|
|
21
33
|
* response, and coaching for a read-aloud. A consumer's own type has none.
|
|
22
34
|
*/
|
|
23
|
-
declare function aiSupports(activityType: string, feature: AiFeature): boolean;
|
|
35
|
+
export declare function aiSupports(activityType: string, feature: AiFeature): boolean;
|
|
24
36
|
/**
|
|
25
37
|
* Whether the item's author allows `feature`. Only an explicit `false`
|
|
26
38
|
* switches it off: an author can refuse a feature, never force one on.
|
|
@@ -29,12 +41,12 @@ declare function aiSupports(activityType: string, feature: AiFeature): boolean;
|
|
|
29
41
|
* model's words about the learner's own answer, and an author who switched one
|
|
30
42
|
* off has switched off the others.
|
|
31
43
|
*/
|
|
32
|
-
declare function aiAllowedByContent(data: AiActivityInput, feature: AiFeature): boolean;
|
|
44
|
+
export declare function aiAllowedByContent(data: AiActivityInput, feature: AiFeature): boolean;
|
|
33
45
|
/** A grade as an explanation must speak to it: all marks, some, or none. */
|
|
34
|
-
declare function aiGradeOf(result: {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
export declare function aiGradeOf(result: {
|
|
47
|
+
score: number;
|
|
48
|
+
maxScore: number;
|
|
49
|
+
passed: boolean;
|
|
38
50
|
}): AiGrade;
|
|
39
51
|
/**
|
|
40
52
|
* The facts a model is given about one item and one answer. `details` are the
|
|
@@ -45,7 +57,7 @@ declare function aiGradeOf(result: {
|
|
|
45
57
|
*
|
|
46
58
|
* `null` for a type the SDK builds no facts for.
|
|
47
59
|
*/
|
|
48
|
-
declare function buildAiFacts(data: AiActivityInput, response: LearnerResponse | null, details: readonly ScoringDetail[] | null): AiItemFacts | null;
|
|
60
|
+
export declare function buildAiFacts(data: AiActivityInput, response: LearnerResponse | null, details: readonly ScoringDetail[] | null): AiItemFacts | null;
|
|
49
61
|
/**
|
|
50
62
|
* The request for an explanation of `response`, or `null` when there is none
|
|
51
63
|
* to give: an unsupported type, an author who switched explanations off,
|
|
@@ -57,12 +69,17 @@ declare function buildAiFacts(data: AiActivityInput, response: LearnerResponse |
|
|
|
57
69
|
* positive and finite, `score` finite from 0 to it) gets no explanation at all:
|
|
58
70
|
* explaining 85 "out of 1" would tell the model a wrong answer was correct, and
|
|
59
71
|
* grading locally instead would speak to a grade the screen does not show.
|
|
72
|
+
*
|
|
73
|
+
* `group` is the item group the question sits in: its material — the passage,
|
|
74
|
+
* or the instructions the group's questions share — goes with the request as
|
|
75
|
+
* `material`, as the learner sees it.
|
|
60
76
|
*/
|
|
61
|
-
declare function aiExplanationRequest(input: {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
77
|
+
export declare function aiExplanationRequest(input: {
|
|
78
|
+
data: AiActivityInput;
|
|
79
|
+
response: LearnerResponse | null;
|
|
80
|
+
outcome?: ItemOutcome;
|
|
81
|
+
group?: AiGroupInput;
|
|
82
|
+
learnerLocale?: string;
|
|
66
83
|
}): AiExplanationRequest | null;
|
|
67
84
|
/**
|
|
68
85
|
* The request for the next hint on an unsubmitted answer, or `null` when
|
|
@@ -71,25 +88,30 @@ declare function aiExplanationRequest(input: {
|
|
|
71
88
|
*
|
|
72
89
|
* The facts carry the key, and which parts the learner has right so far, so a
|
|
73
90
|
* model can hint where it helps. The learner never sees them; a hint that
|
|
74
|
-
* contains an answer is refused by {@link checkAiHint}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
* contains an answer is refused by {@link checkAiHint}, whatever it quotes —
|
|
92
|
+
* the group's material included.
|
|
93
|
+
*
|
|
94
|
+
* `group` is the item group the question sits in, as for
|
|
95
|
+
* {@link aiExplanationRequest}.
|
|
96
|
+
*/
|
|
97
|
+
export declare function aiHintRequest(input: {
|
|
98
|
+
data: AiActivityInput;
|
|
99
|
+
response: LearnerResponse | null;
|
|
100
|
+
previousHints: readonly string[];
|
|
101
|
+
group?: AiGroupInput;
|
|
102
|
+
learnerLocale?: string;
|
|
81
103
|
}): AiHintRequest | null;
|
|
82
104
|
/**
|
|
83
105
|
* Reads what a port returned. Anything but an object with a string `text` is
|
|
84
106
|
* `malformed`; text that is empty once cleaned, or longer than
|
|
85
107
|
* {@link AI_TEXT_MAX_LENGTH}, is refused rather than shown or cut.
|
|
86
108
|
*/
|
|
87
|
-
declare function readAiTextResult(raw: unknown): {
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
export declare function readAiTextResult(raw: unknown): {
|
|
110
|
+
ok: true;
|
|
111
|
+
result: AiTextResult;
|
|
90
112
|
} | {
|
|
91
|
-
|
|
92
|
-
|
|
113
|
+
ok: false;
|
|
114
|
+
refusal: AiRefusal;
|
|
93
115
|
};
|
|
94
116
|
/**
|
|
95
117
|
* Checks an explanation a port returned for `request`. On top of
|
|
@@ -97,24 +119,24 @@ declare function readAiTextResult(raw: unknown): {
|
|
|
97
119
|
* the SDK's grade is refused (`contradicts-grade`) — it explains an answer
|
|
98
120
|
* the learner did not get.
|
|
99
121
|
*/
|
|
100
|
-
declare function checkAiExplanation(raw: unknown, request: AiExplanationRequest): {
|
|
101
|
-
|
|
102
|
-
|
|
122
|
+
export declare function checkAiExplanation(raw: unknown, request: AiExplanationRequest): {
|
|
123
|
+
ok: true;
|
|
124
|
+
result: AiTextResult;
|
|
103
125
|
} | {
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
ok: false;
|
|
127
|
+
refusal: AiRefusal;
|
|
106
128
|
};
|
|
107
129
|
/**
|
|
108
130
|
* Checks a hint a port returned for `request`. On top of
|
|
109
131
|
* {@link readAiTextResult}: a hint that contains an answer is refused
|
|
110
132
|
* (`reveals-answer`) — see {@link hintRevealsAnswer}.
|
|
111
133
|
*/
|
|
112
|
-
declare function checkAiHint(raw: unknown, request: AiHintRequest): {
|
|
113
|
-
|
|
114
|
-
|
|
134
|
+
export declare function checkAiHint(raw: unknown, request: AiHintRequest): {
|
|
135
|
+
ok: true;
|
|
136
|
+
result: AiTextResult;
|
|
115
137
|
} | {
|
|
116
|
-
|
|
117
|
-
|
|
138
|
+
ok: false;
|
|
139
|
+
refusal: AiRefusal;
|
|
118
140
|
};
|
|
119
141
|
/**
|
|
120
142
|
* Whether a hint gives away an answer, judged against the facts it was asked
|
|
@@ -126,15 +148,18 @@ declare function checkAiHint(raw: unknown, request: AiHintRequest): {
|
|
|
126
148
|
* An answer of one short word ("is", "the") counts only where the hint
|
|
127
149
|
* writes it beside a neighbour it has in the passage — "name is", "is
|
|
128
150
|
* Rossi" — so a hint may still use the word on its own.
|
|
151
|
+
* - **Facts of any other kind:** revealing. A hint the check cannot read is
|
|
152
|
+
* withheld, not shown unchecked.
|
|
129
153
|
*
|
|
130
154
|
* Case, accents and punctuation are ignored on both sides.
|
|
131
155
|
*/
|
|
132
|
-
declare function hintRevealsAnswer(facts: AiItemFacts, hint: string): boolean;
|
|
133
|
-
|
|
156
|
+
export declare function hintRevealsAnswer(facts: AiItemFacts, hint: string): boolean;
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/ai-coaching.d.ts
|
|
134
159
|
/** The most words one coaching may work on. More is refused, not cut. */
|
|
135
|
-
declare const AI_COACHING_MAX_WORDS = 20;
|
|
160
|
+
export declare const AI_COACHING_MAX_WORDS = 20;
|
|
136
161
|
/** The longest tip for one word, in code points. */
|
|
137
|
-
declare const AI_COACHING_MAX_TIP_LENGTH = 500;
|
|
162
|
+
export declare const AI_COACHING_MAX_TIP_LENGTH = 500;
|
|
138
163
|
/**
|
|
139
164
|
* The request for coaching on a graded reading, or `null` when there is none
|
|
140
165
|
* to give: not a read-aloud, an author who switched explanations off (coaching
|
|
@@ -151,11 +176,11 @@ declare const AI_COACHING_MAX_TIP_LENGTH = 500;
|
|
|
151
176
|
* the engine's dimension scores. The marks are the engine's; the model
|
|
152
177
|
* explains them.
|
|
153
178
|
*/
|
|
154
|
-
declare function aiCoachingRequest(input: {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
179
|
+
export declare function aiCoachingRequest(input: {
|
|
180
|
+
data: AiActivityInput;
|
|
181
|
+
assessment?: SpeechAssessment | null;
|
|
182
|
+
grade?: GradeRecord | null;
|
|
183
|
+
learnerLocale?: string;
|
|
159
184
|
}): AiCoachingRequest | null;
|
|
160
185
|
/**
|
|
161
186
|
* Checks coaching a port returned for `request`, and turns it into what a
|
|
@@ -180,18 +205,19 @@ declare function aiCoachingRequest(input: {
|
|
|
180
205
|
* (the SDK's reading of the text, never the model's), and each sound spelt as
|
|
181
206
|
* the engine spelt it.
|
|
182
207
|
*/
|
|
183
|
-
declare function checkAiCoaching(raw: unknown, request: AiCoachingRequest): {
|
|
184
|
-
|
|
185
|
-
|
|
208
|
+
export declare function checkAiCoaching(raw: unknown, request: AiCoachingRequest): {
|
|
209
|
+
ok: true;
|
|
210
|
+
coaching: AiCoaching;
|
|
186
211
|
} | {
|
|
187
|
-
|
|
188
|
-
|
|
212
|
+
ok: false;
|
|
213
|
+
refusal: AiRefusal;
|
|
189
214
|
};
|
|
190
|
-
|
|
215
|
+
//#endregion
|
|
216
|
+
//#region src/ai-critique.d.ts
|
|
191
217
|
/** The most findings one critique may carry. More is refused, not cut. */
|
|
192
|
-
declare const AI_CRITIQUE_MAX_FINDINGS = 20;
|
|
218
|
+
export declare const AI_CRITIQUE_MAX_FINDINGS = 20;
|
|
193
219
|
/** The longest message or quote in a finding, in code points. */
|
|
194
|
-
declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
|
|
220
|
+
export declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
|
|
195
221
|
/**
|
|
196
222
|
* What a model is given to review an item, or `null` when there is nothing to
|
|
197
223
|
* review: a draft that is not an object, or one with no words in it yet.
|
|
@@ -207,11 +233,11 @@ declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
|
|
|
207
233
|
*
|
|
208
234
|
* @throws UnknownActivityTypeError when `type` has no registered descriptor.
|
|
209
235
|
*/
|
|
210
|
-
declare function aiCritiqueRequest(input: {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
236
|
+
export declare function aiCritiqueRequest(input: {
|
|
237
|
+
type: ActivityType;
|
|
238
|
+
draft: unknown;
|
|
239
|
+
level?: string;
|
|
240
|
+
authorLocale?: string;
|
|
215
241
|
}): AiCritiqueRequest | null;
|
|
216
242
|
/**
|
|
217
243
|
* Checks a critique a port returned for `request`, and turns it into findings
|
|
@@ -230,18 +256,19 @@ declare function aiCritiqueRequest(input: {
|
|
|
230
256
|
* {@link AI_CRITIQUE_MAX_FIELD_LENGTH} code points; over them `too-long`. A
|
|
231
257
|
* kind the SDK does not name, or any other shape, is `malformed`.
|
|
232
258
|
*/
|
|
233
|
-
declare function checkAiCritique(raw: unknown, request: AiCritiqueRequest): {
|
|
234
|
-
|
|
235
|
-
|
|
259
|
+
export declare function checkAiCritique(raw: unknown, request: AiCritiqueRequest): {
|
|
260
|
+
ok: true;
|
|
261
|
+
critique: AiCritique;
|
|
236
262
|
} | {
|
|
237
|
-
|
|
238
|
-
|
|
263
|
+
ok: false;
|
|
264
|
+
refusal: AiRefusal;
|
|
239
265
|
};
|
|
240
|
-
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/ai-drafts.d.ts
|
|
241
268
|
/** The most drafts one request may ask for, and the most a reply may hold when it names no count. */
|
|
242
|
-
declare const AI_DRAFTS_MAX_COUNT = 50;
|
|
269
|
+
export declare const AI_DRAFTS_MAX_COUNT = 50;
|
|
243
270
|
/** The most repair passes `generateDrafts` makes. */
|
|
244
|
-
declare const AI_DRAFTS_MAX_REPAIRS = 3;
|
|
271
|
+
export declare const AI_DRAFTS_MAX_REPAIRS = 3;
|
|
245
272
|
/**
|
|
246
273
|
* What a model is given to draft items from a source, or `null` when there is
|
|
247
274
|
* no source to draft from: an empty text, or no caption with words in it.
|
|
@@ -264,14 +291,14 @@ declare const AI_DRAFTS_MAX_REPAIRS = 3;
|
|
|
264
291
|
* does not draft, or `count` is not a whole number from 1 to
|
|
265
292
|
* {@link AI_DRAFTS_MAX_COUNT}.
|
|
266
293
|
*/
|
|
267
|
-
declare function aiDraftsRequest(input: {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
294
|
+
export declare function aiDraftsRequest(input: {
|
|
295
|
+
types: readonly AiDraftType[];
|
|
296
|
+
source: AiDraftSource;
|
|
297
|
+
count?: number;
|
|
298
|
+
locale?: string;
|
|
299
|
+
level?: string;
|
|
300
|
+
instructions?: string;
|
|
301
|
+
settings?: AiDraftSettings;
|
|
275
302
|
}): AiDraftsRequest | null;
|
|
276
303
|
/**
|
|
277
304
|
* Reads a model's reply to {@link aiDraftsRequest} into drafts an editor can
|
|
@@ -296,14 +323,14 @@ declare function aiDraftsRequest(input: {
|
|
|
296
323
|
*
|
|
297
324
|
* @throws Error when `newId` returns an empty or repeated id.
|
|
298
325
|
*/
|
|
299
|
-
declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options: {
|
|
300
|
-
|
|
326
|
+
export declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options: {
|
|
327
|
+
newId: () => string;
|
|
301
328
|
}): {
|
|
302
|
-
|
|
303
|
-
|
|
329
|
+
ok: true;
|
|
330
|
+
drafts: AiDrafts;
|
|
304
331
|
} | {
|
|
305
|
-
|
|
306
|
-
|
|
332
|
+
ok: false;
|
|
333
|
+
refusal: AiRefusal;
|
|
307
334
|
};
|
|
308
335
|
/**
|
|
309
336
|
* A second request, for the drafts with something wrong the model can fix —
|
|
@@ -314,7 +341,7 @@ declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options:
|
|
|
314
341
|
* The reply holds one draft for each, in order; {@link checkAiDrafts} reads it
|
|
315
342
|
* and gives each the `index` of the draft it replaces.
|
|
316
343
|
*/
|
|
317
|
-
declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDrafts | readonly AiGeneratedDraft[]): AiDraftsRequest | null;
|
|
344
|
+
export declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDrafts | readonly AiGeneratedDraft[]): AiDraftsRequest | null;
|
|
318
345
|
/**
|
|
319
346
|
* Drafts items from a source, with a bounded repair loop: asks the port with
|
|
320
347
|
* `request`, reads the reply with {@link checkAiDrafts}, then — up to `repairs`
|
|
@@ -340,11 +367,11 @@ declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDraft
|
|
|
340
367
|
* {@link AI_DRAFTS_MAX_REPAIRS} (default 1), and Error when `newId` returns an
|
|
341
368
|
* empty or repeated id.
|
|
342
369
|
*/
|
|
343
|
-
declare function generateDrafts(input: {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
370
|
+
export declare function generateDrafts(input: {
|
|
371
|
+
request: AiDraftsRequest;
|
|
372
|
+
port: (request: AiDraftsRequest) => Promise<unknown> | unknown;
|
|
373
|
+
newId: () => string;
|
|
374
|
+
repairs?: number;
|
|
348
375
|
}): Promise<AiDraftsRun>;
|
|
349
376
|
/**
|
|
350
377
|
* An interactive video made of drafts: an item group whose stimulus is
|
|
@@ -365,19 +392,20 @@ declare function generateDrafts(input: {
|
|
|
365
392
|
*
|
|
366
393
|
* @throws Error when `newId` returns an empty or repeated id.
|
|
367
394
|
*/
|
|
368
|
-
declare function interactiveVideoFromDrafts(input: {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
395
|
+
export declare function interactiveVideoFromDrafts(input: {
|
|
396
|
+
request: AiDraftsRequest;
|
|
397
|
+
drafts: AiDrafts | AiDraftsRun | readonly AiGeneratedDraft[];
|
|
398
|
+
video: ActivityMedia;
|
|
399
|
+
durationSeconds?: number;
|
|
400
|
+
title?: string;
|
|
401
|
+
newId: () => string;
|
|
375
402
|
}): AiVideoDraft;
|
|
376
|
-
|
|
403
|
+
//#endregion
|
|
404
|
+
//#region src/ai-writing.d.ts
|
|
377
405
|
/** The most corrections one piece of writing feedback may carry. More is refused, not cut. */
|
|
378
|
-
declare const AI_WRITING_MAX_CORRECTIONS = 20;
|
|
406
|
+
export declare const AI_WRITING_MAX_CORRECTIONS = 20;
|
|
379
407
|
/** The longest quote, correction, explanation or criterion comment, in code points. */
|
|
380
|
-
declare const AI_WRITING_MAX_FIELD_LENGTH = 500;
|
|
408
|
+
export declare const AI_WRITING_MAX_FIELD_LENGTH = 500;
|
|
381
409
|
/**
|
|
382
410
|
* The request for feedback on a draft, or `null` when there is none to give:
|
|
383
411
|
* not a written response, an author who switched explanations off (writing
|
|
@@ -387,13 +415,16 @@ declare const AI_WRITING_MAX_FIELD_LENGTH = 500;
|
|
|
387
415
|
* The facts are the task as the learner saw it, the draft verbatim with its
|
|
388
416
|
* word count recomputed as the grader will count it, and the rubric the answer
|
|
389
417
|
* will be graded on. `previousFeedback` is the text of the feedback already
|
|
390
|
-
* shown on earlier drafts, so a model can speak to what changed.
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
418
|
+
* shown on earlier drafts, so a model can speak to what changed. `group` is the
|
|
419
|
+
* item group the task sits in: its material, the text a summary is of, goes
|
|
420
|
+
* with the request as `material`.
|
|
421
|
+
*/
|
|
422
|
+
export declare function aiWritingFeedbackRequest(input: {
|
|
423
|
+
data: AiActivityInput;
|
|
424
|
+
response: LearnerResponse | null;
|
|
425
|
+
previousFeedback?: readonly string[];
|
|
426
|
+
group?: AiGroupInput;
|
|
427
|
+
learnerLocale?: string;
|
|
397
428
|
}): AiWritingFeedbackRequest | null;
|
|
398
429
|
/**
|
|
399
430
|
* Checks writing feedback a port returned for `request`, and turns it into what
|
|
@@ -419,14 +450,15 @@ declare function aiWritingFeedbackRequest(input: {
|
|
|
419
450
|
* `gradeFromRubric` computes a grade, when every criterion of the rubric was
|
|
420
451
|
* judged; `null` otherwise. An indication, never a grade.
|
|
421
452
|
*/
|
|
422
|
-
declare function checkAiWritingFeedback(raw: unknown, request: AiWritingFeedbackRequest): {
|
|
423
|
-
|
|
424
|
-
|
|
453
|
+
export declare function checkAiWritingFeedback(raw: unknown, request: AiWritingFeedbackRequest): {
|
|
454
|
+
ok: true;
|
|
455
|
+
feedback: AiWritingFeedback;
|
|
425
456
|
} | {
|
|
426
|
-
|
|
427
|
-
|
|
457
|
+
ok: false;
|
|
458
|
+
refusal: AiRefusal;
|
|
428
459
|
};
|
|
429
|
-
|
|
460
|
+
//#endregion
|
|
461
|
+
//#region src/types/delivery.d.ts
|
|
430
462
|
/**
|
|
431
463
|
* How a paper is delivered: what a learner is shown around the questions, as
|
|
432
464
|
* the school running it decides — separately from the content, so that one
|
|
@@ -439,45 +471,45 @@ declare function checkAiWritingFeedback(raw: unknown, request: AiWritingFeedback
|
|
|
439
471
|
* because the client in an exam has no answer key to grade with.
|
|
440
472
|
*/
|
|
441
473
|
interface DeliveryPolicy {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
474
|
+
/**
|
|
475
|
+
* Whether a graded answer shows as graded: right and wrong marks, the score,
|
|
476
|
+
* and the author's feedback. `false` leaves the learner with "Answer
|
|
477
|
+
* submitted." — a homework quiz marked on the client and shown to the
|
|
478
|
+
* learner at the end, or a review that shows what was answered and not how
|
|
479
|
+
* it was marked. Never on in `exam`.
|
|
480
|
+
*/
|
|
481
|
+
feedback?: boolean | null;
|
|
482
|
+
/**
|
|
483
|
+
* Whether the right answer is shown beside a wrong one, wherever an activity
|
|
484
|
+
* would show it: the correct option of a multiple-choice question, the
|
|
485
|
+
* correct answers `showCorrectAnswers` puts in the blanks, a dictation's
|
|
486
|
+
* transcript. `false` still marks what the learner answered right or wrong.
|
|
487
|
+
* Use it on a paper that will be sat again, or before a retry.
|
|
488
|
+
*/
|
|
489
|
+
solutions?: boolean | null;
|
|
490
|
+
/**
|
|
491
|
+
* Whether the learner can ask for hints: the author's hints on a
|
|
492
|
+
* fill-in-the-blanks blank, a dictation's word hints, and AI hints. `false`
|
|
493
|
+
* switches every kind off.
|
|
494
|
+
*
|
|
495
|
+
* **The author's fill-in-the-blanks hints are on in `exam` unless this says
|
|
496
|
+
* otherwise** — they are public content, and were designed to be. Set
|
|
497
|
+
* `hints: false` on a paper of record whose hints are not part of the test.
|
|
498
|
+
*/
|
|
499
|
+
hints?: boolean | null;
|
|
500
|
+
/**
|
|
501
|
+
* The deployment's switches for AI help, beside the author's switch on the
|
|
502
|
+
* item and the ports the host supplies: a feature appears only where all
|
|
503
|
+
* three allow it. `false` switches a feature off; nothing here can switch one
|
|
504
|
+
* on, and nothing switches AI help on in an `exam`.
|
|
505
|
+
*
|
|
506
|
+
* `ai: false` switches both off and `ai: true` leaves both as the other
|
|
507
|
+
* settings allow — the same as leaving `ai` out.
|
|
508
|
+
*/
|
|
509
|
+
ai?: boolean | {
|
|
467
510
|
hints?: boolean | null;
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
* item and the ports the host supplies: a feature appears only where all
|
|
471
|
-
* three allow it. `false` switches a feature off; nothing here can switch one
|
|
472
|
-
* on, and nothing switches AI help on in an `exam`.
|
|
473
|
-
*
|
|
474
|
-
* `ai: false` switches both off and `ai: true` leaves both as the other
|
|
475
|
-
* settings allow — the same as leaving `ai` out.
|
|
476
|
-
*/
|
|
477
|
-
ai?: boolean | {
|
|
478
|
-
hints?: boolean | null;
|
|
479
|
-
explanations?: boolean | null;
|
|
480
|
-
} | null;
|
|
511
|
+
explanations?: boolean | null;
|
|
512
|
+
} | null;
|
|
481
513
|
}
|
|
482
514
|
/**
|
|
483
515
|
* A policy with every setting spelled out: what {@link resolveDeliveryPolicy}
|
|
@@ -486,231 +518,220 @@ interface DeliveryPolicy {
|
|
|
486
518
|
* change.
|
|
487
519
|
*/
|
|
488
520
|
interface ResolvedDeliveryPolicy {
|
|
489
|
-
|
|
490
|
-
|
|
521
|
+
feedback: boolean;
|
|
522
|
+
solutions: boolean;
|
|
523
|
+
hints: boolean;
|
|
524
|
+
ai: {
|
|
491
525
|
hints: boolean;
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
explanations: boolean;
|
|
495
|
-
};
|
|
526
|
+
explanations: boolean;
|
|
527
|
+
};
|
|
496
528
|
}
|
|
497
529
|
/** One thing {@link validateDeliveryPolicy} found wrong with a policy. */
|
|
498
530
|
interface DeliveryPolicyIssue {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
531
|
+
/** Where, as a dotted path: `hints`, `ai.explanations`, or `''` for the policy itself. */
|
|
532
|
+
path: string;
|
|
533
|
+
message: string;
|
|
502
534
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
* The frozen record of what one attempt was served.
|
|
506
|
-
*
|
|
507
|
-
* A sequence definition is live content: it gets edited, re-ordered, corrected.
|
|
508
|
-
* An attempt is a historical fact. Everything that decides a grade — which
|
|
509
|
-
* questions, in what order, each worth how much, against which version of the
|
|
510
|
-
* content — has to be pinned at the moment the attempt starts, or a re-grade
|
|
511
|
-
* six months later silently answers a different question than the learner was
|
|
512
|
-
* asked.
|
|
513
|
-
*
|
|
514
|
-
* This is the thing you persist next to the responses.
|
|
515
|
-
*/
|
|
516
|
-
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region src/types/attempt-plan.d.ts
|
|
517
537
|
/** One planned position: an item, its identity, its worth, and its fingerprint. */
|
|
518
538
|
interface AttemptPlanSlot {
|
|
539
|
+
/**
|
|
540
|
+
* Slot identity, from `flattenSequence`. Stable under shuffling; stable
|
|
541
|
+
* under editing too when the entries declare `slotKey`. This is the key to
|
|
542
|
+
* store responses and scores against.
|
|
543
|
+
*/
|
|
544
|
+
slotId: string;
|
|
545
|
+
/** 0-based PRESENTED position in this attempt. */
|
|
546
|
+
index: number;
|
|
547
|
+
/** The activity that filled the slot. */
|
|
548
|
+
activityId: string;
|
|
549
|
+
/** The activity's `type` discriminator. */
|
|
550
|
+
activityType: string;
|
|
551
|
+
/**
|
|
552
|
+
* What this slot is worth, frozen. Points belong to the PAPER, not the item:
|
|
553
|
+
* the same question can be worth 1 in a quiz and 3 in a final, so they are
|
|
554
|
+
* resolved when the attempt is planned and never read from content again.
|
|
555
|
+
*/
|
|
556
|
+
points: number;
|
|
557
|
+
/**
|
|
558
|
+
* Fingerprint of the activity's content as served. Compare it later with
|
|
559
|
+
* {@link verifyAttemptPlan} to find out whether the item has been edited
|
|
560
|
+
* since — the difference between "re-grading this attempt" and "grading a
|
|
561
|
+
* different exam".
|
|
562
|
+
*/
|
|
563
|
+
contentHash: string;
|
|
564
|
+
/** Present when the slot came from an item group. */
|
|
565
|
+
group?: {
|
|
566
|
+
id: string;
|
|
567
|
+
title?: string;
|
|
568
|
+
/** Fingerprint of the stimulus as served — a corrected passage changes the question. */
|
|
569
|
+
stimulusHash: string;
|
|
519
570
|
/**
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
|
|
524
|
-
slotId: string;
|
|
525
|
-
/** 0-based PRESENTED position in this attempt. */
|
|
526
|
-
index: number;
|
|
527
|
-
/** The activity that filled the slot. */
|
|
528
|
-
activityId: string;
|
|
529
|
-
/** The activity's `type` discriminator. */
|
|
530
|
-
activityType: string;
|
|
531
|
-
/**
|
|
532
|
-
* What this slot is worth, frozen. Points belong to the PAPER, not the item:
|
|
533
|
-
* the same question can be worth 1 in a quiz and 3 in a final, so they are
|
|
534
|
-
* resolved when the attempt is planned and never read from content again.
|
|
535
|
-
*/
|
|
536
|
-
points: number;
|
|
537
|
-
/**
|
|
538
|
-
* Fingerprint of the activity's content as served. Compare it later with
|
|
539
|
-
* {@link verifyAttemptPlan} to find out whether the item has been edited
|
|
540
|
-
* since — the difference between "re-grading this attempt" and "grading a
|
|
541
|
-
* different exam".
|
|
571
|
+
* The quiz this slot's question sat in, when the group is an interactive
|
|
572
|
+
* video. Frozen because WHEN a question is asked is part of what is asked:
|
|
573
|
+
* moved from before the passage it is about to after it, the same item is
|
|
574
|
+
* a different question.
|
|
542
575
|
*/
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
title?: string;
|
|
548
|
-
/** Fingerprint of the stimulus as served — a corrected passage changes the question. */
|
|
549
|
-
stimulusHash: string;
|
|
550
|
-
/**
|
|
551
|
-
* The quiz this slot's question sat in, when the group is an interactive
|
|
552
|
-
* video. Frozen because WHEN a question is asked is part of what is asked:
|
|
553
|
-
* moved from before the passage it is about to after it, the same item is
|
|
554
|
-
* a different question.
|
|
555
|
-
*/
|
|
556
|
-
cue?: {
|
|
557
|
-
id: string;
|
|
558
|
-
at: number;
|
|
559
|
-
required?: boolean;
|
|
560
|
-
};
|
|
576
|
+
cue?: {
|
|
577
|
+
id: string;
|
|
578
|
+
at: number;
|
|
579
|
+
required?: boolean;
|
|
561
580
|
};
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
581
|
+
};
|
|
582
|
+
/**
|
|
583
|
+
* Play budgets in force for this slot when the attempt was planned.
|
|
584
|
+
*
|
|
585
|
+
* Frozen for the same reason `points` is: a budget decides the grade, so an
|
|
586
|
+
* author who edits `maxPlays: 2 → 4` mid-window must not be able to change
|
|
587
|
+
* what a past learner was held to. A group's stimulus budget repeats on every
|
|
588
|
+
* slot of the group, exactly as `group.stimulusHash` already does.
|
|
589
|
+
*
|
|
590
|
+
* Absent when the slot budgets nothing, which keeps the plan — and therefore
|
|
591
|
+
* `planHash` — byte-identical for every paper written before 0.8.0.
|
|
592
|
+
*/
|
|
593
|
+
mediaBudgets?: MediaBudgetRef[];
|
|
574
594
|
}
|
|
575
595
|
/** A budgeted recording a slot presents, frozen as served. */
|
|
576
596
|
interface MediaBudgetRef {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
597
|
+
/** `slot:<slotId>` or `stimulus:<entryKey>`. */
|
|
598
|
+
key: string;
|
|
599
|
+
/** The `maxPlays` in force when the attempt was planned. */
|
|
600
|
+
maxPlays: number;
|
|
581
601
|
}
|
|
582
602
|
/** Everything needed to reproduce and re-grade one attempt. */
|
|
583
603
|
interface AttemptPlan {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
604
|
+
/** Version of this envelope, so a stored plan stays readable as it evolves. */
|
|
605
|
+
planVersion: '1.0';
|
|
606
|
+
/**
|
|
607
|
+
* The seed every shuffle in this attempt used, when anything shuffled.
|
|
608
|
+
* Absent means nothing was shuffled and the order is the authored one.
|
|
609
|
+
*/
|
|
610
|
+
seed?: string;
|
|
611
|
+
/**
|
|
612
|
+
* Whether the top-level entries were shuffled. Recorded because
|
|
613
|
+
* {@link verifyAttemptPlan} needs to rebuild the SAME presented order: a
|
|
614
|
+
* re-plan that omitted this returned authored order, every slot compared as
|
|
615
|
+
* re-ordered, and unchanged content reported as drift.
|
|
616
|
+
*/
|
|
617
|
+
shuffleEntries?: boolean;
|
|
618
|
+
/**
|
|
619
|
+
* Fingerprint of the whole plan's content — every slot's identity, order,
|
|
620
|
+
* points and content hash. One value to store against an attempt and compare
|
|
621
|
+
* later; the per-slot hashes then say WHICH item moved.
|
|
622
|
+
*/
|
|
623
|
+
planHash: string;
|
|
624
|
+
/**
|
|
625
|
+
* The delivery policy the attempt was sat under, every setting spelled out:
|
|
626
|
+
* whether feedback, solutions and hints showed, and which AI help was on.
|
|
627
|
+
* Absent when `planAttempt` was given none. Part of `planHash` when present.
|
|
628
|
+
*/
|
|
629
|
+
delivery?: ResolvedDeliveryPolicy;
|
|
630
|
+
/**
|
|
631
|
+
* The scoring policy the attempt was sat under, every setting spelled out:
|
|
632
|
+
* the tries each question gave, which counted, and what tries and hints
|
|
633
|
+
* cost. Absent when `planAttempt` was given none. Part of `planHash` when
|
|
634
|
+
* present.
|
|
635
|
+
*/
|
|
636
|
+
scoring?: ResolvedItemScoringPolicy;
|
|
637
|
+
slots: AttemptPlanSlot[];
|
|
638
|
+
/** Sum of every slot's `points`, frozen. The denominator of the paper. */
|
|
639
|
+
totalPoints: number;
|
|
620
640
|
}
|
|
621
641
|
/** What {@link verifyAttemptPlan} found when a plan met current content. */
|
|
622
642
|
interface AttemptPlanDrift {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
643
|
+
/** True when the plan and the content still agree in every respect. */
|
|
644
|
+
matches: boolean;
|
|
645
|
+
/** Slots in the plan that no longer exist in the content at all. */
|
|
646
|
+
missingSlotIds: string[];
|
|
647
|
+
/** Slots present now that the plan never held — content added since. */
|
|
648
|
+
addedSlotIds: string[];
|
|
649
|
+
/** Slots whose activity content has been edited since the attempt. */
|
|
650
|
+
changedSlotIds: string[];
|
|
651
|
+
/** Slots whose item group's stimulus has been edited since the attempt. */
|
|
652
|
+
changedStimulusSlotIds: string[];
|
|
653
|
+
/**
|
|
654
|
+
* Slots of an interactive video whose question now sits in a different quiz,
|
|
655
|
+
* at a different moment, or under a different `required` — or that gained or
|
|
656
|
+
* lost a quiz altogether. Always empty for content without a timeline.
|
|
657
|
+
*/
|
|
658
|
+
changedCueSlotIds: string[];
|
|
659
|
+
/**
|
|
660
|
+
* Slots now worth a different number of points. A reweight is a paper
|
|
661
|
+
* change — it moves the grade without touching a single question — so it
|
|
662
|
+
* cannot be left out of a remark or an appeal.
|
|
663
|
+
*/
|
|
664
|
+
changedPointsSlotIds: string[];
|
|
665
|
+
/** Slots presented at a different position now than they were then. */
|
|
666
|
+
reorderedSlotIds: string[];
|
|
667
|
+
/**
|
|
668
|
+
* The delivery policy differs: one plan records a policy the other does not,
|
|
669
|
+
* or a setting differs. Not a change to any question, but a change to the
|
|
670
|
+
* conditions it was asked under — hints on in one, off in the other — so it
|
|
671
|
+
* breaks `matches` like any other difference.
|
|
672
|
+
*
|
|
673
|
+
* Present only when it is `true`, so a report between two plans without a
|
|
674
|
+
* policy has exactly the shape it had before policies existed.
|
|
675
|
+
*/
|
|
676
|
+
deliveryChanged?: true;
|
|
677
|
+
/**
|
|
678
|
+
* The scoring policy differs: one plan records a policy the other does not,
|
|
679
|
+
* or a setting differs. The same answers are worth something else under
|
|
680
|
+
* another policy, so it breaks `matches`. Present only when it is `true`.
|
|
681
|
+
*/
|
|
682
|
+
scoringChanged?: true;
|
|
663
683
|
}
|
|
664
|
-
|
|
684
|
+
//#endregion
|
|
685
|
+
//#region src/attempt-plan.d.ts
|
|
665
686
|
/** Options for {@link planAttempt}. */
|
|
666
|
-
interface PlanAttemptOptions<TItem> {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
687
|
+
export interface PlanAttemptOptions<TItem> {
|
|
688
|
+
/** Shuffle the top-level entries. A group moves as one block. */
|
|
689
|
+
shuffleEntries?: boolean;
|
|
690
|
+
/**
|
|
691
|
+
* Seed for every shuffle in this attempt. Required whenever anything
|
|
692
|
+
* shuffles — the attempt has to be reproducible, which is the entire point
|
|
693
|
+
* of writing a plan down. Use the attempt id.
|
|
694
|
+
*/
|
|
695
|
+
seed?: string;
|
|
696
|
+
/**
|
|
697
|
+
* What each slot is worth. Defaults to 1 for every slot.
|
|
698
|
+
*
|
|
699
|
+
* Points are resolved HERE, not read from content, because they belong to
|
|
700
|
+
* the paper rather than the item: the same question is worth 1 in a practice
|
|
701
|
+
* quiz and 3 in a final. Whatever this returns is frozen into the plan and
|
|
702
|
+
* is what `composeAssessmentScore` will weight by.
|
|
703
|
+
*
|
|
704
|
+
* @throws Error when it returns a value that is not a finite, non-negative
|
|
705
|
+
* number — a slot worth `NaN` points would poison the whole total.
|
|
706
|
+
*/
|
|
707
|
+
points?: (slot: SequenceSlot<TItem>) => number;
|
|
708
|
+
/**
|
|
709
|
+
* The delivery policy this attempt is sat under — whether hints were
|
|
710
|
+
* offered, whether AI help was, whether feedback and solutions showed.
|
|
711
|
+
* Frozen into the plan with every setting spelled out, so the record of the
|
|
712
|
+
* conditions a grade was earned under does not depend on today's defaults.
|
|
713
|
+
*
|
|
714
|
+
* Recorded only when given: a plan made without one is byte-identical to a
|
|
715
|
+
* plan made before policies existed, `planHash` included.
|
|
716
|
+
*
|
|
717
|
+
* @throws Error when the policy does not pass `validateDeliveryPolicy` —
|
|
718
|
+
* a misspelled restriction is no restriction, and a plan is the
|
|
719
|
+
* record an appeal reads.
|
|
720
|
+
*/
|
|
721
|
+
delivery?: DeliveryPolicy | null;
|
|
722
|
+
/**
|
|
723
|
+
* The scoring policy this attempt is sat under — how many tries each
|
|
724
|
+
* question gives, which one counts, and what tries and hints cost. Frozen
|
|
725
|
+
* into the plan with every setting spelled out, like `delivery`, and for a
|
|
726
|
+
* stronger reason: every setting in it moves a grade, so a re-grade must
|
|
727
|
+
* apply the rules the learner sat under, not today's.
|
|
728
|
+
*
|
|
729
|
+
* Recorded only when given: a plan made without one is byte-identical to a
|
|
730
|
+
* plan made before scoring policies existed, `planHash` included.
|
|
731
|
+
*
|
|
732
|
+
* @throws Error when the policy does not pass `validateItemScoringPolicy`.
|
|
733
|
+
*/
|
|
734
|
+
scoring?: ItemScoringPolicy | null;
|
|
714
735
|
}
|
|
715
736
|
/**
|
|
716
737
|
* Freezes what an attempt is being served: the presented order, each slot's
|
|
@@ -728,9 +749,9 @@ interface PlanAttemptOptions<TItem> {
|
|
|
728
749
|
* empty, when two entries collide on a `slotKey`, or when `points`
|
|
729
750
|
* returns a value that is not finite and non-negative.
|
|
730
751
|
*/
|
|
731
|
-
declare function planAttempt<TItem extends {
|
|
732
|
-
|
|
733
|
-
|
|
752
|
+
export declare function planAttempt<TItem extends {
|
|
753
|
+
id: string;
|
|
754
|
+
type: string;
|
|
734
755
|
}>(entries: readonly SequenceEntry<TItem>[], options?: PlanAttemptOptions<TItem>): AttemptPlan;
|
|
735
756
|
/**
|
|
736
757
|
* Compares a stored plan with the content as it stands now, and reports every
|
|
@@ -756,23 +777,23 @@ declare function planAttempt<TItem extends {
|
|
|
756
777
|
* A drift is not automatically a problem — a fixed typo changes a hash without
|
|
757
778
|
* changing what was asked. It is a fact somebody has to be able to see.
|
|
758
779
|
*/
|
|
759
|
-
declare function verifyAttemptPlan(plan: AttemptPlan, current: AttemptPlan): AttemptPlanDrift;
|
|
780
|
+
export declare function verifyAttemptPlan(plan: AttemptPlan, current: AttemptPlan): AttemptPlanDrift;
|
|
760
781
|
/** How {@link scoredItemsFromPlan} fills a slot that has no recorded outcome. */
|
|
761
|
-
type MissingOutcomePolicy =
|
|
782
|
+
export type MissingOutcomePolicy =
|
|
762
783
|
/**
|
|
763
784
|
* Default. `{ status: 'deferred', reason: 'no_response_recorded' }` — a
|
|
764
785
|
* non-terminal state, so the composed result stays `provisional` and cannot
|
|
765
786
|
* be recorded as a final pass or fail.
|
|
766
787
|
*/
|
|
767
|
-
'deferred'
|
|
788
|
+
'deferred' |
|
|
768
789
|
/**
|
|
769
790
|
* `{ status: 'scored', score: 0 }` — the learner left it blank on a paper
|
|
770
791
|
* that IS complete. Choose this only when you know the attempt was
|
|
771
792
|
* submitted; it is a real zero and makes the result final.
|
|
772
793
|
*/
|
|
773
|
-
|
|
794
|
+
'zero' |
|
|
774
795
|
/** Build the outcome yourself, per slot. */
|
|
775
|
-
|
|
796
|
+
((slot: AttemptPlanSlot) => ItemOutcome);
|
|
776
797
|
/**
|
|
777
798
|
* Turns a plan plus whatever outcomes exist into the `ScoredItem[]`
|
|
778
799
|
* `composeAssessmentScore` consumes.
|
|
@@ -793,12 +814,13 @@ type MissingOutcomePolicy =
|
|
|
793
814
|
* Pass outcomes keyed by `slotId`. Keys the plan does not know are ignored:
|
|
794
815
|
* a plan is the authority on what the attempt contained.
|
|
795
816
|
*/
|
|
796
|
-
declare function scoredItemsFromPlan(plan: AttemptPlan, outcomes: Readonly<Record<string, ItemOutcome>>, options?: {
|
|
797
|
-
|
|
817
|
+
export declare function scoredItemsFromPlan(plan: AttemptPlan, outcomes: Readonly<Record<string, ItemOutcome>>, options?: {
|
|
818
|
+
missing?: MissingOutcomePolicy;
|
|
798
819
|
}): ScoredItem[];
|
|
799
820
|
/** Convenience alias: the entry type a plan is built from. */
|
|
800
|
-
type PlannableEntry = SequenceEntry<ActivityData>;
|
|
801
|
-
|
|
821
|
+
export type PlannableEntry = SequenceEntry<ActivityData>;
|
|
822
|
+
//#endregion
|
|
823
|
+
//#region src/types/attempt-state.d.ts
|
|
802
824
|
/**
|
|
803
825
|
* A resumable snapshot of an attempt in progress.
|
|
804
826
|
*
|
|
@@ -812,46 +834,47 @@ type PlannableEntry = SequenceEntry<ActivityData>;
|
|
|
812
834
|
* slot ids alone would happily line up against the wrong questions.
|
|
813
835
|
*/
|
|
814
836
|
interface AttemptState {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
837
|
+
/** Version of this envelope, so a stored snapshot stays readable as it evolves. */
|
|
838
|
+
stateVersion: '1.0';
|
|
839
|
+
/**
|
|
840
|
+
* `planHash` of the {@link AttemptPlan} this state belongs to. `restoreAttemptState`
|
|
841
|
+
* refuses a plan that does not match, rather than restoring a learner's
|
|
842
|
+
* answers onto a paper they never sat.
|
|
843
|
+
*/
|
|
844
|
+
planHash: string;
|
|
845
|
+
/** The learner's answers so far, keyed by `slotId`. */
|
|
846
|
+
responses: Record<string, LearnerResponse>;
|
|
847
|
+
/**
|
|
848
|
+
* Slots the learner has already submitted. Kept apart from `responses`
|
|
849
|
+
* because they answer different questions: what did they write, and may they
|
|
850
|
+
* still change it.
|
|
851
|
+
*/
|
|
852
|
+
submittedSlotIds: string[];
|
|
853
|
+
/** Presented position the learner was on, so a resume reopens there. */
|
|
854
|
+
index: number;
|
|
855
|
+
/** ISO 8601 timestamp of the snapshot, when the caller supplies one. */
|
|
856
|
+
savedAt?: string;
|
|
835
857
|
}
|
|
836
858
|
/** One slot whose response differs between two snapshots. */
|
|
837
859
|
interface ResponseDiffEntry {
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
860
|
+
slotId: string;
|
|
861
|
+
/** `added` — answered since; `removed` — cleared; `changed` — a different answer. */
|
|
862
|
+
change: 'added' | 'removed' | 'changed';
|
|
863
|
+
before?: LearnerResponse;
|
|
864
|
+
after?: LearnerResponse;
|
|
843
865
|
}
|
|
844
|
-
|
|
866
|
+
//#endregion
|
|
867
|
+
//#region src/attempt-state.d.ts
|
|
845
868
|
/** What {@link serializeAttemptState} is given about an attempt in progress. */
|
|
846
|
-
interface AttemptProgress {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
869
|
+
export interface AttemptProgress {
|
|
870
|
+
/** Answers so far, keyed by `slotId`. */
|
|
871
|
+
responses: Readonly<Record<string, LearnerResponse>>;
|
|
872
|
+
/** Slots already submitted. Defaults to none. */
|
|
873
|
+
submittedSlotIds?: readonly string[];
|
|
874
|
+
/** Presented position the learner is on. Defaults to 0. */
|
|
875
|
+
index?: number;
|
|
876
|
+
/** ISO 8601 timestamp to stamp the snapshot with. The SDK does not read a clock. */
|
|
877
|
+
savedAt?: string;
|
|
855
878
|
}
|
|
856
879
|
/**
|
|
857
880
|
* Captures an in-progress attempt as a storable snapshot, bound to its plan.
|
|
@@ -867,7 +890,7 @@ interface AttemptProgress {
|
|
|
867
890
|
* @throws Error when a response or submitted slot is not in the plan, or when
|
|
868
891
|
* `index` is not a position the plan actually has.
|
|
869
892
|
*/
|
|
870
|
-
declare function serializeAttemptState(plan: AttemptPlan, progress: AttemptProgress): AttemptState;
|
|
893
|
+
export declare function serializeAttemptState(plan: AttemptPlan, progress: AttemptProgress): AttemptState;
|
|
871
894
|
/**
|
|
872
895
|
* Reopens a stored snapshot against a plan, refusing anything that does not
|
|
873
896
|
* belong to it.
|
|
@@ -881,7 +904,7 @@ declare function serializeAttemptState(plan: AttemptPlan, progress: AttemptProgr
|
|
|
881
904
|
* @throws Error when the snapshot belongs to a different plan, or references
|
|
882
905
|
* slots the plan does not contain.
|
|
883
906
|
*/
|
|
884
|
-
declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): AttemptState;
|
|
907
|
+
export declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): AttemptState;
|
|
885
908
|
/**
|
|
886
909
|
* Reports how two snapshots' responses differ, slot by slot.
|
|
887
910
|
*
|
|
@@ -893,8 +916,9 @@ declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): At
|
|
|
893
916
|
* Entries come back sorted by `slotId`, so the output is stable regardless of
|
|
894
917
|
* the order the two objects happened to be written in.
|
|
895
918
|
*/
|
|
896
|
-
declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
|
|
897
|
-
|
|
919
|
+
export declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
|
|
920
|
+
//#endregion
|
|
921
|
+
//#region src/authoring/item-group.d.ts
|
|
898
922
|
/**
|
|
899
923
|
* A new, empty reading or listening testlet for an editor to start from.
|
|
900
924
|
*
|
|
@@ -906,7 +930,7 @@ declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: P
|
|
|
906
930
|
*
|
|
907
931
|
* @throws Error when `newId` returns an empty or repeated id.
|
|
908
932
|
*/
|
|
909
|
-
declare function createItemGroupDraft(context: DraftContext): ItemGroup;
|
|
933
|
+
export declare function createItemGroupDraft(context: DraftContext): ItemGroup;
|
|
910
934
|
/**
|
|
911
935
|
* A new, empty interactive video for an editor to start from: an item group
|
|
912
936
|
* whose stimulus is a video with no file yet, no questions, and a timeline with
|
|
@@ -919,7 +943,7 @@ declare function createItemGroupDraft(context: DraftContext): ItemGroup;
|
|
|
919
943
|
*
|
|
920
944
|
* @throws Error when `newId` returns an empty or repeated id.
|
|
921
945
|
*/
|
|
922
|
-
declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
|
|
946
|
+
export declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
|
|
923
947
|
/**
|
|
924
948
|
* Tells an unfinished testlet from a broken one — {@link validateDraft} for the
|
|
925
949
|
* container that holds several questions around one passage or recording.
|
|
@@ -954,7 +978,7 @@ declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
|
|
|
954
978
|
* An item of a type that is not registered, or without a `type`, is skipped:
|
|
955
979
|
* {@link validateItemGroupDraft} already reports it.
|
|
956
980
|
*/
|
|
957
|
-
declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
|
|
981
|
+
export declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
|
|
958
982
|
/**
|
|
959
983
|
* The item critic over a question set, as `<ActivitySequence>` takes one: each
|
|
960
984
|
* entry's findings under its index — an item group's under `N.items.M.…` — and,
|
|
@@ -962,9 +986,10 @@ declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
|
|
|
962
986
|
* {@link critiqueItemGroupDraft}). An entry of a type that is not registered is
|
|
963
987
|
* skipped.
|
|
964
988
|
*/
|
|
965
|
-
declare function critiqueDrafts(entries: readonly unknown[]): ItemFinding[];
|
|
966
|
-
declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<ItemGroup>;
|
|
967
|
-
|
|
989
|
+
export declare function critiqueDrafts(entries: readonly unknown[]): ItemFinding[];
|
|
990
|
+
export declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<ItemGroup>;
|
|
991
|
+
//#endregion
|
|
992
|
+
//#region src/authoring/index.d.ts
|
|
968
993
|
/**
|
|
969
994
|
* Tells a draft that is not finished from a draft that is wrong.
|
|
970
995
|
*
|
|
@@ -1002,7 +1027,7 @@ declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<I
|
|
|
1002
1027
|
* @throws UnknownActivityTypeError when `type` has no registered descriptor —
|
|
1003
1028
|
* including `'item-group'`, which is a container, not an activity type.
|
|
1004
1029
|
*/
|
|
1005
|
-
declare function validateDraft<T extends ActivityType>(type: T, draft: unknown): DraftValidationResult<ActivityDataMap[T]>;
|
|
1030
|
+
export declare function validateDraft<T extends ActivityType>(type: T, draft: unknown): DraftValidationResult<ActivityDataMap[T]>;
|
|
1006
1031
|
/**
|
|
1007
1032
|
* A new, empty draft of an activity type, for an editor to start from.
|
|
1008
1033
|
*
|
|
@@ -1020,7 +1045,7 @@ declare function validateDraft<T extends ActivityType>(type: T, draft: unknown):
|
|
|
1020
1045
|
* @throws Error when the type declares no `authoring.createDraft`, or when
|
|
1021
1046
|
* `newId` returns an empty or repeated id.
|
|
1022
1047
|
*/
|
|
1023
|
-
declare function createDraft<T extends ActivityType>(type: T, context: DraftContext): ActivityDataMap[T];
|
|
1048
|
+
export declare function createDraft<T extends ActivityType>(type: T, context: DraftContext): ActivityDataMap[T];
|
|
1024
1049
|
/**
|
|
1025
1050
|
* What an experienced item writer would point out on review: flaws a learner
|
|
1026
1051
|
* can exploit or trip over (`warning`) and item-writing guidelines the item
|
|
@@ -1043,8 +1068,29 @@ declare function createDraft<T extends ActivityType>(type: T, context: DraftCont
|
|
|
1043
1068
|
* @throws UnknownActivityTypeError when `type` has no registered descriptor —
|
|
1044
1069
|
* including `'item-group'`: use {@link critiqueItemGroupDraft}.
|
|
1045
1070
|
*/
|
|
1046
|
-
declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[];
|
|
1047
|
-
|
|
1071
|
+
export declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[];
|
|
1072
|
+
//#endregion
|
|
1073
|
+
//#region src/built-in-types.d.ts
|
|
1074
|
+
/**
|
|
1075
|
+
* The activity types the SDK ships, in one closed list.
|
|
1076
|
+
*
|
|
1077
|
+
* {@link ActivityType} is `keyof ActivityDataMap`, which a host widens by
|
|
1078
|
+
* module augmentation to name its own types, so it cannot say which types are
|
|
1079
|
+
* the SDK's. This list can: every table the SDK keeps per built-in type is
|
|
1080
|
+
* typed against it (`satisfies Record<BuiltInActivityType, …>`) or walks it, so
|
|
1081
|
+
* a type added here is a compile error, or a failing test, everywhere it has
|
|
1082
|
+
* not been handled yet.
|
|
1083
|
+
*
|
|
1084
|
+
* The SDK's own registry holds exactly these, in this order, before a host
|
|
1085
|
+
* registers anything.
|
|
1086
|
+
*/
|
|
1087
|
+
export declare const BUILT_IN_ACTIVITY_TYPES: readonly ["multiple-choice", "fill-in-the-blanks", "written-response", "gap-select", "dictation", "read-aloud"];
|
|
1088
|
+
/** One of {@link BUILT_IN_ACTIVITY_TYPES}: an activity type the SDK ships, not one a host registered. */
|
|
1089
|
+
type BuiltInActivityType = (typeof BUILT_IN_ACTIVITY_TYPES)[number];
|
|
1090
|
+
/** Whether `type` names an activity type the SDK ships. */
|
|
1091
|
+
export declare function isBuiltInActivityType(type: unknown): type is BuiltInActivityType;
|
|
1092
|
+
//#endregion
|
|
1093
|
+
//#region src/content-hash.d.ts
|
|
1048
1094
|
/**
|
|
1049
1095
|
* Content fingerprinting — "is this the same content the learner was served?"
|
|
1050
1096
|
*
|
|
@@ -1065,7 +1111,7 @@ declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[
|
|
|
1065
1111
|
* that disagreed would raise a false alarm every time a payload made a
|
|
1066
1112
|
* round-trip through a different serializer.
|
|
1067
1113
|
*/
|
|
1068
|
-
declare function canonicalJson(value: unknown, seen?: Set<object>): string;
|
|
1114
|
+
export declare function canonicalJson(value: unknown, seen?: Set<object>): string;
|
|
1069
1115
|
/**
|
|
1070
1116
|
* FNV-1a over the UTF-8 bytes of `input`, as 16 lowercase hex digits.
|
|
1071
1117
|
*
|
|
@@ -1076,28 +1122,30 @@ declare function canonicalJson(value: unknown, seen?: Set<object>): string;
|
|
|
1076
1122
|
* property, sign the plan with a key the content author does not hold; this
|
|
1077
1123
|
* exists to catch honest edits, which is what actually happens.
|
|
1078
1124
|
*/
|
|
1079
|
-
declare function fingerprint(input: string): string;
|
|
1125
|
+
export declare function fingerprint(input: string): string;
|
|
1080
1126
|
/**
|
|
1081
1127
|
* Fingerprints any JSON-serialisable value through {@link canonicalJson}, so
|
|
1082
1128
|
* the result depends on the content and not on how it was written.
|
|
1083
1129
|
*/
|
|
1084
|
-
declare function contentHash(value: unknown): string;
|
|
1085
|
-
|
|
1130
|
+
export declare function contentHash(value: unknown): string;
|
|
1131
|
+
//#endregion
|
|
1132
|
+
//#region src/count-words.d.ts
|
|
1086
1133
|
/**
|
|
1087
|
-
* Canonical word counter for written-response bounds
|
|
1134
|
+
* Canonical word counter for written-response bounds: tokens are
|
|
1088
1135
|
* maximal runs of non-whitespace (split on `\s+`), so hyphenated forms
|
|
1089
1136
|
* (`well-known`) count as one word. The empty / whitespace-only string counts
|
|
1090
1137
|
* 0. Consumers must use this helper rather than re-implementing the split so
|
|
1091
1138
|
* client previews, SDK scoring, and stored `wordCount` values always agree.
|
|
1092
1139
|
*/
|
|
1093
|
-
declare function countWords(text: string): number;
|
|
1094
|
-
|
|
1140
|
+
export declare function countWords(text: string): number;
|
|
1141
|
+
//#endregion
|
|
1142
|
+
//#region src/delivery.d.ts
|
|
1095
1143
|
/**
|
|
1096
1144
|
* The policy that restricts nothing: every setting `true`. It is what an absent
|
|
1097
1145
|
* policy resolves to, and it is exactly the behaviour the SDK had before
|
|
1098
1146
|
* delivery policies existed.
|
|
1099
1147
|
*/
|
|
1100
|
-
declare const OPEN_DELIVERY_POLICY: ResolvedDeliveryPolicy;
|
|
1148
|
+
export declare const OPEN_DELIVERY_POLICY: ResolvedDeliveryPolicy;
|
|
1101
1149
|
/**
|
|
1102
1150
|
* A policy with every setting spelled out — see {@link DeliveryPolicy}.
|
|
1103
1151
|
*
|
|
@@ -1106,13 +1154,13 @@ declare const OPEN_DELIVERY_POLICY: ResolvedDeliveryPolicy;
|
|
|
1106
1154
|
* policy that is not an object at all restricts everything. Check a policy
|
|
1107
1155
|
* before you store it with {@link validateDeliveryPolicy}; `planAttempt` does.
|
|
1108
1156
|
*/
|
|
1109
|
-
declare function resolveDeliveryPolicy(policy: unknown): ResolvedDeliveryPolicy;
|
|
1157
|
+
export declare function resolveDeliveryPolicy(policy: unknown): ResolvedDeliveryPolicy;
|
|
1110
1158
|
/**
|
|
1111
1159
|
* The strictest of several policies: a setting is on only where every one of
|
|
1112
1160
|
* them leaves it on. How a course's policy and an assessment's combine, and
|
|
1113
1161
|
* how a pager's policy wins over whatever a question it draws was handed.
|
|
1114
1162
|
*/
|
|
1115
|
-
declare function combineDeliveryPolicies(...policies: unknown[]): ResolvedDeliveryPolicy;
|
|
1163
|
+
export declare function combineDeliveryPolicies(...policies: unknown[]): ResolvedDeliveryPolicy;
|
|
1116
1164
|
/**
|
|
1117
1165
|
* Checks a policy before it is stored: each setting `true`, `false`, `null`
|
|
1118
1166
|
* or absent, and nothing else — no misspelled setting, no string standing in
|
|
@@ -1123,24 +1171,25 @@ declare function combineDeliveryPolicies(...policies: unknown[]): ResolvedDelive
|
|
|
1123
1171
|
* policy is a record of the conditions a paper was sat under: it is worth
|
|
1124
1172
|
* refusing before it is written down, rather than read charitably after.
|
|
1125
1173
|
*/
|
|
1126
|
-
declare function validateDeliveryPolicy(policy: unknown): {
|
|
1127
|
-
|
|
1128
|
-
|
|
1174
|
+
export declare function validateDeliveryPolicy(policy: unknown): {
|
|
1175
|
+
success: true;
|
|
1176
|
+
data: DeliveryPolicy;
|
|
1129
1177
|
} | {
|
|
1130
|
-
|
|
1131
|
-
|
|
1178
|
+
success: false;
|
|
1179
|
+
issues: DeliveryPolicyIssue[];
|
|
1132
1180
|
};
|
|
1133
|
-
|
|
1181
|
+
//#endregion
|
|
1182
|
+
//#region src/errors.d.ts
|
|
1134
1183
|
/** Thrown when activity data fails schema validation at a component boundary. */
|
|
1135
|
-
declare class ActivitySchemaError extends Error {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1184
|
+
export declare class ActivitySchemaError extends Error {
|
|
1185
|
+
readonly activityType: string;
|
|
1186
|
+
readonly errors: ValidationError[];
|
|
1187
|
+
constructor(activityType: string, errors: ValidationError[]);
|
|
1139
1188
|
}
|
|
1140
1189
|
/** Thrown when an unrecognised activity type is passed to the scoring engine. */
|
|
1141
|
-
declare class UnknownActivityTypeError extends Error {
|
|
1142
|
-
|
|
1143
|
-
|
|
1190
|
+
export declare class UnknownActivityTypeError extends Error {
|
|
1191
|
+
readonly activityType: string;
|
|
1192
|
+
constructor(activityType: string);
|
|
1144
1193
|
}
|
|
1145
1194
|
/**
|
|
1146
1195
|
* Thrown when a grading entry point is asked to grade a `redact()` projection
|
|
@@ -1152,9 +1201,9 @@ declare class UnknownActivityTypeError extends Error {
|
|
|
1152
1201
|
* type comes back `unscorable`, and a deferred one `deferred`, as it does for
|
|
1153
1202
|
* any item of that type.
|
|
1154
1203
|
*/
|
|
1155
|
-
declare class RedactedScoringError extends Error {
|
|
1156
|
-
|
|
1157
|
-
|
|
1204
|
+
export declare class RedactedScoringError extends Error {
|
|
1205
|
+
readonly activityType: string;
|
|
1206
|
+
constructor(activityType: string);
|
|
1158
1207
|
}
|
|
1159
1208
|
/**
|
|
1160
1209
|
* Thrown when `score()` is called for an activity type whose grading is
|
|
@@ -1163,33 +1212,34 @@ declare class RedactedScoringError extends Error {
|
|
|
1163
1212
|
* a learner a failing grade for work that simply has not been graded yet.
|
|
1164
1213
|
* Call `evaluate()` instead, which returns `{ status: 'deferred', ... }`.
|
|
1165
1214
|
*/
|
|
1166
|
-
declare class DeferredScoringError extends Error {
|
|
1167
|
-
|
|
1168
|
-
|
|
1215
|
+
export declare class DeferredScoringError extends Error {
|
|
1216
|
+
readonly activityType: string;
|
|
1217
|
+
constructor(activityType: string);
|
|
1169
1218
|
}
|
|
1170
|
-
|
|
1219
|
+
//#endregion
|
|
1220
|
+
//#region src/grading.d.ts
|
|
1171
1221
|
/** Options for {@link gradeFromRubric}. */
|
|
1172
|
-
interface GradeFromRubricOptions {
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1222
|
+
export interface GradeFromRubricOptions {
|
|
1223
|
+
/**
|
|
1224
|
+
* Scaled score [0,1] required to pass. Defaults to the activity's
|
|
1225
|
+
* `passThreshold`, or {@link DEFAULT_PASS_THRESHOLD} when absent.
|
|
1226
|
+
*/
|
|
1227
|
+
passThreshold?: number;
|
|
1228
|
+
/** Narrative feedback for the learner, carried onto the record verbatim. */
|
|
1229
|
+
feedback?: string | null;
|
|
1230
|
+
/**
|
|
1231
|
+
* Compare the pass line the way the score is displayed — both sides rounded,
|
|
1232
|
+
* via `gte` — whichever threshold applies: `passThreshold` above, the
|
|
1233
|
+
* activity's own, or the 0.7 default. The returned `score` stays unrounded.
|
|
1234
|
+
* Opt-in, as on `score()` and `evaluate()`: switching it on moves pass/fail
|
|
1235
|
+
* for totals in the rounding band.
|
|
1236
|
+
*
|
|
1237
|
+
* Checked before any criterion is read: `null` reads as no policy, and a
|
|
1238
|
+
* policy that cannot be applied — an unknown `mode`, or a `dp` that is not a
|
|
1239
|
+
* whole number from 0 to 15 — throws a `RangeError`, even for a rubric that
|
|
1240
|
+
* turns out to be unscorable.
|
|
1241
|
+
*/
|
|
1242
|
+
rounding?: RoundingPolicy;
|
|
1193
1243
|
}
|
|
1194
1244
|
/**
|
|
1195
1245
|
* Computes the weighted total from per-criterion scores — the arithmetic that
|
|
@@ -1223,9 +1273,9 @@ interface GradeFromRubricOptions {
|
|
|
1223
1273
|
* The returned `GradeRecord.score` is always scaled [0,1] against
|
|
1224
1274
|
* `maxScore: 1`, like every other score in the SDK.
|
|
1225
1275
|
*/
|
|
1226
|
-
declare function gradeFromRubric(criteria: readonly CriterionScore[], activityData?: ActivityData, options?: GradeFromRubricOptions): GradeRecord | {
|
|
1227
|
-
|
|
1228
|
-
|
|
1276
|
+
export declare function gradeFromRubric(criteria: readonly CriterionScore[], activityData?: ActivityData, options?: GradeFromRubricOptions): GradeRecord | {
|
|
1277
|
+
unscorable: true;
|
|
1278
|
+
reason: string;
|
|
1229
1279
|
};
|
|
1230
1280
|
/**
|
|
1231
1281
|
* Lifts a {@link GradeRecord} into the `graded` arm of {@link ItemOutcome}, so
|
|
@@ -1246,36 +1296,37 @@ declare function gradeFromRubric(criteria: readonly CriterionScore[], activityDa
|
|
|
1246
1296
|
* is what it is: the slot is still owed a real grade, so a composed attempt
|
|
1247
1297
|
* stays `provisional` and names the slot in `rejectedSlotIds`.
|
|
1248
1298
|
*/
|
|
1249
|
-
declare function outcomeFromGrade(grade: GradeRecord): ItemOutcome;
|
|
1299
|
+
export declare function outcomeFromGrade(grade: GradeRecord): ItemOutcome;
|
|
1250
1300
|
/**
|
|
1251
1301
|
* True when an outcome carries a real grade — either the SDK scored it
|
|
1252
1302
|
* synchronously or a grader returned one. Use this instead of testing
|
|
1253
1303
|
* `status === 'scored'`, which silently misses asynchronously graded work.
|
|
1254
1304
|
*/
|
|
1255
|
-
declare function hasGrade(outcome: ItemOutcome): outcome is Extract<ItemOutcome, {
|
|
1256
|
-
|
|
1305
|
+
export declare function hasGrade(outcome: ItemOutcome): outcome is Extract<ItemOutcome, {
|
|
1306
|
+
status: 'scored' | 'graded';
|
|
1257
1307
|
}>;
|
|
1258
|
-
|
|
1308
|
+
//#endregion
|
|
1309
|
+
//#region src/item-group.d.ts
|
|
1259
1310
|
/** Narrows a sequence entry to an item group. */
|
|
1260
|
-
declare function isItemGroup<TItem extends {
|
|
1261
|
-
|
|
1311
|
+
export declare function isItemGroup<TItem extends {
|
|
1312
|
+
type: string;
|
|
1262
1313
|
}>(entry: SequenceEntry<TItem>): entry is ItemGroup<TItem>;
|
|
1263
1314
|
/** Options for {@link flattenSequence}. */
|
|
1264
|
-
interface FlattenSequenceOptions {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1315
|
+
export interface FlattenSequenceOptions {
|
|
1316
|
+
/**
|
|
1317
|
+
* Shuffle the top-level entries. A group moves as ONE block — its items are
|
|
1318
|
+
* never interleaved with other entries — which is the reason a group exists
|
|
1319
|
+
* as a container rather than as a flag on each item.
|
|
1320
|
+
*/
|
|
1321
|
+
shuffleEntries?: boolean;
|
|
1322
|
+
/**
|
|
1323
|
+
* Seed for every shuffle in this call: the entries, and each group whose
|
|
1324
|
+
* `shuffle` is `within-group`. REQUIRED whenever anything shuffles. The SDK
|
|
1325
|
+
* never invents one, because the server that stores an attempt and the
|
|
1326
|
+
* client that renders it must derive the SAME order, and only a shared seed
|
|
1327
|
+
* makes that true. The attempt id is the natural choice.
|
|
1328
|
+
*/
|
|
1329
|
+
seed?: string;
|
|
1279
1330
|
}
|
|
1280
1331
|
/**
|
|
1281
1332
|
* Turns a sequence definition — loose activities and item groups, in authored
|
|
@@ -1291,30 +1342,31 @@ interface FlattenSequenceOptions {
|
|
|
1291
1342
|
*
|
|
1292
1343
|
* @throws Error when a shuffle is requested without a `seed`.
|
|
1293
1344
|
*/
|
|
1294
|
-
declare function flattenSequence<TItem extends {
|
|
1295
|
-
|
|
1296
|
-
|
|
1345
|
+
export declare function flattenSequence<TItem extends {
|
|
1346
|
+
id: string;
|
|
1347
|
+
type: string;
|
|
1297
1348
|
}>(entries: readonly SequenceEntry<TItem>[], options?: FlattenSequenceOptions): SequenceSlot<TItem>[];
|
|
1298
|
-
|
|
1349
|
+
//#endregion
|
|
1350
|
+
//#region src/types/media-budget.d.ts
|
|
1299
1351
|
/**
|
|
1300
1352
|
* What one budgeted recording has cost the learner so far.
|
|
1301
1353
|
*/
|
|
1302
1354
|
interface MediaPlayLedgerEntry {
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1355
|
+
/**
|
|
1356
|
+
* Plays consumed. A non-negative integer. It MAY exceed the budget: an
|
|
1357
|
+
* invigilator override and a race the server resolved both legitimately
|
|
1358
|
+
* produce that, and clamping here would hide it.
|
|
1359
|
+
*/
|
|
1360
|
+
plays: number;
|
|
1361
|
+
/**
|
|
1362
|
+
* Where playback stood at the last report, in seconds.
|
|
1363
|
+
*
|
|
1364
|
+
* Restored on mount so a refresh RESUMES the play the learner already paid
|
|
1365
|
+
* for instead of charging them again for it. It can only ever let them
|
|
1366
|
+
* continue from where they were, never restart, because `seek` resolves to
|
|
1367
|
+
* `'none'` under a budget.
|
|
1368
|
+
*/
|
|
1369
|
+
at?: number;
|
|
1318
1370
|
}
|
|
1319
1371
|
/**
|
|
1320
1372
|
* The spent-play ledger for one attempt.
|
|
@@ -1334,13 +1386,13 @@ interface MediaPlayLedgerEntry {
|
|
|
1334
1386
|
* Bound to its paper by `planHash` for the same reason `AttemptState` is.
|
|
1335
1387
|
*/
|
|
1336
1388
|
interface MediaPlayLedger {
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1389
|
+
ledgerVersion: '1.0';
|
|
1390
|
+
/** The `planHash` of the paper these counts were spent on. */
|
|
1391
|
+
planHash: string;
|
|
1392
|
+
/** Keyed by `slotMediaKey()` / `stimulusMediaKey()`. An absent key means nothing spent. */
|
|
1393
|
+
entries: Record<string, MediaPlayLedgerEntry>;
|
|
1394
|
+
/** ISO 8601, when the caller supplies one. The SDK reads no clock. */
|
|
1395
|
+
savedAt?: string;
|
|
1344
1396
|
}
|
|
1345
1397
|
/**
|
|
1346
1398
|
* What the SDK asks the consumer to record, before a sample of audio is
|
|
@@ -1350,28 +1402,29 @@ interface MediaPlayLedger {
|
|
|
1350
1402
|
* seeded at 0 both claim 1, and only an atomic write can tell them apart.
|
|
1351
1403
|
*/
|
|
1352
1404
|
interface MediaPlayClaim {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1405
|
+
/** `slot:…` / `stimulus:…`. */
|
|
1406
|
+
key: string;
|
|
1407
|
+
/** The count the client believes was already spent — the value to compare against. */
|
|
1408
|
+
previousPlaysUsed: number;
|
|
1409
|
+
/** The count the client is claiming: `previousPlaysUsed + 1`. */
|
|
1410
|
+
playsUsed: number;
|
|
1411
|
+
maxPlays: number;
|
|
1412
|
+
playsRemaining: number;
|
|
1413
|
+
/** Where the learner stood when the claim was made. Forensics; never identity. */
|
|
1414
|
+
slotId: string;
|
|
1415
|
+
index: number;
|
|
1416
|
+
activityId?: string;
|
|
1365
1417
|
}
|
|
1366
1418
|
/** The consumer's authoritative answer to a {@link MediaPlayClaim}. */
|
|
1367
1419
|
interface MediaPlayGrant {
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1420
|
+
/**
|
|
1421
|
+
* The count AFTER the server's atomic write. A value greater than
|
|
1422
|
+
* `maxPlays` refuses the play — which is how a second tab is caught.
|
|
1423
|
+
*/
|
|
1424
|
+
playsUsed: number;
|
|
1373
1425
|
}
|
|
1374
|
-
|
|
1426
|
+
//#endregion
|
|
1427
|
+
//#region src/media-budget.d.ts
|
|
1375
1428
|
/**
|
|
1376
1429
|
* The authored-entry prefix of a slot id: `"3"` for both `"3"` and `"3.1"`.
|
|
1377
1430
|
*
|
|
@@ -1379,9 +1432,9 @@ interface MediaPlayGrant {
|
|
|
1379
1432
|
* `keyOf` rejects a `.` in both an entry key and an item key — so the first
|
|
1380
1433
|
* `.` is always the group/item separator.
|
|
1381
1434
|
*/
|
|
1382
|
-
declare function entryKeyOf(slotId: string): string;
|
|
1435
|
+
export declare function entryKeyOf(slotId: string): string;
|
|
1383
1436
|
/** Budget key for an activity's OWN `data.media`. One budget per slot. */
|
|
1384
|
-
declare function slotMediaKey(slotId: string): string;
|
|
1437
|
+
export declare function slotMediaKey(slotId: string): string;
|
|
1385
1438
|
/**
|
|
1386
1439
|
* Budget key for an item group's `stimulus.media`.
|
|
1387
1440
|
*
|
|
@@ -1391,15 +1444,15 @@ declare function slotMediaKey(slotId: string): string;
|
|
|
1391
1444
|
* `stimulus.id` would collide across papers, which is the thing slot keys and
|
|
1392
1445
|
* `planHash` exist to prevent.
|
|
1393
1446
|
*/
|
|
1394
|
-
declare function stimulusMediaKey(slotId: string): string;
|
|
1447
|
+
export declare function stimulusMediaKey(slotId: string): string;
|
|
1395
1448
|
/** A playback policy with every default resolved. One derivation, used everywhere. */
|
|
1396
|
-
interface ResolvedPlaybackPolicy {
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1449
|
+
export interface ResolvedPlaybackPolicy {
|
|
1450
|
+
controls: 'native' | 'minimal';
|
|
1451
|
+
/** `null` when the recording is unbudgeted. */
|
|
1452
|
+
maxPlays: number | null;
|
|
1453
|
+
seek: 'allow' | 'none';
|
|
1454
|
+
rate: 'allow' | 'fixed';
|
|
1455
|
+
nativeControlHints: readonly NativeControlHint[];
|
|
1403
1456
|
}
|
|
1404
1457
|
/**
|
|
1405
1458
|
* Resolves the defaults once, so the schema refinements, the plan and the
|
|
@@ -1408,7 +1461,7 @@ interface ResolvedPlaybackPolicy {
|
|
|
1408
1461
|
* Absent `playback` resolves to exactly the SDK's pre-0.8.0 behaviour:
|
|
1409
1462
|
* `controls: 'native'`, no budget, free seeking, free speed, no hints.
|
|
1410
1463
|
*/
|
|
1411
|
-
declare function resolvePlaybackPolicy(media: ActivityMedia): ResolvedPlaybackPolicy;
|
|
1464
|
+
export declare function resolvePlaybackPolicy(media: ActivityMedia): ResolvedPlaybackPolicy;
|
|
1412
1465
|
/**
|
|
1413
1466
|
* Every budgeted recording a plan contains: budget key → the `maxPlays` that
|
|
1414
1467
|
* was frozen when the attempt was planned.
|
|
@@ -1416,7 +1469,7 @@ declare function resolvePlaybackPolicy(media: ActivityMedia): ResolvedPlaybackPo
|
|
|
1416
1469
|
* Use it to build the storage rows an attempt needs, and to check a stored
|
|
1417
1470
|
* ledger against the paper it claims to belong to.
|
|
1418
1471
|
*/
|
|
1419
|
-
declare function planMediaBudgets(plan: AttemptPlan): Record<string, number>;
|
|
1472
|
+
export declare function planMediaBudgets(plan: AttemptPlan): Record<string, number>;
|
|
1420
1473
|
/**
|
|
1421
1474
|
* Validates a set of spent-play counts against the plan that budgeted them,
|
|
1422
1475
|
* and stamps the envelope.
|
|
@@ -1428,8 +1481,8 @@ declare function planMediaBudgets(plan: AttemptPlan): Record<string, number>;
|
|
|
1428
1481
|
* @throws Error when a key is not budgeted by the plan, or a count is not a
|
|
1429
1482
|
* non-negative integer, or a position is not a finite number.
|
|
1430
1483
|
*/
|
|
1431
|
-
declare function serializeMediaPlayLedger(plan: AttemptPlan, entries: Readonly<Record<string, MediaPlayLedgerEntry>>, options?: {
|
|
1432
|
-
|
|
1484
|
+
export declare function serializeMediaPlayLedger(plan: AttemptPlan, entries: Readonly<Record<string, MediaPlayLedgerEntry>>, options?: {
|
|
1485
|
+
savedAt?: string;
|
|
1433
1486
|
}): MediaPlayLedger;
|
|
1434
1487
|
/**
|
|
1435
1488
|
* Reopens a stored ledger against the paper it was spent on.
|
|
@@ -1443,8 +1496,9 @@ declare function serializeMediaPlayLedger(plan: AttemptPlan, entries: Readonly<R
|
|
|
1443
1496
|
* @throws Error on an unrecognised `ledgerVersion`, a `planHash` mismatch, or
|
|
1444
1497
|
* anything `serializeMediaPlayLedger` refuses.
|
|
1445
1498
|
*/
|
|
1446
|
-
declare function restoreMediaPlayLedger(plan: AttemptPlan, stored: MediaPlayLedger): MediaPlayLedger;
|
|
1447
|
-
|
|
1499
|
+
export declare function restoreMediaPlayLedger(plan: AttemptPlan, stored: MediaPlayLedger): MediaPlayLedger;
|
|
1500
|
+
//#endregion
|
|
1501
|
+
//#region src/standard-schema.d.ts
|
|
1448
1502
|
/**
|
|
1449
1503
|
* Standard Schema v1 (https://standardschema.dev): the interface zod, valibot,
|
|
1450
1504
|
* ArkType and other validators implement, so a library can accept a schema from
|
|
@@ -1457,68 +1511,85 @@ declare function restoreMediaPlayLedger(plan: AttemptPlan, stored: MediaPlayLedg
|
|
|
1457
1511
|
*/
|
|
1458
1512
|
/** A schema that validates unknown input and produces `Output`. */
|
|
1459
1513
|
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
1460
|
-
|
|
1461
|
-
|
|
1514
|
+
/** The Standard Schema properties. */
|
|
1515
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
1462
1516
|
}
|
|
1463
1517
|
declare namespace StandardSchemaV1 {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1518
|
+
/** The Standard Schema properties interface. */
|
|
1519
|
+
interface Props<Input = unknown, Output = Input> {
|
|
1520
|
+
/** The version number of the standard. */
|
|
1521
|
+
readonly version: 1;
|
|
1522
|
+
/** The vendor name of the schema library. */
|
|
1523
|
+
readonly vendor: string;
|
|
1524
|
+
/**
|
|
1525
|
+
* Validates unknown input values. lk-core validates synchronously, so a
|
|
1526
|
+
* schema whose validation returns a Promise is refused when it is read.
|
|
1527
|
+
*/
|
|
1528
|
+
readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
|
|
1529
|
+
/** Inferred types associated with the schema. */
|
|
1530
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
1531
|
+
}
|
|
1532
|
+
/** The result interface of the validate function. */
|
|
1533
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
1534
|
+
/** The result interface if validation succeeds. */
|
|
1535
|
+
interface SuccessResult<Output> {
|
|
1536
|
+
/** The typed output value. */
|
|
1537
|
+
readonly value: Output;
|
|
1538
|
+
/** The absence of issues indicates success. */
|
|
1539
|
+
readonly issues?: undefined;
|
|
1540
|
+
}
|
|
1541
|
+
/** Options for the validate function. */
|
|
1542
|
+
interface Options {
|
|
1543
|
+
/** Implicit support for additional vendor-specific parameters, if needed. */
|
|
1544
|
+
readonly libraryOptions?: Record<string, unknown> | undefined;
|
|
1545
|
+
}
|
|
1546
|
+
/** The result interface if validation fails. */
|
|
1547
|
+
interface FailureResult {
|
|
1548
|
+
/** The issues of failed validation. */
|
|
1549
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
1550
|
+
}
|
|
1551
|
+
/** The issue interface of the failure output. */
|
|
1552
|
+
interface Issue {
|
|
1553
|
+
/** The error message of the issue. */
|
|
1554
|
+
readonly message: string;
|
|
1555
|
+
/** The path of the issue, if any. */
|
|
1556
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
1557
|
+
}
|
|
1558
|
+
/** The path segment interface of the issue. */
|
|
1559
|
+
interface PathSegment {
|
|
1560
|
+
/** The key representing a path segment. */
|
|
1561
|
+
readonly key: PropertyKey;
|
|
1562
|
+
}
|
|
1563
|
+
/** The Standard Schema types interface. */
|
|
1564
|
+
interface Types<Input = unknown, Output = Input> {
|
|
1565
|
+
/** The input type of the schema. */
|
|
1566
|
+
readonly input: Input;
|
|
1567
|
+
/** The output type of the schema. */
|
|
1568
|
+
readonly output: Output;
|
|
1569
|
+
}
|
|
1570
|
+
/** Infers the input type of a Standard Schema. */
|
|
1571
|
+
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
1572
|
+
/** Infers the output type of a Standard Schema. */
|
|
1573
|
+
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
1520
1574
|
}
|
|
1521
|
-
|
|
1575
|
+
//#endregion
|
|
1576
|
+
//#region src/registry/define.d.ts
|
|
1577
|
+
/**
|
|
1578
|
+
* Identity helper that gives full type inference when authoring a descriptor:
|
|
1579
|
+
*
|
|
1580
|
+
* ```ts
|
|
1581
|
+
* const myType = defineActivityType<MyTypeData, MyTypeLearnerResponse>({ ... });
|
|
1582
|
+
* registerActivityType(myType);
|
|
1583
|
+
* ```
|
|
1584
|
+
*
|
|
1585
|
+
* In a module of its own so the SDK's built-in descriptors can use it without
|
|
1586
|
+
* importing the registry they are read into.
|
|
1587
|
+
*/
|
|
1588
|
+
export declare function defineActivityType<TData extends {
|
|
1589
|
+
type: string;
|
|
1590
|
+
}, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): ActivityTypeDescriptor<TData, TResponse>;
|
|
1591
|
+
//#endregion
|
|
1592
|
+
//#region src/registry/registry.d.ts
|
|
1522
1593
|
/** ScoringResult without `passed` — the public `score()` / `evaluate()` fill that in. */
|
|
1523
1594
|
type PartialScoringResult = Omit<ScoringResult, 'passed'>;
|
|
1524
1595
|
/**
|
|
@@ -1541,18 +1612,18 @@ type Sensitivity = 'public' | 'answer-key' | 'author-only';
|
|
|
1541
1612
|
* without classifying it hides it, never leaks it.
|
|
1542
1613
|
*/
|
|
1543
1614
|
interface FieldPolicy {
|
|
1544
|
-
|
|
1615
|
+
readonly [field: string]: Sensitivity | FieldPolicy;
|
|
1545
1616
|
}
|
|
1546
1617
|
/** xAPI interaction types defined by xAPI 1.0.3 (cmi.interaction vocabulary). */
|
|
1547
1618
|
type XAPIInteractionType = 'choice' | 'fill-in' | 'long-fill-in' | 'matching' | 'sequencing' | 'performance' | 'true-false' | 'other';
|
|
1548
1619
|
/** Interop facts a generic statement builder cannot infer from data alone. */
|
|
1549
1620
|
interface ActivityTypeInterop<TData> {
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1621
|
+
/** IRI for the xAPI Activity `definition.type`. */
|
|
1622
|
+
readonly xapiActivityTypeIri?: string;
|
|
1623
|
+
/** xAPI `definition.interactionType` for this activity type. */
|
|
1624
|
+
readonly xapiInteractionType?: XAPIInteractionType;
|
|
1625
|
+
/** Builds the xAPI `correctResponsesPattern` strings for an item. */
|
|
1626
|
+
readonly correctResponsesPattern?: (data: TData) => string[];
|
|
1556
1627
|
}
|
|
1557
1628
|
/**
|
|
1558
1629
|
* How responses to an activity type are graded:
|
|
@@ -1562,12 +1633,12 @@ interface ActivityTypeInterop<TData> {
|
|
|
1562
1633
|
* (e.g. word counts), surfaced in `ItemOutcome.partial`.
|
|
1563
1634
|
*/
|
|
1564
1635
|
type ActivityTypeScoring<TData, TResponse> = {
|
|
1565
|
-
|
|
1566
|
-
|
|
1636
|
+
readonly kind: 'sync';
|
|
1637
|
+
readonly score: (data: TData, response: TResponse) => PartialScoringResult;
|
|
1567
1638
|
} | {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1639
|
+
readonly kind: 'deferred';
|
|
1640
|
+
readonly reason: 'requires_async_grading';
|
|
1641
|
+
readonly partial?: (data: TData, response: TResponse | undefined) => DeferredScoringPartial;
|
|
1571
1642
|
};
|
|
1572
1643
|
/**
|
|
1573
1644
|
* Authoring support for an activity type: the empty draft an editor starts
|
|
@@ -1577,47 +1648,47 @@ type ActivityTypeScoring<TData, TResponse> = {
|
|
|
1577
1648
|
* `createDraft()` throws for the type.
|
|
1578
1649
|
*/
|
|
1579
1650
|
interface ActivityTypeAuthoring<TData> {
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1651
|
+
/**
|
|
1652
|
+
* A new draft: every required field present, nothing authored yet. It must
|
|
1653
|
+
* come back from `validateDraft` as `incomplete` — never `invalid`, and never
|
|
1654
|
+
* `complete` — so a freshly added question is not reported as an error, and
|
|
1655
|
+
* cannot pass validation before anyone has written it.
|
|
1656
|
+
*/
|
|
1657
|
+
readonly createDraft?: (context: DraftContext) => TData;
|
|
1658
|
+
/**
|
|
1659
|
+
* Reports what is missing (`incomplete`) and what is wrong (`invalid`) in a
|
|
1660
|
+
* draft. Receives any plain object and must not throw on one.
|
|
1661
|
+
*
|
|
1662
|
+
* Report each problem at the path the schema reports it. `validateDraft` adds
|
|
1663
|
+
* every schema failure as `invalid` unless an issue returned here sits at that
|
|
1664
|
+
* path or inside it — so an issue at the wrong path leaves the schema's
|
|
1665
|
+
* message standing beside yours, and makes an unfinished draft read as wrong.
|
|
1666
|
+
* An issue inside a path accounts for every failure at that path, a list's
|
|
1667
|
+
* length included, so report a rule about a whole list at the list's own path.
|
|
1668
|
+
* A failure at the root of the draft is accounted for only by an issue at the
|
|
1669
|
+
* root. A `null` the schema refuses, where nothing here reports it, comes back
|
|
1670
|
+
* as `null_not_allowed`. A zod 4 schema tells a refused `null` from a rule of
|
|
1671
|
+
* yours that merely points at one, which keeps its own code; a schema from
|
|
1672
|
+
* another library cannot, so report such a rule here, at its path.
|
|
1673
|
+
*
|
|
1674
|
+
* A code documented in `docs/authoring.md` is reported with its documented
|
|
1675
|
+
* severity. For a code of your own, a severity other than `'incomplete'` is
|
|
1676
|
+
* reported as `invalid`.
|
|
1677
|
+
*/
|
|
1678
|
+
readonly checkDraft?: (draft: Readonly<Record<string, unknown>>) => DraftIssue[];
|
|
1679
|
+
/**
|
|
1680
|
+
* The item critic for the type: what `critiqueDraft` reports about a draft
|
|
1681
|
+
* that may be perfectly valid — a flaw a learner can exploit (`warning`), or
|
|
1682
|
+
* an item-writing guideline it departs from (`advice`). Receives any plain
|
|
1683
|
+
* object, finished or not, and must not throw on one: skip a rule whose
|
|
1684
|
+
* fields are not there yet. Never a reason to refuse the item; that is
|
|
1685
|
+
* `checkDraft`'s.
|
|
1686
|
+
*
|
|
1687
|
+
* A code documented in `docs/authoring.md` is reported with its documented
|
|
1688
|
+
* severity. For a code of your own, a severity other than `'advice'` is
|
|
1689
|
+
* reported as `warning`.
|
|
1690
|
+
*/
|
|
1691
|
+
readonly critique?: (draft: Readonly<Record<string, unknown>>) => ItemFinding[];
|
|
1621
1692
|
}
|
|
1622
1693
|
/**
|
|
1623
1694
|
* A value-level description of an activity type: its contract (schema), its
|
|
@@ -1640,77 +1711,66 @@ interface ActivityTypeAuthoring<TData> {
|
|
|
1640
1711
|
* ```
|
|
1641
1712
|
*/
|
|
1642
1713
|
interface ActivityTypeDescriptor<TData extends {
|
|
1643
|
-
|
|
1714
|
+
type: string;
|
|
1644
1715
|
}, TResponse> {
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1716
|
+
/** The `type` discriminator string (kebab-case by convention). */
|
|
1717
|
+
readonly type: TData['type'];
|
|
1718
|
+
/**
|
|
1719
|
+
* The activity's data contract, as a Standard Schema whose output is the
|
|
1720
|
+
* data. Its validation must be synchronous: every entry point that reads it
|
|
1721
|
+
* is.
|
|
1722
|
+
*/
|
|
1723
|
+
readonly schema: StandardSchemaV1<unknown, TData>;
|
|
1724
|
+
/**
|
|
1725
|
+
* The contract as JSON Schema, for `jsonSchemaFor`. Leave it out when
|
|
1726
|
+
* `schema` can produce one itself through the Standard JSON Schema converter
|
|
1727
|
+
* (`'~standard'.jsonSchema`), as a zod 4.6 schema can; give it to override
|
|
1728
|
+
* that, or for a library that cannot.
|
|
1729
|
+
*/
|
|
1730
|
+
readonly jsonSchema?: Readonly<Record<string, unknown>>;
|
|
1731
|
+
/** How responses are graded. */
|
|
1732
|
+
readonly scoring: ActivityTypeScoring<TData, TResponse>;
|
|
1733
|
+
/** Whether a response counts as an answer (vs. blank/untouched). */
|
|
1734
|
+
readonly isAnswered?: (response: TResponse | undefined) => boolean;
|
|
1735
|
+
/** Per-field sensitivity map driving `redact()`. Fail-closed. */
|
|
1736
|
+
readonly fieldPolicy?: FieldPolicy;
|
|
1737
|
+
/**
|
|
1738
|
+
* Schema the output of `redact(data)` (with default `reveal: 'none'`) must
|
|
1739
|
+
* satisfy, as a Standard Schema. Strict by design: it proves the ABSENCE of
|
|
1740
|
+
* answer-key fields, so `assertRedacted` can guarantee a payload is safe to
|
|
1741
|
+
* send to a learner.
|
|
1742
|
+
*/
|
|
1743
|
+
readonly redactedSchema?: StandardSchemaV1;
|
|
1744
|
+
/** Interop facts for xAPI (and later QTI) statement building. */
|
|
1745
|
+
readonly interop?: ActivityTypeInterop<TData>;
|
|
1746
|
+
/** The interaction-event kinds components for this type emit. */
|
|
1747
|
+
readonly interactions?: readonly string[];
|
|
1748
|
+
/** Draft support for authoring tools. See {@link ActivityTypeAuthoring}. */
|
|
1749
|
+
readonly authoring?: ActivityTypeAuthoring<TData>;
|
|
1679
1750
|
}
|
|
1680
1751
|
/**
|
|
1681
1752
|
* Internal type-erased descriptor shape stored in the registry. Dispatch call
|
|
1682
1753
|
* sites cast payloads back; the public generic API preserves inference.
|
|
1683
1754
|
*/
|
|
1684
1755
|
interface RegisteredActivityTypeDescriptor {
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1756
|
+
readonly type: string;
|
|
1757
|
+
readonly schema: StandardSchemaV1;
|
|
1758
|
+
readonly jsonSchema?: Readonly<Record<string, unknown>>;
|
|
1759
|
+
readonly scoring: {
|
|
1760
|
+
readonly kind: 'sync';
|
|
1761
|
+
readonly score: (data: unknown, response: unknown) => PartialScoringResult;
|
|
1762
|
+
} | {
|
|
1763
|
+
readonly kind: 'deferred';
|
|
1764
|
+
readonly reason: 'requires_async_grading';
|
|
1765
|
+
readonly partial?: (data: unknown, response: unknown) => DeferredScoringPartial;
|
|
1766
|
+
};
|
|
1767
|
+
readonly isAnswered?: (response: unknown) => boolean;
|
|
1768
|
+
readonly fieldPolicy?: FieldPolicy;
|
|
1769
|
+
readonly redactedSchema?: StandardSchemaV1;
|
|
1770
|
+
readonly interop?: ActivityTypeInterop<unknown>;
|
|
1771
|
+
readonly interactions?: readonly string[];
|
|
1772
|
+
readonly authoring?: ActivityTypeAuthoring<unknown>;
|
|
1702
1773
|
}
|
|
1703
|
-
/**
|
|
1704
|
-
* Identity helper that gives full type inference when authoring a descriptor:
|
|
1705
|
-
*
|
|
1706
|
-
* ```ts
|
|
1707
|
-
* const myType = defineActivityType<MyTypeData, MyTypeLearnerResponse>({ ... });
|
|
1708
|
-
* registerActivityType(myType);
|
|
1709
|
-
* ```
|
|
1710
|
-
*/
|
|
1711
|
-
declare function defineActivityType<TData extends {
|
|
1712
|
-
type: string;
|
|
1713
|
-
}, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): ActivityTypeDescriptor<TData, TResponse>;
|
|
1714
1774
|
/**
|
|
1715
1775
|
* Registers an activity type on the default registry, making it live for
|
|
1716
1776
|
* `validateActivity`, `score`, `evaluate`, `redact`, and `jsonSchemaFor`.
|
|
@@ -1719,14 +1779,15 @@ declare function defineActivityType<TData extends {
|
|
|
1719
1779
|
* type's contract or scoring is exactly the class of accident a summative
|
|
1720
1780
|
* SDK must not allow.
|
|
1721
1781
|
*/
|
|
1722
|
-
declare function registerActivityType<TData extends {
|
|
1723
|
-
|
|
1782
|
+
export declare function registerActivityType<TData extends {
|
|
1783
|
+
type: string;
|
|
1724
1784
|
}, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): void;
|
|
1725
1785
|
/** Returns the registered descriptor for `type`, or `undefined`. */
|
|
1726
|
-
declare function getActivityTypeDescriptor(type: string): RegisteredActivityTypeDescriptor | undefined;
|
|
1786
|
+
export declare function getActivityTypeDescriptor(type: string): RegisteredActivityTypeDescriptor | undefined;
|
|
1727
1787
|
/** The type strings currently registered (built-ins plus consumer-registered). */
|
|
1728
|
-
declare function registeredActivityTypes(): string[];
|
|
1729
|
-
|
|
1788
|
+
export declare function registeredActivityTypes(): string[];
|
|
1789
|
+
//#endregion
|
|
1790
|
+
//#region src/redact.d.ts
|
|
1730
1791
|
/**
|
|
1731
1792
|
* A learner-safe projection of activity data produced by {@link redact}:
|
|
1732
1793
|
* the activity's public fields plus the `redacted: true` marker. Renderable
|
|
@@ -1734,49 +1795,49 @@ declare function registeredActivityTypes(): string[];
|
|
|
1734
1795
|
* but stripped of the answer key, scoring rules, authored feedback, and
|
|
1735
1796
|
* author-only assets.
|
|
1736
1797
|
*/
|
|
1737
|
-
interface RedactedActivityData {
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1798
|
+
export interface RedactedActivityData {
|
|
1799
|
+
redacted: true;
|
|
1800
|
+
schemaVersion: string;
|
|
1801
|
+
type: string;
|
|
1802
|
+
id: string;
|
|
1803
|
+
title: string;
|
|
1804
|
+
[key: string]: unknown;
|
|
1744
1805
|
}
|
|
1745
1806
|
/** Options for {@link redact}. */
|
|
1746
|
-
interface RedactOptions {
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1807
|
+
export interface RedactOptions {
|
|
1808
|
+
/**
|
|
1809
|
+
* Which sensitivity tiers to keep beyond `public`:
|
|
1810
|
+
* - `'none'` (default) — public fields only; the output satisfies the
|
|
1811
|
+
* type's strict redacted schema and `assertRedacted`.
|
|
1812
|
+
* - `'after-submit'` — public + answer-key fields (for post-submission
|
|
1813
|
+
* review renders). `author-only` fields and unclassified fields are
|
|
1814
|
+
* STILL removed; the output will NOT pass `assertRedacted`.
|
|
1815
|
+
*/
|
|
1816
|
+
reveal?: 'none' | 'after-submit';
|
|
1817
|
+
/**
|
|
1818
|
+
* Per-call sensitivity overrides, merged over the type's registered
|
|
1819
|
+
* `fieldPolicy` (top-level keys replace; nested objects merge one level).
|
|
1820
|
+
*
|
|
1821
|
+
* Sensitivity is partly a PEDAGOGICAL decision, not purely a security one —
|
|
1822
|
+
* whether a rubric or a hint is learner-visible differs legitimately between
|
|
1823
|
+
* deployments — and the SDK must not freeze that choice. Use this to tighten
|
|
1824
|
+
* a field the SDK ships as `public`:
|
|
1825
|
+
*
|
|
1826
|
+
* ```ts
|
|
1827
|
+
* redact(essay, { policy: { rubric: 'author-only' } });
|
|
1828
|
+
* ```
|
|
1829
|
+
*
|
|
1830
|
+
* Overrides can only be applied to fields; they cannot re-open a field the
|
|
1831
|
+
* caller has not classified, because unclassified still means removed.
|
|
1832
|
+
* What can be tightened is a field the type's `redactedSchema` leaves
|
|
1833
|
+
* OPTIONAL, as it leaves the rubric above: the schema check rejects a
|
|
1834
|
+
* payload that reveals more than the learner-safe shape, and equally one
|
|
1835
|
+
* that is missing part of it. Tightening a field the redacted shape requires
|
|
1836
|
+
* — a read-aloud item's `scoring`, `recording`, `referenceText` or `locale`,
|
|
1837
|
+
* without which the learner has no item to read — throws
|
|
1838
|
+
* {@link ActivitySchemaError} instead of hiding it.
|
|
1839
|
+
*/
|
|
1840
|
+
policy?: FieldPolicy;
|
|
1780
1841
|
}
|
|
1781
1842
|
/**
|
|
1782
1843
|
* Produces the learner-safe projection of activity data (R7), driven by the
|
|
@@ -1793,8 +1854,8 @@ interface RedactOptions {
|
|
|
1793
1854
|
* @throws Error when the registered descriptor declares no `fieldPolicy`
|
|
1794
1855
|
* (redaction cannot guess sensitivities).
|
|
1795
1856
|
*/
|
|
1796
|
-
declare function redact<T extends {
|
|
1797
|
-
|
|
1857
|
+
export declare function redact<T extends {
|
|
1858
|
+
type: string;
|
|
1798
1859
|
}>(data: T, options?: RedactOptions): RedactedActivityData;
|
|
1799
1860
|
/**
|
|
1800
1861
|
* Asserts that `data` is a learner-safe redacted projection: it carries the
|
|
@@ -1803,10 +1864,10 @@ declare function redact<T extends {
|
|
|
1803
1864
|
* Use this at the server boundary before sending activity data to a client
|
|
1804
1865
|
* that must not hold the key.
|
|
1805
1866
|
*/
|
|
1806
|
-
declare function assertRedacted(data: unknown): asserts data is RedactedActivityData;
|
|
1867
|
+
export declare function assertRedacted(data: unknown): asserts data is RedactedActivityData;
|
|
1807
1868
|
/** A learner-safe item group: the container with its marker, holding `redact()` projections. */
|
|
1808
|
-
type RedactedItemGroup = ItemGroup<RedactedActivityData> & {
|
|
1809
|
-
|
|
1869
|
+
export type RedactedItemGroup = ItemGroup<RedactedActivityData> & {
|
|
1870
|
+
redacted: true;
|
|
1810
1871
|
};
|
|
1811
1872
|
/**
|
|
1812
1873
|
* Produces the learner-safe projection of an item group: the container and
|
|
@@ -1818,8 +1879,8 @@ type RedactedItemGroup = ItemGroup<RedactedActivityData> & {
|
|
|
1818
1879
|
* With the default `reveal: 'none'` the container is verified against the
|
|
1819
1880
|
* strict redacted schema; each item was already verified by `redact`.
|
|
1820
1881
|
*/
|
|
1821
|
-
declare function redactItemGroup<TItem extends {
|
|
1822
|
-
|
|
1882
|
+
export declare function redactItemGroup<TItem extends {
|
|
1883
|
+
type: string;
|
|
1823
1884
|
}>(group: ItemGroup<TItem>, options?: RedactOptions): RedactedItemGroup;
|
|
1824
1885
|
/**
|
|
1825
1886
|
* Asserts that `data` is a learner-safe item group: it carries the marker,
|
|
@@ -1829,12 +1890,13 @@ declare function redactItemGroup<TItem extends {
|
|
|
1829
1890
|
* failures are reported at `items.<index>.…`. Use it at the server boundary
|
|
1830
1891
|
* before sending a group to a client that must not hold the key.
|
|
1831
1892
|
*/
|
|
1832
|
-
declare function assertRedactedItemGroup(data: unknown): asserts data is RedactedItemGroup;
|
|
1833
|
-
|
|
1893
|
+
export declare function assertRedactedItemGroup(data: unknown): asserts data is RedactedItemGroup;
|
|
1894
|
+
//#endregion
|
|
1895
|
+
//#region src/registry/builtins.d.ts
|
|
1834
1896
|
/** Built-in Multiple Choice descriptor. */
|
|
1835
|
-
declare const multipleChoiceType: ActivityTypeDescriptor<MultipleChoiceData, MultipleChoiceLearnerResponse>;
|
|
1897
|
+
export declare const multipleChoiceType: ActivityTypeDescriptor<MultipleChoiceData, MultipleChoiceLearnerResponse>;
|
|
1836
1898
|
/** Built-in Fill-in-the-Blanks descriptor. */
|
|
1837
|
-
declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, FillInTheBlanksLearnerResponse>;
|
|
1899
|
+
export declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, FillInTheBlanksLearnerResponse>;
|
|
1838
1900
|
/**
|
|
1839
1901
|
* Built-in Written Response descriptor. Grading is DEFERRED: submissions are
|
|
1840
1902
|
* graded asynchronously (AI or human) by the consumer; the synchronous
|
|
@@ -1842,23 +1904,24 @@ declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, F
|
|
|
1842
1904
|
* submitted text with the canonical `countWords()` — the client-supplied
|
|
1843
1905
|
* count is informational, never trusted.
|
|
1844
1906
|
*/
|
|
1845
|
-
declare const writtenResponseType: ActivityTypeDescriptor<WrittenResponseData, WrittenResponseLearnerResponse>;
|
|
1907
|
+
export declare const writtenResponseType: ActivityTypeDescriptor<WrittenResponseData, WrittenResponseLearnerResponse>;
|
|
1846
1908
|
/** Built-in Gap Select descriptor. */
|
|
1847
|
-
declare const gapSelectType: ActivityTypeDescriptor<GapSelectData, GapSelectLearnerResponse>;
|
|
1909
|
+
export declare const gapSelectType: ActivityTypeDescriptor<GapSelectData, GapSelectLearnerResponse>;
|
|
1848
1910
|
/**
|
|
1849
1911
|
* Built-in Dictation descriptor. Graded synchronously: the score is the
|
|
1850
1912
|
* character-level similarity of the typed text to the transcript, a pure
|
|
1851
1913
|
* computation identical in a browser and on a server.
|
|
1852
1914
|
*/
|
|
1853
|
-
declare const dictationType: ActivityTypeDescriptor<DictationData, DictationLearnerResponse>;
|
|
1915
|
+
export declare const dictationType: ActivityTypeDescriptor<DictationData, DictationLearnerResponse>;
|
|
1854
1916
|
/**
|
|
1855
1917
|
* Built-in Read Aloud descriptor. Grading is DEFERRED: the SDK calls no
|
|
1856
1918
|
* assessor, so the synchronous outcome reports only whether a recording was
|
|
1857
1919
|
* stored, and `gradeReadAloud` produces the grade once the application holds a
|
|
1858
1920
|
* speech assessment.
|
|
1859
1921
|
*/
|
|
1860
|
-
declare const readAloudType: ActivityTypeDescriptor<ReadAloudData, ReadAloudLearnerResponse>;
|
|
1861
|
-
|
|
1922
|
+
export declare const readAloudType: ActivityTypeDescriptor<ReadAloudData, ReadAloudLearnerResponse>;
|
|
1923
|
+
//#endregion
|
|
1924
|
+
//#region src/shuffle.d.ts
|
|
1862
1925
|
/**
|
|
1863
1926
|
* Seeded, deterministic shuffling — the ONE algorithm every presentation-order
|
|
1864
1927
|
* decision in the SDK goes through: option order in a multiple-choice item,
|
|
@@ -1873,7 +1936,7 @@ declare const readAloudType: ActivityTypeDescriptor<ReadAloudData, ReadAloudLear
|
|
|
1873
1936
|
* permutation test exists so an accidental one fails loudly.
|
|
1874
1937
|
*/
|
|
1875
1938
|
/** FNV-1a hash of a string → unsigned 32-bit integer. */
|
|
1876
|
-
declare function hashSeed(input: string): number;
|
|
1939
|
+
export declare function hashSeed(input: string): number;
|
|
1877
1940
|
/**
|
|
1878
1941
|
* Which draw the Fisher–Yates step uses.
|
|
1879
1942
|
*
|
|
@@ -1905,11 +1968,16 @@ declare function hashSeed(input: string): number;
|
|
|
1905
1968
|
* is a package major — scheduled, not smuggled in. Choose v2 for new content
|
|
1906
1969
|
* where no attempt has been recorded yet.
|
|
1907
1970
|
*/
|
|
1908
|
-
type ShuffleVersion = 1 | 2;
|
|
1971
|
+
export type ShuffleVersion = 1 | 2;
|
|
1909
1972
|
/** Options for {@link seededShuffle}. */
|
|
1910
|
-
interface SeededShuffleOptions {
|
|
1911
|
-
|
|
1912
|
-
|
|
1973
|
+
export interface SeededShuffleOptions {
|
|
1974
|
+
/**
|
|
1975
|
+
* Draw algorithm — see {@link ShuffleVersion}. Left out, it is `1`; leaving
|
|
1976
|
+
* it out is deprecated since lk-core 1.3, since a 2.0 may make `2` the
|
|
1977
|
+
* default. Name it: `1` to reproduce an order already recorded, `2` for new
|
|
1978
|
+
* content.
|
|
1979
|
+
*/
|
|
1980
|
+
version?: ShuffleVersion;
|
|
1913
1981
|
}
|
|
1914
1982
|
/**
|
|
1915
1983
|
* Returns a new array holding a permutation of `items` determined entirely by
|
|
@@ -1920,8 +1988,17 @@ interface SeededShuffleOptions {
|
|
|
1920
1988
|
* (`${attemptId}:${itemId}`), so two shuffles in one attempt do not share an
|
|
1921
1989
|
* order.
|
|
1922
1990
|
*/
|
|
1923
|
-
declare function seededShuffle<T>(items: readonly T[], seed: string, options
|
|
1924
|
-
|
|
1991
|
+
export declare function seededShuffle<T>(items: readonly T[], seed: string, options: SeededShuffleOptions & {
|
|
1992
|
+
version: ShuffleVersion;
|
|
1993
|
+
}): T[];
|
|
1994
|
+
/**
|
|
1995
|
+
* @deprecated Since lk-core 1.3, name the version: `{ version: 1 }` draws
|
|
1996
|
+
* exactly what this does, `{ version: 2 }` reaches every order. A 2.0 may make
|
|
1997
|
+
* `2` the default, which would re-order what this call returns.
|
|
1998
|
+
*/
|
|
1999
|
+
export declare function seededShuffle<T>(items: readonly T[], seed: string, options?: SeededShuffleOptions): T[];
|
|
2000
|
+
//#endregion
|
|
2001
|
+
//#region src/timeline.d.ts
|
|
1925
2002
|
/**
|
|
1926
2003
|
* Reads a stored {@link MediaProgress}. Never throws: anything that is not one
|
|
1927
2004
|
* — a string, a stale shape, an object whose getters throw — answers `null`,
|
|
@@ -1933,7 +2010,7 @@ declare function seededShuffle<T>(items: readonly T[], seed: string, options?: S
|
|
|
1933
2010
|
* re-cut must not put the playhead somewhere it cannot be. Give `duration`
|
|
1934
2011
|
* once the video's metadata is known, and both positions are held inside it.
|
|
1935
2012
|
*/
|
|
1936
|
-
declare function readMediaProgress(value: unknown, duration?: number): MediaProgress | null;
|
|
2013
|
+
export declare function readMediaProgress(value: unknown, duration?: number): MediaProgress | null;
|
|
1937
2014
|
/**
|
|
1938
2015
|
* One interactive video's composed result: the scored items whose slot belongs
|
|
1939
2016
|
* to the entry, composed as one section of weight 1. A slot belongs when
|
|
@@ -1948,8 +2025,9 @@ declare function readMediaProgress(value: unknown, duration?: number): MediaProg
|
|
|
1948
2025
|
* otherwise compose nothing into a `final` result, and a refusal must
|
|
1949
2026
|
* never read as a grade.
|
|
1950
2027
|
*/
|
|
1951
|
-
declare function composeTimelineScore(entryKey: string, items: readonly ScoredItem[], policy: CompositionPolicy): AssessmentScore;
|
|
1952
|
-
|
|
2028
|
+
export declare function composeTimelineScore(entryKey: string, items: readonly ScoredItem[], policy: CompositionPolicy): AssessmentScore;
|
|
2029
|
+
//#endregion
|
|
2030
|
+
//#region src/timeline-limits.d.ts
|
|
1953
2031
|
/**
|
|
1954
2032
|
* The bounds of an interactive video — an item group with a `timeline`.
|
|
1955
2033
|
*
|
|
@@ -1963,78 +2041,80 @@ declare function composeTimelineScore(entryKey: string, items: readonly ScoredIt
|
|
|
1963
2041
|
* a read-aloud's microphone included, because every quiz pauses the video
|
|
1964
2042
|
* first.
|
|
1965
2043
|
*/
|
|
1966
|
-
declare const INTERACTIVE_VIDEO_ITEM_TYPES: readonly ["multiple-choice", "fill-in-the-blanks", "gap-select", "dictation", "read-aloud"];
|
|
2044
|
+
export declare const INTERACTIVE_VIDEO_ITEM_TYPES: readonly ["multiple-choice", "fill-in-the-blanks", "gap-select", "dictation", "read-aloud"];
|
|
1967
2045
|
/** One of {@link INTERACTIVE_VIDEO_ITEM_TYPES}. */
|
|
1968
|
-
type InteractiveVideoItemType = (typeof INTERACTIVE_VIDEO_ITEM_TYPES)[number];
|
|
2046
|
+
export type InteractiveVideoItemType = (typeof INTERACTIVE_VIDEO_ITEM_TYPES)[number];
|
|
1969
2047
|
/** Whether `type` is one of the item types an interactive video may present. */
|
|
1970
|
-
declare function isInteractiveVideoItemType(type: unknown): type is InteractiveVideoItemType;
|
|
2048
|
+
export declare function isInteractiveVideoItemType(type: unknown): type is InteractiveVideoItemType;
|
|
1971
2049
|
/** The most quizzes one video may hold. */
|
|
1972
|
-
declare const TIMELINE_MAX_QUIZZES = 100;
|
|
2050
|
+
export declare const TIMELINE_MAX_QUIZZES = 100;
|
|
1973
2051
|
/**
|
|
1974
2052
|
* The most questions one interactive video may hold, across all its quizzes.
|
|
1975
2053
|
* The player keeps every one of them mounted, so an answer survives the
|
|
1976
2054
|
* learner rewinding past its quiz.
|
|
1977
2055
|
*/
|
|
1978
|
-
declare const TIMELINE_MAX_ITEMS = 200;
|
|
2056
|
+
export declare const TIMELINE_MAX_ITEMS = 200;
|
|
1979
2057
|
/** The most chapters one video may hold. */
|
|
1980
|
-
declare const TIMELINE_MAX_CHAPTERS = 100;
|
|
2058
|
+
export declare const TIMELINE_MAX_CHAPTERS = 100;
|
|
1981
2059
|
/** The longest quiz or chapter title, in UTF-16 units. A title sits on one line of the player. */
|
|
1982
|
-
declare const TIMELINE_MAX_TITLE_LENGTH = 120;
|
|
1983
|
-
|
|
2060
|
+
export declare const TIMELINE_MAX_TITLE_LENGTH = 120;
|
|
2061
|
+
//#endregion
|
|
2062
|
+
//#region src/types/theme.d.ts
|
|
1984
2063
|
/**
|
|
1985
2064
|
* All CSS custom property tokens consumed by learning-kit components.
|
|
1986
2065
|
* Every key maps to a `--lk-*` CSS variable name; every value is a CSS value string.
|
|
1987
2066
|
* Pass a `Partial<ThemeTokens>` to `ThemeProvider` to override individual tokens.
|
|
1988
2067
|
*/
|
|
1989
2068
|
interface ThemeTokens {
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2069
|
+
'--lk-color-primary': string;
|
|
2070
|
+
'--lk-color-primary-hover': string;
|
|
2071
|
+
'--lk-color-surface': string;
|
|
2072
|
+
'--lk-color-surface-raised': string;
|
|
2073
|
+
'--lk-color-border': string;
|
|
2074
|
+
'--lk-color-text': string;
|
|
2075
|
+
'--lk-color-text-muted': string;
|
|
2076
|
+
'--lk-color-success': string;
|
|
2077
|
+
'--lk-color-error': string;
|
|
2078
|
+
'--lk-color-warning': string;
|
|
2079
|
+
'--lk-color-focus-ring': string;
|
|
2080
|
+
/**
|
|
2081
|
+
* The accent a video player draws on its own dark chrome: the played part
|
|
2082
|
+
* of the progress bar, quiz markers, the centre play button. Optional, so a
|
|
2083
|
+
* theme written before it existed still type-checks; the default is white,
|
|
2084
|
+
* which reads on any video. Set it to a brand colour to match a product.
|
|
2085
|
+
*/
|
|
2086
|
+
'--lk-color-media-accent'?: string;
|
|
2087
|
+
/**
|
|
2088
|
+
* The interactive video's drawn captions. Optional like the accent above, so
|
|
2089
|
+
* a theme written before them still type-checks. The primary line's colour;
|
|
2090
|
+
* the second language's colour, which must clear 4.5:1 on the caption box;
|
|
2091
|
+
* the second line's size as a share of the first (a number, e.g. `0.85`);
|
|
2092
|
+
* and the space between the two lines. The second line differs from the
|
|
2093
|
+
* first by position and size as well as colour: colour alone would fail
|
|
2094
|
+
* WCAG 1.4.1.
|
|
2095
|
+
*/
|
|
2096
|
+
'--lk-iv-caption-color'?: string;
|
|
2097
|
+
'--lk-iv-caption-secondary-color'?: string;
|
|
2098
|
+
'--lk-iv-caption-secondary-scale'?: string;
|
|
2099
|
+
'--lk-iv-caption-gap'?: string;
|
|
2100
|
+
'--lk-spacing-xs': string;
|
|
2101
|
+
'--lk-spacing-sm': string;
|
|
2102
|
+
'--lk-spacing-md': string;
|
|
2103
|
+
'--lk-spacing-lg': string;
|
|
2104
|
+
'--lk-spacing-xl': string;
|
|
2105
|
+
'--lk-font-family-base': string;
|
|
2106
|
+
'--lk-font-size-sm': string;
|
|
2107
|
+
'--lk-font-size-base': string;
|
|
2108
|
+
'--lk-font-size-lg': string;
|
|
2109
|
+
'--lk-font-weight-normal': string;
|
|
2110
|
+
'--lk-font-weight-bold': string;
|
|
2111
|
+
'--lk-line-height-base': string;
|
|
2112
|
+
'--lk-radius-sm': string;
|
|
2113
|
+
'--lk-radius-base': string;
|
|
2114
|
+
'--lk-radius-lg': string;
|
|
2115
|
+
'--lk-transition-fast': string;
|
|
2116
|
+
'--lk-transition-base': string;
|
|
2038
2117
|
}
|
|
2039
|
-
|
|
2040
|
-
export {
|
|
2118
|
+
//#endregion
|
|
2119
|
+
export { type ActivityAiPermissions, type ActivityData, type ActivityDataMap, type ActivityFeedback, type ActivityMedia, type ActivityResult, type ActivityType, type ActivityTypeAuthoring, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, type AiActivityInput, type AiBlankFact, type AiCoaching, type AiCoachingRequest, type AiCoachingResult, type AiCoachingWord, type AiCriterionJudgement, type AiCritique, type AiCritiqueField, type AiCritiqueFinding, type AiCritiqueFindingResult, type AiCritiqueKind, type AiCritiqueRequest, type AiCritiqueResult, type AiDictationFacts, type AiDraftCaption, type AiDraftProblem, type AiDraftSettings, type AiDraftSource, type AiDraftType, type AiDrafts, type AiDraftsCall, type AiDraftsRequest, type AiDraftsRun, type AiExplanationRequest, type AiFeature, type AiFillInTheBlanksFacts, type AiGapFact, type AiGapSelectFacts, type AiGeneratedDraft, type AiGrade, type AiGroupInput, type AiHintRequest, type AiItemFacts, type AiMaterialFacts, type AiMultipleChoiceFacts, type AiOptionFact, type AiProvenance, type AiReadingFacts, type AiReadingWordFact, type AiRefusal, type AiRubricCriterionFact, type AiSoundFact, type AiSupportedActivityType, type AiTextResult, type AiVerdict, type AiVideoDraft, type AiWordFact, type AiWritingCorrection, type AiWritingFacts, type AiWritingFeedback, type AiWritingFeedbackRequest, type AiWritingFeedbackResult, type AnsweredStatementParams, type AssessmentScore, type AssessmentSectionInput, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptState, type Band, type BlankConfig, type BuiltInActivityType, type CompletedStatementParams, type CompositionPolicy, type CriterionScore, DEFAULT_ITEM_SCORING_POLICY, DEFAULT_PASS_THRESHOLD, DICTATION_MAX_ACCEPTED_TRANSCRIPTS, DICTATION_MAX_EQUIVALENCES, DICTATION_MAX_EQUIVALENCE_LENGTH, DICTATION_MAX_TEXT_LENGTH, DICTATION_MAX_TRANSCRIPT_LENGTH, type DeferredReason, type DeferredScoringPartial, type DeliveryPolicy, type DeliveryPolicyIssue, type DictationAlignment, type DictationCharOp, type DictationData, type DictationEquivalence, type DictationLearnerResponse, type DictationReference, type DictationSlowMedia, type DictationTolerance, type DictationWordAlignment, type DraftComplete, type DraftContext, type DraftIssue, type DraftNotComplete, type DraftSeverity, type DraftValidationResult, EvaluateOptions, type FieldPolicy, type FillInTheBlanksData, type FillInTheBlanksLearnerResponse, type GapSelectBank, type GapSelectChoice, type GapSelectData, type GapSelectGap, type GapSelectLearnerResponse, type GradeReadAloudOptions, type GradeRecord, type Grader, type GraderKind, type GraderUsage, type GradingState, ITEM_SCORING_MAX_RETRIES, type InlineCorrection, type InteractionEvent, type InteractionKind, type ItemFinding, type ItemFindingSeverity, type ItemGroup, type ItemOutcome, type ItemScoringCount, type ItemScoringPolicy, type ItemScoringPolicyIssue, ItemTriesOutcome, type ItemTriesScore, type ItemTry, type ItemTryScore, type LearnerResponse, type LearnerResponseMap, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, type MediaPlaybackPolicy, type MediaProgress, type MediaTimeline, type MediaTrack, type MultipleChoiceData, type MultipleChoiceLearnerResponse, type MultipleChoiceOption, type MultipleChoiceOptionMedia, type NativeControlHint, type PartialScoringResult, type PassFailureReason, READ_ALOUD_MAX_DIMENSION_WEIGHT, READ_ALOUD_MAX_REFERENCE_LENGTH, READ_ALOUD_MAX_SECONDS, READ_ALOUD_MAX_TAKES, type ReadAloudData, type ReadAloudDimension, type ReadAloudDimensionWeight, type ReadAloudLearnerResponse, type ReadAloudSlowMedia, type ReadAloudWordAlignment, type ReadAloudWordState, type RecordingBounds, type RecordingRef, type RedactedActivity, type RedactedBlankConfig, type RedactedDictationData, type RedactedDictationSlowMedia, type RedactedFillInTheBlanksData, type RedactedGapSelectBank, type RedactedGapSelectChoice, type RedactedGapSelectData, type RedactedGapSelectGap, type RedactedMultipleChoiceData, type RedactedMultipleChoiceOption, type RedactedMultipleChoiceOptionMedia, type RedactedReadAloudData, type RedactedStimulus, type RedactedWrittenResponseData, type RegisteredActivityTypeDescriptor, type ResolvedDeliveryPolicy, type ResolvedItemScoringPolicy, type ResponseDiffEntry, type RoundingMode, type RoundingPolicy, SPEECH_ASSESSMENT_MAX_WORDS, type ScoredItem, type ScoringDetail, ScoringOptions, type ScoringOutcome, type ScoringResult, type SectionScore, type Sensitivity, type SequenceEntry, type SequenceSlot, type SequenceSlotGroup, type SpeechAssessment, type SpeechMeasurement, type SpeechPhoneme, type SpeechPhonemeCandidate, type SpeechPlausibilityPolicy, type SpeechSyllable, type SpeechUnscorable, type SpeechUnscorableCode, type SpeechWord, type SpeechWordError, type StandardSchemaV1, type Stimulus, type StimulusKind, type SubmittedStatementParams, type TextMatchPolicy, type TextMatchResult, type ThemeTokens, type TimelineChapter, type TimelineCue, type ValidationError, type ValidationResult, type WavInspection, type WavInspectionPolicy, type WrittenResponseData, type WrittenResponseLearnerResponse, type WrittenResponseRubric, type WrittenResponseRubricCriterion, type XAPIActor, type XAPIConfig, type XAPIContext, type XAPIContextActivities, type XAPIError, type XAPIInteractionType, type XAPIObject, type XAPIObjectParams, type XAPIResult, type XAPIScore, type XAPIStatement, type XAPIStatementParams, XAPIVerb, type XAPIVerbKey, type XAPIVerbObject, XAPI_VERB_DISPLAY, alignDictation, alignReadAloud, classifyBand, composeAssessmentScore, computePassThreshold, dictationJsonSchema, dictationReferenceWords, diffDictationChars, evaluate, evaluateTries, fillInTheBlanksJsonSchema, gapSelectJsonSchema, gradeReadAloud, gte, inspectWav, itemGroupJsonSchema, jsonSchemaFor, levenshteinDistance, matchText, multipleChoiceJsonSchema, outcomeFromUnscorable, readAloudJsonSchema, resolveItemScoringPolicy, roundGrade, score, scoreTries, stimulusJsonSchema, validateActivity, validateItemGroup, validateItemScoringPolicy, validateMedia, validateOptionMedia, validateSpeechAssessment, validateXAPIStatement, writtenResponseJsonSchema, xAPIBuilder, xapiDefinitionFor };
|
|
2120
|
+
//# sourceMappingURL=index.d.ts.map
|