@intellectif/lk-core 1.4.0 → 1.6.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/README.md +2 -0
  3. package/dist/ai-check.cjs +175 -17
  4. package/dist/ai-check.cjs.map +1 -1
  5. package/dist/ai-check.d.cts +13 -5
  6. package/dist/ai-check.d.cts.map +1 -1
  7. package/dist/ai-check.d.ts +13 -5
  8. package/dist/ai-check.d.ts.map +1 -1
  9. package/dist/ai-check.js +175 -17
  10. package/dist/ai-check.js.map +1 -1
  11. package/dist/{ai-CnmLPMzd.d.ts → ai-i3jwXnpX.d.cts} +242 -7
  12. package/dist/ai-i3jwXnpX.d.cts.map +1 -0
  13. package/dist/{ai-CnmLPMzd.d.cts → ai-i3jwXnpX.d.ts} +242 -7
  14. package/dist/ai-i3jwXnpX.d.ts.map +1 -0
  15. package/dist/{ai-writing-G6tnCGzw.cjs → ai-writing-C4YRVrFi.cjs} +683 -72
  16. package/dist/ai-writing-C4YRVrFi.cjs.map +1 -0
  17. package/dist/{ai-writing-CPpH9Qxq.js → ai-writing-OJ5m_1EB.js} +663 -88
  18. package/dist/ai-writing-OJ5m_1EB.js.map +1 -0
  19. package/dist/{index-BqMXWuNC.d.cts → index--U7hHV0s.d.cts} +2 -2
  20. package/dist/{index-BqMXWuNC.d.cts.map → index--U7hHV0s.d.cts.map} +1 -1
  21. package/dist/{index-B54baFUA.d.ts → index-CFRgZLhH.d.cts} +45 -12
  22. package/dist/index-CFRgZLhH.d.cts.map +1 -0
  23. package/dist/{index-CVWvymVb.d.ts → index-DeD8EI1D.d.ts} +327 -3
  24. package/dist/index-DeD8EI1D.d.ts.map +1 -0
  25. package/dist/{index-CcHDTxIZ.d.ts → index-Dj92T76o.d.ts} +2 -2
  26. package/dist/{index-CcHDTxIZ.d.ts.map → index-Dj92T76o.d.ts.map} +1 -1
  27. package/dist/{index-BAfEHCnD.d.cts → index-Uh1u57yq.d.cts} +327 -3
  28. package/dist/index-Uh1u57yq.d.cts.map +1 -0
  29. package/dist/{index-2nigSf4N.d.cts → index-WBHSrIUU.d.ts} +45 -12
  30. package/dist/index-WBHSrIUU.d.ts.map +1 -0
  31. package/dist/index.cjs +88 -131
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +217 -95
  34. package/dist/index.d.cts.map +1 -1
  35. package/dist/index.d.ts +217 -95
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +60 -118
  38. package/dist/index.js.map +1 -1
  39. package/dist/{item-group-DXiR8nOr.js → item-group-BbvvH_Ob.js} +3 -2
  40. package/dist/item-group-BbvvH_Ob.js.map +1 -0
  41. package/dist/{item-group-DroFXgLb.cjs → item-group-CQRbb8Rx.cjs} +3 -2
  42. package/dist/item-group-CQRbb8Rx.cjs.map +1 -0
  43. package/dist/{registry-Dsx9mNsS.js → registry-B23o9UWh.js} +218 -21
  44. package/dist/registry-B23o9UWh.js.map +1 -0
  45. package/dist/{registry-DVi0LR_i.cjs → registry-Ih5n4PVZ.cjs} +265 -20
  46. package/dist/registry-Ih5n4PVZ.cjs.map +1 -0
  47. package/dist/{schemas-DVbAOrtd.cjs → schemas-Q2dyOgc2.cjs} +77 -14
  48. package/dist/schemas-Q2dyOgc2.cjs.map +1 -0
  49. package/dist/{schemas-Bdw0nGPo.js → schemas-yId-bJhD.js} +72 -15
  50. package/dist/schemas-yId-bJhD.js.map +1 -0
  51. package/dist/schemas.cjs +5 -2
  52. package/dist/schemas.d.cts +2 -2
  53. package/dist/schemas.d.ts +2 -2
  54. package/dist/schemas.js +4 -3
  55. package/dist/{scoring-BZqUkuDF.js → scoring-CLMdk8i9.js} +657 -3
  56. package/dist/scoring-CLMdk8i9.js.map +1 -0
  57. package/dist/{scoring-B2_HEhMT.cjs → scoring-CaPS6q8b.cjs} +722 -2
  58. package/dist/scoring-CaPS6q8b.cjs.map +1 -0
  59. package/dist/scoring.cjs +8 -2
  60. package/dist/scoring.d.cts +3 -3
  61. package/dist/scoring.d.ts +3 -3
  62. package/dist/scoring.js +3 -3
  63. package/dist/{xapi-DNzkSJ0S.cjs → xapi-BX0hvRRB.cjs} +2 -2
  64. package/dist/{xapi-DNzkSJ0S.cjs.map → xapi-BX0hvRRB.cjs.map} +1 -1
  65. package/dist/{xapi-CMTph7wG.js → xapi-Cdk9fTvV.js} +2 -2
  66. package/dist/{xapi-CMTph7wG.js.map → xapi-Cdk9fTvV.js.map} +1 -1
  67. package/dist/xapi.cjs +1 -1
  68. package/dist/xapi.d.cts +1 -1
  69. package/dist/xapi.d.ts +1 -1
  70. package/dist/xapi.js +1 -2
  71. package/package.json +2 -2
  72. package/vectors/README.md +24 -1
  73. package/vectors/scoring.json +18182 -1
  74. package/dist/ai-CnmLPMzd.d.cts.map +0 -1
  75. package/dist/ai-CnmLPMzd.d.ts.map +0 -1
  76. package/dist/ai-writing-CPpH9Qxq.js.map +0 -1
  77. package/dist/ai-writing-G6tnCGzw.cjs.map +0 -1
  78. package/dist/index-2nigSf4N.d.cts.map +0 -1
  79. package/dist/index-B54baFUA.d.ts.map +0 -1
  80. package/dist/index-BAfEHCnD.d.cts.map +0 -1
  81. package/dist/index-CVWvymVb.d.ts.map +0 -1
  82. package/dist/item-group-DXiR8nOr.js.map +0 -1
  83. package/dist/item-group-DroFXgLb.cjs.map +0 -1
  84. package/dist/registry-DVi0LR_i.cjs.map +0 -1
  85. package/dist/registry-Dsx9mNsS.js.map +0 -1
  86. package/dist/schemas-Bdw0nGPo.js.map +0 -1
  87. package/dist/schemas-DVbAOrtd.cjs.map +0 -1
  88. package/dist/scoring-B2_HEhMT.cjs.map +0 -1
  89. package/dist/scoring-BZqUkuDF.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,82 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_registry = require("./registry-DVi0LR_i.cjs");
