diff --git a/amd/build/Item.min.js.map b/amd/build/Item.min.js.map index 03aeaa4..d356773 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","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 +{"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"} \ 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 f0cca99..06931ba 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","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 +{"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,QAAAA,QAUR,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,mBAlGT,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 918913b..0b830b3 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":";;;;;;AAuBAA,oCAAO,CAAC,SAAU,uBAAuB,SAASC,EAAGC,YAC5C,CACLC,KAAM,WACJF,EAAE,qBAAqBG,QAAO,eACxBC,SAAWJ,EAAEK,MAAMC,MACP,WAAZF,WACFJ,EAAE,oBAAoBO,KAAK,YAAY,GACvCP,EAAE,wBAAwBO,KAAK,YAAY,GAAMA,KAAK,WAAW,GACjEP,EAAE,iBAAiBO,KAAK,YAAY,GAAMA,KAAK,WAAW,GAC1DP,EAAE,oBAAoBO,KAAK,YAAY,IAGzB,YAAZH,WACFJ,EAAE,wBAAwBO,KAAK,YAAY,GAC3CP,EAAE,iBAAiBO,KAAK,YAAY,GACpCP,EAAE,oBAAoBO,KAAK,YAAY,GACvCP,EAAE,oBAAoBO,KAAK,YAAY,IAEzB,YAAZH,WACFJ,EAAE,oBAAoBO,KAAK,YAAY,GAAMA,KAAK,WAAW,GAC7DP,EAAE,wBAAwBO,KAAK,YAAY,GAAMA,KAAK,WAAW,GACjEP,EAAE,iBAAiBO,KAAK,YAAY,GAAMA,KAAK,WAAW,GAC1DP,EAAE,oBAAoBO,KAAK,YAAY,GAAMA,KAAK,WAAW,OAMjEP,EAAE,2BAA2BQ,GAAG,SAAS,cACtBR,EAAE,gBAAgBS,OAMlB,SACfT,EAAE,iCAAiCU,IAAI,CACrCC,QAAS,SACTC,MAAO,aAETZ,EAAE,iCAAiC,GAAGa,UAAYC,EAAEC,KAAKC,WACvD,oBACA,qBAIJhB,EAAE,mCAAmCiB,KAAK,WAAY,QAClDjB,EAAE,4BAA4BkB,IAAI,GAAGC,kBAAmB,CAC1DnB,EAAE,4BAA4BiB,KAAK,kBAAmB,SACtDjB,EAAE,0BACCoB,KAAK,UACLH,KAAK,WAAY,YAChBI,kBAAoBrB,EAAE,4BAA4BU,IAAI,UACtDY,iBAAmBtB,EAAE,4BAA4BU,IAAI,SACzDV,EAAE,4BAA4BU,IAAI,UAAW,QAE7CV,EAAE,2BAA2BU,aAoPba,YAIdC,MAEAC,KAJAC,QAAU,MAMVH,OAAOd,OAAQ,KAEbkB,IAAMJ,OAAOL,IAAI,MACjBU,OAAOC,iBAAkB,KAEvBC,QAAU,YACVC,GAAK,SAASC,EAAGC,UACZA,EAAEC,eAEPC,SAAW,SAASC,eACfA,OAAOC,QAAQP,QAASC,QAG5BP,MAAQI,OAAOC,iBAAiBF,IAAK,cACpCW,MAAOC,MACFC,EAAI,EAAGC,EAAIjB,MAAMf,OAAQ+B,EAAIC,EAAGD,IAEvCF,MAAQH,SADRV,KAAOD,MAAMgB,IAEbD,MAAQf,MAAMkB,iBAAiBjB,MAC/BC,QAAQY,OAASC,WAEd,GAAKf,MAAQG,IAAIgB,iBACjBlB,QAAQD,MACXE,QAAQD,MAAQD,MAAMC,WAEdD,MAAQG,IAAIH,SACtBE,iBAcUF,MAAOE,QAASD,UAC3BA,QAAQD,MACe,mBAAfA,MAAMC,QACfC,QAAQD,MAAQD,MAAMC,cAGnBC,QApBSkB,CAASpB,MAAOE,QAASD,cAE9BC,gBAGJ,EA1RHmB,CAAW7C,EAAE,kCAEX8C,GAAK9C,EAAE,4BAA4B+C,QACrC,6BAEF/C,EAAE,2BACCgD,SAASF,IACTpC,IAAI,WAAY,YACnBV,EAAE,2BAA2BU,IAAI,CAC/BC,QAAS,QACTsC,WAAY,cAIdjD,EAAE,2BAA2BkD,KAC3BlD,EAAE,4BAA4BO,KAAK,cAErCP,EAAE,2BAA2BU,IAAI,CAC/ByC,OAAQ9B,kBACR+B,MAAO9B,mBAETtB,EAAE,2BAA2BU,IAAI,CAACyC,OAAQ,OAAQC,MAAO,SACzDpD,EAAE,2BAA2BkD,KAC3BpC,EAAEC,KAAKC,WAAW,mBAAoB,kBAGxChB,EAAE,2BAA2BmD,OAC3BnD,EAAE,4BAA4BmD,UAIhCE,YAAYrD,EAAE,2BAA2B,SAEzCA,EAAE,4BAA4BU,IAAI,CAChCC,QAAS,QACT2C,gBAAiB,UAEnBtD,EAAE,4BAA4BiB,KAAK,kBAAmB,QACtDjB,EAAE,2BAA2BU,IAAI,UAAW,QAC5CV,EAAE,0BACCoB,KAAK,UACLmC,WAAW,YACdvD,EAAE,sBAAsBU,IAAI,UAAW,QACvCV,EAAE,2BAA2BkD,KAC3BpC,EAAEC,KAAKC,WAAW,kBAAmB,kBAEvChB,EAAE,kBAAkBuD,WAAW,eAKnCvD,EAAE,2BAA2BQ,GAAG,SAAS,SAASgD,OAM7CxD,EAAE,4BAA4BkB,IAAI,GAAGC,mBACtCqC,EAAEC,OAAOC,GAAGC,MAAM,cAClB,KACIC,aAAe5D,EAAE,oBAAoBM,MACrCuD,KAAO,IAAI5D,KAAKuD,EAAEC,OAAO5C,UAAW+C,cAGpCE,aAAeD,KAAKE,gBAAgBP,EAAEC,QACrB,OAAjBK,cAAiD,IAAxBA,aAAarD,QACxCT,EAAE,uBAAuBkD,KAAK,IAC9BlD,EAAE,yBAAyBkD,KAAK,MAEhClD,EAAE,uBAAuBkD,KAAKY,aAAaE,iBAC3ChE,EAAE,yBAAyBkD,KAAKY,aAAaG,oBAE/CjE,EAAE,4BAA4BkE,KAC5BpD,EAAEC,KAAKC,WAAW,UAAW,kBAE/BhB,EAAE,8BAA8BkE,KAC9BpD,EAAEC,KAAKC,WAAW,YAAa,kBAEjChB,EAAE,6CAA6CiB,KAC7C,WACA,QAEFjB,EAAE,6CAA6CiB,KAC7C,WACA,QAEFjB,EAAE,mDAAmDiB,KACnD,WACA,YAEEkD,MAAQrD,EAAEC,KAAKC,WAAW,kBAAmB,iBAEjDmD,OACE,KACAnE,EAAE,UACCkD,KAAKW,KAAKO,cACVF,OACLG,QAAQ,CAAC,SAAU,aAAa,SAASrE,GACvCA,EAAE,0BAA0BsE,OAAO,CACjCC,SAAU,CACRC,GAAI,QACJC,GAAI,QACJC,GAAI,2BAENvB,OAAQ,IACRC,MAAO,MACPuB,OAAO,EACPR,MAAOA,MACPS,QAAS,CACP,CACEV,KAAM,KACNR,GAAI,mBACJmB,MAAO,eACDC,QAAUjB,KAAKkB,WAAWvB,GAC9BxD,EAAE,kBAAkBuD,WAAW,YAC/BvD,EAAE,yBAAyBM,IAAIwE,SAC/B9E,EAAE,sBAAsBsE,OAAO,SAE/BtE,EAAE,4BAA4BiB,KAC5B,kBACA,QAEFjB,EAAE,2BAA2B6E,wBAyBvCxB,YACK,SAAS2B,QAMVC,KAKAC,KAAMhB,KAVNiB,MAAQ,EACRC,KAAO,GAKTC,eAnBWC,aACXC,IAAM,GACD/C,EAAI,EAAGgD,KAAOF,IAAI7E,OAAQ+B,EAAIgD,KAAMhD,IAC3C+C,IAAIE,KAAKH,IAAI9C,WAER+C,IAcKG,EAHVV,GAAKA,IAAMA,GAAGW,WAAaX,GAAKY,SAASC,MAGpBC,YACP,4BAAVd,GAAGtB,IAAoCyB,MAAQ,IACjDA,MAAQ,WAONY,GAJAnC,aAAe5D,EAAE,oBAAoBM,MACrCmC,EAAImB,aAAaoC,UAAU,EAAG,GAC9BC,EAAIrC,aAAaoC,UAAU,EAAG,GAC9BE,MAAQ,IAAIC,OAAO,MAAQ1D,EAAI,QAAUwD,EAAI,IAAK,KAEpDG,KAAOR,SAASS,cAAc,QAE5BC,KAAO,CACTC,OAAQ,GACRC,OAAQ,GACRC,MAAO,GACPC,OAAQ,GACRC,SAAU,GACVC,OAAQ,IAGDpE,EAAI,EAAGgD,KAAOH,MAAM5E,OAAQ+B,EAAIgD,KAAMhD,OAGvB,KAFtByC,KAAOI,MAAM7C,IAEJqE,UAAoB5B,KAAK6B,QAAQC,gBAAiBT,MAGpD,GAAsB,IAAlBrB,KAAK4B,SAAgB,KAC1BG,UAAY,IAAIb,OAAO,MAAQ1D,EAAI,QAAUwD,EAAI,IAAK,QAC1D/B,KAAOe,KAAKgC,KAAKC,MAAMF,WACb,CAER9B,KAAOU,SAASuB,6BACX,IAAIC,EAAI,EAAGC,KAAOnD,KAAKzD,OAAQ2G,EAAIC,KAAMD,IAE5CE,MAAMpD,KAAMkC,KAAMgB,GAItBnC,KAAKU,WAAW4B,aAAarC,KAAMD,YAdnC5B,YAAY4B,eAwBPqC,MAAMpD,KAAMkC,KAAMgB,MACzBhC,KAAO,GACHc,MAAMsB,KAAKtD,KAAKkD,IAAK,CACvBrB,GAAKK,KAAKqB,WAAU,GACpBtC,QACAY,GAAG2B,UAAY,WACX7D,KAAO,IAAI5D,KAAKiE,KAAKkD,GAAIpH,EAAE,oBAAoBM,UAC/CuD,KAAK8D,QAAU,GAAI,SACjBC,SAAW,EACNC,EAAI,EAAGA,EAAIzC,KAAK3E,SAAUoH,EAC7BzC,KAAKyC,KAAOhE,KAAKK,MACnB0D,WAGJ/D,KAAKH,GAAK,KAAOyB,MAAQ,IAAMyC,SAC/B7B,GAAGrC,GAAKG,KAAKH,OACToE,GAAKjE,KAAKE,gBAAgBF,MAC1BA,KAAKkE,UAAUD,GAAG9D,iBAAmB,KACvC+B,GAAG2B,UAAY,cAEb7D,KAAKkE,UAAUD,GAAG7D,mBAAqB,KACzC8B,GAAG2B,UAAY3B,GAAG2B,UAAH3B,iBAEjBX,KAAKK,KAAK5B,KAAK8D,SAEjB5B,GAAGiC,YAAYpC,SAASqC,eAAe/D,KAAKkD,KAC5ClC,KAAK8C,YAAYjC,SAGjBb,KAAK8C,YAAYpC,SAASqC,eAAe/D,KAAKkD"} \ No newline at end of file