@intellectif/lk-core 0.16.0 → 0.18.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 (48) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +2 -2
  3. package/dist/{activity-DcxtpX7Z.d.cts → activity-HH8dxN1v.d.cts} +234 -4
  4. package/dist/{activity-DcxtpX7Z.d.ts → activity-HH8dxN1v.d.ts} +234 -4
  5. package/dist/{chunk-FJJ2GVBA.cjs → chunk-2CV6NU32.cjs} +19 -19
  6. package/dist/{chunk-FJJ2GVBA.cjs.map → chunk-2CV6NU32.cjs.map} +1 -1
  7. package/dist/{chunk-6P6XK2LI.cjs → chunk-COBK2RUX.cjs} +74 -39
  8. package/dist/chunk-COBK2RUX.cjs.map +1 -0
  9. package/dist/{chunk-IRUD73IQ.js → chunk-D3GP5MET.js} +683 -638
  10. package/dist/chunk-D3GP5MET.js.map +1 -0
  11. package/dist/{chunk-F7UOLKWV.cjs → chunk-D4TOPSHV.cjs} +518 -473
  12. package/dist/chunk-D4TOPSHV.cjs.map +1 -0
  13. package/dist/{chunk-VFTVZJO5.cjs → chunk-EOFWSGLU.cjs} +4 -4
  14. package/dist/{chunk-VFTVZJO5.cjs.map → chunk-EOFWSGLU.cjs.map} +1 -1
  15. package/dist/{chunk-S63IOKFP.js → chunk-MMEQKFFQ.js} +44 -9
  16. package/dist/chunk-MMEQKFFQ.js.map +1 -0
  17. package/dist/{chunk-OXF7VT7S.js → chunk-X5DAXBJI.js} +2 -2
  18. package/dist/{chunk-GOZGBVJP.js → chunk-Z7QQZ53L.js} +2 -2
  19. package/dist/{chunk-GOZGBVJP.js.map → chunk-Z7QQZ53L.js.map} +1 -1
  20. package/dist/{index-DRJqwO2y.d.ts → index-BrBBUb1i.d.ts} +141 -83
  21. package/dist/{index-BWpwZRQw.d.cts → index-DejnxQpK.d.cts} +141 -83
  22. package/dist/index.cjs +547 -127
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +145 -9
  25. package/dist/index.d.ts +145 -9
  26. package/dist/index.js +427 -7
  27. package/dist/index.js.map +1 -1
  28. package/dist/schemas.cjs +5 -3
  29. package/dist/schemas.cjs.map +1 -1
  30. package/dist/schemas.d.cts +2 -2
  31. package/dist/schemas.d.ts +2 -2
  32. package/dist/schemas.js +4 -2
  33. package/dist/scoring.cjs +3 -3
  34. package/dist/scoring.d.cts +33 -5
  35. package/dist/scoring.d.ts +33 -5
  36. package/dist/scoring.js +2 -2
  37. package/dist/xapi.cjs +3 -3
  38. package/dist/xapi.d.cts +1 -1
  39. package/dist/xapi.d.ts +1 -1
  40. package/dist/xapi.js +2 -2
  41. package/package.json +1 -1
  42. package/vectors/README.md +9 -3
  43. package/vectors/scoring.json +1258 -10
  44. package/dist/chunk-6P6XK2LI.cjs.map +0 -1
  45. package/dist/chunk-F7UOLKWV.cjs.map +0 -1
  46. package/dist/chunk-IRUD73IQ.js.map +0 -1
  47. package/dist/chunk-S63IOKFP.js.map +0 -1
  48. /package/dist/{chunk-OXF7VT7S.js.map → chunk-X5DAXBJI.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/chunk-FJJ2GVBA.cjs","../src/schemas/item-group.ts","../src/timeline-limits.ts","../src/schemas/json-schema.ts","../src/schemas/index.ts"],"names":["z"],"mappings":"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","file":"/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/chunk-FJJ2GVBA.cjs","sourcesContent":[null,"import { z } from 'zod/v4';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport {\n INTERACTIVE_VIDEO_ITEM_TYPES,\n isInteractiveVideoItemType,\n TIMELINE_MAX_CHAPTERS,\n TIMELINE_MAX_ITEMS,\n TIMELINE_MAX_QUIZZES,\n TIMELINE_MAX_TITLE_LENGTH,\n} from '../timeline-limits.js';\nimport type { ActivityData, ValidationError, ValidationResult } from '../types/activity.js';\nimport type { ItemGroup, StimulusKind } from '../types/item-group.js';\nimport { GROUP_CAPTIONS_REVEAL_DICTATION, groupCaptionsField } from './dictation.js';\nimport { MediaSchema, RedactedMediaSchema } from './media.js';\n\n/**\n * An authored slot key.\n *\n * A `.` is rejected here, not at render time: `flattenSequence` uses the first\n * `.` to separate a group from its item, so a key containing one would produce\n * an ambiguous slot id. `keyOf` already threw on it — this moves the rejection\n * to `validateItemGroup`, where an author finds it, instead of leaving it to\n * surface when a learner opens the paper. Content that would newly fail\n * validation already threw at flatten time, so it can never have been sat.\n */\nconst SlotKeySchema = z\n .string()\n .min(1)\n .refine((key) => !key.includes('.'), {\n error:\n 'slotKey must not contain \".\" — that character separates a group from its item in a slot id, so a key containing one would make the slot ambiguous.',\n });\n\nfunction hasBody(stimulus: { body?: string | undefined }): boolean {\n return typeof stimulus.body === 'string' && stimulus.body.trim().length > 0;\n}\n\n/** Which media types can carry a stimulus of each kind. `text`/`mixed` accept any. */\nfunction mediaFits(kind: StimulusKind, mediaType: string | undefined): boolean {\n switch (kind) {\n case 'audio':\n return mediaType === 'audio';\n case 'video':\n return mediaType === 'video' || mediaType === 'embed';\n case 'image':\n return mediaType === 'image';\n default:\n return true;\n }\n}\n\n/**\n * Zod schema for a {@link Stimulus}. Loose: unknown keys preserved.\n *\n * The semantic guards exist because a stimulus that does not carry what its\n * `kind` promises is an authoring error that must not reach an exam: an\n * \"audio\" stimulus with no recording renders as a blank panel above six\n * listening questions. Unrepresentable in JSON Schema; dropped from\n * `stimulusJsonSchema` by design.\n */\nexport const StimulusSchema = z\n .looseObject({\n id: z.string().min(1),\n kind: z.enum(['text', 'audio', 'video', 'image', 'mixed']),\n title: z.string().optional(),\n body: z.string().optional(),\n bodyHtml: z.string().optional(),\n media: MediaSchema.optional(),\n transcript: z.string().optional(),\n locale: z.string().optional(),\n attribution: z.string().optional(),\n })\n .refine((stimulus) => stimulus.bodyHtml === undefined || hasBody(stimulus), {\n error:\n 'bodyHtml requires a plain-text body: it is the accessible fallback rendered when no sanitiser is supplied.',\n path: ['body'],\n })\n .refine(\n (stimulus) => (stimulus.kind !== 'text' && stimulus.kind !== 'mixed') || hasBody(stimulus),\n {\n error: 'A text or mixed stimulus needs a non-empty body.',\n path: ['body'],\n },\n )\n .refine((stimulus) => stimulus.kind === 'text' || stimulus.media !== undefined, {\n error: 'An audio, video, image or mixed stimulus needs media.',\n path: ['media'],\n })\n .refine(\n (stimulus) => stimulus.media === undefined || mediaFits(stimulus.kind, stimulus.media.type),\n {\n error:\n 'media.type does not fit the stimulus kind: audio needs audio; video needs video or embed; image needs image.',\n path: ['media', 'type'],\n },\n );\n\nconst TimelineTitleSchema = z\n .string()\n .max(TIMELINE_MAX_TITLE_LENGTH)\n .refine((title) => title.trim().length > 0, { error: 'A title must not be empty.' });\n\n/** Seconds from the start of the video. zod rejects NaN and ±Infinity itself. */\nconst TimelineTimeSchema = z.number().min(0, { error: 'A time is 0 seconds or more.' });\n\n/**\n * A quiz. STRICT, like every part of a timeline: a misspelt `requried` would\n * otherwise be kept and the quiz silently optional on a paper that believed it\n * was required.\n */\nexport const TimelineCueSchema = z.strictObject({\n id: z.string().min(1).max(64),\n at: TimelineTimeSchema,\n itemIds: z.array(z.string().min(1)).min(1).max(TIMELINE_MAX_ITEMS),\n title: TimelineTitleSchema.optional(),\n required: z.boolean().optional(),\n});\n\nexport const TimelineChapterSchema = z.strictObject({\n at: TimelineTimeSchema,\n title: TimelineTitleSchema,\n});\n\n/**\n * A timeline on its own: its quizzes, chapters and navigation. The rules that\n * need the group — every item in exactly one quiz, a video stimulus, the five\n * item types — are {@link timelineIssues}, which both group schemas run.\n */\nexport const MediaTimelineSchema = z\n .strictObject({\n cues: z.array(TimelineCueSchema).max(TIMELINE_MAX_QUIZZES),\n chapters: z.array(TimelineChapterSchema).max(TIMELINE_MAX_CHAPTERS).optional(),\n navigation: z.enum(['free', 'no-skip-ahead']).optional(),\n })\n .check((ctx) => {\n const seen = new Set<string>();\n ctx.value.cues.forEach((cue, index) => {\n if (seen.has(cue.id)) {\n ctx.issues.push({\n code: 'custom',\n input: cue.id,\n message: `Quiz id \"${cue.id}\" is used twice: events, drafts and the contents panel name a quiz by its id.`,\n path: ['cues', index, 'id'],\n });\n }\n seen.add(cue.id);\n });\n // Strictly increasing, not merely sorted: two chapters starting at one\n // moment leave the first with no length, and the scrubber no room to draw it.\n const chapters = ctx.value.chapters ?? [];\n chapters.forEach((chapter, index) => {\n const previous = chapters[index - 1];\n if (previous !== undefined && chapter.at <= previous.at) {\n ctx.issues.push({\n code: 'custom',\n input: chapter.at,\n message: 'Chapter times must be strictly increasing.',\n path: ['chapters', index, 'at'],\n });\n }\n });\n });\n\n/** A URL only this document can resolve, or one that inlines the bytes. */\nfunction isLocalOnlyUrl(url: unknown): boolean {\n return typeof url === 'string' && /^(data|blob):/i.test(url);\n}\n\n/**\n * The rules of an interactive video that span the timeline, the stimulus and\n * the items. Run by the content schema and, for everything but the two\n * authoring-only rules, by the strict redacted schema — a projection built by\n * hand never passed through the content schema.\n *\n * Items are read defensively: the redacted schema leaves them opaque, and each\n * is proven against its own type's schema elsewhere.\n */\nfunction timelineIssues(\n group: {\n stimulus: {\n kind: string;\n media?:\n | {\n type: string;\n url: string;\n poster?: string | undefined;\n tracks?: readonly { src: string }[] | undefined;\n }\n | undefined;\n };\n items: readonly unknown[];\n shuffle?: string | undefined;\n timeline?: { cues: readonly { itemIds: readonly string[] }[] } | undefined;\n },\n scope: 'content' | 'redacted',\n): { path: (string | number)[]; message: string; input: unknown }[] {\n const timeline = group.timeline;\n if (timeline === undefined) {\n return [];\n }\n const issues: { path: (string | number)[]; message: string; input: unknown }[] = [];\n const media = group.stimulus.media;\n\n // Reported at the field that is wrong, so an editor's own check at that path\n // can stand in for it without hiding anything else about the stimulus.\n if (group.stimulus.kind !== 'video') {\n issues.push({\n path: ['stimulus', 'kind'],\n input: group.stimulus.kind,\n message:\n 'An interactive video needs a video stimulus: quizzes open at moments of a video, and nothing else has them.',\n });\n } else if (media !== undefined && media.type !== 'video') {\n issues.push({\n path: ['stimulus', 'media', 'type'],\n input: media.type,\n message:\n 'An interactive video needs a video file. An embedded provider player cannot be paused at the moment a quiz opens.',\n });\n }\n if (group.shuffle === 'within-group') {\n issues.push({\n path: ['shuffle'],\n input: group.shuffle,\n message:\n 'An interactive video presents its questions in the order its quizzes open; shuffle: \"within-group\" cannot apply to it.',\n });\n }\n if (group.items.length > TIMELINE_MAX_ITEMS) {\n issues.push({\n path: ['items'],\n input: group.items.length,\n message: `An interactive video holds at most ${TIMELINE_MAX_ITEMS} questions.`,\n });\n }\n\n const itemIds = new Map<string, number>();\n group.items.forEach((item, index) => {\n const {\n id,\n type,\n media: itemMedia,\n } = (item ?? {}) as { id?: unknown; type?: unknown; media?: unknown };\n if (typeof id === 'string') {\n itemIds.set(id, index);\n }\n if (!isInteractiveVideoItemType(type)) {\n issues.push({\n path: ['items', index, 'type'],\n input: type,\n message: `An interactive video may hold only ${INTERACTIVE_VIDEO_ITEM_TYPES.join(', ')} questions.`,\n });\n }\n // The \"play the stimulus\" fallback a dictation has in a listening group\n // means nothing halfway through a video.\n if (scope === 'content' && type === 'dictation' && itemMedia === undefined) {\n issues.push({\n path: ['items', index, 'media'],\n input: itemMedia,\n message: 'A dictation inside an interactive video needs its own recording.',\n });\n }\n });\n\n const placed = new Set<string>();\n timeline.cues.forEach((cue, cueIndex) => {\n cue.itemIds.forEach((itemId, position) => {\n const path = ['timeline', 'cues', cueIndex, 'itemIds', position];\n if (!itemIds.has(itemId)) {\n issues.push({\n path,\n input: itemId,\n message: `No item in this group has the id \"${itemId}\".`,\n });\n } else if (placed.has(itemId)) {\n issues.push({\n path,\n input: itemId,\n message: `Item \"${itemId}\" is placed twice: every question belongs to exactly one quiz.`,\n });\n }\n placed.add(itemId);\n });\n });\n for (const [itemId, index] of itemIds) {\n if (!placed.has(itemId)) {\n issues.push({\n path: ['items', index],\n input: itemId,\n message: `Item \"${itemId}\" is in no quiz, so the video would never show it.`,\n });\n }\n }\n\n // A `data:` video swells the payload and every fingerprint over it; a stored\n // `blob:` URL means nothing in another document.\n if (scope === 'content' && media !== undefined) {\n const urls: [unknown, (string | number)[]][] = [\n [media.url, ['stimulus', 'media', 'url']],\n [media.poster, ['stimulus', 'media', 'poster']],\n ...(media.tracks ?? []).map((track, index): [unknown, (string | number)[]] => [\n track.src,\n ['stimulus', 'media', 'tracks', index, 'src'],\n ]),\n ];\n for (const [url, path] of urls) {\n if (isLocalOnlyUrl(url)) {\n issues.push({\n path,\n input: url,\n message:\n 'An interactive video is stored and served: its URLs cannot be data: or blob: URLs.',\n });\n }\n }\n }\n return issues;\n}\n\n/**\n * The structural minimum of an item as seen by the CONTAINER schema. Each\n * item's own contract is checked against its registered schema by\n * {@link validateItemGroup} — a zod schema cannot dispatch on a registry\n * that consumers extend at runtime.\n */\nconst ItemShapeSchema = z.looseObject({\n type: z.string().min(1),\n id: z.string().min(1),\n slotKey: SlotKeySchema.optional(),\n});\n\n/**\n * Zod schema for an {@link ItemGroup} CONTAINER. Loose: unknown keys\n * preserved. Validates the group's own fields and the stimulus in full, and\n * each item only structurally (`type` and `id`); use {@link validateItemGroup}\n * to validate the items against their registered schemas as well.\n */\nexport const ItemGroupSchema = z\n .looseObject({\n schemaVersion: z.literal('1.0'),\n type: z.literal('item-group'),\n id: z.string().min(1),\n title: z.string().optional(),\n slotKey: SlotKeySchema.optional(),\n stimulus: StimulusSchema,\n items: z.array(ItemShapeSchema).min(1),\n shuffle: z.enum(['none', 'within-group']).optional(),\n timeline: MediaTimelineSchema.optional(),\n })\n .refine((group) => group.items.every((item) => item.type !== 'item-group'), {\n error: 'Item groups do not nest: every item must be an activity.',\n path: ['items'],\n })\n .refine((group) => new Set(group.items.map((item) => item.id)).size === group.items.length, {\n error: 'Item ids must be unique within a group.',\n path: ['items'],\n })\n .check((ctx) => {\n for (const issue of timelineIssues(ctx.value, 'content')) {\n ctx.issues.push({ code: 'custom', ...issue });\n }\n });\n\n/** The learner-safe shape of a stimulus, derived from the strict schema below. */\nexport type RedactedStimulus = z.infer<typeof RedactedStimulusSchema>;\n\n/** Strict learner-safe stimulus: everything but the author-only `transcript`. */\nexport const RedactedStimulusSchema = z.strictObject({\n id: z.string().min(1),\n kind: z.enum(['text', 'audio', 'video', 'image', 'mixed']),\n title: z.string().optional(),\n body: z.string().optional(),\n bodyHtml: z.string().optional(),\n media: RedactedMediaSchema.optional(),\n locale: z.string().optional(),\n attribution: z.string().optional(),\n});\n\n/**\n * Strict learner-safe item group. Items are left opaque here — each is proven\n * learner-safe by `assertRedacted` against its OWN type's redacted schema,\n * which is the only place that knowledge lives. The one exception is the one\n * rule that spans the container and an item: a captioned stimulus recording\n * played to a dictation is not learner-safe, because the captions are the\n * dictation's answer.\n */\nexport const RedactedItemGroupSchema = z\n .strictObject({\n redacted: z.literal(true),\n schemaVersion: z.literal('1.0'),\n type: z.literal('item-group'),\n id: z.string().min(1),\n title: z.string().optional(),\n slotKey: SlotKeySchema.optional(),\n stimulus: RedactedStimulusSchema,\n items: z.array(z.unknown()).min(1),\n shuffle: z.enum(['none', 'within-group']).optional(),\n timeline: MediaTimelineSchema.optional(),\n })\n .check((ctx) => {\n for (const issue of timelineIssues(ctx.value, 'redacted')) {\n ctx.issues.push({ code: 'custom', ...issue });\n }\n const captions = groupCaptionsField(ctx.value);\n if (captions !== undefined) {\n ctx.issues.push({\n code: 'custom',\n input: ctx.value.stimulus.media?.[captions],\n message: GROUP_CAPTIONS_REVEAL_DICTATION,\n path: ['stimulus', 'media', captions],\n });\n }\n });\n\nfunction toValidationErrors(\n issues: readonly { path: PropertyKey[]; message: string; code: string }[],\n prefix: string[],\n): ValidationError[] {\n return issues.map((issue) => ({\n path: [...prefix, ...issue.path.map(String)],\n message: issue.message,\n code: issue.code,\n }));\n}\n\n/**\n * Validates an item group in full: the container and stimulus against\n * {@link ItemGroupSchema}, then every item against the schema registered for\n * its `type`. Errors from items are reported at `items.<index>.…`.\n *\n * Unlike `validateActivity`, an item whose type is not registered is REPORTED\n * (code `unknown_activity_type`) rather than thrown: a group is validated as\n * a whole, and an author fixing a six-item group wants every problem listed,\n * not the first one that happened to throw.\n */\nexport function validateItemGroup(data: unknown): ValidationResult<ItemGroup> {\n const container = ItemGroupSchema.safeParse(data);\n if (!container.success) {\n return { success: false, errors: toValidationErrors(container.error.issues, []) };\n }\n\n const errors: ValidationError[] = [];\n const items: ActivityData[] = [];\n container.data.items.forEach((item, index) => {\n const descriptor = getActivityTypeDescriptor(item.type);\n if (descriptor === undefined) {\n errors.push({\n path: ['items', String(index), 'type'],\n message: `Activity type \"${item.type}\" is not registered`,\n code: 'unknown_activity_type',\n });\n return;\n }\n const parsed = descriptor.schema.safeParse(item);\n if (!parsed.success) {\n errors.push(...toValidationErrors(parsed.error.issues, ['items', String(index)]));\n return;\n }\n items.push(parsed.data as ActivityData);\n });\n const captions = groupCaptionsField(container.data);\n if (captions !== undefined) {\n errors.push({\n path: ['stimulus', 'media', captions],\n message: GROUP_CAPTIONS_REVEAL_DICTATION,\n code: 'custom',\n });\n }\n\n if (errors.length > 0) {\n return { success: false, errors };\n }\n // zod4 optional outputs are `T | undefined`; the wire type uses exact\n // optionals. Structurally identical at runtime — the cast is type-level.\n return { success: true, data: { ...container.data, items } as unknown as ItemGroup };\n}\n","/**\n * The bounds of an interactive video — an item group with a `timeline`.\n *\n * A leaf module on purpose: the schemas, the authoring checks and the timeline\n * helpers all read these, and nothing here may import any of them back.\n */\n\n/**\n * The item types an interactive video may present. CLOSED on purpose: a type\n * added to the SDK later, or a custom type a host registers, is not silently\n * embeddable. Each one here was chosen, and each works inside a paused video —\n * a read-aloud's microphone included, because every quiz pauses the video\n * first.\n */\nexport const INTERACTIVE_VIDEO_ITEM_TYPES = [\n 'multiple-choice',\n 'fill-in-the-blanks',\n 'gap-select',\n 'dictation',\n 'read-aloud',\n] as const;\n\n/** One of {@link INTERACTIVE_VIDEO_ITEM_TYPES}. */\nexport type InteractiveVideoItemType = (typeof INTERACTIVE_VIDEO_ITEM_TYPES)[number];\n\n/** Whether `type` is one of the item types an interactive video may present. */\nexport function isInteractiveVideoItemType(type: unknown): type is InteractiveVideoItemType {\n return (INTERACTIVE_VIDEO_ITEM_TYPES as readonly unknown[]).includes(type);\n}\n\n/** The most quizzes one video may hold. */\nexport const TIMELINE_MAX_QUIZZES = 100;\n\n/**\n * The most questions one interactive video may hold, across all its quizzes.\n * The player keeps every one of them mounted, so an answer survives the\n * learner rewinding past its quiz.\n */\nexport const TIMELINE_MAX_ITEMS = 200;\n\n/** The most chapters one video may hold. */\nexport const TIMELINE_MAX_CHAPTERS = 100;\n\n/** The longest quiz or chapter title, in UTF-16 units. A title sits on one line of the player. */\nexport const TIMELINE_MAX_TITLE_LENGTH = 120;\n","import { z } from 'zod/v4';\nimport { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport { DictationDataSchema } from './dictation.js';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { GapSelectDataSchema } from './gap-select.js';\nimport { ItemGroupSchema, StimulusSchema } from './item-group.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\nimport { ReadAloudDataSchema } from './read-aloud.js';\nimport { WrittenResponseDataSchema } from './written-response.js';\n\n/**\n * JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the\n * kind/media/body consistency guards are Zod-only.\n */\nexport const stimulusJsonSchema = z.toJSONSchema(StimulusSchema, { target: 'draft-7' });\n\n/**\n * JSON Schema (Draft 7) for an `ItemGroup` CONTAINER. Items appear as objects\n * with `type` and `id` only; each item's own contract is `jsonSchemaFor(type)`.\n * For an AI generation pipeline, ask for the group and each item separately\n * rather than a single nested schema — that keeps the per-type schema the\n * registry's, not a copy.\n */\nexport const itemGroupJsonSchema = z.toJSONSchema(ItemGroupSchema, { target: 'draft-7' });\n\n/**\n * JSON Schema (Draft 7) representation of the Multiple Choice activity data\n * contract, generated natively by Zod 4. Draft 7 is mandated by Requirement\n * 2.2 for the widest AI-prompt / OpenAPI tooling compatibility. The semantic\n * `.refine()` guards are not representable in JSON Schema and are\n * intentionally omitted — the export captures the *structural* contract only.\n * Since v0.3 the source schemas are loose, so these no longer emit\n * `additionalProperties: false` — the JSON Schema and `validateActivity` now\n * agree on unknown-key handling.\n */\n/**\n * JSON Schema (Draft 7) representation of the Gap Select activity data\n * contract. Structural contract only: the six semantic guards — the\n * passage/gap bijection, id uniqueness, the one-choice-source rule, and an\n * answer key that names a choice the gap offers — are Zod-only, as they are\n * for the other types.\n */\nexport const gapSelectJsonSchema = z.toJSONSchema(GapSelectDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Dictation activity data\n * contract. Structural contract, plus the raw length caps JSON Schema can\n * state in code points as zod counts them — `maxLength` 2000 on a transcript\n * and an accepted transcript, 200 on a rule's `from` and `to`. The twelve\n * semantic guards — a transcript that survives normalisation, the caps after\n * equivalences are applied, distinct candidates, audio only, the\n * slow-recording rules, no captions, no transcript in the title — are\n * Zod-only, as they are for the other types.\n */\nexport const dictationJsonSchema = z.toJSONSchema(DictationDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Read Aloud activity data\n * contract. Structural contract, plus the raw cap JSON Schema can state in code\n * points as zod counts them — `maxLength` 2000 on the reference text — and the\n * canonical locale pattern. The ten semantic guards — the cap after\n * normalisation, a text that survives it, the spaced-script rule, the\n * model-recording rules, unique dimensions, a weight above 0, and the take\n * bounds — are Zod-only, as they are for the other types.\n */\nexport const readAloudJsonSchema = z.toJSONSchema(ReadAloudDataSchema, {\n target: 'draft-7',\n});\n\nexport const multipleChoiceJsonSchema = z.toJSONSchema(MultipleChoiceDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Fill-in-the-Blanks activity data\n * contract, generated natively by Zod 4. Structural contract only (semantic\n * `.refine()` guards are Zod-only and not representable in JSON Schema).\n */\nexport const fillInTheBlanksJsonSchema = z.toJSONSchema(FillInTheBlanksDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Written Response activity data\n * contract. Structural contract only.\n */\nexport const writtenResponseJsonSchema = z.toJSONSchema(WrittenResponseDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * Derives the JSON Schema (Draft 7) for any REGISTERED activity type — the\n * live, registry-backed replacement for the static per-type exports above,\n * and the building block for AI generation pipelines (R6.1): pass the result\n * as a structured-output schema so a model can only emit valid items.\n *\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function jsonSchemaFor(type: string): Record<string, unknown> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(type);\n }\n return z.toJSONSchema(descriptor.schema as never, { target: 'draft-7' }) as Record<\n string,\n unknown\n >;\n}\n","import { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport type { ActivityDataMap, ActivityType, ValidationResult } from '../types/activity.js';\n\nexport {\n DictationDataSchema,\n DictationEquivalenceSchema,\n DictationSlowMediaSchema,\n DictationToleranceSchema,\n} from './dictation.js';\nexport { FeedbackSchema } from './feedback.js';\nexport {\n BlankConfigSchema,\n FillInTheBlanksDataSchema,\n TextMatchPolicySchema,\n} from './fill-in-the-blanks.js';\nexport {\n GapSelectBankSchema,\n GapSelectChoiceSchema,\n GapSelectDataSchema,\n GapSelectGapSchema,\n} from './gap-select.js';\nexport type { RedactedStimulus } from './item-group.js';\nexport {\n ItemGroupSchema,\n MediaTimelineSchema,\n RedactedItemGroupSchema,\n RedactedStimulusSchema,\n StimulusSchema,\n TimelineChapterSchema,\n TimelineCueSchema,\n validateItemGroup,\n} from './item-group.js';\nexport {\n dictationJsonSchema,\n fillInTheBlanksJsonSchema,\n gapSelectJsonSchema,\n itemGroupJsonSchema,\n jsonSchemaFor,\n multipleChoiceJsonSchema,\n readAloudJsonSchema,\n stimulusJsonSchema,\n writtenResponseJsonSchema,\n} from './json-schema.js';\nexport {\n MediaPlaybackSchema,\n MediaSchema,\n MediaTrackSchema,\n MediaUrlSchema,\n NativeControlHintSchema,\n RedactedMediaSchema,\n} from './media.js';\nexport {\n MultipleChoiceDataSchema,\n MultipleChoiceOptionMediaSchema,\n MultipleChoiceOptionSchema,\n} from './multiple-choice.js';\nexport { ReadAloudDataSchema, ReadAloudSlowMediaSchema } from './read-aloud.js';\nexport type {\n RedactedActivity,\n RedactedBlankConfig,\n RedactedDictationData,\n RedactedDictationSlowMedia,\n RedactedFillInTheBlanksData,\n RedactedGapSelectBank,\n RedactedGapSelectChoice,\n RedactedGapSelectData,\n RedactedGapSelectGap,\n RedactedMultipleChoiceData,\n RedactedMultipleChoiceOption,\n RedactedMultipleChoiceOptionMedia,\n RedactedReadAloudData,\n RedactedWrittenResponseData,\n} from './redacted.js';\nexport {\n RedactedBlankConfigSchema,\n RedactedDictationDataSchema,\n RedactedDictationSlowMediaSchema,\n RedactedFillInTheBlanksDataSchema,\n RedactedGapSelectBankSchema,\n RedactedGapSelectChoiceSchema,\n RedactedGapSelectDataSchema,\n RedactedGapSelectGapSchema,\n RedactedMultipleChoiceDataSchema,\n RedactedMultipleChoiceOptionMediaSchema,\n RedactedMultipleChoiceOptionSchema,\n RedactedReadAloudDataSchema,\n RedactedWrittenResponseDataSchema,\n} from './redacted.js';\nexport {\n WrittenResponseDataSchema,\n WrittenResponseRubricCriterionSchema,\n WrittenResponseRubricSchema,\n} from './written-response.js';\n\n/**\n * Validates raw activity data against the schema registered for the given\n * activity type (built-in or consumer-registered via `registerActivityType`).\n *\n * Unknown keys are PRESERVED, not stripped: every built-in schema is loose,\n * so consumer sidecar fields and forward-version fields survive validation\n * verbatim in the returned `data`.\n *\n * @returns `{ success: true, data }` with the typed, validated data, or\n * `{ success: false, errors }` with one entry per failed constraint.\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function validateActivity<T extends ActivityType>(\n type: T,\n data: unknown,\n): ValidationResult<ActivityDataMap[T]> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(String(type));\n }\n\n const result = descriptor.schema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data as ActivityDataMap[T] };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n };\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/chunk-2CV6NU32.cjs","../src/schemas/item-group.ts","../src/timeline-limits.ts","../src/schemas/json-schema.ts","../src/schemas/index.ts"],"names":["z"],"mappings":"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","file":"/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/chunk-2CV6NU32.cjs","sourcesContent":[null,"import { z } from 'zod/v4';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport {\n INTERACTIVE_VIDEO_ITEM_TYPES,\n isInteractiveVideoItemType,\n TIMELINE_MAX_CHAPTERS,\n TIMELINE_MAX_ITEMS,\n TIMELINE_MAX_QUIZZES,\n TIMELINE_MAX_TITLE_LENGTH,\n} from '../timeline-limits.js';\nimport type { ActivityData, ValidationError, ValidationResult } from '../types/activity.js';\nimport type { ItemGroup, StimulusKind } from '../types/item-group.js';\nimport { GROUP_CAPTIONS_REVEAL_DICTATION, groupCaptionsField } from './dictation.js';\nimport { MediaSchema, RedactedMediaSchema } from './media.js';\n\n/**\n * An authored slot key.\n *\n * A `.` is rejected here, not at render time: `flattenSequence` uses the first\n * `.` to separate a group from its item, so a key containing one would produce\n * an ambiguous slot id. `keyOf` already threw on it — this moves the rejection\n * to `validateItemGroup`, where an author finds it, instead of leaving it to\n * surface when a learner opens the paper. Content that would newly fail\n * validation already threw at flatten time, so it can never have been sat.\n */\nconst SlotKeySchema = z\n .string()\n .min(1)\n .refine((key) => !key.includes('.'), {\n error:\n 'slotKey must not contain \".\" — that character separates a group from its item in a slot id, so a key containing one would make the slot ambiguous.',\n });\n\nfunction hasBody(stimulus: { body?: string | undefined }): boolean {\n return typeof stimulus.body === 'string' && stimulus.body.trim().length > 0;\n}\n\n/** Which media types can carry a stimulus of each kind. `text`/`mixed` accept any. */\nfunction mediaFits(kind: StimulusKind, mediaType: string | undefined): boolean {\n switch (kind) {\n case 'audio':\n return mediaType === 'audio';\n case 'video':\n return mediaType === 'video' || mediaType === 'embed';\n case 'image':\n return mediaType === 'image';\n default:\n return true;\n }\n}\n\n/**\n * Zod schema for a {@link Stimulus}. Loose: unknown keys preserved.\n *\n * The semantic guards exist because a stimulus that does not carry what its\n * `kind` promises is an authoring error that must not reach an exam: an\n * \"audio\" stimulus with no recording renders as a blank panel above six\n * listening questions. Unrepresentable in JSON Schema; dropped from\n * `stimulusJsonSchema` by design.\n */\nexport const StimulusSchema = z\n .looseObject({\n id: z.string().min(1),\n kind: z.enum(['text', 'audio', 'video', 'image', 'mixed']),\n title: z.string().optional(),\n body: z.string().optional(),\n bodyHtml: z.string().optional(),\n media: MediaSchema.optional(),\n transcript: z.string().optional(),\n locale: z.string().optional(),\n attribution: z.string().optional(),\n })\n .refine((stimulus) => stimulus.bodyHtml === undefined || hasBody(stimulus), {\n error:\n 'bodyHtml requires a plain-text body: it is the accessible fallback rendered when no sanitiser is supplied.',\n path: ['body'],\n })\n .refine(\n (stimulus) => (stimulus.kind !== 'text' && stimulus.kind !== 'mixed') || hasBody(stimulus),\n {\n error: 'A text or mixed stimulus needs a non-empty body.',\n path: ['body'],\n },\n )\n .refine((stimulus) => stimulus.kind === 'text' || stimulus.media !== undefined, {\n error: 'An audio, video, image or mixed stimulus needs media.',\n path: ['media'],\n })\n .refine(\n (stimulus) => stimulus.media === undefined || mediaFits(stimulus.kind, stimulus.media.type),\n {\n error:\n 'media.type does not fit the stimulus kind: audio needs audio; video needs video or embed; image needs image.',\n path: ['media', 'type'],\n },\n );\n\nconst TimelineTitleSchema = z\n .string()\n .max(TIMELINE_MAX_TITLE_LENGTH)\n .refine((title) => title.trim().length > 0, { error: 'A title must not be empty.' });\n\n/** Seconds from the start of the video. zod rejects NaN and ±Infinity itself. */\nconst TimelineTimeSchema = z.number().min(0, { error: 'A time is 0 seconds or more.' });\n\n/**\n * A quiz. STRICT, like every part of a timeline: a misspelt `requried` would\n * otherwise be kept and the quiz silently optional on a paper that believed it\n * was required.\n */\nexport const TimelineCueSchema = z.strictObject({\n id: z.string().min(1).max(64),\n at: TimelineTimeSchema,\n itemIds: z.array(z.string().min(1)).min(1).max(TIMELINE_MAX_ITEMS),\n title: TimelineTitleSchema.optional(),\n required: z.boolean().optional(),\n});\n\nexport const TimelineChapterSchema = z.strictObject({\n at: TimelineTimeSchema,\n title: TimelineTitleSchema,\n});\n\n/**\n * A timeline on its own: its quizzes, chapters and navigation. The rules that\n * need the group — every item in exactly one quiz, a video stimulus, the five\n * item types — are {@link timelineIssues}, which both group schemas run.\n */\nexport const MediaTimelineSchema = z\n .strictObject({\n cues: z.array(TimelineCueSchema).max(TIMELINE_MAX_QUIZZES),\n chapters: z.array(TimelineChapterSchema).max(TIMELINE_MAX_CHAPTERS).optional(),\n navigation: z.enum(['free', 'no-skip-ahead']).optional(),\n })\n .check((ctx) => {\n const seen = new Set<string>();\n ctx.value.cues.forEach((cue, index) => {\n if (seen.has(cue.id)) {\n ctx.issues.push({\n code: 'custom',\n input: cue.id,\n message: `Quiz id \"${cue.id}\" is used twice: events, drafts and the contents panel name a quiz by its id.`,\n path: ['cues', index, 'id'],\n });\n }\n seen.add(cue.id);\n });\n // Strictly increasing, not merely sorted: two chapters starting at one\n // moment leave the first with no length, and the scrubber no room to draw it.\n const chapters = ctx.value.chapters ?? [];\n chapters.forEach((chapter, index) => {\n const previous = chapters[index - 1];\n if (previous !== undefined && chapter.at <= previous.at) {\n ctx.issues.push({\n code: 'custom',\n input: chapter.at,\n message: 'Chapter times must be strictly increasing.',\n path: ['chapters', index, 'at'],\n });\n }\n });\n });\n\n/** A URL only this document can resolve, or one that inlines the bytes. */\nfunction isLocalOnlyUrl(url: unknown): boolean {\n return typeof url === 'string' && /^(data|blob):/i.test(url);\n}\n\n/**\n * The rules of an interactive video that span the timeline, the stimulus and\n * the items. Run by the content schema and, for everything but the two\n * authoring-only rules, by the strict redacted schema — a projection built by\n * hand never passed through the content schema.\n *\n * Items are read defensively: the redacted schema leaves them opaque, and each\n * is proven against its own type's schema elsewhere.\n */\nfunction timelineIssues(\n group: {\n stimulus: {\n kind: string;\n media?:\n | {\n type: string;\n url: string;\n poster?: string | undefined;\n tracks?: readonly { src: string }[] | undefined;\n }\n | undefined;\n };\n items: readonly unknown[];\n shuffle?: string | undefined;\n timeline?: { cues: readonly { itemIds: readonly string[] }[] } | undefined;\n },\n scope: 'content' | 'redacted',\n): { path: (string | number)[]; message: string; input: unknown }[] {\n const timeline = group.timeline;\n if (timeline === undefined) {\n return [];\n }\n const issues: { path: (string | number)[]; message: string; input: unknown }[] = [];\n const media = group.stimulus.media;\n\n // Reported at the field that is wrong, so an editor's own check at that path\n // can stand in for it without hiding anything else about the stimulus.\n if (group.stimulus.kind !== 'video') {\n issues.push({\n path: ['stimulus', 'kind'],\n input: group.stimulus.kind,\n message:\n 'An interactive video needs a video stimulus: quizzes open at moments of a video, and nothing else has them.',\n });\n } else if (media !== undefined && media.type !== 'video') {\n issues.push({\n path: ['stimulus', 'media', 'type'],\n input: media.type,\n message:\n 'An interactive video needs a video file. An embedded provider player cannot be paused at the moment a quiz opens.',\n });\n }\n if (group.shuffle === 'within-group') {\n issues.push({\n path: ['shuffle'],\n input: group.shuffle,\n message:\n 'An interactive video presents its questions in the order its quizzes open; shuffle: \"within-group\" cannot apply to it.',\n });\n }\n if (group.items.length > TIMELINE_MAX_ITEMS) {\n issues.push({\n path: ['items'],\n input: group.items.length,\n message: `An interactive video holds at most ${TIMELINE_MAX_ITEMS} questions.`,\n });\n }\n\n const itemIds = new Map<string, number>();\n group.items.forEach((item, index) => {\n const {\n id,\n type,\n media: itemMedia,\n } = (item ?? {}) as { id?: unknown; type?: unknown; media?: unknown };\n if (typeof id === 'string') {\n itemIds.set(id, index);\n }\n if (!isInteractiveVideoItemType(type)) {\n issues.push({\n path: ['items', index, 'type'],\n input: type,\n message: `An interactive video may hold only ${INTERACTIVE_VIDEO_ITEM_TYPES.join(', ')} questions.`,\n });\n }\n // The \"play the stimulus\" fallback a dictation has in a listening group\n // means nothing halfway through a video.\n if (scope === 'content' && type === 'dictation' && itemMedia === undefined) {\n issues.push({\n path: ['items', index, 'media'],\n input: itemMedia,\n message: 'A dictation inside an interactive video needs its own recording.',\n });\n }\n });\n\n const placed = new Set<string>();\n timeline.cues.forEach((cue, cueIndex) => {\n cue.itemIds.forEach((itemId, position) => {\n const path = ['timeline', 'cues', cueIndex, 'itemIds', position];\n if (!itemIds.has(itemId)) {\n issues.push({\n path,\n input: itemId,\n message: `No item in this group has the id \"${itemId}\".`,\n });\n } else if (placed.has(itemId)) {\n issues.push({\n path,\n input: itemId,\n message: `Item \"${itemId}\" is placed twice: every question belongs to exactly one quiz.`,\n });\n }\n placed.add(itemId);\n });\n });\n for (const [itemId, index] of itemIds) {\n if (!placed.has(itemId)) {\n issues.push({\n path: ['items', index],\n input: itemId,\n message: `Item \"${itemId}\" is in no quiz, so the video would never show it.`,\n });\n }\n }\n\n // A `data:` video swells the payload and every fingerprint over it; a stored\n // `blob:` URL means nothing in another document.\n if (scope === 'content' && media !== undefined) {\n const urls: [unknown, (string | number)[]][] = [\n [media.url, ['stimulus', 'media', 'url']],\n [media.poster, ['stimulus', 'media', 'poster']],\n ...(media.tracks ?? []).map((track, index): [unknown, (string | number)[]] => [\n track.src,\n ['stimulus', 'media', 'tracks', index, 'src'],\n ]),\n ];\n for (const [url, path] of urls) {\n if (isLocalOnlyUrl(url)) {\n issues.push({\n path,\n input: url,\n message:\n 'An interactive video is stored and served: its URLs cannot be data: or blob: URLs.',\n });\n }\n }\n }\n return issues;\n}\n\n/**\n * The structural minimum of an item as seen by the CONTAINER schema. Each\n * item's own contract is checked against its registered schema by\n * {@link validateItemGroup} — a zod schema cannot dispatch on a registry\n * that consumers extend at runtime.\n */\nconst ItemShapeSchema = z.looseObject({\n type: z.string().min(1),\n id: z.string().min(1),\n slotKey: SlotKeySchema.optional(),\n});\n\n/**\n * Zod schema for an {@link ItemGroup} CONTAINER. Loose: unknown keys\n * preserved. Validates the group's own fields and the stimulus in full, and\n * each item only structurally (`type` and `id`); use {@link validateItemGroup}\n * to validate the items against their registered schemas as well.\n */\nexport const ItemGroupSchema = z\n .looseObject({\n schemaVersion: z.literal('1.0'),\n type: z.literal('item-group'),\n id: z.string().min(1),\n title: z.string().optional(),\n slotKey: SlotKeySchema.optional(),\n stimulus: StimulusSchema,\n items: z.array(ItemShapeSchema).min(1),\n shuffle: z.enum(['none', 'within-group']).optional(),\n timeline: MediaTimelineSchema.optional(),\n })\n .refine((group) => group.items.every((item) => item.type !== 'item-group'), {\n error: 'Item groups do not nest: every item must be an activity.',\n path: ['items'],\n })\n .refine((group) => new Set(group.items.map((item) => item.id)).size === group.items.length, {\n error: 'Item ids must be unique within a group.',\n path: ['items'],\n })\n .check((ctx) => {\n for (const issue of timelineIssues(ctx.value, 'content')) {\n ctx.issues.push({ code: 'custom', ...issue });\n }\n });\n\n/** The learner-safe shape of a stimulus, derived from the strict schema below. */\nexport type RedactedStimulus = z.infer<typeof RedactedStimulusSchema>;\n\n/** Strict learner-safe stimulus: everything but the author-only `transcript`. */\nexport const RedactedStimulusSchema = z.strictObject({\n id: z.string().min(1),\n kind: z.enum(['text', 'audio', 'video', 'image', 'mixed']),\n title: z.string().optional(),\n body: z.string().optional(),\n bodyHtml: z.string().optional(),\n media: RedactedMediaSchema.optional(),\n locale: z.string().optional(),\n attribution: z.string().optional(),\n});\n\n/**\n * Strict learner-safe item group. Items are left opaque here — each is proven\n * learner-safe by `assertRedacted` against its OWN type's redacted schema,\n * which is the only place that knowledge lives. The one exception is the one\n * rule that spans the container and an item: a captioned stimulus recording\n * played to a dictation is not learner-safe, because the captions are the\n * dictation's answer.\n */\nexport const RedactedItemGroupSchema = z\n .strictObject({\n redacted: z.literal(true),\n schemaVersion: z.literal('1.0'),\n type: z.literal('item-group'),\n id: z.string().min(1),\n title: z.string().optional(),\n slotKey: SlotKeySchema.optional(),\n stimulus: RedactedStimulusSchema,\n items: z.array(z.unknown()).min(1),\n shuffle: z.enum(['none', 'within-group']).optional(),\n timeline: MediaTimelineSchema.optional(),\n })\n .check((ctx) => {\n for (const issue of timelineIssues(ctx.value, 'redacted')) {\n ctx.issues.push({ code: 'custom', ...issue });\n }\n const captions = groupCaptionsField(ctx.value);\n if (captions !== undefined) {\n ctx.issues.push({\n code: 'custom',\n input: ctx.value.stimulus.media?.[captions],\n message: GROUP_CAPTIONS_REVEAL_DICTATION,\n path: ['stimulus', 'media', captions],\n });\n }\n });\n\nfunction toValidationErrors(\n issues: readonly { path: PropertyKey[]; message: string; code: string }[],\n prefix: string[],\n): ValidationError[] {\n return issues.map((issue) => ({\n path: [...prefix, ...issue.path.map(String)],\n message: issue.message,\n code: issue.code,\n }));\n}\n\n/**\n * Validates an item group in full: the container and stimulus against\n * {@link ItemGroupSchema}, then every item against the schema registered for\n * its `type`. Errors from items are reported at `items.<index>.…`.\n *\n * Unlike `validateActivity`, an item whose type is not registered is REPORTED\n * (code `unknown_activity_type`) rather than thrown: a group is validated as\n * a whole, and an author fixing a six-item group wants every problem listed,\n * not the first one that happened to throw.\n */\nexport function validateItemGroup(data: unknown): ValidationResult<ItemGroup> {\n const container = ItemGroupSchema.safeParse(data);\n if (!container.success) {\n return { success: false, errors: toValidationErrors(container.error.issues, []) };\n }\n\n const errors: ValidationError[] = [];\n const items: ActivityData[] = [];\n container.data.items.forEach((item, index) => {\n const descriptor = getActivityTypeDescriptor(item.type);\n if (descriptor === undefined) {\n errors.push({\n path: ['items', String(index), 'type'],\n message: `Activity type \"${item.type}\" is not registered`,\n code: 'unknown_activity_type',\n });\n return;\n }\n const parsed = descriptor.schema.safeParse(item);\n if (!parsed.success) {\n errors.push(...toValidationErrors(parsed.error.issues, ['items', String(index)]));\n return;\n }\n items.push(parsed.data as ActivityData);\n });\n const captions = groupCaptionsField(container.data);\n if (captions !== undefined) {\n errors.push({\n path: ['stimulus', 'media', captions],\n message: GROUP_CAPTIONS_REVEAL_DICTATION,\n code: 'custom',\n });\n }\n\n if (errors.length > 0) {\n return { success: false, errors };\n }\n // zod4 optional outputs are `T | undefined`; the wire type uses exact\n // optionals. Structurally identical at runtime — the cast is type-level.\n return { success: true, data: { ...container.data, items } as unknown as ItemGroup };\n}\n","/**\n * The bounds of an interactive video — an item group with a `timeline`.\n *\n * A leaf module on purpose: the schemas, the authoring checks and the timeline\n * helpers all read these, and nothing here may import any of them back.\n */\n\n/**\n * The item types an interactive video may present. CLOSED on purpose: a type\n * added to the SDK later, or a custom type a host registers, is not silently\n * embeddable. Each one here was chosen, and each works inside a paused video —\n * a read-aloud's microphone included, because every quiz pauses the video\n * first.\n */\nexport const INTERACTIVE_VIDEO_ITEM_TYPES = [\n 'multiple-choice',\n 'fill-in-the-blanks',\n 'gap-select',\n 'dictation',\n 'read-aloud',\n] as const;\n\n/** One of {@link INTERACTIVE_VIDEO_ITEM_TYPES}. */\nexport type InteractiveVideoItemType = (typeof INTERACTIVE_VIDEO_ITEM_TYPES)[number];\n\n/** Whether `type` is one of the item types an interactive video may present. */\nexport function isInteractiveVideoItemType(type: unknown): type is InteractiveVideoItemType {\n return (INTERACTIVE_VIDEO_ITEM_TYPES as readonly unknown[]).includes(type);\n}\n\n/** The most quizzes one video may hold. */\nexport const TIMELINE_MAX_QUIZZES = 100;\n\n/**\n * The most questions one interactive video may hold, across all its quizzes.\n * The player keeps every one of them mounted, so an answer survives the\n * learner rewinding past its quiz.\n */\nexport const TIMELINE_MAX_ITEMS = 200;\n\n/** The most chapters one video may hold. */\nexport const TIMELINE_MAX_CHAPTERS = 100;\n\n/** The longest quiz or chapter title, in UTF-16 units. A title sits on one line of the player. */\nexport const TIMELINE_MAX_TITLE_LENGTH = 120;\n","import { z } from 'zod/v4';\nimport { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport { DictationDataSchema } from './dictation.js';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { GapSelectDataSchema } from './gap-select.js';\nimport { ItemGroupSchema, StimulusSchema } from './item-group.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\nimport { ReadAloudDataSchema } from './read-aloud.js';\nimport { WrittenResponseDataSchema } from './written-response.js';\n\n/**\n * JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the\n * kind/media/body consistency guards are Zod-only.\n */\nexport const stimulusJsonSchema = z.toJSONSchema(StimulusSchema, { target: 'draft-7' });\n\n/**\n * JSON Schema (Draft 7) for an `ItemGroup` CONTAINER. Items appear as objects\n * with `type` and `id` only; each item's own contract is `jsonSchemaFor(type)`.\n * For an AI generation pipeline, ask for the group and each item separately\n * rather than a single nested schema — that keeps the per-type schema the\n * registry's, not a copy.\n */\nexport const itemGroupJsonSchema = z.toJSONSchema(ItemGroupSchema, { target: 'draft-7' });\n\n/**\n * JSON Schema (Draft 7) representation of the Multiple Choice activity data\n * contract, generated natively by Zod 4. Draft 7 is mandated by Requirement\n * 2.2 for the widest AI-prompt / OpenAPI tooling compatibility. The semantic\n * `.refine()` guards are not representable in JSON Schema and are\n * intentionally omitted — the export captures the *structural* contract only.\n * Since v0.3 the source schemas are loose, so these no longer emit\n * `additionalProperties: false` — the JSON Schema and `validateActivity` now\n * agree on unknown-key handling.\n */\n/**\n * JSON Schema (Draft 7) representation of the Gap Select activity data\n * contract. Structural contract only: the six semantic guards — the\n * passage/gap bijection, id uniqueness, the one-choice-source rule, and an\n * answer key that names a choice the gap offers — are Zod-only, as they are\n * for the other types.\n */\nexport const gapSelectJsonSchema = z.toJSONSchema(GapSelectDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Dictation activity data\n * contract. Structural contract, plus the raw length caps JSON Schema can\n * state in code points as zod counts them — `maxLength` 2000 on a transcript\n * and an accepted transcript, 200 on a rule's `from` and `to`. The twelve\n * semantic guards — a transcript that survives normalisation, the caps after\n * equivalences are applied, distinct candidates, audio only, the\n * slow-recording rules, no captions, no transcript in the title — are\n * Zod-only, as they are for the other types.\n */\nexport const dictationJsonSchema = z.toJSONSchema(DictationDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Read Aloud activity data\n * contract. Structural contract, plus the raw cap JSON Schema can state in code\n * points as zod counts them — `maxLength` 2000 on the reference text — and the\n * canonical locale pattern. The ten semantic guards — the cap after\n * normalisation, a text that survives it, the spaced-script rule, the\n * model-recording rules, unique dimensions, a weight above 0, and the take\n * bounds — are Zod-only, as they are for the other types.\n */\nexport const readAloudJsonSchema = z.toJSONSchema(ReadAloudDataSchema, {\n target: 'draft-7',\n});\n\nexport const multipleChoiceJsonSchema = z.toJSONSchema(MultipleChoiceDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Fill-in-the-Blanks activity data\n * contract, generated natively by Zod 4. Structural contract only (semantic\n * `.refine()` guards are Zod-only and not representable in JSON Schema).\n */\nexport const fillInTheBlanksJsonSchema = z.toJSONSchema(FillInTheBlanksDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Written Response activity data\n * contract. Structural contract only.\n */\nexport const writtenResponseJsonSchema = z.toJSONSchema(WrittenResponseDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * Derives the JSON Schema (Draft 7) for any REGISTERED activity type — the\n * live, registry-backed replacement for the static per-type exports above,\n * and the building block for AI generation pipelines (R6.1): pass the result\n * as a structured-output schema so a model can only emit valid items.\n *\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function jsonSchemaFor(type: string): Record<string, unknown> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(type);\n }\n return z.toJSONSchema(descriptor.schema as never, { target: 'draft-7' }) as Record<\n string,\n unknown\n >;\n}\n","import { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport type { ActivityDataMap, ActivityType, ValidationResult } from '../types/activity.js';\n\nexport { AiPermissionsSchema } from './ai.js';\nexport {\n DictationDataSchema,\n DictationEquivalenceSchema,\n DictationSlowMediaSchema,\n DictationToleranceSchema,\n} from './dictation.js';\nexport { FeedbackSchema } from './feedback.js';\nexport {\n BlankConfigSchema,\n FillInTheBlanksDataSchema,\n TextMatchPolicySchema,\n} from './fill-in-the-blanks.js';\nexport {\n GapSelectBankSchema,\n GapSelectChoiceSchema,\n GapSelectDataSchema,\n GapSelectGapSchema,\n} from './gap-select.js';\nexport type { RedactedStimulus } from './item-group.js';\nexport {\n ItemGroupSchema,\n MediaTimelineSchema,\n RedactedItemGroupSchema,\n RedactedStimulusSchema,\n StimulusSchema,\n TimelineChapterSchema,\n TimelineCueSchema,\n validateItemGroup,\n} from './item-group.js';\nexport {\n dictationJsonSchema,\n fillInTheBlanksJsonSchema,\n gapSelectJsonSchema,\n itemGroupJsonSchema,\n jsonSchemaFor,\n multipleChoiceJsonSchema,\n readAloudJsonSchema,\n stimulusJsonSchema,\n writtenResponseJsonSchema,\n} from './json-schema.js';\nexport {\n MediaPlaybackSchema,\n MediaSchema,\n MediaTrackSchema,\n MediaUrlSchema,\n NativeControlHintSchema,\n RedactedMediaSchema,\n} from './media.js';\nexport {\n MultipleChoiceDataSchema,\n MultipleChoiceOptionMediaSchema,\n MultipleChoiceOptionSchema,\n} from './multiple-choice.js';\nexport { ReadAloudDataSchema, ReadAloudSlowMediaSchema } from './read-aloud.js';\nexport type {\n RedactedActivity,\n RedactedBlankConfig,\n RedactedDictationData,\n RedactedDictationSlowMedia,\n RedactedFillInTheBlanksData,\n RedactedGapSelectBank,\n RedactedGapSelectChoice,\n RedactedGapSelectData,\n RedactedGapSelectGap,\n RedactedMultipleChoiceData,\n RedactedMultipleChoiceOption,\n RedactedMultipleChoiceOptionMedia,\n RedactedReadAloudData,\n RedactedWrittenResponseData,\n} from './redacted.js';\nexport {\n RedactedBlankConfigSchema,\n RedactedDictationDataSchema,\n RedactedDictationSlowMediaSchema,\n RedactedFillInTheBlanksDataSchema,\n RedactedGapSelectBankSchema,\n RedactedGapSelectChoiceSchema,\n RedactedGapSelectDataSchema,\n RedactedGapSelectGapSchema,\n RedactedMultipleChoiceDataSchema,\n RedactedMultipleChoiceOptionMediaSchema,\n RedactedMultipleChoiceOptionSchema,\n RedactedReadAloudDataSchema,\n RedactedWrittenResponseDataSchema,\n} from './redacted.js';\nexport {\n WrittenResponseDataSchema,\n WrittenResponseRubricCriterionSchema,\n WrittenResponseRubricSchema,\n} from './written-response.js';\n\n/**\n * Validates raw activity data against the schema registered for the given\n * activity type (built-in or consumer-registered via `registerActivityType`).\n *\n * Unknown keys are PRESERVED, not stripped: every built-in schema is loose,\n * so consumer sidecar fields and forward-version fields survive validation\n * verbatim in the returned `data`.\n *\n * @returns `{ success: true, data }` with the typed, validated data, or\n * `{ success: false, errors }` with one entry per failed constraint.\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function validateActivity<T extends ActivityType>(\n type: T,\n data: unknown,\n): ValidationResult<ActivityDataMap[T]> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(String(type));\n }\n\n const result = descriptor.schema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data as ActivityDataMap[T] };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n };\n}\n"]}
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
 
17
- var _chunkF7UOLKWVcjs = require('./chunk-F7UOLKWV.cjs');
17
+ var _chunkD4TOPSHVcjs = require('./chunk-D4TOPSHV.cjs');
18
18
 
19
19
  // src/is-redacted.ts
20
20
  function isRedacted(data) {
@@ -99,6 +99,12 @@ function selectFeedback(activityData, passed) {
99
99
  return _nullishCoalesce((passed ? feedback.correct : feedback.incorrect), () => ( null));
100
100
  }
101
101
 
102
+ // src/scoring/grade-numbers.ts
103
+ var OVERSHOOT = 1e-9;
104
+ function isGradeInRange(score2, maxScore) {
105
+ return Number.isFinite(maxScore) && maxScore > 0 && Number.isFinite(score2) && score2 >= 0 && score2 - maxScore <= maxScore * OVERSHOOT;
106
+ }
107
+
102
108
  // src/grading.ts
103
109
  function gradeFromRubric(criteria, activityData, options = {}) {
104
110
  const rounding = roundingPolicyOf(_optionalChain([options, 'optionalAccess', _ => _.rounding]));
@@ -147,12 +153,19 @@ function gradeFromRubric(criteria, activityData, options = {}) {
147
153
  reason: "Criterion weights do not sum to a positive number, so the weighted total is undefined."
148
154
  };
149
155
  }
156
+ const negativeWeight = scoreable.find((criterion) => (_nullishCoalesce(criterion.weight, () => ( 1))) < 0);
157
+ if (negativeWeight !== void 0) {
158
+ return {
159
+ unscorable: true,
160
+ reason: `Criterion "${negativeWeight.name}" has weight ${String(negativeWeight.weight)}; a weight must be zero or more.`
161
+ };
162
+ }
150
163
  const weighted = scoreable.reduce(
151
164
  (sum, criterion) => sum + ratioOf(criterion) * (_nullishCoalesce(criterion.weight, () => ( 1))),
152
165
  0
153
166
  );
154
167
  const rawScore = weighted / totalWeight;
155
- if (!Number.isFinite(rawScore)) {
168
+ if (!Number.isFinite(totalWeight) || !Number.isFinite(rawScore)) {
156
169
  return {
157
170
  unscorable: true,
158
171
  reason: "The weighted total is not a finite number, so no grade can be produced."
@@ -170,11 +183,15 @@ function gradeFromRubric(criteria, activityData, options = {}) {
170
183
  };
171
184
  }
172
185
  function outcomeFromGrade(grade) {
186
+ const { score: score2, maxScore } = grade;
187
+ if (!isGradeInRange(score2, maxScore)) {
188
+ return { status: "deferred", reason: "grade_rejected", maxScore: 1, rejectedGrade: grade };
189
+ }
173
190
  return {
174
191
  status: "graded",
175
192
  grade,
176
- score: grade.score,
177
- maxScore: grade.maxScore,
193
+ score: score2,
194
+ maxScore,
178
195
  passed: grade.passed,
179
196
  feedback: grade.feedback
180
197
  };
@@ -187,29 +204,41 @@ function hasGrade(outcome) {
187
204
  function earned(item) {
188
205
  const { outcome } = item;
189
206
  if (hasGrade(outcome)) {
190
- const max = outcome.maxScore > 0 ? outcome.maxScore : 1;
191
- return { state: "graded", points: outcome.score / max * item.points };
207
+ const { score: score2, maxScore } = outcome;
208
+ if (!isGradeInRange(score2, maxScore)) {
209
+ return { state: "rejected" };
210
+ }
211
+ return { state: "graded", points: score2 / maxScore * item.points };
192
212
  }
193
213
  if (outcome.status === "deferred") {
194
- return { state: "pending" };
214
+ return outcome.reason === "grade_rejected" ? { state: "rejected" } : { state: "pending" };
195
215
  }
196
216
  return { state: "unscorable" };
197
217
  }
218
+ function rejectedField(slotIds) {
219
+ return slotIds.length > 0 ? { rejectedSlotIds: slotIds } : {};
220
+ }
198
221
  function composeAssessmentScore(sections, policy) {
199
222
  const pendingAll = [];
223
+ const rejectedAll = [];
200
224
  const unscorableAll = [];
201
225
  const partials = sections.map((section) => {
202
226
  let earnedPoints = 0;
203
227
  let gradedMaxPoints = 0;
204
228
  let maxPoints = 0;
205
229
  const pendingSlotIds = [];
230
+ const rejectedSlotIds = [];
206
231
  const unscorableSlotIds = [];
207
232
  for (const item of section.items) {
208
233
  maxPoints += item.points;
209
234
  const contribution = earned(item);
210
- if (contribution.state === "pending") {
235
+ if (contribution.state === "pending" || contribution.state === "rejected") {
211
236
  pendingSlotIds.push(item.slotId);
212
237
  pendingAll.push(item.slotId);
238
+ if (contribution.state === "rejected") {
239
+ rejectedSlotIds.push(item.slotId);
240
+ rejectedAll.push(item.slotId);
241
+ }
213
242
  continue;
214
243
  }
215
244
  if (contribution.state === "unscorable") {
@@ -230,6 +259,7 @@ function composeAssessmentScore(sections, policy) {
230
259
  score: roundGrade(raw, policy.rounding),
231
260
  appliedThreshold,
232
261
  pendingSlotIds,
262
+ rejectedSlotIds,
233
263
  unscorableSlotIds
234
264
  };
235
265
  });
@@ -250,6 +280,7 @@ function composeAssessmentScore(sections, policy) {
250
280
  passed: partial.appliedThreshold === null || partial.gradedMaxPoints === 0 ? true : gte(partial.score, partial.appliedThreshold, policy.rounding),
251
281
  appliedThreshold: partial.appliedThreshold,
252
282
  pendingSlotIds: partial.pendingSlotIds,
283
+ ...rejectedField(partial.rejectedSlotIds),
253
284
  unscorableSlotIds: partial.unscorableSlotIds
254
285
  }));
255
286
  const weightedRaw = scored.reduce(
@@ -266,6 +297,7 @@ function composeAssessmentScore(sections, policy) {
266
297
  passFailureReason: null,
267
298
  status,
268
299
  pendingSlotIds: pendingAll,
300
+ ...rejectedField(rejectedAll),
269
301
  unscorableSlotIds: unscorableAll
270
302
  };
271
303
  }
@@ -277,6 +309,7 @@ function composeAssessmentScore(sections, policy) {
277
309
  passFailureReason: null,
278
310
  status,
279
311
  pendingSlotIds: pendingAll,
312
+ ...rejectedField(rejectedAll),
280
313
  unscorableSlotIds: unscorableAll
281
314
  };
282
315
  }
@@ -291,6 +324,7 @@ function composeAssessmentScore(sections, policy) {
291
324
  passFailureReason,
292
325
  status,
293
326
  pendingSlotIds: pendingAll,
327
+ ...rejectedField(rejectedAll),
294
328
  unscorableSlotIds: unscorableAll
295
329
  };
296
330
  }
@@ -299,12 +333,12 @@ function composeAssessmentScore(sections, policy) {
299
333
  function diffDictationChars(reference, attempt) {
300
334
  const referencePoints = Array.from(reference);
301
335
  const attemptPoints = Array.from(attempt);
302
- return _chunkF7UOLKWVcjs.alignSequences.call(void 0, referencePoints, attemptPoints).map(
336
+ return _chunkD4TOPSHVcjs.alignSequences.call(void 0, referencePoints, attemptPoints).map(
303
337
  ({ step, referenceIndex, attemptIndex }) => {
304
- if (step === _chunkF7UOLKWVcjs.STEP.missing) {
338
+ if (step === _chunkD4TOPSHVcjs.STEP.missing) {
305
339
  return { op: "missing", reference: referencePoints[referenceIndex], attempt: "" };
306
340
  }
307
- if (step === _chunkF7UOLKWVcjs.STEP.extra) {
341
+ if (step === _chunkD4TOPSHVcjs.STEP.extra) {
308
342
  return { op: "extra", reference: "", attempt: attemptPoints[attemptIndex] };
309
343
  }
310
344
  const referencePoint = referencePoints[referenceIndex];
@@ -326,14 +360,14 @@ function heardTokens(words) {
326
360
  const tokens = [];
327
361
  let length = 0;
328
362
  for (const [wordIndex, word] of words.entries()) {
329
- const normalized = _chunkF7UOLKWVcjs.normalizeDictationText.call(void 0, word.text);
363
+ const normalized = _chunkD4TOPSHVcjs.normalizeDictationText.call(void 0, word.text);
330
364
  if (normalized === "") {
331
365
  continue;
332
366
  }
333
367
  const inserted = word.error === "insertion";
334
368
  for (const text of normalized.split(" ")) {
335
- length += _chunkF7UOLKWVcjs.codePointLength.call(void 0, text) + (length === 0 ? 0 : 1);
336
- if (!inserted && length <= _chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH) {
369
+ length += _chunkD4TOPSHVcjs.codePointLength.call(void 0, text) + (length === 0 ? 0 : 1);
370
+ if (!inserted && length <= _chunkD4TOPSHVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH) {
337
371
  tokens.push({ text, wordIndex });
338
372
  }
339
373
  }
@@ -384,7 +418,7 @@ var SpeechAssessmentSchema = _v4.z.strictObject({
384
418
  assessmentVersion: _v4.z.literal("1.0"),
385
419
  status: _v4.z.enum(["assessed", "no_speech"]),
386
420
  task: _v4.z.enum(["scripted", "unscripted"]),
387
- locale: _v4.z.string().regex(_chunkF7UOLKWVcjs.CANONICAL_LOCALE_RE),
421
+ locale: _v4.z.string().regex(_chunkD4TOPSHVcjs.CANONICAL_LOCALE_RE),
388
422
  referenceText: _v4.z.string().max(8e3).optional(),
389
423
  recordingKey: _v4.z.string().min(1).max(1024).optional(),
390
424
  assessor: AssessorSchema,
@@ -399,7 +433,7 @@ var SpeechAssessmentSchema = _v4.z.strictObject({
399
433
  recognizedText: _v4.z.string().max(8e3).optional(),
400
434
  miscue: _v4.z.enum(["assessor", "none"]),
401
435
  phonemeAlphabet: _v4.z.enum(["ipa", "sapi"]).optional(),
402
- words: _v4.z.array(WordSchema).max(_chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_WORDS),
436
+ words: _v4.z.array(WordSchema).max(_chunkD4TOPSHVcjs.SPEECH_ASSESSMENT_MAX_WORDS),
403
437
  prosody: _v4.z.strictObject({ monotoneConfidence: Confidence.optional() }).optional(),
404
438
  signal: _v4.z.strictObject({ snrDb: _v4.z.number().optional() }).optional()
405
439
  });
@@ -421,21 +455,21 @@ function rawTextLength(words) {
421
455
  }
422
456
  function totalTextErrors(words) {
423
457
  const raw = rawTextLength(words);
424
- if (raw > _chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH) {
458
+ if (raw > _chunkD4TOPSHVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH) {
425
459
  return [
426
460
  {
427
461
  path: ["words"],
428
- message: `The words of an assessment carry ${raw} characters between them, and at most ${_chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH} can be aligned against the text of an item.`,
462
+ message: `The words of an assessment carry ${raw} characters between them, and at most ${_chunkD4TOPSHVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH} can be aligned against the text of an item.`,
429
463
  code: "too_big"
430
464
  }
431
465
  ];
432
466
  }
433
467
  const normalized = heardTokens(words).length;
434
- if (normalized > _chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH) {
468
+ if (normalized > _chunkD4TOPSHVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH) {
435
469
  return [
436
470
  {
437
471
  path: ["words"],
438
- message: `The words of an assessment spell ${normalized} characters between them once they are normalised, and at most ${_chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH} can be aligned against the text of an item. One character can stand for several.`,
472
+ message: `The words of an assessment spell ${normalized} characters between them once they are normalised, and at most ${_chunkD4TOPSHVcjs.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH} can be aligned against the text of an item. One character can stand for several.`,
439
473
  code: "too_big"
440
474
  }
441
475
  ];
@@ -505,16 +539,16 @@ function alignReadAloud(data, assessment) {
505
539
  return alignValidated(data, checked.data);
506
540
  }
507
541
  function alignValidated(data, assessment) {
508
- const reference = _chunkF7UOLKWVcjs.dictationReferenceWords.call(void 0, {
542
+ const reference = _chunkD4TOPSHVcjs.dictationReferenceWords.call(void 0, {
509
543
  transcript: data.referenceText
510
544
  })[0];
511
545
  const heard = heardTokens(assessment.words).tokens;
512
546
  const entries = [];
513
- for (const { step, referenceIndex, attemptIndex } of _chunkF7UOLKWVcjs.alignSequences.call(void 0,
547
+ for (const { step, referenceIndex, attemptIndex } of _chunkD4TOPSHVcjs.alignSequences.call(void 0,
514
548
  reference.map((word) => word.word),
515
549
  heard.map((token) => token.text)
516
550
  )) {
517
- if (step === _chunkF7UOLKWVcjs.STEP.extra) {
551
+ if (step === _chunkD4TOPSHVcjs.STEP.extra) {
518
552
  const token2 = heard[attemptIndex];
519
553
  entries.push({
520
554
  reference: "",
@@ -526,7 +560,7 @@ function alignValidated(data, assessment) {
526
560
  continue;
527
561
  }
528
562
  const referenceWord = reference[referenceIndex];
529
- if (step === _chunkF7UOLKWVcjs.STEP.missing) {
563
+ if (step === _chunkD4TOPSHVcjs.STEP.missing) {
530
564
  entries.push({
531
565
  itemId: referenceWord.itemId,
532
566
  reference: referenceWord.word,
@@ -579,7 +613,7 @@ function placeInsertions(assessment, entries) {
579
613
  reference: "",
580
614
  // Every insertion is accounted for, including one whose text normalises
581
615
  // to nothing: a reader of `wordIndex` must find each word it looks for.
582
- heard: _chunkF7UOLKWVcjs.normalizeDictationText.call(void 0, word.text),
616
+ heard: _chunkD4TOPSHVcjs.normalizeDictationText.call(void 0, word.text),
583
617
  state: "inserted",
584
618
  ...accuracyOf(word),
585
619
  wordIndex
@@ -616,9 +650,9 @@ function readResponseRecording(value) {
616
650
  function spokenWordCount(assessment) {
617
651
  const recognized = assessment.recognizedText;
618
652
  if (recognized !== void 0 && recognized.trim() !== "") {
619
- return _chunkF7UOLKWVcjs.countWords.call(void 0, recognized);
653
+ return _chunkD4TOPSHVcjs.countWords.call(void 0, recognized);
620
654
  }
621
- return _chunkF7UOLKWVcjs.countWords.call(void 0,
655
+ return _chunkD4TOPSHVcjs.countWords.call(void 0,
622
656
  assessment.words.filter((word) => word.error !== "omission" && word.error !== "insertion").map((word) => word.text).join(" ")
623
657
  );
624
658
  }
@@ -642,9 +676,9 @@ function gradeReadAloud(data, response, assessment, options) {
642
676
  );
643
677
  }
644
678
  const rounding = roundingPolicyOf(_optionalChain([options, 'optionalAccess', _6 => _6.rounding]));
645
- const parsed = _chunkF7UOLKWVcjs.ReadAloudDataSchema.safeParse(data);
679
+ const parsed = _chunkD4TOPSHVcjs.ReadAloudDataSchema.safeParse(data);
646
680
  if (!parsed.success) {
647
- throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(
681
+ throw new (0, _chunkD4TOPSHVcjs.ActivitySchemaError)(
648
682
  "read-aloud",
649
683
  parsed.error.issues.map((issue) => ({
650
684
  path: issue.path.map(String),
@@ -654,7 +688,7 @@ function gradeReadAloud(data, response, assessment, options) {
654
688
  );
655
689
  }
656
690
  if (isRedacted(data) || isRedacted(parsed.data)) {
657
- throw new (0, _chunkF7UOLKWVcjs.RedactedScoringError)("read-aloud");
691
+ throw new (0, _chunkD4TOPSHVcjs.RedactedScoringError)("read-aloud");
658
692
  }
659
693
  const item = parsed.data;
660
694
  const checkedResponse = readResponseRecording(response);
@@ -807,7 +841,7 @@ function gradeReadAloud(data, response, assessment, options) {
807
841
  };
808
842
  }
809
843
  function referenceWordsOf(data) {
810
- return _chunkF7UOLKWVcjs.dictationReferenceWords.call(void 0, { transcript: data.referenceText })[0];
844
+ return _chunkD4TOPSHVcjs.dictationReferenceWords.call(void 0, { transcript: data.referenceText })[0];
811
845
  }
812
846
 
813
847
  // src/scoring/speech/wav.ts
@@ -949,19 +983,19 @@ function outcomeFromUnscorable(result) {
949
983
  // src/scoring/index.ts
950
984
  function score(activityType, activityData, learnerResponse, options) {
951
985
  const rounding = roundingPolicyOf(_optionalChain([options, 'optionalAccess', _9 => _9.rounding]));
952
- const descriptor = _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, activityType);
986
+ const descriptor = _chunkD4TOPSHVcjs.getActivityTypeDescriptor.call(void 0, activityType);
953
987
  if (descriptor === void 0) {
954
- throw new (0, _chunkF7UOLKWVcjs.UnknownActivityTypeError)(String(activityType));
988
+ throw new (0, _chunkD4TOPSHVcjs.UnknownActivityTypeError)(String(activityType));
955
989
  }
956
990
  if (descriptor.scoring.kind === "deferred") {
957
- throw new (0, _chunkF7UOLKWVcjs.DeferredScoringError)(descriptor.type);
991
+ throw new (0, _chunkD4TOPSHVcjs.DeferredScoringError)(descriptor.type);
958
992
  }
959
993
  if (isRedacted(activityData)) {
960
- throw new (0, _chunkF7UOLKWVcjs.RedactedScoringError)(descriptor.type);
994
+ throw new (0, _chunkD4TOPSHVcjs.RedactedScoringError)(descriptor.type);
961
995
  }
962
996
  const result = descriptor.scoring.score(activityData, learnerResponse);
963
997
  if (!Number.isFinite(result.score)) {
964
- throw new (0, _chunkF7UOLKWVcjs.RedactedScoringError)(descriptor.type);
998
+ throw new (0, _chunkD4TOPSHVcjs.RedactedScoringError)(descriptor.type);
965
999
  }
966
1000
  const passed = computePassThreshold(activityData, result.score, rounding);
967
1001
  return { ...result, passed, feedback: _nullishCoalesce(result.feedback, () => ( selectFeedback(activityData, passed))) };
@@ -969,7 +1003,7 @@ function score(activityType, activityData, learnerResponse, options) {
969
1003
  function evaluate(data, response, options) {
970
1004
  const rounding = roundingPolicyOf(_optionalChain([options, 'optionalAccess', _10 => _10.rounding]));
971
1005
  const type = data.type;
972
- const descriptor = typeof type === "string" ? _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, type) : void 0;
1006
+ const descriptor = typeof type === "string" ? _chunkD4TOPSHVcjs.getActivityTypeDescriptor.call(void 0, type) : void 0;
973
1007
  if (descriptor === void 0) {
974
1008
  return {
975
1009
  status: "unscorable",
@@ -1030,5 +1064,6 @@ function evaluate(data, response, options) {
1030
1064
 
1031
1065
 
1032
1066
 
1033
- exports.roundGrade = roundGrade; exports.gte = gte; exports.classifyBand = classifyBand; exports.DEFAULT_PASS_THRESHOLD = DEFAULT_PASS_THRESHOLD; exports.computePassThreshold = computePassThreshold; exports.gradeFromRubric = gradeFromRubric; exports.outcomeFromGrade = outcomeFromGrade; exports.hasGrade = hasGrade; exports.composeAssessmentScore = composeAssessmentScore; exports.diffDictationChars = diffDictationChars; exports.validateSpeechAssessment = validateSpeechAssessment; exports.alignReadAloud = alignReadAloud; exports.gradeReadAloud = gradeReadAloud; exports.inspectWav = inspectWav; exports.outcomeFromUnscorable = outcomeFromUnscorable; exports.score = score; exports.evaluate = evaluate;
1034
- //# sourceMappingURL=chunk-6P6XK2LI.cjs.map
1067
+
1068
+ exports.isGradeInRange = isGradeInRange; exports.roundGrade = roundGrade; exports.gte = gte; exports.classifyBand = classifyBand; exports.DEFAULT_PASS_THRESHOLD = DEFAULT_PASS_THRESHOLD; exports.computePassThreshold = computePassThreshold; exports.gradeFromRubric = gradeFromRubric; exports.outcomeFromGrade = outcomeFromGrade; exports.hasGrade = hasGrade; exports.composeAssessmentScore = composeAssessmentScore; exports.diffDictationChars = diffDictationChars; exports.validateSpeechAssessment = validateSpeechAssessment; exports.alignReadAloud = alignReadAloud; exports.gradeReadAloud = gradeReadAloud; exports.inspectWav = inspectWav; exports.outcomeFromUnscorable = outcomeFromUnscorable; exports.score = score; exports.evaluate = evaluate;
1069
+ //# sourceMappingURL=chunk-COBK2RUX.cjs.map