3
- const require_ai_writing = require("./ai-writing-G6tnCGzw.cjs");
4
- const require_scoring = require("./scoring-B2_HEhMT.cjs");
5
- const require_item_group = require("./item-group-DroFXgLb.cjs");
6
- const require_schemas = require("./schemas-DVbAOrtd.cjs");
7
- const require_xapi = require("./xapi-DNzkSJ0S.cjs");
8
- //#region src/content-hash.ts
9
- /**
10
- * Content fingerprinting — "is this the same content the learner was served?"
11
- *
12
- * A recorded attempt outlives the content it was taken against. Papers get
13
- * corrected, a typo is fixed, an option is reworded — and six months later a
14
- * remark, an appeal, or a per-item analysis is run against content that is no
15
- * longer what the learner saw. Nothing warns anybody, because the ids all still
16
- * match. A fingerprint stored with the attempt turns that silent drift into a
17
- * question somebody can answer.
18
- */
19
- /**
20
- * Deterministic JSON: object keys sorted, arrays left in order, `undefined`
21
- * omitted from objects (matching `JSON.stringify`) and rendered as `null`
22
- * inside arrays.
23
- *
24
- * Key order is the whole point. Two objects that differ only in the order
25
- * their keys happened to be written are the SAME content, and a fingerprint
26
- * that disagreed would raise a false alarm every time a payload made a
27
- * round-trip through a different serializer.
28
- */
29
- function canonicalJson(value, seen = /* @__PURE__ */ new Set()) {
30
- if (value === null) return "null";
31
- if (typeof value === "number") return Number.isFinite(value) ? JSON.stringify(value === 0 ? 0 : value) : `"#${String(value)}"`;
32
- if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
33
- if (typeof value === "bigint") return `"#${value.toString()}n"`;
34
- if (typeof value === "object") {
35
- if (seen.has(value)) throw new Error("canonicalJson: the value contains a circular reference and cannot be fingerprinted.");
36
- seen.add(value);
37
- try {
38
- if (Array.isArray(value)) return `[${value.map((element) => element === void 0 ? "null" : canonicalJson(element, seen)).join(",")}]`;
39
- const source = value;
40
- const parts = [];
41
- for (const key of Object.keys(source).sort()) {
42
- const entry = source[key];
43
- if (entry === void 0) continue;
44
- parts.push(`${JSON.stringify(key)}:${canonicalJson(entry, seen)}`);
45
- }
46
- return `{${parts.join(",")}}`;
47
- } finally {
48
- seen.delete(value);
49
- }
50
- }
51
- return "null";
52
- }
53
- const FNV_OFFSET = 14695981039346656037n;
54
- const FNV_PRIME = 1099511628211n;
55
- const MASK64 = (1n << 64n) - 1n;
56
- /**
57
- * FNV-1a over the UTF-8 bytes of `input`, as 16 lowercase hex digits.
58
- *
59
- * **This is a change-detection fingerprint, not a tamper-evident signature.**
60
- * It is deterministic across runtimes and dependency-free, which is what makes
61
- * it usable in a stored grade record — but an adversary who can edit content
62
- * can also, with effort, preserve the fingerprint. If you need the stronger
63
- * property, sign the plan with a key the content author does not hold; this
64
- * exists to catch honest edits, which is what actually happens.
65
- */
66
- function fingerprint(input) {
67
- const bytes = new TextEncoder().encode(input);
68
- let hash = FNV_OFFSET;
69
- for (const byte of bytes) hash = (hash ^ BigInt(byte)) * FNV_PRIME & MASK64;
70
- return hash.toString(16).padStart(16, "0");
71
- }
72
- /**
73
- * Fingerprints any JSON-serialisable value through {@link canonicalJson}, so
74
- * the result depends on the content and not on how it was written.
75
- */
76
- function contentHash(value) {
77
- return fingerprint(canonicalJson(value));
78
- }
79
- //#endregion
2
+ const require_registry = require("./registry-Ih5n4PVZ.cjs");
3
+ const require_ai_writing = require("./ai-writing-C4YRVrFi.cjs");
4
+ const require_scoring = require("./scoring-CaPS6q8b.cjs");
5
+ const require_item_group = require("./item-group-CQRbb8Rx.cjs");
6
+ const require_schemas = require("./schemas-Q2dyOgc2.cjs");
7
+ const require_xapi = require("./xapi-BX0hvRRB.cjs");
80
8
  //#region src/delivery.ts
