{"version":3,"file":"106.e36ae7ea63317cae.bundle.js","mappings":"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","sources":["webpack://WebComponents/./runestone/fitb/js/fitb-i18n.en.js","webpack://WebComponents/./runestone/fitb/js/fitb-i18n.pt-br.js","webpack://WebComponents/./runestone/fitb/js/fitb.js","webpack://WebComponents/./runestone/fitb/js/timedfitb.js"],"sourcesContent":["$.i18n().load({\n en: {\n msg_no_answer: \"No answer provided.\",\n msg_fitb_check_me: \"Check me\",\n msg_fitb_compare_me: \"Compare me\",\n },\n});\n","$.i18n().load({\n \"pt-br\": {\n msg_no_answer: \"Nenhuma resposta dada.\",\n msg_fitb_check_me: \"Verificar\",\n msg_fitb_compare_me: \"Comparar\"\n },\n});\n","// *********\n// |docname|\n// *********\n// This file contains the JS for the Runestone fillintheblank component. It was created By Isaiah Mayerchak and Kirby Olson, 6/4/15 then revised by Brad Miller, 2/7/20.\n\"use strict\";\n\nimport RunestoneBase from \"../../common/js/runestonebase.js\";\nimport \"./fitb-i18n.en.js\";\nimport \"./fitb-i18n.pt-br.js\";\nimport \"../css/fitb.css\";\n\nexport var FITBList = {}; // Object containing all instances of FITB that aren't a child of a timed assessment.\n\n// FITB constructor\nexport default class FITB extends RunestoneBase {\n constructor(opts) {\n super(opts);\n var orig = opts.orig; // entire

element\n this.useRunestoneServices = opts.useRunestoneServices;\n this.origElem = orig;\n this.divid = orig.id;\n this.correct = null;\n // See comments in fitb.py for the format of ``feedbackArray`` (which is identical in both files).\n //\n // Find the script tag containing JSON and parse it. See `SO `_. If this parses to ``false``, then no feedback is available; server-side grading will be performed.\n this.feedbackArray = JSON.parse(\n this.scriptSelector(this.origElem).html()\n );\n this.createFITBElement();\n this.caption = \"Fill in the Blank\";\n this.addCaption(\"runestone\");\n this.checkServer(\"fillb\", true);\n }\n // Find the script tag containing JSON in a given root DOM node.\n scriptSelector(root_node) {\n return $(root_node).find(`script[type=\"application/json\"]`);\n }\n /*===========================================\n ==== Functions generating final HTML ====\n ===========================================*/\n createFITBElement() {\n this.renderFITBInput();\n this.renderFITBButtons();\n this.renderFITBFeedbackDiv();\n // replaces the intermediate HTML for this component with the rendered HTML of this component\n $(this.origElem).replaceWith(this.containerDiv);\n }\n renderFITBInput() {\n // The text [input] elements are created by the template.\n this.containerDiv = document.createElement(\"div\");\n this.containerDiv.id = this.divid;\n // Copy the original elements to the container holding what the user will see.\n $(this.origElem).children().clone().appendTo(this.containerDiv);\n // Remove the script tag.\n this.scriptSelector(this.containerDiv).remove();\n // Set the class for the text inputs, then store references to them.\n let ba = $(this.containerDiv).find(\":input\");\n ba.attr(\"class\", \"form form-control selectwidthauto\");\n ba.attr(\"aria-label\", \"input area\");\n this.blankArray = ba.toArray();\n // When a blank is changed mark this component as interacted with.\n // And set a class on the component in case we want to render components that have been used\n // differently\n for (let blank of this.blankArray) {\n $(blank).change(this.recordAnswered.bind(this));\n }\n }\n\n recordAnswered() {\n this.isAnswered = true;\n //let rcontainer = this.containerDiv.closest(\".runestone\");\n //rcontainer.addClass(\"answered\");\n }\n\n renderFITBButtons() {\n // \"submit\" button and \"compare me\" button\n this.submitButton = document.createElement(\"button\");\n this.submitButton.textContent = $.i18n(\"msg_fitb_check_me\");\n $(this.submitButton).attr({\n class: \"btn btn-success\",\n name: \"do answer\",\n type: \"button\",\n });\n this.submitButton.addEventListener(\n \"click\",\n function () {\n this.checkCurrentAnswer();\n this.logCurrentAnswer();\n }.bind(this),\n false\n );\n this.containerDiv.appendChild(document.createElement(\"br\"));\n this.containerDiv.appendChild(document.createElement(\"br\"));\n this.containerDiv.appendChild(this.submitButton);\n if (this.useRunestoneServices) {\n this.compareButton = document.createElement(\"button\");\n $(this.compareButton).attr({\n class: \"btn btn-default\",\n id: this.origElem.id + \"_bcomp\",\n disabled: \"\",\n name: \"compare\",\n });\n this.compareButton.textContent = $.i18n(\"msg_fitb_compare_me\");\n this.compareButton.addEventListener(\n \"click\",\n function () {\n this.compareFITBAnswers();\n }.bind(this),\n false\n );\n this.containerDiv.appendChild(this.compareButton);\n }\n this.containerDiv.appendChild(document.createElement(\"div\"));\n }\n renderFITBFeedbackDiv() {\n this.feedBackDiv = document.createElement(\"div\");\n this.feedBackDiv.id = this.divid + \"_feedback\";\n this.containerDiv.appendChild(document.createElement(\"br\"));\n this.containerDiv.appendChild(this.feedBackDiv);\n }\n /*===================================\n === Checking/loading from storage ===\n ===================================*/\n restoreAnswers(data) {\n var arr;\n // Restore answers from storage retrieval done in RunestoneBase.\n try {\n // The newer format encodes data as a JSON object.\n arr = JSON.parse(data.answer);\n // The result should be an array. If not, try comma parsing instead.\n if (!Array.isArray(arr)) {\n throw new Error();\n }\n } catch (err) {\n // The old format didn't.\n arr = data.answer.split(\",\");\n }\n for (var i = 0; i < this.blankArray.length; i++) {\n $(this.blankArray[i]).attr(\"value\", arr[i]);\n }\n // Use the feedback from the server, or recompute it locally.\n if (!this.feedbackArray) {\n this.displayFeed = data.displayFeed;\n this.correct = data.correct;\n this.isCorrectArray = data.isCorrectArray;\n // Only render if all the data is present; local storage might have old data missing some of these items.\n if (\n typeof this.displayFeed !== \"undefined\" &&\n typeof this.correct !== \"undefined\" &&\n typeof this.isCorrectArray !== \"undefined\"\n ) {\n this.renderFeedback();\n }\n } else {\n this.checkCurrentAnswer();\n }\n }\n checkLocalStorage() {\n // Loads previous answers from local storage if they exist\n var storedData;\n if (this.graderactive) {\n return;\n }\n var len = localStorage.length;\n if (len > 0) {\n var ex = localStorage.getItem(this.localStorageKey());\n if (ex !== null) {\n try {\n storedData = JSON.parse(ex);\n var arr = storedData.answer;\n } catch (err) {\n // error while parsing; likely due to bad value stored in storage\n console.log(err.message);\n localStorage.removeItem(this.localStorageKey());\n return;\n }\n this.restoreAnswers(storedData);\n }\n }\n }\n setLocalStorage(data) {\n let key = this.localStorageKey();\n localStorage.setItem(key, JSON.stringify(data));\n }\n\n checkCurrentAnswer() {\n // Start of the evaluation chain\n this.isCorrectArray = [];\n this.displayFeed = [];\n this.given_arr = [];\n for (var i = 0; i < this.blankArray.length; i++)\n this.given_arr.push(this.blankArray[i].value);\n if (this.useRunestoneServices) {\n if (eBookConfig.enableCompareMe) {\n this.enableCompareButton();\n }\n }\n // Grade locally if we can't ask the server to grade.\n if (this.feedbackArray) {\n this.evaluateAnswers();\n if (!this.isTimed) {\n this.renderFeedback();\n }\n }\n }\n\n async logCurrentAnswer(sid) {\n let answer = JSON.stringify(this.given_arr);\n // Save the answer locally.\n let feedback = true;\n this.setLocalStorage({\n answer: answer,\n timestamp: new Date(),\n });\n let data = {\n event: \"fillb\",\n act: answer || \"\",\n answer: answer || \"\",\n correct: this.correct ? \"T\" : \"F\",\n div_id: this.divid,\n };\n if (typeof sid !== \"undefined\") {\n data.sid = sid;\n feedback = false;\n }\n // Per `logBookEvent `, the result is undefined if there's no server. Otherwise, the server provides the endpoint-specific results in ``data.details``; see `make_json_response`.\n data = await this.logBookEvent(data);\n let detail = data && data.detail;\n if (!feedback) return;\n if (!this.feedbackArray) {\n // On success, update the feedback from the server's grade.\n this.setLocalStorage({\n answer: answer,\n timestamp: detail.timestamp,\n });\n this.correct = detail.correct;\n this.displayFeed = detail.displayFeed;\n this.isCorrectArray = detail.isCorrectArray;\n if (!this.isTimed) {\n this.renderFeedback();\n }\n }\n return detail;\n }\n\n /*==============================\n === Evaluation of answer and ===\n === display feedback ===\n ==============================*/\n // Inputs:\n //\n // - Strings entered by the student in ``this.blankArray[i].value``.\n // - Feedback in ``this.feedbackArray``.\n //\n // Outputs:\n //\n // - ``this.displayFeed`` is an array of HTML feedback.\n // - ``this.isCorrectArray`` is an array of true, false, or null (the question wasn't answered).\n // - ``this.correct`` is true, false, or null (the question wasn't answered).\n evaluateAnswers() {\n // Keep track if all answers are correct or not.\n this.correct = true;\n for (var i = 0; i < this.blankArray.length; i++) {\n var given = this.blankArray[i].value;\n // If this blank is empty, provide no feedback for it.\n if (given === \"\") {\n this.isCorrectArray.push(null);\n this.displayFeed.push($.i18n(\"msg_no_answer\"));\n this.correct = false;\n } else {\n // Look through all feedback for this blank. The last element in the array always matches. If no feedback for this blank exists, use an empty list.\n var fbl = this.feedbackArray[i] || [];\n for (var j = 0; j < fbl.length; j++) {\n // The last item of feedback always matches.\n if (j === fbl.length - 1) {\n this.displayFeed.push(fbl[j][\"feedback\"]);\n break;\n }\n // If this is a regexp...\n if (\"regex\" in fbl[j]) {\n var patt = RegExp(\n fbl[j][\"regex\"],\n fbl[j][\"regexFlags\"]\n );\n if (patt.test(given)) {\n this.displayFeed.push(fbl[j][\"feedback\"]);\n break;\n }\n } else {\n // This is a number.\n console.assert(\"number\" in fbl[j]);\n var [min, max] = fbl[j][\"number\"];\n // Convert the given string to a number. While there are `lots of ways `_ to do this; this version supports other bases (hex/binary/octal) as well as floats.\n var actual = +given;\n if (actual >= min && actual <= max) {\n this.displayFeed.push(fbl[j][\"feedback\"]);\n break;\n }\n }\n }\n // The answer is correct if it matched the first element in the array. A special case: if only one answer is provided, count it wrong; this is a misformed problem.\n let is_correct = j === 0 && fbl.length > 1;\n this.isCorrectArray.push(is_correct);\n if (!is_correct) {\n this.correct = false;\n }\n }\n }\n this.percent =\n this.isCorrectArray.filter(Boolean).length / this.blankArray.length;\n }\n\n renderFeedback() {\n if (this.correct) {\n $(this.feedBackDiv).attr(\"class\", \"alert alert-info\");\n for (let j = 0; j < this.blankArray.length; j++) {\n $(this.blankArray[j]).removeClass(\"input-validation-error\");\n }\n } else {\n if (this.displayFeed === null) {\n this.displayFeed = \"\";\n }\n for (let j = 0; j < this.blankArray.length; j++) {\n if (this.isCorrectArray[j] !== true) {\n $(this.blankArray[j]).addClass(\"input-validation-error\");\n } else {\n $(this.blankArray[j]).removeClass(\"input-validation-error\");\n }\n }\n $(this.feedBackDiv).attr(\"class\", \"alert alert-danger\");\n }\n var feedback_html = \"

\";\n // Remove the list if it's just one element.\n if (this.displayFeed.length == 1) {\n feedback_html = feedback_html.slice(\n \"\".length\n );\n }\n this.feedBackDiv.innerHTML = feedback_html;\n if (typeof MathJax !== \"undefined\") {\n this.queueMathJax(document.body);\n }\n }\n\n /*==================================\n === Functions for compare button ===\n ==================================*/\n enableCompareButton() {\n this.compareButton.disabled = false;\n }\n // _`compareFITBAnswers`\n compareFITBAnswers() {\n var data = {};\n data.div_id = this.divid;\n data.course = eBookConfig.course;\n jQuery.get(\n `${eBookConfig.new_server_prefix}/assessment/gettop10Answers`,\n data,\n this.compareFITB\n );\n }\n compareFITB(data, status, whatever) {\n var answers = data.detail.res;\n var misc = data.detail.miscdata;\n var body = \"\";\n body += \"\";\n for (var row in answers) {\n body +=\n \"\";\n }\n body += \"
AnswerCount
\" +\n answers[row].answer +\n \"\" +\n answers[row].count +\n \" times
\";\n var html =\n \"\";\n var el = $(html);\n el.modal();\n }\n\n disableInteraction() {\n for (var i = 0; i < this.blankArray.length; i++) {\n this.blankArray[i].disabled = true;\n }\n }\n}\n\n/*=================================\n== Find the custom HTML tags and ==\n== execute our code on them ==\n=================================*/\n$(document).on(\"runestone:login-complete\", function () {\n $(\"[data-component=fillintheblank]\").each(function (index) {\n var opts = {\n orig: this,\n useRunestoneServices: eBookConfig.useRunestoneServices,\n };\n if ($(this).closest(\"[data-component=timedAssessment]\").length == 0) {\n // If this element exists within a timed component, don't render it here\n try {\n FITBList[this.id] = new FITB(opts);\n } catch (err) {\n console.log(\n `Error rendering Fill in the Blank Problem ${this.id}\n Details: ${err}`\n );\n }\n }\n });\n});\n","import FITB from \"./fitb.js\";\nexport default class TimedFITB extends FITB {\n constructor(opts) {\n super(opts);\n this.renderTimedIcon(this.inputDiv);\n this.hideButtons();\n this.needsReinitialization = true;\n }\n hideButtons() {\n $(this.submitButton).hide();\n $(this.compareButton).hide();\n }\n renderTimedIcon(component) {\n // renders the clock icon on timed components. The component parameter\n // is the element that the icon should be appended to.\n var timeIconDiv = document.createElement(\"div\");\n var timeIcon = document.createElement(\"img\");\n $(timeIcon).attr({\n src: \"../_static/clock.png\",\n style: \"width:15px;height:15px\",\n });\n timeIconDiv.className = \"timeTip\";\n timeIconDiv.title = \"\";\n timeIconDiv.appendChild(timeIcon);\n $(component).prepend(timeIconDiv);\n }\n checkCorrectTimed() {\n // Returns if the question was correct, incorrect, or skipped (return null in the last case)\n switch (this.correct) {\n case true:\n return \"T\";\n case false:\n return \"F\";\n default:\n return null;\n }\n }\n hideFeedback() {\n for (var i = 0; i < this.blankArray.length; i++) {\n $(this.blankArray[i]).removeClass(\"input-validation-error\");\n }\n this.feedBackDiv.style.display = \"none\";\n }\n\n reinitializeListeners() {\n for (let blank of this.blankArray) {\n $(blank).change(this.recordAnswered.bind(this));\n }\n }\n}\n\nif (typeof window.component_factory === \"undefined\") {\n window.component_factory = {};\n}\nwindow.component_factory.fillintheblank = function (opts) {\n if (opts.timed) {\n return new TimedFITB(opts);\n }\n return new FITB(opts);\n};\n"],"names":["$","i18n","load","en","msg_no_answer","msg_fitb_check_me","msg_fitb_compare_me","FITBList","FITB","constructor","opts","super","orig","this","useRunestoneServices","origElem","divid","id","correct","feedbackArray","JSON","parse","scriptSelector","html","createFITBElement","caption","addCaption","checkServer","root_node","find","renderFITBInput","renderFITBButtons","renderFITBFeedbackDiv","replaceWith","containerDiv","document","createElement","children","clone","appendTo","remove","ba","attr","blankArray","toArray","blank","change","recordAnswered","bind","isAnswered","submitButton","textContent","class","name","type","addEventListener","checkCurrentAnswer","logCurrentAnswer","appendChild","compareButton","disabled","compareFITBAnswers","feedBackDiv","restoreAnswers","data","arr","answer","Array","isArray","Error","err","split","i","length","displayFeed","isCorrectArray","renderFeedback","checkLocalStorage","storedData","graderactive","localStorage","ex","getItem","localStorageKey","console","log","message","removeItem","setLocalStorage","key","setItem","stringify","given_arr","push","value","eBookConfig","enableCompareMe","enableCompareButton","evaluateAnswers","isTimed","async","sid","feedback","timestamp","Date","event","act","div_id","logBookEvent","detail","given","fbl","j","RegExp","test","assert","min","max","actual","is_correct","percent","filter","Boolean","removeClass","addClass","feedback_html","slice","innerHTML","MathJax","queueMathJax","body","course","jQuery","get","new_server_prefix","compareFITB","status","whatever","answers","res","miscdata","row","count","modal","disableInteraction","on","each","index","closest","TimedFITB","renderTimedIcon","inputDiv","hideButtons","needsReinitialization","hide","component","timeIconDiv","timeIcon","src","style","className","title","prepend","checkCorrectTimed","hideFeedback","display","reinitializeListeners","window","component_factory","fillintheblank","timed"],"sourceRoot":""}