@pie-element/multiple-choice 12.0.0-next.43 → 12.1.2-next.1

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.
@@ -11,7 +11,7 @@ exports.model = model;
11
11
  exports.normalize = void 0;
12
12
  exports.outcome = outcome;
13
13
  exports.validate = void 0;
14
- var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
14
+ var _lodashEs = require("lodash-es");
15
15
  var _utils = require("./utils");
16
16
  var _defaults = _interopRequireDefault(require("./defaults"));
17
17
  var _controllerUtils = require("@pie-lib/controller-utils");
@@ -123,7 +123,7 @@ async function model(question, session, env, updateSession) {
123
123
  return out;
124
124
  }
125
125
  const getScore = (config, session) => {
126
- if (!session || (0, _isEmpty.default)(session)) {
126
+ if (!session || (0, _lodashEs.isEmpty)(session)) {
127
127
  return 0;
128
128
  }
129
129
  const selectedChoices = session.value || [];
@@ -151,7 +151,7 @@ const getScore = (config, session) => {
151
151
  exports.getScore = getScore;
152
152
  function outcome(model, session, env) {
153
153
  return new Promise(resolve => {
154
- if (!session || (0, _isEmpty.default)(session)) {
154
+ if (!session || (0, _lodashEs.isEmpty)(session)) {
155
155
  resolve({
156
156
  score: 0,
157
157
  empty: true
@@ -239,10 +239,10 @@ const validate = (model = {}, config = {}) => {
239
239
  if (!hasCorrectResponse) {
240
240
  errors.correctResponse = 'No correct response defined.';
241
241
  }
242
- if (!(0, _isEmpty.default)(choicesErrors)) {
242
+ if (!(0, _lodashEs.isEmpty)(choicesErrors)) {
243
243
  errors.choices = choicesErrors;
244
244
  }
245
- if (!(0, _isEmpty.default)(rationaleErrors)) {
245
+ if (!(0, _lodashEs.isEmpty)(rationaleErrors)) {
246
246
  errors.rationale = rationaleErrors;
247
247
  }
248
248
  return errors;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_isEmpty","_interopRequireDefault","require","_utils","_defaults","_controllerUtils","prepareChoice","model","env","defaultFeedback","choice","role","mode","out","label","value","rationale","rationaleEnabled","correct","feedbackEnabled","feedbackType","feedback","type","createDefaultModel","Promise","resolve","defaults","normalize","question","verticalMode","choicesLayout","questionProps","exports","session","updateSession","normalizedQuestion","Object","assign","incorrect","choices","map","lockChoiceOrder","lockChoices","getShuffledChoices","disabled","prompt","promptEnabled","gridColumns","choiceMode","keyMode","choicePrefix","responseCorrect","isResponseCorrect","undefined","language","extraCSSRules","fontSizeFactor","isSelectionButtonBelow","selectedAnswerBackgroundColor","selectedAnswerStrokeColor","selectedAnswerStrokeWidth","hoverAnswerBackgroundColor","hoverAnswerStrokeColor","hoverAnswerStrokeWidth","minSelections","maxSelections","keyboardEventsEnabled","autoplayAudioEnabled","completeAudioEnabled","customAudioButton","teacherInstructions","teacherInstructionsEnabled","getScore","config","isEmpty","selectedChoices","correctChoices","filter","ch","score","reduce","acc","selectedChoice","find","length","str","parseFloat","toFixed","outcome","empty","partialScoringEnabled","partialScoring","enabled","createCorrectResponseSession","id","c","getInnerText","html","replaceAll","getContent","replace","validate","minAnswerChoices","maxAnswerChoices","reversedChoices","reverse","choicesErrors","rationaleErrors","errors","forEach","field","required","hasCorrectResponse","index","identicalAnswer","slice","some","nbOfChoices","answerChoices","correctResponse"],"sources":["../src/index.js"],"sourcesContent":["/* eslint-disable no-console */\nimport isEmpty from 'lodash/isEmpty';\nimport { isResponseCorrect } from './utils';\nimport defaults from './defaults';\nimport { lockChoices, partialScoring, getShuffledChoices } from '@pie-lib/controller-utils';\n\nconst prepareChoice = (model, env, defaultFeedback) => (choice) => {\n const { role, mode } = env || {};\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = model.rationaleEnabled ? choice.rationale : null;\n } else {\n out.rationale = null;\n }\n\n if (mode === 'evaluate') {\n out.correct = !!choice.correct;\n\n if (model.feedbackEnabled) {\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n }\n\n return out;\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => resolve({ ...defaults, ...model }));\n}\n\nexport const normalize = (question) => {\n const { verticalMode, choicesLayout, ...questionProps } = question || {};\n\n return {\n ...defaults,\n ...questionProps,\n // This is used for offering support for old models which have the property verticalMode\n // Same thing is set in authoring : packages/multiple-choice/configure/src/index.jsx - createDefaultModel\n choicesLayout: choicesLayout || (verticalMode === false && 'horizontal') || defaults.choicesLayout,\n };\n};\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport async function model(question, session, env, updateSession) {\n const normalizedQuestion = normalize(question);\n\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n let choices = (normalizedQuestion.choices || []).map(prepareChoice(normalizedQuestion, env, defaultFeedback));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'value');\n }\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choicesLayout: normalizedQuestion.choicesLayout,\n gridColumns: normalizedQuestion.gridColumns,\n choiceMode: normalizedQuestion.choiceMode,\n keyMode: normalizedQuestion.choicePrefix,\n choices,\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n language: normalizedQuestion.language,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n fontSizeFactor: normalizedQuestion.fontSizeFactor,\n isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,\n selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',\n selectedAnswerStrokeColor: normalizedQuestion.selectedAnswerStrokeColor || 'initial',\n selectedAnswerStrokeWidth: normalizedQuestion.selectedAnswerStrokeWidth || 'initial',\n hoverAnswerBackgroundColor: normalizedQuestion.hoverAnswerBackgroundColor || 'initial',\n hoverAnswerStrokeColor: normalizedQuestion.hoverAnswerStrokeColor || 'initial',\n hoverAnswerStrokeWidth: normalizedQuestion.hoverAnswerStrokeWidth || 'initial',\n minSelections: normalizedQuestion.minSelections,\n maxSelections: normalizedQuestion.maxSelections,\n keyboardEventsEnabled: normalizedQuestion.keyboardEventsEnabled,\n autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled,\n completeAudioEnabled: normalizedQuestion.completeAudioEnabled,\n customAudioButton: normalizedQuestion.customAudioButton,\n };\n\n const { role, mode } = env || {};\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n}\n\nexport const getScore = (config, session) => {\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n const selectedChoices = session.value || [];\n const correctChoices = (config.choices || []).filter((ch) => ch.correct);\n\n let score = selectedChoices.reduce(\n (acc, selectedChoice) => acc + (correctChoices.find((ch) => ch.value === selectedChoice) ? 1 : 0),\n 0,\n );\n\n if (correctChoices.length < selectedChoices.length) {\n score -= selectedChoices.length - correctChoices.length;\n\n if (score < 0) {\n score = 0;\n }\n }\n\n const str = correctChoices.length ? score / correctChoices.length : 0;\n\n return parseFloat(str.toFixed(2));\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will\n * override the value in `model`.\n * @param {Object} model - the main model\n * @param {*} session\n * @param {Object} env\n */\nexport function outcome(model, session, env) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n } else {\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n const score = getScore(model, session);\n\n resolve({ score: partialScoringEnabled ? score : score === 1 ? 1 : 0, empty: false });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question || { choices: [] };\n\n resolve({\n id: '1',\n value: choices.filter((c) => c.correct).map((c) => c.value),\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices } = model;\n const { minAnswerChoices = 2, maxAnswerChoices } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const choicesErrors = {};\n const rationaleErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n let hasCorrectResponse = false;\n\n reversedChoices.forEach((choice, index) => {\n const { correct, value, label, rationale } = choice;\n\n if (correct) {\n hasCorrectResponse = true;\n }\n\n if (!getContent(label)) {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n\n if (config.rationale?.required && !getContent(rationale)) {\n rationaleErrors[value] = 'This field is required.';\n }\n });\n\n const nbOfChoices = (choices || []).length;\n\n if (nbOfChoices < minAnswerChoices) {\n errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (!hasCorrectResponse) {\n errors.correctResponse = 'No correct response defined.';\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choices = choicesErrors;\n }\n\n if (!isEmpty(rationaleErrors)) {\n errors.rationale = rationaleErrors;\n }\n\n return errors;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_lodashEs","require","_utils","_defaults","_interopRequireDefault","_controllerUtils","prepareChoice","model","env","defaultFeedback","choice","role","mode","out","label","value","rationale","rationaleEnabled","correct","feedbackEnabled","feedbackType","feedback","type","createDefaultModel","Promise","resolve","defaults","normalize","question","verticalMode","choicesLayout","questionProps","exports","session","updateSession","normalizedQuestion","Object","assign","incorrect","choices","map","lockChoiceOrder","lockChoices","getShuffledChoices","disabled","prompt","promptEnabled","gridColumns","choiceMode","keyMode","choicePrefix","responseCorrect","isResponseCorrect","undefined","language","extraCSSRules","fontSizeFactor","isSelectionButtonBelow","selectedAnswerBackgroundColor","selectedAnswerStrokeColor","selectedAnswerStrokeWidth","hoverAnswerBackgroundColor","hoverAnswerStrokeColor","hoverAnswerStrokeWidth","minSelections","maxSelections","keyboardEventsEnabled","autoplayAudioEnabled","completeAudioEnabled","customAudioButton","teacherInstructions","teacherInstructionsEnabled","getScore","config","isEmpty","selectedChoices","correctChoices","filter","ch","score","reduce","acc","selectedChoice","find","length","str","parseFloat","toFixed","outcome","empty","partialScoringEnabled","partialScoring","enabled","createCorrectResponseSession","id","c","getInnerText","html","replaceAll","getContent","replace","validate","minAnswerChoices","maxAnswerChoices","reversedChoices","reverse","choicesErrors","rationaleErrors","errors","forEach","field","required","hasCorrectResponse","index","identicalAnswer","slice","some","nbOfChoices","answerChoices","correctResponse"],"sources":["../src/index.js"],"sourcesContent":["/* eslint-disable no-console */\nimport { isEmpty } from 'lodash-es';\nimport { isResponseCorrect } from './utils';\nimport defaults from './defaults';\nimport { lockChoices, partialScoring, getShuffledChoices } from '@pie-lib/controller-utils';\n\nconst prepareChoice = (model, env, defaultFeedback) => (choice) => {\n const { role, mode } = env || {};\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = model.rationaleEnabled ? choice.rationale : null;\n } else {\n out.rationale = null;\n }\n\n if (mode === 'evaluate') {\n out.correct = !!choice.correct;\n\n if (model.feedbackEnabled) {\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n }\n\n return out;\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => resolve({ ...defaults, ...model }));\n}\n\nexport const normalize = (question) => {\n const { verticalMode, choicesLayout, ...questionProps } = question || {};\n\n return {\n ...defaults,\n ...questionProps,\n // This is used for offering support for old models which have the property verticalMode\n // Same thing is set in authoring : packages/multiple-choice/configure/src/index.jsx - createDefaultModel\n choicesLayout: choicesLayout || (verticalMode === false && 'horizontal') || defaults.choicesLayout,\n };\n};\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport async function model(question, session, env, updateSession) {\n const normalizedQuestion = normalize(question);\n\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n let choices = (normalizedQuestion.choices || []).map(prepareChoice(normalizedQuestion, env, defaultFeedback));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'value');\n }\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choicesLayout: normalizedQuestion.choicesLayout,\n gridColumns: normalizedQuestion.gridColumns,\n choiceMode: normalizedQuestion.choiceMode,\n keyMode: normalizedQuestion.choicePrefix,\n choices,\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n language: normalizedQuestion.language,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n fontSizeFactor: normalizedQuestion.fontSizeFactor,\n isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,\n selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',\n selectedAnswerStrokeColor: normalizedQuestion.selectedAnswerStrokeColor || 'initial',\n selectedAnswerStrokeWidth: normalizedQuestion.selectedAnswerStrokeWidth || 'initial',\n hoverAnswerBackgroundColor: normalizedQuestion.hoverAnswerBackgroundColor || 'initial',\n hoverAnswerStrokeColor: normalizedQuestion.hoverAnswerStrokeColor || 'initial',\n hoverAnswerStrokeWidth: normalizedQuestion.hoverAnswerStrokeWidth || 'initial',\n minSelections: normalizedQuestion.minSelections,\n maxSelections: normalizedQuestion.maxSelections,\n keyboardEventsEnabled: normalizedQuestion.keyboardEventsEnabled,\n autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled,\n completeAudioEnabled: normalizedQuestion.completeAudioEnabled,\n customAudioButton: normalizedQuestion.customAudioButton,\n };\n\n const { role, mode } = env || {};\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n}\n\nexport const getScore = (config, session) => {\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n const selectedChoices = session.value || [];\n const correctChoices = (config.choices || []).filter((ch) => ch.correct);\n\n let score = selectedChoices.reduce(\n (acc, selectedChoice) => acc + (correctChoices.find((ch) => ch.value === selectedChoice) ? 1 : 0),\n 0,\n );\n\n if (correctChoices.length < selectedChoices.length) {\n score -= selectedChoices.length - correctChoices.length;\n\n if (score < 0) {\n score = 0;\n }\n }\n\n const str = correctChoices.length ? score / correctChoices.length : 0;\n\n return parseFloat(str.toFixed(2));\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will\n * override the value in `model`.\n * @param {Object} model - the main model\n * @param {*} session\n * @param {Object} env\n */\nexport function outcome(model, session, env) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n } else {\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n const score = getScore(model, session);\n\n resolve({ score: partialScoringEnabled ? score : score === 1 ? 1 : 0, empty: false });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question || { choices: [] };\n\n resolve({\n id: '1',\n value: choices.filter((c) => c.correct).map((c) => c.value),\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices } = model;\n const { minAnswerChoices = 2, maxAnswerChoices } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const choicesErrors = {};\n const rationaleErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n let hasCorrectResponse = false;\n\n reversedChoices.forEach((choice, index) => {\n const { correct, value, label, rationale } = choice;\n\n if (correct) {\n hasCorrectResponse = true;\n }\n\n if (!getContent(label)) {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n\n if (config.rationale?.required && !getContent(rationale)) {\n rationaleErrors[value] = 'This field is required.';\n }\n });\n\n const nbOfChoices = (choices || []).length;\n\n if (nbOfChoices < minAnswerChoices) {\n errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (!hasCorrectResponse) {\n errors.correctResponse = 'No correct response defined.';\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choices = choicesErrors;\n }\n\n if (!isEmpty(rationaleErrors)) {\n errors.rationale = rationaleErrors;\n }\n\n return errors;\n};\n"],"mappings":";;;;;;;;;;;;;AACA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,SAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,gBAAA,GAAAJ,OAAA;AAJA;;AAMA,MAAMK,aAAa,GAAGA,CAACC,KAAK,EAAEC,GAAG,EAAEC,eAAe,KAAMC,MAAM,IAAK;EACjE,MAAM;IAAEC,IAAI;IAAEC;EAAK,CAAC,GAAGJ,GAAG,IAAI,CAAC,CAAC;EAChC,MAAMK,GAAG,GAAG;IACVC,KAAK,EAAEJ,MAAM,CAACI,KAAK;IACnBC,KAAK,EAAEL,MAAM,CAACK;EAChB,CAAC;EAED,IAAIJ,IAAI,KAAK,YAAY,KAAKC,IAAI,KAAK,MAAM,IAAIA,IAAI,KAAK,UAAU,CAAC,EAAE;IACrEC,GAAG,CAACG,SAAS,GAAGT,KAAK,CAACU,gBAAgB,GAAGP,MAAM,CAACM,SAAS,GAAG,IAAI;EAClE,CAAC,MAAM;IACLH,GAAG,CAACG,SAAS,GAAG,IAAI;EACtB;EAEA,IAAIJ,IAAI,KAAK,UAAU,EAAE;IACvBC,GAAG,CAACK,OAAO,GAAG,CAAC,CAACR,MAAM,CAACQ,OAAO;IAE9B,IAAIX,KAAK,CAACY,eAAe,EAAE;MACzB,MAAMC,YAAY,GAAIV,MAAM,CAACW,QAAQ,IAAIX,MAAM,CAACW,QAAQ,CAACC,IAAI,IAAK,MAAM;MAExE,IAAIF,YAAY,KAAK,SAAS,EAAE;QAC9BP,GAAG,CAACQ,QAAQ,GAAGZ,eAAe,CAACC,MAAM,CAACQ,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;MAC1E,CAAC,MAAM,IAAIE,YAAY,KAAK,QAAQ,EAAE;QACpCP,GAAG,CAACQ,QAAQ,GAAGX,MAAM,CAACW,QAAQ,CAACN,KAAK;MACtC;IACF;EACF;EAEA,OAAOF,GAAG;AACZ,CAAC;AAEM,SAASU,kBAAkBA,CAAChB,KAAK,GAAG,CAAC,CAAC,EAAE;EAC7C,OAAO,IAAIiB,OAAO,CAAEC,OAAO,IAAKA,OAAO,CAAC;IAAE,GAAGC,iBAAQ;IAAE,GAAGnB;EAAM,CAAC,CAAC,CAAC;AACrE;AAEO,MAAMoB,SAAS,GAAIC,QAAQ,IAAK;EACrC,MAAM;IAAEC,YAAY;IAAEC,aAAa;IAAE,GAAGC;EAAc,CAAC,GAAGH,QAAQ,IAAI,CAAC,CAAC;EAExE,OAAO;IACL,GAAGF,iBAAQ;IACX,GAAGK,aAAa;IAChB;IACA;IACAD,aAAa,EAAEA,aAAa,IAAKD,YAAY,KAAK,KAAK,IAAI,YAAa,IAAIH,iBAAQ,CAACI;EACvF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AANAE,OAAA,CAAAL,SAAA,GAAAA,SAAA;AAOO,eAAepB,KAAKA,CAACqB,QAAQ,EAAEK,OAAO,EAAEzB,GAAG,EAAE0B,aAAa,EAAE;EACjE,MAAMC,kBAAkB,GAAGR,SAAS,CAACC,QAAQ,CAAC;EAE9C,MAAMnB,eAAe,GAAG2B,MAAM,CAACC,MAAM,CACnC;IAAEnB,OAAO,EAAE,SAAS;IAAEoB,SAAS,EAAE;EAAY,CAAC,EAC9CH,kBAAkB,CAAC1B,eACrB,CAAC;EAED,IAAI8B,OAAO,GAAG,CAACJ,kBAAkB,CAACI,OAAO,IAAI,EAAE,EAAEC,GAAG,CAAClC,aAAa,CAAC6B,kBAAkB,EAAE3B,GAAG,EAAEC,eAAe,CAAC,CAAC;EAE7G,MAAMgC,eAAe,GAAG,IAAAC,4BAAW,EAACP,kBAAkB,EAAEF,OAAO,EAAEzB,GAAG,CAAC;EAErE,IAAI,CAACiC,eAAe,EAAE;IACpBF,OAAO,GAAG,MAAM,IAAAI,mCAAkB,EAACJ,OAAO,EAAEN,OAAO,EAAEC,aAAa,EAAE,OAAO,CAAC;EAC9E;EAEA,MAAMrB,GAAG,GAAG;IACV+B,QAAQ,EAAEpC,GAAG,CAACI,IAAI,KAAK,QAAQ;IAC/BA,IAAI,EAAEJ,GAAG,CAACI,IAAI;IACdiC,MAAM,EAAEV,kBAAkB,CAACW,aAAa,GAAGX,kBAAkB,CAACU,MAAM,GAAG,IAAI;IAC3Ef,aAAa,EAAEK,kBAAkB,CAACL,aAAa;IAC/CiB,WAAW,EAAEZ,kBAAkB,CAACY,WAAW;IAC3CC,UAAU,EAAEb,kBAAkB,CAACa,UAAU;IACzCC,OAAO,EAAEd,kBAAkB,CAACe,YAAY;IACxCX,OAAO;IACPY,eAAe,EAAE3C,GAAG,CAACI,IAAI,KAAK,UAAU,GAAG,IAAAwC,wBAAiB,EAACjB,kBAAkB,EAAEF,OAAO,CAAC,GAAGoB,SAAS;IACrGC,QAAQ,EAAEnB,kBAAkB,CAACmB,QAAQ;IACrCC,aAAa,EAAEpB,kBAAkB,CAACoB,aAAa;IAC/CC,cAAc,EAAErB,kBAAkB,CAACqB,cAAc;IACjDC,sBAAsB,EAAEtB,kBAAkB,CAACsB,sBAAsB;IACjEC,6BAA6B,EAAEvB,kBAAkB,CAACuB,6BAA6B,IAAI,SAAS;IAC5FC,yBAAyB,EAAExB,kBAAkB,CAACwB,yBAAyB,IAAI,SAAS;IACpFC,yBAAyB,EAAEzB,kBAAkB,CAACyB,yBAAyB,IAAI,SAAS;IACpFC,0BAA0B,EAAE1B,kBAAkB,CAAC0B,0BAA0B,IAAI,SAAS;IACtFC,sBAAsB,EAAE3B,kBAAkB,CAAC2B,sBAAsB,IAAI,SAAS;IAC9EC,sBAAsB,EAAE5B,kBAAkB,CAAC4B,sBAAsB,IAAI,SAAS;IAC9EC,aAAa,EAAE7B,kBAAkB,CAAC6B,aAAa;IAC/CC,aAAa,EAAE9B,kBAAkB,CAAC8B,aAAa;IAC/CC,qBAAqB,EAAE/B,kBAAkB,CAAC+B,qBAAqB;IAC/DC,oBAAoB,EAAEhC,kBAAkB,CAACgC,oBAAoB;IAC7DC,oBAAoB,EAAEjC,kBAAkB,CAACiC,oBAAoB;IAC7DC,iBAAiB,EAAElC,kBAAkB,CAACkC;EACxC,CAAC;EAED,MAAM;IAAE1D,IAAI;IAAEC;EAAK,CAAC,GAAGJ,GAAG,IAAI,CAAC,CAAC;EAEhC,IAAIG,IAAI,KAAK,YAAY,KAAKC,IAAI,KAAK,MAAM,IAAIA,IAAI,KAAK,UAAU,CAAC,EAAE;IACrEC,GAAG,CAACyD,mBAAmB,GAAGnC,kBAAkB,CAACoC,0BAA0B,GACnEpC,kBAAkB,CAACmC,mBAAmB,GACtC,IAAI;EACV,CAAC,MAAM;IACLzD,GAAG,CAACyD,mBAAmB,GAAG,IAAI;EAChC;EAEA,OAAOzD,GAAG;AACZ;AAEO,MAAM2D,QAAQ,GAAGA,CAACC,MAAM,EAAExC,OAAO,KAAK;EAC3C,IAAI,CAACA,OAAO,IAAI,IAAAyC,iBAAO,EAACzC,OAAO,CAAC,EAAE;IAChC,OAAO,CAAC;EACV;EAEA,MAAM0C,eAAe,GAAG1C,OAAO,CAAClB,KAAK,IAAI,EAAE;EAC3C,MAAM6D,cAAc,GAAG,CAACH,MAAM,CAAClC,OAAO,IAAI,EAAE,EAAEsC,MAAM,CAAEC,EAAE,IAAKA,EAAE,CAAC5D,OAAO,CAAC;EAExE,IAAI6D,KAAK,GAAGJ,eAAe,CAACK,MAAM,CAChC,CAACC,GAAG,EAAEC,cAAc,KAAKD,GAAG,IAAIL,cAAc,CAACO,IAAI,CAAEL,EAAE,IAAKA,EAAE,CAAC/D,KAAK,KAAKmE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EACjG,CACF,CAAC;EAED,IAAIN,cAAc,CAACQ,MAAM,GAAGT,eAAe,CAACS,MAAM,EAAE;IAClDL,KAAK,IAAIJ,eAAe,CAACS,MAAM,GAAGR,cAAc,CAACQ,MAAM;IAEvD,IAAIL,KAAK,GAAG,CAAC,EAAE;MACbA,KAAK,GAAG,CAAC;IACX;EACF;EAEA,MAAMM,GAAG,GAAGT,cAAc,CAACQ,MAAM,GAAGL,KAAK,GAAGH,cAAc,CAACQ,MAAM,GAAG,CAAC;EAErE,OAAOE,UAAU,CAACD,GAAG,CAACE,OAAO,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARAvD,OAAA,CAAAwC,QAAA,GAAAA,QAAA;AASO,SAASgB,OAAOA,CAACjF,KAAK,EAAE0B,OAAO,EAAEzB,GAAG,EAAE;EAC3C,OAAO,IAAIgB,OAAO,CAAEC,OAAO,IAAK;IAC9B,IAAI,CAACQ,OAAO,IAAI,IAAAyC,iBAAO,EAACzC,OAAO,CAAC,EAAE;MAChCR,OAAO,CAAC;QAAEsD,KAAK,EAAE,CAAC;QAAEU,KAAK,EAAE;MAAK,CAAC,CAAC;IACpC,CAAC,MAAM;MACL,MAAMC,qBAAqB,GAAGC,+BAAc,CAACC,OAAO,CAACrF,KAAK,EAAEC,GAAG,CAAC,IAAID,KAAK,CAACyC,UAAU,KAAK,OAAO;MAChG,MAAM+B,KAAK,GAAGP,QAAQ,CAACjE,KAAK,EAAE0B,OAAO,CAAC;MAEtCR,OAAO,CAAC;QAAEsD,KAAK,EAAEW,qBAAqB,GAAGX,KAAK,GAAGA,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAAEU,KAAK,EAAE;MAAM,CAAC,CAAC;IACvF;EACF,CAAC,CAAC;AACJ;AAEO,MAAMI,4BAA4B,GAAGA,CAACjE,QAAQ,EAAEpB,GAAG,KAAK;EAC7D,OAAO,IAAIgB,OAAO,CAAEC,OAAO,IAAK;IAC9B,IAAIjB,GAAG,CAACI,IAAI,KAAK,UAAU,IAAIJ,GAAG,CAACG,IAAI,KAAK,YAAY,EAAE;MACxD,MAAM;QAAE4B;MAAQ,CAAC,GAAGX,QAAQ,IAAI;QAAEW,OAAO,EAAE;MAAG,CAAC;MAE/Cd,OAAO,CAAC;QACNqE,EAAE,EAAE,GAAG;QACP/E,KAAK,EAAEwB,OAAO,CAACsC,MAAM,CAAEkB,CAAC,IAAKA,CAAC,CAAC7E,OAAO,CAAC,CAACsB,GAAG,CAAEuD,CAAC,IAAKA,CAAC,CAAChF,KAAK;MAC5D,CAAC,CAAC;IACJ,CAAC,MAAM;MACLU,OAAO,CAAC,IAAI,CAAC;IACf;EACF,CAAC,CAAC;AACJ,CAAC;;AAED;AAAAO,OAAA,CAAA6D,4BAAA,GAAAA,4BAAA;AACA,MAAMG,YAAY,GAAIC,IAAI,IAAK,CAACA,IAAI,IAAI,EAAE,EAAEC,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC;;AAEtE;AACA,MAAMC,UAAU,GAAIF,IAAI,IAAK,CAACA,IAAI,IAAI,EAAE,EAAEG,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC;AAEpF,MAAMC,QAAQ,GAAGA,CAAC9F,KAAK,GAAG,CAAC,CAAC,EAAEkE,MAAM,GAAG,CAAC,CAAC,KAAK;EACnD,MAAM;IAAElC;EAAQ,CAAC,GAAGhC,KAAK;EACzB,MAAM;IAAE+F,gBAAgB,GAAG,CAAC;IAAEC;EAAiB,CAAC,GAAG9B,MAAM;EACzD,MAAM+B,eAAe,GAAG,CAAC,IAAIjE,OAAO,IAAI,EAAE,CAAC,CAAC,CAACkE,OAAO,CAAC,CAAC;EACtD,MAAMC,aAAa,GAAG,CAAC,CAAC;EACxB,MAAMC,eAAe,GAAG,CAAC,CAAC;EAC1B,MAAMC,MAAM,GAAG,CAAC,CAAC;EAEjB,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAACC,OAAO,CAAEC,KAAK,IAAK;IACnD,IAAIrC,MAAM,CAACqC,KAAK,CAAC,EAAEC,QAAQ,IAAI,CAACZ,UAAU,CAAC5F,KAAK,CAACuG,KAAK,CAAC,CAAC,EAAE;MACxDF,MAAM,CAACE,KAAK,CAAC,GAAG,yBAAyB;IAC3C;EACF,CAAC,CAAC;EAEF,IAAIE,kBAAkB,GAAG,KAAK;EAE9BR,eAAe,CAACK,OAAO,CAAC,CAACnG,MAAM,EAAEuG,KAAK,KAAK;IACzC,MAAM;MAAE/F,OAAO;MAAEH,KAAK;MAAED,KAAK;MAAEE;IAAU,CAAC,GAAGN,MAAM;IAEnD,IAAIQ,OAAO,EAAE;MACX8F,kBAAkB,GAAG,IAAI;IAC3B;IAEA,IAAI,CAACb,UAAU,CAACrF,KAAK,CAAC,EAAE;MACtB4F,aAAa,CAAC3F,KAAK,CAAC,GAAG,8BAA8B;IACvD,CAAC,MAAM;MACL,MAAMmG,eAAe,GAAGV,eAAe,CAACW,KAAK,CAACF,KAAK,GAAG,CAAC,CAAC,CAACG,IAAI,CAAErB,CAAC,IAAKA,CAAC,CAACjF,KAAK,KAAKA,KAAK,CAAC;MAEvF,IAAIoG,eAAe,EAAE;QACnBR,aAAa,CAAC3F,KAAK,CAAC,GAAG,2BAA2B;MACpD;IACF;IAEA,IAAI0D,MAAM,CAACzD,SAAS,EAAE+F,QAAQ,IAAI,CAACZ,UAAU,CAACnF,SAAS,CAAC,EAAE;MACxD2F,eAAe,CAAC5F,KAAK,CAAC,GAAG,yBAAyB;IACpD;EACF,CAAC,CAAC;EAEF,MAAMsG,WAAW,GAAG,CAAC9E,OAAO,IAAI,EAAE,EAAE6C,MAAM;EAE1C,IAAIiC,WAAW,GAAGf,gBAAgB,EAAE;IAClCM,MAAM,CAACU,aAAa,GAAG,4BAA4BhB,gBAAgB,mBAAmB;EACxF,CAAC,MAAM,IAAIe,WAAW,GAAGd,gBAAgB,EAAE;IACzCK,MAAM,CAACU,aAAa,GAAG,gBAAgBf,gBAAgB,6BAA6B;EACtF;EAEA,IAAI,CAACS,kBAAkB,EAAE;IACvBJ,MAAM,CAACW,eAAe,GAAG,8BAA8B;EACzD;EAEA,IAAI,CAAC,IAAA7C,iBAAO,EAACgC,aAAa,CAAC,EAAE;IAC3BE,MAAM,CAACrE,OAAO,GAAGmE,aAAa;EAChC;EAEA,IAAI,CAAC,IAAAhC,iBAAO,EAACiC,eAAe,CAAC,EAAE;IAC7BC,MAAM,CAAC5F,SAAS,GAAG2F,eAAe;EACpC;EAEA,OAAOC,MAAM;AACf,CAAC;AAAC5E,OAAA,CAAAqE,QAAA,GAAAA,QAAA","ignoreList":[]}
@@ -1,16 +1,15 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.isResponseCorrect = exports.getCorrectResponse = void 0;
8
- var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
7
+ var _lodashEs = require("lodash-es");
9
8
  const getCorrectResponse = choices => choices.filter(c => c.correct).map(c => c.value).sort();
10
9
  exports.getCorrectResponse = getCorrectResponse;
11
10
  const isResponseCorrect = (question, session) => {
12
11
  let correctResponse = getCorrectResponse(question.choices);
13
- return session && (0, _isEqual.default)((session.value || []).sort(), correctResponse);
12
+ return session && (0, _lodashEs.isEqual)((session.value || []).sort(), correctResponse);
14
13
  };
15
14
  exports.isResponseCorrect = isResponseCorrect;
16
15
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["_isEqual","_interopRequireDefault","require","getCorrectResponse","choices","filter","c","correct","map","value","sort","exports","isResponseCorrect","question","session","correctResponse","isEqual"],"sources":["../src/utils.js"],"sourcesContent":["import isEqual from 'lodash/isEqual';\n\nexport const getCorrectResponse = (choices) =>\n choices\n .filter((c) => c.correct)\n .map((c) => c.value)\n .sort();\n\nexport const isResponseCorrect = (question, session) => {\n let correctResponse = getCorrectResponse(question.choices);\n return session && isEqual((session.value || []).sort(), correctResponse);\n};\n"],"mappings":";;;;;;;AAAA,IAAAA,QAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEO,MAAMC,kBAAkB,GAAIC,OAAO,IACxCA,OAAO,CACJC,MAAM,CAAEC,CAAC,IAAKA,CAAC,CAACC,OAAO,CAAC,CACxBC,GAAG,CAAEF,CAAC,IAAKA,CAAC,CAACG,KAAK,CAAC,CACnBC,IAAI,CAAC,CAAC;AAACC,OAAA,CAAAR,kBAAA,GAAAA,kBAAA;AAEL,MAAMS,iBAAiB,GAAGA,CAACC,QAAQ,EAAEC,OAAO,KAAK;EACtD,IAAIC,eAAe,GAAGZ,kBAAkB,CAACU,QAAQ,CAACT,OAAO,CAAC;EAC1D,OAAOU,OAAO,IAAI,IAAAE,gBAAO,EAAC,CAACF,OAAO,CAACL,KAAK,IAAI,EAAE,EAAEC,IAAI,CAAC,CAAC,EAAEK,eAAe,CAAC;AAC1E,CAAC;AAACJ,OAAA,CAAAC,iBAAA,GAAAA,iBAAA","ignoreList":[]}
1
+ {"version":3,"file":"utils.js","names":["_lodashEs","require","getCorrectResponse","choices","filter","c","correct","map","value","sort","exports","isResponseCorrect","question","session","correctResponse","isEqual"],"sources":["../src/utils.js"],"sourcesContent":["import { isEqual } from 'lodash-es';\n\nexport const getCorrectResponse = (choices) =>\n choices\n .filter((c) => c.correct)\n .map((c) => c.value)\n .sort();\n\nexport const isResponseCorrect = (question, session) => {\n let correctResponse = getCorrectResponse(question.choices);\n return session && isEqual((session.value || []).sort(), correctResponse);\n};\n"],"mappings":";;;;;;AAAA,IAAAA,SAAA,GAAAC,OAAA;AAEO,MAAMC,kBAAkB,GAAIC,OAAO,IACxCA,OAAO,CACJC,MAAM,CAAEC,CAAC,IAAKA,CAAC,CAACC,OAAO,CAAC,CACxBC,GAAG,CAAEF,CAAC,IAAKA,CAAC,CAACG,KAAK,CAAC,CACnBC,IAAI,CAAC,CAAC;AAACC,OAAA,CAAAR,kBAAA,GAAAA,kBAAA;AAEL,MAAMS,iBAAiB,GAAGA,CAACC,QAAQ,EAAEC,OAAO,KAAK;EACtD,IAAIC,eAAe,GAAGZ,kBAAkB,CAACU,QAAQ,CAACT,OAAO,CAAC;EAC1D,OAAOU,OAAO,IAAI,IAAAE,iBAAO,EAAC,CAACF,OAAO,CAACL,KAAK,IAAI,EAAE,EAAEC,IAAI,CAAC,CAAC,EAAEK,eAAe,CAAC;AAC1E,CAAC;AAACJ,OAAA,CAAAC,iBAAA,GAAAA,iBAAA","ignoreList":[]}
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@pie-element/multiple-choice-controller",
3
3
  "private": true,
4
- "version": "7.0.0-beta.1",
4
+ "version": "7.1.1-next.1",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "module": "src/index.js",
8
8
  "author": "",
9
9
  "license": "ISC",
10
10
  "dependencies": {
11
- "@pie-lib/controller-utils": "1.1.1-next.0",
11
+ "@pie-lib/controller-utils": "1.2.0-next.3",
12
12
  "debug": "^4.1.1",
13
- "lodash": "^4.17.23"
13
+ "lodash-es": "^4.17.23"
14
14
  }
15
15
  }
package/lib/index.js CHANGED
@@ -8,7 +8,7 @@ exports.isComplete = exports.default = void 0;
8
8
  var _main = _interopRequireDefault(require("./main"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
10
  var _client = require("react-dom/client");
11
- var _debounce = _interopRequireDefault(require("lodash/debounce"));
11
+ var _lodashEs = require("lodash-es");
12
12
  var _debug = _interopRequireDefault(require("debug"));
13
13
  var _piePlayerEvents = require("@pie-framework/pie-player-events");
14
14
  var _mathRendering = require("@pie-lib/math-rendering");
@@ -62,7 +62,7 @@ class MultipleChoice extends HTMLElement {
62
62
  this._keyboardEventsEnabled = false;
63
63
  this._audioInitialized = false;
64
64
  this._root = null;
65
- this._rerender = (0, _debounce.default)(() => {
65
+ this._rerender = (0, _lodashEs.debounce)(() => {
66
66
  if (this._model && this._session) {
67
67
  var element = /*#__PURE__*/_react.default.createElement(_main.default, {
68
68
  model: this._model,
@@ -80,7 +80,8 @@ class MultipleChoice extends HTMLElement {
80
80
  this._root = (0, _client.createRoot)(this);
81
81
  }
82
82
  this._root.render(element);
83
- queueMicrotask(() => {
83
+ // Use requestAnimationFrame to ensure DOM is fully painted before rendering math
84
+ requestAnimationFrame(() => {
84
85
  log('render complete - render math');
85
86
  (0, _mathRendering.renderMath)(this);
86
87
  });
@@ -94,10 +95,10 @@ class MultipleChoice extends HTMLElement {
94
95
  leading: false,
95
96
  trailing: true
96
97
  });
97
- this._dispatchResponseChanged = (0, _debounce.default)(() => {
98
+ this._dispatchResponseChanged = (0, _lodashEs.debounce)(() => {
98
99
  this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete, this)));
99
100
  });
100
- this._dispatchModelSet = (0, _debounce.default)(() => {
101
+ this._dispatchModelSet = (0, _lodashEs.debounce)(() => {
101
102
  this.dispatchEvent(new _piePlayerEvents.ModelSetEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete, this), this._model !== undefined));
102
103
  }, 50, {
103
104
  leading: false,
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_main","_interopRequireDefault","require","_react","_client","_debounce","_debug","_piePlayerEvents","_mathRendering","_renderUi","_sessionUpdater","log","debug","isComplete","session","model","audioComplete","elementContext","autoplayAudioEnabled","completeAudioEnabled","audio","querySelector","isInsidePrompt","closest","value","choiceMode","minSelections","maxSelections","selections","length","exports","MultipleChoice","HTMLElement","constructor","_model","_session","_options","_boundHandleKeyDown","handleKeyDown","bind","_keyboardEventsEnabled","_audioInitialized","_root","_rerender","debounce","element","React","createElement","Main","options","onChoiceChanged","_onChange","onShowCorrectToggle","setAttribute","setLangAttribute","createRoot","render","queueMicrotask","renderMath","keyboardEventsEnabled","enableKeyboardEvents","leading","trailing","_dispatchResponseChanged","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","_dispatchModelSet","ModelSetEvent","undefined","language","lang","slice","s","o","data","updateSessionValue","_createAudioInfoToast","info","document","id","Object","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","connectedCallback","observer","MutationObserver","mutationsList","forEach","mutation","type","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","updateSessionMetadata","audioStartTime","Date","getTime","handleEnded","audioEndTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","window","disconnectedCallback","unmount","event","mode","keyToIndex","key","numOffset","letterOffset","test","charCodeAt","choiceIndex","choices","currentValue","choiceId","newValue","selected","includes","selector","default"],"sources":["../src/index.js"],"sourcesContent":["import Main from './main';\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport debounce from 'lodash/debounce';\nimport debug from 'debug';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { EnableAudioAutoplayImage } from '@pie-lib/render-ui';\nimport { updateSessionValue, updateSessionMetadata } from './session-updater';\n\nconst log = debug('pie-ui:multiple-choice');\n\nexport const isComplete = (session, model, audioComplete, elementContext) => {\n const { autoplayAudioEnabled, completeAudioEnabled } = model || {};\n\n // check audio completion if audio settings are enabled and audio actually exists\n if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {\n if (elementContext) {\n const audio = elementContext.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n // only require audio completion if audio exists and is inside the prompt\n if (audio && isInsidePrompt) {\n return false;\n }\n }\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n const { choiceMode, minSelections = 1, maxSelections } = model || {};\n const selections = session.value.length || 0;\n\n if (choiceMode === 'radio') {\n return !!selections;\n }\n\n if (selections < minSelections || selections > maxSelections) {\n return false;\n }\n\n return true;\n};\n\nexport default class MultipleChoice extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this._options = null; // added for ebsr print mode detection\n this.audioComplete = false;\n this._boundHandleKeyDown = this.handleKeyDown.bind(this);\n this._keyboardEventsEnabled = false;\n this._audioInitialized = false;\n this._root = null;\n\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n var element = React.createElement(Main, {\n model: this._model,\n session: this._session,\n options: this._options,\n onChoiceChanged: this._onChange.bind(this),\n onShowCorrectToggle: this.onShowCorrectToggle.bind(this),\n });\n\n //TODO: aria-label is set in the _rerender because we need to change it when the model.choiceMode is updated. Consider revisiting the placement of the aria-label setting in the _rerender\n this.setAttribute(\n 'aria-label',\n this._model.choiceMode === 'radio' ? 'Multiple Choice Question' : 'Multiple Correct Answer Question',\n );\n this.setAttribute('role', 'region');\n this.setLangAttribute();\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n queueMicrotask(() => {\n log('render complete - render math');\n renderMath(this);\n });\n\n if (this._model.keyboardEventsEnabled === true && !this._keyboardEventsEnabled) {\n this.enableKeyboardEvents();\n }\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n\n this._dispatchResponseChanged = debounce(() => {\n this.dispatchEvent(\n new SessionChangedEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model, this.audioComplete, this),\n ),\n );\n });\n\n this._dispatchModelSet = debounce(\n () => {\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model, this.audioComplete, this),\n this._model !== undefined,\n ),\n );\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n\n onShowCorrectToggle() {\n renderMath(this);\n }\n\n setLangAttribute() {\n const language = this._model && typeof this._model.language ? this._model.language : '';\n const lang = language ? language.slice(0, 2) : 'en';\n this.setAttribute('lang', lang);\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n // reset the audioInitialized to false since the model changed, and we might need to reinitialize the audio\n this._audioInitialized = false;\n this._dispatchModelSet();\n }\n\n get session() {\n return this._session;\n }\n\n get options() {\n return this._options;\n }\n\n set options(o) {\n this._options = o;\n this._rerender();\n }\n\n set session(s) {\n this._session = s;\n this._rerender();\n //TODO: remove this session-changed should only be emit on user change\n this._dispatchResponseChanged();\n }\n\n _onChange(data) {\n updateSessionValue(this._session, this._model.choiceMode, data);\n this._dispatchResponseChanged();\n this._rerender();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000',\n cursor: 'pointer',\n });\n\n const img = document.createElement('img');\n img.src = EnableAudioAutoplayImage;\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._rerender();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n if (this._audioInitialized) return;\n\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n updateSessionMetadata(this._session, { audioStartTime: new Date().getTime() });\n\n const info = this.querySelector('#play-audio-info');\n if (info) {\n container.removeChild(info);\n }\n\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });\n this.audioComplete = true;\n this._dispatchResponseChanged();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n // set to true to prevent multiple initializations\n this._audioInitialized = true;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n enableKeyboardEvents() {\n if (!this._keyboardEventsEnabled) {\n window.addEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = true;\n }\n }\n\n disconnectedCallback() {\n if (this._keyboardEventsEnabled) {\n window.removeEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = false;\n }\n\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n\n if (this._root) {\n this._root.unmount();\n }\n }\n\n /**\n * Handles global keyboard events for selecting or toggling multiple-choice answers.\n * Maps keys (1-9, 0, a-j, A-J) to choices and updates the session state accordingly.\n * Ensures valid key presses toggle or select the appropriate choice based on the model.\n */\n handleKeyDown(event) {\n if (!this._model || !this._session) {\n return;\n }\n\n const { mode } = this._model;\n if (mode !== 'gather') {\n return;\n }\n\n const keyToIndex = (key) => {\n const numOffset = key >= '1' && key <= '9' ? key - '1' : key === '0' ? 9 : -1;\n const letterOffset = /^[a-jA-J]$/.test(key) ? key.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0) : -1;\n return numOffset >= 0 ? numOffset : letterOffset;\n };\n\n const choiceIndex = keyToIndex(event.key);\n\n if (choiceIndex === undefined || choiceIndex <= -1 || choiceIndex >= this._model.choices?.length) {\n return;\n }\n\n const currentValue = this._session.value || [];\n const choiceId = this._model.choices[choiceIndex].value;\n\n const newValue = {\n value: choiceId,\n selected: !currentValue.includes(choiceId),\n selector: 'Keyboard',\n };\n\n this._onChange(newValue);\n }\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,KAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,MAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,SAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,MAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,gBAAA,GAAAL,OAAA;AACA,IAAAM,cAAA,GAAAN,OAAA;AACA,IAAAO,SAAA,GAAAP,OAAA;AACA,IAAAQ,eAAA,GAAAR,OAAA;AAEA,MAAMS,GAAG,GAAG,IAAAC,cAAK,EAAC,wBAAwB,CAAC;AAEpC,MAAMC,UAAU,GAAGA,CAACC,OAAO,EAAEC,KAAK,EAAEC,aAAa,EAAEC,cAAc,KAAK;EAC3E,MAAM;IAAEC,oBAAoB;IAAEC;EAAqB,CAAC,GAAGJ,KAAK,IAAI,CAAC,CAAC;;EAElE;EACA,IAAIG,oBAAoB,IAAIC,oBAAoB,IAAI,CAACH,aAAa,EAAE;IAClE,IAAIC,cAAc,EAAE;MAClB,MAAMG,KAAK,GAAGH,cAAc,CAACI,aAAa,CAAC,OAAO,CAAC;MACnD,MAAMC,cAAc,GAAGF,KAAK,IAAIA,KAAK,CAACG,OAAO,CAAC,iBAAiB,CAAC;;MAEhE;MACA,IAAIH,KAAK,IAAIE,cAAc,EAAE;QAC3B,OAAO,KAAK;MACd;IACF;EACF;EAEA,IAAI,CAACR,OAAO,IAAI,CAACA,OAAO,CAACU,KAAK,EAAE;IAC9B,OAAO,KAAK;EACd;EAEA,MAAM;IAAEC,UAAU;IAAEC,aAAa,GAAG,CAAC;IAAEC;EAAc,CAAC,GAAGZ,KAAK,IAAI,CAAC,CAAC;EACpE,MAAMa,UAAU,GAAGd,OAAO,CAACU,KAAK,CAACK,MAAM,IAAI,CAAC;EAE5C,IAAIJ,UAAU,KAAK,OAAO,EAAE;IAC1B,OAAO,CAAC,CAACG,UAAU;EACrB;EAEA,IAAIA,UAAU,GAAGF,aAAa,IAAIE,UAAU,GAAGD,aAAa,EAAE;IAC5D,OAAO,KAAK;EACd;EAEA,OAAO,IAAI;AACb,CAAC;AAACG,OAAA,CAAAjB,UAAA,GAAAA,UAAA;AAEa,MAAMkB,cAAc,SAASC,WAAW,CAAC;EACtDC,WAAWA,CAAA,EAAG;IACZ,KAAK,CAAC,CAAC;IACP,IAAI,CAACC,MAAM,GAAG,IAAI;IAClB,IAAI,CAACC,QAAQ,GAAG,IAAI;IACpB,IAAI,CAACC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACtB,IAAI,CAACpB,aAAa,GAAG,KAAK;IAC1B,IAAI,CAACqB,mBAAmB,GAAG,IAAI,CAACC,aAAa,CAACC,IAAI,CAAC,IAAI,CAAC;IACxD,IAAI,CAACC,sBAAsB,GAAG,KAAK;IACnC,IAAI,CAACC,iBAAiB,GAAG,KAAK;IAC9B,IAAI,CAACC,KAAK,GAAG,IAAI;IAEjB,IAAI,CAACC,SAAS,GAAG,IAAAC,iBAAQ,EACvB,MAAM;MACJ,IAAI,IAAI,CAACV,MAAM,IAAI,IAAI,CAACC,QAAQ,EAAE;QAChC,IAAIU,OAAO,gBAAGC,cAAK,CAACC,aAAa,CAACC,aAAI,EAAE;UACtCjC,KAAK,EAAE,IAAI,CAACmB,MAAM;UAClBpB,OAAO,EAAE,IAAI,CAACqB,QAAQ;UACtBc,OAAO,EAAE,IAAI,CAACb,QAAQ;UACtBc,eAAe,EAAE,IAAI,CAACC,SAAS,CAACZ,IAAI,CAAC,IAAI,CAAC;UAC1Ca,mBAAmB,EAAE,IAAI,CAACA,mBAAmB,CAACb,IAAI,CAAC,IAAI;QACzD,CAAC,CAAC;;QAEF;QACA,IAAI,CAACc,YAAY,CACf,YAAY,EACZ,IAAI,CAACnB,MAAM,CAACT,UAAU,KAAK,OAAO,GAAG,0BAA0B,GAAG,kCACpE,CAAC;QACD,IAAI,CAAC4B,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC;QACnC,IAAI,CAACC,gBAAgB,CAAC,CAAC;QAEvB,IAAI,CAAC,IAAI,CAACZ,KAAK,EAAE;UACf,IAAI,CAACA,KAAK,GAAG,IAAAa,kBAAU,EAAC,IAAI,CAAC;QAC/B;QACA,IAAI,CAACb,KAAK,CAACc,MAAM,CAACX,OAAO,CAAC;QAC1BY,cAAc,CAAC,MAAM;UACnB9C,GAAG,CAAC,+BAA+B,CAAC;UACpC,IAAA+C,yBAAU,EAAC,IAAI,CAAC;QAClB,CAAC,CAAC;QAEF,IAAI,IAAI,CAACxB,MAAM,CAACyB,qBAAqB,KAAK,IAAI,IAAI,CAAC,IAAI,CAACnB,sBAAsB,EAAE;UAC9E,IAAI,CAACoB,oBAAoB,CAAC,CAAC;QAC7B;MACF,CAAC,MAAM;QACLjD,GAAG,CAAC,MAAM,CAAC;MACb;IACF,CAAC,EACD,EAAE,EACF;MAAEkD,OAAO,EAAE,KAAK;MAAEC,QAAQ,EAAE;IAAK,CACnC,CAAC;IAED,IAAI,CAACC,wBAAwB,GAAG,IAAAnB,iBAAQ,EAAC,MAAM;MAC7C,IAAI,CAACoB,aAAa,CAChB,IAAIC,oCAAmB,CACrB,IAAI,CAACC,OAAO,CAACC,WAAW,CAAC,CAAC,EAC1BtD,UAAU,CAAC,IAAI,CAACsB,QAAQ,EAAE,IAAI,CAACD,MAAM,EAAE,IAAI,CAAClB,aAAa,EAAE,IAAI,CACjE,CACF,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAACoD,iBAAiB,GAAG,IAAAxB,iBAAQ,EAC/B,MAAM;MACJ,IAAI,CAACoB,aAAa,CAChB,IAAIK,8BAAa,CACf,IAAI,CAACH,OAAO,CAACC,WAAW,CAAC,CAAC,EAC1BtD,UAAU,CAAC,IAAI,CAACsB,QAAQ,EAAE,IAAI,CAACD,MAAM,EAAE,IAAI,CAAClB,aAAa,EAAE,IAAI,CAAC,EAChE,IAAI,CAACkB,MAAM,KAAKoC,SAClB,CACF,CAAC;IACH,CAAC,EACD,EAAE,EACF;MAAET,OAAO,EAAE,KAAK;MAAEC,QAAQ,EAAE;IAAK,CACnC,CAAC;EACH;EAEAV,mBAAmBA,CAAA,EAAG;IACpB,IAAAM,yBAAU,EAAC,IAAI,CAAC;EAClB;EAEAJ,gBAAgBA,CAAA,EAAG;IACjB,MAAMiB,QAAQ,GAAG,IAAI,CAACrC,MAAM,IAAI,OAAO,IAAI,CAACA,MAAM,CAACqC,QAAQ,GAAG,IAAI,CAACrC,MAAM,CAACqC,QAAQ,GAAG,EAAE;IACvF,MAAMC,IAAI,GAAGD,QAAQ,GAAGA,QAAQ,CAACE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;IACnD,IAAI,CAACpB,YAAY,CAAC,MAAM,EAAEmB,IAAI,CAAC;EACjC;EAEA,IAAIzD,KAAKA,CAAC2D,CAAC,EAAE;IACX,IAAI,CAACxC,MAAM,GAAGwC,CAAC;IACf,IAAI,CAAC/B,SAAS,CAAC,CAAC;IAChB;IACA,IAAI,CAACF,iBAAiB,GAAG,KAAK;IAC9B,IAAI,CAAC2B,iBAAiB,CAAC,CAAC;EAC1B;EAEA,IAAItD,OAAOA,CAAA,EAAG;IACZ,OAAO,IAAI,CAACqB,QAAQ;EACtB;EAEA,IAAIc,OAAOA,CAAA,EAAG;IACZ,OAAO,IAAI,CAACb,QAAQ;EACtB;EAEA,IAAIa,OAAOA,CAAC0B,CAAC,EAAE;IACb,IAAI,CAACvC,QAAQ,GAAGuC,CAAC;IACjB,IAAI,CAAChC,SAAS,CAAC,CAAC;EAClB;EAEA,IAAI7B,OAAOA,CAAC4D,CAAC,EAAE;IACb,IAAI,CAACvC,QAAQ,GAAGuC,CAAC;IACjB,IAAI,CAAC/B,SAAS,CAAC,CAAC;IAChB;IACA,IAAI,CAACoB,wBAAwB,CAAC,CAAC;EACjC;EAEAZ,SAASA,CAACyB,IAAI,EAAE;IACd,IAAAC,kCAAkB,EAAC,IAAI,CAAC1C,QAAQ,EAAE,IAAI,CAACD,MAAM,CAACT,UAAU,EAAEmD,IAAI,CAAC;IAC/D,IAAI,CAACb,wBAAwB,CAAC,CAAC;IAC/B,IAAI,CAACpB,SAAS,CAAC,CAAC;EAClB;EAEAmC,qBAAqBA,CAAA,EAAG;IACtB,MAAMC,IAAI,GAAGC,QAAQ,CAACjC,aAAa,CAAC,KAAK,CAAC;IAC1CgC,IAAI,CAACE,EAAE,GAAG,iBAAiB;IAE3BC,MAAM,CAACC,MAAM,CAACJ,IAAI,CAACK,KAAK,EAAE;MACxBC,QAAQ,EAAE,UAAU;MACpBC,GAAG,EAAE,CAAC;MACNC,KAAK,EAAE,MAAM;MACbC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,MAAM;MACfC,cAAc,EAAE,QAAQ;MACxBC,UAAU,EAAE,QAAQ;MACpBC,UAAU,EAAE,OAAO;MACnBC,MAAM,EAAE,MAAM;MACdC,MAAM,EAAE;IACV,CAAC,CAAC;IAEF,MAAMC,GAAG,GAAGf,QAAQ,CAACjC,aAAa,CAAC,KAAK,CAAC;IACzCgD,GAAG,CAACC,GAAG,GAAGC,kCAAwB;IAClCF,GAAG,CAACG,GAAG,GAAG,yCAAyC;IACnDH,GAAG,CAACR,KAAK,GAAG,GAAG;IACfQ,GAAG,CAACP,MAAM,GAAG,GAAG;IAEhBT,IAAI,CAACoB,WAAW,CAACJ,GAAG,CAAC;IACrB,OAAOhB,IAAI;EACb;EAEAqB,iBAAiBA,CAAA,EAAG;IAClB,IAAI,CAACzD,SAAS,CAAC,CAAC;;IAEhB;IACA;IACA;IACA,MAAM0D,QAAQ,GAAG,IAAIC,gBAAgB,CAAC,CAACC,aAAa,EAAEF,QAAQ,KAAK;MACjEE,aAAa,CAACC,OAAO,CAAEC,QAAQ,IAAK;QAClC,IAAIA,QAAQ,CAACC,IAAI,KAAK,WAAW,EAAE;UACjC,IAAI,IAAI,CAACjE,iBAAiB,EAAE;UAE5B,MAAMrB,KAAK,GAAG,IAAI,CAACC,aAAa,CAAC,OAAO,CAAC;UACzC,MAAMC,cAAc,GAAGF,KAAK,IAAIA,KAAK,CAACG,OAAO,CAAC,iBAAiB,CAAC;UAEhE,IAAI,CAAC,IAAI,CAACW,MAAM,EAAE;UAClB,IAAI,CAAC,IAAI,CAACA,MAAM,CAAChB,oBAAoB,EAAE;UACvC,IAAIE,KAAK,IAAI,CAACE,cAAc,EAAE;UAC9B,IAAI,CAACF,KAAK,EAAE;UAEZ,MAAM2D,IAAI,GAAG,IAAI,CAACD,qBAAqB,CAAC,CAAC;UACzC,MAAM6B,SAAS,GAAG,IAAI,CAACtF,aAAa,CAAC,iBAAiB,CAAC;UACvD,MAAMuF,WAAW,GAAGA,CAAA,KAAM;YACxB,IAAI,IAAI,CAACvF,aAAa,CAAC,kBAAkB,CAAC,EAAE;cAC1CD,KAAK,CAACyF,IAAI,CAAC,CAAC;cACZF,SAAS,CAACG,WAAW,CAAC/B,IAAI,CAAC;YAC7B;YAEAC,QAAQ,CAAC+B,mBAAmB,CAAC,OAAO,EAAEH,WAAW,CAAC;UACpD,CAAC;;UAED;UACA;UACAI,UAAU,CAAC,MAAM;YACf,IAAI5F,KAAK,CAAC6F,MAAM,IAAI,CAAC,IAAI,CAAC5F,aAAa,CAAC,kBAAkB,CAAC,EAAE;cAC3D;cACAsF,SAAS,CAACR,WAAW,CAACpB,IAAI,CAAC;cAC3BC,QAAQ,CAACkC,gBAAgB,CAAC,OAAO,EAAEN,WAAW,CAAC;YACjD,CAAC,MAAM;cACL5B,QAAQ,CAAC+B,mBAAmB,CAAC,OAAO,EAAEH,WAAW,CAAC;YACpD;UACF,CAAC,EAAE,GAAG,CAAC;;UAEP;UACA,MAAMO,aAAa,GAAGA,CAAA,KAAM;YAC1B,IAAAC,qCAAqB,EAAC,IAAI,CAACjF,QAAQ,EAAE;cAAEkF,cAAc,EAAE,IAAIC,IAAI,CAAC,CAAC,CAACC,OAAO,CAAC;YAAE,CAAC,CAAC;YAE9E,MAAMxC,IAAI,GAAG,IAAI,CAAC1D,aAAa,CAAC,kBAAkB,CAAC;YACnD,IAAI0D,IAAI,EAAE;cACR4B,SAAS,CAACG,WAAW,CAAC/B,IAAI,CAAC;YAC7B;YAEA3D,KAAK,CAAC2F,mBAAmB,CAAC,SAAS,EAAEI,aAAa,CAAC;UACrD,CAAC;UAED/F,KAAK,CAAC8F,gBAAgB,CAAC,SAAS,EAAEC,aAAa,CAAC;;UAEhD;UACA,MAAMK,WAAW,GAAGA,CAAA,KAAM;YACxB,IAAAJ,qCAAqB,EAAC,IAAI,CAACjF,QAAQ,EAAE;cAAEsF,YAAY,EAAE,IAAIH,IAAI,CAAC,CAAC,CAACC,OAAO,CAAC;YAAE,CAAC,CAAC;YAC5E,IAAI,CAACvG,aAAa,GAAG,IAAI;YACzB,IAAI,CAAC+C,wBAAwB,CAAC,CAAC;YAC/B3C,KAAK,CAAC2F,mBAAmB,CAAC,OAAO,EAAES,WAAW,CAAC;UACjD,CAAC;UAEDpG,KAAK,CAAC8F,gBAAgB,CAAC,OAAO,EAAEM,WAAW,CAAC;;UAE5C;UACA,IAAI,CAACE,MAAM,GAAGtG,KAAK;UACnB,IAAI,CAACuG,cAAc,GAAGR,aAAa;UACnC,IAAI,CAACS,YAAY,GAAGJ,WAAW;UAC/B,IAAI,CAACK,YAAY,GAAGjB,WAAW;UAC/B;UACA,IAAI,CAACnE,iBAAiB,GAAG,IAAI;UAE7B4D,QAAQ,CAACyB,UAAU,CAAC,CAAC;QACvB;MACF,CAAC,CAAC;IACJ,CAAC,CAAC;IAEFzB,QAAQ,CAAC0B,OAAO,CAAC,IAAI,EAAE;MAAEC,SAAS,EAAE,IAAI;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC;EAC5D;EAEArE,oBAAoBA,CAAA,EAAG;IACrB,IAAI,CAAC,IAAI,CAACpB,sBAAsB,EAAE;MAChC0F,MAAM,CAAChB,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC7E,mBAAmB,CAAC;MAC5D,IAAI,CAACG,sBAAsB,GAAG,IAAI;IACpC;EACF;EAEA2F,oBAAoBA,CAAA,EAAG;IACrB,IAAI,IAAI,CAAC3F,sBAAsB,EAAE;MAC/B0F,MAAM,CAACnB,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC1E,mBAAmB,CAAC;MAC/D,IAAI,CAACG,sBAAsB,GAAG,KAAK;IACrC;IAEAwC,QAAQ,CAAC+B,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAACc,YAAY,CAAC;IAExD,IAAI,IAAI,CAACH,MAAM,EAAE;MACf,IAAI,CAACA,MAAM,CAACX,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAACY,cAAc,CAAC;MAC/D,IAAI,CAACD,MAAM,CAACX,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAACa,YAAY,CAAC;MAC3D,IAAI,CAACF,MAAM,GAAG,IAAI;IACpB;IAEA,IAAI,IAAI,CAAChF,KAAK,EAAE;MACd,IAAI,CAACA,KAAK,CAAC0F,OAAO,CAAC,CAAC;IACtB;EACF;;EAEA;AACF;AACA;AACA;AACA;EACE9F,aAAaA,CAAC+F,KAAK,EAAE;IACnB,IAAI,CAAC,IAAI,CAACnG,MAAM,IAAI,CAAC,IAAI,CAACC,QAAQ,EAAE;MAClC;IACF;IAEA,MAAM;MAAEmG;IAAK,CAAC,GAAG,IAAI,CAACpG,MAAM;IAC5B,IAAIoG,IAAI,KAAK,QAAQ,EAAE;MACrB;IACF;IAEA,MAAMC,UAAU,GAAIC,GAAG,IAAK;MAC1B,MAAMC,SAAS,GAAGD,GAAG,IAAI,GAAG,IAAIA,GAAG,IAAI,GAAG,GAAGA,GAAG,GAAG,GAAG,GAAGA,GAAG,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;MAC7E,MAAME,YAAY,GAAG,YAAY,CAACC,IAAI,CAACH,GAAG,CAAC,GAAGA,GAAG,CAACrE,WAAW,CAAC,CAAC,CAACyE,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAACA,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;MACtG,OAAOH,SAAS,IAAI,CAAC,GAAGA,SAAS,GAAGC,YAAY;IAClD,CAAC;IAED,MAAMG,WAAW,GAAGN,UAAU,CAACF,KAAK,CAACG,GAAG,CAAC;IAEzC,IAAIK,WAAW,KAAKvE,SAAS,IAAIuE,WAAW,IAAI,CAAC,CAAC,IAAIA,WAAW,IAAI,IAAI,CAAC3G,MAAM,CAAC4G,OAAO,EAAEjH,MAAM,EAAE;MAChG;IACF;IAEA,MAAMkH,YAAY,GAAG,IAAI,CAAC5G,QAAQ,CAACX,KAAK,IAAI,EAAE;IAC9C,MAAMwH,QAAQ,GAAG,IAAI,CAAC9G,MAAM,CAAC4G,OAAO,CAACD,WAAW,CAAC,CAACrH,KAAK;IAEvD,MAAMyH,QAAQ,GAAG;MACfzH,KAAK,EAAEwH,QAAQ;MACfE,QAAQ,EAAE,CAACH,YAAY,CAACI,QAAQ,CAACH,QAAQ,CAAC;MAC1CI,QAAQ,EAAE;IACZ,CAAC;IAED,IAAI,CAACjG,SAAS,CAAC8F,QAAQ,CAAC;EAC1B;AACF;AAACnH,OAAA,CAAAuH,OAAA,GAAAtH,cAAA","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_main","_interopRequireDefault","require","_react","_client","_lodashEs","_debug","_piePlayerEvents","_mathRendering","_renderUi","_sessionUpdater","log","debug","isComplete","session","model","audioComplete","elementContext","autoplayAudioEnabled","completeAudioEnabled","audio","querySelector","isInsidePrompt","closest","value","choiceMode","minSelections","maxSelections","selections","length","exports","MultipleChoice","HTMLElement","constructor","_model","_session","_options","_boundHandleKeyDown","handleKeyDown","bind","_keyboardEventsEnabled","_audioInitialized","_root","_rerender","debounce","element","React","createElement","Main","options","onChoiceChanged","_onChange","onShowCorrectToggle","setAttribute","setLangAttribute","createRoot","render","requestAnimationFrame","renderMath","keyboardEventsEnabled","enableKeyboardEvents","leading","trailing","_dispatchResponseChanged","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","_dispatchModelSet","ModelSetEvent","undefined","language","lang","slice","s","o","data","updateSessionValue","_createAudioInfoToast","info","document","id","Object","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","connectedCallback","observer","MutationObserver","mutationsList","forEach","mutation","type","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","updateSessionMetadata","audioStartTime","Date","getTime","handleEnded","audioEndTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","window","disconnectedCallback","unmount","event","mode","keyToIndex","key","numOffset","letterOffset","test","charCodeAt","choiceIndex","choices","currentValue","choiceId","newValue","selected","includes","selector","default"],"sources":["../src/index.js"],"sourcesContent":["import Main from './main';\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { debounce } from 'lodash-es';\nimport debug from 'debug';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { EnableAudioAutoplayImage } from '@pie-lib/render-ui';\nimport { updateSessionValue, updateSessionMetadata } from './session-updater';\n\nconst log = debug('pie-ui:multiple-choice');\n\nexport const isComplete = (session, model, audioComplete, elementContext) => {\n const { autoplayAudioEnabled, completeAudioEnabled } = model || {};\n\n // check audio completion if audio settings are enabled and audio actually exists\n if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {\n if (elementContext) {\n const audio = elementContext.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n // only require audio completion if audio exists and is inside the prompt\n if (audio && isInsidePrompt) {\n return false;\n }\n }\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n const { choiceMode, minSelections = 1, maxSelections } = model || {};\n const selections = session.value.length || 0;\n\n if (choiceMode === 'radio') {\n return !!selections;\n }\n\n if (selections < minSelections || selections > maxSelections) {\n return false;\n }\n\n return true;\n};\n\nexport default class MultipleChoice extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this._options = null; // added for ebsr print mode detection\n this.audioComplete = false;\n this._boundHandleKeyDown = this.handleKeyDown.bind(this);\n this._keyboardEventsEnabled = false;\n this._audioInitialized = false;\n this._root = null;\n\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n var element = React.createElement(Main, {\n model: this._model,\n session: this._session,\n options: this._options,\n onChoiceChanged: this._onChange.bind(this),\n onShowCorrectToggle: this.onShowCorrectToggle.bind(this),\n });\n\n //TODO: aria-label is set in the _rerender because we need to change it when the model.choiceMode is updated. Consider revisiting the placement of the aria-label setting in the _rerender\n this.setAttribute(\n 'aria-label',\n this._model.choiceMode === 'radio' ? 'Multiple Choice Question' : 'Multiple Correct Answer Question',\n );\n this.setAttribute('role', 'region');\n this.setLangAttribute();\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n // Use requestAnimationFrame to ensure DOM is fully painted before rendering math\n requestAnimationFrame(() => {\n log('render complete - render math');\n renderMath(this);\n });\n\n if (this._model.keyboardEventsEnabled === true && !this._keyboardEventsEnabled) {\n this.enableKeyboardEvents();\n }\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n\n this._dispatchResponseChanged = debounce(() => {\n this.dispatchEvent(\n new SessionChangedEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model, this.audioComplete, this),\n ),\n );\n });\n\n this._dispatchModelSet = debounce(\n () => {\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model, this.audioComplete, this),\n this._model !== undefined,\n ),\n );\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n\n onShowCorrectToggle() {\n renderMath(this);\n }\n\n setLangAttribute() {\n const language = this._model && typeof this._model.language ? this._model.language : '';\n const lang = language ? language.slice(0, 2) : 'en';\n this.setAttribute('lang', lang);\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n // reset the audioInitialized to false since the model changed, and we might need to reinitialize the audio\n this._audioInitialized = false;\n this._dispatchModelSet();\n }\n\n get session() {\n return this._session;\n }\n\n get options() {\n return this._options;\n }\n\n set options(o) {\n this._options = o;\n this._rerender();\n }\n\n set session(s) {\n this._session = s;\n this._rerender();\n //TODO: remove this session-changed should only be emit on user change\n this._dispatchResponseChanged();\n }\n\n _onChange(data) {\n updateSessionValue(this._session, this._model.choiceMode, data);\n this._dispatchResponseChanged();\n this._rerender();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000',\n cursor: 'pointer',\n });\n\n const img = document.createElement('img');\n img.src = EnableAudioAutoplayImage;\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._rerender();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n if (this._audioInitialized) return;\n\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n updateSessionMetadata(this._session, { audioStartTime: new Date().getTime() });\n\n const info = this.querySelector('#play-audio-info');\n if (info) {\n container.removeChild(info);\n }\n\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });\n this.audioComplete = true;\n this._dispatchResponseChanged();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n // set to true to prevent multiple initializations\n this._audioInitialized = true;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n enableKeyboardEvents() {\n if (!this._keyboardEventsEnabled) {\n window.addEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = true;\n }\n }\n\n disconnectedCallback() {\n if (this._keyboardEventsEnabled) {\n window.removeEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = false;\n }\n\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n\n if (this._root) {\n this._root.unmount();\n }\n }\n\n /**\n * Handles global keyboard events for selecting or toggling multiple-choice answers.\n * Maps keys (1-9, 0, a-j, A-J) to choices and updates the session state accordingly.\n * Ensures valid key presses toggle or select the appropriate choice based on the model.\n */\n handleKeyDown(event) {\n if (!this._model || !this._session) {\n return;\n }\n\n const { mode } = this._model;\n if (mode !== 'gather') {\n return;\n }\n\n const keyToIndex = (key) => {\n const numOffset = key >= '1' && key <= '9' ? key - '1' : key === '0' ? 9 : -1;\n const letterOffset = /^[a-jA-J]$/.test(key) ? key.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0) : -1;\n return numOffset >= 0 ? numOffset : letterOffset;\n };\n\n const choiceIndex = keyToIndex(event.key);\n\n if (choiceIndex === undefined || choiceIndex <= -1 || choiceIndex >= this._model.choices?.length) {\n return;\n }\n\n const currentValue = this._session.value || [];\n const choiceId = this._model.choices[choiceIndex].value;\n\n const newValue = {\n value: choiceId,\n selected: !currentValue.includes(choiceId),\n selector: 'Keyboard',\n };\n\n this._onChange(newValue);\n }\n}\n"],"mappings":"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","ignoreList":[]}
package/lib/print.js CHANGED
@@ -7,8 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _client = require("react-dom/client");
10
- var _debounce = _interopRequireDefault(require("lodash/debounce"));
11
- var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
10
+ var _lodashEs = require("lodash-es");
12
11
  var _main = _interopRequireDefault(require("./main"));
13
12
  var _mathRendering = require("@pie-lib/math-rendering");
14
13
  var _debug = _interopRequireDefault(require("debug"));
@@ -33,7 +32,7 @@ const preparePrintModel = (model, opts) => {
33
32
  model.animationsDisabled = true;
34
33
  model.lockChoiceOrder = true;
35
34
  model.choicesLayout = model.choicesLayout || 'vertical';
36
- const choices = (0, _cloneDeep.default)(model.choices);
35
+ const choices = (0, _lodashEs.cloneDeep)(model.choices);
37
36
  model.choices = choices.map(c => {
38
37
  c.rationale = instr && model.rationaleEnabled !== false ? c.rationale : undefined;
39
38
  c.hideTick = instr;
@@ -50,7 +49,7 @@ class MultipleChoicePrint extends HTMLElement {
50
49
  this._model = null;
51
50
  this._session = [];
52
51
  this._root = null;
53
- this._rerender = (0, _debounce.default)(() => {
52
+ this._rerender = (0, _lodashEs.debounce)(() => {
54
53
  if (this._model && this._session) {
55
54
  const printModel = preparePrintModel(this._model, this._options);
56
55
  const element = this._options && /*#__PURE__*/_react.default.createElement(_main.default, {
@@ -62,7 +61,9 @@ class MultipleChoicePrint extends HTMLElement {
62
61
  this._root = (0, _client.createRoot)(this);
63
62
  }
64
63
  this._root.render(element);
65
- queueMicrotask(() => {
64
+ // Use requestAnimationFrame to ensure DOM is fully painted before rendering math
65
+ // This is especially important for nested components like PreviewPrompt (rationale, choice labels)
66
+ requestAnimationFrame(() => {
66
67
  log('render complete - render math');
67
68
  (0, _mathRendering.renderMath)(this);
68
69
  });
package/lib/print.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"print.js","names":["_react","_interopRequireDefault","require","_client","_debounce","_cloneDeep","_main","_mathRendering","_debug","log","debug","preparePrintModel","model","opts","instr","role","prompt","promptEnabled","undefined","teacherInstructions","teacherInstructionsEnabled","showTeacherInstructions","alwaysShowCorrect","mode","disabled","animationsDisabled","lockChoiceOrder","choicesLayout","choices","cloneDeep","map","c","rationale","rationaleEnabled","hideTick","feedback","keyMode","choicePrefix","MultipleChoicePrint","HTMLElement","constructor","_options","_model","_session","_root","_rerender","debounce","printModel","element","React","createElement","Main","session","options","createRoot","render","queueMicrotask","renderMath","leading","trailing","o","s","connectedCallback","disconnectedCallback","unmount","exports","default"],"sources":["../src/print.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport debounce from 'lodash/debounce';\nimport cloneDeep from 'lodash/cloneDeep';\nimport Main from './main';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport debug from 'debug';\n\nconst log = debug('pie-element:multiple-choice:print');\n\n/**\n * Live in same package as main element - so we can access some of the shared comps!\n *\n * - update pslb to build print if src/print.js is there\n * - update demo el\n * - get configure/controller building\n */\n\nconst preparePrintModel = (model, opts) => {\n const instr = opts.role === 'instructor';\n\n model.prompt = model.promptEnabled !== false ? model.prompt : undefined;\n model.teacherInstructions =\n instr && model.teacherInstructionsEnabled !== false ? model.teacherInstructions : undefined;\n model.showTeacherInstructions = instr;\n model.alwaysShowCorrect = instr;\n model.mode = instr ? 'evaluate' : model.mode;\n\n model.disabled = true;\n model.animationsDisabled = true;\n model.lockChoiceOrder = true;\n model.choicesLayout = model.choicesLayout || 'vertical';\n\n const choices = cloneDeep(model.choices);\n\n model.choices = choices.map((c) => {\n c.rationale = instr && model.rationaleEnabled !== false ? c.rationale : undefined;\n c.hideTick = instr;\n c.feedback = undefined;\n return c;\n });\n\n model.keyMode = model.choicePrefix || 'letters';\n\n return model;\n};\n\nexport default class MultipleChoicePrint extends HTMLElement {\n constructor() {\n super();\n this._options = null;\n this._model = null;\n this._session = [];\n this._root = null;\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n const printModel = preparePrintModel(this._model, this._options);\n\n const element =\n this._options &&\n React.createElement(Main, {\n model: printModel,\n session: {},\n options: this._options,\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n queueMicrotask(() => {\n log('render complete - render math');\n renderMath(this);\n });\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n set options(o) {\n this._options = o;\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n }\n\n connectedCallback() {}\n\n disconnectedCallback() {\n if (this._root) {\n this._root.unmount();\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"print.js","names":["_react","_interopRequireDefault","require","_client","_lodashEs","_main","_mathRendering","_debug","log","debug","preparePrintModel","model","opts","instr","role","prompt","promptEnabled","undefined","teacherInstructions","teacherInstructionsEnabled","showTeacherInstructions","alwaysShowCorrect","mode","disabled","animationsDisabled","lockChoiceOrder","choicesLayout","choices","cloneDeep","map","c","rationale","rationaleEnabled","hideTick","feedback","keyMode","choicePrefix","MultipleChoicePrint","HTMLElement","constructor","_options","_model","_session","_root","_rerender","debounce","printModel","element","React","createElement","Main","session","options","createRoot","render","requestAnimationFrame","renderMath","leading","trailing","o","s","connectedCallback","disconnectedCallback","unmount","exports","default"],"sources":["../src/print.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { cloneDeep, debounce } from 'lodash-es';\nimport Main from './main';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport debug from 'debug';\n\nconst log = debug('pie-element:multiple-choice:print');\n\n/**\n * Live in same package as main element - so we can access some of the shared comps!\n *\n * - update pslb to build print if src/print.js is there\n * - update demo el\n * - get configure/controller building\n */\n\nconst preparePrintModel = (model, opts) => {\n const instr = opts.role === 'instructor';\n\n model.prompt = model.promptEnabled !== false ? model.prompt : undefined;\n model.teacherInstructions =\n instr && model.teacherInstructionsEnabled !== false ? model.teacherInstructions : undefined;\n model.showTeacherInstructions = instr;\n model.alwaysShowCorrect = instr;\n model.mode = instr ? 'evaluate' : model.mode;\n\n model.disabled = true;\n model.animationsDisabled = true;\n model.lockChoiceOrder = true;\n model.choicesLayout = model.choicesLayout || 'vertical';\n\n const choices = cloneDeep(model.choices);\n\n model.choices = choices.map((c) => {\n c.rationale = instr && model.rationaleEnabled !== false ? c.rationale : undefined;\n c.hideTick = instr;\n c.feedback = undefined;\n return c;\n });\n\n model.keyMode = model.choicePrefix || 'letters';\n\n return model;\n};\n\nexport default class MultipleChoicePrint extends HTMLElement {\n constructor() {\n super();\n this._options = null;\n this._model = null;\n this._session = [];\n this._root = null;\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n const printModel = preparePrintModel(this._model, this._options);\n\n const element =\n this._options &&\n React.createElement(Main, {\n model: printModel,\n session: {},\n options: this._options,\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n // Use requestAnimationFrame to ensure DOM is fully painted before rendering math\n // This is especially important for nested components like PreviewPrompt (rationale, choice labels)\n requestAnimationFrame(() => {\n log('render complete - render math');\n renderMath(this);\n });\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n set options(o) {\n this._options = o;\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n }\n\n connectedCallback() {}\n\n disconnectedCallback() {\n if (this._root) {\n this._root.unmount();\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pie-element/multiple-choice",
3
3
  "repository": "pie-framework/pie-elements",
4
- "version": "12.0.0-next.43+4249fa78f",
4
+ "version": "12.1.2-next.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -11,19 +11,19 @@
11
11
  "@mui/icons-material": "^7.3.4",
12
12
  "@mui/material": "^7.3.4",
13
13
  "@pie-framework/pie-player-events": "^0.1.0",
14
- "@pie-lib/correct-answer-toggle": "3.1.1-next.0",
15
- "@pie-lib/math-rendering": "4.1.1-next.0",
16
- "@pie-lib/render-ui": "5.1.1-next.0",
17
- "@pie-lib/translator": "3.1.1-next.0",
14
+ "@pie-lib/correct-answer-toggle": "3.2.0-next.4",
15
+ "@pie-lib/math-rendering": "4.2.0-next.3",
16
+ "@pie-lib/render-ui": "5.2.0-next.4",
17
+ "@pie-lib/translator": "3.2.0-next.3",
18
18
  "classnames": "^2.2.5",
19
19
  "debug": "^4.1.1",
20
- "lodash": "^4.17.23",
20
+ "lodash-es": "^4.17.23",
21
21
  "prop-types": "^15.8.1",
22
22
  "react": "18.3.1",
23
23
  "react-dom": "18.3.1",
24
24
  "react-transition-group": "^4.4.5"
25
25
  },
26
- "gitHead": "4249fa78fc423ef0a8c89002b8f937c42b3478ea",
26
+ "gitHead": "9cc4a1cd183a260a03c7d817e0085517112a1a56",
27
27
  "scripts": {
28
28
  "postpublish": "../../scripts/postpublish"
29
29
  },
@@ -1 +0,0 @@
1
- import{_dll_react_dom as e,_dll_react as t,_dll_prop_types as o,_dll_mui__material_styles as n,_dll_pie_lib__render_ui as i,_dll_mui__material as a,_dll_lodash as s,_dll_mui__icons_material as l,_dll_debug as r}from"../../../@pie-lib/shared-module@^3.0.5/module/index.js";import{_dll_pie_lib__config_ui as c}from"../../../@pie-lib/config-module@^3.0.0/module/index.js";import{_dll_pie_lib__editable_html_tip_tap as d}from"../../../@pie-lib/editable-html-module@^6.0.5/module/index.js";var h,u=e;h=u.createRoot,u.hydrateRoot;var g={};Object.defineProperty(g,"__esModule",{value:!0});class p extends CustomEvent{constructor(e,t=!1){super(p.TYPE,{bubbles:!0,detail:{update:e,reset:t}}),this.update=e,this.reset=t}}p.TYPE="model.updated";var m=g.ModelUpdatedEvent=p;class b extends CustomEvent{constructor(e,t){super(b.TYPE,{bubbles:!0,detail:{src:e,done:t}}),this.src=e,this.done=t}}b.TYPE="delete.image";var C=g.DeleteImageEvent=b;class _ extends CustomEvent{constructor(e){super(_.TYPE,{bubbles:!0,detail:e}),this.handler=e}}_.TYPE="insert.image";var f=g.InsertImageEvent=_;class E extends CustomEvent{constructor(e,t){super(E.TYPE,{bubbles:!0,detail:{src:e,done:t}}),this.src=e,this.done=t}}E.TYPE="delete.sound";var S=g.DeleteSoundEvent=E;class y extends CustomEvent{constructor(e){super(y.TYPE,{bubbles:!0,detail:e}),this.handler=e}}y.TYPE="insert.sound";var v=g.InsertSoundEvent=y;const k=t,I=o,{styled:x}=n,{color:A}=i,{Button:M}=a,{Tooltip:P}=a,{Typography:w}=a,{Box:T}=a,{Info:R}=l,{merge:O}=s,L=d,{AlertDialog:D}=c,{InputContainer:q}=c,{ChoiceConfiguration:W}=c,{settings:z}=c,{layout:Y}=c,{choiceUtils:B}=c;function U(e){let t,o=e[0],n=1;for(;n<e.length;){const i=e[n],a=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==o)return;"access"===i||"optionalAccess"===i?(t=o,o=a(o)):"call"!==i&&"optionalCall"!==i||(o=a((...e)=>o.call(t,...e)),t=void 0)}return o}const{Panel:$,toggle:H,radio:j,dropdown:F}=z,N=x(q)(({theme:e})=>({width:"100%",paddingTop:e.spacing(2),marginBottom:e.spacing(2)})),G=x(q)(({theme:e})=>({flex:1,marginTop:e.spacing(1.5),paddingTop:e.spacing(2),marginLeft:e.spacing(3.5)})),V=x(q)(({theme:e})=>({display:"flex",flexDirection:"column",marginBottom:e.spacing(1),width:"100%"})),J=x(M)(({theme:e})=>({marginTop:e.spacing(1),float:"right"})),K=x(J)({cursor:"not-allowed",pointerEvents:"all",backgroundColor:A.disabled(),"&:hover":{backgroundColor:A.disabled()},"&:focus":{backgroundColor:A.disabled()}}),Q=x(T)({display:"flex",alignItems:"center"}),X=x(w)(({theme:e})=>({fontSize:e.typography.fontSize+2,marginRight:e.spacing(1)})),Z=x(P)(({theme:e})=>({"& .MuiTooltip-tooltip":{fontSize:e.typography.fontSize-2,whiteSpace:"pre",maxWidth:"500px"}})),ee=x("div")(({theme:e})=>({fontSize:e.typography.fontSize-2,color:e.palette.error.main,paddingTop:e.spacing(1)})),te=e=>{const{model:t,configuration:o,onPromptChanged:n,onChoiceChanged:i,onRemoveChoice:a,onAddChoice:s,imageSupport:l,uploadSoundSupport:r,onChangeModel:c,onConfigurationChanged:d,onTeacherInstructionsChanged:h}=e,{addChoiceButton:u={},contentDimensions:g={},feedback:p={},deleteChoice:m={},choiceMode:b={},choicePrefix:C={},partialScoring:_={},lockChoiceOrder:f={},teacherInstructions:E={},studentInstructions:S={},rationale:y={},scoringType:v={},sequentialChoiceLabels:I={},settingsPanelDisabled:x,choicesLayout:A,spellCheck:M={},gridColumns:P,maxImageWidth:w={},maxImageHeight:T={},prompt:O={},withRubric:D={},mathMlOptions:q={},language:z={},languageChoices:B={}}=o||{};let{maxAnswerChoices:te}=o||{};const{limitChoicesNumber:oe,teacherInstructionsEnabled:ne,rationaleEnabled:ie,feedbackEnabled:ae,promptEnabled:se,spellCheckEnabled:le,choices:re,errors:ce,toolbarEditorPosition:de,extraCSSRules:he}=t||{},{answerChoices:ue,choices:ge,correctResponse:pe,prompt:me,rationale:be,teacherInstructions:Ce}=ce||{},_e=U([re,"optionalAccess",e=>e.length])?Array.from({length:re.length},(e,t)=>`${t+1}`):[],{baseInputConfiguration:fe={}}=o,Ee={position:"top"===de?"top":"bottom"};oe&&(te=9);const Se=(e={})=>({...fe,...e}),ye=(e=>{const{minAnswerChoices:t,maxAnswerChoices:o}=e;return`Validation requirements:\nThere should be at least ${t} `+(o?`and at most ${o} `:"")+"answer choices defined.\nEvery answer choice should be non-blank and unique.\nA correct answer must be defined."})(o),ve=w&&w.prompt,ke=T&&T.prompt,Ie=te&&U([re,"optionalAccess",e=>e.length])>=te?`Only ${te} allowed maximum`:"",xe={choiceMode:b.settings&&j(b.label,["checkbox","radio"]),"sequentialChoiceLabels.enabled":I.settings&&H(I.label,!0),choicePrefix:C.settings&&j(C.label,["numbers","letters"]),partialScoring:_.settings&&H(_.label),lockChoiceOrder:f.settings&&H(f.label),feedbackEnabled:p.settings&&H(p.label),choicesLayout:A.settings&&F(A.label,["vertical","grid","horizontal"]),gridColumns:A.settings&&"grid"===t.choicesLayout&&_e.length>0&&F(P.label,_e),"language.enabled":z.settings&&H(z.label,!0),language:z.settings&&z.enabled&&F(B.label,B.options)},Ae={teacherInstructionsEnabled:E.settings&&H(E.label),studentInstructionsEnabled:S.settings&&H(S.label),promptEnabled:O.settings&&H(O.label),rationaleEnabled:y.settings&&H(y.label),spellCheckEnabled:M.settings&&H(M.label),scoringType:v.settings&&j(v.label,["auto","rubric"]),rubricEnabled:U([D,"optionalAccess",e=>e.settings])&&H(U([D,"optionalAccess",e=>e.label]))};return k.createElement(Y.ConfigLayout,{dimensions:g,hideSettings:x,extraCSSRules:he,classes:{},settings:k.createElement($,{model:t,onChangeModel:c,configuration:o,onChangeConfiguration:d,groups:{Settings:xe,Properties:Ae}})},ne&&k.createElement(N,{label:E.label},k.createElement(L,{markup:t.teacherInstructions||"",onChange:h,imageSupport:l,nonEmpty:!1,disableUnderline:!0,error:Ce,toolbarOpts:Ee,pluginProps:Se(U([o,"optionalAccess",e=>e.teacherInstructions,"optionalAccess",e=>e.inputConfiguration])),spellCheck:le,maxImageWidth:w&&w.teacherInstructions||ve,maxImageHeight:T&&T.teacherInstructions||ke,uploadSoundSupport:r,languageCharactersProps:[{language:"spanish"},{language:"special"}],mathMlOptions:q}),Ce&&k.createElement(ee,null,Ce)),se&&k.createElement(N,{label:O.label},k.createElement(L,{markup:t.prompt,onChange:n,imageSupport:l,nonEmpty:!1,disableUnderline:!0,error:me,toolbarOpts:Ee,pluginProps:Se(U([o,"optionalAccess",e=>e.prompt,"optionalAccess",e=>e.inputConfiguration])),spellCheck:le,maxImageWidth:w&&w.prompt,maxImageHeight:T&&T.prompt,uploadSoundSupport:r,languageCharactersProps:[{language:"spanish"},{language:"special"}],mathMlOptions:q}),me&&k.createElement(ee,null,me)),k.createElement(Q,null,k.createElement(X,{component:"div"},"Choices"),k.createElement(Z,{disableFocusListener:!0,disableTouchListener:!0,placement:"right",title:ye},k.createElement(R,{fontSize:"small",color:"primary"}))),re.map((e,n)=>k.createElement(V,{key:`choice-${n}`},k.createElement(W,{key:n,index:n+1,useLetterOrdering:"letters"===t.choicePrefix,mode:t.choiceMode,data:e,defaultFeedback:{},imageSupport:l,disableImageAlignmentButtons:!0,onDelete:()=>a(n),onChange:e=>i(n,e),allowFeedBack:ae,allowDelete:m.settings,noLabels:!0,pluginOpts:Se(U([o,"optionalAccess",e=>e.choices,"optionalAccess",e=>e.inputConfiguration])),toolbarOpts:Ee,spellCheck:le,error:U([ge,"optionalAccess",t=>t[e.value]])||null,noCorrectAnswerError:pe,maxImageWidth:w&&w.choices||ve,maxImageHeight:T&&T.choices||ke,uploadSoundSupport:r,mathMlOptions:q}),ie&&k.createElement(G,{key:`rationale-${n}`,label:y.label},k.createElement(L,{markup:e.rationale||"",onChange:t=>i(n,{...e,rationale:t}),imageSupport:l,error:U([be,"optionalAccess",t=>t[e.value]])||null,toolbarOpts:Ee,pluginProps:Se(U([o,"optionalAccess",e=>e.rationale,"optionalAccess",e=>e.inputConfiguration])),spellCheck:le,maxImageWidth:w&&w.rationale||ve,maxImageHeight:T&&T.rationale||ke,uploadSoundSupport:r,languageCharactersProps:[{language:"spanish"},{language:"special"}],mathMlOptions:q}),U([be,"optionalAccess",t=>t[e.value]])&&k.createElement(ee,null,U([be,"optionalAccess",t=>t[e.value]]))))),pe&&k.createElement(ee,null,pe),ue&&k.createElement(ee,null,ue),u.settings&&k.createElement(Z,{title:Ie},te&&U([re,"optionalAccess",e=>e.length])>=te?k.createElement(K,{variant:"contained",color:"primary",onClick:s,disabled:!0},u.label):k.createElement(J,{variant:"contained",color:"primary",onClick:s},u.label)))};class oe extends k.Component{constructor(...e){super(...e),oe.prototype.__init.call(this),oe.prototype.__init2.call(this),oe.prototype.__init3.call(this),oe.prototype.__init4.call(this),oe.prototype.__init5.call(this),oe.prototype.__init6.call(this),oe.prototype.__init7.call(this)}static __initStatic(){this.propTypes={model:I.object.isRequired,configuration:I.object.isRequired,disableSidePanel:I.bool,onModelChanged:I.func.isRequired,onConfigurationChanged:I.func.isRequired,imageSupport:I.shape({add:I.func.isRequired,delete:I.func.isRequired})}}__init(){this.state={showWarning:!1}}__init2(){this.onRemoveChoice=e=>{const{model:t,configuration:o,onModelChanged:n}=this.props,{minAnswerChoices:i}=o||{};i&&t.choices.length===i?this.setState({showWarning:!0}):(t.choices.splice(e,1),n(t))}}__init3(){this.onAddChoice=()=>{const{model:e,configuration:t,onModelChanged:o}=this.props;let{maxAnswerChoices:n}=t||{};const{limitChoicesNumber:i}=e||{};i&&(n=9),n&&e.choices.length>=n||(e.choices.push({label:"",value:B.firstAvailableIndex(e.choices.map(e=>e.value),0),feedback:{type:"none"}}),o(e))}}__init4(){this.onChoiceChanged=(e,t)=>{const{model:o,onModelChanged:n}=this.props;t.correct&&"radio"===o.choiceMode&&(o.choices=o.choices.map(e=>O({},e,{correct:!1}))),o.choices.splice(e,1,t),n(o)}}__init5(){this.onPromptChanged=e=>{this.props.onModelChanged({...this.props.model,prompt:e})}}__init6(){this.onTeacherInstructionsChanged=e=>{this.props.onModelChanged({...this.props.model,teacherInstructions:e})}}__init7(){this.onModelChanged=(e,t)=>{const{onModelChanged:o}=this.props;if("choiceMode"===t){if("radio"===e.choiceMode){let t=!1;e.choices=e.choices.map(e=>t?(e.correct=!1,e):(e.correct&&(t=!0),e))}o(e,!0)}else o(e)}}render(){const{configuration:{minAnswerChoices:e}={}}=this.props,{showWarning:t}=this.state;return k.createElement(k.Fragment,null,k.createElement(D,{open:t,title:"Warning",text:`There can't be less than ${e||0} choices.`,onConfirm:()=>this.setState({showWarning:!1})}),k.createElement(te,{...this.props,onChangeModel:this.onModelChanged,onRemoveChoice:this.onRemoveChoice,onChoiceChanged:this.onChoiceChanged,onAddChoice:this.onAddChoice,onPromptChanged:this.onPromptChanged,onTeacherInstructionsChanged:this.onTeacherInstructionsChanged}))}}oe.__initStatic();var ne={choiceMode:"checkbox",choicePrefix:"letters",choices:[],choicesLayout:"vertical",feedbackEnabled:!1,gridColumns:2,lockChoiceOrder:!0,partialScoring:!0,prompt:"",promptEnabled:!0,rationale:"",rationaleEnabled:!0,scoringType:"auto",studentInstructionsEnabled:!0,teacherInstructions:"",teacherInstructionsEnabled:!0,toolbarEditorPosition:"bottom",selectedAnswerBackgroundColor:"initial",keyboardEventsEnabled:!1},ie={baseInputConfiguration:{audio:{disabled:!1},video:{disabled:!1},image:{disabled:!1},textAlign:{disabled:!0},showParagraphs:{disabled:!1},separateParagraphs:{disabled:!0}},choices:{inputConfiguration:{audio:{disabled:!1},video:{disabled:!1},image:{disabled:!1}}},spellCheck:{label:"Spellcheck",settings:!1,enabled:!0},choicesLayout:{settings:!1,label:"Choices Layout"},gridColumns:{label:"Grid columns"},answerChoiceCount:0,addChoiceButton:{settings:!0,label:"Add a Choice"},choiceMode:{settings:!0,label:"Response Type"},choicePrefix:{settings:!0,label:"Choice Labels"},deleteChoice:{settings:!0},feedback:{settings:!0,label:"Feedback"},prompt:{settings:!0,label:"Prompt",inputConfiguration:{audio:{disabled:!1},video:{disabled:!1},image:{disabled:!1}},required:!1},lockChoiceOrder:{settings:!0,label:"Lock Choice Order"},partialScoring:{settings:!1,label:"Allow Partial Scoring"},rationale:{settings:!0,label:"Rationale",inputConfiguration:{audio:{disabled:!0},video:{disabled:!0},image:{disabled:!1}},required:!1},scoringType:{settings:!1,label:"Scoring Type"},studentInstructions:{settings:!1,label:"Student Instructions"},teacherInstructions:{settings:!0,label:"Teacher Instructions",inputConfiguration:{audio:{disabled:!1},video:{disabled:!1},image:{disabled:!1}},required:!1},toolbarEditorPosition:{settings:!1,label:"Toolbar Editor Position"},minAnswerChoices:2,maxAnswerChoices:5,maxImageWidth:{teacherInstructions:300,prompt:300,rationale:636,choices:900},maxImageHeight:{teacherInstructions:300,prompt:300,rationale:300,choices:300},withRubric:{settings:!1,label:"Add Rubric"},mathMlOptions:{mmlOutput:!1,mmlEditing:!1},language:{settings:!1,label:"Specify Language",enabled:!1},languageChoices:{label:"Language Choices",options:[]}};const ae=t,se=r,{defaults:le}=s,{choiceUtils:re}=c;function ce(e){let t,o=e[0],n=1;for(;n<e.length;){const i=e[n],a=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==o)return;"access"===i||"optionalAccess"===i?(t=o,o=a(o)):"call"!==i&&"optionalCall"!==i||(o=a((...e)=>o.call(t,...e)),t=void 0)}return o}const de=se("multiple-choice:configure"),he=(e,t=0)=>{if(!e||0===e.length){let e=[];for(let o=0;o<t;o++)e.push({value:`${o}`,label:"",feedback:{type:"none",value:""}});return e}return e},ue=(e,t)=>{const o=le(e,ie);return{configuration:o,model:{...t,choices:he(t&&t.choices||[],o&&o.answerChoiceCount)}}};class ge extends HTMLElement{static __initStatic(){this.createDefaultModel=(e={})=>{const t=re.normalizeChoices({...ne,...e,choices:he(e&&e.choices||[])});return t.choicesLayout=e.choicesLayout||!1===e.verticalMode&&"horizontal"||ne.choicesLayout,t}}constructor(){super(),this._root=null,this._reactContainer=null,this._model=ge.createDefaultModel(),this._configuration=ie,this.onModelChanged=this.onModelChanged.bind(this),this.onConfigurationChanged=this.onConfigurationChanged.bind(this)}set model(e){this._model=ge.createDefaultModel(e),this._render()}set configuration(e){const t=ue(e,this._model);this.onModelChanged(t.model);const o={...ie,...t.configuration};this._configuration=o,ce([o,"optionalAccess",e=>e.language,"optionalAccess",e=>e.enabled])?ce([o,"optionalAccess",e=>e.languageChoices,"optionalAccess",e=>e.options,"optionalAccess",e=>e.length])&&(this._model.language=ce([o,"optionalAccess",e=>e.languageChoices,"access",e=>e.options,"access",e=>e[0],"access",e=>e.value])):o.language.settings&&this._model.language?(this._configuration.language.enabled=!0,this._configuration.languageChoices.options&&this._configuration.languageChoices.options.length||(this._configuration.languageChoices.options=[]),this._configuration.languageChoices.options.find(e=>e.value===this._model.language)||this._configuration.languageChoices.options.push({value:this._model.language,label:this._model.language})):delete this._model.language,this._render()}set disableSidePanel(e){this._disableSidePanel=e,this._render()}dispatchModelUpdated(e){const t=!!e;this.dispatchEvent(new m(this._model,t))}onModelChanged(e,t){this._model=e,this._render(),this.dispatchModelUpdated(t)}onConfigurationChanged(e){this._configuration=ue(e,this._model).configuration,this._model&&this.onModelChanged(this._model),this._render()}insertImage(e){this.dispatchEvent(new f(e))}onDeleteImage(e,t){this.dispatchEvent(new C(e,t))}insertSound(e){this.dispatchEvent(new v(e))}onDeleteSound(e,t){this.dispatchEvent(new S(e,t))}_render(){console.log("🔧 [multiple-choice-configure] _render - Starting render"),console.log("🔧 [multiple-choice-configure] _render - Model:",this._model?"present":"missing"),console.log("🔧 [multiple-choice-configure] _render - Configuration:",this._configuration?"present":"missing"),console.log("🔧 [multiple-choice-configure] _render - Root exists:",!!this._root),de("_render - Starting render"),de("_render - Model:",this._model?"present":"missing"),de("_render - Configuration:",this._configuration?"present":"missing"),de("_render - Root exists:",!!this._root);try{let e=ae.createElement(oe,{model:this._model,configuration:this._configuration,onModelChanged:this.onModelChanged,onConfigurationChanged:this.onConfigurationChanged,disableSidePanel:this._disableSidePanel,imageSupport:{add:this.insertImage.bind(this),delete:this.onDeleteImage.bind(this)},uploadSoundSupport:{add:this.insertSound.bind(this),delete:this.onDeleteSound.bind(this)}});this._root||(console.log("🔧 [multiple-choice-configure] _render - Creating React container"),de("_render - Creating React container"),this._reactContainer=document.createElement("div"),this._reactContainer.className="pie-configure-wrapper",this.appendChild(this._reactContainer),console.log("🔧 [multiple-choice-configure] _render - Creating new React root"),de("_render - Creating new React root"),this._root=h(this._reactContainer),console.log("✅ [multiple-choice-configure] _render - React root created successfully"),de("_render - React root created successfully")),console.log("🔧 [multiple-choice-configure] _render - Calling root.render()"),de("_render - Calling root.render()"),this._root.render(e),console.log("✅ [multiple-choice-configure] _render - Render completed successfully"),de("_render - Render completed successfully")}catch(e){throw console.error("❌ [multiple-choice-configure] Render error:",e),console.error("Error stack:",e.stack),e}}connectedCallback(){console.log("🔧 [multiple-choice-configure] connectedCallback - Component connected to DOM"),de("connectedCallback - Component connected to DOM"),de("connectedCallback - Model:",this._model?"present":"missing"),de("connectedCallback - Configuration:",this._configuration?"present":"missing")}disconnectedCallback(){console.log("🔧 [multiple-choice-configure] disconnectedCallback - Component disconnected from DOM"),de("disconnectedCallback - Component disconnected from DOM"),this._root&&(console.log("🔧 [multiple-choice-configure] disconnectedCallback - Unmounting React root"),de("disconnectedCallback - Unmounting React root"),this._root.unmount(),this._root=null),this._reactContainer&&(this._reactContainer=null)}}ge.__initStatic();export{ge as default};