81
9
  /**
82
10
  * The policy that restricts nothing: every setting `true`. It is what an absent
@@ -232,44 +160,6 @@ function validateDeliveryPolicy(policy) {
232
160
  };
233
161
  }
234
162
  //#endregion
235
- //#region src/shuffle.ts
236
- /**
237
- * Seeded, deterministic shuffling — the ONE algorithm every presentation-order
238
- * decision in the SDK goes through: option order in a multiple-choice item,
239
- * item order inside an item group, entry order in a sequence. A server and a
240
- * client holding the same seed derive the same order, and an order recorded
241
- * against an attempt can be rebuilt later from nothing but its seed.
242
- *
243
- * STABILITY: the hash and the generator are part of the wire contract. A
244
- * stored attempt may hold only a seed and rely on this function to reproduce
245
- * the order it presented; changing either would silently re-order every
246
- * recorded attempt. Any change here is a package major, and the pinned
247
- * permutation test exists so an accidental one fails loudly.
248
- */
249
- /** FNV-1a hash of a string → unsigned 32-bit integer. */
250
- function hashSeed(input) {
251
- let h = 2166136261;
252
- for (let i = 0; i < input.length; i += 1) {
253
- h ^= input.charCodeAt(i);
254
- h = Math.imul(h, 16777619) >>> 0;
255
- }
256
- return h;
257
- }
258
- /** LCG-driven Fisher–Yates over a 32-bit seed; returns a permutation (no loss, no duplicate). */
259
- function shuffleWithSeed(items, seed, version) {
260
- const out = [...items];
261
- let s = seed >>> 0 || 1;
262
- for (let i = out.length - 1; i > 0; i -= 1) {
263
- s = Math.imul(s, 1664525) + 1013904223 >>> 0;
264
- const j = version === 2 ? Math.floor(s / 4294967296 * (i + 1)) : s % (i + 1);
265
- [out[i], out[j]] = [out[j], out[i]];
266
- }
267
- return out;
268
- }
269
- function seededShuffle(items, seed, options = {}) {
270
- return shuffleWithSeed(items, hashSeed(seed), options.version ?? 1);
271
- }
272
- //#endregion
273
163
  //#region src/item-group.ts
