Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 21x 30x 60x 87x 60x 30x 30x 30x 30x 390x 390x 30x 30x 30x | import type { ExampleFocusArea } from "../../course-content/embedded-tutor-annotation";
import { validateCurriculumTopic, type CurriculumTopic } from "./curriculum-schema";
export const INLINE_FOCUS_TOPIC_PREFIX = "inline-";
/**
* Builds the Topic for the focus areas a teacher wrote into an Example's annotation. Every focus area
* is one Concept with its questions; a focus area is mastered once every one of its questions was
* answered successfully, and progression uses fixed defaults. The questions carry
* no fact requirements: the teacher authored them for exactly this sketch.
*/
export function buildInlineFocusTopic(exampleId: string, focus: readonly ExampleFocusArea[]): CurriculumTopic {
const topic: CurriculumTopic = {
schemaVersion: 1,
id: `${INLINE_FOCUS_TOPIC_PREFIX}${toSafeId(exampleId)}`,
title: "Fokus dieses Beispiels",
locale: "de-DE",
activation: { any: [{ fact: "serial-call", values: ["print", "write"] }] },
concepts: focus.map((area) => ({
id: area.id,
title: area.title,
objective: area.objective,
prerequisites: [],
difficulty: { entry: [1, 100], transfer: [1, 100] },
misconceptions: [],
indicators: [{ id: `understands-${area.id}`.slice(0, 64), description: area.objective }],
mastery: {
minimumSuccessfulProbes: area.questions.length,
successRatingAtLeast: 3,
requiredIndicators: [`understands-${area.id}`.slice(0, 64)],
minimumDistinctQuestionKinds: 1,
recentWeakAnswersAllowed: 0,
},
})),
questions: focus.flatMap((area) => area.questions.map((question, index) => ({
id: `${area.id}-q${index + 1}`.slice(0, 64),
concept: area.id,
indicator: `understands-${area.id}`.slice(0, 64),
kind: question.kind,
difficulty: [1, 100] as [number, number],
requires: [],
text: question.text,
}))),
scaffolds: [],
progression: {
entryConcepts: [focus[0]?.id ?? ""],
preferredOrder: focus.map(({ id }) => id),
onRating: {
"1-2": "remediate",
"3": "clarify-same-indicator",
"4": "probe-missing-indicator",
"5": "evaluate-mastery-and-advance",
},
},
};
return validateCurriculumTopic(topic);
}
function toSafeId(value: string): string {
const parts: string[] = [];
let current = "";
for (const character of value.toLowerCase()) {
if ((character >= "a" && character <= "z") || (character >= "0" && character <= "9") || character === "-") {
current += character;
} else Eif (current !== "") {
parts.push(current);
current = "";
}
}
Eif (current !== "") parts.push(current);
const cleaned = parts.join("-").replaceAll("--", "-");
return (cleaned === "" ? "example" : cleaned).slice(0, 64 - INLINE_FOCUS_TOPIC_PREFIX.length);
}
|