import {Module} from "."; export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam; export type Variant = "diagnostic" | "partial"; export interface ReadingExam { parts: ReadingPart[]; id: string; module: "reading"; minTimer: number; type: "academic" | "general"; isDiagnostic: boolean; variant?: Variant; } export interface ReadingPart { text: { title: string; content: string; }; exercises: Exercise[]; } export interface LevelExam { module: "level"; id: string; exercises: Exercise[]; minTimer: number; isDiagnostic: boolean; variant?: Variant; } export interface ListeningExam { parts: ListeningPart[]; id: string; module: "listening"; minTimer: number; isDiagnostic: boolean; variant?: Variant; } export interface ListeningPart { audio: { source: string; repeatableTimes: number; // *The amount of times the user is allowed to repeat the audio, 0 for unlimited }; exercises: Exercise[]; } export interface UserSolution { id?: string; solutions: any[]; module?: Module; exam?: string; type: string; score: { correct: number; total: number; missing: number; }; exercise: string; } export interface WritingExam { module: "writing"; id: string; exercises: Exercise[]; minTimer: number; isDiagnostic: boolean; variant?: Variant; } interface WordCounter { type: "min" | "max"; limit: number; } export interface SpeakingExam { id: string; module: "speaking"; exercises: Exercise[]; minTimer: number; isDiagnostic: boolean; variant?: Variant; } export type Exercise = | FillBlanksExercise | TrueFalseExercise | MatchSentencesExercise | MultipleChoiceExercise | WriteBlanksExercise | WritingExercise | SpeakingExercise | InteractiveSpeakingExercise; export interface Evaluation { comment: string; overall: number; task_response: {[key: string]: number}; misspelled_pairs?: {correction: string | null; misspelled: string}[]; } interface InteractiveSpeakingEvaluation extends Evaluation { perfect_answer_1?: string; perfect_answer_2?: string; perfect_answer_3?: string; } interface CommonEvaluation extends Evaluation { perfect_answer?: string; perfect_answer_1?: string; fixed_text?: string; } export interface WritingExercise { id: string; type: "writing"; prefix: string; //* The information about the task, like the amount of time they should spend on it suffix: string; prompt: string; //* The context given to the user containing what they should write about wordCounter: WordCounter; //* The minimum or maximum amount of words that should be written attachment?: { url: string; description: string; }; //* The url for an image to work as an attachment to show the user userSolutions: { id: string; solution: string; evaluation?: CommonEvaluation; }[]; } export interface SpeakingExercise { id: string; type: "speaking"; title: string; text: string; prompts: string[]; video_url: string; userSolutions: { id: string; solution: string; evaluation?: CommonEvaluation; }[]; } export interface InteractiveSpeakingExercise { id: string; type: "interactiveSpeaking"; title: string; text: string; prompts: {text: string; video_url: string}[]; userSolutions: { id: string; solution: {question: string; answer: string}[]; evaluation?: InteractiveSpeakingEvaluation; }[]; } export interface FillBlanksExercise { prompt: string; // *EXAMPLE: "Complete the summary below. Click a blank to select the corresponding word for it." type: "fillBlanks"; id: string; words: string[]; // *EXAMPLE: ["preserve", "unaware"] text: string; // *EXAMPLE: "They tried to {{1}} burning" allowRepetition: boolean; solutions: { id: string; // *EXAMPLE: "1" solution: string; // *EXAMPLE: "preserve" }[]; userSolutions: { id: string; // *EXAMPLE: "1" solution: string; // *EXAMPLE: "preserve" }[]; } export interface TrueFalseExercise { type: "trueFalse"; id: string; prompt: string; // *EXAMPLE: "Select the appropriate option." questions: TrueFalseQuestion[]; userSolutions: {id: string; solution: "true" | "false" | "not_given"}[]; } export interface TrueFalseQuestion { id: string; // *EXAMPLE: "1" prompt: string; // *EXAMPLE: "What does her briefcase look like?" solution: "true" | "false" | "not_given"; // *EXAMPLE: "True" } export interface WriteBlanksExercise { prompt: string; // *EXAMPLE: "Complete the notes below by writing NO MORE THAN THREE WORDS in the spaces provided." maxWords: number; // *EXAMPLE: 3 - The maximum amount of words allowed per blank, 0 for unlimited type: "writeBlanks"; id: string; text: string; // *EXAMPLE: "The Government plans to give ${{14}}" solutions: { id: string; // *EXAMPLE: "14" solution: string[]; // *EXAMPLE: ["Prescott"] - All possible solutions (case sensitive) }[]; userSolutions: { id: string; solution: string; }[]; } export interface MatchSentencesExercise { type: "matchSentences"; id: string; prompt: string; userSolutions: {question: string; option: string}[]; sentences: { id: string; sentence: string; solution: string; color: string; }[]; allowRepetition: boolean; options: { id: string; sentence: string; }[]; } export interface MultipleChoiceExercise { type: "multipleChoice"; id: string; prompt: string; // *EXAMPLE: "Select the appropriate option." questions: MultipleChoiceQuestion[]; userSolutions: {question: string; option: string}[]; } export interface MultipleChoiceQuestion { variant: "image" | "text"; id: string; // *EXAMPLE: "1" prompt: string; // *EXAMPLE: "What does her briefcase look like?" solution: string; // *EXAMPLE: "A" options: { id: string; // *EXAMPLE: "A" src?: string; // *EXAMPLE: "https://i.imgur.com/rEbrSqA.png" (only used if the variant is "image") text?: string; // *EXAMPLE: "wallet, pens and novel" (only used if the variant is "text") }[]; }