274
164
  /** Narrows a sequence entry to an item group. */
275
165
  function isItemGroup(entry) {
@@ -342,7 +232,7 @@ function flattenSequence(entries, options = {}) {
342
232
  entry,
343
233
  entryIndex
344
234
  }));
345
- const ordered = shuffleEntries ? seededShuffle(authored, `${seed}:entries`, { version: 1 }) : authored;
235
+ const ordered = shuffleEntries ? require_scoring.seededShuffle(authored, `${seed}:entries`, { version: 1 }) : authored;
346
236
  const slots = [];
347
237
  for (const { entry, entryIndex } of ordered) {
348
238
  const entryKey = keyOf(entry) ?? String(entryIndex);
@@ -361,7 +251,7 @@ function flattenSequence(entries, options = {}) {
361
251
  item,
362
252
  itemIndex
363
253
  }));
364
- const presented = timeline !== void 0 ? inQuizOrder(items, timeline) : entry.shuffle === "within-group" ? seededShuffle(items, `${seed}:group:${entry.id}`, { version: 1 }) : items;
254
+ const presented = timeline !== void 0 ? inQuizOrder(items, timeline) : entry.shuffle === "within-group" ? require_scoring.seededShuffle(items, `${seed}:group:${entry.id}`, { version: 1 }) : items;
365
255
  const size = presented.length;
