diff --git a/amd/build/Item.min.js.map b/amd/build/Item.min.js.map
index 2e58ae3..03aeaa4 100644
--- a/amd/build/Item.min.js.map
+++ b/amd/build/Item.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"Item.min.js","sources":["../src/Item.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JavaScript code for the gapfill question type.\n *\n * @copyright 2017 Marcus Green\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\"jquery\"], function($) {\n /**\n *\n * @param {string} text\n * @param {string} delimitchars\n */\n return function Item(text, delimitchars) {\n this.questionid = $(\"input[name=id]\").val();\n this.settings = getSettings();\n this.gaptext = text;\n this.delimitchars = delimitchars;\n /* The l and r is for left and right */\n this.l = delimitchars.substr(0, 1);\n this.r = delimitchars.substr(1, 1);\n this.len = this.gaptext.length;\n this.startchar = this.gaptext.substring(0, 1);\n /* For checking if the end char is the right delimiter */\n this.endchar = this.gaptext.substring(this.len - 1, this.len);\n this.gaptextNodelim = \"\";\n this.feedback = {};\n this.instance = 0;\n this.feedback.correct = $(\"#id_corecteditable\").html();\n this.feedback.incorrect = $(\"#id_incorrecteditable\").html();\n Item.prototype.striptags = function(gaptext) {\n /* This is not a perfect way of stripping html but it may be good enough */\n if (gaptext === undefined) {\n return \"\";\n }\n var regex = /(<([^>]+)>)/gi;\n return gaptext.replace(regex, \"\");\n };\n /**\n * Pull data from hidden settings field on form\n * @returns {object} settings\n */\n function getSettings() {\n var settings = [];\n var settingsdata = $(\"[name='itemsettings']\").val();\n if (settingsdata > \"\") {\n var obj = JSON.parse(settingsdata);\n for (var o in obj) {\n settings.push(obj[o]);\n }\n }\n return settings;\n }\n this.stripdelim = function() {\n if (this.startchar === this.l) {\n this.gaptextNodelim = this.gaptext.substring(1, this.len);\n }\n if (this.endchar === this.r) {\n var len = this.gaptextNodelim.length;\n this.gaptextNodelim = this.gaptextNodelim.substring(0, len - 1);\n }\n return this.gaptextNodelim;\n };\n var itemsettings = [];\n Item.prototype.getItemSettings = function(target) {\n var itemid = target.id;\n var underscore = itemid.indexOf(\"_\");\n /* The instance, normally 0 but incremented if a gap has the same text as another\n * instance is not currently used*/\n this.instance = itemid.substr(underscore + 1);\n for (var set in this.settings) {\n text = this.stripdelim();\n if (this.settings[set].gaptext === text) {\n itemsettings = this.settings[set];\n }\n }\n return itemsettings;\n };\n this.updateJson = function(e) {\n var found = false;\n var id = e.target.id;\n for (var set in this.settings) {\n if (this.settings[set].gaptext === this.stripdelim()) {\n this.settings[set].correctfeedback = $(\n \"#id_correcteditable\"\n )[0].innerHTML;\n this.settings[set].incorrectfeedback = $(\n \"#id_incorrecteditable\"\n )[0].innerHTML;\n found = true;\n }\n }\n if (found === false) {\n /* If there is no record for this word add one */\n var itemsettings = {\n itemid: id,\n questionid: $(\"input[name=id]\").val(),\n correctfeedback: $(\"#id_correcteditable\").html(),\n incorrectfeedback: $(\"#id_incorrecteditable\").html(),\n gaptext: this.stripdelim()\n };\n this.settings.push(itemsettings);\n }\n return JSON.stringify(this.settings);\n };\n };\n});\n"],"names":["define","$","Item","text","delimitchars","this","questionid","val","settings","settingsdata","obj","JSON","parse","o","push","getSettings","gaptext","l","substr","r","len","length","startchar","substring","endchar","gaptextNodelim","feedback","instance","correct","html","incorrect","prototype","striptags","undefined","replace","stripdelim","itemsettings","getItemSettings","target","itemid","id","underscore","indexOf","set","updateJson","e","found","correctfeedback","innerHTML","incorrectfeedback","stringify"],"mappings":";;;;;;AAqBAA,4BAAO,CAAC,WAAW,SAASC,GAM1B,OAAO,SAASC,KAAKC,KAAMC,cACzBC,KAAKC,WAAaL,EAAE,kBAAkBM,MACtCF,KAAKG,SA2BL,WACE,IAAIA,SAAW,GACXC,aAAeR,EAAE,yBAAyBM,MAC9C,GAAIE,aAAe,GAAI,CACrB,IAAIC,IAAMC,KAAKC,MAAMH,cACrB,IAAK,IAAII,KAAKH,IACZF,SAASM,KAAKJ,IAAIG,IAGtB,OAAOL,SApCOO,GAChBV,KAAKW,QAAUb,KACfE,KAAKD,aAAeA,aAEpBC,KAAKY,EAAIb,aAAac,OAAO,EAAG,GAChCb,KAAKc,EAAIf,aAAac,OAAO,EAAG,GAChCb,KAAKe,IAAMf,KAAKW,QAAQK,OACxBhB,KAAKiB,UAAYjB,KAAKW,QAAQO,UAAU,EAAG,GAE3ClB,KAAKmB,QAAUnB,KAAKW,QAAQO,UAAUlB,KAAKe,IAAM,EAAGf,KAAKe,KACzDf,KAAKoB,eAAiB,GACtBpB,KAAKqB,SAAW,GAChBrB,KAAKsB,SAAW,EAChBtB,KAAKqB,SAASE,QAAU3B,EAAE,sBAAsB4B,OAChDxB,KAAKqB,SAASI,UAAY7B,EAAE,yBAAyB4B,OACrD3B,KAAK6B,UAAUC,UAAY,SAAShB,SAElC,QAAgBiB,IAAZjB,QACF,MAAO,GAGT,OAAOA,QAAQkB,QADH,gBACkB,KAiBhC7B,KAAK8B,WAAa,WAIhB,GAHI9B,KAAKiB,YAAcjB,KAAKY,IAC1BZ,KAAKoB,eAAiBpB,KAAKW,QAAQO,UAAU,EAAGlB,KAAKe,MAEnDf,KAAKmB,UAAYnB,KAAKc,EAAG,CAC3B,IAAIC,IAAMf,KAAKoB,eAAeJ,OAC9BhB,KAAKoB,eAAiBpB,KAAKoB,eAAeF,UAAU,EAAGH,IAAM,GAE/D,OAAOf,KAAKoB,gBAEd,IAAIW,aAAe,GACnBlC,KAAK6B,UAAUM,gBAAkB,SAASC,QACxC,IAAIC,OAASD,OAAOE,GAChBC,WAAaF,OAAOG,QAAQ,KAIhC,IAAK,IAAIC,OADTtC,KAAKsB,SAAWY,OAAOrB,OAAOuB,WAAa,GAC3BpC,KAAKG,SACnBL,KAAOE,KAAK8B,aACR9B,KAAKG,SAASmC,KAAK3B,UAAYb,OACjCiC,aAAe/B,KAAKG,SAASmC,MAGjC,OAAOP,cAET/B,KAAKuC,WAAa,SAASC,GACzB,IAAIC,OAAQ,EACRN,GAAKK,EAAEP,OAAOE,GAClB,IAAK,IAAIG,OAAOtC,KAAKG,SACfH,KAAKG,SAASmC,KAAK3B,UAAYX,KAAK8B,eACtC9B,KAAKG,SAASmC,KAAKI,gBAAkB9C,EACnC,uBACA,GAAG+C,UACL3C,KAAKG,SAASmC,KAAKM,kBAAoBhD,EACrC,yBACA,GAAG+C,UACLF,OAAQ,GAGZ,IAAc,IAAVA,MAAiB,CAEnB,IAAIV,aAAe,CACjBG,OAAQC,GACRlC,WAAYL,EAAE,kBAAkBM,MAChCwC,gBAAiB9C,EAAE,uBAAuB4B,OAC1CoB,kBAAmBhD,EAAE,yBAAyB4B,OAC9Cb,QAASX,KAAK8B,cAEhB9B,KAAKG,SAASM,KAAKsB,cAErB,OAAOzB,KAAKuC,UAAU7C,KAAKG"}
\ No newline at end of file
+{"version":3,"file":"Item.min.js","sources":["../src/Item.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JavaScript code for the gapfill question type.\n *\n * @copyright 2017 Marcus Green\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\"jquery\"], function($) {\n /**\n *\n * @param {string} text\n * @param {string} delimitchars\n */\n return function Item(text, delimitchars) {\n this.questionid = $(\"input[name=id]\").val();\n this.settings = getSettings();\n this.gaptext = text;\n this.delimitchars = delimitchars;\n /* The l and r is for left and right */\n this.l = delimitchars.substr(0, 1);\n this.r = delimitchars.substr(1, 1);\n this.len = this.gaptext.length;\n this.startchar = this.gaptext.substring(0, 1);\n /* For checking if the end char is the right delimiter */\n this.endchar = this.gaptext.substring(this.len - 1, this.len);\n this.gaptextNodelim = \"\";\n this.feedback = {};\n this.instance = 0;\n this.feedback.correct = $(\"#id_corecteditable\").html();\n this.feedback.incorrect = $(\"#id_incorrecteditable\").html();\n Item.prototype.striptags = function(gaptext) {\n /* This is not a perfect way of stripping html but it may be good enough */\n if (gaptext === undefined) {\n return \"\";\n }\n var regex = /(<([^>]+)>)/gi;\n return gaptext.replace(regex, \"\");\n };\n /**\n * Pull data from hidden settings field on form\n * @returns {object} settings\n */\n function getSettings() {\n var settings = [];\n var settingsdata = $(\"[name='itemsettings']\").val();\n if (settingsdata > \"\") {\n var obj = JSON.parse(settingsdata);\n for (var o in obj) {\n settings.push(obj[o]);\n }\n }\n return settings;\n }\n this.stripdelim = function() {\n if (this.startchar === this.l) {\n this.gaptextNodelim = this.gaptext.substring(1, this.len);\n }\n if (this.endchar === this.r) {\n var len = this.gaptextNodelim.length;\n this.gaptextNodelim = this.gaptextNodelim.substring(0, len - 1);\n }\n return this.gaptextNodelim;\n };\n var itemsettings = [];\n Item.prototype.getItemSettings = function(target) {\n var itemid = target.id;\n var underscore = itemid.indexOf(\"_\");\n /* The instance, normally 0 but incremented if a gap has the same text as another\n * instance is not currently used*/\n this.instance = itemid.substr(underscore + 1);\n for (var set in this.settings) {\n text = this.stripdelim();\n if (this.settings[set].gaptext === text) {\n itemsettings = this.settings[set];\n }\n }\n return itemsettings;\n };\n this.updateJson = function(e) {\n var found = false;\n var id = e.target.id;\n for (var set in this.settings) {\n if (this.settings[set].gaptext === this.stripdelim()) {\n this.settings[set].correctfeedback = $(\n \"#id_correcteditable\"\n )[0].innerHTML;\n this.settings[set].incorrectfeedback = $(\n \"#id_incorrecteditable\"\n )[0].innerHTML;\n found = true;\n }\n }\n if (found === false) {\n /* If there is no record for this word add one */\n var itemsettings = {\n itemid: id,\n questionid: $(\"input[name=id]\").val(),\n correctfeedback: $(\"#id_correcteditable\").html(),\n incorrectfeedback: $(\"#id_incorrecteditable\").html(),\n gaptext: this.stripdelim()\n };\n this.settings.push(itemsettings);\n }\n return JSON.stringify(this.settings);\n };\n };\n});\n"],"names":["define","$","Item","text","delimitchars","questionid","val","settings","settingsdata","obj","JSON","parse","o","push","getSettings","gaptext","l","substr","r","len","this","length","startchar","substring","endchar","gaptextNodelim","feedback","instance","correct","html","incorrect","prototype","striptags","undefined","replace","stripdelim","itemsettings","getItemSettings","target","itemid","id","underscore","indexOf","set","updateJson","e","found","correctfeedback","innerHTML","incorrectfeedback","stringify"],"mappings":";;;;;;AAqBAA,4BAAO,CAAC,WAAW,SAASC,UAMnB,SAASC,KAAKC,KAAMC,mBACpBC,WAAaJ,EAAE,kBAAkBK,WACjCC,wBA4BCA,SAAW,GACXC,aAAeP,EAAE,yBAAyBK,SAC1CE,aAAe,GAAI,KACjBC,IAAMC,KAAKC,MAAMH,kBAChB,IAAII,KAAKH,IACZF,SAASM,KAAKJ,IAAIG,WAGfL,SApCOO,QACXC,QAAUZ,UACVC,aAAeA,kBAEfY,EAAIZ,aAAaa,OAAO,EAAG,QAC3BC,EAAId,aAAaa,OAAO,EAAG,QAC3BE,IAAMC,KAAKL,QAAQM,YACnBC,UAAYF,KAAKL,QAAQQ,UAAU,EAAG,QAEtCC,QAAUJ,KAAKL,QAAQQ,UAAUH,KAAKD,IAAM,EAAGC,KAAKD,UACpDM,eAAiB,QACjBC,SAAW,QACXC,SAAW,OACXD,SAASE,QAAU3B,EAAE,sBAAsB4B,YAC3CH,SAASI,UAAY7B,EAAE,yBAAyB4B,OACrD3B,KAAK6B,UAAUC,UAAY,SAASjB,iBAElBkB,IAAZlB,cACK,UAGFA,QAAQmB,QADH,gBACkB,UAiB3BC,WAAa,cACZf,KAAKE,YAAcF,KAAKJ,SACrBS,eAAiBL,KAAKL,QAAQQ,UAAU,EAAGH,KAAKD,MAEnDC,KAAKI,UAAYJ,KAAKF,EAAG,KACvBC,IAAMC,KAAKK,eAAeJ,YACzBI,eAAiBL,KAAKK,eAAeF,UAAU,EAAGJ,IAAM,UAExDC,KAAKK,oBAEVW,aAAe,GACnBlC,KAAK6B,UAAUM,gBAAkB,SAASC,YACpCC,OAASD,OAAOE,GAChBC,WAAaF,OAAOG,QAAQ,SAI3B,IAAIC,YADJhB,SAAWY,OAAOtB,OAAOwB,WAAa,GAC3BrB,KAAKb,SACnBJ,KAAOiB,KAAKe,aACRf,KAAKb,SAASoC,KAAK5B,UAAYZ,OACjCiC,aAAehB,KAAKb,SAASoC,aAG1BP,mBAEJQ,WAAa,SAASC,OACrBC,OAAQ,EACRN,GAAKK,EAAEP,OAAOE,OACb,IAAIG,OAAOvB,KAAKb,SACfa,KAAKb,SAASoC,KAAK5B,UAAYK,KAAKe,oBACjC5B,SAASoC,KAAKI,gBAAkB9C,EACnC,uBACA,GAAG+C,eACAzC,SAASoC,KAAKM,kBAAoBhD,EACrC,yBACA,GAAG+C,UACLF,OAAQ,OAGE,IAAVA,MAAiB,KAEfV,aAAe,CACjBG,OAAQC,GACRnC,WAAYJ,EAAE,kBAAkBK,MAChCyC,gBAAiB9C,EAAE,uBAAuB4B,OAC1CoB,kBAAmBhD,EAAE,yBAAyB4B,OAC9Cd,QAASK,KAAKe,mBAEX5B,SAASM,KAAKuB,qBAEd1B,KAAKwC,UAAU9B,KAAKb,WAGhC"}
\ No newline at end of file
diff --git a/amd/build/dragdrop.min.js b/amd/build/dragdrop.min.js
index f7e70e2..16a0b6b 100644
--- a/amd/build/dragdrop.min.js
+++ b/amd/build/dragdrop.min.js
@@ -1,3 +1,3 @@
-define("qtype_gapfill/dragdrop",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;_exports.init=function(singleuse){Window.singleuse=singleuse;var draggables=document.querySelectorAll('span[class*="draggable"]');function dragShow(that){var targetVal=that.value;draggables.forEach((function(e){e.innerText.trim()===targetVal.trim()&&(e.classList.remove("hide"),that.value="")}))}function drop(e){dragShow(this),e.target.value=e.dataTransfer.getData("text/plain");var sourceId=e.dataTransfer.getData("sourceId"),sourceEl=document.getElementById(sourceId);Window.singleuse&&(sourceEl.classList.add("hide"),e.preventDefault()),e.preventDefault()}function dragStart(e){e.dataTransfer.setData("text/plain",e.target.innerText),e.dataTransfer.setData("sourceId",this.id)}draggables.forEach((function(e){e.addEventListener("dragstart",dragStart)})),document.querySelectorAll('input[class*="droptarget"]').forEach((function(e){e.addEventListener("dblclick",(function(){Window.singleuse&&dragShow(this),this.value=""})),e.addEventListener("drop",drop)})),document.addEventListener("dragover",(function(e){e.preventDefault()}))}}));
+define("qtype_gapfill/dragdrop",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;_exports.init=singleuse=>{Window.singleuse=singleuse;var draggables=document.querySelectorAll('span[class*="draggable"]');function dragShow(that){var targetVal=that.value;draggables.forEach((function(e){e.innerText.trim()===targetVal.trim()&&(e.classList.remove("hide"),that.value="")}))}function drop(e){dragShow(this),e.target.value=e.dataTransfer.getData("text/plain");var sourceId=e.dataTransfer.getData("sourceId"),sourceEl=document.getElementById(sourceId);Window.singleuse&&(sourceEl.classList.add("hide"),e.preventDefault()),e.preventDefault()}function dragStart(e){e.dataTransfer.setData("text/plain",e.target.innerText),e.dataTransfer.setData("sourceId",this.id),e.dataTransfer.effectAllowed="move",e.dataTransfer.dropEffect="move"}draggables.forEach((function(e){e.addEventListener("dragstart",dragStart)})),document.querySelectorAll('input[class*="droptarget"]').forEach((function(e){e.addEventListener("dblclick",(function(){Window.singleuse&&dragShow(this),this.value=""})),e.addEventListener("drop",drop)})),document.addEventListener("dragover",(function(e){e.preventDefault()}))}}));
//# sourceMappingURL=dragdrop.min.js.map
\ No newline at end of file
diff --git a/amd/build/dragdrop.min.js.map b/amd/build/dragdrop.min.js.map
index e43414d..4c9eda2 100644
--- a/amd/build/dragdrop.min.js.map
+++ b/amd/build/dragdrop.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"dragdrop.min.js","sources":["../src/dragdrop.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JavaScript code for the gapfill question type.\n *\n * @copyright 2020 Marcus Green\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const init = (singleuse) => {\n Window.singleuse = singleuse;\n var draggables = document.querySelectorAll('span[class*=\"draggable\"]');\n draggables.forEach(function(e) {\n e.addEventListener('dragstart', dragStart);\n });\n document.querySelectorAll('input[class*=\"droptarget\"]').forEach(function(e) {\n e.addEventListener(\"dblclick\", function() {\n if (Window.singleuse) {\n dragShow(this);\n }\n this.value = \"\";\n });\n\n e.addEventListener(\"drop\", drop);\n\n });\n /**\n *\n * @param {*} that\n */\n function dragShow(that) {\n var targetVal = that.value;\n draggables.forEach(function(e) {\n if (e.innerText.trim() === targetVal.trim()) {\n e.classList.remove(\"hide\");\n that.value = \"\";\n }\n });\n }\n\n /**\n * Stops strange things happening on ios drop event\n * @param {*} e\n */\n document.addEventListener('dragover', function(e) {\n e.preventDefault();\n });\n\n\n /**\n *\n * @param {*} e\n */\n function drop(e) {\n dragShow(this);\n e.target.value = e.dataTransfer.getData('text/plain');\n var sourceId = e.dataTransfer.getData(\"sourceId\");\n var sourceEl = document.getElementById(sourceId);\n if (Window.singleuse) {\n sourceEl.classList.add('hide');\n e.preventDefault();\n }\n e.preventDefault();\n }\n /**\n *\n * @param {*} e\n */\n function dragStart(e) {\n e.dataTransfer.setData('text/plain', e.target.innerText);\n e.dataTransfer.setData('sourceId', this.id);\n }\n};\n\n"],"names":["singleuse","Window","draggables","document","querySelectorAll","dragShow","that","targetVal","value","forEach","e","innerText","trim","classList","remove","drop","this","target","dataTransfer","getData","sourceId","sourceEl","getElementById","add","preventDefault","dragStart","setData","id","addEventListener"],"mappings":"2JAsBoB,SAACA,WACnBC,OAAOD,UAAYA,UACnB,IAAIE,WAAaC,SAASC,iBAAiB,4BAmB3C,SAASC,SAASC,MAChB,IAAIC,UAAYD,KAAKE,MACrBN,WAAWO,SAAQ,SAASC,GACtBA,EAAEC,UAAUC,SAAWL,UAAUK,SACnCF,EAAEG,UAAUC,OAAO,QACnBR,KAAKE,MAAQ,OAkBnB,SAASO,KAAKL,GACZL,SAASW,MACTN,EAAEO,OAAOT,MAAQE,EAAEQ,aAAaC,QAAQ,cACxC,IAAIC,SAAWV,EAAEQ,aAAaC,QAAQ,YAClCE,SAAWlB,SAASmB,eAAeF,UACnCnB,OAAOD,YACTqB,SAASR,UAAUU,IAAI,QACvBb,EAAEc,kBAEJd,EAAEc,iBAMJ,SAASC,UAAUf,GACjBA,EAAEQ,aAAaQ,QAAQ,aAAchB,EAAEO,OAAON,WAC9CD,EAAEQ,aAAaQ,QAAQ,WAAYV,KAAKW,IA1D1CzB,WAAWO,SAAQ,SAASC,GAC1BA,EAAEkB,iBAAiB,YAAaH,cAElCtB,SAASC,iBAAiB,8BAA8BK,SAAQ,SAASC,GACvEA,EAAEkB,iBAAiB,YAAY,WACzB3B,OAAOD,WACTK,SAASW,MAEXA,KAAKR,MAAQ,MAGfE,EAAEkB,iBAAiB,OAAQb,SAqB7BZ,SAASyB,iBAAiB,YAAY,SAASlB,GAC7CA,EAAEc"}
\ No newline at end of file
+{"version":3,"file":"dragdrop.min.js","sources":["../src/dragdrop.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JavaScript code for the gapfill question type.\n *\n * @copyright 2020 Marcus Green\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const init = (singleuse) => {\n Window.singleuse = singleuse;\n var draggables = document.querySelectorAll('span[class*=\"draggable\"]');\n draggables.forEach(function(e) {\n e.addEventListener('dragstart', dragStart);\n });\n document.querySelectorAll('input[class*=\"droptarget\"]').forEach(function(e) {\n e.addEventListener(\"dblclick\", function() {\n if (Window.singleuse) {\n dragShow(this);\n }\n this.value = \"\";\n });\n\n e.addEventListener(\"drop\", drop);\n\n });\n /**\n *\n * @param {*} that\n */\n function dragShow(that) {\n var targetVal = that.value;\n draggables.forEach(function(e) {\n if (e.innerText.trim() === targetVal.trim()) {\n e.classList.remove(\"hide\");\n that.value = \"\";\n }\n });\n }\n\n /**\n * Stops strange things happening on ios drop event\n * @param {*} e\n */\n document.addEventListener('dragover', function(e) {\n e.preventDefault();\n });\n\n\n /**\n *\n * @param {*} e\n */\n function drop(e) {\n dragShow(this);\n e.target.value = e.dataTransfer.getData('text/plain');\n var sourceId = e.dataTransfer.getData(\"sourceId\");\n var sourceEl = document.getElementById(sourceId);\n if (Window.singleuse) {\n sourceEl.classList.add('hide');\n e.preventDefault();\n }\n e.preventDefault();\n }\n /**\n *\n * @param {*} e\n */\n function dragStart(e) {\n e.dataTransfer.setData('text/plain', e.target.innerText);\n e.dataTransfer.setData('sourceId', this.id);\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.dropEffect = \"move\";\n }\n};\n\n"],"names":["singleuse","Window","draggables","document","querySelectorAll","dragShow","that","targetVal","value","forEach","e","innerText","trim","classList","remove","drop","this","target","dataTransfer","getData","sourceId","sourceEl","getElementById","add","preventDefault","dragStart","setData","id","effectAllowed","dropEffect","addEventListener"],"mappings":"2JAsBqBA,YACnBC,OAAOD,UAAYA,cACfE,WAAaC,SAASC,iBAAiB,qCAmBlCC,SAASC,UACZC,UAAYD,KAAKE,MACrBN,WAAWO,SAAQ,SAASC,GACtBA,EAAEC,UAAUC,SAAWL,UAAUK,SACnCF,EAAEG,UAAUC,OAAO,QACnBR,KAAKE,MAAQ,gBAkBVO,KAAKL,GACZL,SAASW,MACTN,EAAEO,OAAOT,MAAQE,EAAEQ,aAAaC,QAAQ,kBACpCC,SAAWV,EAAEQ,aAAaC,QAAQ,YAClCE,SAAWlB,SAASmB,eAAeF,UACnCnB,OAAOD,YACTqB,SAASR,UAAUU,IAAI,QACvBb,EAAEc,kBAEJd,EAAEc,0BAMMC,UAAUf,GAClBA,EAAEQ,aAAaQ,QAAQ,aAAchB,EAAEO,OAAON,WAC9CD,EAAEQ,aAAaQ,QAAQ,WAAYV,KAAKW,IACxCjB,EAAEQ,aAAaU,cAAgB,OAC/BlB,EAAEQ,aAAaW,WAAa,OA5D9B3B,WAAWO,SAAQ,SAASC,GAC1BA,EAAEoB,iBAAiB,YAAaL,cAElCtB,SAASC,iBAAiB,8BAA8BK,SAAQ,SAASC,GACvEA,EAAEoB,iBAAiB,YAAY,WACzB7B,OAAOD,WACTK,SAASW,WAENR,MAAQ,MAGfE,EAAEoB,iBAAiB,OAAQf,SAqB7BZ,SAAS2B,iBAAiB,YAAY,SAASpB,GAC7CA,EAAEc"}
\ No newline at end of file
diff --git a/amd/build/jquery.ui.touch-punch-improved.min.js.map b/amd/build/jquery.ui.touch-punch-improved.min.js.map
index b63a609..f0cca99 100644
--- a/amd/build/jquery.ui.touch-punch-improved.min.js.map
+++ b/amd/build/jquery.ui.touch-punch-improved.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"jquery.ui.touch-punch-improved.min.js","sources":["../src/jquery.ui.touch-punch-improved.js"],"sourcesContent":["/*\n * JQuery UI Touch Punch Improved 0.3.1\n *\n *\n * Copyright 2013, Chris Hutchinson \n * Original jquery-ui-touch-punch Copyright 2011, Dave Furfero\n * Dual licensed under the MIT or GPL Version 2 licenses.\n *\n * Depends:\n * jquery.ui.widget.js\n * jquery.ui.mouse.js\n */\n(function(factory) {\n if (typeof define === \"function\" && define.amd) {\n\n // AMD. Register as an anonymous module.\n define([\"jquery\", \"jqueryui\"], factory);\n } else {\n\n // Browser globals.\n factory(window.jQuery);\n }\n}(function($) {\n var pointerEnabled = window.navigator.pointerEnabled\n || window.navigator.msPointerEnabled;\n\n // Detect touch support.\n $.support.touch = 'ontouchend' in document || pointerEnabled;\n\n // Ignore browsers without touch support or mouse support.\n if (!$.support.touch || !$.ui.mouse) {\n return;\n }\n\n var mouseProto = $.ui.mouse.prototype,\n _mouseInit = mouseProto._mouseInit,\n touchHandled;\n\n /**\n * See http://stackoverflow.com/a/12714084/220825.\n * @param {*} touch\n * @returns {object}\n */\n function fixTouch(touch) {\n var winPageX = window.pageXOffset,\n winPageY = window.pageYOffset,\n x = touch.clientX,\n y = touch.clientY;\n\n if (touch.pageY === 0 && Math.floor(y) > Math.floor(touch.pageY)\n || touch.pageX === 0 && Math.floor(x) > Math.floor(touch.pageX)) {\n // ...iOS4 clientX/clientY have the value that should have been.\n // ...in pageX/pageY. While pageX/page/ have the value 0.\n x = x - winPageX;\n y = y - winPageY;\n } else if (y < (touch.pageY - winPageY) || x < (touch.pageX - winPageX)) {\n // Some Android browsers have totally bogus values for clientX/Y.\n // when scrolling/zooming a page. Detectable since clientX/clientY.\n // should never be smaller than pageX/pageY minus page scroll.\n x = touch.pageX - winPageX;\n y = touch.pageY - winPageY;\n }\n\n return {\n clientX: x,\n clientY: y\n };\n }\n\n /**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} event A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\n function simulateMouseEvent(event, simulatedType) {\n // Ignore multi-touch events.\n if ((!pointerEnabled && event.originalEvent.touches.length > 1) || (pointerEnabled && !event.isPrimary)) {\n return;\n }\n\n var touch = pointerEnabled ? event.originalEvent : event.originalEvent.changedTouches[0],\n simulatedEvent = document.createEvent('MouseEvents'),\n coord = fixTouch(touch);\n\n // Check if element is an input or a textarea.\n if ($(touch.target).is(\"input\") || $(touch.target).is(\"textarea\")) {\n event.stopPropagation();\n } else {\n event.preventDefault();\n }\n\n // Initialize the simulated mouse event using the touch event's coordinates.\n simulatedEvent.initMouseEvent(\n simulatedType, // ...type.\n true, // ...bubbles.\n true, // ...cancelable.\n window, // ...view.\n 1, // ...detail\n event.screenX || touch.screenX, // ...screenX.\n event.screenY || touch.screenY, // ...screenY.\n event.clientX || coord.clientX, // ...clientX.\n event.clientY || coord.clientY, // ...clientY.\n false, // ...ctrlKey.\n false, // ...altKey.\n false, // ...shiftKey.\n false, // ...metaKey.\n 0, // ...button.\n null // ...relatedTarget.\n );\n\n // Dispatch the simulated event to the target element.\n event.target.dispatchEvent(simulatedEvent);\n }\n\n /**\n * Handle the jQuery UI widget's touchstart events\n * @param {Object} event The widget element's touchstart event\n */\n mouseProto._touchStart = function(event) {\n var self = this;\n\n // Ignore the event if another widget is already being handled.\n if (touchHandled || (!pointerEnabled && !self._mouseCapture(event.originalEvent.changedTouches[0]))) {\n return;\n }\n\n // Set the flag to prevent other widgets from inheriting the touch event.\n touchHandled = true;\n\n // Track movement to determine if interaction was a click.\n self._touchMoved = false;\n\n // Simulate the mouseover event.\n simulateMouseEvent(event, 'mouseover');\n\n // Simulate the mousemove event.\n simulateMouseEvent(event, 'mousemove');\n\n // Simulate the mousedown event.\n simulateMouseEvent(event, 'mousedown');\n };\n\n /**\n * Handle the jQuery UI widget's touchmove events\n * @param {Object} event The document's touchmove event\n */\n mouseProto._touchMove = function(event) {\n // Ignore event if not handled.\n if (!touchHandled) {\n return;\n }\n\n // Interaction was not a click.\n this._touchMoved = true;\n\n // Simulate the mousemove event.\n simulateMouseEvent(event, 'mousemove');\n };\n\n /**\n * Handle the jQuery UI widget's touchend events\n * @param {Object} event The document's touchend event\n */\n mouseProto._touchEnd = function(event) {\n // Ignore event if not handled.\n if (!touchHandled) {\n return;\n }\n\n // Simulate the mouseup event.\n simulateMouseEvent(event, 'mouseup');\n\n // Simulate the mouseout event.\n simulateMouseEvent(event, 'mouseout');\n\n // If the touch interaction did not move, it should trigger a click.\n if (!this._touchMoved) {\n // Simulate the click event.\n simulateMouseEvent(event, 'click');\n }\n\n // Unset the flag to allow other widgets to inherit the touch event.\n touchHandled = false;\n };\n\n /**\n * A duck punch of the $.ui.mouse _mouseInit method to support touch events.\n * This method extends the widget with bound touch event handlers that\n * translate touch events to mouse events and pass them to the widget's\n * original mouse event handling methods.\n */\n mouseProto._mouseInit = function() {\n var self = this;\n\n self.element.on({\n 'touchstart': $.proxy(self, '_touchStart'),\n 'touchmove': $.proxy(self, '_touchMove'),\n 'touchend': $.proxy(self, '_touchEnd'),\n 'pointerDown': $.proxy(self, '_touchStart'),\n 'pointerMove': $.proxy(self, '_touchMove'),\n 'pointerUp': $.proxy(self, '_touchEnd'),\n 'MSPointerDown': $.proxy(self, '_touchStart'),\n 'MSPointerMove': $.proxy(self, '_touchMove'),\n 'MSPointerUp': $.proxy(self, '_touchEnd')\n });\n\n // Call the original $.ui.mouse init method.\n _mouseInit.call(self);\n };\n\n}));"],"names":["factory","$","pointerEnabled","window","navigator","msPointerEnabled","support","touch","document","ui","mouse","touchHandled","mouseProto","prototype","_mouseInit","_touchStart","event","this","_mouseCapture","originalEvent","changedTouches","_touchMoved","simulateMouseEvent","_touchMove","_touchEnd","element","on","touchstart","proxy","touchmove","touchend","pointerDown","pointerMove","pointerUp","MSPointerDown","MSPointerMove","MSPointerUp","call","simulatedType","touches","length","isPrimary","simulatedEvent","createEvent","coord","winPageX","pageXOffset","winPageY","pageYOffset","x","clientX","y","clientY","pageY","Math","floor","pageX","fixTouch","target","is","stopPropagation","preventDefault","initMouseEvent","screenX","screenY","dispatchEvent","define","amd","jQuery"],"mappings":"AAYC,IAASA,gBAUR,SAASC,GACP,IAAIC,eAAiBC,OAAOC,UAAUF,gBAC/BC,OAAOC,UAAUC,iBAMxB,GAHAJ,EAAEK,QAAQC,MAAQ,eAAgBC,UAAYN,eAGzCD,EAAEK,QAAQC,OAAUN,EAAEQ,GAAGC,MAA9B,CAIA,IAEIC,aAFAC,WAAaX,EAAEQ,GAAGC,MAAMG,UACxBC,WAAaF,WAAWE,WAmF5BF,WAAWG,YAAc,SAASC,OAI1BL,eAAkBT,iBAHXe,KAGmCC,cAAcF,MAAMG,cAAcC,eAAe,MAK/FT,cAAe,EARJM,KAWNI,aAAc,EAGnBC,mBAAmBN,MAAO,aAG1BM,mBAAmBN,MAAO,aAG1BM,mBAAmBN,MAAO,eAO9BJ,WAAWW,WAAa,SAASP,OAExBL,eAKLM,KAAKI,aAAc,EAGnBC,mBAAmBN,MAAO,eAO9BJ,WAAWY,UAAY,SAASR,OAEvBL,eAKLW,mBAAmBN,MAAO,WAG1BM,mBAAmBN,MAAO,YAGrBC,KAAKI,aAENC,mBAAmBN,MAAO,SAI9BL,cAAe,IASnBC,WAAWE,WAAa,WACTG,KAENQ,QAAQC,GAAG,CACZC,WAAc1B,EAAE2B,MAHTX,KAGqB,eAC5BY,UAAa5B,EAAE2B,MAJRX,KAIoB,cAC3Ba,SAAY7B,EAAE2B,MALPX,KAKmB,aAC1Bc,YAAe9B,EAAE2B,MANVX,KAMsB,eAC7Be,YAAe/B,EAAE2B,MAPVX,KAOsB,cAC7BgB,UAAahC,EAAE2B,MARRX,KAQoB,aAC3BiB,cAAiBjC,EAAE2B,MATZX,KASwB,eAC/BkB,cAAiBlC,EAAE2B,MAVZX,KAUwB,cAC/BmB,YAAenC,EAAE2B,MAXVX,KAWsB,eAIjCH,WAAWuB,KAfApB,OAtHf,SAASK,mBAAmBN,MAAOsB,eAE/B,MAAMpC,gBAAkBc,MAAMG,cAAcoB,QAAQC,OAAS,GAAOtC,iBAAmBc,MAAMyB,WAA7F,CAIA,IAAIlC,MAAQL,eAAiBc,MAAMG,cAAgBH,MAAMG,cAAcC,eAAe,GAClFsB,eAAiBlC,SAASmC,YAAY,eACtCC,MAvCR,SAAkBrC,OACd,IAAIsC,SAAW1C,OAAO2C,YAClBC,SAAW5C,OAAO6C,YAClBC,EAAI1C,MAAM2C,QACVC,EAAI5C,MAAM6C,QAgBd,OAdoB,IAAhB7C,MAAM8C,OAAeC,KAAKC,MAAMJ,GAAKG,KAAKC,MAAMhD,MAAM8C,QACtC,IAAhB9C,MAAMiD,OAAeF,KAAKC,MAAMN,GAAKK,KAAKC,MAAMhD,MAAMiD,QAGtDP,GAAQJ,SACRM,GAAQJ,WACDI,EAAK5C,MAAM8C,MAAQN,UAAaE,EAAK1C,MAAMiD,MAAQX,YAI1DI,EAAI1C,MAAMiD,MAAQX,SAClBM,EAAI5C,MAAM8C,MAAQN,UAGf,CACHG,QAASD,EACTG,QAASD,GAiBDM,CAASlD,OAGjBN,EAAEM,MAAMmD,QAAQC,GAAG,UAAY1D,EAAEM,MAAMmD,QAAQC,GAAG,YAClD3C,MAAM4C,kBAEN5C,MAAM6C,iBAIVnB,eAAeoB,eACXxB,eACA,GACA,EACAnC,OACA,EACAa,MAAM+C,SAAWxD,MAAMwD,QACvB/C,MAAMgD,SAAWzD,MAAMyD,QACvBhD,MAAMkC,SAAWN,MAAMM,QACvBlC,MAAMoC,SAAWR,MAAMQ,SACvB,GACA,GACA,GACA,EACA,EACA,MAIJpC,MAAM0C,OAAOO,cAAcvB,mBAlGT,mBAAXwB,QAAyBA,OAAOC,IAGvCD,OAAM,+CAAC,CAAC,SAAU,YAAalE,SAI/BA,QAAQG,OAAOiE"}
\ No newline at end of file
+{"version":3,"file":"jquery.ui.touch-punch-improved.min.js","sources":["../src/jquery.ui.touch-punch-improved.js"],"sourcesContent":["/*\n * JQuery UI Touch Punch Improved 0.3.1\n *\n *\n * Copyright 2013, Chris Hutchinson \n * Original jquery-ui-touch-punch Copyright 2011, Dave Furfero\n * Dual licensed under the MIT or GPL Version 2 licenses.\n *\n * Depends:\n * jquery.ui.widget.js\n * jquery.ui.mouse.js\n */\n(function(factory) {\n if (typeof define === \"function\" && define.amd) {\n\n // AMD. Register as an anonymous module.\n define([\"jquery\", \"jqueryui\"], factory);\n } else {\n\n // Browser globals.\n factory(window.jQuery);\n }\n}(function($) {\n var pointerEnabled = window.navigator.pointerEnabled\n || window.navigator.msPointerEnabled;\n\n // Detect touch support.\n $.support.touch = 'ontouchend' in document || pointerEnabled;\n\n // Ignore browsers without touch support or mouse support.\n if (!$.support.touch || !$.ui.mouse) {\n return;\n }\n\n var mouseProto = $.ui.mouse.prototype,\n _mouseInit = mouseProto._mouseInit,\n touchHandled;\n\n /**\n * See http://stackoverflow.com/a/12714084/220825.\n * @param {*} touch\n * @returns {object}\n */\n function fixTouch(touch) {\n var winPageX = window.pageXOffset,\n winPageY = window.pageYOffset,\n x = touch.clientX,\n y = touch.clientY;\n\n if (touch.pageY === 0 && Math.floor(y) > Math.floor(touch.pageY)\n || touch.pageX === 0 && Math.floor(x) > Math.floor(touch.pageX)) {\n // ...iOS4 clientX/clientY have the value that should have been.\n // ...in pageX/pageY. While pageX/page/ have the value 0.\n x = x - winPageX;\n y = y - winPageY;\n } else if (y < (touch.pageY - winPageY) || x < (touch.pageX - winPageX)) {\n // Some Android browsers have totally bogus values for clientX/Y.\n // when scrolling/zooming a page. Detectable since clientX/clientY.\n // should never be smaller than pageX/pageY minus page scroll.\n x = touch.pageX - winPageX;\n y = touch.pageY - winPageY;\n }\n\n return {\n clientX: x,\n clientY: y\n };\n }\n\n /**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} event A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\n function simulateMouseEvent(event, simulatedType) {\n // Ignore multi-touch events.\n if ((!pointerEnabled && event.originalEvent.touches.length > 1) || (pointerEnabled && !event.isPrimary)) {\n return;\n }\n\n var touch = pointerEnabled ? event.originalEvent : event.originalEvent.changedTouches[0],\n simulatedEvent = document.createEvent('MouseEvents'),\n coord = fixTouch(touch);\n\n // Check if element is an input or a textarea.\n if ($(touch.target).is(\"input\") || $(touch.target).is(\"textarea\")) {\n event.stopPropagation();\n } else {\n event.preventDefault();\n }\n\n // Initialize the simulated mouse event using the touch event's coordinates.\n simulatedEvent.initMouseEvent(\n simulatedType, // ...type.\n true, // ...bubbles.\n true, // ...cancelable.\n window, // ...view.\n 1, // ...detail\n event.screenX || touch.screenX, // ...screenX.\n event.screenY || touch.screenY, // ...screenY.\n event.clientX || coord.clientX, // ...clientX.\n event.clientY || coord.clientY, // ...clientY.\n false, // ...ctrlKey.\n false, // ...altKey.\n false, // ...shiftKey.\n false, // ...metaKey.\n 0, // ...button.\n null // ...relatedTarget.\n );\n\n // Dispatch the simulated event to the target element.\n event.target.dispatchEvent(simulatedEvent);\n }\n\n /**\n * Handle the jQuery UI widget's touchstart events\n * @param {Object} event The widget element's touchstart event\n */\n mouseProto._touchStart = function(event) {\n var self = this;\n\n // Ignore the event if another widget is already being handled.\n if (touchHandled || (!pointerEnabled && !self._mouseCapture(event.originalEvent.changedTouches[0]))) {\n return;\n }\n\n // Set the flag to prevent other widgets from inheriting the touch event.\n touchHandled = true;\n\n // Track movement to determine if interaction was a click.\n self._touchMoved = false;\n\n // Simulate the mouseover event.\n simulateMouseEvent(event, 'mouseover');\n\n // Simulate the mousemove event.\n simulateMouseEvent(event, 'mousemove');\n\n // Simulate the mousedown event.\n simulateMouseEvent(event, 'mousedown');\n };\n\n /**\n * Handle the jQuery UI widget's touchmove events\n * @param {Object} event The document's touchmove event\n */\n mouseProto._touchMove = function(event) {\n // Ignore event if not handled.\n if (!touchHandled) {\n return;\n }\n\n // Interaction was not a click.\n this._touchMoved = true;\n\n // Simulate the mousemove event.\n simulateMouseEvent(event, 'mousemove');\n };\n\n /**\n * Handle the jQuery UI widget's touchend events\n * @param {Object} event The document's touchend event\n */\n mouseProto._touchEnd = function(event) {\n // Ignore event if not handled.\n if (!touchHandled) {\n return;\n }\n\n // Simulate the mouseup event.\n simulateMouseEvent(event, 'mouseup');\n\n // Simulate the mouseout event.\n simulateMouseEvent(event, 'mouseout');\n\n // If the touch interaction did not move, it should trigger a click.\n if (!this._touchMoved) {\n // Simulate the click event.\n simulateMouseEvent(event, 'click');\n }\n\n // Unset the flag to allow other widgets to inherit the touch event.\n touchHandled = false;\n };\n\n /**\n * A duck punch of the $.ui.mouse _mouseInit method to support touch events.\n * This method extends the widget with bound touch event handlers that\n * translate touch events to mouse events and pass them to the widget's\n * original mouse event handling methods.\n */\n mouseProto._mouseInit = function() {\n var self = this;\n\n self.element.on({\n 'touchstart': $.proxy(self, '_touchStart'),\n 'touchmove': $.proxy(self, '_touchMove'),\n 'touchend': $.proxy(self, '_touchEnd'),\n 'pointerDown': $.proxy(self, '_touchStart'),\n 'pointerMove': $.proxy(self, '_touchMove'),\n 'pointerUp': $.proxy(self, '_touchEnd'),\n 'MSPointerDown': $.proxy(self, '_touchStart'),\n 'MSPointerMove': $.proxy(self, '_touchMove'),\n 'MSPointerUp': $.proxy(self, '_touchEnd')\n });\n\n // Call the original $.ui.mouse init method.\n _mouseInit.call(self);\n };\n\n}));"],"names":["factory","$","pointerEnabled","window","navigator","msPointerEnabled","support","touch","document","ui","mouse","touchHandled","mouseProto","prototype","_mouseInit","_touchStart","event","this","_mouseCapture","originalEvent","changedTouches","_touchMoved","simulateMouseEvent","_touchMove","_touchEnd","element","on","proxy","call","simulatedType","touches","length","isPrimary","simulatedEvent","createEvent","coord","winPageX","pageXOffset","winPageY","pageYOffset","x","clientX","y","clientY","pageY","Math","floor","pageX","fixTouch","target","is","stopPropagation","preventDefault","initMouseEvent","screenX","screenY","dispatchEvent","define","amd","jQuery"],"mappings":"AAYC,IAASA,gBAUR,SAASC,OACHC,eAAiBC,OAAOC,UAAUF,gBAC/BC,OAAOC,UAAUC,oBAGxBJ,EAAEK,QAAQC,MAAQ,eAAgBC,UAAYN,eAGzCD,EAAEK,QAAQC,OAAUN,EAAEQ,GAAGC,WAM1BC,aAFAC,WAAaX,EAAEQ,GAAGC,MAAMG,UACxBC,WAAaF,WAAWE,WAmF5BF,WAAWG,YAAc,SAASC,OAI1BL,eAAkBT,iBAHXe,KAGmCC,cAAcF,MAAMG,cAAcC,eAAe,MAK/FT,cAAe,EARJM,KAWNI,aAAc,EAGnBC,mBAAmBN,MAAO,aAG1BM,mBAAmBN,MAAO,aAG1BM,mBAAmBN,MAAO,eAO9BJ,WAAWW,WAAa,SAASP,OAExBL,oBAKAU,aAAc,EAGnBC,mBAAmBN,MAAO,eAO9BJ,WAAWY,UAAY,SAASR,OAEvBL,eAKLW,mBAAmBN,MAAO,WAG1BM,mBAAmBN,MAAO,YAGrBC,KAAKI,aAENC,mBAAmBN,MAAO,SAI9BL,cAAe,IASnBC,WAAWE,WAAa,WACTG,KAENQ,QAAQC,GAAG,YACEzB,EAAE0B,MAHTV,KAGqB,yBACfhB,EAAE0B,MAJRV,KAIoB,uBACfhB,EAAE0B,MALPV,KAKmB,yBACXhB,EAAE0B,MANVV,KAMsB,2BACdhB,EAAE0B,MAPVV,KAOsB,wBAChBhB,EAAE0B,MARRV,KAQoB,2BACVhB,EAAE0B,MATZV,KASwB,6BACdhB,EAAE0B,MAVZV,KAUwB,0BAChBhB,EAAE0B,MAXVV,KAWsB,eAIjCH,WAAWc,KAfAX,gBAtHNK,mBAAmBN,MAAOa,qBAEzB3B,gBAAkBc,MAAMG,cAAcW,QAAQC,OAAS,GAAO7B,iBAAmBc,MAAMgB,gBAIzFzB,MAAQL,eAAiBc,MAAMG,cAAgBH,MAAMG,cAAcC,eAAe,GAClFa,eAAiBzB,SAAS0B,YAAY,eACtCC,eAvCU5B,WACV6B,SAAWjC,OAAOkC,YAClBC,SAAWnC,OAAOoC,YAClBC,EAAIjC,MAAMkC,QACVC,EAAInC,MAAMoC,eAEM,IAAhBpC,MAAMqC,OAAeC,KAAKC,MAAMJ,GAAKG,KAAKC,MAAMvC,MAAMqC,QACtC,IAAhBrC,MAAMwC,OAAeF,KAAKC,MAAMN,GAAKK,KAAKC,MAAMvC,MAAMwC,QAGtDP,GAAQJ,SACRM,GAAQJ,WACDI,EAAKnC,MAAMqC,MAAQN,UAAaE,EAAKjC,MAAMwC,MAAQX,YAI1DI,EAAIjC,MAAMwC,MAAQX,SAClBM,EAAInC,MAAMqC,MAAQN,UAGf,CACHG,QAASD,EACTG,QAASD,GAiBDM,CAASzC,OAGjBN,EAAEM,MAAM0C,QAAQC,GAAG,UAAYjD,EAAEM,MAAM0C,QAAQC,GAAG,YAClDlC,MAAMmC,kBAENnC,MAAMoC,iBAIVnB,eAAeoB,eACXxB,eACA,GACA,EACA1B,OACA,EACAa,MAAMsC,SAAW/C,MAAM+C,QACvBtC,MAAMuC,SAAWhD,MAAMgD,QACvBvC,MAAMyB,SAAWN,MAAMM,QACvBzB,MAAM2B,SAAWR,MAAMQ,SACvB,GACA,GACA,GACA,EACA,EACA,MAIJ3B,MAAMiC,OAAOO,cAAcvB,iBAmGlC,EArMyB,mBAAXwB,QAAyBA,OAAOC,IAGvCD,sDAAO,CAAC,SAAU,YAAazD,SAI/BA,QAAQG,OAAOwD"}
\ No newline at end of file
diff --git a/amd/build/questionedit.min.js.map b/amd/build/questionedit.min.js.map
index 77ab0c0..918913b 100644
--- a/amd/build/questionedit.min.js.map
+++ b/amd/build/questionedit.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"questionedit.min.js","sources":["../src/questionedit.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JavaScript code for the gapfill question type.\n *\n * @copyright 2017 Marcus Green\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/* The data is stored in a hidden field */\ndefine(['jquery', 'qtype_gapfill/Item'], function($, Item) {\n return {\n init: function() {\n $('#id_answerdisplay').change(function() {\n var selected = $(this).val();\n if (selected == 'gapfill') {\n $('#id_fixedgapsize').prop('disabled', false);\n $(\"#id_optionsaftertext\").prop('disabled', true).prop('checked', false);\n $('#id_singleuse').prop('disabled', true).prop('checked', false);\n $('#id_disableregex').prop('disabled', false);\n\n }\n if (selected == 'dragdrop') {\n $('#id_optionsaftertext').prop('disabled', false);\n $('#id_singleuse').prop('disabled', false);\n $('#id_fixedgapsize').prop('disabled', false);\n $('#id_disableregex').prop('disabled', false);\n }\n if (selected == 'dropdown') {\n $('#id_fixedgapsize').prop('disabled', true).prop('checked', false);\n $('#id_optionsaftertext').prop('disabled', true).prop('checked', false);\n $('#id_singleuse').prop('disabled', true).prop('checked', false);\n $('#id_disableregex').prop('disabled', true).prop('checked', false);\n }\n\n\n });\n /* A click on the itemsettings button */\n $('#id_itemsettings_button').on('click', function() {\n var attoIsLive = $('.editor_atto').length;\n /* Show error if Atto is not loaded. It might be because the page has not finished loading\n * or because plain text elements are being used or (perhaps less likely as time goes on)\n * the HTMLarea editor is being used. It might be possible to work with those other editors\n * but limiting to Atto keeps things straightforward and maintainable.\n */\n if (attoIsLive < 1) {\n $('#id_error_itemsettings_button').css({\n display: 'inline',\n color: 'red',\n });\n $('#id_error_itemsettings_button')[0].innerHTML = M.util.get_string(\n 'itemsettingserror',\n 'qtype_gapfill'\n );\n return;\n }\n $('#questiontext .atto_html_button').attr('disabled', 'true');\n if ($('#id_questiontexteditable').get(0).isContentEditable) {\n $('#id_questiontexteditable').attr('contenteditable', 'false');\n $('#fitem_id_questiontext')\n .find('button')\n .attr('disabled', 'true');\n var settingformheight = $('#id_questiontexteditable').css('height');\n var settingformwidth = $('#id_questiontexteditable').css('width');\n $('#id_questiontexteditable').css('display', 'none');\n /* Copy the styles from attos editable area so the canvas looks the same (except gray) */\n $('#id_itemsettings_canvas').css(\n copyStyles($('#id_questiontexteditable'))\n );\n var ed = $('#id_questiontexteditable').closest(\n '.editor_atto_content_wrap'\n );\n $('#id_itemsettings_canvas')\n .appendTo(ed)\n .css('position', 'relative');\n $('#id_itemsettings_canvas').css({\n display: 'block',\n background: 'lightgrey',\n });\n\n /* Copy the real html to the feedback editing html */\n $('#id_itemsettings_canvas').html(\n $('#id_questiontexteditable').prop('innerHTML')\n );\n $('#id_itemsettings_canvas').css({\n height: settingformheight,\n width: settingformwidth,\n });\n $('#id_itemsettings_canvas').css({height: '100%', width: '100%'});\n $('#id_itemsettings_button').html(\n M.util.get_string('editquestiontext', 'qtype_gapfill')\n );\n /* Setting the height by hand gets around a quirk of MSIE */\n $('#id_itemsettings_canvas').height(\n $('#id_questiontexteditable').height()\n );\n /* Disable the buttons on questiontext but not on the feedback form */\n /* wrapContent should be the last on this block as it sometimes falls over with an error */\n wrapContent($('#id_itemsettings_canvas')[0]);\n } else {\n $('#id_questiontexteditable').css({\n display: 'block',\n backgroundColor: 'white',\n });\n $('#id_questiontexteditable').attr('contenteditable', 'true');\n $('#id_itemsettings_canvas').css('display', 'none');\n $('#fitem_id_questiontext')\n .find('button')\n .removeAttr('disabled');\n $('#id_settings_popup').css('display', 'none');\n $('#id_itemsettings_button').html(\n M.util.get_string('additemsettings', 'qtype_gapfill')\n );\n $('[class^=atto_]').removeAttr('disabled');\n }\n });\n\n /* A click on the text */\n $('#id_itemsettings_canvas').on('click', function(e) {\n /*\n * Questiontext needs to be edditable and the target must start\n * with id followed by one or more digits and an underscore\n * */\n if (\n !$('#id_questiontexteditable').get(0).isContentEditable &&\n e.target.id.match(/^id[0-9]+_/)\n ) {\n var delimitchars = $('#id_delimitchars').val();\n var item = new Item(e.target.innerHTML, delimitchars);\n\n // Var item = new Item(e.target.innerHTML, delimitchars);\n var itemsettings = item.getItemSettings(e.target);\n if (itemsettings === null || itemsettings.length === 0) {\n $('#id_correcteditable').html('');\n $('#id_incorrecteditable').html('');\n } else {\n $('#id_correcteditable').html(itemsettings.correctfeedback);\n $('#id_incorrecteditable').html(itemsettings.incorrectfeedback);\n }\n $(\"label[for*='id_correct']\").text(\n M.util.get_string('correct', 'qtype_gapfill')\n );\n $(\"label[for*='id_incorrect']\").text(\n M.util.get_string('incorrect', 'qtype_gapfill')\n );\n $('#id_itemsettings_popup .atto_image_button').attr(\n 'disabled',\n 'true'\n );\n $('#id_itemsettings_popup .atto_media_button').attr(\n 'disabled',\n 'true'\n );\n $('#id_itemsettings_popup .atto_managefiles_button').attr(\n 'disabled',\n 'true'\n );\n var title = M.util.get_string('additemsettings', 'qtype_gapfill');\n /* The html jquery call will turn any encoded entities such as > to html, i.e. > */\n title +=\n ': ' +\n $('')\n .html(item.stripdelim())\n .text();\n require(['jquery', 'jqueryui'], function($) {\n $('#id_itemsettings_popup').dialog({\n position: {\n my: 'right',\n at: 'right',\n of: '#id_itemsettings_canvas',\n },\n height: 500,\n width: '70%',\n modal: false,\n title: title,\n buttons: [\n {\n text: 'OK',\n id: 'SaveItemFeedback',\n click: function() {\n var JSONstr = item.updateJson(e);\n $('[class^=atto_]').removeAttr('disabled');\n $(\"[name='itemsettings']\").val(JSONstr);\n $('.ui-dialog-content').dialog('close');\n /* Set editable to true as it is checked at the start of click */\n $('#id_questiontexteditable').attr(\n 'contenteditable',\n 'true'\n );\n $('#id_itemsettings_button').click();\n },\n },\n ],\n });\n });\n }\n });\n\n /**\n * Convert an object to an array\n * @param {object} obj\n * @return {array}\n */\n function toArray(obj) {\n var arr = [];\n for (var i = 0, iLen = obj.length; i < iLen; i++) {\n arr.push(obj[i]);\n }\n return arr;\n }\n\n // Wrap the words of an element and child elements in a span.\n // Recurs over child elements, add an ID and class to the wrapping span.\n // Does not affect elements with no content, or those to be excluded.\n var wrapContent = (function() {\n return function(el) {\n var count = 0;\n var gaps = [];\n // If element provided, start there, otherwise use the body.\n el = el && el.parentNode ? el : document.body;\n // Get all child nodes as a static array.\n var node,\n nodes = toArray(el.childNodes);\n if (el.id === 'id_questiontextfeedback' && count > 0) {\n count = 0;\n }\n var frag, text;\n var delimitchars = $('#id_delimitchars').val();\n var l = delimitchars.substring(0, 1);\n var r = delimitchars.substring(1, 2);\n var regex = new RegExp('(\\\\' + l + '.*?\\\\' + r + ')', 'g');\n var sp,\n span = document.createElement('span');\n // Tag names of elements to skip, there are more to add.\n var skip = {\n script: '',\n button: '',\n input: '',\n select: '',\n textarea: '',\n option: '',\n };\n // For each child node...\n for (var i = 0, iLen = nodes.length; i < iLen; i++) {\n node = nodes[i];\n // If it's an element, call wrapContent.\n if (node.nodeType === 1 && !(node.tagName.toLowerCase() in skip)) {\n wrapContent(node);\n // If it's a text node, wrap words.\n } else if (node.nodeType === 3) {\n var textsplit = new RegExp('(\\\\' + l + '.*?\\\\' + r + ')', 'g');\n text = node.data.split(textsplit);\n if (text) {\n // Create a fragment, handy suckers these.\n frag = document.createDocumentFragment();\n for (var j = 0, jLen = text.length; j < jLen; j++) {\n // If not whitespace, wrap it and append to the fragment.\n doGap(text, span, j);\n }\n }\n // Replace the original node with the fragment.\n node.parentNode.replaceChild(frag, node);\n }\n }\n /**\n * Process each gap\n *\n * @param {*} text\n * @param {*} span\n * @param {*} j\n */\n function doGap(text, span, j) {\n gaps = [];\n if (regex.test(text[j])) {\n sp = span.cloneNode(false);\n count++;\n sp.className = 'item';\n var item = new Item(text[j], $('#id_delimitchars').val());\n if (item.gaptext > '') {\n var instance = 0;\n for (var k = 0; k < gaps.length; ++k) {\n if (gaps[k] === item.text) {\n instance++;\n }\n }\n item.id = 'id' + count + '_' + instance;\n sp.id = item.id;\n var is = item.getItemSettings(item);\n if (item.striptags(is.correctfeedback) > '') {\n sp.className = 'hascorrect';\n }\n if (item.striptags(is.incorrectfeedback) > '') {\n sp.className = sp.className + ' ' + 'hasnocorrect';\n }\n gaps.push(item.gaptext);\n }\n sp.appendChild(document.createTextNode(text[j]));\n frag.appendChild(sp);\n // Otherwise, just append it to the fragment.\n } else {\n frag.appendChild(document.createTextNode(text[j]));\n }\n }\n };\n })();\n /**\n *\n * @param {array} source\n * @return {array} product\n */\n function copyStyles(source) {\n // The map to return with requested styles and values as KVP.\n var product = {};\n // The style object from the DOM element we need to iterate through.\n var style;\n // Recycle the name of the style attribute.\n var name;\n // Prevent from empty selector.\n if (source.length) {\n // Otherwise, we need to get everything.\n var dom = source.get(0);\n if (window.getComputedStyle) {\n // Convenience methods to turn css case ('background-image') to camel ('backgroundImage').\n var pattern = /-([a-z])/g;\n var uc = function(a, b) {\n return b.toUpperCase();\n };\n var camelize = function(string) {\n return string.replace(pattern, uc);\n };\n // Make sure we're getting a good reference.\n if ((style = window.getComputedStyle(dom, null))) {\n var camel, value;\n for (var i = 0, l = style.length; i < l; i++) {\n name = style[i];\n camel = camelize(name);\n value = style.getPropertyValue(name);\n product[camel] = value;\n }\n } else if ((style = dom.currentStyle)) {\n for (name in style) {\n product[name] = style[name];\n }\n } else if ((style = dom.style)) {\n product = getStyle(style, product, name);\n }\n return product;\n }\n }\n return false;\n }\n /**\n * TODO check if this function is needed\n * @param {string} style\n * @param {object} product\n * @param {string} name\n * @returns {string}\n */\n function getStyle(style, product, name) {\n for (name in style) {\n if (typeof style[name] != 'function') {\n product[name] = style[name];\n }\n }\n return product;\n }\n },\n };\n});\n"],"names":["define","$","Item","init","change","selected","this","val","prop","on","length","css","display","color","innerHTML","M","util","get_string","attr","get","isContentEditable","find","settingformheight","settingformwidth","source","style","name","product","dom","window","getComputedStyle","pattern","uc","a","b","toUpperCase","camelize","string","replace","camel","value","i","l","getPropertyValue","currentStyle","getStyle","copyStyles","ed","closest","appendTo","background","html","height","width","wrapContent","backgroundColor","removeAttr","e","target","id","match","delimitchars","item","itemsettings","getItemSettings","correctfeedback","incorrectfeedback","text","title","stripdelim","require","dialog","position","my","at","of","modal","buttons","click","JSONstr","updateJson","el","node","frag","count","gaps","nodes","obj","arr","iLen","push","toArray","parentNode","document","body","childNodes","sp","substring","r","regex","RegExp","span","createElement","skip","script","button","input","select","textarea","option","nodeType","tagName","toLowerCase","textsplit","data","split","createDocumentFragment","j","jLen","doGap","replaceChild","test","cloneNode","className","gaptext","instance","k","is","striptags","appendChild","createTextNode"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"questionedit.min.js","sources":["../src/questionedit.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JavaScript code for the gapfill question type.\n *\n * @copyright 2017 Marcus Green\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/* The data is stored in a hidden field */\ndefine(['jquery', 'qtype_gapfill/Item'], function($, Item) {\n return {\n init: function() {\n $('#id_answerdisplay').change(function() {\n var selected = $(this).val();\n if (selected == 'gapfill') {\n $('#id_fixedgapsize').prop('disabled', false);\n $(\"#id_optionsaftertext\").prop('disabled', true).prop('checked', false);\n $('#id_singleuse').prop('disabled', true).prop('checked', false);\n $('#id_disableregex').prop('disabled', false);\n\n }\n if (selected == 'dragdrop') {\n $('#id_optionsaftertext').prop('disabled', false);\n $('#id_singleuse').prop('disabled', false);\n $('#id_fixedgapsize').prop('disabled', false);\n $('#id_disableregex').prop('disabled', false);\n }\n if (selected == 'dropdown') {\n $('#id_fixedgapsize').prop('disabled', true).prop('checked', false);\n $('#id_optionsaftertext').prop('disabled', true).prop('checked', false);\n $('#id_singleuse').prop('disabled', true).prop('checked', false);\n $('#id_disableregex').prop('disabled', true).prop('checked', false);\n }\n\n\n });\n /* A click on the itemsettings button */\n $('#id_itemsettings_button').on('click', function() {\n var attoIsLive = $('.editor_atto').length;\n /* Show error if Atto is not loaded. It might be because the page has not finished loading\n * or because plain text elements are being used or (perhaps less likely as time goes on)\n * the HTMLarea editor is being used. It might be possible to work with those other editors\n * but limiting to Atto keeps things straightforward and maintainable.\n */\n if (attoIsLive < 1) {\n $('#id_error_itemsettings_button').css({\n display: 'inline',\n color: 'red',\n });\n $('#id_error_itemsettings_button')[0].innerHTML = M.util.get_string(\n 'itemsettingserror',\n 'qtype_gapfill'\n );\n return;\n }\n $('#questiontext .atto_html_button').attr('disabled', 'true');\n if ($('#id_questiontexteditable').get(0).isContentEditable) {\n $('#id_questiontexteditable').attr('contenteditable', 'false');\n $('#fitem_id_questiontext')\n .find('button')\n .attr('disabled', 'true');\n var settingformheight = $('#id_questiontexteditable').css('height');\n var settingformwidth = $('#id_questiontexteditable').css('width');\n $('#id_questiontexteditable').css('display', 'none');\n /* Copy the styles from attos editable area so the canvas looks the same (except gray) */\n $('#id_itemsettings_canvas').css(\n copyStyles($('#id_questiontexteditable'))\n );\n var ed = $('#id_questiontexteditable').closest(\n '.editor_atto_content_wrap'\n );\n $('#id_itemsettings_canvas')\n .appendTo(ed)\n .css('position', 'relative');\n $('#id_itemsettings_canvas').css({\n display: 'block',\n background: 'lightgrey',\n });\n\n /* Copy the real html to the feedback editing html */\n $('#id_itemsettings_canvas').html(\n $('#id_questiontexteditable').prop('innerHTML')\n );\n $('#id_itemsettings_canvas').css({\n height: settingformheight,\n width: settingformwidth,\n });\n $('#id_itemsettings_canvas').css({height: '100%', width: '100%'});\n $('#id_itemsettings_button').html(\n M.util.get_string('editquestiontext', 'qtype_gapfill')\n );\n /* Setting the height by hand gets around a quirk of MSIE */\n $('#id_itemsettings_canvas').height(\n $('#id_questiontexteditable').height()\n );\n /* Disable the buttons on questiontext but not on the feedback form */\n /* wrapContent should be the last on this block as it sometimes falls over with an error */\n wrapContent($('#id_itemsettings_canvas')[0]);\n } else {\n $('#id_questiontexteditable').css({\n display: 'block',\n backgroundColor: 'white',\n });\n $('#id_questiontexteditable').attr('contenteditable', 'true');\n $('#id_itemsettings_canvas').css('display', 'none');\n $('#fitem_id_questiontext')\n .find('button')\n .removeAttr('disabled');\n $('#id_settings_popup').css('display', 'none');\n $('#id_itemsettings_button').html(\n M.util.get_string('additemsettings', 'qtype_gapfill')\n );\n $('[class^=atto_]').removeAttr('disabled');\n }\n });\n\n /* A click on the text */\n $('#id_itemsettings_canvas').on('click', function(e) {\n /*\n * Questiontext needs to be edditable and the target must start\n * with id followed by one or more digits and an underscore\n * */\n if (\n !$('#id_questiontexteditable').get(0).isContentEditable &&\n e.target.id.match(/^id[0-9]+_/)\n ) {\n var delimitchars = $('#id_delimitchars').val();\n var item = new Item(e.target.innerHTML, delimitchars);\n\n // Var item = new Item(e.target.innerHTML, delimitchars);\n var itemsettings = item.getItemSettings(e.target);\n if (itemsettings === null || itemsettings.length === 0) {\n $('#id_correcteditable').html('');\n $('#id_incorrecteditable').html('');\n } else {\n $('#id_correcteditable').html(itemsettings.correctfeedback);\n $('#id_incorrecteditable').html(itemsettings.incorrectfeedback);\n }\n $(\"label[for*='id_correct']\").text(\n M.util.get_string('correct', 'qtype_gapfill')\n );\n $(\"label[for*='id_incorrect']\").text(\n M.util.get_string('incorrect', 'qtype_gapfill')\n );\n $('#id_itemsettings_popup .atto_image_button').attr(\n 'disabled',\n 'true'\n );\n $('#id_itemsettings_popup .atto_media_button').attr(\n 'disabled',\n 'true'\n );\n $('#id_itemsettings_popup .atto_managefiles_button').attr(\n 'disabled',\n 'true'\n );\n var title = M.util.get_string('additemsettings', 'qtype_gapfill');\n /* The html jquery call will turn any encoded entities such as > to html, i.e. > */\n title +=\n ': ' +\n $('')\n .html(item.stripdelim())\n .text();\n require(['jquery', 'jqueryui'], function($) {\n $('#id_itemsettings_popup').dialog({\n position: {\n my: 'right',\n at: 'right',\n of: '#id_itemsettings_canvas',\n },\n height: 500,\n width: '70%',\n modal: false,\n title: title,\n buttons: [\n {\n text: 'OK',\n id: 'SaveItemFeedback',\n click: function() {\n var JSONstr = item.updateJson(e);\n $('[class^=atto_]').removeAttr('disabled');\n $(\"[name='itemsettings']\").val(JSONstr);\n $('.ui-dialog-content').dialog('close');\n /* Set editable to true as it is checked at the start of click */\n $('#id_questiontexteditable').attr(\n 'contenteditable',\n 'true'\n );\n $('#id_itemsettings_button').click();\n },\n },\n ],\n });\n });\n }\n });\n\n /**\n * Convert an object to an array\n * @param {object} obj\n * @return {array}\n */\n function toArray(obj) {\n var arr = [];\n for (var i = 0, iLen = obj.length; i < iLen; i++) {\n arr.push(obj[i]);\n }\n return arr;\n }\n\n // Wrap the words of an element and child elements in a span.\n // Recurs over child elements, add an ID and class to the wrapping span.\n // Does not affect elements with no content, or those to be excluded.\n var wrapContent = (function() {\n return function(el) {\n var count = 0;\n var gaps = [];\n // If element provided, start there, otherwise use the body.\n el = el && el.parentNode ? el : document.body;\n // Get all child nodes as a static array.\n var node,\n nodes = toArray(el.childNodes);\n if (el.id === 'id_questiontextfeedback' && count > 0) {\n count = 0;\n }\n var frag, text;\n var delimitchars = $('#id_delimitchars').val();\n var l = delimitchars.substring(0, 1);\n var r = delimitchars.substring(1, 2);\n var regex = new RegExp('(\\\\' + l + '.*?\\\\' + r + ')', 'g');\n var sp,\n span = document.createElement('span');\n // Tag names of elements to skip, there are more to add.\n var skip = {\n script: '',\n button: '',\n input: '',\n select: '',\n textarea: '',\n option: '',\n };\n // For each child node...\n for (var i = 0, iLen = nodes.length; i < iLen; i++) {\n node = nodes[i];\n // If it's an element, call wrapContent.\n if (node.nodeType === 1 && !(node.tagName.toLowerCase() in skip)) {\n wrapContent(node);\n // If it's a text node, wrap words.\n } else if (node.nodeType === 3) {\n var textsplit = new RegExp('(\\\\' + l + '.*?\\\\' + r + ')', 'g');\n text = node.data.split(textsplit);\n if (text) {\n // Create a fragment, handy suckers these.\n frag = document.createDocumentFragment();\n for (var j = 0, jLen = text.length; j < jLen; j++) {\n // If not whitespace, wrap it and append to the fragment.\n doGap(text, span, j);\n }\n }\n // Replace the original node with the fragment.\n node.parentNode.replaceChild(frag, node);\n }\n }\n /**\n * Process each gap\n *\n * @param {*} text\n * @param {*} span\n * @param {*} j\n */\n function doGap(text, span, j) {\n gaps = [];\n if (regex.test(text[j])) {\n sp = span.cloneNode(false);\n count++;\n sp.className = 'item';\n var item = new Item(text[j], $('#id_delimitchars').val());\n if (item.gaptext > '') {\n var instance = 0;\n for (var k = 0; k < gaps.length; ++k) {\n if (gaps[k] === item.text) {\n instance++;\n }\n }\n item.id = 'id' + count + '_' + instance;\n sp.id = item.id;\n var is = item.getItemSettings(item);\n if (item.striptags(is.correctfeedback) > '') {\n sp.className = 'hascorrect';\n }\n if (item.striptags(is.incorrectfeedback) > '') {\n sp.className = sp.className + ' ' + 'hasnocorrect';\n }\n gaps.push(item.gaptext);\n }\n sp.appendChild(document.createTextNode(text[j]));\n frag.appendChild(sp);\n // Otherwise, just append it to the fragment.\n } else {\n frag.appendChild(document.createTextNode(text[j]));\n }\n }\n };\n })();\n /**\n *\n * @param {array} source\n * @return {array} product\n */\n function copyStyles(source) {\n // The map to return with requested styles and values as KVP.\n var product = {};\n // The style object from the DOM element we need to iterate through.\n var style;\n // Recycle the name of the style attribute.\n var name;\n // Prevent from empty selector.\n if (source.length) {\n // Otherwise, we need to get everything.\n var dom = source.get(0);\n if (window.getComputedStyle) {\n // Convenience methods to turn css case ('background-image') to camel ('backgroundImage').\n var pattern = /-([a-z])/g;\n var uc = function(a, b) {\n return b.toUpperCase();\n };\n var camelize = function(string) {\n return string.replace(pattern, uc);\n };\n // Make sure we're getting a good reference.\n if ((style = window.getComputedStyle(dom, null))) {\n var camel, value;\n for (var i = 0, l = style.length; i < l; i++) {\n name = style[i];\n camel = camelize(name);\n value = style.getPropertyValue(name);\n product[camel] = value;\n }\n } else if ((style = dom.currentStyle)) {\n for (name in style) {\n product[name] = style[name];\n }\n } else if ((style = dom.style)) {\n product = getStyle(style, product, name);\n }\n return product;\n }\n }\n return false;\n }\n /**\n * TODO check if this function is needed\n * @param {string} style\n * @param {object} product\n * @param {string} name\n * @returns {string}\n */\n function getStyle(style, product, name) {\n for (name in style) {\n if (typeof style[name] != 'function') {\n product[name] = style[name];\n }\n }\n return product;\n }\n },\n };\n});\n"],"names":["define","$","Item","init","change","selected","this","val","prop","on","length","css","display","color","innerHTML","M","util","get_string","attr","get","isContentEditable","find","settingformheight","settingformwidth","source","style","name","product","dom","window","getComputedStyle","pattern","uc","a","b","toUpperCase","camelize","string","replace","camel","value","i","l","getPropertyValue","currentStyle","getStyle","copyStyles","ed","closest","appendTo","background","html","height","width","wrapContent","backgroundColor","removeAttr","e","target","id","match","delimitchars","item","itemsettings","getItemSettings","correctfeedback","incorrectfeedback","text","title","stripdelim","require","dialog","position","my","at","of","modal","buttons","click","JSONstr","updateJson","el","node","frag","count","gaps","nodes","obj","arr","iLen","push","toArray","parentNode","document","body","childNodes","sp","substring","r","regex","RegExp","span","createElement","skip","script","button","input","select","textarea","option","nodeType","tagName","toLowerCase","textsplit","data","split","createDocumentFragment","j","jLen","doGap","replaceChild","test","cloneNode","className","gaptext","instance","k","is","striptags","appendChild","createTextNode"],"mappings":"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"}
\ No newline at end of file
diff --git a/amd/src/dragdrop.js b/amd/src/dragdrop.js
index 43a37ed..7ae88e2 100755
--- a/amd/src/dragdrop.js
+++ b/amd/src/dragdrop.js
@@ -79,9 +79,11 @@ export const init = (singleuse) => {
*
* @param {*} e
*/
- function dragStart(e) {
+ function dragStart(e) {
e.dataTransfer.setData('text/plain', e.target.innerText);
e.dataTransfer.setData('sourceId', this.id);
+ e.dataTransfer.effectAllowed = "move";
+ e.dataTransfer.dropEffect = "move";
}
};