{"version":3,"sources":["../src/components/Quiz/Quiz.utils.ts"],"sourcesContent":["import {\n  QuizVariant,\n  type QuestionAnswerResult,\n  type TrueOrFalseOptionState,\n} from './Quiz.types';\nimport { TrueFalseEnum } from '../../enums/Quiz';\nimport { OptionStatus } from '../../enums/Options';\n\n/**\n * Helper function to format exam info (bank - year)\n * @param examBoard - The exam board/bank name\n * @param examYear - The exam year\n * @returns Formatted string like \"(ENEM - 2023)\" or empty string if no info\n */\nexport const formatExamInfo = (\n  examBoard: string | null | undefined,\n  examYear: string | null | undefined\n): string => {\n  if (examBoard && examYear) {\n    return `(${examBoard} - ${examYear})`;\n  }\n  if (examBoard) {\n    return `(${examBoard})`;\n  }\n  if (examYear) {\n    return `(${examYear})`;\n  }\n  return '';\n};\n\n/**\n * Shuffle array using a seed for consistent ordering per question\n * Uses Fisher-Yates shuffle with seeded random for deterministic results\n */\nexport const shuffleWithSeed = <T>(array: T[], seed: string): T[] => {\n  const shuffled = [...array];\n  // Simple hash function to convert string seed to number\n  let hash = 0;\n  for (let i = 0; i < seed.length; i++) {\n    const char = seed.codePointAt(i) ?? 0;\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash; // Convert to 32bit integer\n  }\n  // Fisher-Yates shuffle with seeded random\n  const seededRandom = (max: number) => {\n    hash = (hash * 1103515245 + 12345) & 0x7fffffff;\n    return hash % max;\n  };\n  for (let i = shuffled.length - 1; i > 0; i--) {\n    const j = seededRandom(i + 1);\n    [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];\n  }\n  return shuffled;\n};\n\n/**\n * Helper to prepend letter to HTML content (handles <p> tags)\n * @example prependLetterToHtml('a', '<p>Text</p>') => '<p>a) Text</p>'\n * @example prependLetterToHtml('a', 'Text') => 'a) Text'\n */\nexport const prependLetterToHtml = (letter: string, html: string): string => {\n  if (html.trim().startsWith('<p>')) {\n    return html.replace(/^(\\s*<p>)/, `$1${letter}) `);\n  }\n  return `${letter}) ${html}`;\n};\n\n/**\n * Compute state for a true/false option\n * Handles both interactive (default) and result modes\n */\nexport const getTrueOrFalseOptionState = (\n  optionId: string,\n  variant: string,\n  currentQuestionResult: QuestionAnswerResult | null | undefined,\n  localAnswers: Record<string, string>\n): TrueOrFalseOptionState => {\n  // Get whether the statement is TRUE or FALSE from persisted result\n  const correctAnswerOption = currentQuestionResult?.options?.find(\n    (op) => op.id === optionId\n  );\n  const isStatementTrue =\n    variant === QuizVariant.RESULT\n      ? (correctAnswerOption?.isCorrect ?? false)\n      : false;\n\n  // Get student's selection from selectedOptions\n  const studentSelection =\n    variant === QuizVariant.RESULT\n      ? currentQuestionResult?.selectedOptions?.find(\n          (op) => op.optionId === optionId\n        )\n      : undefined;\n\n  // Determine if answered and what was marked\n  const hasAnswered =\n    variant === QuizVariant.RESULT\n      ? studentSelection !== undefined\n      : !!localAnswers[optionId];\n\n  const studentMarkedTrue =\n    variant === QuizVariant.RESULT\n      ? (studentSelection?.isCorrect ?? false)\n      : localAnswers[optionId] === TrueFalseEnum.VERDADEIRO;\n\n  // Compute display values\n  const getStudentAnswerDisplay = (): string => {\n    if (variant !== QuizVariant.RESULT) {\n      return localAnswers[optionId] || '-';\n    }\n    if (!hasAnswered) {\n      return '-';\n    }\n    return studentMarkedTrue ? TrueFalseEnum.VERDADEIRO : TrueFalseEnum.FALSO;\n  };\n  const studentAnswer = getStudentAnswerDisplay();\n\n  const correctAnswer = isStatementTrue\n    ? TrueFalseEnum.VERDADEIRO\n    : TrueFalseEnum.FALSO;\n  const isStudentCorrect = hasAnswered && studentMarkedTrue === isStatementTrue;\n  const variantCorrect = isStudentCorrect\n    ? OptionStatus.CORRECT\n    : OptionStatus.INCORRECT;\n\n  return {\n    isStatementTrue,\n    hasAnswered,\n    studentMarkedTrue,\n    studentAnswer,\n    correctAnswer,\n    isStudentCorrect,\n    variantCorrect,\n  };\n};\n"],"mappings":";AAcO,IAAM,iBAAiB,CAC5B,WACA,aACW;AACX,MAAI,aAAa,UAAU;AACzB,WAAO,IAAI,SAAS,MAAM,QAAQ;AAAA,EACpC;AACA,MAAI,WAAW;AACb,WAAO,IAAI,SAAS;AAAA,EACtB;AACA,MAAI,UAAU;AACZ,WAAO,IAAI,QAAQ;AAAA,EACrB;AACA,SAAO;AACT;AAMO,IAAM,kBAAkB,CAAI,OAAY,SAAsB;AACnE,QAAM,WAAW,CAAC,GAAG,KAAK;AAE1B,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,OAAO,KAAK,YAAY,CAAC,KAAK;AACpC,YAAQ,QAAQ,KAAK,OAAO;AAC5B,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,eAAe,CAAC,QAAgB;AACpC,WAAQ,OAAO,aAAa,QAAS;AACrC,WAAO,OAAO;AAAA,EAChB;AACA,WAAS,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;AAC5C,UAAM,IAAI,aAAa,IAAI,CAAC;AAC5B,KAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAOO,IAAM,sBAAsB,CAAC,QAAgB,SAAyB;AAC3E,MAAI,KAAK,KAAK,EAAE,WAAW,KAAK,GAAG;AACjC,WAAO,KAAK,QAAQ,aAAa,KAAK,MAAM,IAAI;AAAA,EAClD;AACA,SAAO,GAAG,MAAM,KAAK,IAAI;AAC3B;AAMO,IAAM,4BAA4B,CACvC,UACA,SACA,uBACA,iBAC2B;AAE3B,QAAM,sBAAsB,uBAAuB,SAAS;AAAA,IAC1D,CAAC,OAAO,GAAG,OAAO;AAAA,EACpB;AACA,QAAM,kBACJ,oCACK,qBAAqB,aAAa,QACnC;AAGN,QAAM,mBACJ,oCACI,uBAAuB,iBAAiB;AAAA,IACtC,CAAC,OAAO,GAAG,aAAa;AAAA,EAC1B,IACA;AAGN,QAAM,cACJ,oCACI,qBAAqB,SACrB,CAAC,CAAC,aAAa,QAAQ;AAE7B,QAAM,oBACJ,oCACK,kBAAkB,aAAa,QAChC,aAAa,QAAQ;AAG3B,QAAM,0BAA0B,MAAc;AAC5C,QAAI,mCAAgC;AAClC,aAAO,aAAa,QAAQ,KAAK;AAAA,IACnC;AACA,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,wBAAwB;AAE9C,QAAM,gBAAgB;AAGtB,QAAM,mBAAmB,eAAe,sBAAsB;AAC9D,QAAM,iBAAiB;AAIvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}