366
256
  presented.forEach(({ item, itemIndex }, position) => {
367
257
  const cue = timeline?.cues.find((candidate) => candidate.itemIds.includes(item.id));
@@ -579,11 +469,11 @@ function planSlot(slot, points) {
579
469
  activityId: slot.activity.id,
580
470
  activityType: slot.activity.type,
581
471
  points,
582
- contentHash: contentHash(contentOf(slot.activity)),
472
+ contentHash: require_scoring.contentHash(contentOf(slot.activity)),
583
473
  ...slot.group !== void 0 ? { group: {
584
474
  id: slot.group.id,
585
475
  ...slot.group.title !== void 0 ? { title: slot.group.title } : {},
586
- stimulusHash: contentHash(slot.group.stimulus),
476
+ stimulusHash: require_scoring.contentHash(slot.group.stimulus),
587
477
  ...slot.group.cue !== void 0 ? { cue: {
588
478
  id: slot.group.cue.id,
589
479
  at: slot.group.cue.at,
@@ -624,7 +514,7 @@ function planAttempt(entries, options = {}) {
624
514
  planVersion: "1.0",
625
515
  ...seed !== void 0 ? { seed } : {},
626
516
  ...shuffleEntries !== void 0 ? { shuffleEntries } : {},
627
- planHash: contentHash(delivery === void 0 && scoring === void 0 ? planned : {
517
+ planHash: require_scoring.contentHash(delivery === void 0 && scoring === void 0 ? planned : {
628
518
  slots: planned,
629
519
  ...delivery !== void 0 ? { delivery } : {},
630
520
  ...scoring !== void 0 ? { scoring } : {}
@@ -669,14 +559,14 @@ function verifyAttemptPlan(plan, current) {
669
559
  const changedCueSlotIds = [];
670
560
  const changedPointsSlotIds = [];
671
561
  const reorderedSlotIds = [];
672
- const deliveryChanged = contentHash(plan.delivery ?? null) !== contentHash(current.delivery ?? null);
673
- const scoringChanged = contentHash(plan.scoring ?? null) !== contentHash(current.scoring ?? null);
562
+ const deliveryChanged = require_scoring.contentHash(plan.delivery ?? null) !== require_scoring.contentHash(current.delivery ?? null);
563
+ const scoringChanged = require_scoring.contentHash(plan.scoring ?? null) !== require_scoring.contentHash(current.scoring ?? null);
674
564
  for (const slot of plan.slots) {
675
565
  const now = after.get(slot.slotId);
676
566
  if (now === void 0) continue;
677
567
  if (now.contentHash !== slot.contentHash) changedSlotIds.push(slot.slotId);
678
568
  if (now.group?.stimulusHash !== slot.group?.stimulusHash) changedStimulusSlotIds.push(slot.slotId);
679
- if (contentHash(now.group?.cue ?? null) !== contentHash(slot.group?.cue ?? null)) changedCueSlotIds.push(slot.slotId);
569
+ if (require_scoring.contentHash(now.group?.cue ?? null) !== require_scoring.contentHash(slot.group?.cue ?? null)) changedCueSlotIds.push(slot.slotId);
680
570
  if (now.points !== slot.points) changedPointsSlotIds.push(slot.slotId);
681
571
  if (now.index !== slot.index) reorderedSlotIds.push(slot.slotId);
682
572
  }
@@ -877,7 +767,7 @@ function diffResponses(before, after) {
877
767
  });
878
768
  continue;
879
769
  }
880
- if (canonicalJson(from) !== canonicalJson(to)) entries.push({
770
+ if (require_scoring.canonicalJson(from) !== require_scoring.canonicalJson(to)) entries.push({
881
771
  slotId,
882
772
  change: "changed",
883
773
  ...from !== void 0 ? { before: from } : {},
@@ -925,6 +815,8 @@ function redactValue(value, policy, reveal) {
925
815
  if (keepField(classification, reveal)) output[key] = fieldValue;
926
816
  continue;
927
817
  }
818
+ const guard = require_registry.guardOf(classification);
819
+ if (guard !== void 0 && !guard(fieldValue)) continue;
928
820
  const nested = redactValue(fieldValue, classification, reveal);
929
821
  if (nested !== void 0 && !isEmptyObject(nested)) output[key] = nested;
930
822
  }
@@ -1015,7 +907,8 @@ const ITEM_GROUP_FIELD_POLICY = {
1015
907
  media: require_registry.MEDIA_FIELD_POLICY,
1016
908
  locale: "public",
1017
909
  attribution: "public",
1018
- transcript: "author-only"
910
+ transcript: "author-only",
911
+ script: "author-only"
1019
912
  },
1020
913
  timeline: {
1021
914
  cues: {
@@ -1102,6 +995,55 @@ function assertRedactedItemGroup(data) {
1102
995
  }
1103
996
  });
1104
997
  }
998
+ /** A deep copy of plain data with every field its policy calls `author-only` left out. */
999
+ function withoutAuthorOnlyValue(value, policy) {
1000
+ if (Array.isArray(value)) return value.map((element) => withoutAuthorOnlyValue(element, policy));
1001
+ if (value === null || typeof value !== "object") return value;
1002
+ const output = {};
1003
+ for (const [key, field] of Object.entries(value)) {
1004
+ const classification = policy?.[key];
1005
+ if (classification === "author-only") continue;
1006
+ output[key] = withoutAuthorOnlyValue(field, classification === void 0 || isSensitivity(classification) ? void 0 : classification);
1007
+ }
1008
+ return output;
1009
+ }
1010
+ /** The policy an activity is stripped under; the same one `redact()` reads. */
1011
+ function policyOf(type) {
1012
+ const descriptor = typeof type === "string" ? require_registry.getActivityTypeDescriptor(type) : void 0;
1013
+ if (descriptor === void 0) throw new require_registry.UnknownActivityTypeError(String(type));
1014
+ if (descriptor.fieldPolicy === void 0) throw new Error(`Activity type "${descriptor.type}" has no fieldPolicy; withoutAuthorOnly() cannot tell which of its fields are author-only.`);
1015
+ return descriptor.fieldPolicy;
1016
+ }
1017
+ /**
1018
+ * A copy of an activity or an item group without its `author-only` fields:
1019
+ * a recording's `transcript` and `script`, on an item's media, a
1020
+ * multiple-choice option's recording, a stimulus or its media. Everything
1021
+ * else is kept as stored, the answer key and your own fields included, and
1022
+ * the copy is not marked redacted, so it scores exactly as the stored item.
1023
+ *
1024
+ * For practice an app scores in the browser, where the learner may hold the
1025
+ * key but not the author's material. It is NOT a learner-safe projection: an
1026
+ * exam, or anything a learner must not be able to answer from the payload,
1027
+ * goes through {@link redact} / {@link redactItemGroup}, whose output a scorer
1028
+ * refuses.
1029
+ *
1030
+ * ```ts
1031
+ * res.json(withoutAuthorOnly(practiceItem));
1032
+ * ```
1033
+ *
1034
+ * @throws UnknownActivityTypeError when an activity's type is not registered,
1035
+ * and Error when it declares no `fieldPolicy`.
1036
+ */
1037
+ function withoutAuthorOnly(entry) {
1038
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) throw new TypeError("withoutAuthorOnly: expects an activity or an item group.");
1039
+ const record = entry;
1040
+ if (record.type !== "item-group") return withoutAuthorOnlyValue(entry, policyOf(record.type));
1041
+ const { items, ...container } = record;
1042
+ return {
1043
+ ...withoutAuthorOnlyValue(container, ITEM_GROUP_FIELD_POLICY),
1044
+ ...Array.isArray(items) ? { items: items.map((item) => withoutAuthorOnlyValue(item, policyOf(item?.type))) } : items !== void 0 ? { items } : {}
1045
+ };
1046
+ }
1105
1047
  //#endregion
1106
1048
  //#region src/timeline.ts
1107
1049
  /**
@@ -1165,6 +1107,7 @@ exports.AI_CRITIQUE_MAX_FINDINGS = require_ai_writing.AI_CRITIQUE_MAX_FINDINGS;
1165
1107
  exports.AI_DRAFTS_MAX_COUNT = require_ai_writing.AI_DRAFTS_MAX_COUNT;
1166
1108
  exports.AI_DRAFTS_MAX_REPAIRS = require_ai_writing.AI_DRAFTS_MAX_REPAIRS;
1167
1109
  exports.AI_EXPLANATION_TYPES = require_ai_writing.AI_EXPLANATION_TYPES;
1110
+ exports.AI_GRADING_PROBABILITY_TOLERANCE = require_ai_writing.AI_GRADING_PROBABILITY_TOLERANCE;
1168
1111
  exports.AI_HINT_TYPES = require_ai_writing.AI_HINT_TYPES;
1169
1112
  exports.AI_MATERIAL_MAX_LENGTH = require_ai_writing.AI_MATERIAL_MAX_LENGTH;
1170
1113
  exports.AI_TEXT_MAX_LENGTH = require_ai_writing.AI_TEXT_MAX_LENGTH;
@@ -1188,6 +1131,7 @@ exports.READ_ALOUD_MAX_REFERENCE_LENGTH = require_registry.READ_ALOUD_MAX_REFERE
1188
1131
  exports.READ_ALOUD_MAX_SECONDS = require_registry.READ_ALOUD_MAX_SECONDS;
1189
1132
  exports.READ_ALOUD_MAX_TAKES = require_registry.READ_ALOUD_MAX_TAKES;
1190
1133
  exports.RedactedScoringError = require_registry.RedactedScoringError;
1134
+ exports.SCRIPT_MAX_TURNS = require_registry.SCRIPT_MAX_TURNS;
1191
1135
  exports.SPEECH_ASSESSMENT_MAX_WORDS = require_registry.SPEECH_ASSESSMENT_MAX_WORDS;
1192
1136
  exports.TIMELINE_MAX_CHAPTERS = require_item_group.TIMELINE_MAX_CHAPTERS;
1193
1137
  exports.TIMELINE_MAX_ITEMS = require_item_group.TIMELINE_MAX_ITEMS;
@@ -1203,6 +1147,7 @@ exports.aiDraftsRepairRequest = require_ai_writing.aiDraftsRepairRequest;
1203
1147
  exports.aiDraftsRequest = require_ai_writing.aiDraftsRequest;
1204
1148
  exports.aiExplanationRequest = require_ai_writing.aiExplanationRequest;
1205
1149
  exports.aiGradeOf = require_ai_writing.aiGradeOf;
1150
+ exports.aiGradingRequest = require_ai_writing.aiGradingRequest;
1206
1151
  exports.aiHintRequest = require_ai_writing.aiHintRequest;
1207
1152
  exports.aiSupports = require_ai_writing.aiSupports;
1208
1153
  exports.aiWritingFeedbackRequest = require_ai_writing.aiWritingFeedbackRequest;
@@ -1211,11 +1156,13 @@ exports.alignReadAloud = require_scoring.alignReadAloud;
1211
1156
  exports.assertRedacted = assertRedacted;
1212
1157
  exports.assertRedactedItemGroup = assertRedactedItemGroup;
1213
1158
  exports.buildAiFacts = require_ai_writing.buildAiFacts;
1214
- exports.canonicalJson = canonicalJson;
1159
+ exports.calibrationReport = require_scoring.calibrationReport;
1160
+ exports.canonicalJson = require_scoring.canonicalJson;
1215
1161
  exports.checkAiCoaching = require_ai_writing.checkAiCoaching;
1216
1162
  exports.checkAiCritique = require_ai_writing.checkAiCritique;
1217
1163
  exports.checkAiDrafts = require_ai_writing.checkAiDrafts;
1218
1164
  exports.checkAiExplanation = require_ai_writing.checkAiExplanation;
1165
+ exports.checkAiGrading = require_ai_writing.checkAiGrading;
1219
1166
  exports.checkAiHint = require_ai_writing.checkAiHint;
1220
1167
  exports.checkAiWritingFeedback = require_ai_writing.checkAiWritingFeedback;
1221
1168
  exports.classifyBand = require_scoring.classifyBand;
@@ -1223,7 +1170,8 @@ exports.combineDeliveryPolicies = combineDeliveryPolicies;
1223
1170
  exports.composeAssessmentScore = require_scoring.composeAssessmentScore;
1224
1171
  exports.composeTimelineScore = composeTimelineScore;
1225
1172
  exports.computePassThreshold = require_scoring.computePassThreshold;
1226
- exports.contentHash = contentHash;
1173
+ exports.contentHash = require_scoring.contentHash;
1174
+ exports.contentJsonSchema = require_schemas.contentJsonSchema;
1227
1175
  exports.countWords = require_registry.countWords;
1228
1176
  exports.createDraft = require_ai_writing.createDraft;
1229
1177
  exports.createInteractiveVideoDraft = require_ai_writing.createInteractiveVideoDraft;
@@ -1242,18 +1190,21 @@ exports.evaluate = require_scoring.evaluate;
1242
1190
  exports.evaluateTries = require_scoring.evaluateTries;
1243
1191
  exports.fillInTheBlanksJsonSchema = require_schemas.fillInTheBlanksJsonSchema;
1244
1192
  exports.fillInTheBlanksType = require_registry.fillInTheBlanksType;
1245
- exports.fingerprint = fingerprint;
1193
+ exports.fingerprint = require_scoring.fingerprint;
1246
1194
  exports.flattenSequence = flattenSequence;
1247
1195
  exports.gapSelectJsonSchema = require_schemas.gapSelectJsonSchema;
1248
1196
  exports.gapSelectType = require_registry.gapSelectType;
1249
1197
  exports.generateDrafts = require_ai_writing.generateDrafts;
1250
1198
  exports.getActivityTypeDescriptor = require_registry.getActivityTypeDescriptor;
1199
+ exports.gradeFromJudgement = require_scoring.gradeFromJudgement;
1251
1200
  exports.gradeFromRubric = require_scoring.gradeFromRubric;
1252
1201
  exports.gradeReadAloud = require_scoring.gradeReadAloud;
1202
+ exports.graderConfiguration = require_scoring.graderConfiguration;
1253
1203
  exports.gte = require_scoring.gte;
1254
1204
  exports.hasGrade = require_scoring.hasGrade;
1255
- exports.hashSeed = hashSeed;
1205
+ exports.hashSeed = require_scoring.hashSeed;
1256
1206
  exports.hintRevealsAnswer = require_ai_writing.hintRevealsAnswer;
1207
+ exports.inAuditSample = require_scoring.inAuditSample;
1257
1208
  exports.inspectWav = require_scoring.inspectWav;
1258
1209
  exports.interactiveVideoFromDrafts = require_ai_writing.interactiveVideoFromDrafts;
1259
1210
  exports.isBuiltInActivityType = require_registry.isBuiltInActivityType;
@@ -1262,10 +1213,13 @@ exports.isItemGroup = isItemGroup;
1262
1213
  exports.itemGroupJsonSchema = require_schemas.itemGroupJsonSchema;
1263
1214
  exports.jsonSchemaFor = require_schemas.jsonSchemaFor;
1264
1215
  exports.levenshteinDistance = require_registry.levenshteinDistance;
1216
+ exports.listMediaRefs = require_ai_writing.listMediaRefs;
1217
+ exports.mapMediaRefs = require_ai_writing.mapMediaRefs;
1265
1218
  exports.matchText = require_registry.matchText;
1266
1219
  exports.multipleChoiceJsonSchema = require_schemas.multipleChoiceJsonSchema;
1267
1220
  exports.multipleChoiceType = require_registry.multipleChoiceType;
1268
1221
  exports.outcomeFromGrade = require_scoring.outcomeFromGrade;
1222
+ exports.outcomeFromRoutedGrade = require_scoring.outcomeFromRoutedGrade;
1269
1223
  exports.outcomeFromUnscorable = require_scoring.outcomeFromUnscorable;
1270
1224
  exports.planAttempt = planAttempt;
1271
1225
  exports.planMediaBudgets = planMediaBudgets;
@@ -1283,15 +1237,17 @@ exports.resolvePlaybackPolicy = resolvePlaybackPolicy;
1283
1237
  exports.restoreAttemptState = restoreAttemptState;
1284
1238
  exports.restoreMediaPlayLedger = restoreMediaPlayLedger;
1285
1239
  exports.roundGrade = require_scoring.roundGrade;
1240
+ exports.routeGrade = require_scoring.routeGrade;
1286
1241
  exports.score = require_scoring.score;
1287
1242
  exports.scoreTries = require_scoring.scoreTries;
1288
1243
  exports.scoredItemsFromPlan = scoredItemsFromPlan;
1289
- exports.seededShuffle = seededShuffle;
1244
+ exports.seededShuffle = require_scoring.seededShuffle;
1290
1245
  exports.serializeAttemptState = serializeAttemptState;
1291
1246
  exports.serializeMediaPlayLedger = serializeMediaPlayLedger;
1292
1247
  exports.slotMediaKey = slotMediaKey;
1293
1248
  exports.stimulusJsonSchema = require_schemas.stimulusJsonSchema;
1294
1249
  exports.stimulusMediaKey = stimulusMediaKey;
1250
+ exports.transcriptOf = require_ai_writing.transcriptOf;
1295
1251
  exports.validateActivity = require_schemas.validateActivity;
1296
1252
  exports.validateDeliveryPolicy = validateDeliveryPolicy;
1297
1253
  exports.validateDraft = require_ai_writing.validateDraft;
@@ -1303,6 +1259,7 @@ exports.validateOptionMedia = require_schemas.validateOptionMedia;
1303
1259
  exports.validateSpeechAssessment = require_scoring.validateSpeechAssessment;
1304
1260
  exports.validateXAPIStatement = require_xapi.validateXAPIStatement;
1305
1261
  exports.verifyAttemptPlan = verifyAttemptPlan;
1262
+ exports.withoutAuthorOnly = withoutAuthorOnly;
1306
1263
  exports.writtenResponseJsonSchema = require_schemas.writtenResponseJsonSchema;
1307
1264
  exports.writtenResponseType = require_registry.writtenResponseType;
1308
1265
  exports.xAPIBuilder = require_xapi.xAPIBuilder;