diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6b97a47..96fd453 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,9 @@ Types of changes
* **Fixed** for any bug fixes.
* **Security** in case of vulnerabilities.
+## Version (4.5.0) - 2024-09-10
+- Upgraded and refactored for Moodle 4.5
+
## Version (4.4.0) - 2024-04-05
- Upgraded and refactored for Moodle 4.4
diff --git a/README.md b/README.md
index 45bb43f..2d5a38a 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Special thanks to Gemma Lesterhuis ([Lesterhuis Training & Consultancy](https://
* Author: Luuk Verhoeven, [ldesignmedia.nl](https://ldesignmedia.nl/)
* Author: Gemma Lesterhuis, [Lesterhuis Training & Consultancy](https://ltnc.nl/)
* Min. required: Moodle 3.9.x
-* Max. Required: Moodle 4.1.x
+* Max. Required: Moodle 4.5.x
* Supports PHP: 7.4 - 8.1
![Moodle39](https://img.shields.io/badge/moodle-3.9-brightgreen.svg)
@@ -18,6 +18,7 @@ Special thanks to Gemma Lesterhuis ([Lesterhuis Training & Consultancy](https://
![Moodle402](https://img.shields.io/badge/moodle-4.2-brightgreen.svg)
![Moodle403](https://img.shields.io/badge/moodle-4.3-brightgreen.svg)
![Moodle404](https://img.shields.io/badge/moodle-4.4-brightgreen.svg)
+![Moodle405](https://img.shields.io/badge/moodle-4.5-brightgreen.svg)
![PHP7.4](https://img.shields.io/badge/PHP-7.2-blue.svg)
![PHP8.0](https://img.shields.io/badge/PHP-8.0-blue.svg)
diff --git a/amd/build/canvas.min.js b/amd/build/canvas.min.js
index 2066718..41413ba 100644
--- a/amd/build/canvas.min.js
+++ b/amd/build/canvas.min.js
@@ -8,6 +8,6 @@
* @copyright 2018 MFreak.nl
* @author Luuk Verhoeven
**/
-define("mod_gcanvas/canvas",["jquery","core/notification"],(function($,notification){var opts={id:0,debugjs:!1,hasHorizontalRuler:!0,background:""},debug={},bufferStep=0,bufferActive=!0,canvas=null,canvasModule={canvasWidth:800,canvasHeight:500,defaultShaperect:{width:70,height:70,left:200,top:50,angle:0,fill:"#ffb628"},defaultShapecircle:{radius:40,left:200,top:50,fill:"#b3cc2b"},defaultShapetriangle:{top:50,left:200,width:70,height:70,fill:"#0081b4"},defaultShapetextbox:{top:50,left:200,fill:"#0081b4"},loadHistory:function(){$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"load_history",data:JSON.stringify({id:opts.id})},dataType:"json",success:function(response){debug.log(response),response.success&&$("#history").html(response.html)},error:function(response){debug.error(response.responseText),notification.addNotification({message:response.responseText,type:"error"})}})},saveCanvasAjax:function(){fabric.Canvas.supports("toDataURL")?$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"save_canvas",data:JSON.stringify({id:opts.id,status:"final",canvas_data:canvas.toDataURL({multiplier:1,format:"png"}),json_data:JSON.stringify(canvas)})},dataType:"json",success:function(response){debug.log(response),response.success?(notification.addNotification({message:M.util.get_string("javascript:updated","mod_gcanvas"),type:"success"}),canvasModule.loadHistory()):notification.addNotification({message:response.error,type:"error"})},error:function(response){debug.error(response.responseText),notification.addNotification({message:response.responseText,type:"error"})}}):notification.addNotification({message:"This browser doesn't provide means to serialize canvas to an image",type:"error"})},deleteSelectedCanvasItems:function(){try{var activeobjects=canvas.getActiveObjects();if(activeobjects.length<=0)return void debug.log("Selection empty");for(var i in activeobjects)if(activeobjects.hasOwnProperty(i)){var element=activeobjects[i];if(void 0!==element.id&&"ruler"===element.id){debug.log("Ruler: Not removable!");continue}canvas.remove(element)}canvas.discardActiveObject().renderAll()}catch(e){debug.error("Nothing selected",e)}},loadDynamicToolbarMappingShapes:function(){$("#toolbar .icon[data-element-type]").on("click",(function(){var el,elementtype=$(this).data("element-type");try{canvas.discardActiveObject()}catch(e){}var shape="defaultShape"+elementtype.toLowerCase();debug.log("Search for shape: "+shape),canvasModule.hasOwnProperty(shape)?(debug.log("Shape found"),el="Textbox"===elementtype?new fabric[elementtype]("DEMO",canvasModule[shape]):new fabric[elementtype](canvasModule[shape]),canvas.add(el),canvas.setActiveObject(el)):debug.error("Shape not found!"),canvas.renderAll()}))},loadColorPicker:function(){$("#colorpicker").spectrum({showPalette:!0,palette:[],showSelectionPalette:!0,selectionPalette:["red","green","blue","orange"],flat:!1,change:function(color){debug.log("change color"),canvasModule.setColor(color)}}).on("dragstart.spectrum , dragstop.spectrum",(function(e,color){debug.log("change color - dragstop - dragstart"),canvasModule.setColor(color)}))},loadEmojiCsv:function(src){debug.log("loadEmojiCsv : ",src),fabric.Image.fromURL(src.replace(".png",".svg"),(function(object){object.set({height:500,width:500,left:150,top:100,angle:0,centerTransform:!0}).scale(.4).setCoords(),canvas.add(object),canvas.setActiveObject(object)}))},deleteAttempt:function($el){debug.log("Delete",$el),notification.confirm(M.util.get_string("javascript:confirm_title","mod_gcanvas"),M.util.get_string("javascript:confirm_desc","mod_gcanvas"),M.util.get_string("javascript:yes","mod_gcanvas"),M.util.get_string("javascript:no","mod_gcanvas"),(function(){$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"delete_attempt",data:JSON.stringify({id:opts.id,attempt_id:$el.data("id")})},dataType:"json",success:function(response){debug.log(response),response.success?canvasModule.loadHistory():notification.addNotification({message:response.error,type:"error"})},error:function(response){debug.error(response.responseText),notification.addNotification({message:response.responseText,type:"error"})}})}))},restoreAttempt:function($el){debug.log("Restore",$el),$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"get_attempt",data:JSON.stringify({id:opts.id,attempt_id:$el.data("id")})},dataType:"json",success:function(response){debug.log(response),response.success&&(bufferActive=!1,canvas.loadFromJSON(response.record.json_data,canvas.renderAll.bind(canvas)),setTimeout((function(){bufferActive=!0}),1e3))}})},showFileuploader:function(filearea){$("#canvas-filepicker-form-"+filearea).toggle()},setBackgroundImage:function(){""!==opts.background&&"false"!==opts.background&&fabric.Image.fromURL(opts.background,(function(img){canvas.setBackgroundImage(img,canvas.renderAll.bind(canvas),{scaleX:canvas.width/img.width,scaleY:canvas.height/img.height})}))},addUserImage:function(){var formdata={id:opts.id},inputs=$("#canvas-filepicker-form-student_image form").serializeArray();$.each(inputs,(function(i,input){formdata[input.name]=input.value})),$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"upload_images",data:JSON.stringify(formdata)},dataType:"json",success:function(response){debug.log(response),response.success&&canvasModule.addImageFromUrl(response.image),$("#canvas-filepicker-form-student_image").hide()}})},addImageFromUrl:function(path){fabric.Image.fromURL(path,(function(object){object.set({left:150,top:100,angle:0,centerTransform:!0}).setCoords();var maxwidth=canvas.getWidth()/3;object.width>maxwidth&&object.scaleToWidth(maxwidth),canvas.add(object),canvas.setActiveObject(object)}))},selectToolbarImage:function(){var dialog=$("#image-picker");dialog.is(":visible")?dialog.hide():(dialog.show(),$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"get_toolbar_images",data:JSON.stringify({id:opts.id})},dataType:"json",success:function(response){if(debug.log(response),response.success){var html='
';$.each(response.images,(function(i,src){html+=' '})),html+=" ",dialog.html(html)}}}))},undo:function(){if(0!==bufferStep)try{var data=localStorage.getItem("buffer_"+bufferStep);canvas.loadFromJSON(data,canvas.renderAll.bind(canvas)),localStorage.removeItem("buffer_"+bufferStep),bufferStep--}catch(e){debug.log(e)}},loadToolbar:function(){this.setBackgroundImage(),this.loadDynamicToolbarMappingShapes(),this.loadColorPicker(),$("#clear").on("click",(function(){canvas.clear(),opts.hasHorizontalRuler&&canvasModule.addHorizontalRuler(),canvasModule.setBackgroundImage()})),$("#arrow i").on("click",(function(){canvasModule.loadArrowToCanvas()})),$("#trash i").on("click",(function(){canvasModule.deleteSelectedCanvasItems()})),$("#smiley i").on("click",(function(){canvasModule.loadEmojiPicker()})),$("#undo").on("click",(function(){bufferActive=!1,canvasModule.undo(),setTimeout((function(){bufferActive=!0}),500)})),$("#add-image i").on("click",(function(){canvasModule.showFileuploader("student_image")})),$("#select-a-image i").on("click",(function(){canvasModule.selectToolbarImage()})),$("#image-picker ").on("click","img",(function(){canvasModule.addImageFromUrl($(this).attr("src")),$("#image-picker").hide()})),$("#save-canvas").on("click",(function(){canvasModule.saveCanvasAjax()})),$("#show-help").on("click",(function(){$("#dialog-help").show()})),$("#dialog-help").on("click",(function(){$("#dialog-help").hide()})),$("#history").on("click",".delete",(function(e){e.preventDefault(),canvasModule.deleteAttempt($(this))})).on("click",".restore",(function(e){e.preventDefault(),canvasModule.restoreAttempt($(this))})),$("#emoji-picker").on("click","img",(function(){canvasModule.loadEmojiCsv($(this).attr("src")),$("#emoji-picker").hide()})),$("#change_background").on("click",(function(){canvasModule.showFileuploader("background")})),$("#add_toolbar_images").on("click",(function(){canvasModule.showFileuploader("toolbar_shape")})),$("#canvas-filepicker-form-student_image").on("click","#id_submitbutton",(function(e){e.preventDefault(),canvasModule.addUserImage()})),$(".dialog").on("click",".btn-secondary",(function(e){e.preventDefault(),debug.log("Cancel"),$(".dialog").hide()}))},loadEmojiPicker:function(){var $picker=$("#emoji-picker");if(""!==$picker.html())return debug.log("Toggle emoji"),void $picker.toggle();$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"emoji",data:JSON.stringify({id:opts.id})},dataType:"json",success:function(response){debug.log(response),response.success&&$picker.html(response.html).show()}})},loadArrowToCanvas:function(){fabric.loadSVGFromURL("pix/arrow.svg",(function(objects,options){var obj=fabric.util.groupSVGElements(objects,options);canvas.add(obj.scale(.1)).centerObject(obj).renderAll(),obj.setCoords(),canvas.setActiveObject(obj)}))},setColor:function(color){var colorhex=color.toHexString(),activeobjects=canvas.getActiveObjects();if(activeobjects){for(var i in activeobjects)if(activeobjects.hasOwnProperty(i)){var element=activeobjects[i];if(element.hasOwnProperty("id")&&"ruler"===element.id)continue;element.set("fill",colorhex)}canvas.renderAll()}else debug.log("No active items")},preventMovingOutOfCanvas:function(){canvas.on("object:moving",(function(e){var obj=e.target;obj.currentHeight>obj.canvas.height||obj.currentWidth>obj.canvas.width||(obj.setCoords(),(obj.getBoundingRect().top<0||obj.getBoundingRect().left<0)&&(obj.top=Math.max(obj.top,obj.top-obj.getBoundingRect().top),obj.left=Math.max(obj.left,obj.left-obj.getBoundingRect().left)),(obj.getBoundingRect().top+obj.getBoundingRect().height>obj.canvas.height||obj.getBoundingRect().left+obj.getBoundingRect().width>obj.canvas.width)&&(obj.top=Math.min(obj.top,obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top),obj.left=Math.min(obj.left,obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left)))}))},keyboardActions:function(){$(document).keydown((function(e){if(debug.log("keypress",e.which),46===e.which)canvasModule.deleteSelectedCanvasItems()}))},init:function(){this.__canvas=canvas=new fabric.Canvas("sketch"),$("body").on("contextmenu","canvas , img",(function(){return!1})),canvas.setHeight(this.canvasHeight),canvas.setWidth(this.canvasWidth-70),canvas.on({"selection:created":this.onchange,"selection:updated":this.onchange,"object:added":this.addToCache,"object:removed":this.addToCache,"object:modified":this.addToCache}),localStorage.clear(),this.preventMovingOutOfCanvas(),this.loadToolbar(),opts.hasHorizontalRuler&&this.addHorizontalRuler(),this.loadHistory(),this.keyboardActions()},addToCache:function(){debug.log("history"),canvasModule.addCanvasToCacheBuffer()},addCanvasToCacheBuffer:function(){bufferActive&&(clearTimeout(0),setTimeout((function(){try{bufferStep++,localStorage.setItem("buffer_"+bufferStep,JSON.stringify(canvas))}catch(e){debug.log(e)}}),500))},addHorizontalRuler:function(){var ruler=new fabric.Rect({width:this.canvasWidth,height:2,id:"ruler",left:0,top:410,angle:0,fill:"#8b58a1"});ruler.flipY=!1,ruler.lockMovementX=!0,ruler.lockScalingX=!0,ruler.lockScalingY=!0,ruler.lockUniScaling=!0,ruler.lockRotation=!0,canvas.add(ruler),canvas.renderAll(),$(document).keydown((function(e){switch(e.which){case 38:ruler.top=ruler.top-10,canvas.renderAll();break;case 40:ruler.top=ruler.top+10,canvas.renderAll();break;default:return}e.preventDefault()}))},onchange:function(options){options.target.hasOwnProperty("id")&&"ruler"===options.target.id||$("#colorpicker").spectrum("set",options.target.fill)}};return{initialise:function(args){$.getScript(M.cfg.wwwroot+"/mod/gcanvas/javascript/spectrum.js").done((function(){!function(options){var key,vartype;for(key in opts)opts.hasOwnProperty(key)&&options.hasOwnProperty(key)&&("boolean"==(vartype=typeof opts[key])?opts[key]=Boolean(options[key]):"number"===vartype?opts[key]=Number(options[key]):"string"===vartype&&(opts[key]=String(options[key])))}(args),function(isenabled){if(isenabled)for(var m in console)"function"==typeof console[m]&&(debug[m]=console[m].bind(window.console));else for(var i in console)"function"==typeof console[i]&&(debug[i]=function(){})}(opts.debugjs),$.noConflict(),$(document).ready((function(){debug.log("Canvas Module v1.2"),canvasModule.init()}))})).fail((function(jqxhr,settings,exception){debug.log(jqxhr),debug.log(settings),debug.log(exception)}))}}}));
+define("mod_gcanvas/canvas",["jquery","core/notification","mod_gcanvas/spectrum"],(function($,notification){var opts={id:0,debugjs:!1,hasHorizontalRuler:!0,background:""},debug={},bufferStep=0,bufferActive=!0,canvas=null,canvasModule={canvasWidth:800,canvasHeight:500,defaultShaperect:{width:70,height:70,left:200,top:50,angle:0,fill:"#ffb628"},defaultShapecircle:{radius:40,left:200,top:50,fill:"#b3cc2b"},defaultShapetriangle:{top:50,left:200,width:70,height:70,fill:"#0081b4"},defaultShapetextbox:{top:50,left:200,fill:"#0081b4"},loadHistory:function(){$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"load_history",data:JSON.stringify({id:opts.id})},dataType:"json",success:function(response){debug.log(response),response.success&&$("#history").html(response.html)},error:function(response){debug.error(response.responseText),notification.addNotification({message:response.responseText,type:"error"})}})},saveCanvasAjax:function(){fabric.Canvas.supports("toDataURL")?$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"save_canvas",data:JSON.stringify({id:opts.id,status:"final",canvas_data:canvas.toDataURL({multiplier:1,format:"png"}),json_data:JSON.stringify(canvas)})},dataType:"json",success:function(response){debug.log(response),response.success?(notification.addNotification({message:M.util.get_string("javascript:updated","mod_gcanvas"),type:"success"}),canvasModule.loadHistory()):notification.addNotification({message:response.error,type:"error"})},error:function(response){debug.error(response.responseText),notification.addNotification({message:response.responseText,type:"error"})}}):notification.addNotification({message:"This browser doesn't provide means to serialize canvas to an image",type:"error"})},deleteSelectedCanvasItems:function(){try{var activeobjects=canvas.getActiveObjects();if(activeobjects.length<=0)return void debug.log("Selection empty");for(var i in activeobjects)if(activeobjects.hasOwnProperty(i)){var element=activeobjects[i];if(void 0!==element.id&&"ruler"===element.id){debug.log("Ruler: Not removable!");continue}canvas.remove(element)}canvas.discardActiveObject().renderAll()}catch(e){debug.error("Nothing selected",e)}},loadDynamicToolbarMappingShapes:function(){$("#toolbar .icon[data-element-type]").on("click",(function(){var el,elementtype=$(this).data("element-type");try{canvas.discardActiveObject()}catch(e){}var shape="defaultShape"+elementtype.toLowerCase();debug.log("Search for shape: "+shape),canvasModule.hasOwnProperty(shape)?(debug.log("Shape found"),el="Textbox"===elementtype?new fabric[elementtype]("DEMO",canvasModule[shape]):new fabric[elementtype](canvasModule[shape]),canvas.add(el),canvas.setActiveObject(el)):debug.error("Shape not found!"),canvas.renderAll()}))},loadColorPicker:function(){$("#colorpicker").spectrum({showPalette:!0,palette:[],showSelectionPalette:!0,selectionPalette:["red","green","blue","orange"],flat:!1,change:function(color){debug.log("change color"),canvasModule.setColor(color)}}).on("dragstart.spectrum , dragstop.spectrum",(function(e,color){debug.log("change color - dragstop - dragstart"),canvasModule.setColor(color)}))},loadEmojiCsv:function(src){debug.log("loadEmojiCsv : ",src),fabric.Image.fromURL(src.replace(".png",".svg"),(function(object){object.set({height:500,width:500,left:150,top:100,angle:0,centerTransform:!0}).scale(.4).setCoords(),canvas.add(object),canvas.setActiveObject(object)}))},deleteAttempt:function($el){debug.log("Delete",$el),notification.confirm(M.util.get_string("javascript:confirm_title","mod_gcanvas"),M.util.get_string("javascript:confirm_desc","mod_gcanvas"),M.util.get_string("javascript:yes","mod_gcanvas"),M.util.get_string("javascript:no","mod_gcanvas"),(function(){$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"delete_attempt",data:JSON.stringify({id:opts.id,attempt_id:$el.data("id")})},dataType:"json",success:function(response){debug.log(response),response.success?canvasModule.loadHistory():notification.addNotification({message:response.error,type:"error"})},error:function(response){debug.error(response.responseText),notification.addNotification({message:response.responseText,type:"error"})}})}))},restoreAttempt:function($el){debug.log("Restore",$el),$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"get_attempt",data:JSON.stringify({id:opts.id,attempt_id:$el.data("id")})},dataType:"json",success:function(response){debug.log(response),response.success&&(bufferActive=!1,canvas.loadFromJSON(response.record.json_data,canvas.renderAll.bind(canvas)),setTimeout((function(){bufferActive=!0}),1e3))}})},showFileuploader:function(filearea){$("#canvas-filepicker-form-"+filearea).toggle()},setBackgroundImage:function(){""!==opts.background&&"false"!==opts.background&&fabric.Image.fromURL(opts.background,(function(img){canvas.setBackgroundImage(img,canvas.renderAll.bind(canvas),{scaleX:canvas.width/img.width,scaleY:canvas.height/img.height})}))},addUserImage:function(){var formdata={id:opts.id},inputs=$("#canvas-filepicker-form-student_image form").serializeArray();$.each(inputs,(function(i,input){formdata[input.name]=input.value})),$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"upload_images",data:JSON.stringify(formdata)},dataType:"json",success:function(response){debug.log(response),response.success&&canvasModule.addImageFromUrl(response.image),$("#canvas-filepicker-form-student_image").hide()}})},addImageFromUrl:function(path){fabric.Image.fromURL(path,(function(object){object.set({left:150,top:100,angle:0,centerTransform:!0}).setCoords();var maxwidth=canvas.getWidth()/3;object.width>maxwidth&&object.scaleToWidth(maxwidth),canvas.add(object),canvas.setActiveObject(object)}))},selectToolbarImage:function(){var dialog=$("#image-picker");dialog.is(":visible")?dialog.hide():(dialog.show(),$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"get_toolbar_images",data:JSON.stringify({id:opts.id})},dataType:"json",success:function(response){if(debug.log(response),response.success){var html='';$.each(response.images,(function(i,src){html+=' '})),html+=" ",dialog.html(html)}}}))},undo:function(){if(0!==bufferStep)try{var data=localStorage.getItem("buffer_"+bufferStep);canvas.loadFromJSON(data,canvas.renderAll.bind(canvas)),localStorage.removeItem("buffer_"+bufferStep),bufferStep--}catch(e){debug.log(e)}},loadToolbar:function(){this.setBackgroundImage(),this.loadDynamicToolbarMappingShapes(),this.loadColorPicker(),$("#clear").on("click",(function(){canvas.clear(),opts.hasHorizontalRuler&&canvasModule.addHorizontalRuler(),canvasModule.setBackgroundImage()})),$("#arrow i").on("click",(function(){canvasModule.loadArrowToCanvas()})),$("#trash i").on("click",(function(){canvasModule.deleteSelectedCanvasItems()})),$("#smiley i").on("click",(function(){canvasModule.loadEmojiPicker()})),$("#undo").on("click",(function(){bufferActive=!1,canvasModule.undo(),setTimeout((function(){bufferActive=!0}),500)})),$("#add-image i").on("click",(function(){canvasModule.showFileuploader("student_image")})),$("#select-a-image i").on("click",(function(){canvasModule.selectToolbarImage()})),$("#image-picker ").on("click","img",(function(){canvasModule.addImageFromUrl($(this).attr("src")),$("#image-picker").hide()})),$("#save-canvas").on("click",(function(){canvasModule.saveCanvasAjax()})),$("#show-help").on("click",(function(){$("#dialog-help").show()})),$("#dialog-help").on("click",(function(){$("#dialog-help").hide()})),$("#history").on("click",".delete",(function(e){e.preventDefault(),canvasModule.deleteAttempt($(this))})).on("click",".restore",(function(e){e.preventDefault(),canvasModule.restoreAttempt($(this))})),$("#emoji-picker").on("click","img",(function(){canvasModule.loadEmojiCsv($(this).attr("src")),$("#emoji-picker").hide()})),$("#change_background").on("click",(function(){canvasModule.showFileuploader("background")})),$("#add_toolbar_images").on("click",(function(){canvasModule.showFileuploader("toolbar_shape")})),$("#canvas-filepicker-form-student_image").on("click","#id_submitbutton",(function(e){e.preventDefault(),canvasModule.addUserImage()})),$(".dialog").on("click",".btn-secondary",(function(e){e.preventDefault(),debug.log("Cancel"),$(".dialog").hide()}))},loadEmojiPicker:function(){var $picker=$("#emoji-picker");if(""!==$picker.html())return debug.log("Toggle emoji"),void $picker.toggle();$.ajax({type:"POST",url:M.cfg.wwwroot+"/mod/gcanvas/ajax.php",data:{sesskey:M.cfg.sesskey,action:"emoji",data:JSON.stringify({id:opts.id})},dataType:"json",success:function(response){debug.log(response),response.success&&$picker.html(response.html).show()}})},loadArrowToCanvas:function(){fabric.loadSVGFromURL("pix/arrow.svg",(function(objects,options){var obj=fabric.util.groupSVGElements(objects,options);canvas.add(obj.scale(.1)).centerObject(obj).renderAll(),obj.setCoords(),canvas.setActiveObject(obj)}))},setColor:function(color){var colorhex=color.toHexString(),activeobjects=canvas.getActiveObjects();if(activeobjects){for(var i in activeobjects)if(activeobjects.hasOwnProperty(i)){var element=activeobjects[i];if(element.hasOwnProperty("id")&&"ruler"===element.id)continue;element.set("fill",colorhex)}canvas.renderAll()}else debug.log("No active items")},preventMovingOutOfCanvas:function(){canvas.on("object:moving",(function(e){var obj=e.target;obj.currentHeight>obj.canvas.height||obj.currentWidth>obj.canvas.width||(obj.setCoords(),(obj.getBoundingRect().top<0||obj.getBoundingRect().left<0)&&(obj.top=Math.max(obj.top,obj.top-obj.getBoundingRect().top),obj.left=Math.max(obj.left,obj.left-obj.getBoundingRect().left)),(obj.getBoundingRect().top+obj.getBoundingRect().height>obj.canvas.height||obj.getBoundingRect().left+obj.getBoundingRect().width>obj.canvas.width)&&(obj.top=Math.min(obj.top,obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top),obj.left=Math.min(obj.left,obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left)))}))},keyboardActions:function(){$(document).keydown((function(e){if(debug.log("keypress",e.which),46===e.which)canvasModule.deleteSelectedCanvasItems()}))},init:function(){this.__canvas=canvas=new fabric.Canvas("sketch"),$("body").on("contextmenu","canvas , img",(function(){return!1})),canvas.setHeight(this.canvasHeight),canvas.setWidth(this.canvasWidth-70),canvas.on({"selection:created":this.onchange,"selection:updated":this.onchange,"object:added":this.addToCache,"object:removed":this.addToCache,"object:modified":this.addToCache}),localStorage.clear(),this.preventMovingOutOfCanvas(),this.loadToolbar(),opts.hasHorizontalRuler&&this.addHorizontalRuler(),this.loadHistory(),this.keyboardActions()},addToCache:function(){debug.log("history"),canvasModule.addCanvasToCacheBuffer()},addCanvasToCacheBuffer:function(){bufferActive&&(clearTimeout(0),setTimeout((function(){try{bufferStep++,localStorage.setItem("buffer_"+bufferStep,JSON.stringify(canvas))}catch(e){debug.log(e)}}),500))},addHorizontalRuler:function(){var ruler=new fabric.Rect({width:this.canvasWidth,height:2,id:"ruler",left:0,top:410,angle:0,fill:"#8b58a1"});ruler.flipY=!1,ruler.lockMovementX=!0,ruler.lockScalingX=!0,ruler.lockScalingY=!0,ruler.lockUniScaling=!0,ruler.lockRotation=!0,canvas.add(ruler),canvas.renderAll(),$(document).keydown((function(e){switch(e.which){case 38:ruler.top=ruler.top-10,canvas.renderAll();break;case 40:ruler.top=ruler.top+10,canvas.renderAll();break;default:return}e.preventDefault()}))},onchange:function(options){options.target.hasOwnProperty("id")&&"ruler"===options.target.id||$("#colorpicker").spectrum("set",options.target.fill)}};return{initialise:function(args){!function(options){var key,vartype;for(key in opts)opts.hasOwnProperty(key)&&options.hasOwnProperty(key)&&("boolean"==(vartype=typeof opts[key])?opts[key]=Boolean(options[key]):"number"===vartype?opts[key]=Number(options[key]):"string"===vartype&&(opts[key]=String(options[key])))}(args),function(isenabled){if(isenabled)for(var m in console)"function"==typeof console[m]&&(debug[m]=console[m].bind(window.console));else for(var i in console)"function"==typeof console[i]&&(debug[i]=function(){})}(opts.debugjs),$.noConflict(),$(document).ready((function(){debug.log("Canvas Module v1.2"),canvasModule.init()}))}}}));
//# sourceMappingURL=canvas.min.js.map
\ No newline at end of file
diff --git a/amd/build/canvas.min.js.map b/amd/build/canvas.min.js.map
index 285c894..7c9808f 100644
--- a/amd/build/canvas.min.js.map
+++ b/amd/build/canvas.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"canvas.min.js","sources":["../src/canvas.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 * JS Canvas\n *\n * Tested in Moodle 3.9\n *\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n * @copyright 2018 MFreak.nl\n * @author Luuk Verhoeven\n **/\n/* global fabric */\n/* eslint no-unused-expressions: \"off\", no-console:off, no-invalid-this:\"off\",no-script-url:\"off\", block-scoped-var: \"off\" */\ndefine(['jquery', 'core/notification'], function($, notification) {\n 'use strict';\n\n /**\n * Possible options\n * @type {{id: number, debugjs: boolean, hasHorizontalRuler: boolean, background: string}}\n */\n var opts = {\n id: 0,\n debugjs: false,\n hasHorizontalRuler: true,\n background: '',\n };\n\n /**\n * Set options base on listed options\n * @param {object} options\n */\n var setOptions = function(options) {\n \"use strict\";\n var key, vartype;\n for (key in opts) {\n if (opts.hasOwnProperty(key) && options.hasOwnProperty(key)) {\n\n // Casting to prevent errors.\n vartype = typeof opts[key];\n if (vartype === \"boolean\") {\n opts[key] = Boolean(options[key]);\n } else if (vartype === 'number') {\n opts[key] = Number(options[key]);\n } else if (vartype === 'string') {\n opts[key] = String(options[key]);\n }\n // Skip all other types.\n }\n }\n };\n\n /**\n * Console log debug wrapper.\n */\n var debug = {};\n\n /**\n * Local history/cache buffer\n * @type {number}\n */\n var bufferStep = 0;\n\n /**\n *\n * @type {number}\n */\n var bufferTimer = 0;\n\n /**\n * Should we store changes to localstorage\n * @type {boolean}\n */\n var bufferActive = true;\n\n /**\n * Set debug mode\n * Should only be enabled if site is in debug mode.\n * @param {boolean} isenabled\n */\n var setDebug = function(isenabled) {\n\n if (isenabled) {\n for (var m in console) {\n if (typeof console[m] == 'function') {\n debug[m] = console[m].bind(window.console);\n }\n }\n } else {\n // Fake wrapper.\n for (var i in console) {\n if (typeof console[i] == 'function') {\n debug[i] = function() {\n // Don't do anything.\n };\n }\n }\n }\n };\n\n /**\n * Canvas holder.\n * @type fabric.Canvas\n */\n var canvas = null;\n\n /**\n * Module canvas wrapper.\n */\n var canvasModule = {\n\n /**\n * @type int\n */\n canvasWidth: 800,\n\n /**\n * @type int\n */\n canvasHeight: 500,\n\n /**\n * Default rectangle.\n */\n defaultShaperect: {\n width: 70,\n height: 70,\n left: 200,\n top: 50,\n angle: 0,\n fill: '#ffb628'\n },\n\n /**\n * Default circle.\n */\n defaultShapecircle: {\n radius: 40,\n left: 200,\n top: 50,\n fill: '#b3cc2b'\n },\n\n /**\n * Default triangle.\n */\n defaultShapetriangle: {\n top: 50,\n left: 200,\n width: 70,\n height: 70,\n fill: '#0081b4'\n },\n\n /**\n * Default text.\n */\n defaultShapetextbox: {\n top: 50,\n left: 200,\n fill: '#0081b4'\n },\n\n /**\n * Load user there history.\n */\n loadHistory: function() {\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'load_history',\n data: JSON.stringify({\n 'id': opts.id,\n }),\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n if (response.success) {\n $('#history').html(response.html);\n }\n },\n error: function(response) {\n debug.error(response.responseText);\n // Show a error messages.\n notification.addNotification({\n message: response.responseText,\n type: \"error\"\n });\n }\n });\n },\n\n /**\n * Save the current canvas.\n */\n saveCanvasAjax: function() {\n // Canvas to image.\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL\n if (!fabric.Canvas.supports('toDataURL')) {\n\n notification.addNotification({\n message: 'This browser doesn\\'t provide means to serialize canvas to an image',\n type: \"error\"\n });\n\n } else {\n\n // Send data to AJAX.\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'save_canvas',\n data: JSON.stringify({\n 'id': opts.id,\n 'status': 'final',\n 'canvas_data': canvas.toDataURL({\n multiplier: 1,\n format: 'png'\n }),\n 'json_data': JSON.stringify(canvas)\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n notification.addNotification({\n message: M.util.get_string('javascript:updated', 'mod_gcanvas'),\n type: \"success\",\n });\n\n // Load attempts.\n canvasModule.loadHistory();\n\n } else {\n notification.addNotification({\n message: response.error,\n type: \"error\"\n });\n }\n },\n error: function(response) {\n debug.error(response.responseText);\n // Show a error messages.\n notification.addNotification({\n message: response.responseText,\n type: \"error\"\n });\n }\n });\n }\n },\n\n /**\n * Trash selected canvas items.\n */\n deleteSelectedCanvasItems: function() {\n try {\n var activeobjects = canvas.getActiveObjects();\n if (activeobjects.length <= 0) {\n debug.log('Selection empty');\n return;\n }\n\n for (var i in activeobjects) {\n if (activeobjects.hasOwnProperty(i)) {\n var element = activeobjects[i];\n\n if (element.id !== undefined && element.id === 'ruler') {\n debug.log('Ruler: Not removable!');\n continue;\n }\n\n canvas.remove(element);\n }\n }\n\n canvas.discardActiveObject().renderAll();\n\n } catch (e) {\n debug.error('Nothing selected', e);\n }\n },\n\n /**\n * Dynamic method for selecting a shape.\n */\n loadDynamicToolbarMappingShapes: function() {\n\n $('#toolbar .icon[data-element-type]').on('click', function() {\n var el;\n var elementtype = $(this).data('element-type');\n\n try {\n canvas.discardActiveObject();\n } catch (e) {\n // If nothing is added to the canvas this gives a error.\n }\n\n var shape = \"defaultShape\" + elementtype.toLowerCase();\n debug.log(\"Search for shape: \" + shape);\n\n if (canvasModule.hasOwnProperty(shape)) {\n debug.log(\"Shape found\");\n\n if (elementtype === 'Textbox') {\n el = new fabric[elementtype]('DEMO', canvasModule[shape]);\n } else {\n el = new fabric[elementtype](canvasModule[shape]);\n }\n\n canvas.add(el);\n canvas.setActiveObject(el);\n } else {\n debug.error('Shape not found!');\n }\n\n canvas.renderAll();\n });\n },\n\n /**\n * Colorpicker used for changing the color of a shape.\n */\n loadColorPicker: function() {\n $(\"#colorpicker\").spectrum({\n showPalette: true,\n palette: [],\n showSelectionPalette: true,\n selectionPalette: [\"red\", \"green\", \"blue\", \"orange\"],\n flat: false,\n change: function(color) {\n debug.log('change color');\n canvasModule.setColor(color);\n }\n }).on(\"dragstart.spectrum , dragstop.spectrum\", function(e, color) {\n debug.log('change color - dragstop - dragstart');\n canvasModule.setColor(color);\n }\n );\n },\n\n /**\n * Using svg making sure it looks nice.\n *\n * @param {string} src\n */\n loadEmojiCsv: function(src) {\n debug.log('loadEmojiCsv : ', src);\n // Issue when using loadsvgfromurl.\n fabric.Image.fromURL(src.replace('.png', '.svg'), function(object) {\n // Logic below needed to work with the svg files.\n object.set({\n height: 500,\n width: 500,\n left: 150,\n top: 100,\n angle: 0,\n centerTransform: true\n }).scale(0.4).setCoords();\n canvas.add(object);\n canvas.setActiveObject(object);\n });\n },\n\n /**\n * Delete a attempt/sketch\n * TODO we could better use amd Ajax helper Moodle and external webservice, for now this is okay.\n *\n * @param {jQuery} $el\n */\n deleteAttempt: function($el) {\n debug.log('Delete', $el);\n notification.confirm(\n M.util.get_string('javascript:confirm_title', 'mod_gcanvas'),\n M.util.get_string('javascript:confirm_desc', 'mod_gcanvas'),\n M.util.get_string('javascript:yes', 'mod_gcanvas'),\n M.util.get_string('javascript:no', 'mod_gcanvas'), function() {\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'delete_attempt',\n data: JSON.stringify({\n 'id': opts.id,\n 'attempt_id': $el.data('id'),\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n // Load attempts.\n canvasModule.loadHistory();\n\n } else {\n notification.addNotification({\n message: response.error,\n type: \"error\"\n });\n }\n },\n error: function(response) {\n debug.error(response.responseText);\n // Show a error messages.\n notification.addNotification({\n message: response.responseText,\n type: \"error\"\n });\n }\n });\n });\n },\n\n /**\n * Restore a attempt/sketch\n *\n * @param {jQuery} $el\n */\n restoreAttempt: function($el) {\n debug.log('Restore', $el);\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'get_attempt',\n data: JSON.stringify({\n 'id': opts.id,\n 'attempt_id': $el.data('id'),\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n bufferActive = false;\n\n canvas.loadFromJSON(response.record.json_data, canvas.renderAll.bind(canvas));\n\n setTimeout(function() {\n bufferActive = true;\n }, 1000);\n }\n }\n });\n },\n\n /**\n * Show the fileuploader.\n *\n * @param {string} filearea\n */\n showFileuploader: function(filearea) {\n $('#canvas-filepicker-form-' + filearea).toggle();\n },\n\n /**\n * Set background of the canvas.\n */\n setBackgroundImage: function() {\n\n if (opts.background !== '' && opts.background !== 'false') {\n fabric.Image.fromURL(opts.background, function(img) {\n // Add background image.\n canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {\n scaleX: canvas.width / img.width,\n scaleY: canvas.height / img.height\n });\n });\n }\n },\n\n /**\n * Add user image.\n */\n addUserImage: function() {\n var formdata = {'id': opts.id},\n inputs = $('#canvas-filepicker-form-student_image form').serializeArray();\n\n $.each(inputs, function(i, input) {\n formdata[input.name] = input.value;\n });\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'upload_images',\n data: JSON.stringify(formdata)\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n canvasModule.addImageFromUrl(response.image);\n }\n $('#canvas-filepicker-form-student_image').hide();\n }\n });\n },\n\n /**\n * Add image from url\n * TODO SVG support.\n * @param {string} path\n */\n addImageFromUrl: function(path) {\n\n fabric.Image.fromURL(path, function(object) {\n object.set({\n left: 150,\n top: 100,\n angle: 0,\n centerTransform: true\n }).setCoords();\n\n // Prevent to large objects.\n var maxwidth = canvas.getWidth() / 3;\n\n if (object.width > maxwidth) {\n object.scaleToWidth(maxwidth);\n }\n\n canvas.add(object);\n canvas.setActiveObject(object);\n });\n },\n\n /**\n * Select toolbar images.\n */\n selectToolbarImage: function() {\n var dialog = $('#image-picker');\n if (dialog.is(':visible')) {\n dialog.hide();\n return;\n }\n dialog.show();\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'get_toolbar_images',\n data: JSON.stringify({\n 'id': opts.id,\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n var html = '';\n $.each(response.images, function(i, src) {\n html += ' ';\n });\n html += ' ';\n\n dialog.html(html);\n }\n }\n });\n },\n\n /**\n * Undo 1 canvas step.\n */\n undo: function() {\n\n if (bufferStep === 0) {\n return;\n }\n try {\n var data = localStorage.getItem('buffer_' + bufferStep);\n canvas.loadFromJSON(data, canvas.renderAll.bind(canvas));\n\n localStorage.removeItem('buffer_' + bufferStep);\n\n bufferStep--;\n } catch (e) {\n debug.log(e);\n }\n },\n\n /**\n * Toolbar actions.\n */\n loadToolbar: function() {\n\n this.setBackgroundImage();\n\n // Most shapes will be placed on canvas by this function.\n this.loadDynamicToolbarMappingShapes();\n\n // Color picker.\n this.loadColorPicker();\n\n // Clear canvas items.\n $('#clear').on('click', function() {\n canvas.clear();\n\n if (opts.hasHorizontalRuler) {\n canvasModule.addHorizontalRuler();\n }\n\n canvasModule.setBackgroundImage();\n });\n\n // Arrow.\n $('#arrow i').on('click', function() {\n canvasModule.loadArrowToCanvas();\n });\n\n // Remove selected items.\n $('#trash i').on('click', function() {\n canvasModule.deleteSelectedCanvasItems();\n });\n\n // Load emoji picker.\n $('#smiley i').on('click', function() {\n canvasModule.loadEmojiPicker();\n });\n\n $('#undo').on('click', function() {\n bufferActive = false;\n canvasModule.undo();\n\n setTimeout(function() {\n bufferActive = true;\n }, 500);\n });\n\n // Add own image to the canvas.\n $('#add-image i').on('click', function() {\n canvasModule.showFileuploader('student_image');\n });\n\n // Student selecting a image, added to the toolbar by teachers.\n $('#select-a-image i').on('click', function() {\n canvasModule.selectToolbarImage();\n });\n\n $('#image-picker ').on('click', 'img', function() {\n canvasModule.addImageFromUrl($(this).attr('src'));\n $('#image-picker').hide();\n });\n\n $('#save-canvas').on('click', function() {\n canvasModule.saveCanvasAjax();\n });\n\n $('#show-help').on('click', function() {\n $('#dialog-help').show();\n });\n\n $('#dialog-help').on('click', function() {\n $('#dialog-help').hide();\n });\n\n $('#history').on('click', '.delete', function(e) {\n e.preventDefault();\n canvasModule.deleteAttempt($(this));\n\n }).on('click', '.restore', function(e) {\n\n e.preventDefault();\n canvasModule.restoreAttempt($(this));\n\n });\n\n // Dialog to selected a emoji.\n $('#emoji-picker').on('click', 'img', function() {\n canvasModule.loadEmojiCsv($(this).attr('src'));\n $('#emoji-picker').hide();\n });\n\n // Teacher background.\n $('#change_background').on('click', function() {\n canvasModule.showFileuploader('background');\n });\n\n // Teacher image.\n $('#add_toolbar_images').on('click', function() {\n canvasModule.showFileuploader('toolbar_shape');\n });\n\n $('#canvas-filepicker-form-student_image').on('click', '#id_submitbutton', function(e) {\n e.preventDefault();\n\n // Form should be posted to AJAX call so we can get the image.\n canvasModule.addUserImage();\n });\n\n // Hide pressing on cancel.\n $('.dialog').on('click', '.btn-secondary', function(e) {\n e.preventDefault();\n debug.log('Cancel');\n $('.dialog').hide();\n });\n },\n\n /**\n * Emoji dialog\n */\n loadEmojiPicker: function() {\n var $picker = $('#emoji-picker');\n if ($picker.html() !== '') {\n debug.log('Toggle emoji');\n $picker.toggle();\n return;\n }\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'emoji',\n data: JSON.stringify({\n 'id': opts.id,\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n $picker.html(response.html).show();\n }\n }\n });\n },\n\n /**\n * Load the arrow icon to the canvas.\n */\n loadArrowToCanvas: function() {\n fabric.loadSVGFromURL('pix/arrow.svg', function(objects, options) {\n var obj = fabric.util.groupSVGElements(objects, options);\n canvas.add(obj.scale(0.1)).centerObject(obj).renderAll();\n obj.setCoords();\n canvas.setActiveObject(obj);\n });\n },\n\n /**\n * Set active element colors.\n * @param {object} color\n */\n setColor: function(color) {\n\n var colorhex = color.toHexString(); // #ff0000\n var activeobjects = canvas.getActiveObjects();\n if (activeobjects) {\n\n for (var i in activeobjects) {\n if (activeobjects.hasOwnProperty(i)) {\n var element = activeobjects[i];\n\n if (element.hasOwnProperty('id') && element.id === 'ruler') {\n continue;\n }\n\n element.set(\"fill\", colorhex);\n }\n }\n\n canvas.renderAll();\n } else {\n debug.log('No active items');\n }\n },\n\n /**\n * Don't allow going out of canvas.\n */\n preventMovingOutOfCanvas: function() {\n canvas.on('object:moving', function(e) {\n var obj = e.target;\n // If object is too big ignore.\n if (obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width) {\n return;\n }\n obj.setCoords();\n\n if (obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0) {\n obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top);\n obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left);\n }\n\n if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height ||\n obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width) {\n obj.top = Math.min(obj.top, obj.canvas.height - obj.getBoundingRect().height + obj.top -\n obj.getBoundingRect().top);\n obj.left = Math.min(obj.left, obj.canvas.width - obj.getBoundingRect().width + obj.left -\n obj.getBoundingRect().left);\n }\n });\n },\n\n /**\n * Trigger for extra keyboard commands.\n */\n keyboardActions: function() {\n $(document).keydown(function(e) {\n debug.log('keypress', e.which);\n switch (e.which) {\n case 46:\n canvasModule.deleteSelectedCanvasItems();\n break;\n }\n });\n },\n\n /**\n * Start this module.\n */\n init: function() {\n\n // Load canvas.\n this.__canvas = canvas = new fabric.Canvas('sketch');\n\n // Prevent right click.\n $('body').on('contextmenu', 'canvas , img', function() {\n return false;\n });\n\n // Dimensions.\n canvas.setHeight(this.canvasHeight);\n canvas.setWidth(this.canvasWidth - 70);\n\n // Catch some actions.\n canvas.on({\n 'selection:created': this.onchange,\n 'selection:updated': this.onchange,\n\n // 'object:moving' : this.add_to_history,\n 'object:added': this.addToCache,\n 'object:removed': this.addToCache,\n 'object:modified': this.addToCache,\n });\n\n // Make sure we start with a empty storage.\n localStorage.clear();\n\n this.preventMovingOutOfCanvas();\n\n this.loadToolbar();\n\n if (opts.hasHorizontalRuler) {\n this.addHorizontalRuler();\n }\n\n this.loadHistory();\n\n this.keyboardActions();\n },\n\n /**\n * Keep a history/cache buffer.\n */\n addToCache: function() {\n debug.log('history');\n canvasModule.addCanvasToCacheBuffer();\n },\n\n /**\n * Add canvas to local storage.\n */\n addCanvasToCacheBuffer: function() {\n // When undo there lot of modified events we doesnt want to trigger if thats the case.\n if (!bufferActive) {\n return;\n }\n\n clearTimeout(bufferTimer);\n setTimeout(function() {\n try {\n bufferStep++;\n localStorage.setItem('buffer_' + bufferStep, JSON.stringify(canvas));\n } catch (e) {\n debug.log(e);\n }\n }, 500);\n },\n\n /**\n * Horizontal ruler.\n */\n addHorizontalRuler: function() {\n var ruler = new fabric.Rect({\n width: this.canvasWidth,\n height: 2,\n id: 'ruler',\n left: 0,\n top: 410,\n angle: 0,\n fill: '#8b58a1'\n });\n\n ruler.flipY = false;\n ruler.lockMovementX = true;\n ruler.lockScalingX = true;\n ruler.lockScalingY = true;\n ruler.lockUniScaling = true;\n ruler.lockRotation = true;\n\n canvas.add(ruler);\n canvas.renderAll();\n\n // Keyboard arrows move ruler.\n $(document).keydown(function(e) {\n switch (e.which) {\n\n case 38: // Up arrow.\n ruler.top = ruler.top - 10;\n canvas.renderAll();\n break;\n\n case 40: // Down arrow.\n ruler.top = ruler.top + 10;\n canvas.renderAll();\n\n break;\n\n default:\n return; // Exit this handler for other keys.\n }\n e.preventDefault(); // Prevent the default action (scroll / move caret).\n });\n },\n\n /**\n * Trigger on canvas element actions.\n * @param {object} options\n */\n onchange: function(options) {\n if (options.target.hasOwnProperty('id') && options.target.id === 'ruler') {\n return;\n }\n\n $(\"#colorpicker\").spectrum(\"set\", options.target.fill);\n }\n };\n\n return {\n\n /**\n * Init\n * @param {object} args\n */\n initialise: function(args) {\n\n // Load spectrum javascript form here.\n $.getScript(M.cfg.wwwroot + \"/mod/gcanvas/javascript/spectrum.js\").done(function() {\n\n // Load the args passed from PHP.\n setOptions(args);\n\n // Set internal debug console.\n setDebug(opts.debugjs);\n\n $.noConflict();\n $(document).ready(function() {\n debug.log('Canvas Module v1.2');\n canvasModule.init();\n });\n }).fail(function(jqxhr, settings, exception) {\n // Display loading issue in console.\n debug.log(jqxhr);\n debug.log(settings);\n debug.log(exception);\n });\n }\n };\n});\n"],"names":["define","$","notification","opts","id","debugjs","hasHorizontalRuler","background","debug","bufferStep","bufferActive","canvas","canvasModule","canvasWidth","canvasHeight","defaultShaperect","width","height","left","top","angle","fill","defaultShapecircle","radius","defaultShapetriangle","defaultShapetextbox","loadHistory","ajax","type","url","M","cfg","wwwroot","data","sesskey","action","JSON","stringify","dataType","success","response","log","html","error","responseText","addNotification","message","saveCanvasAjax","fabric","Canvas","supports","toDataURL","multiplier","format","util","get_string","deleteSelectedCanvasItems","activeobjects","getActiveObjects","length","i","hasOwnProperty","element","undefined","remove","discardActiveObject","renderAll","e","loadDynamicToolbarMappingShapes","on","el","elementtype","this","shape","toLowerCase","add","setActiveObject","loadColorPicker","spectrum","showPalette","palette","showSelectionPalette","selectionPalette","flat","change","color","setColor","loadEmojiCsv","src","Image","fromURL","replace","object","set","centerTransform","scale","setCoords","deleteAttempt","$el","confirm","restoreAttempt","loadFromJSON","record","json_data","bind","setTimeout","showFileuploader","filearea","toggle","setBackgroundImage","img","scaleX","scaleY","addUserImage","formdata","inputs","serializeArray","each","input","name","value","addImageFromUrl","image","hide","path","maxwidth","getWidth","scaleToWidth","selectToolbarImage","dialog","is","show","images","undo","localStorage","getItem","removeItem","loadToolbar","clear","addHorizontalRuler","loadArrowToCanvas","loadEmojiPicker","attr","preventDefault","$picker","loadSVGFromURL","objects","options","obj","groupSVGElements","centerObject","colorhex","toHexString","preventMovingOutOfCanvas","target","currentHeight","currentWidth","getBoundingRect","Math","max","min","keyboardActions","document","keydown","which","init","__canvas","setHeight","setWidth","onchange","addToCache","addCanvasToCacheBuffer","clearTimeout","setItem","ruler","Rect","flipY","lockMovementX","lockScalingX","lockScalingY","lockUniScaling","lockRotation","initialise","args","getScript","done","key","vartype","Boolean","Number","String","setOptions","isenabled","m","console","window","setDebug","noConflict","ready","fail","jqxhr","settings","exception"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"canvas.min.js","sources":["../src/canvas.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 * JS Canvas\n *\n * Tested in Moodle 3.9\n *\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n * @copyright 2018 MFreak.nl\n * @author Luuk Verhoeven\n **/\n/* global fabric */\n/* eslint no-unused-expressions: \"off\", no-console:off, no-invalid-this:\"off\",no-script-url:\"off\", block-scoped-var: \"off\" */\ndefine(['jquery', 'core/notification', 'mod_gcanvas/spectrum'], function ($, notification) {\n 'use strict';\n\n /**\n * Possible options\n * @type {{id: number, debugjs: boolean, hasHorizontalRuler: boolean, background: string}}\n */\n var opts = {\n id: 0,\n debugjs: false,\n hasHorizontalRuler: true,\n background: '',\n };\n\n /**\n * Set options base on listed options\n * @param {object} options\n */\n var setOptions = function(options) {\n \"use strict\";\n var key, vartype;\n for (key in opts) {\n if (opts.hasOwnProperty(key) && options.hasOwnProperty(key)) {\n\n // Casting to prevent errors.\n vartype = typeof opts[key];\n if (vartype === \"boolean\") {\n opts[key] = Boolean(options[key]);\n } else if (vartype === 'number') {\n opts[key] = Number(options[key]);\n } else if (vartype === 'string') {\n opts[key] = String(options[key]);\n }\n // Skip all other types.\n }\n }\n };\n\n /**\n * Console log debug wrapper.\n */\n var debug = {};\n\n /**\n * Local history/cache buffer\n * @type {number}\n */\n var bufferStep = 0;\n\n /**\n *\n * @type {number}\n */\n var bufferTimer = 0;\n\n /**\n * Should we store changes to localstorage\n * @type {boolean}\n */\n var bufferActive = true;\n\n /**\n * Set debug mode\n * Should only be enabled if site is in debug mode.\n * @param {boolean} isenabled\n */\n var setDebug = function(isenabled) {\n\n if (isenabled) {\n for (var m in console) {\n if (typeof console[m] == 'function') {\n debug[m] = console[m].bind(window.console);\n }\n }\n } else {\n // Fake wrapper.\n for (var i in console) {\n if (typeof console[i] == 'function') {\n debug[i] = function() {\n // Don't do anything.\n };\n }\n }\n }\n };\n\n /**\n * Canvas holder.\n * @type fabric.Canvas\n */\n var canvas = null;\n\n /**\n * Module canvas wrapper.\n */\n var canvasModule = {\n\n /**\n * @type int\n */\n canvasWidth: 800,\n\n /**\n * @type int\n */\n canvasHeight: 500,\n\n /**\n * Default rectangle.\n */\n defaultShaperect: {\n width: 70,\n height: 70,\n left: 200,\n top: 50,\n angle: 0,\n fill: '#ffb628'\n },\n\n /**\n * Default circle.\n */\n defaultShapecircle: {\n radius: 40,\n left: 200,\n top: 50,\n fill: '#b3cc2b'\n },\n\n /**\n * Default triangle.\n */\n defaultShapetriangle: {\n top: 50,\n left: 200,\n width: 70,\n height: 70,\n fill: '#0081b4'\n },\n\n /**\n * Default text.\n */\n defaultShapetextbox: {\n top: 50,\n left: 200,\n fill: '#0081b4'\n },\n\n /**\n * Load user there history.\n */\n loadHistory: function() {\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'load_history',\n data: JSON.stringify({\n 'id': opts.id,\n }),\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n if (response.success) {\n $('#history').html(response.html);\n }\n },\n error: function(response) {\n debug.error(response.responseText);\n // Show a error messages.\n notification.addNotification({\n message: response.responseText,\n type: \"error\"\n });\n }\n });\n },\n\n /**\n * Save the current canvas.\n */\n saveCanvasAjax: function() {\n // Canvas to image.\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL\n if (!fabric.Canvas.supports('toDataURL')) {\n\n notification.addNotification({\n message: 'This browser doesn\\'t provide means to serialize canvas to an image',\n type: \"error\"\n });\n\n } else {\n\n // Send data to AJAX.\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'save_canvas',\n data: JSON.stringify({\n 'id': opts.id,\n 'status': 'final',\n 'canvas_data': canvas.toDataURL({\n multiplier: 1,\n format: 'png'\n }),\n 'json_data': JSON.stringify(canvas)\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n notification.addNotification({\n message: M.util.get_string('javascript:updated', 'mod_gcanvas'),\n type: \"success\",\n });\n\n // Load attempts.\n canvasModule.loadHistory();\n\n } else {\n notification.addNotification({\n message: response.error,\n type: \"error\"\n });\n }\n },\n error: function(response) {\n debug.error(response.responseText);\n // Show a error messages.\n notification.addNotification({\n message: response.responseText,\n type: \"error\"\n });\n }\n });\n }\n },\n\n /**\n * Trash selected canvas items.\n */\n deleteSelectedCanvasItems: function() {\n try {\n var activeobjects = canvas.getActiveObjects();\n if (activeobjects.length <= 0) {\n debug.log('Selection empty');\n return;\n }\n\n for (var i in activeobjects) {\n if (activeobjects.hasOwnProperty(i)) {\n var element = activeobjects[i];\n\n if (element.id !== undefined && element.id === 'ruler') {\n debug.log('Ruler: Not removable!');\n continue;\n }\n\n canvas.remove(element);\n }\n }\n\n canvas.discardActiveObject().renderAll();\n\n } catch (e) {\n debug.error('Nothing selected', e);\n }\n },\n\n /**\n * Dynamic method for selecting a shape.\n */\n loadDynamicToolbarMappingShapes: function() {\n\n $('#toolbar .icon[data-element-type]').on('click', function() {\n var el;\n var elementtype = $(this).data('element-type');\n\n try {\n canvas.discardActiveObject();\n } catch (e) {\n // If nothing is added to the canvas this gives a error.\n }\n\n var shape = \"defaultShape\" + elementtype.toLowerCase();\n debug.log(\"Search for shape: \" + shape);\n\n if (canvasModule.hasOwnProperty(shape)) {\n debug.log(\"Shape found\");\n\n if (elementtype === 'Textbox') {\n el = new fabric[elementtype]('DEMO', canvasModule[shape]);\n } else {\n el = new fabric[elementtype](canvasModule[shape]);\n }\n\n canvas.add(el);\n canvas.setActiveObject(el);\n } else {\n debug.error('Shape not found!');\n }\n\n canvas.renderAll();\n });\n },\n\n /**\n * Colorpicker used for changing the color of a shape.\n */\n loadColorPicker: function() {\n $(\"#colorpicker\").spectrum({\n showPalette: true,\n palette: [],\n showSelectionPalette: true,\n selectionPalette: [\"red\", \"green\", \"blue\", \"orange\"],\n flat: false,\n change: function(color) {\n debug.log('change color');\n canvasModule.setColor(color);\n }\n }).on(\"dragstart.spectrum , dragstop.spectrum\", function(e, color) {\n debug.log('change color - dragstop - dragstart');\n canvasModule.setColor(color);\n }\n );\n },\n\n /**\n * Using svg making sure it looks nice.\n *\n * @param {string} src\n */\n loadEmojiCsv: function(src) {\n debug.log('loadEmojiCsv : ', src);\n // Issue when using loadsvgfromurl.\n fabric.Image.fromURL(src.replace('.png', '.svg'), function(object) {\n // Logic below needed to work with the svg files.\n object.set({\n height: 500,\n width: 500,\n left: 150,\n top: 100,\n angle: 0,\n centerTransform: true\n }).scale(0.4).setCoords();\n canvas.add(object);\n canvas.setActiveObject(object);\n });\n },\n\n /**\n * Delete a attempt/sketch\n * TODO we could better use amd Ajax helper Moodle and external webservice, for now this is okay.\n *\n * @param {jQuery} $el\n */\n deleteAttempt: function($el) {\n debug.log('Delete', $el);\n notification.confirm(\n M.util.get_string('javascript:confirm_title', 'mod_gcanvas'),\n M.util.get_string('javascript:confirm_desc', 'mod_gcanvas'),\n M.util.get_string('javascript:yes', 'mod_gcanvas'),\n M.util.get_string('javascript:no', 'mod_gcanvas'), function() {\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'delete_attempt',\n data: JSON.stringify({\n 'id': opts.id,\n 'attempt_id': $el.data('id'),\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n // Load attempts.\n canvasModule.loadHistory();\n\n } else {\n notification.addNotification({\n message: response.error,\n type: \"error\"\n });\n }\n },\n error: function(response) {\n debug.error(response.responseText);\n // Show a error messages.\n notification.addNotification({\n message: response.responseText,\n type: \"error\"\n });\n }\n });\n });\n },\n\n /**\n * Restore a attempt/sketch\n *\n * @param {jQuery} $el\n */\n restoreAttempt: function($el) {\n debug.log('Restore', $el);\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'get_attempt',\n data: JSON.stringify({\n 'id': opts.id,\n 'attempt_id': $el.data('id'),\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n bufferActive = false;\n\n canvas.loadFromJSON(response.record.json_data, canvas.renderAll.bind(canvas));\n\n setTimeout(function() {\n bufferActive = true;\n }, 1000);\n }\n }\n });\n },\n\n /**\n * Show the fileuploader.\n *\n * @param {string} filearea\n */\n showFileuploader: function(filearea) {\n $('#canvas-filepicker-form-' + filearea).toggle();\n },\n\n /**\n * Set background of the canvas.\n */\n setBackgroundImage: function() {\n\n if (opts.background !== '' && opts.background !== 'false') {\n fabric.Image.fromURL(opts.background, function(img) {\n // Add background image.\n canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {\n scaleX: canvas.width / img.width,\n scaleY: canvas.height / img.height\n });\n });\n }\n },\n\n /**\n * Add user image.\n */\n addUserImage: function() {\n var formdata = {'id': opts.id},\n inputs = $('#canvas-filepicker-form-student_image form').serializeArray();\n\n $.each(inputs, function(i, input) {\n formdata[input.name] = input.value;\n });\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'upload_images',\n data: JSON.stringify(formdata)\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n canvasModule.addImageFromUrl(response.image);\n }\n $('#canvas-filepicker-form-student_image').hide();\n }\n });\n },\n\n /**\n * Add image from url\n * TODO SVG support.\n * @param {string} path\n */\n addImageFromUrl: function(path) {\n\n fabric.Image.fromURL(path, function(object) {\n object.set({\n left: 150,\n top: 100,\n angle: 0,\n centerTransform: true\n }).setCoords();\n\n // Prevent to large objects.\n var maxwidth = canvas.getWidth() / 3;\n\n if (object.width > maxwidth) {\n object.scaleToWidth(maxwidth);\n }\n\n canvas.add(object);\n canvas.setActiveObject(object);\n });\n },\n\n /**\n * Select toolbar images.\n */\n selectToolbarImage: function() {\n var dialog = $('#image-picker');\n if (dialog.is(':visible')) {\n dialog.hide();\n return;\n }\n dialog.show();\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'get_toolbar_images',\n data: JSON.stringify({\n 'id': opts.id,\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n var html = '';\n $.each(response.images, function(i, src) {\n html += ' ';\n });\n html += ' ';\n\n dialog.html(html);\n }\n }\n });\n },\n\n /**\n * Undo 1 canvas step.\n */\n undo: function() {\n\n if (bufferStep === 0) {\n return;\n }\n try {\n var data = localStorage.getItem('buffer_' + bufferStep);\n canvas.loadFromJSON(data, canvas.renderAll.bind(canvas));\n\n localStorage.removeItem('buffer_' + bufferStep);\n\n bufferStep--;\n } catch (e) {\n debug.log(e);\n }\n },\n\n /**\n * Toolbar actions.\n */\n loadToolbar: function() {\n\n this.setBackgroundImage();\n\n // Most shapes will be placed on canvas by this function.\n this.loadDynamicToolbarMappingShapes();\n\n // Color picker.\n this.loadColorPicker();\n\n // Clear canvas items.\n $('#clear').on('click', function() {\n canvas.clear();\n\n if (opts.hasHorizontalRuler) {\n canvasModule.addHorizontalRuler();\n }\n\n canvasModule.setBackgroundImage();\n });\n\n // Arrow.\n $('#arrow i').on('click', function() {\n canvasModule.loadArrowToCanvas();\n });\n\n // Remove selected items.\n $('#trash i').on('click', function() {\n canvasModule.deleteSelectedCanvasItems();\n });\n\n // Load emoji picker.\n $('#smiley i').on('click', function() {\n canvasModule.loadEmojiPicker();\n });\n\n $('#undo').on('click', function() {\n bufferActive = false;\n canvasModule.undo();\n\n setTimeout(function() {\n bufferActive = true;\n }, 500);\n });\n\n // Add own image to the canvas.\n $('#add-image i').on('click', function() {\n canvasModule.showFileuploader('student_image');\n });\n\n // Student selecting a image, added to the toolbar by teachers.\n $('#select-a-image i').on('click', function() {\n canvasModule.selectToolbarImage();\n });\n\n $('#image-picker ').on('click', 'img', function() {\n canvasModule.addImageFromUrl($(this).attr('src'));\n $('#image-picker').hide();\n });\n\n $('#save-canvas').on('click', function() {\n canvasModule.saveCanvasAjax();\n });\n\n $('#show-help').on('click', function() {\n $('#dialog-help').show();\n });\n\n $('#dialog-help').on('click', function() {\n $('#dialog-help').hide();\n });\n\n $('#history').on('click', '.delete', function(e) {\n e.preventDefault();\n canvasModule.deleteAttempt($(this));\n\n }).on('click', '.restore', function(e) {\n\n e.preventDefault();\n canvasModule.restoreAttempt($(this));\n\n });\n\n // Dialog to selected a emoji.\n $('#emoji-picker').on('click', 'img', function() {\n canvasModule.loadEmojiCsv($(this).attr('src'));\n $('#emoji-picker').hide();\n });\n\n // Teacher background.\n $('#change_background').on('click', function() {\n canvasModule.showFileuploader('background');\n });\n\n // Teacher image.\n $('#add_toolbar_images').on('click', function() {\n canvasModule.showFileuploader('toolbar_shape');\n });\n\n $('#canvas-filepicker-form-student_image').on('click', '#id_submitbutton', function(e) {\n e.preventDefault();\n\n // Form should be posted to AJAX call so we can get the image.\n canvasModule.addUserImage();\n });\n\n // Hide pressing on cancel.\n $('.dialog').on('click', '.btn-secondary', function(e) {\n e.preventDefault();\n debug.log('Cancel');\n $('.dialog').hide();\n });\n },\n\n /**\n * Emoji dialog\n */\n loadEmojiPicker: function() {\n var $picker = $('#emoji-picker');\n if ($picker.html() !== '') {\n debug.log('Toggle emoji');\n $picker.toggle();\n return;\n }\n\n $.ajax({\n type: 'POST',\n url: M.cfg.wwwroot + '/mod/gcanvas/ajax.php',\n data: {\n sesskey: M.cfg.sesskey,\n action: 'emoji',\n data: JSON.stringify({\n 'id': opts.id,\n })\n },\n dataType: \"json\",\n success: function(response) {\n debug.log(response);\n\n if (response.success) {\n $picker.html(response.html).show();\n }\n }\n });\n },\n\n /**\n * Load the arrow icon to the canvas.\n */\n loadArrowToCanvas: function() {\n fabric.loadSVGFromURL('pix/arrow.svg', function(objects, options) {\n var obj = fabric.util.groupSVGElements(objects, options);\n canvas.add(obj.scale(0.1)).centerObject(obj).renderAll();\n obj.setCoords();\n canvas.setActiveObject(obj);\n });\n },\n\n /**\n * Set active element colors.\n * @param {object} color\n */\n setColor: function(color) {\n\n var colorhex = color.toHexString(); // #ff0000\n var activeobjects = canvas.getActiveObjects();\n if (activeobjects) {\n\n for (var i in activeobjects) {\n if (activeobjects.hasOwnProperty(i)) {\n var element = activeobjects[i];\n\n if (element.hasOwnProperty('id') && element.id === 'ruler') {\n continue;\n }\n\n element.set(\"fill\", colorhex);\n }\n }\n\n canvas.renderAll();\n } else {\n debug.log('No active items');\n }\n },\n\n /**\n * Don't allow going out of canvas.\n */\n preventMovingOutOfCanvas: function() {\n canvas.on('object:moving', function(e) {\n var obj = e.target;\n // If object is too big ignore.\n if (obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width) {\n return;\n }\n obj.setCoords();\n\n if (obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0) {\n obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top);\n obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left);\n }\n\n if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height ||\n obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width) {\n obj.top = Math.min(obj.top, obj.canvas.height - obj.getBoundingRect().height + obj.top -\n obj.getBoundingRect().top);\n obj.left = Math.min(obj.left, obj.canvas.width - obj.getBoundingRect().width + obj.left -\n obj.getBoundingRect().left);\n }\n });\n },\n\n /**\n * Trigger for extra keyboard commands.\n */\n keyboardActions: function() {\n $(document).keydown(function(e) {\n debug.log('keypress', e.which);\n switch (e.which) {\n case 46:\n canvasModule.deleteSelectedCanvasItems();\n break;\n }\n });\n },\n\n /**\n * Start this module.\n */\n init: function() {\n\n // Load canvas.\n this.__canvas = canvas = new fabric.Canvas('sketch');\n\n // Prevent right click.\n $('body').on('contextmenu', 'canvas , img', function() {\n return false;\n });\n\n // Dimensions.\n canvas.setHeight(this.canvasHeight);\n canvas.setWidth(this.canvasWidth - 70);\n\n // Catch some actions.\n canvas.on({\n 'selection:created': this.onchange,\n 'selection:updated': this.onchange,\n\n // 'object:moving' : this.add_to_history,\n 'object:added': this.addToCache,\n 'object:removed': this.addToCache,\n 'object:modified': this.addToCache,\n });\n\n // Make sure we start with a empty storage.\n localStorage.clear();\n\n this.preventMovingOutOfCanvas();\n\n this.loadToolbar();\n\n if (opts.hasHorizontalRuler) {\n this.addHorizontalRuler();\n }\n\n this.loadHistory();\n\n this.keyboardActions();\n },\n\n /**\n * Keep a history/cache buffer.\n */\n addToCache: function() {\n debug.log('history');\n canvasModule.addCanvasToCacheBuffer();\n },\n\n /**\n * Add canvas to local storage.\n */\n addCanvasToCacheBuffer: function() {\n // When undo there lot of modified events we doesnt want to trigger if thats the case.\n if (!bufferActive) {\n return;\n }\n\n clearTimeout(bufferTimer);\n setTimeout(function() {\n try {\n bufferStep++;\n localStorage.setItem('buffer_' + bufferStep, JSON.stringify(canvas));\n } catch (e) {\n debug.log(e);\n }\n }, 500);\n },\n\n /**\n * Horizontal ruler.\n */\n addHorizontalRuler: function() {\n var ruler = new fabric.Rect({\n width: this.canvasWidth,\n height: 2,\n id: 'ruler',\n left: 0,\n top: 410,\n angle: 0,\n fill: '#8b58a1'\n });\n\n ruler.flipY = false;\n ruler.lockMovementX = true;\n ruler.lockScalingX = true;\n ruler.lockScalingY = true;\n ruler.lockUniScaling = true;\n ruler.lockRotation = true;\n\n canvas.add(ruler);\n canvas.renderAll();\n\n // Keyboard arrows move ruler.\n $(document).keydown(function(e) {\n switch (e.which) {\n\n case 38: // Up arrow.\n ruler.top = ruler.top - 10;\n canvas.renderAll();\n break;\n\n case 40: // Down arrow.\n ruler.top = ruler.top + 10;\n canvas.renderAll();\n\n break;\n\n default:\n return; // Exit this handler for other keys.\n }\n e.preventDefault(); // Prevent the default action (scroll / move caret).\n });\n },\n\n /**\n * Trigger on canvas element actions.\n * @param {object} options\n */\n onchange: function(options) {\n if (options.target.hasOwnProperty('id') && options.target.id === 'ruler') {\n return;\n }\n\n $(\"#colorpicker\").spectrum(\"set\", options.target.fill);\n }\n };\n\n return {\n\n /**\n * Init\n * @param {object} args\n */\n initialise: function (args) {\n\n // Load the args passed from PHP.\n setOptions(args);\n\n // Set internal debug console.\n setDebug(opts.debugjs);\n\n $.noConflict();\n $(document).ready(function () {\n debug.log('Canvas Module v1.2');\n canvasModule.init();\n });\n }\n };\n});\n"],"names":["define","$","notification","opts","id","debugjs","hasHorizontalRuler","background","debug","bufferStep","bufferActive","canvas","canvasModule","canvasWidth","canvasHeight","defaultShaperect","width","height","left","top","angle","fill","defaultShapecircle","radius","defaultShapetriangle","defaultShapetextbox","loadHistory","ajax","type","url","M","cfg","wwwroot","data","sesskey","action","JSON","stringify","dataType","success","response","log","html","error","responseText","addNotification","message","saveCanvasAjax","fabric","Canvas","supports","toDataURL","multiplier","format","util","get_string","deleteSelectedCanvasItems","activeobjects","getActiveObjects","length","i","hasOwnProperty","element","undefined","remove","discardActiveObject","renderAll","e","loadDynamicToolbarMappingShapes","on","el","elementtype","this","shape","toLowerCase","add","setActiveObject","loadColorPicker","spectrum","showPalette","palette","showSelectionPalette","selectionPalette","flat","change","color","setColor","loadEmojiCsv","src","Image","fromURL","replace","object","set","centerTransform","scale","setCoords","deleteAttempt","$el","confirm","restoreAttempt","loadFromJSON","record","json_data","bind","setTimeout","showFileuploader","filearea","toggle","setBackgroundImage","img","scaleX","scaleY","addUserImage","formdata","inputs","serializeArray","each","input","name","value","addImageFromUrl","image","hide","path","maxwidth","getWidth","scaleToWidth","selectToolbarImage","dialog","is","show","images","undo","localStorage","getItem","removeItem","loadToolbar","clear","addHorizontalRuler","loadArrowToCanvas","loadEmojiPicker","attr","preventDefault","$picker","loadSVGFromURL","objects","options","obj","groupSVGElements","centerObject","colorhex","toHexString","preventMovingOutOfCanvas","target","currentHeight","currentWidth","getBoundingRect","Math","max","min","keyboardActions","document","keydown","which","init","__canvas","setHeight","setWidth","onchange","addToCache","addCanvasToCacheBuffer","clearTimeout","setItem","ruler","Rect","flipY","lockMovementX","lockScalingX","lockScalingY","lockUniScaling","lockRotation","initialise","args","key","vartype","Boolean","Number","String","setOptions","isenabled","m","console","window","setDebug","noConflict","ready"],"mappings":"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"}
\ No newline at end of file
diff --git a/amd/build/spectrum.min.js b/amd/build/spectrum.min.js
new file mode 100644
index 0000000..39a6ad9
--- /dev/null
+++ b/amd/build/spectrum.min.js
@@ -0,0 +1,3 @@
+var factory;factory=function($,undefined$1){var defaultOpts={beforeShow:noop,move:noop,change:noop,show:noop,hide:noop,color:!1,flat:!1,showInput:!1,allowEmpty:!1,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!1,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:7,cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:!1,className:"",containerClassName:"",replacerClassName:"",showAlpha:!1,theme:"sp-light",palette:[["#ffffff","#000000","#ff0000","#ff8000","#ffff00","#008000","#0000ff","#4b0082","#9400d3"]],selectionPalette:[],disabled:!1,offset:null},spectrums=[],IE=!!/msie/i.exec(window.navigator.userAgent),rgbaSupport=function(){function contains(str,substr){return!!~(""+str).indexOf(substr)}var style=document.createElement("div").style;return style.cssText="background-color:rgba(0,0,0,.5)",contains(style.backgroundColor,"rgba")||contains(style.backgroundColor,"hsla")}(),replaceInput=[""].join(""),markup=function(){var gradientFix="";if(IE)for(var i=1;i<=6;i++)gradientFix+="
";return[""].join("")}();function paletteTemplate(p,color,className,opts){for(var html=[],i=0;i ')}else html.push($("
").append($(' ').attr("title",opts.noColorSelectedText)).html())}return""+html.join("")+"
"}function spectrum(element,o){var func,wait,debounce,timeout,opts=function(o,callbackContext){var opts=$.extend({},defaultOpts,o);return opts.callbacks={move:bind(opts.move,callbackContext),change:bind(opts.change,callbackContext),show:bind(opts.show,callbackContext),hide:bind(opts.hide,callbackContext),beforeShow:bind(opts.beforeShow,callbackContext)},opts}(o,element),flat=opts.flat,showSelectionPalette=opts.showSelectionPalette,localStorageKey=opts.localStorageKey,theme=opts.theme,callbacks=opts.callbacks,resize=(func=reflow,wait=10,function(){var context=this,args=arguments,throttler=function(){timeout=null,func.apply(context,args)};debounce&&clearTimeout(timeout),!debounce&&timeout||(timeout=setTimeout(throttler,wait))}),visible=!1,isDragging=!1,dragWidth=0,dragHeight=0,dragHelperHeight=0,slideHeight=0,alphaWidth=0,alphaSlideHelperWidth=0,slideHelperHeight=0,currentHue=0,currentSaturation=0,currentValue=0,currentAlpha=1,palette=[],paletteArray=[],paletteLookup={},selectionPalette=opts.selectionPalette.slice(0),maxSelectionSize=opts.maxSelectionSize,shiftMovementDirection=null,doc=element.ownerDocument,boundElement=(doc.body,$(element)),disabled=!1,container=$(markup,doc).addClass(theme),pickerContainer=container.find(".sp-picker-container"),dragger=container.find(".sp-color"),dragHelper=container.find(".sp-dragger"),slider=container.find(".sp-hue"),slideHelper=container.find(".sp-slider"),alphaSliderInner=container.find(".sp-alpha-inner"),alphaSlider=container.find(".sp-alpha"),alphaSlideHelper=container.find(".sp-alpha-handle"),textInput=container.find(".sp-input"),paletteContainer=container.find(".sp-palette"),initialColorContainer=container.find(".sp-initial"),cancelButton=container.find(".sp-cancel"),clearButton=container.find(".sp-clear"),chooseButton=container.find(".sp-choose"),toggleButton=container.find(".sp-palette-toggle"),isInput=boundElement.is("input"),isInputTypeColor=isInput&&"color"===boundElement.attr("type")&&inputTypeColorSupport(),shouldReplace=isInput&&!flat,replacer=shouldReplace?$(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName):$([]),offsetElement=shouldReplace?replacer:boundElement,previewElement=replacer.find(".sp-preview-inner"),initialColor=opts.color||isInput&&boundElement.val(),colorOnShow=!1,currentPreferredFormat=opts.preferredFormat,clickoutFiresChange=!opts.showButtons||opts.clickoutFiresChange,isEmpty=!initialColor,allowEmpty=opts.allowEmpty&&!isInputTypeColor;function applyOptions(){if(opts.showPaletteOnly&&(opts.showPalette=!0),toggleButton.text(opts.showPaletteOnly?opts.togglePaletteMoreText:opts.togglePaletteLessText),opts.palette){palette=opts.palette.slice(0),paletteArray=$.isArray(palette[0])?palette:[palette],paletteLookup={};for(var i=0;i1&&(delete window.localStorage[localStorageKey],$.each(oldPalette,(function(i,c){addColorToSelectionPalette(c)})))}catch(e){}try{selectionPalette=window.localStorage[localStorageKey].split(";")}catch(e){}}}function addColorToSelectionPalette(color){if(showSelectionPalette){var rgb=tinycolor(color).toRgbString();if(!paletteLookup[rgb]&&-1===$.inArray(rgb,selectionPalette))for(selectionPalette.push(rgb);selectionPalette.length>maxSelectionSize;)selectionPalette.shift();if(localStorageKey&&window.localStorage)try{window.localStorage[localStorageKey]=selectionPalette.join(";")}catch(e){}}}function drawPalette(){var currentColor=get(),html=$.map(paletteArray,(function(palette,i){return paletteTemplate(palette,currentColor,"sp-palette-row sp-palette-row-"+i,opts)}));updateSelectionPaletteFromStorage(),selectionPalette&&html.push(paletteTemplate(function(){var unique=[];if(opts.showPalette)for(var i=0;iviewWidth&&viewWidth>dpWidth?Math.abs(offset.left+dpWidth-viewWidth):0),offset.top-=Math.min(offset.top,offset.top+dpHeight>viewHeight&&viewHeight>dpHeight?Math.abs(dpHeight+inputHeight-extraY):extraY),offset}(container,offsetElement))),updateHelperLocations(),opts.showPalette&&drawPalette(),boundElement.trigger("reflow.spectrum"))}function disable(){hide(),disabled=!0,boundElement.attr("disabled",!0),offsetElement.addClass("sp-disabled")}!function(){if(IE&&container.find("*:not(input)").attr("unselectable","on"),applyOptions(),shouldReplace&&boundElement.after(replacer).hide(),allowEmpty||clearButton.hide(),flat)boundElement.after(container).hide();else{var appendTo="parent"===opts.appendTo?boundElement.parent():$(opts.appendTo);1!==appendTo.length&&(appendTo=$("body")),appendTo.append(container)}function paletteElementClick(e){return e.data&&e.data.ignore?(set($(e.target).closest(".sp-thumb-el").data("color")),move()):(set($(e.target).closest(".sp-thumb-el").data("color")),move(),updateOriginalInput(!0),opts.hideAfterPaletteSelect&&hide()),!1}updateSelectionPaletteFromStorage(),offsetElement.bind("click.spectrum touchstart.spectrum",(function(e){disabled||toggle(),e.stopPropagation(),$(e.target).is("input")||e.preventDefault()})),(boundElement.is(":disabled")||!0===opts.disabled)&&disable(),container.click(stopPropagation),textInput.change(setFromTextInput),textInput.bind("paste",(function(){setTimeout(setFromTextInput,1)})),textInput.keydown((function(e){13==e.keyCode&&setFromTextInput()})),cancelButton.text(opts.cancelText),cancelButton.bind("click.spectrum",(function(e){e.stopPropagation(),e.preventDefault(),revert(),hide()})),clearButton.attr("title",opts.clearText),clearButton.bind("click.spectrum",(function(e){e.stopPropagation(),e.preventDefault(),isEmpty=!0,move(),flat&&updateOriginalInput(!0)})),chooseButton.text(opts.chooseText),chooseButton.bind("click.spectrum",(function(e){e.stopPropagation(),e.preventDefault(),IE&&textInput.is(":focus")&&textInput.trigger("change"),textInput.hasClass("sp-validation-error")||(updateOriginalInput(!0),hide())})),toggleButton.text(opts.showPaletteOnly?opts.togglePaletteMoreText:opts.togglePaletteLessText),toggleButton.bind("click.spectrum",(function(e){e.stopPropagation(),e.preventDefault(),opts.showPaletteOnly=!opts.showPaletteOnly,opts.showPaletteOnly||flat||container.css("left","-="+(pickerContainer.outerWidth(!0)+5)),applyOptions()})),draggable(alphaSlider,(function(dragX,dragY,e){currentAlpha=dragX/alphaWidth,isEmpty=!1,e.shiftKey&&(currentAlpha=Math.round(10*currentAlpha)/10),move()}),dragStart,dragStop),draggable(slider,(function(dragX,dragY){currentHue=parseFloat(dragY/slideHeight),isEmpty=!1,opts.showAlpha||(currentAlpha=1),move()}),dragStart,dragStop),draggable(dragger,(function(dragX,dragY,e){if(e.shiftKey){if(!shiftMovementDirection){var oldDragX=currentSaturation*dragWidth,oldDragY=dragHeight-currentValue*dragHeight,furtherFromX=Math.abs(dragX-oldDragX)>Math.abs(dragY-oldDragY);shiftMovementDirection=furtherFromX?"x":"y"}}else shiftMovementDirection=null;var setValue=!shiftMovementDirection||"y"===shiftMovementDirection;(!shiftMovementDirection||"x"===shiftMovementDirection)&&(currentSaturation=parseFloat(dragX/dragWidth)),setValue&&(currentValue=parseFloat((dragHeight-dragY)/dragHeight)),isEmpty=!1,opts.showAlpha||(currentAlpha=1),move()}),dragStart,dragStop),initialColor?(set(initialColor),updateUI(),currentPreferredFormat=opts.preferredFormat||tinycolor(initialColor).format,addColorToSelectionPalette(initialColor)):updateUI(),flat&&show();var paletteEvent=IE?"mousedown.spectrum":"click.spectrum touchstart.spectrum";paletteContainer.delegate(".sp-thumb-el",paletteEvent,paletteElementClick),initialColorContainer.delegate(".sp-thumb-el:nth-child(1)",paletteEvent,{ignore:!0},paletteElementClick)}();var spect={show:show,hide:hide,toggle:toggle,reflow:reflow,option:function(optionName,optionValue){return optionName===undefined$1?$.extend({},opts):optionValue===undefined$1?opts[optionName]:(opts[optionName]=optionValue,"preferredFormat"===optionName&&(currentPreferredFormat=opts.preferredFormat),void applyOptions())},enable:function(){disabled=!1,boundElement.attr("disabled",!1),offsetElement.removeClass("sp-disabled")},disable:disable,offset:function(coord){opts.offset=coord,reflow()},set:function(c){set(c),updateOriginalInput()},get:get,destroy:function(){boundElement.show(),offsetElement.unbind("click.spectrum touchstart.spectrum"),container.remove(),replacer.remove(),spectrums[spect.id]=null},container:container};return spect.id=spectrums.push(spect)-1,spect}function noop(){}function stopPropagation(e){e.stopPropagation()}function bind(func,obj){var slice=Array.prototype.slice,args=slice.call(arguments,2);return function(){return func.apply(obj,args.concat(slice.call(arguments)))}}function draggable(element,onmove,onstart,onstop){onmove=onmove||function(){},onstart=onstart||function(){},onstop=onstop||function(){};var doc=document,dragging=!1,offset={},maxHeight=0,maxWidth=0,hasTouch="ontouchstart"in window,duringDragEvents={};function prevent(e){e.stopPropagation&&e.stopPropagation(),e.preventDefault&&e.preventDefault(),e.returnValue=!1}function move(e){if(dragging){if(IE&&doc.documentMode<9&&!e.button)return stop();var t0=e.originalEvent&&e.originalEvent.touches&&e.originalEvent.touches[0],pageX=t0&&t0.pageX||e.pageX,pageY=t0&&t0.pageY||e.pageY,dragX=Math.max(0,Math.min(pageX-offset.left,maxWidth)),dragY=Math.max(0,Math.min(pageY-offset.top,maxHeight));hasTouch&&prevent(e),onmove.apply(element,[dragX,dragY,e])}}function stop(){dragging&&($(doc).unbind(duringDragEvents),$(doc.body).removeClass("sp-dragging"),setTimeout((function(){onstop.apply(element,arguments)}),0)),dragging=!1}duringDragEvents.selectstart=prevent,duringDragEvents.dragstart=prevent,duringDragEvents["touchmove mousemove"]=move,duringDragEvents["touchend mouseup"]=stop,$(element).bind("touchstart mousedown",(function(e){var rightclick=e.which?3==e.which:2==e.button;rightclick||dragging||!1!==onstart.apply(element,arguments)&&(dragging=!0,maxHeight=$(element).height(),maxWidth=$(element).width(),offset=$(element).offset(),$(doc).bind(duringDragEvents),$(doc.body).addClass("sp-dragging"),move(e),prevent(e))}))}function inputTypeColorSupport(){return $.fn.spectrum.inputTypeColorSupport()}var dataID="spectrum.id";$.fn.spectrum=function(opts,extra){if("string"==typeof opts){var returnValue=this,args=Array.prototype.slice.call(arguments,1);return this.each((function(){var spect=spectrums[$(this).data(dataID)];if(spect){var method=spect[opts];if(!method)throw new Error("Spectrum: no such method: '"+opts+"'");"get"==opts?returnValue=spect.get():"container"==opts?returnValue=spect.container:"option"==opts?returnValue=spect.option.apply(spect,args):"destroy"==opts?(spect.destroy(),$(this).removeData(dataID)):method.apply(spect,args)}})),returnValue}return this.spectrum("destroy").each((function(){var spect=spectrum(this,$.extend({},opts,$(this).data()));$(this).data(dataID,spect.id)}))},$.fn.spectrum.load=!0,$.fn.spectrum.loadOpts={},$.fn.spectrum.draggable=draggable,$.fn.spectrum.defaults=defaultOpts,$.fn.spectrum.inputTypeColorSupport=function inputTypeColorSupport(){if(void 0===inputTypeColorSupport._cachedResult){var colorInput=$(" ")[0];inputTypeColorSupport._cachedResult="color"===colorInput.type&&""!==colorInput.value}return inputTypeColorSupport._cachedResult},$.spectrum={},$.spectrum.localization={},$.spectrum.palettes={},$.fn.spectrum.processNativeColorInputs=function(){var colorInputs=$("input[type=color]");colorInputs.length&&!inputTypeColorSupport()&&colorInputs.spectrum({preferredFormat:"hex6"})},function(){var trimLeft=/^[\s,#]+/,trimRight=/\s+$/,tinyCounter=0,math=Math,mathRound=math.round,mathMin=math.min,mathMax=math.max,mathRandom=math.random,tinycolor=function(color,opts){if(opts=opts||{},(color=color||"")instanceof tinycolor)return color;if(!(this instanceof tinycolor))return new tinycolor(color,opts);var rgb=function(color){var r,g,b,rgb={r:0,g:0,b:0},a=1,ok=!1,format=!1;return"string"==typeof color&&(color=function(color){color=color.replace(trimLeft,"").replace(trimRight,"").toLowerCase();var match,named=!1;if(names[color])color=names[color],named=!0;else if("transparent"==color)return{r:0,g:0,b:0,a:0,format:"name"};return(match=matchers.rgb.exec(color))?{r:match[1],g:match[2],b:match[3]}:(match=matchers.rgba.exec(color))?{r:match[1],g:match[2],b:match[3],a:match[4]}:(match=matchers.hsl.exec(color))?{h:match[1],s:match[2],l:match[3]}:(match=matchers.hsla.exec(color))?{h:match[1],s:match[2],l:match[3],a:match[4]}:(match=matchers.hsv.exec(color))?{h:match[1],s:match[2],v:match[3]}:(match=matchers.hsva.exec(color))?{h:match[1],s:match[2],v:match[3],a:match[4]}:(match=matchers.hex8.exec(color))?{a:convertHexToDecimal(match[1]),r:parseIntFromHex(match[2]),g:parseIntFromHex(match[3]),b:parseIntFromHex(match[4]),format:named?"name":"hex8"}:(match=matchers.hex6.exec(color))?{r:parseIntFromHex(match[1]),g:parseIntFromHex(match[2]),b:parseIntFromHex(match[3]),format:named?"name":"hex"}:!!(match=matchers.hex3.exec(color))&&{r:parseIntFromHex(match[1]+""+match[1]),g:parseIntFromHex(match[2]+""+match[2]),b:parseIntFromHex(match[3]+""+match[3]),format:named?"name":"hex"}}(color)),"object"==typeof color&&(color.hasOwnProperty("r")&&color.hasOwnProperty("g")&&color.hasOwnProperty("b")?(r=color.r,g=color.g,b=color.b,rgb={r:255*bound01(r,255),g:255*bound01(g,255),b:255*bound01(b,255)},ok=!0,format="%"===String(color.r).substr(-1)?"prgb":"rgb"):color.hasOwnProperty("h")&&color.hasOwnProperty("s")&&color.hasOwnProperty("v")?(color.s=convertToPercentage(color.s),color.v=convertToPercentage(color.v),rgb=function(h,s,v){h=6*bound01(h,360),s=bound01(s,100),v=bound01(v,100);var i=math.floor(h),f=h-i,p=v*(1-s),q=v*(1-f*s),t=v*(1-(1-f)*s),mod=i%6;return{r:255*[v,q,p,p,t,v][mod],g:255*[t,v,v,q,p,p][mod],b:255*[p,p,t,v,v,q][mod]}}(color.h,color.s,color.v),ok=!0,format="hsv"):color.hasOwnProperty("h")&&color.hasOwnProperty("s")&&color.hasOwnProperty("l")&&(color.s=convertToPercentage(color.s),color.l=convertToPercentage(color.l),rgb=function(h,s,l){var r,g,b;function hue2rgb(p,q,t){return t<0&&(t+=1),t>1&&(t-=1),t<1/6?p+6*(q-p)*t:t<.5?q:t<2/3?p+(q-p)*(2/3-t)*6:p}if(h=bound01(h,360),s=bound01(s,100),l=bound01(l,100),0===s)r=g=b=l;else{var q=l<.5?l*(1+s):l+s-l*s,p=2*l-q;r=hue2rgb(p,q,h+1/3),g=hue2rgb(p,q,h),b=hue2rgb(p,q,h-1/3)}return{r:255*r,g:255*g,b:255*b}}(color.h,color.s,color.l),ok=!0,format="hsl"),color.hasOwnProperty("a")&&(a=color.a)),a=boundAlpha(a),{ok:ok,format:color.format||format,r:mathMin(255,mathMax(rgb.r,0)),g:mathMin(255,mathMax(rgb.g,0)),b:mathMin(255,mathMax(rgb.b,0)),a:a}}(color);this._originalInput=color,this._r=rgb.r,this._g=rgb.g,this._b=rgb.b,this._a=rgb.a,this._roundA=mathRound(100*this._a)/100,this._format=opts.format||rgb.format,this._gradientType=opts.gradientType,this._r<1&&(this._r=mathRound(this._r)),this._g<1&&(this._g=mathRound(this._g)),this._b<1&&(this._b=mathRound(this._b)),this._ok=rgb.ok,this._tc_id=tinyCounter++};function rgbToHsl(r,g,b){r=bound01(r,255),g=bound01(g,255),b=bound01(b,255);var h,s,max=mathMax(r,g,b),min=mathMin(r,g,b),l=(max+min)/2;if(max==min)h=s=0;else{var d=max-min;switch(s=l>.5?d/(2-max-min):d/(max+min),max){case r:h=(g-b)/d+(g>1)+720)%360;--results;)hsl.h=(hsl.h+part)%360,ret.push(tinycolor(hsl));return ret}function monochromatic(color,results){results=results||6;for(var hsv=tinycolor(color).toHsv(),h=hsv.h,s=hsv.s,v=hsv.v,ret=[],modification=1/results;results--;)ret.push(tinycolor({h:h,s:s,v:v})),v=(v+modification)%1;return ret}tinycolor.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var rgb=this.toRgb();return(299*rgb.r+587*rgb.g+114*rgb.b)/1e3},setAlpha:function(value){return this._a=boundAlpha(value),this._roundA=mathRound(100*this._a)/100,this},toHsv:function(){var hsv=rgbToHsv(this._r,this._g,this._b);return{h:360*hsv.h,s:hsv.s,v:hsv.v,a:this._a}},toHsvString:function(){var hsv=rgbToHsv(this._r,this._g,this._b),h=mathRound(360*hsv.h),s=mathRound(100*hsv.s),v=mathRound(100*hsv.v);return 1==this._a?"hsv("+h+", "+s+"%, "+v+"%)":"hsva("+h+", "+s+"%, "+v+"%, "+this._roundA+")"},toHsl:function(){var hsl=rgbToHsl(this._r,this._g,this._b);return{h:360*hsl.h,s:hsl.s,l:hsl.l,a:this._a}},toHslString:function(){var hsl=rgbToHsl(this._r,this._g,this._b),h=mathRound(360*hsl.h),s=mathRound(100*hsl.s),l=mathRound(100*hsl.l);return 1==this._a?"hsl("+h+", "+s+"%, "+l+"%)":"hsla("+h+", "+s+"%, "+l+"%, "+this._roundA+")"},toHex:function(allow3Char){return rgbToHex(this._r,this._g,this._b,allow3Char)},toHexString:function(allow3Char){return"#"+this.toHex(allow3Char)},toHex8:function(){return rgbaToHex(this._r,this._g,this._b,this._a)},toHex8String:function(){return"#"+this.toHex8()},toRgb:function(){return{r:mathRound(this._r),g:mathRound(this._g),b:mathRound(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+mathRound(this._r)+", "+mathRound(this._g)+", "+mathRound(this._b)+")":"rgba("+mathRound(this._r)+", "+mathRound(this._g)+", "+mathRound(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:mathRound(100*bound01(this._r,255))+"%",g:mathRound(100*bound01(this._g,255))+"%",b:mathRound(100*bound01(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+mathRound(100*bound01(this._r,255))+"%, "+mathRound(100*bound01(this._g,255))+"%, "+mathRound(100*bound01(this._b,255))+"%)":"rgba("+mathRound(100*bound01(this._r,255))+"%, "+mathRound(100*bound01(this._g,255))+"%, "+mathRound(100*bound01(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(hexNames[rgbToHex(this._r,this._g,this._b,!0)]||!1)},toFilter:function(secondColor){var hex8String="#"+rgbaToHex(this._r,this._g,this._b,this._a),secondHex8String=hex8String,gradientType=this._gradientType?"GradientType = 1, ":"";return secondColor&&(secondHex8String=tinycolor(secondColor).toHex8String()),"progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")"},toString:function(format){var formatSet=!!format;format=format||this._format;var formattedString=!1,hasAlpha=this._a<1&&this._a>=0;return formatSet||!hasAlpha||"hex"!==format&&"hex6"!==format&&"hex3"!==format&&"name"!==format?("rgb"===format&&(formattedString=this.toRgbString()),"prgb"===format&&(formattedString=this.toPercentageRgbString()),"hex"!==format&&"hex6"!==format||(formattedString=this.toHexString()),"hex3"===format&&(formattedString=this.toHexString(!0)),"hex8"===format&&(formattedString=this.toHex8String()),"name"===format&&(formattedString=this.toName()),"hsl"===format&&(formattedString=this.toHslString()),"hsv"===format&&(formattedString=this.toHsvString()),formattedString||this.toHexString()):"name"===format&&0===this._a?this.toName():this.toRgbString()},_applyModification:function(fn,args){var color=fn.apply(null,[this].concat([].slice.call(args)));return this._r=color._r,this._g=color._g,this._b=color._b,this.setAlpha(color._a),this},lighten:function(){return this._applyModification(lighten,arguments)},brighten:function(){return this._applyModification(brighten,arguments)},darken:function(){return this._applyModification(darken,arguments)},desaturate:function(){return this._applyModification(desaturate,arguments)},saturate:function(){return this._applyModification(saturate,arguments)},greyscale:function(){return this._applyModification(greyscale,arguments)},spin:function(){return this._applyModification(spin,arguments)},_applyCombination:function(fn,args){return fn.apply(null,[this].concat([].slice.call(args)))},analogous:function(){return this._applyCombination(analogous,arguments)},complement:function(){return this._applyCombination(complement,arguments)},monochromatic:function(){return this._applyCombination(monochromatic,arguments)},splitcomplement:function(){return this._applyCombination(splitcomplement,arguments)},triad:function(){return this._applyCombination(triad,arguments)},tetrad:function(){return this._applyCombination(tetrad,arguments)}},tinycolor.fromRatio=function(color,opts){if("object"==typeof color){var newColor={};for(var i in color)color.hasOwnProperty(i)&&(newColor[i]="a"===i?color[i]:convertToPercentage(color[i]));color=newColor}return tinycolor(color,opts)},tinycolor.equals=function(color1,color2){return!(!color1||!color2)&&tinycolor(color1).toRgbString()==tinycolor(color2).toRgbString()},tinycolor.random=function(){return tinycolor.fromRatio({r:mathRandom(),g:mathRandom(),b:mathRandom()})},tinycolor.mix=function(color1,color2,amount){amount=0===amount?0:amount||50;var w1,rgb1=tinycolor(color1).toRgb(),rgb2=tinycolor(color2).toRgb(),p=amount/100,w=2*p-1,a=rgb2.a-rgb1.a,w2=1-(w1=((w1=w*a==-1?w:(w+a)/(1+w*a))+1)/2),rgba={r:rgb2.r*w1+rgb1.r*w2,g:rgb2.g*w1+rgb1.g*w2,b:rgb2.b*w1+rgb1.b*w2,a:rgb2.a*p+rgb1.a*(1-p)};return tinycolor(rgba)},tinycolor.readability=function(color1,color2){var c1=tinycolor(color1),c2=tinycolor(color2),rgb1=c1.toRgb(),rgb2=c2.toRgb(),brightnessA=c1.getBrightness(),brightnessB=c2.getBrightness(),colorDiff=Math.max(rgb1.r,rgb2.r)-Math.min(rgb1.r,rgb2.r)+Math.max(rgb1.g,rgb2.g)-Math.min(rgb1.g,rgb2.g)+Math.max(rgb1.b,rgb2.b)-Math.min(rgb1.b,rgb2.b);return{brightness:Math.abs(brightnessA-brightnessB),color:colorDiff}},tinycolor.isReadable=function(color1,color2){var readability=tinycolor.readability(color1,color2);return readability.brightness>125&&readability.color>500},tinycolor.mostReadable=function(baseColor,colorList){for(var bestColor=null,bestScore=0,bestIsReadable=!1,i=0;i125&&readability.color>500,score=readability.brightness/125*3+readability.color/500;(readable&&!bestIsReadable||readable&&bestIsReadable&&score>bestScore||!readable&&!bestIsReadable&&score>bestScore)&&(bestIsReadable=readable,bestScore=score,bestColor=tinycolor(colorList[i]))}return bestColor};var names=tinycolor.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},hexNames=tinycolor.hexNames=function(o){var flipped={};for(var i in o)o.hasOwnProperty(i)&&(flipped[o[i]]=i);return flipped}(names);function boundAlpha(a){return a=parseFloat(a),(isNaN(a)||a<0||a>1)&&(a=1),a}function bound01(n,max){(function(n){return"string"==typeof n&&-1!=n.indexOf(".")&&1===parseFloat(n)})(n)&&(n="100%");var processPercent=function(n){return"string"==typeof n&&-1!=n.indexOf("%")}(n);return n=mathMin(max,mathMax(0,parseFloat(n))),processPercent&&(n=parseInt(n*max,10)/100),math.abs(n-max)<1e-6?1:n%max/parseFloat(max)}function clamp01(val){return mathMin(1,mathMax(0,val))}function parseIntFromHex(val){return parseInt(val,16)}function pad2(c){return 1==c.length?"0"+c:""+c}function convertToPercentage(n){return n<=1&&(n=100*n+"%"),n}function convertHexToDecimal(h){return parseIntFromHex(h)/255}var CSS_UNIT,PERMISSIVE_MATCH3,PERMISSIVE_MATCH4,matchers=(PERMISSIVE_MATCH3="[\\s|\\(]+("+(CSS_UNIT="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+CSS_UNIT+")[,|\\s]+("+CSS_UNIT+")\\s*\\)?",PERMISSIVE_MATCH4="[\\s|\\(]+("+CSS_UNIT+")[,|\\s]+("+CSS_UNIT+")[,|\\s]+("+CSS_UNIT+")[,|\\s]+("+CSS_UNIT+")\\s*\\)?",{rgb:new RegExp("rgb"+PERMISSIVE_MATCH3),rgba:new RegExp("rgba"+PERMISSIVE_MATCH4),hsl:new RegExp("hsl"+PERMISSIVE_MATCH3),hsla:new RegExp("hsla"+PERMISSIVE_MATCH4),hsv:new RegExp("hsv"+PERMISSIVE_MATCH3),hsva:new RegExp("hsva"+PERMISSIVE_MATCH4),hex3:/^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex8:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});window.tinycolor=tinycolor}(),$((function(){$.fn.spectrum.load&&$.fn.spectrum.processNativeColorInputs()}))},"function"==typeof define&&define.amd?define("mod_gcanvas/spectrum",["jquery"],factory):"object"==typeof exports&&"object"==typeof module?module.exports=factory(require("jquery")):factory(jQuery);
+
+//# sourceMappingURL=spectrum.min.js.map
\ No newline at end of file
diff --git a/amd/build/spectrum.min.js.map b/amd/build/spectrum.min.js.map
new file mode 100644
index 0000000..8b98e6c
--- /dev/null
+++ b/amd/build/spectrum.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"spectrum.min.js","sources":["../src/spectrum.js"],"sourcesContent":["/* eslint-disable */\n\n(function (factory) {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define([\"jquery\"], factory)\n } else if (typeof exports == \"object\" && typeof module == \"object\") {\n module.exports = factory(require(\"jquery\"))\n } else {\n factory(jQuery)\n }\n})(function ($, undefined) {\n \"use strict\";\n var defaultOpts = {\n beforeShow: noop,\n move: noop,\n change: noop,\n show: noop,\n hide: noop,\n color: false,\n flat: false,\n showInput: false,\n allowEmpty: false,\n showButtons: true,\n clickoutFiresChange: true,\n showInitial: false,\n showPalette: false,\n showPaletteOnly: false,\n hideAfterPaletteSelect: false,\n togglePaletteOnly: false,\n showSelectionPalette: true,\n localStorageKey: false,\n appendTo: \"body\",\n maxSelectionSize: 7,\n cancelText: \"cancel\",\n chooseText: \"choose\",\n togglePaletteMoreText: \"more\",\n togglePaletteLessText: \"less\",\n clearText: \"Clear Color Selection\",\n noColorSelectedText: \"No Color Selected\",\n preferredFormat: false,\n className: \"\",\n containerClassName: \"\",\n replacerClassName: \"\",\n showAlpha: false,\n theme: \"sp-light\",\n palette: [[\"#ffffff\", \"#000000\", \"#ff0000\", \"#ff8000\", \"#ffff00\", \"#008000\", \"#0000ff\", \"#4b0082\", \"#9400d3\"]],\n selectionPalette: [],\n disabled: false,\n offset: null\n }, spectrums = [], IE = !!/msie/i.exec(window.navigator.userAgent), rgbaSupport = function () {\n function contains(str, substr) {\n return !!~(\"\" + str).indexOf(substr)\n }\n\n var elem = document.createElement(\"div\");\n var style = elem.style;\n style.cssText = \"background-color:rgba(0,0,0,.5)\";\n return contains(style.backgroundColor, \"rgba\") || contains(style.backgroundColor, \"hsla\")\n }(), replaceInput = [\"\"].join(\"\"),\n markup = function () {\n var gradientFix = \"\";\n if (IE) {\n for (var i = 1; i <= 6; i++) {\n gradientFix += \"
\"\n }\n }\n return [\"\", \"
\", \"
\", \"
\", \" \", \"
\", \"
\", \"
\", \"
\", \"
\", \"
\", \"
\", \"
\", \"
\", \"
\", \"
\", gradientFix, \"
\", \"
\", \"
\", \"
\", \"
\", \" \", \"
\", \"
\", \"
\", \"
\", \"
\"].join(\"\")\n }();\n\n function paletteTemplate(p, color, className, opts) {\n var html = [];\n for (var i = 0; i < p.length; i++) {\n var current = p[i];\n if (current) {\n var tiny = tinycolor(current);\n var c = tiny.toHsl().l < .5 ? \"sp-thumb-el sp-thumb-dark\" : \"sp-thumb-el sp-thumb-light\";\n c += tinycolor.equals(color, current) ? \" sp-thumb-active\" : \"\";\n var formattedString = tiny.toString(opts.preferredFormat || \"rgb\");\n var swatchStyle = rgbaSupport ? \"background-color:\" + tiny.toRgbString() : \"filter:\" + tiny.toFilter();\n html.push(' ')\n } else {\n var cls = \"sp-clear-display\";\n html.push($(\"
\").append($(' ').attr(\"title\", opts.noColorSelectedText)).html())\n }\n }\n return \"\" + html.join(\"\") + \"
\"\n }\n\n function hideAll() {\n for (var i = 0; i < spectrums.length; i++) {\n if (spectrums[i]) {\n spectrums[i].hide()\n }\n }\n }\n\n function instanceOptions(o, callbackContext) {\n var opts = $.extend({}, defaultOpts, o);\n opts.callbacks = {\n move: bind(opts.move, callbackContext),\n change: bind(opts.change, callbackContext),\n show: bind(opts.show, callbackContext),\n hide: bind(opts.hide, callbackContext),\n beforeShow: bind(opts.beforeShow, callbackContext)\n };\n return opts\n }\n\n function spectrum(element, o) {\n var opts = instanceOptions(o, element), flat = opts.flat, showSelectionPalette = opts.showSelectionPalette, localStorageKey = opts.localStorageKey, theme = opts.theme,\n callbacks = opts.callbacks, resize = throttle(reflow, 10), visible = false, isDragging = false, dragWidth = 0, dragHeight = 0, dragHelperHeight = 0, slideHeight = 0,\n slideWidth = 0, alphaWidth = 0, alphaSlideHelperWidth = 0, slideHelperHeight = 0, currentHue = 0, currentSaturation = 0, currentValue = 0, currentAlpha = 1,\n palette = [], paletteArray = [], paletteLookup = {}, selectionPalette = opts.selectionPalette.slice(0), maxSelectionSize = opts.maxSelectionSize,\n draggingClass = \"sp-dragging\", shiftMovementDirection = null;\n var doc = element.ownerDocument, body = doc.body, boundElement = $(element), disabled = false, container = $(markup, doc).addClass(theme),\n pickerContainer = container.find(\".sp-picker-container\"), dragger = container.find(\".sp-color\"), dragHelper = container.find(\".sp-dragger\"),\n slider = container.find(\".sp-hue\"), slideHelper = container.find(\".sp-slider\"), alphaSliderInner = container.find(\".sp-alpha-inner\"),\n alphaSlider = container.find(\".sp-alpha\"), alphaSlideHelper = container.find(\".sp-alpha-handle\"), textInput = container.find(\".sp-input\"),\n paletteContainer = container.find(\".sp-palette\"), initialColorContainer = container.find(\".sp-initial\"), cancelButton = container.find(\".sp-cancel\"),\n clearButton = container.find(\".sp-clear\"), chooseButton = container.find(\".sp-choose\"), toggleButton = container.find(\".sp-palette-toggle\"),\n isInput = boundElement.is(\"input\"), isInputTypeColor = isInput && boundElement.attr(\"type\") === \"color\" && inputTypeColorSupport(), shouldReplace = isInput && !flat,\n replacer = shouldReplace ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),\n offsetElement = shouldReplace ? replacer : boundElement, previewElement = replacer.find(\".sp-preview-inner\"),\n initialColor = opts.color || isInput && boundElement.val(), colorOnShow = false, currentPreferredFormat = opts.preferredFormat,\n clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange, isEmpty = !initialColor, allowEmpty = opts.allowEmpty && !isInputTypeColor;\n\n function applyOptions() {\n if (opts.showPaletteOnly) {\n opts.showPalette = true\n }\n toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);\n if (opts.palette) {\n palette = opts.palette.slice(0);\n paletteArray = $.isArray(palette[0]) ? palette : [palette];\n paletteLookup = {};\n for (var i = 0; i < paletteArray.length; i++) {\n for (var j = 0; j < paletteArray[i].length; j++) {\n var rgb = tinycolor(paletteArray[i][j]).toRgbString();\n paletteLookup[rgb] = true\n }\n }\n }\n container.toggleClass(\"sp-flat\", flat);\n container.toggleClass(\"sp-input-disabled\", !opts.showInput);\n container.toggleClass(\"sp-alpha-enabled\", opts.showAlpha);\n container.toggleClass(\"sp-clear-enabled\", allowEmpty);\n container.toggleClass(\"sp-buttons-disabled\", !opts.showButtons);\n container.toggleClass(\"sp-palette-buttons-disabled\", !opts.togglePaletteOnly);\n container.toggleClass(\"sp-palette-disabled\", !opts.showPalette);\n container.toggleClass(\"sp-palette-only\", opts.showPaletteOnly);\n container.toggleClass(\"sp-initial-disabled\", !opts.showInitial);\n container.addClass(opts.className).addClass(opts.containerClassName);\n reflow()\n }\n\n function initialize() {\n if (IE) {\n container.find(\"*:not(input)\").attr(\"unselectable\", \"on\")\n }\n applyOptions();\n if (shouldReplace) {\n boundElement.after(replacer).hide()\n }\n if (!allowEmpty) {\n clearButton.hide()\n }\n if (flat) {\n boundElement.after(container).hide()\n } else {\n var appendTo = opts.appendTo === \"parent\" ? boundElement.parent() : $(opts.appendTo);\n if (appendTo.length !== 1) {\n appendTo = $(\"body\")\n }\n appendTo.append(container)\n }\n updateSelectionPaletteFromStorage();\n offsetElement.bind(\"click.spectrum touchstart.spectrum\", function (e) {\n if (!disabled) {\n toggle()\n }\n e.stopPropagation();\n if (!$(e.target).is(\"input\")) {\n e.preventDefault()\n }\n });\n if (boundElement.is(\":disabled\") || opts.disabled === true) {\n disable()\n }\n container.click(stopPropagation);\n textInput.change(setFromTextInput);\n textInput.bind(\"paste\", function () {\n setTimeout(setFromTextInput, 1)\n });\n textInput.keydown(function (e) {\n if (e.keyCode == 13) {\n setFromTextInput()\n }\n });\n cancelButton.text(opts.cancelText);\n cancelButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n revert();\n hide()\n });\n clearButton.attr(\"title\", opts.clearText);\n clearButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n isEmpty = true;\n move();\n if (flat) {\n updateOriginalInput(true)\n }\n });\n chooseButton.text(opts.chooseText);\n chooseButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n if (IE && textInput.is(\":focus\")) {\n textInput.trigger(\"change\")\n }\n if (isValid()) {\n updateOriginalInput(true);\n hide()\n }\n });\n toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);\n toggleButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n opts.showPaletteOnly = !opts.showPaletteOnly;\n if (!opts.showPaletteOnly && !flat) {\n container.css(\"left\", \"-=\" + (pickerContainer.outerWidth(true) + 5))\n }\n applyOptions()\n });\n draggable(alphaSlider, function (dragX, dragY, e) {\n currentAlpha = dragX / alphaWidth;\n isEmpty = false;\n if (e.shiftKey) {\n currentAlpha = Math.round(currentAlpha * 10) / 10\n }\n move()\n }, dragStart, dragStop);\n draggable(slider, function (dragX, dragY) {\n currentHue = parseFloat(dragY / slideHeight);\n isEmpty = false;\n if (!opts.showAlpha) {\n currentAlpha = 1\n }\n move()\n }, dragStart, dragStop);\n draggable(dragger, function (dragX, dragY, e) {\n if (!e.shiftKey) {\n shiftMovementDirection = null\n } else if (!shiftMovementDirection) {\n var oldDragX = currentSaturation * dragWidth;\n var oldDragY = dragHeight - currentValue * dragHeight;\n var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);\n shiftMovementDirection = furtherFromX ? \"x\" : \"y\"\n }\n var setSaturation = !shiftMovementDirection || shiftMovementDirection === \"x\";\n var setValue = !shiftMovementDirection || shiftMovementDirection === \"y\";\n if (setSaturation) {\n currentSaturation = parseFloat(dragX / dragWidth)\n }\n if (setValue) {\n currentValue = parseFloat((dragHeight - dragY) / dragHeight)\n }\n isEmpty = false;\n if (!opts.showAlpha) {\n currentAlpha = 1\n }\n move()\n }, dragStart, dragStop);\n if (!!initialColor) {\n set(initialColor);\n updateUI();\n currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;\n addColorToSelectionPalette(initialColor)\n } else {\n updateUI()\n }\n if (flat) {\n show()\n }\n\n function paletteElementClick(e) {\n if (e.data && e.data.ignore) {\n set($(e.target).closest(\".sp-thumb-el\").data(\"color\"));\n move()\n } else {\n set($(e.target).closest(\".sp-thumb-el\").data(\"color\"));\n move();\n updateOriginalInput(true);\n if (opts.hideAfterPaletteSelect) {\n hide()\n }\n }\n return false\n }\n\n var paletteEvent = IE ? \"mousedown.spectrum\" : \"click.spectrum touchstart.spectrum\";\n paletteContainer.delegate(\".sp-thumb-el\", paletteEvent, paletteElementClick);\n initialColorContainer.delegate(\".sp-thumb-el:nth-child(1)\", paletteEvent, {ignore: true}, paletteElementClick)\n }\n\n function updateSelectionPaletteFromStorage() {\n if (localStorageKey && window.localStorage) {\n try {\n var oldPalette = window.localStorage[localStorageKey].split(\",#\");\n if (oldPalette.length > 1) {\n delete window.localStorage[localStorageKey];\n $.each(oldPalette, function (i, c) {\n addColorToSelectionPalette(c)\n })\n }\n } catch (e) {\n }\n try {\n selectionPalette = window.localStorage[localStorageKey].split(\";\")\n } catch (e) {\n }\n }\n }\n\n function addColorToSelectionPalette(color) {\n if (showSelectionPalette) {\n var rgb = tinycolor(color).toRgbString();\n if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {\n selectionPalette.push(rgb);\n while (selectionPalette.length > maxSelectionSize) {\n selectionPalette.shift()\n }\n }\n if (localStorageKey && window.localStorage) {\n try {\n window.localStorage[localStorageKey] = selectionPalette.join(\";\")\n } catch (e) {\n }\n }\n }\n }\n\n function getUniqueSelectionPalette() {\n var unique = [];\n if (opts.showPalette) {\n for (var i = 0; i < selectionPalette.length; i++) {\n var rgb = tinycolor(selectionPalette[i]).toRgbString();\n if (!paletteLookup[rgb]) {\n unique.push(selectionPalette[i])\n }\n }\n }\n return unique.reverse().slice(0, opts.maxSelectionSize)\n }\n\n function drawPalette() {\n var currentColor = get();\n var html = $.map(paletteArray, function (palette, i) {\n return paletteTemplate(palette, currentColor, \"sp-palette-row sp-palette-row-\" + i, opts)\n });\n updateSelectionPaletteFromStorage();\n if (selectionPalette) {\n html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, \"sp-palette-row sp-palette-row-selection\", opts))\n }\n paletteContainer.html(html.join(\"\"))\n }\n\n function drawInitial() {\n if (opts.showInitial) {\n var initial = colorOnShow;\n var current = get();\n initialColorContainer.html(paletteTemplate([initial, current], current, \"sp-palette-row-initial\", opts))\n }\n }\n\n function dragStart() {\n if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {\n reflow()\n }\n isDragging = true;\n container.addClass(draggingClass);\n shiftMovementDirection = null;\n boundElement.trigger(\"dragstart.spectrum\", [get()])\n }\n\n function dragStop() {\n isDragging = false;\n container.removeClass(draggingClass);\n boundElement.trigger(\"dragstop.spectrum\", [get()])\n }\n\n function setFromTextInput() {\n var value = textInput.val();\n if ((value === null || value === \"\") && allowEmpty) {\n set(null);\n updateOriginalInput(true)\n } else {\n var tiny = tinycolor(value);\n if (tiny.isValid()) {\n set(tiny);\n updateOriginalInput(true)\n } else {\n textInput.addClass(\"sp-validation-error\")\n }\n }\n }\n\n function toggle() {\n if (visible) {\n hide()\n } else {\n show()\n }\n }\n\n function show() {\n var event = $.Event(\"beforeShow.spectrum\");\n if (visible) {\n reflow();\n return\n }\n boundElement.trigger(event, [get()]);\n if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {\n return\n }\n hideAll();\n visible = true;\n $(doc).bind(\"keydown.spectrum\", onkeydown);\n $(doc).bind(\"click.spectrum\", clickout);\n $(window).bind(\"resize.spectrum\", resize);\n replacer.addClass(\"sp-active\");\n container.removeClass(\"sp-hidden\");\n reflow();\n updateUI();\n colorOnShow = get();\n drawInitial();\n callbacks.show(colorOnShow);\n boundElement.trigger(\"show.spectrum\", [colorOnShow])\n }\n\n function onkeydown(e) {\n if (e.keyCode === 27) {\n hide()\n }\n }\n\n function clickout(e) {\n if (e.button == 2) {\n return\n }\n if (isDragging) {\n return\n }\n if (clickoutFiresChange) {\n updateOriginalInput(true)\n } else {\n revert()\n }\n hide()\n }\n\n function hide() {\n if (!visible || flat) {\n return\n }\n visible = false;\n $(doc).unbind(\"keydown.spectrum\", onkeydown);\n $(doc).unbind(\"click.spectrum\", clickout);\n $(window).unbind(\"resize.spectrum\", resize);\n replacer.removeClass(\"sp-active\");\n container.addClass(\"sp-hidden\");\n callbacks.hide(get());\n boundElement.trigger(\"hide.spectrum\", [get()])\n }\n\n function revert() {\n set(colorOnShow, true)\n }\n\n function set(color, ignoreFormatChange) {\n if (tinycolor.equals(color, get())) {\n updateUI();\n return\n }\n var newColor, newHsv;\n if (!color && allowEmpty) {\n isEmpty = true\n } else {\n isEmpty = false;\n newColor = tinycolor(color);\n newHsv = newColor.toHsv();\n currentHue = newHsv.h % 360 / 360;\n currentSaturation = newHsv.s;\n currentValue = newHsv.v;\n currentAlpha = newHsv.a\n }\n updateUI();\n if (newColor && newColor.isValid() && !ignoreFormatChange) {\n currentPreferredFormat = opts.preferredFormat || newColor.getFormat()\n }\n }\n\n function get(opts) {\n opts = opts || {};\n if (allowEmpty && isEmpty) {\n return null\n }\n return tinycolor.fromRatio({\n h: currentHue,\n s: currentSaturation,\n v: currentValue,\n a: Math.round(currentAlpha * 100) / 100\n }, {format: opts.format || currentPreferredFormat})\n }\n\n function isValid() {\n return !textInput.hasClass(\"sp-validation-error\")\n }\n\n function move() {\n updateUI();\n callbacks.move(get());\n boundElement.trigger(\"move.spectrum\", [get()])\n }\n\n function updateUI() {\n textInput.removeClass(\"sp-validation-error\");\n updateHelperLocations();\n var flatColor = tinycolor.fromRatio({h: currentHue, s: 1, v: 1});\n dragger.css(\"background-color\", flatColor.toHexString());\n var format = currentPreferredFormat;\n if (currentAlpha < 1 && !(currentAlpha === 0 && format === \"name\")) {\n if (format === \"hex\" || format === \"hex3\" || format === \"hex6\" || format === \"name\") {\n format = \"rgb\"\n }\n }\n var realColor = get({format: format}), displayColor = \"\";\n previewElement.removeClass(\"sp-clear-display\");\n previewElement.css(\"background-color\", \"transparent\");\n if (!realColor && allowEmpty) {\n previewElement.addClass(\"sp-clear-display\")\n } else {\n var realHex = realColor.toHexString(), realRgb = realColor.toRgbString();\n if (rgbaSupport || realColor.alpha === 1) {\n previewElement.css(\"background-color\", realRgb)\n } else {\n previewElement.css(\"background-color\", \"transparent\");\n previewElement.css(\"filter\", realColor.toFilter())\n }\n if (opts.showAlpha) {\n var rgb = realColor.toRgb();\n rgb.a = 0;\n var realAlpha = tinycolor(rgb).toRgbString();\n var gradient = \"linear-gradient(left, \" + realAlpha + \", \" + realHex + \")\";\n if (IE) {\n alphaSliderInner.css(\"filter\", tinycolor(realAlpha).toFilter({gradientType: 1}, realHex))\n } else {\n alphaSliderInner.css(\"background\", \"-webkit-\" + gradient);\n alphaSliderInner.css(\"background\", \"-moz-\" + gradient);\n alphaSliderInner.css(\"background\", \"-ms-\" + gradient);\n alphaSliderInner.css(\"background\", \"linear-gradient(to right, \" + realAlpha + \", \" + realHex + \")\")\n }\n }\n displayColor = realColor.toString(format)\n }\n if (opts.showInput) {\n textInput.val(displayColor)\n }\n if (opts.showPalette) {\n drawPalette()\n }\n drawInitial()\n }\n\n function updateHelperLocations() {\n var s = currentSaturation;\n var v = currentValue;\n if (allowEmpty && isEmpty) {\n alphaSlideHelper.hide();\n slideHelper.hide();\n dragHelper.hide()\n } else {\n alphaSlideHelper.show();\n slideHelper.show();\n dragHelper.show();\n var dragX = s * dragWidth;\n var dragY = dragHeight - v * dragHeight;\n dragX = Math.max(-dragHelperHeight, Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight));\n dragY = Math.max(-dragHelperHeight, Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight));\n dragHelper.css({top: dragY + \"px\", left: dragX + \"px\"});\n var alphaX = currentAlpha * alphaWidth;\n alphaSlideHelper.css({left: alphaX - alphaSlideHelperWidth / 2 + \"px\"});\n var slideY = currentHue * slideHeight;\n slideHelper.css({top: slideY - slideHelperHeight + \"px\"})\n }\n }\n\n function updateOriginalInput(fireCallback) {\n var color = get(), displayColor = \"\", hasChanged = !tinycolor.equals(color, colorOnShow);\n if (color) {\n displayColor = color.toString(currentPreferredFormat);\n addColorToSelectionPalette(color)\n }\n if (isInput) {\n boundElement.val(displayColor)\n }\n if (fireCallback && hasChanged) {\n callbacks.change(color);\n boundElement.trigger(\"change\", [color])\n }\n }\n\n function reflow() {\n if (!visible) {\n return\n }\n dragWidth = dragger.width();\n dragHeight = dragger.height();\n dragHelperHeight = dragHelper.height();\n slideWidth = slider.width();\n slideHeight = slider.height();\n slideHelperHeight = slideHelper.height();\n alphaWidth = alphaSlider.width();\n alphaSlideHelperWidth = alphaSlideHelper.width();\n if (!flat) {\n container.css(\"position\", \"absolute\");\n if (opts.offset) {\n container.offset(opts.offset)\n } else {\n container.offset(getOffset(container, offsetElement))\n }\n }\n updateHelperLocations();\n if (opts.showPalette) {\n drawPalette()\n }\n boundElement.trigger(\"reflow.spectrum\")\n }\n\n function destroy() {\n boundElement.show();\n offsetElement.unbind(\"click.spectrum touchstart.spectrum\");\n container.remove();\n replacer.remove();\n spectrums[spect.id] = null\n }\n\n function option(optionName, optionValue) {\n if (optionName === undefined) {\n return $.extend({}, opts)\n }\n if (optionValue === undefined) {\n return opts[optionName]\n }\n opts[optionName] = optionValue;\n if (optionName === \"preferredFormat\") {\n currentPreferredFormat = opts.preferredFormat\n }\n applyOptions()\n }\n\n function enable() {\n disabled = false;\n boundElement.attr(\"disabled\", false);\n offsetElement.removeClass(\"sp-disabled\")\n }\n\n function disable() {\n hide();\n disabled = true;\n boundElement.attr(\"disabled\", true);\n offsetElement.addClass(\"sp-disabled\")\n }\n\n function setOffset(coord) {\n opts.offset = coord;\n reflow()\n }\n\n initialize();\n var spect = {\n show: show, hide: hide, toggle: toggle, reflow: reflow, option: option, enable: enable, disable: disable, offset: setOffset, set: function (c) {\n set(c);\n updateOriginalInput()\n }, get: get, destroy: destroy, container: container\n };\n spect.id = spectrums.push(spect) - 1;\n return spect\n }\n\n function getOffset(picker, input) {\n var extraY = 0;\n var dpWidth = picker.outerWidth();\n var dpHeight = picker.outerHeight();\n var inputHeight = input.outerHeight();\n var doc = picker[0].ownerDocument;\n var docElem = doc.documentElement;\n var viewWidth = docElem.clientWidth + $(doc).scrollLeft();\n var viewHeight = docElem.clientHeight + $(doc).scrollTop();\n var offset = input.offset();\n offset.top += inputHeight;\n offset.left -= Math.min(offset.left, offset.left + dpWidth > viewWidth && viewWidth > dpWidth ? Math.abs(offset.left + dpWidth - viewWidth) : 0);\n offset.top -= Math.min(offset.top, offset.top + dpHeight > viewHeight && viewHeight > dpHeight ? Math.abs(dpHeight + inputHeight - extraY) : extraY);\n return offset\n }\n\n function noop() {\n }\n\n function stopPropagation(e) {\n e.stopPropagation()\n }\n\n function bind(func, obj) {\n var slice = Array.prototype.slice;\n var args = slice.call(arguments, 2);\n return function () {\n return func.apply(obj, args.concat(slice.call(arguments)))\n }\n }\n\n function draggable(element, onmove, onstart, onstop) {\n onmove = onmove || function () {\n };\n onstart = onstart || function () {\n };\n onstop = onstop || function () {\n };\n var doc = document;\n var dragging = false;\n var offset = {};\n var maxHeight = 0;\n var maxWidth = 0;\n var hasTouch = \"ontouchstart\" in window;\n var duringDragEvents = {};\n duringDragEvents[\"selectstart\"] = prevent;\n duringDragEvents[\"dragstart\"] = prevent;\n duringDragEvents[\"touchmove mousemove\"] = move;\n duringDragEvents[\"touchend mouseup\"] = stop;\n\n function prevent(e) {\n if (e.stopPropagation) {\n e.stopPropagation()\n }\n if (e.preventDefault) {\n e.preventDefault()\n }\n e.returnValue = false\n }\n\n function move(e) {\n if (dragging) {\n if (IE && doc.documentMode < 9 && !e.button) {\n return stop()\n }\n var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];\n var pageX = t0 && t0.pageX || e.pageX;\n var pageY = t0 && t0.pageY || e.pageY;\n var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));\n var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));\n if (hasTouch) {\n prevent(e)\n }\n onmove.apply(element, [dragX, dragY, e])\n }\n }\n\n function start(e) {\n var rightclick = e.which ? e.which == 3 : e.button == 2;\n if (!rightclick && !dragging) {\n if (onstart.apply(element, arguments) !== false) {\n dragging = true;\n maxHeight = $(element).height();\n maxWidth = $(element).width();\n offset = $(element).offset();\n $(doc).bind(duringDragEvents);\n $(doc.body).addClass(\"sp-dragging\");\n move(e);\n prevent(e)\n }\n }\n }\n\n function stop() {\n if (dragging) {\n $(doc).unbind(duringDragEvents);\n $(doc.body).removeClass(\"sp-dragging\");\n setTimeout(function () {\n onstop.apply(element, arguments)\n }, 0)\n }\n dragging = false\n }\n\n $(element).bind(\"touchstart mousedown\", start)\n }\n\n function throttle(func, wait, debounce) {\n var timeout;\n return function () {\n var context = this, args = arguments;\n var throttler = function () {\n timeout = null;\n func.apply(context, args)\n };\n if (debounce) clearTimeout(timeout);\n if (debounce || !timeout) timeout = setTimeout(throttler, wait)\n }\n }\n\n function inputTypeColorSupport() {\n return $.fn.spectrum.inputTypeColorSupport()\n }\n\n var dataID = \"spectrum.id\";\n $.fn.spectrum = function (opts, extra) {\n if (typeof opts == \"string\") {\n var returnValue = this;\n var args = Array.prototype.slice.call(arguments, 1);\n this.each(function () {\n var spect = spectrums[$(this).data(dataID)];\n if (spect) {\n var method = spect[opts];\n if (!method) {\n throw new Error(\"Spectrum: no such method: '\" + opts + \"'\")\n }\n if (opts == \"get\") {\n returnValue = spect.get()\n } else if (opts == \"container\") {\n returnValue = spect.container\n } else if (opts == \"option\") {\n returnValue = spect.option.apply(spect, args)\n } else if (opts == \"destroy\") {\n spect.destroy();\n $(this).removeData(dataID)\n } else {\n method.apply(spect, args)\n }\n }\n });\n return returnValue\n }\n return this.spectrum(\"destroy\").each(function () {\n var options = $.extend({}, opts, $(this).data());\n var spect = spectrum(this, options);\n $(this).data(dataID, spect.id)\n })\n };\n $.fn.spectrum.load = true;\n $.fn.spectrum.loadOpts = {};\n $.fn.spectrum.draggable = draggable;\n $.fn.spectrum.defaults = defaultOpts;\n $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {\n if (typeof inputTypeColorSupport._cachedResult === \"undefined\") {\n var colorInput = $(\" \")[0];\n inputTypeColorSupport._cachedResult = colorInput.type === \"color\" && colorInput.value !== \"\"\n }\n return inputTypeColorSupport._cachedResult\n };\n $.spectrum = {};\n $.spectrum.localization = {};\n $.spectrum.palettes = {};\n $.fn.spectrum.processNativeColorInputs = function () {\n var colorInputs = $(\"input[type=color]\");\n if (colorInputs.length && !inputTypeColorSupport()) {\n colorInputs.spectrum({preferredFormat: \"hex6\"})\n }\n };\n (function () {\n var trimLeft = /^[\\s,#]+/, trimRight = /\\s+$/, tinyCounter = 0, math = Math, mathRound = math.round, mathMin = math.min, mathMax = math.max, mathRandom = math.random;\n var tinycolor = function (color, opts) {\n color = color ? color : \"\";\n opts = opts || {};\n if (color instanceof tinycolor) {\n return color\n }\n if (!(this instanceof tinycolor)) {\n return new tinycolor(color, opts)\n }\n var rgb = inputToRGB(color);\n this._originalInput = color, this._r = rgb.r, this._g = rgb.g, this._b = rgb.b, this._a = rgb.a, this._roundA = mathRound(100 * this._a) / 100, this._format = opts.format || rgb.format;\n this._gradientType = opts.gradientType;\n if (this._r < 1) {\n this._r = mathRound(this._r)\n }\n if (this._g < 1) {\n this._g = mathRound(this._g)\n }\n if (this._b < 1) {\n this._b = mathRound(this._b)\n }\n this._ok = rgb.ok;\n this._tc_id = tinyCounter++\n };\n tinycolor.prototype = {\n isDark: function () {\n return this.getBrightness() < 128\n }, isLight: function () {\n return !this.isDark()\n }, isValid: function () {\n return this._ok\n }, getOriginalInput: function () {\n return this._originalInput\n }, getFormat: function () {\n return this._format\n }, getAlpha: function () {\n return this._a\n }, getBrightness: function () {\n var rgb = this.toRgb();\n return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1e3\n }, setAlpha: function (value) {\n this._a = boundAlpha(value);\n this._roundA = mathRound(100 * this._a) / 100;\n return this\n }, toHsv: function () {\n var hsv = rgbToHsv(this._r, this._g, this._b);\n return {h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a}\n }, toHsvString: function () {\n var hsv = rgbToHsv(this._r, this._g, this._b);\n var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);\n return this._a == 1 ? \"hsv(\" + h + \", \" + s + \"%, \" + v + \"%)\" : \"hsva(\" + h + \", \" + s + \"%, \" + v + \"%, \" + this._roundA + \")\"\n }, toHsl: function () {\n var hsl = rgbToHsl(this._r, this._g, this._b);\n return {h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a}\n }, toHslString: function () {\n var hsl = rgbToHsl(this._r, this._g, this._b);\n var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);\n return this._a == 1 ? \"hsl(\" + h + \", \" + s + \"%, \" + l + \"%)\" : \"hsla(\" + h + \", \" + s + \"%, \" + l + \"%, \" + this._roundA + \")\"\n }, toHex: function (allow3Char) {\n return rgbToHex(this._r, this._g, this._b, allow3Char)\n }, toHexString: function (allow3Char) {\n return \"#\" + this.toHex(allow3Char)\n }, toHex8: function () {\n return rgbaToHex(this._r, this._g, this._b, this._a)\n }, toHex8String: function () {\n return \"#\" + this.toHex8()\n }, toRgb: function () {\n return {r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a}\n }, toRgbString: function () {\n return this._a == 1 ? \"rgb(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \")\" : \"rgba(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \", \" + this._roundA + \")\"\n }, toPercentageRgb: function () {\n return {\n r: mathRound(bound01(this._r, 255) * 100) + \"%\",\n g: mathRound(bound01(this._g, 255) * 100) + \"%\",\n b: mathRound(bound01(this._b, 255) * 100) + \"%\",\n a: this._a\n }\n }, toPercentageRgbString: function () {\n return this._a == 1 ? \"rgb(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%)\" : \"rgba(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%, \" + this._roundA + \")\"\n }, toName: function () {\n if (this._a === 0) {\n return \"transparent\"\n }\n if (this._a < 1) {\n return false\n }\n return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false\n }, toFilter: function (secondColor) {\n var hex8String = \"#\" + rgbaToHex(this._r, this._g, this._b, this._a);\n var secondHex8String = hex8String;\n var gradientType = this._gradientType ? \"GradientType = 1, \" : \"\";\n if (secondColor) {\n var s = tinycolor(secondColor);\n secondHex8String = s.toHex8String()\n }\n return \"progid:DXImageTransform.Microsoft.gradient(\" + gradientType + \"startColorstr=\" + hex8String + \",endColorstr=\" + secondHex8String + \")\"\n }, toString: function (format) {\n var formatSet = !!format;\n format = format || this._format;\n var formattedString = false;\n var hasAlpha = this._a < 1 && this._a >= 0;\n var needsAlphaFormat = !formatSet && hasAlpha && (format === \"hex\" || format === \"hex6\" || format === \"hex3\" || format === \"name\");\n if (needsAlphaFormat) {\n if (format === \"name\" && this._a === 0) {\n return this.toName()\n }\n return this.toRgbString()\n }\n if (format === \"rgb\") {\n formattedString = this.toRgbString()\n }\n if (format === \"prgb\") {\n formattedString = this.toPercentageRgbString()\n }\n if (format === \"hex\" || format === \"hex6\") {\n formattedString = this.toHexString()\n }\n if (format === \"hex3\") {\n formattedString = this.toHexString(true)\n }\n if (format === \"hex8\") {\n formattedString = this.toHex8String()\n }\n if (format === \"name\") {\n formattedString = this.toName()\n }\n if (format === \"hsl\") {\n formattedString = this.toHslString()\n }\n if (format === \"hsv\") {\n formattedString = this.toHsvString()\n }\n return formattedString || this.toHexString()\n }, _applyModification: function (fn, args) {\n var color = fn.apply(null, [this].concat([].slice.call(args)));\n this._r = color._r;\n this._g = color._g;\n this._b = color._b;\n this.setAlpha(color._a);\n return this\n }, lighten: function () {\n return this._applyModification(lighten, arguments)\n }, brighten: function () {\n return this._applyModification(brighten, arguments)\n }, darken: function () {\n return this._applyModification(darken, arguments)\n }, desaturate: function () {\n return this._applyModification(desaturate, arguments)\n }, saturate: function () {\n return this._applyModification(saturate, arguments)\n }, greyscale: function () {\n return this._applyModification(greyscale, arguments)\n }, spin: function () {\n return this._applyModification(spin, arguments)\n }, _applyCombination: function (fn, args) {\n return fn.apply(null, [this].concat([].slice.call(args)))\n }, analogous: function () {\n return this._applyCombination(analogous, arguments)\n }, complement: function () {\n return this._applyCombination(complement, arguments)\n }, monochromatic: function () {\n return this._applyCombination(monochromatic, arguments)\n }, splitcomplement: function () {\n return this._applyCombination(splitcomplement, arguments)\n }, triad: function () {\n return this._applyCombination(triad, arguments)\n }, tetrad: function () {\n return this._applyCombination(tetrad, arguments)\n }\n };\n tinycolor.fromRatio = function (color, opts) {\n if (typeof color == \"object\") {\n var newColor = {};\n for (var i in color) {\n if (color.hasOwnProperty(i)) {\n if (i === \"a\") {\n newColor[i] = color[i]\n } else {\n newColor[i] = convertToPercentage(color[i])\n }\n }\n }\n color = newColor\n }\n return tinycolor(color, opts)\n };\n\n function inputToRGB(color) {\n var rgb = {r: 0, g: 0, b: 0};\n var a = 1;\n var ok = false;\n var format = false;\n if (typeof color == \"string\") {\n color = stringInputToObject(color)\n }\n if (typeof color == \"object\") {\n if (color.hasOwnProperty(\"r\") && color.hasOwnProperty(\"g\") && color.hasOwnProperty(\"b\")) {\n rgb = rgbToRgb(color.r, color.g, color.b);\n ok = true;\n format = String(color.r).substr(-1) === \"%\" ? \"prgb\" : \"rgb\"\n } else if (color.hasOwnProperty(\"h\") && color.hasOwnProperty(\"s\") && color.hasOwnProperty(\"v\")) {\n color.s = convertToPercentage(color.s);\n color.v = convertToPercentage(color.v);\n rgb = hsvToRgb(color.h, color.s, color.v);\n ok = true;\n format = \"hsv\"\n } else if (color.hasOwnProperty(\"h\") && color.hasOwnProperty(\"s\") && color.hasOwnProperty(\"l\")) {\n color.s = convertToPercentage(color.s);\n color.l = convertToPercentage(color.l);\n rgb = hslToRgb(color.h, color.s, color.l);\n ok = true;\n format = \"hsl\"\n }\n if (color.hasOwnProperty(\"a\")) {\n a = color.a\n }\n }\n a = boundAlpha(a);\n return {ok: ok, format: color.format || format, r: mathMin(255, mathMax(rgb.r, 0)), g: mathMin(255, mathMax(rgb.g, 0)), b: mathMin(255, mathMax(rgb.b, 0)), a: a}\n }\n\n function rgbToRgb(r, g, b) {\n return {r: bound01(r, 255) * 255, g: bound01(g, 255) * 255, b: bound01(b, 255) * 255}\n }\n\n function rgbToHsl(r, g, b) {\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, l = (max + min) / 2;\n if (max == min) {\n h = s = 0\n } else {\n var d = max - min;\n s = l > .5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break\n }\n h /= 6\n }\n return {h: h, s: s, l: l}\n }\n\n function hslToRgb(h, s, l) {\n var r, g, b;\n h = bound01(h, 360);\n s = bound01(s, 100);\n l = bound01(l, 100);\n\n function hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p\n }\n\n if (s === 0) {\n r = g = b = l\n } else {\n var q = l < .5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3)\n }\n return {r: r * 255, g: g * 255, b: b * 255}\n }\n\n function rgbToHsv(r, g, b) {\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, v = max;\n var d = max - min;\n s = max === 0 ? 0 : d / max;\n if (max == min) {\n h = 0\n } else {\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break\n }\n h /= 6\n }\n return {h: h, s: s, v: v}\n }\n\n function hsvToRgb(h, s, v) {\n h = bound01(h, 360) * 6;\n s = bound01(s, 100);\n v = bound01(v, 100);\n var i = math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod],\n g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod];\n return {r: r * 255, g: g * 255, b: b * 255}\n }\n\n function rgbToHex(r, g, b, allow3Char) {\n var hex = [pad2(mathRound(r).toString(16)), pad2(mathRound(g).toString(16)), pad2(mathRound(b).toString(16))];\n if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {\n return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0)\n }\n return hex.join(\"\")\n }\n\n function rgbaToHex(r, g, b, a) {\n var hex = [pad2(convertDecimalToHex(a)), pad2(mathRound(r).toString(16)), pad2(mathRound(g).toString(16)), pad2(mathRound(b).toString(16))];\n return hex.join(\"\")\n }\n\n tinycolor.equals = function (color1, color2) {\n if (!color1 || !color2) {\n return false\n }\n return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString()\n };\n tinycolor.random = function () {\n return tinycolor.fromRatio({\n r: mathRandom(), g: mathRandom(),\n b: mathRandom()\n })\n };\n\n function desaturate(color, amount) {\n amount = amount === 0 ? 0 : amount || 10;\n var hsl = tinycolor(color).toHsl();\n hsl.s -= amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl)\n }\n\n function saturate(color, amount) {\n amount = amount === 0 ? 0 : amount || 10;\n var hsl = tinycolor(color).toHsl();\n hsl.s += amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl)\n }\n\n function greyscale(color) {\n return tinycolor(color).desaturate(100)\n }\n\n function lighten(color, amount) {\n amount = amount === 0 ? 0 : amount || 10;\n var hsl = tinycolor(color).toHsl();\n hsl.l += amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl)\n }\n\n function brighten(color, amount) {\n amount = amount === 0 ? 0 : amount || 10;\n var rgb = tinycolor(color).toRgb();\n rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * -(amount / 100))));\n rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * -(amount / 100))));\n rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * -(amount / 100))));\n return tinycolor(rgb)\n }\n\n function darken(color, amount) {\n amount = amount === 0 ? 0 : amount || 10;\n var hsl = tinycolor(color).toHsl();\n hsl.l -= amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl)\n }\n\n function spin(color, amount) {\n var hsl = tinycolor(color).toHsl();\n var hue = (mathRound(hsl.h) + amount) % 360;\n hsl.h = hue < 0 ? 360 + hue : hue;\n return tinycolor(hsl)\n }\n\n function complement(color) {\n var hsl = tinycolor(color).toHsl();\n hsl.h = (hsl.h + 180) % 360;\n return tinycolor(hsl)\n }\n\n function triad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [tinycolor(color), tinycolor({h: (h + 120) % 360, s: hsl.s, l: hsl.l}), tinycolor({h: (h + 240) % 360, s: hsl.s, l: hsl.l})]\n }\n\n function tetrad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [tinycolor(color), tinycolor({h: (h + 90) % 360, s: hsl.s, l: hsl.l}), tinycolor({h: (h + 180) % 360, s: hsl.s, l: hsl.l}), tinycolor({\n h: (h + 270) % 360,\n s: hsl.s,\n l: hsl.l\n })]\n }\n\n function splitcomplement(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [tinycolor(color), tinycolor({h: (h + 72) % 360, s: hsl.s, l: hsl.l}), tinycolor({h: (h + 216) % 360, s: hsl.s, l: hsl.l})]\n }\n\n function analogous(color, results, slices) {\n results = results || 6;\n slices = slices || 30;\n var hsl = tinycolor(color).toHsl();\n var part = 360 / slices;\n var ret = [tinycolor(color)];\n for (hsl.h = (hsl.h - (part * results >> 1) + 720) % 360; --results;) {\n hsl.h = (hsl.h + part) % 360;\n ret.push(tinycolor(hsl))\n }\n return ret\n }\n\n function monochromatic(color, results) {\n results = results || 6;\n var hsv = tinycolor(color).toHsv();\n var h = hsv.h, s = hsv.s, v = hsv.v;\n var ret = [];\n var modification = 1 / results;\n while (results--) {\n ret.push(tinycolor({h: h, s: s, v: v}));\n v = (v + modification) % 1\n }\n return ret\n }\n\n tinycolor.mix = function (color1, color2, amount) {\n amount = amount === 0 ? 0 : amount || 50;\n var rgb1 = tinycolor(color1).toRgb();\n var rgb2 = tinycolor(color2).toRgb();\n var p = amount / 100;\n var w = p * 2 - 1;\n var a = rgb2.a - rgb1.a;\n var w1;\n if (w * a == -1) {\n w1 = w\n } else {\n w1 = (w + a) / (1 + w * a)\n }\n w1 = (w1 + 1) / 2;\n var w2 = 1 - w1;\n var rgba = {r: rgb2.r * w1 + rgb1.r * w2, g: rgb2.g * w1 + rgb1.g * w2, b: rgb2.b * w1 + rgb1.b * w2, a: rgb2.a * p + rgb1.a * (1 - p)};\n return tinycolor(rgba)\n };\n tinycolor.readability = function (color1, color2) {\n var c1 = tinycolor(color1);\n var c2 = tinycolor(color2);\n var rgb1 = c1.toRgb();\n var rgb2 = c2.toRgb();\n var brightnessA = c1.getBrightness();\n var brightnessB = c2.getBrightness();\n var colorDiff = Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) + Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) + Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b);\n return {brightness: Math.abs(brightnessA - brightnessB), color: colorDiff}\n };\n tinycolor.isReadable = function (color1, color2) {\n var readability = tinycolor.readability(color1, color2);\n return readability.brightness > 125 && readability.color > 500\n };\n tinycolor.mostReadable = function (baseColor, colorList) {\n var bestColor = null;\n var bestScore = 0;\n var bestIsReadable = false;\n for (var i = 0; i < colorList.length; i++) {\n var readability = tinycolor.readability(baseColor, colorList[i]);\n var readable = readability.brightness > 125 && readability.color > 500;\n var score = 3 * (readability.brightness / 125) + readability.color / 500;\n if (readable && !bestIsReadable || readable && bestIsReadable && score > bestScore || !readable && !bestIsReadable && score > bestScore) {\n bestIsReadable = readable;\n bestScore = score;\n bestColor = tinycolor(colorList[i])\n }\n }\n return bestColor\n };\n var names = tinycolor.names = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"0ff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000\",\n blanchedalmond: \"ffebcd\",\n blue: \"00f\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n burntsienna: \"ea7e5d\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"0ff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkgrey: \"a9a9a9\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkslategrey: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dimgrey: \"696969\",\n dodgerblue: \"1e90ff\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"f0f\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n grey: \"808080\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgray: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightgrey: \"d3d3d3\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslategray: \"789\",\n lightslategrey: \"789\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"0f0\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"f0f\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370db\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"db7093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n rebeccapurple: \"663399\",\n red: \"f00\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n slategrey: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n wheat: \"f5deb3\",\n white: \"fff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ff0\",\n yellowgreen: \"9acd32\"\n };\n var hexNames = tinycolor.hexNames = flip(names);\n\n function flip(o) {\n var flipped = {};\n for (var i in o) {\n if (o.hasOwnProperty(i)) {\n flipped[o[i]] = i\n }\n }\n return flipped\n }\n\n function boundAlpha(a) {\n a = parseFloat(a);\n if (isNaN(a) || a < 0 || a > 1) {\n a = 1\n }\n return a\n }\n\n function bound01(n, max) {\n if (isOnePointZero(n)) {\n n = \"100%\"\n }\n var processPercent = isPercentage(n);\n n = mathMin(max, mathMax(0, parseFloat(n)));\n if (processPercent) {\n n = parseInt(n * max, 10) / 100\n }\n if (math.abs(n - max) < 1e-6) {\n return 1\n }\n return n % max / parseFloat(max)\n }\n\n function clamp01(val) {\n return mathMin(1, mathMax(0, val))\n }\n\n function parseIntFromHex(val) {\n return parseInt(val, 16)\n }\n\n function isOnePointZero(n) {\n return typeof n == \"string\" && n.indexOf(\".\") != -1 && parseFloat(n) === 1\n }\n\n function isPercentage(n) {\n return typeof n === \"string\" && n.indexOf(\"%\") != -1\n }\n\n function pad2(c) {\n return c.length == 1 ? \"0\" + c : \"\" + c\n }\n\n function convertToPercentage(n) {\n if (n <= 1) {\n n = n * 100 + \"%\"\n }\n return n\n }\n\n function convertDecimalToHex(d) {\n return Math.round(parseFloat(d) * 255).toString(16)\n }\n\n function convertHexToDecimal(h) {\n return parseIntFromHex(h) / 255\n }\n\n var matchers = function () {\n var CSS_INTEGER = \"[-\\\\+]?\\\\d+%?\";\n var CSS_NUMBER = \"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\";\n var CSS_UNIT = \"(?:\" + CSS_NUMBER + \")|(?:\" + CSS_INTEGER + \")\";\n var PERMISSIVE_MATCH3 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n var PERMISSIVE_MATCH4 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n return {\n rgb: new RegExp(\"rgb\" + PERMISSIVE_MATCH3),\n rgba: new RegExp(\"rgba\" + PERMISSIVE_MATCH4),\n hsl: new RegExp(\"hsl\" + PERMISSIVE_MATCH3),\n hsla: new RegExp(\"hsla\" + PERMISSIVE_MATCH4),\n hsv: new RegExp(\"hsv\" + PERMISSIVE_MATCH3),\n hsva: new RegExp(\"hsva\" + PERMISSIVE_MATCH4),\n hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,\n hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n }\n }();\n\n function stringInputToObject(color) {\n color = color.replace(trimLeft, \"\").replace(trimRight, \"\").toLowerCase();\n var named = false;\n if (names[color]) {\n color = names[color];\n named = true\n } else if (color == \"transparent\") {\n return {r: 0, g: 0, b: 0, a: 0, format: \"name\"}\n }\n var match;\n if (match = matchers.rgb.exec(color)) {\n return {r: match[1], g: match[2], b: match[3]}\n }\n if (match = matchers.rgba.exec(color)) {\n return {r: match[1], g: match[2], b: match[3], a: match[4]}\n }\n if (match = matchers.hsl.exec(color)) {\n return {h: match[1], s: match[2], l: match[3]}\n }\n if (match = matchers.hsla.exec(color)) {\n return {h: match[1], s: match[2], l: match[3], a: match[4]}\n }\n if (match = matchers.hsv.exec(color)) {\n return {h: match[1], s: match[2], v: match[3]}\n }\n if (match = matchers.hsva.exec(color)) {\n return {h: match[1], s: match[2], v: match[3], a: match[4]}\n }\n if (match = matchers.hex8.exec(color)) {\n return {a: convertHexToDecimal(match[1]), r: parseIntFromHex(match[2]), g: parseIntFromHex(match[3]), b: parseIntFromHex(match[4]), format: named ? \"name\" : \"hex8\"}\n }\n if (match = matchers.hex6.exec(color)) {\n return {r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), format: named ? \"name\" : \"hex\"}\n }\n if (match = matchers.hex3.exec(color)) {\n return {\n r: parseIntFromHex(match[1] + \"\" + match[1]),\n g: parseIntFromHex(match[2] + \"\" + match[2]),\n b: parseIntFromHex(match[3] + \"\" + match[3]),\n format: named ? \"name\" : \"hex\"\n }\n }\n return false\n }\n\n window.tinycolor = tinycolor\n })();\n $(function () {\n if ($.fn.spectrum.load) {\n $.fn.spectrum.processNativeColorInputs()\n }\n })\n});\n"],"names":["factory","$","undefined","defaultOpts","beforeShow","noop","move","change","show","hide","color","flat","showInput","allowEmpty","showButtons","clickoutFiresChange","showInitial","showPalette","showPaletteOnly","hideAfterPaletteSelect","togglePaletteOnly","showSelectionPalette","localStorageKey","appendTo","maxSelectionSize","cancelText","chooseText","togglePaletteMoreText","togglePaletteLessText","clearText","noColorSelectedText","preferredFormat","className","containerClassName","replacerClassName","showAlpha","theme","palette","selectionPalette","disabled","offset","spectrums","IE","exec","window","navigator","userAgent","rgbaSupport","contains","str","substr","indexOf","style","document","createElement","cssText","backgroundColor","replaceInput","join","markup","gradientFix","i","paletteTemplate","p","opts","html","length","current","tiny","tinycolor","c","toHsl","l","equals","formattedString","toString","swatchStyle","toRgbString","toFilter","push","append","attr","spectrum","element","o","func","wait","debounce","timeout","callbackContext","extend","callbacks","bind","instanceOptions","resize","reflow","context","this","args","arguments","throttler","apply","clearTimeout","setTimeout","visible","isDragging","dragWidth","dragHeight","dragHelperHeight","slideHeight","alphaWidth","alphaSlideHelperWidth","slideHelperHeight","currentHue","currentSaturation","currentValue","currentAlpha","paletteArray","paletteLookup","slice","shiftMovementDirection","doc","ownerDocument","boundElement","body","container","addClass","pickerContainer","find","dragger","dragHelper","slider","slideHelper","alphaSliderInner","alphaSlider","alphaSlideHelper","textInput","paletteContainer","initialColorContainer","cancelButton","clearButton","chooseButton","toggleButton","isInput","is","isInputTypeColor","inputTypeColorSupport","shouldReplace","replacer","offsetElement","previewElement","initialColor","val","colorOnShow","currentPreferredFormat","isEmpty","applyOptions","text","isArray","j","rgb","toggleClass","updateSelectionPaletteFromStorage","localStorage","oldPalette","split","each","addColorToSelectionPalette","e","inArray","shift","drawPalette","currentColor","get","map","unique","reverse","getUniqueSelectionPalette","drawInitial","initial","dragStart","trigger","dragStop","removeClass","setFromTextInput","value","isValid","set","updateOriginalInput","toggle","event","Event","isDefaultPrevented","hideAll","onkeydown","clickout","updateUI","keyCode","button","revert","unbind","ignoreFormatChange","newColor","newHsv","toHsv","h","s","v","a","getFormat","fromRatio","Math","round","format","updateHelperLocations","flatColor","css","toHexString","realColor","displayColor","realHex","realRgb","alpha","toRgb","realAlpha","gradient","gradientType","dragX","dragY","max","min","top","left","alphaX","slideY","fireCallback","hasChanged","width","height","picker","input","extraY","dpWidth","outerWidth","dpHeight","outerHeight","inputHeight","docElem","documentElement","viewWidth","clientWidth","scrollLeft","viewHeight","clientHeight","scrollTop","abs","getOffset","disable","after","parent","paletteElementClick","data","ignore","target","closest","stopPropagation","preventDefault","click","keydown","hasClass","draggable","shiftKey","parseFloat","oldDragX","oldDragY","furtherFromX","setValue","paletteEvent","delegate","initialize","spect","option","optionName","optionValue","enable","coord","destroy","remove","id","obj","Array","prototype","call","concat","onmove","onstart","onstop","dragging","maxHeight","maxWidth","hasTouch","duringDragEvents","prevent","returnValue","documentMode","stop","t0","originalEvent","touches","pageX","pageY","rightclick","which","fn","dataID","extra","method","Error","removeData","load","loadOpts","defaults","_cachedResult","colorInput","type","localization","palettes","processNativeColorInputs","colorInputs","trimLeft","trimRight","tinyCounter","math","mathRound","mathMin","mathMax","mathRandom","random","r","g","b","ok","replace","toLowerCase","match","named","names","matchers","rgba","hsl","hsla","hsv","hsva","hex8","convertHexToDecimal","parseIntFromHex","hex6","hex3","stringInputToObject","hasOwnProperty","bound01","String","convertToPercentage","floor","f","q","t","mod","hsvToRgb","hue2rgb","hslToRgb","boundAlpha","inputToRGB","_originalInput","_r","_g","_b","_a","_roundA","_format","_gradientType","_ok","_tc_id","rgbToHsl","d","rgbToHsv","rgbToHex","allow3Char","hex","pad2","charAt","rgbaToHex","desaturate","amount","clamp01","saturate","greyscale","lighten","brighten","darken","spin","hue","complement","triad","tetrad","splitcomplement","analogous","results","slices","part","ret","monochromatic","modification","isDark","getBrightness","isLight","getOriginalInput","getAlpha","setAlpha","toHsvString","toHslString","toHex","toHex8","toHex8String","toPercentageRgb","toPercentageRgbString","toName","hexNames","secondColor","hex8String","secondHex8String","formatSet","hasAlpha","_applyModification","_applyCombination","color1","color2","mix","w1","rgb1","rgb2","w","w2","readability","c1","c2","brightnessA","brightnessB","colorDiff","brightness","isReadable","mostReadable","baseColor","colorList","bestColor","bestScore","bestIsReadable","readable","score","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","burntsienna","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","flipped","flip","isNaN","n","isOnePointZero","processPercent","isPercentage","parseInt","CSS_UNIT","PERMISSIVE_MATCH3","PERMISSIVE_MATCH4","RegExp","define","amd","exports","module","require","jQuery"],"mappings":"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"}
\ No newline at end of file
diff --git a/amd/src/canvas.js b/amd/src/canvas.js
index 5700005..b7de176 100644
--- a/amd/src/canvas.js
+++ b/amd/src/canvas.js
@@ -25,7 +25,7 @@
**/
/* global fabric */
/* eslint no-unused-expressions: "off", no-console:off, no-invalid-this:"off",no-script-url:"off", block-scoped-var: "off" */
-define(['jquery', 'core/notification'], function($, notification) {
+define(['jquery', 'core/notification', 'mod_gcanvas/spectrum'], function ($, notification) {
'use strict';
/**
@@ -978,27 +978,18 @@ define(['jquery', 'core/notification'], function($, notification) {
* Init
* @param {object} args
*/
- initialise: function(args) {
+ initialise: function (args) {
- // Load spectrum javascript form here.
- $.getScript(M.cfg.wwwroot + "/mod/gcanvas/javascript/spectrum.js").done(function() {
+ // Load the args passed from PHP.
+ setOptions(args);
- // Load the args passed from PHP.
- setOptions(args);
+ // Set internal debug console.
+ setDebug(opts.debugjs);
- // Set internal debug console.
- setDebug(opts.debugjs);
-
- $.noConflict();
- $(document).ready(function() {
- debug.log('Canvas Module v1.2');
- canvasModule.init();
- });
- }).fail(function(jqxhr, settings, exception) {
- // Display loading issue in console.
- debug.log(jqxhr);
- debug.log(settings);
- debug.log(exception);
+ $.noConflict();
+ $(document).ready(function () {
+ debug.log('Canvas Module v1.2');
+ canvasModule.init();
});
}
};
diff --git a/amd/src/spectrum.js b/amd/src/spectrum.js
new file mode 100644
index 0000000..e18c8b0
--- /dev/null
+++ b/amd/src/spectrum.js
@@ -0,0 +1,1662 @@
+/* eslint-disable */
+
+(function (factory) {
+ "use strict";
+ if (typeof define === "function" && define.amd) {
+ define(["jquery"], factory)
+ } else if (typeof exports == "object" && typeof module == "object") {
+ module.exports = factory(require("jquery"))
+ } else {
+ factory(jQuery)
+ }
+})(function ($, undefined) {
+ "use strict";
+ var defaultOpts = {
+ beforeShow: noop,
+ move: noop,
+ change: noop,
+ show: noop,
+ hide: noop,
+ color: false,
+ flat: false,
+ showInput: false,
+ allowEmpty: false,
+ showButtons: true,
+ clickoutFiresChange: true,
+ showInitial: false,
+ showPalette: false,
+ showPaletteOnly: false,
+ hideAfterPaletteSelect: false,
+ togglePaletteOnly: false,
+ showSelectionPalette: true,
+ localStorageKey: false,
+ appendTo: "body",
+ maxSelectionSize: 7,
+ cancelText: "cancel",
+ chooseText: "choose",
+ togglePaletteMoreText: "more",
+ togglePaletteLessText: "less",
+ clearText: "Clear Color Selection",
+ noColorSelectedText: "No Color Selected",
+ preferredFormat: false,
+ className: "",
+ containerClassName: "",
+ replacerClassName: "",
+ showAlpha: false,
+ theme: "sp-light",
+ palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
+ selectionPalette: [],
+ disabled: false,
+ offset: null
+ }, spectrums = [], IE = !!/msie/i.exec(window.navigator.userAgent), rgbaSupport = function () {
+ function contains(str, substr) {
+ return !!~("" + str).indexOf(substr)
+ }
+
+ var elem = document.createElement("div");
+ var style = elem.style;
+ style.cssText = "background-color:rgba(0,0,0,.5)";
+ return contains(style.backgroundColor, "rgba") || contains(style.backgroundColor, "hsla")
+ }(), replaceInput = [""].join(""),
+ markup = function () {
+ var gradientFix = "";
+ if (IE) {
+ for (var i = 1; i <= 6; i++) {
+ gradientFix += "
"
+ }
+ }
+ return ["", "
", "
", "
", "
", " ", "
", "
", "
", "
", "
"].join("")
+ }();
+
+ function paletteTemplate(p, color, className, opts) {
+ var html = [];
+ for (var i = 0; i < p.length; i++) {
+ var current = p[i];
+ if (current) {
+ var tiny = tinycolor(current);
+ var c = tiny.toHsl().l < .5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
+ c += tinycolor.equals(color, current) ? " sp-thumb-active" : "";
+ var formattedString = tiny.toString(opts.preferredFormat || "rgb");
+ var swatchStyle = rgbaSupport ? "background-color:" + tiny.toRgbString() : "filter:" + tiny.toFilter();
+ html.push(' ')
+ } else {
+ var cls = "sp-clear-display";
+ html.push($("
").append($(' ').attr("title", opts.noColorSelectedText)).html())
+ }
+ }
+ return "" + html.join("") + "
"
+ }
+
+ function hideAll() {
+ for (var i = 0; i < spectrums.length; i++) {
+ if (spectrums[i]) {
+ spectrums[i].hide()
+ }
+ }
+ }
+
+ function instanceOptions(o, callbackContext) {
+ var opts = $.extend({}, defaultOpts, o);
+ opts.callbacks = {
+ move: bind(opts.move, callbackContext),
+ change: bind(opts.change, callbackContext),
+ show: bind(opts.show, callbackContext),
+ hide: bind(opts.hide, callbackContext),
+ beforeShow: bind(opts.beforeShow, callbackContext)
+ };
+ return opts
+ }
+
+ function spectrum(element, o) {
+ var opts = instanceOptions(o, element), flat = opts.flat, showSelectionPalette = opts.showSelectionPalette, localStorageKey = opts.localStorageKey, theme = opts.theme,
+ callbacks = opts.callbacks, resize = throttle(reflow, 10), visible = false, isDragging = false, dragWidth = 0, dragHeight = 0, dragHelperHeight = 0, slideHeight = 0,
+ slideWidth = 0, alphaWidth = 0, alphaSlideHelperWidth = 0, slideHelperHeight = 0, currentHue = 0, currentSaturation = 0, currentValue = 0, currentAlpha = 1,
+ palette = [], paletteArray = [], paletteLookup = {}, selectionPalette = opts.selectionPalette.slice(0), maxSelectionSize = opts.maxSelectionSize,
+ draggingClass = "sp-dragging", shiftMovementDirection = null;
+ var doc = element.ownerDocument, body = doc.body, boundElement = $(element), disabled = false, container = $(markup, doc).addClass(theme),
+ pickerContainer = container.find(".sp-picker-container"), dragger = container.find(".sp-color"), dragHelper = container.find(".sp-dragger"),
+ slider = container.find(".sp-hue"), slideHelper = container.find(".sp-slider"), alphaSliderInner = container.find(".sp-alpha-inner"),
+ alphaSlider = container.find(".sp-alpha"), alphaSlideHelper = container.find(".sp-alpha-handle"), textInput = container.find(".sp-input"),
+ paletteContainer = container.find(".sp-palette"), initialColorContainer = container.find(".sp-initial"), cancelButton = container.find(".sp-cancel"),
+ clearButton = container.find(".sp-clear"), chooseButton = container.find(".sp-choose"), toggleButton = container.find(".sp-palette-toggle"),
+ isInput = boundElement.is("input"), isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(), shouldReplace = isInput && !flat,
+ replacer = shouldReplace ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
+ offsetElement = shouldReplace ? replacer : boundElement, previewElement = replacer.find(".sp-preview-inner"),
+ initialColor = opts.color || isInput && boundElement.val(), colorOnShow = false, currentPreferredFormat = opts.preferredFormat,
+ clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange, isEmpty = !initialColor, allowEmpty = opts.allowEmpty && !isInputTypeColor;
+
+ function applyOptions() {
+ if (opts.showPaletteOnly) {
+ opts.showPalette = true
+ }
+ toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
+ if (opts.palette) {
+ palette = opts.palette.slice(0);
+ paletteArray = $.isArray(palette[0]) ? palette : [palette];
+ paletteLookup = {};
+ for (var i = 0; i < paletteArray.length; i++) {
+ for (var j = 0; j < paletteArray[i].length; j++) {
+ var rgb = tinycolor(paletteArray[i][j]).toRgbString();
+ paletteLookup[rgb] = true
+ }
+ }
+ }
+ container.toggleClass("sp-flat", flat);
+ container.toggleClass("sp-input-disabled", !opts.showInput);
+ container.toggleClass("sp-alpha-enabled", opts.showAlpha);
+ container.toggleClass("sp-clear-enabled", allowEmpty);
+ container.toggleClass("sp-buttons-disabled", !opts.showButtons);
+ container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly);
+ container.toggleClass("sp-palette-disabled", !opts.showPalette);
+ container.toggleClass("sp-palette-only", opts.showPaletteOnly);
+ container.toggleClass("sp-initial-disabled", !opts.showInitial);
+ container.addClass(opts.className).addClass(opts.containerClassName);
+ reflow()
+ }
+
+ function initialize() {
+ if (IE) {
+ container.find("*:not(input)").attr("unselectable", "on")
+ }
+ applyOptions();
+ if (shouldReplace) {
+ boundElement.after(replacer).hide()
+ }
+ if (!allowEmpty) {
+ clearButton.hide()
+ }
+ if (flat) {
+ boundElement.after(container).hide()
+ } else {
+ var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
+ if (appendTo.length !== 1) {
+ appendTo = $("body")
+ }
+ appendTo.append(container)
+ }
+ updateSelectionPaletteFromStorage();
+ offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
+ if (!disabled) {
+ toggle()
+ }
+ e.stopPropagation();
+ if (!$(e.target).is("input")) {
+ e.preventDefault()
+ }
+ });
+ if (boundElement.is(":disabled") || opts.disabled === true) {
+ disable()
+ }
+ container.click(stopPropagation);
+ textInput.change(setFromTextInput);
+ textInput.bind("paste", function () {
+ setTimeout(setFromTextInput, 1)
+ });
+ textInput.keydown(function (e) {
+ if (e.keyCode == 13) {
+ setFromTextInput()
+ }
+ });
+ cancelButton.text(opts.cancelText);
+ cancelButton.bind("click.spectrum", function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ revert();
+ hide()
+ });
+ clearButton.attr("title", opts.clearText);
+ clearButton.bind("click.spectrum", function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ isEmpty = true;
+ move();
+ if (flat) {
+ updateOriginalInput(true)
+ }
+ });
+ chooseButton.text(opts.chooseText);
+ chooseButton.bind("click.spectrum", function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ if (IE && textInput.is(":focus")) {
+ textInput.trigger("change")
+ }
+ if (isValid()) {
+ updateOriginalInput(true);
+ hide()
+ }
+ });
+ toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
+ toggleButton.bind("click.spectrum", function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ opts.showPaletteOnly = !opts.showPaletteOnly;
+ if (!opts.showPaletteOnly && !flat) {
+ container.css("left", "-=" + (pickerContainer.outerWidth(true) + 5))
+ }
+ applyOptions()
+ });
+ draggable(alphaSlider, function (dragX, dragY, e) {
+ currentAlpha = dragX / alphaWidth;
+ isEmpty = false;
+ if (e.shiftKey) {
+ currentAlpha = Math.round(currentAlpha * 10) / 10
+ }
+ move()
+ }, dragStart, dragStop);
+ draggable(slider, function (dragX, dragY) {
+ currentHue = parseFloat(dragY / slideHeight);
+ isEmpty = false;
+ if (!opts.showAlpha) {
+ currentAlpha = 1
+ }
+ move()
+ }, dragStart, dragStop);
+ draggable(dragger, function (dragX, dragY, e) {
+ if (!e.shiftKey) {
+ shiftMovementDirection = null
+ } else if (!shiftMovementDirection) {
+ var oldDragX = currentSaturation * dragWidth;
+ var oldDragY = dragHeight - currentValue * dragHeight;
+ var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
+ shiftMovementDirection = furtherFromX ? "x" : "y"
+ }
+ var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
+ var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
+ if (setSaturation) {
+ currentSaturation = parseFloat(dragX / dragWidth)
+ }
+ if (setValue) {
+ currentValue = parseFloat((dragHeight - dragY) / dragHeight)
+ }
+ isEmpty = false;
+ if (!opts.showAlpha) {
+ currentAlpha = 1
+ }
+ move()
+ }, dragStart, dragStop);
+ if (!!initialColor) {
+ set(initialColor);
+ updateUI();
+ currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;
+ addColorToSelectionPalette(initialColor)
+ } else {
+ updateUI()
+ }
+ if (flat) {
+ show()
+ }
+
+ function paletteElementClick(e) {
+ if (e.data && e.data.ignore) {
+ set($(e.target).closest(".sp-thumb-el").data("color"));
+ move()
+ } else {
+ set($(e.target).closest(".sp-thumb-el").data("color"));
+ move();
+ updateOriginalInput(true);
+ if (opts.hideAfterPaletteSelect) {
+ hide()
+ }
+ }
+ return false
+ }
+
+ var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
+ paletteContainer.delegate(".sp-thumb-el", paletteEvent, paletteElementClick);
+ initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, {ignore: true}, paletteElementClick)
+ }
+
+ function updateSelectionPaletteFromStorage() {
+ if (localStorageKey && window.localStorage) {
+ try {
+ var oldPalette = window.localStorage[localStorageKey].split(",#");
+ if (oldPalette.length > 1) {
+ delete window.localStorage[localStorageKey];
+ $.each(oldPalette, function (i, c) {
+ addColorToSelectionPalette(c)
+ })
+ }
+ } catch (e) {
+ }
+ try {
+ selectionPalette = window.localStorage[localStorageKey].split(";")
+ } catch (e) {
+ }
+ }
+ }
+
+ function addColorToSelectionPalette(color) {
+ if (showSelectionPalette) {
+ var rgb = tinycolor(color).toRgbString();
+ if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
+ selectionPalette.push(rgb);
+ while (selectionPalette.length > maxSelectionSize) {
+ selectionPalette.shift()
+ }
+ }
+ if (localStorageKey && window.localStorage) {
+ try {
+ window.localStorage[localStorageKey] = selectionPalette.join(";")
+ } catch (e) {
+ }
+ }
+ }
+ }
+
+ function getUniqueSelectionPalette() {
+ var unique = [];
+ if (opts.showPalette) {
+ for (var i = 0; i < selectionPalette.length; i++) {
+ var rgb = tinycolor(selectionPalette[i]).toRgbString();
+ if (!paletteLookup[rgb]) {
+ unique.push(selectionPalette[i])
+ }
+ }
+ }
+ return unique.reverse().slice(0, opts.maxSelectionSize)
+ }
+
+ function drawPalette() {
+ var currentColor = get();
+ var html = $.map(paletteArray, function (palette, i) {
+ return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts)
+ });
+ updateSelectionPaletteFromStorage();
+ if (selectionPalette) {
+ html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts))
+ }
+ paletteContainer.html(html.join(""))
+ }
+
+ function drawInitial() {
+ if (opts.showInitial) {
+ var initial = colorOnShow;
+ var current = get();
+ initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts))
+ }
+ }
+
+ function dragStart() {
+ if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
+ reflow()
+ }
+ isDragging = true;
+ container.addClass(draggingClass);
+ shiftMovementDirection = null;
+ boundElement.trigger("dragstart.spectrum", [get()])
+ }
+
+ function dragStop() {
+ isDragging = false;
+ container.removeClass(draggingClass);
+ boundElement.trigger("dragstop.spectrum", [get()])
+ }
+
+ function setFromTextInput() {
+ var value = textInput.val();
+ if ((value === null || value === "") && allowEmpty) {
+ set(null);
+ updateOriginalInput(true)
+ } else {
+ var tiny = tinycolor(value);
+ if (tiny.isValid()) {
+ set(tiny);
+ updateOriginalInput(true)
+ } else {
+ textInput.addClass("sp-validation-error")
+ }
+ }
+ }
+
+ function toggle() {
+ if (visible) {
+ hide()
+ } else {
+ show()
+ }
+ }
+
+ function show() {
+ var event = $.Event("beforeShow.spectrum");
+ if (visible) {
+ reflow();
+ return
+ }
+ boundElement.trigger(event, [get()]);
+ if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
+ return
+ }
+ hideAll();
+ visible = true;
+ $(doc).bind("keydown.spectrum", onkeydown);
+ $(doc).bind("click.spectrum", clickout);
+ $(window).bind("resize.spectrum", resize);
+ replacer.addClass("sp-active");
+ container.removeClass("sp-hidden");
+ reflow();
+ updateUI();
+ colorOnShow = get();
+ drawInitial();
+ callbacks.show(colorOnShow);
+ boundElement.trigger("show.spectrum", [colorOnShow])
+ }
+
+ function onkeydown(e) {
+ if (e.keyCode === 27) {
+ hide()
+ }
+ }
+
+ function clickout(e) {
+ if (e.button == 2) {
+ return
+ }
+ if (isDragging) {
+ return
+ }
+ if (clickoutFiresChange) {
+ updateOriginalInput(true)
+ } else {
+ revert()
+ }
+ hide()
+ }
+
+ function hide() {
+ if (!visible || flat) {
+ return
+ }
+ visible = false;
+ $(doc).unbind("keydown.spectrum", onkeydown);
+ $(doc).unbind("click.spectrum", clickout);
+ $(window).unbind("resize.spectrum", resize);
+ replacer.removeClass("sp-active");
+ container.addClass("sp-hidden");
+ callbacks.hide(get());
+ boundElement.trigger("hide.spectrum", [get()])
+ }
+
+ function revert() {
+ set(colorOnShow, true)
+ }
+
+ function set(color, ignoreFormatChange) {
+ if (tinycolor.equals(color, get())) {
+ updateUI();
+ return
+ }
+ var newColor, newHsv;
+ if (!color && allowEmpty) {
+ isEmpty = true
+ } else {
+ isEmpty = false;
+ newColor = tinycolor(color);
+ newHsv = newColor.toHsv();
+ currentHue = newHsv.h % 360 / 360;
+ currentSaturation = newHsv.s;
+ currentValue = newHsv.v;
+ currentAlpha = newHsv.a
+ }
+ updateUI();
+ if (newColor && newColor.isValid() && !ignoreFormatChange) {
+ currentPreferredFormat = opts.preferredFormat || newColor.getFormat()
+ }
+ }
+
+ function get(opts) {
+ opts = opts || {};
+ if (allowEmpty && isEmpty) {
+ return null
+ }
+ return tinycolor.fromRatio({
+ h: currentHue,
+ s: currentSaturation,
+ v: currentValue,
+ a: Math.round(currentAlpha * 100) / 100
+ }, {format: opts.format || currentPreferredFormat})
+ }
+
+ function isValid() {
+ return !textInput.hasClass("sp-validation-error")
+ }
+
+ function move() {
+ updateUI();
+ callbacks.move(get());
+ boundElement.trigger("move.spectrum", [get()])
+ }
+
+ function updateUI() {
+ textInput.removeClass("sp-validation-error");
+ updateHelperLocations();
+ var flatColor = tinycolor.fromRatio({h: currentHue, s: 1, v: 1});
+ dragger.css("background-color", flatColor.toHexString());
+ var format = currentPreferredFormat;
+ if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
+ if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
+ format = "rgb"
+ }
+ }
+ var realColor = get({format: format}), displayColor = "";
+ previewElement.removeClass("sp-clear-display");
+ previewElement.css("background-color", "transparent");
+ if (!realColor && allowEmpty) {
+ previewElement.addClass("sp-clear-display")
+ } else {
+ var realHex = realColor.toHexString(), realRgb = realColor.toRgbString();
+ if (rgbaSupport || realColor.alpha === 1) {
+ previewElement.css("background-color", realRgb)
+ } else {
+ previewElement.css("background-color", "transparent");
+ previewElement.css("filter", realColor.toFilter())
+ }
+ if (opts.showAlpha) {
+ var rgb = realColor.toRgb();
+ rgb.a = 0;
+ var realAlpha = tinycolor(rgb).toRgbString();
+ var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
+ if (IE) {
+ alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({gradientType: 1}, realHex))
+ } else {
+ alphaSliderInner.css("background", "-webkit-" + gradient);
+ alphaSliderInner.css("background", "-moz-" + gradient);
+ alphaSliderInner.css("background", "-ms-" + gradient);
+ alphaSliderInner.css("background", "linear-gradient(to right, " + realAlpha + ", " + realHex + ")")
+ }
+ }
+ displayColor = realColor.toString(format)
+ }
+ if (opts.showInput) {
+ textInput.val(displayColor)
+ }
+ if (opts.showPalette) {
+ drawPalette()
+ }
+ drawInitial()
+ }
+
+ function updateHelperLocations() {
+ var s = currentSaturation;
+ var v = currentValue;
+ if (allowEmpty && isEmpty) {
+ alphaSlideHelper.hide();
+ slideHelper.hide();
+ dragHelper.hide()
+ } else {
+ alphaSlideHelper.show();
+ slideHelper.show();
+ dragHelper.show();
+ var dragX = s * dragWidth;
+ var dragY = dragHeight - v * dragHeight;
+ dragX = Math.max(-dragHelperHeight, Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight));
+ dragY = Math.max(-dragHelperHeight, Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight));
+ dragHelper.css({top: dragY + "px", left: dragX + "px"});
+ var alphaX = currentAlpha * alphaWidth;
+ alphaSlideHelper.css({left: alphaX - alphaSlideHelperWidth / 2 + "px"});
+ var slideY = currentHue * slideHeight;
+ slideHelper.css({top: slideY - slideHelperHeight + "px"})
+ }
+ }
+
+ function updateOriginalInput(fireCallback) {
+ var color = get(), displayColor = "", hasChanged = !tinycolor.equals(color, colorOnShow);
+ if (color) {
+ displayColor = color.toString(currentPreferredFormat);
+ addColorToSelectionPalette(color)
+ }
+ if (isInput) {
+ boundElement.val(displayColor)
+ }
+ if (fireCallback && hasChanged) {
+ callbacks.change(color);
+ boundElement.trigger("change", [color])
+ }
+ }
+
+ function reflow() {
+ if (!visible) {
+ return
+ }
+ dragWidth = dragger.width();
+ dragHeight = dragger.height();
+ dragHelperHeight = dragHelper.height();
+ slideWidth = slider.width();
+ slideHeight = slider.height();
+ slideHelperHeight = slideHelper.height();
+ alphaWidth = alphaSlider.width();
+ alphaSlideHelperWidth = alphaSlideHelper.width();
+ if (!flat) {
+ container.css("position", "absolute");
+ if (opts.offset) {
+ container.offset(opts.offset)
+ } else {
+ container.offset(getOffset(container, offsetElement))
+ }
+ }
+ updateHelperLocations();
+ if (opts.showPalette) {
+ drawPalette()
+ }
+ boundElement.trigger("reflow.spectrum")
+ }
+
+ function destroy() {
+ boundElement.show();
+ offsetElement.unbind("click.spectrum touchstart.spectrum");
+ container.remove();
+ replacer.remove();
+ spectrums[spect.id] = null
+ }
+
+ function option(optionName, optionValue) {
+ if (optionName === undefined) {
+ return $.extend({}, opts)
+ }
+ if (optionValue === undefined) {
+ return opts[optionName]
+ }
+ opts[optionName] = optionValue;
+ if (optionName === "preferredFormat") {
+ currentPreferredFormat = opts.preferredFormat
+ }
+ applyOptions()
+ }
+
+ function enable() {
+ disabled = false;
+ boundElement.attr("disabled", false);
+ offsetElement.removeClass("sp-disabled")
+ }
+
+ function disable() {
+ hide();
+ disabled = true;
+ boundElement.attr("disabled", true);
+ offsetElement.addClass("sp-disabled")
+ }
+
+ function setOffset(coord) {
+ opts.offset = coord;
+ reflow()
+ }
+
+ initialize();
+ var spect = {
+ show: show, hide: hide, toggle: toggle, reflow: reflow, option: option, enable: enable, disable: disable, offset: setOffset, set: function (c) {
+ set(c);
+ updateOriginalInput()
+ }, get: get, destroy: destroy, container: container
+ };
+ spect.id = spectrums.push(spect) - 1;
+ return spect
+ }
+
+ function getOffset(picker, input) {
+ var extraY = 0;
+ var dpWidth = picker.outerWidth();
+ var dpHeight = picker.outerHeight();
+ var inputHeight = input.outerHeight();
+ var doc = picker[0].ownerDocument;
+ var docElem = doc.documentElement;
+ var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
+ var viewHeight = docElem.clientHeight + $(doc).scrollTop();
+ var offset = input.offset();
+ offset.top += inputHeight;
+ offset.left -= Math.min(offset.left, offset.left + dpWidth > viewWidth && viewWidth > dpWidth ? Math.abs(offset.left + dpWidth - viewWidth) : 0);
+ offset.top -= Math.min(offset.top, offset.top + dpHeight > viewHeight && viewHeight > dpHeight ? Math.abs(dpHeight + inputHeight - extraY) : extraY);
+ return offset
+ }
+
+ function noop() {
+ }
+
+ function stopPropagation(e) {
+ e.stopPropagation()
+ }
+
+ function bind(func, obj) {
+ var slice = Array.prototype.slice;
+ var args = slice.call(arguments, 2);
+ return function () {
+ return func.apply(obj, args.concat(slice.call(arguments)))
+ }
+ }
+
+ function draggable(element, onmove, onstart, onstop) {
+ onmove = onmove || function () {
+ };
+ onstart = onstart || function () {
+ };
+ onstop = onstop || function () {
+ };
+ var doc = document;
+ var dragging = false;
+ var offset = {};
+ var maxHeight = 0;
+ var maxWidth = 0;
+ var hasTouch = "ontouchstart" in window;
+ var duringDragEvents = {};
+ duringDragEvents["selectstart"] = prevent;
+ duringDragEvents["dragstart"] = prevent;
+ duringDragEvents["touchmove mousemove"] = move;
+ duringDragEvents["touchend mouseup"] = stop;
+
+ function prevent(e) {
+ if (e.stopPropagation) {
+ e.stopPropagation()
+ }
+ if (e.preventDefault) {
+ e.preventDefault()
+ }
+ e.returnValue = false
+ }
+
+ function move(e) {
+ if (dragging) {
+ if (IE && doc.documentMode < 9 && !e.button) {
+ return stop()
+ }
+ var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];
+ var pageX = t0 && t0.pageX || e.pageX;
+ var pageY = t0 && t0.pageY || e.pageY;
+ var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
+ var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
+ if (hasTouch) {
+ prevent(e)
+ }
+ onmove.apply(element, [dragX, dragY, e])
+ }
+ }
+
+ function start(e) {
+ var rightclick = e.which ? e.which == 3 : e.button == 2;
+ if (!rightclick && !dragging) {
+ if (onstart.apply(element, arguments) !== false) {
+ dragging = true;
+ maxHeight = $(element).height();
+ maxWidth = $(element).width();
+ offset = $(element).offset();
+ $(doc).bind(duringDragEvents);
+ $(doc.body).addClass("sp-dragging");
+ move(e);
+ prevent(e)
+ }
+ }
+ }
+
+ function stop() {
+ if (dragging) {
+ $(doc).unbind(duringDragEvents);
+ $(doc.body).removeClass("sp-dragging");
+ setTimeout(function () {
+ onstop.apply(element, arguments)
+ }, 0)
+ }
+ dragging = false
+ }
+
+ $(element).bind("touchstart mousedown", start)
+ }
+
+ function throttle(func, wait, debounce) {
+ var timeout;
+ return function () {
+ var context = this, args = arguments;
+ var throttler = function () {
+ timeout = null;
+ func.apply(context, args)
+ };
+ if (debounce) clearTimeout(timeout);
+ if (debounce || !timeout) timeout = setTimeout(throttler, wait)
+ }
+ }
+
+ function inputTypeColorSupport() {
+ return $.fn.spectrum.inputTypeColorSupport()
+ }
+
+ var dataID = "spectrum.id";
+ $.fn.spectrum = function (opts, extra) {
+ if (typeof opts == "string") {
+ var returnValue = this;
+ var args = Array.prototype.slice.call(arguments, 1);
+ this.each(function () {
+ var spect = spectrums[$(this).data(dataID)];
+ if (spect) {
+ var method = spect[opts];
+ if (!method) {
+ throw new Error("Spectrum: no such method: '" + opts + "'")
+ }
+ if (opts == "get") {
+ returnValue = spect.get()
+ } else if (opts == "container") {
+ returnValue = spect.container
+ } else if (opts == "option") {
+ returnValue = spect.option.apply(spect, args)
+ } else if (opts == "destroy") {
+ spect.destroy();
+ $(this).removeData(dataID)
+ } else {
+ method.apply(spect, args)
+ }
+ }
+ });
+ return returnValue
+ }
+ return this.spectrum("destroy").each(function () {
+ var options = $.extend({}, opts, $(this).data());
+ var spect = spectrum(this, options);
+ $(this).data(dataID, spect.id)
+ })
+ };
+ $.fn.spectrum.load = true;
+ $.fn.spectrum.loadOpts = {};
+ $.fn.spectrum.draggable = draggable;
+ $.fn.spectrum.defaults = defaultOpts;
+ $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {
+ if (typeof inputTypeColorSupport._cachedResult === "undefined") {
+ var colorInput = $(" ")[0];
+ inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== ""
+ }
+ return inputTypeColorSupport._cachedResult
+ };
+ $.spectrum = {};
+ $.spectrum.localization = {};
+ $.spectrum.palettes = {};
+ $.fn.spectrum.processNativeColorInputs = function () {
+ var colorInputs = $("input[type=color]");
+ if (colorInputs.length && !inputTypeColorSupport()) {
+ colorInputs.spectrum({preferredFormat: "hex6"})
+ }
+ };
+ (function () {
+ var trimLeft = /^[\s,#]+/, trimRight = /\s+$/, tinyCounter = 0, math = Math, mathRound = math.round, mathMin = math.min, mathMax = math.max, mathRandom = math.random;
+ var tinycolor = function (color, opts) {
+ color = color ? color : "";
+ opts = opts || {};
+ if (color instanceof tinycolor) {
+ return color
+ }
+ if (!(this instanceof tinycolor)) {
+ return new tinycolor(color, opts)
+ }
+ var rgb = inputToRGB(color);
+ this._originalInput = color, this._r = rgb.r, this._g = rgb.g, this._b = rgb.b, this._a = rgb.a, this._roundA = mathRound(100 * this._a) / 100, this._format = opts.format || rgb.format;
+ this._gradientType = opts.gradientType;
+ if (this._r < 1) {
+ this._r = mathRound(this._r)
+ }
+ if (this._g < 1) {
+ this._g = mathRound(this._g)
+ }
+ if (this._b < 1) {
+ this._b = mathRound(this._b)
+ }
+ this._ok = rgb.ok;
+ this._tc_id = tinyCounter++
+ };
+ tinycolor.prototype = {
+ isDark: function () {
+ return this.getBrightness() < 128
+ }, isLight: function () {
+ return !this.isDark()
+ }, isValid: function () {
+ return this._ok
+ }, getOriginalInput: function () {
+ return this._originalInput
+ }, getFormat: function () {
+ return this._format
+ }, getAlpha: function () {
+ return this._a
+ }, getBrightness: function () {
+ var rgb = this.toRgb();
+ return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1e3
+ }, setAlpha: function (value) {
+ this._a = boundAlpha(value);
+ this._roundA = mathRound(100 * this._a) / 100;
+ return this
+ }, toHsv: function () {
+ var hsv = rgbToHsv(this._r, this._g, this._b);
+ return {h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a}
+ }, toHsvString: function () {
+ var hsv = rgbToHsv(this._r, this._g, this._b);
+ var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
+ return this._a == 1 ? "hsv(" + h + ", " + s + "%, " + v + "%)" : "hsva(" + h + ", " + s + "%, " + v + "%, " + this._roundA + ")"
+ }, toHsl: function () {
+ var hsl = rgbToHsl(this._r, this._g, this._b);
+ return {h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a}
+ }, toHslString: function () {
+ var hsl = rgbToHsl(this._r, this._g, this._b);
+ var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
+ return this._a == 1 ? "hsl(" + h + ", " + s + "%, " + l + "%)" : "hsla(" + h + ", " + s + "%, " + l + "%, " + this._roundA + ")"
+ }, toHex: function (allow3Char) {
+ return rgbToHex(this._r, this._g, this._b, allow3Char)
+ }, toHexString: function (allow3Char) {
+ return "#" + this.toHex(allow3Char)
+ }, toHex8: function () {
+ return rgbaToHex(this._r, this._g, this._b, this._a)
+ }, toHex8String: function () {
+ return "#" + this.toHex8()
+ }, toRgb: function () {
+ return {r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a}
+ }, toRgbString: function () {
+ return this._a == 1 ? "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" : "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")"
+ }, toPercentageRgb: function () {
+ return {
+ r: mathRound(bound01(this._r, 255) * 100) + "%",
+ g: mathRound(bound01(this._g, 255) * 100) + "%",
+ b: mathRound(bound01(this._b, 255) * 100) + "%",
+ a: this._a
+ }
+ }, toPercentageRgbString: function () {
+ return this._a == 1 ? "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" : "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"
+ }, toName: function () {
+ if (this._a === 0) {
+ return "transparent"
+ }
+ if (this._a < 1) {
+ return false
+ }
+ return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false
+ }, toFilter: function (secondColor) {
+ var hex8String = "#" + rgbaToHex(this._r, this._g, this._b, this._a);
+ var secondHex8String = hex8String;
+ var gradientType = this._gradientType ? "GradientType = 1, " : "";
+ if (secondColor) {
+ var s = tinycolor(secondColor);
+ secondHex8String = s.toHex8String()
+ }
+ return "progid:DXImageTransform.Microsoft.gradient(" + gradientType + "startColorstr=" + hex8String + ",endColorstr=" + secondHex8String + ")"
+ }, toString: function (format) {
+ var formatSet = !!format;
+ format = format || this._format;
+ var formattedString = false;
+ var hasAlpha = this._a < 1 && this._a >= 0;
+ var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
+ if (needsAlphaFormat) {
+ if (format === "name" && this._a === 0) {
+ return this.toName()
+ }
+ return this.toRgbString()
+ }
+ if (format === "rgb") {
+ formattedString = this.toRgbString()
+ }
+ if (format === "prgb") {
+ formattedString = this.toPercentageRgbString()
+ }
+ if (format === "hex" || format === "hex6") {
+ formattedString = this.toHexString()
+ }
+ if (format === "hex3") {
+ formattedString = this.toHexString(true)
+ }
+ if (format === "hex8") {
+ formattedString = this.toHex8String()
+ }
+ if (format === "name") {
+ formattedString = this.toName()
+ }
+ if (format === "hsl") {
+ formattedString = this.toHslString()
+ }
+ if (format === "hsv") {
+ formattedString = this.toHsvString()
+ }
+ return formattedString || this.toHexString()
+ }, _applyModification: function (fn, args) {
+ var color = fn.apply(null, [this].concat([].slice.call(args)));
+ this._r = color._r;
+ this._g = color._g;
+ this._b = color._b;
+ this.setAlpha(color._a);
+ return this
+ }, lighten: function () {
+ return this._applyModification(lighten, arguments)
+ }, brighten: function () {
+ return this._applyModification(brighten, arguments)
+ }, darken: function () {
+ return this._applyModification(darken, arguments)
+ }, desaturate: function () {
+ return this._applyModification(desaturate, arguments)
+ }, saturate: function () {
+ return this._applyModification(saturate, arguments)
+ }, greyscale: function () {
+ return this._applyModification(greyscale, arguments)
+ }, spin: function () {
+ return this._applyModification(spin, arguments)
+ }, _applyCombination: function (fn, args) {
+ return fn.apply(null, [this].concat([].slice.call(args)))
+ }, analogous: function () {
+ return this._applyCombination(analogous, arguments)
+ }, complement: function () {
+ return this._applyCombination(complement, arguments)
+ }, monochromatic: function () {
+ return this._applyCombination(monochromatic, arguments)
+ }, splitcomplement: function () {
+ return this._applyCombination(splitcomplement, arguments)
+ }, triad: function () {
+ return this._applyCombination(triad, arguments)
+ }, tetrad: function () {
+ return this._applyCombination(tetrad, arguments)
+ }
+ };
+ tinycolor.fromRatio = function (color, opts) {
+ if (typeof color == "object") {
+ var newColor = {};
+ for (var i in color) {
+ if (color.hasOwnProperty(i)) {
+ if (i === "a") {
+ newColor[i] = color[i]
+ } else {
+ newColor[i] = convertToPercentage(color[i])
+ }
+ }
+ }
+ color = newColor
+ }
+ return tinycolor(color, opts)
+ };
+
+ function inputToRGB(color) {
+ var rgb = {r: 0, g: 0, b: 0};
+ var a = 1;
+ var ok = false;
+ var format = false;
+ if (typeof color == "string") {
+ color = stringInputToObject(color)
+ }
+ if (typeof color == "object") {
+ if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
+ rgb = rgbToRgb(color.r, color.g, color.b);
+ ok = true;
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"
+ } else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
+ color.s = convertToPercentage(color.s);
+ color.v = convertToPercentage(color.v);
+ rgb = hsvToRgb(color.h, color.s, color.v);
+ ok = true;
+ format = "hsv"
+ } else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
+ color.s = convertToPercentage(color.s);
+ color.l = convertToPercentage(color.l);
+ rgb = hslToRgb(color.h, color.s, color.l);
+ ok = true;
+ format = "hsl"
+ }
+ if (color.hasOwnProperty("a")) {
+ a = color.a
+ }
+ }
+ a = boundAlpha(a);
+ return {ok: ok, format: color.format || format, r: mathMin(255, mathMax(rgb.r, 0)), g: mathMin(255, mathMax(rgb.g, 0)), b: mathMin(255, mathMax(rgb.b, 0)), a: a}
+ }
+
+ function rgbToRgb(r, g, b) {
+ return {r: bound01(r, 255) * 255, g: bound01(g, 255) * 255, b: bound01(b, 255) * 255}
+ }
+
+ function rgbToHsl(r, g, b) {
+ r = bound01(r, 255);
+ g = bound01(g, 255);
+ b = bound01(b, 255);
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
+ var h, s, l = (max + min) / 2;
+ if (max == min) {
+ h = s = 0
+ } else {
+ var d = max - min;
+ s = l > .5 ? d / (2 - max - min) : d / (max + min);
+ switch (max) {
+ case r:
+ h = (g - b) / d + (g < b ? 6 : 0);
+ break;
+ case g:
+ h = (b - r) / d + 2;
+ break;
+ case b:
+ h = (r - g) / d + 4;
+ break
+ }
+ h /= 6
+ }
+ return {h: h, s: s, l: l}
+ }
+
+ function hslToRgb(h, s, l) {
+ var r, g, b;
+ h = bound01(h, 360);
+ s = bound01(s, 100);
+ l = bound01(l, 100);
+
+ function hue2rgb(p, q, t) {
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
+ if (t < 1 / 2) return q;
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+ return p
+ }
+
+ if (s === 0) {
+ r = g = b = l
+ } else {
+ var q = l < .5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1 / 3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1 / 3)
+ }
+ return {r: r * 255, g: g * 255, b: b * 255}
+ }
+
+ function rgbToHsv(r, g, b) {
+ r = bound01(r, 255);
+ g = bound01(g, 255);
+ b = bound01(b, 255);
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
+ var h, s, v = max;
+ var d = max - min;
+ s = max === 0 ? 0 : d / max;
+ if (max == min) {
+ h = 0
+ } else {
+ switch (max) {
+ case r:
+ h = (g - b) / d + (g < b ? 6 : 0);
+ break;
+ case g:
+ h = (b - r) / d + 2;
+ break;
+ case b:
+ h = (r - g) / d + 4;
+ break
+ }
+ h /= 6
+ }
+ return {h: h, s: s, v: v}
+ }
+
+ function hsvToRgb(h, s, v) {
+ h = bound01(h, 360) * 6;
+ s = bound01(s, 100);
+ v = bound01(v, 100);
+ var i = math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod],
+ g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod];
+ return {r: r * 255, g: g * 255, b: b * 255}
+ }
+
+ function rgbToHex(r, g, b, allow3Char) {
+ var hex = [pad2(mathRound(r).toString(16)), pad2(mathRound(g).toString(16)), pad2(mathRound(b).toString(16))];
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0)
+ }
+ return hex.join("")
+ }
+
+ function rgbaToHex(r, g, b, a) {
+ var hex = [pad2(convertDecimalToHex(a)), pad2(mathRound(r).toString(16)), pad2(mathRound(g).toString(16)), pad2(mathRound(b).toString(16))];
+ return hex.join("")
+ }
+
+ tinycolor.equals = function (color1, color2) {
+ if (!color1 || !color2) {
+ return false
+ }
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString()
+ };
+ tinycolor.random = function () {
+ return tinycolor.fromRatio({
+ r: mathRandom(), g: mathRandom(),
+ b: mathRandom()
+ })
+ };
+
+ function desaturate(color, amount) {
+ amount = amount === 0 ? 0 : amount || 10;
+ var hsl = tinycolor(color).toHsl();
+ hsl.s -= amount / 100;
+ hsl.s = clamp01(hsl.s);
+ return tinycolor(hsl)
+ }
+
+ function saturate(color, amount) {
+ amount = amount === 0 ? 0 : amount || 10;
+ var hsl = tinycolor(color).toHsl();
+ hsl.s += amount / 100;
+ hsl.s = clamp01(hsl.s);
+ return tinycolor(hsl)
+ }
+
+ function greyscale(color) {
+ return tinycolor(color).desaturate(100)
+ }
+
+ function lighten(color, amount) {
+ amount = amount === 0 ? 0 : amount || 10;
+ var hsl = tinycolor(color).toHsl();
+ hsl.l += amount / 100;
+ hsl.l = clamp01(hsl.l);
+ return tinycolor(hsl)
+ }
+
+ function brighten(color, amount) {
+ amount = amount === 0 ? 0 : amount || 10;
+ var rgb = tinycolor(color).toRgb();
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * -(amount / 100))));
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * -(amount / 100))));
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * -(amount / 100))));
+ return tinycolor(rgb)
+ }
+
+ function darken(color, amount) {
+ amount = amount === 0 ? 0 : amount || 10;
+ var hsl = tinycolor(color).toHsl();
+ hsl.l -= amount / 100;
+ hsl.l = clamp01(hsl.l);
+ return tinycolor(hsl)
+ }
+
+ function spin(color, amount) {
+ var hsl = tinycolor(color).toHsl();
+ var hue = (mathRound(hsl.h) + amount) % 360;
+ hsl.h = hue < 0 ? 360 + hue : hue;
+ return tinycolor(hsl)
+ }
+
+ function complement(color) {
+ var hsl = tinycolor(color).toHsl();
+ hsl.h = (hsl.h + 180) % 360;
+ return tinycolor(hsl)
+ }
+
+ function triad(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [tinycolor(color), tinycolor({h: (h + 120) % 360, s: hsl.s, l: hsl.l}), tinycolor({h: (h + 240) % 360, s: hsl.s, l: hsl.l})]
+ }
+
+ function tetrad(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [tinycolor(color), tinycolor({h: (h + 90) % 360, s: hsl.s, l: hsl.l}), tinycolor({h: (h + 180) % 360, s: hsl.s, l: hsl.l}), tinycolor({
+ h: (h + 270) % 360,
+ s: hsl.s,
+ l: hsl.l
+ })]
+ }
+
+ function splitcomplement(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [tinycolor(color), tinycolor({h: (h + 72) % 360, s: hsl.s, l: hsl.l}), tinycolor({h: (h + 216) % 360, s: hsl.s, l: hsl.l})]
+ }
+
+ function analogous(color, results, slices) {
+ results = results || 6;
+ slices = slices || 30;
+ var hsl = tinycolor(color).toHsl();
+ var part = 360 / slices;
+ var ret = [tinycolor(color)];
+ for (hsl.h = (hsl.h - (part * results >> 1) + 720) % 360; --results;) {
+ hsl.h = (hsl.h + part) % 360;
+ ret.push(tinycolor(hsl))
+ }
+ return ret
+ }
+
+ function monochromatic(color, results) {
+ results = results || 6;
+ var hsv = tinycolor(color).toHsv();
+ var h = hsv.h, s = hsv.s, v = hsv.v;
+ var ret = [];
+ var modification = 1 / results;
+ while (results--) {
+ ret.push(tinycolor({h: h, s: s, v: v}));
+ v = (v + modification) % 1
+ }
+ return ret
+ }
+
+ tinycolor.mix = function (color1, color2, amount) {
+ amount = amount === 0 ? 0 : amount || 50;
+ var rgb1 = tinycolor(color1).toRgb();
+ var rgb2 = tinycolor(color2).toRgb();
+ var p = amount / 100;
+ var w = p * 2 - 1;
+ var a = rgb2.a - rgb1.a;
+ var w1;
+ if (w * a == -1) {
+ w1 = w
+ } else {
+ w1 = (w + a) / (1 + w * a)
+ }
+ w1 = (w1 + 1) / 2;
+ var w2 = 1 - w1;
+ var rgba = {r: rgb2.r * w1 + rgb1.r * w2, g: rgb2.g * w1 + rgb1.g * w2, b: rgb2.b * w1 + rgb1.b * w2, a: rgb2.a * p + rgb1.a * (1 - p)};
+ return tinycolor(rgba)
+ };
+ tinycolor.readability = function (color1, color2) {
+ var c1 = tinycolor(color1);
+ var c2 = tinycolor(color2);
+ var rgb1 = c1.toRgb();
+ var rgb2 = c2.toRgb();
+ var brightnessA = c1.getBrightness();
+ var brightnessB = c2.getBrightness();
+ var colorDiff = Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) + Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) + Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b);
+ return {brightness: Math.abs(brightnessA - brightnessB), color: colorDiff}
+ };
+ tinycolor.isReadable = function (color1, color2) {
+ var readability = tinycolor.readability(color1, color2);
+ return readability.brightness > 125 && readability.color > 500
+ };
+ tinycolor.mostReadable = function (baseColor, colorList) {
+ var bestColor = null;
+ var bestScore = 0;
+ var bestIsReadable = false;
+ for (var i = 0; i < colorList.length; i++) {
+ var readability = tinycolor.readability(baseColor, colorList[i]);
+ var readable = readability.brightness > 125 && readability.color > 500;
+ var score = 3 * (readability.brightness / 125) + readability.color / 500;
+ if (readable && !bestIsReadable || readable && bestIsReadable && score > bestScore || !readable && !bestIsReadable && score > bestScore) {
+ bestIsReadable = readable;
+ bestScore = score;
+ bestColor = tinycolor(colorList[i])
+ }
+ }
+ return bestColor
+ };
+ var names = tinycolor.names = {
+ aliceblue: "f0f8ff",
+ antiquewhite: "faebd7",
+ aqua: "0ff",
+ aquamarine: "7fffd4",
+ azure: "f0ffff",
+ beige: "f5f5dc",
+ bisque: "ffe4c4",
+ black: "000",
+ blanchedalmond: "ffebcd",
+ blue: "00f",
+ blueviolet: "8a2be2",
+ brown: "a52a2a",
+ burlywood: "deb887",
+ burntsienna: "ea7e5d",
+ cadetblue: "5f9ea0",
+ chartreuse: "7fff00",
+ chocolate: "d2691e",
+ coral: "ff7f50",
+ cornflowerblue: "6495ed",
+ cornsilk: "fff8dc",
+ crimson: "dc143c",
+ cyan: "0ff",
+ darkblue: "00008b",
+ darkcyan: "008b8b",
+ darkgoldenrod: "b8860b",
+ darkgray: "a9a9a9",
+ darkgreen: "006400",
+ darkgrey: "a9a9a9",
+ darkkhaki: "bdb76b",
+ darkmagenta: "8b008b",
+ darkolivegreen: "556b2f",
+ darkorange: "ff8c00",
+ darkorchid: "9932cc",
+ darkred: "8b0000",
+ darksalmon: "e9967a",
+ darkseagreen: "8fbc8f",
+ darkslateblue: "483d8b",
+ darkslategray: "2f4f4f",
+ darkslategrey: "2f4f4f",
+ darkturquoise: "00ced1",
+ darkviolet: "9400d3",
+ deeppink: "ff1493",
+ deepskyblue: "00bfff",
+ dimgray: "696969",
+ dimgrey: "696969",
+ dodgerblue: "1e90ff",
+ firebrick: "b22222",
+ floralwhite: "fffaf0",
+ forestgreen: "228b22",
+ fuchsia: "f0f",
+ gainsboro: "dcdcdc",
+ ghostwhite: "f8f8ff",
+ gold: "ffd700",
+ goldenrod: "daa520",
+ gray: "808080",
+ green: "008000",
+ greenyellow: "adff2f",
+ grey: "808080",
+ honeydew: "f0fff0",
+ hotpink: "ff69b4",
+ indianred: "cd5c5c",
+ indigo: "4b0082",
+ ivory: "fffff0",
+ khaki: "f0e68c",
+ lavender: "e6e6fa",
+ lavenderblush: "fff0f5",
+ lawngreen: "7cfc00",
+ lemonchiffon: "fffacd",
+ lightblue: "add8e6",
+ lightcoral: "f08080",
+ lightcyan: "e0ffff",
+ lightgoldenrodyellow: "fafad2",
+ lightgray: "d3d3d3",
+ lightgreen: "90ee90",
+ lightgrey: "d3d3d3",
+ lightpink: "ffb6c1",
+ lightsalmon: "ffa07a",
+ lightseagreen: "20b2aa",
+ lightskyblue: "87cefa",
+ lightslategray: "789",
+ lightslategrey: "789",
+ lightsteelblue: "b0c4de",
+ lightyellow: "ffffe0",
+ lime: "0f0",
+ limegreen: "32cd32",
+ linen: "faf0e6",
+ magenta: "f0f",
+ maroon: "800000",
+ mediumaquamarine: "66cdaa",
+ mediumblue: "0000cd",
+ mediumorchid: "ba55d3",
+ mediumpurple: "9370db",
+ mediumseagreen: "3cb371",
+ mediumslateblue: "7b68ee",
+ mediumspringgreen: "00fa9a",
+ mediumturquoise: "48d1cc",
+ mediumvioletred: "c71585",
+ midnightblue: "191970",
+ mintcream: "f5fffa",
+ mistyrose: "ffe4e1",
+ moccasin: "ffe4b5",
+ navajowhite: "ffdead",
+ navy: "000080",
+ oldlace: "fdf5e6",
+ olive: "808000",
+ olivedrab: "6b8e23",
+ orange: "ffa500",
+ orangered: "ff4500",
+ orchid: "da70d6",
+ palegoldenrod: "eee8aa",
+ palegreen: "98fb98",
+ paleturquoise: "afeeee",
+ palevioletred: "db7093",
+ papayawhip: "ffefd5",
+ peachpuff: "ffdab9",
+ peru: "cd853f",
+ pink: "ffc0cb",
+ plum: "dda0dd",
+ powderblue: "b0e0e6",
+ purple: "800080",
+ rebeccapurple: "663399",
+ red: "f00",
+ rosybrown: "bc8f8f",
+ royalblue: "4169e1",
+ saddlebrown: "8b4513",
+ salmon: "fa8072",
+ sandybrown: "f4a460",
+ seagreen: "2e8b57",
+ seashell: "fff5ee",
+ sienna: "a0522d",
+ silver: "c0c0c0",
+ skyblue: "87ceeb",
+ slateblue: "6a5acd",
+ slategray: "708090",
+ slategrey: "708090",
+ snow: "fffafa",
+ springgreen: "00ff7f",
+ steelblue: "4682b4",
+ tan: "d2b48c",
+ teal: "008080",
+ thistle: "d8bfd8",
+ tomato: "ff6347",
+ turquoise: "40e0d0",
+ violet: "ee82ee",
+ wheat: "f5deb3",
+ white: "fff",
+ whitesmoke: "f5f5f5",
+ yellow: "ff0",
+ yellowgreen: "9acd32"
+ };
+ var hexNames = tinycolor.hexNames = flip(names);
+
+ function flip(o) {
+ var flipped = {};
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) {
+ flipped[o[i]] = i
+ }
+ }
+ return flipped
+ }
+
+ function boundAlpha(a) {
+ a = parseFloat(a);
+ if (isNaN(a) || a < 0 || a > 1) {
+ a = 1
+ }
+ return a
+ }
+
+ function bound01(n, max) {
+ if (isOnePointZero(n)) {
+ n = "100%"
+ }
+ var processPercent = isPercentage(n);
+ n = mathMin(max, mathMax(0, parseFloat(n)));
+ if (processPercent) {
+ n = parseInt(n * max, 10) / 100
+ }
+ if (math.abs(n - max) < 1e-6) {
+ return 1
+ }
+ return n % max / parseFloat(max)
+ }
+
+ function clamp01(val) {
+ return mathMin(1, mathMax(0, val))
+ }
+
+ function parseIntFromHex(val) {
+ return parseInt(val, 16)
+ }
+
+ function isOnePointZero(n) {
+ return typeof n == "string" && n.indexOf(".") != -1 && parseFloat(n) === 1
+ }
+
+ function isPercentage(n) {
+ return typeof n === "string" && n.indexOf("%") != -1
+ }
+
+ function pad2(c) {
+ return c.length == 1 ? "0" + c : "" + c
+ }
+
+ function convertToPercentage(n) {
+ if (n <= 1) {
+ n = n * 100 + "%"
+ }
+ return n
+ }
+
+ function convertDecimalToHex(d) {
+ return Math.round(parseFloat(d) * 255).toString(16)
+ }
+
+ function convertHexToDecimal(h) {
+ return parseIntFromHex(h) / 255
+ }
+
+ var matchers = function () {
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
+ return {
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
+ hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
+ hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
+ hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
+ hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
+ }
+ }();
+
+ function stringInputToObject(color) {
+ color = color.replace(trimLeft, "").replace(trimRight, "").toLowerCase();
+ var named = false;
+ if (names[color]) {
+ color = names[color];
+ named = true
+ } else if (color == "transparent") {
+ return {r: 0, g: 0, b: 0, a: 0, format: "name"}
+ }
+ var match;
+ if (match = matchers.rgb.exec(color)) {
+ return {r: match[1], g: match[2], b: match[3]}
+ }
+ if (match = matchers.rgba.exec(color)) {
+ return {r: match[1], g: match[2], b: match[3], a: match[4]}
+ }
+ if (match = matchers.hsl.exec(color)) {
+ return {h: match[1], s: match[2], l: match[3]}
+ }
+ if (match = matchers.hsla.exec(color)) {
+ return {h: match[1], s: match[2], l: match[3], a: match[4]}
+ }
+ if (match = matchers.hsv.exec(color)) {
+ return {h: match[1], s: match[2], v: match[3]}
+ }
+ if (match = matchers.hsva.exec(color)) {
+ return {h: match[1], s: match[2], v: match[3], a: match[4]}
+ }
+ if (match = matchers.hex8.exec(color)) {
+ return {a: convertHexToDecimal(match[1]), r: parseIntFromHex(match[2]), g: parseIntFromHex(match[3]), b: parseIntFromHex(match[4]), format: named ? "name" : "hex8"}
+ }
+ if (match = matchers.hex6.exec(color)) {
+ return {r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), format: named ? "name" : "hex"}
+ }
+ if (match = matchers.hex3.exec(color)) {
+ return {
+ r: parseIntFromHex(match[1] + "" + match[1]),
+ g: parseIntFromHex(match[2] + "" + match[2]),
+ b: parseIntFromHex(match[3] + "" + match[3]),
+ format: named ? "name" : "hex"
+ }
+ }
+ return false
+ }
+
+ window.tinycolor = tinycolor
+ })();
+ $(function () {
+ if ($.fn.spectrum.load) {
+ $.fn.spectrum.processNativeColorInputs()
+ }
+ })
+});
diff --git a/javascript/spectrum.js b/javascript/spectrum.js
deleted file mode 100644
index b60ac8f..0000000
--- a/javascript/spectrum.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(t){"use strict";!function(Dt,It){var qt={beforeShow:t,move:t,change:t,show:t,hide:t,color:!1,flat:!1,showInput:!1,allowEmpty:!1,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!1,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:7,cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:!1,className:"",containerClassName:"",replacerClassName:"",showAlpha:!1,theme:"sp-light",palette:[["#ffffff","#000000","#ff0000","#ff8000","#ffff00","#008000","#0000ff","#4b0082","#9400d3"]],selectionPalette:[],disabled:!1,offset:null},jt=[],zt=!!/msie/i.exec(window.navigator.userAgent),Bt=function(){function t(t,e){return!!~(""+t).indexOf(e)}var e=document.createElement("div"),r=e.style;return r.cssText="background-color:rgba(0,0,0,.5)",t(r.backgroundColor,"rgba")||t(r.backgroundColor,"hsla")}(),Lt=[""].join(""),Kt=function(){var t="";if(zt)for(var e=1;e<=6;e++)t+="
";return[""].join("")}();function Vt(t,e,r,a){for(var n=[],i=0;i ')}else{n.push(Dt("
").append(Dt(' ').attr("title",a.noColorSelectedText)).html())}}return""+n.join("")+"
"}function i(t,e){var r,a,n,i,s,o,l,f=(s=e,o=t,(l=Dt.extend({},qt,s)).callbacks={move:Wt(l.move,o),change:Wt(l.change,o),show:Wt(l.show,o),hide:Wt(l.hide,o),beforeShow:Wt(l.beforeShow,o)},l),h=f.flat,c=f.showSelectionPalette,u=f.localStorageKey,d=f.theme,p=f.callbacks,g=(r=Ot,a=10,function(){var t=this,e=arguments;n&&clearTimeout(i),!n&&i||(i=setTimeout(function(){i=null,r.apply(t,e)},a))}),b=!1,v=!1,m=0,y=0,w=0,_=0,x=0,k=0,S=0,C=0,P=0,A=0,M=1,R=[],H=[],F={},T=f.selectionPalette.slice(0),O=f.maxSelectionSize,N="sp-dragging",E=null,D=t.ownerDocument,I=(D.body,Dt(t)),q=!1,j=Dt(Kt,D).addClass(d),z=j.find(".sp-picker-container"),B=j.find(".sp-color"),L=j.find(".sp-dragger"),K=j.find(".sp-hue"),V=j.find(".sp-slider"),$=j.find(".sp-alpha-inner"),W=j.find(".sp-alpha"),X=j.find(".sp-alpha-handle"),Y=j.find(".sp-input"),G=j.find(".sp-palette"),Q=j.find(".sp-initial"),J=j.find(".sp-cancel"),U=j.find(".sp-clear"),Z=j.find(".sp-choose"),tt=j.find(".sp-palette-toggle"),et=I.is("input"),rt=et&&"color"===I.attr("type")&&Yt(),at=et&&!h,nt=at?Dt(Lt).addClass(d).addClass(f.className).addClass(f.replacerClassName):Dt([]),it=at?nt:I,st=nt.find(".sp-preview-inner"),ot=f.color||et&&I.val(),lt=!1,ct=f.preferredFormat,ft=!f.showButtons||f.clickoutFiresChange,ht=!ot,ut=f.allowEmpty&&!rt;function dt(){if(f.showPaletteOnly&&(f.showPalette=!0),tt.text(f.showPaletteOnly?f.togglePaletteMoreText:f.togglePaletteLessText),f.palette){R=f.palette.slice(0),H=Dt.isArray(R[0])?R:[R],F={};for(var t=0;tO;)T.shift();if(u&&window.localStorage)try{window.localStorage[u]=T.join(";")}catch(t){}}}function bt(){var r=Mt(),t=Dt.map(H,function(t,e){return Vt(t,r,"sp-palette-row sp-palette-row-"+e,f)});pt(),T&&t.push(Vt(function(){var t=[];if(f.showPalette)for(var e=0;eo&&rl&&aMath.abs(e-n);E=i?"x":"y"}}else E=null;var s=!E||"y"===E;(!E||"x"===E)&&(P=parseFloat(t/m)),s&&(A=parseFloat((y-e)/y)),ht=!1,f.showAlpha||(M=1),Rt()},mt,yt),ot?(At(ot),Ht(),ct=f.preferredFormat||tinycolor(ot).format,gt(ot)):Ht();h&&xt();function e(t){return t.data&&t.data.ignore?(At(Dt(t.target).closest(".sp-thumb-el").data("color")),Rt()):(At(Dt(t.target).closest(".sp-thumb-el").data("color")),Rt(),Tt(!0),f.hideAfterPaletteSelect&&Ct()),!1}var r=zt?"mousedown.spectrum":"click.spectrum touchstart.spectrum";G.delegate(".sp-thumb-el",r,e),Q.delegate(".sp-thumb-el:nth-child(1)",r,{ignore:!0},e)}();var Et={show:xt,hide:Ct,toggle:_t,reflow:Ot,option:function(t,e){if(t===It)return Dt.extend({},f);if(e===It)return f[t];f[t]=e,"preferredFormat"===t&&(ct=f.preferredFormat);dt()},enable:function(){q=!1,I.attr("disabled",!1),it.removeClass("sp-disabled")},disable:Nt,offset:function(t){f.offset=t,Ot()},set:function(t){At(t),Tt()},get:Mt,destroy:function(){I.show(),it.unbind("click.spectrum touchstart.spectrum"),j.remove(),nt.remove(),jt[Et.id]=null},container:j};return Et.id=jt.push(Et)-1,Et}function t(){}function $t(t){t.stopPropagation()}function Wt(t,e){var r=Array.prototype.slice,a=r.call(arguments,2);return function(){return t.apply(e,a.concat(r.call(arguments)))}}function Xt(s,o,e,t){o=o||function(){},e=e||function(){},t=t||function(){};var l=document,c=!1,f={},h=0,u=0,d="ontouchstart"in window,r={};function p(t){t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.returnValue=!1}function a(t){if(c){if(zt&&l.documentMode<9&&!t.button)return g();var e=t.originalEvent&&t.originalEvent.touches&&t.originalEvent.touches[0],r=e&&e.pageX||t.pageX,a=e&&e.pageY||t.pageY,n=Math.max(0,Math.min(r-f.left,u)),i=Math.max(0,Math.min(a-f.top,h));d&&p(t),o.apply(s,[n,i,t])}}function g(){c&&(Dt(l).unbind(r),Dt(l.body).removeClass("sp-dragging"),setTimeout(function(){t.apply(s,arguments)},0)),c=!1}r.selectstart=p,r.dragstart=p,r["touchmove mousemove"]=a,r["touchend mouseup"]=g,Dt(s).bind("touchstart mousedown",function(t){(t.which?3==t.which:2==t.button)||c||!1!==e.apply(s,arguments)&&(c=!0,h=Dt(s).height(),u=Dt(s).width(),f=Dt(s).offset(),Dt(l).bind(r),Dt(l.body).addClass("sp-dragging"),a(t),p(t))})}function Yt(){return Dt.fn.spectrum.inputTypeColorSupport()}var s="spectrum.id";Dt.fn.spectrum=function(r,t){if("string"!=typeof r)return this.spectrum("destroy").each(function(){var t=Dt.extend({},r,Dt(this).data()),e=i(this,t);Dt(this).data(s,e.id)});var a=this,n=Array.prototype.slice.call(arguments,1);return this.each(function(){var t=jt[Dt(this).data(s)];if(t){var e=t[r];if(!e)throw new Error("Spectrum: no such method: '"+r+"'");"get"==r?a=t.get():"container"==r?a=t.container:"option"==r?a=t.option.apply(t,n):"destroy"==r?(t.destroy(),Dt(this).removeData(s)):e.apply(t,n)}}),a},Dt.fn.spectrum.load=!0,Dt.fn.spectrum.loadOpts={},Dt.fn.spectrum.draggable=Xt,Dt.fn.spectrum.defaults=qt,Dt.fn.spectrum.inputTypeColorSupport=function t(){if(void 0===t._cachedResult){var e=Dt(" ")[0];t._cachedResult="color"===e.type&&""!==e.value}return t._cachedResult},Dt.spectrum={},Dt.spectrum.localization={},Dt.spectrum.palettes={},Dt.fn.spectrum.processNativeColorInputs=function(){var t=Dt("input[type=color]");t.length&&!Yt()&&t.spectrum({preferredFormat:"hex6"})},function(){var l=/^[\s,#]+/,c=/\s+$/,a=0,f=Math,s=f.round,h=f.min,u=f.max,t=f.random,d=function(t,e){if(e=e||{},(t=t||"")instanceof d)return t;if(!(this instanceof d))return new d(t,e);var r=function(t){var e={r:0,g:0,b:0},r=1,a=!1,n=!1;"string"==typeof t&&(t=function(t){t=t.replace(l,"").replace(c,"").toLowerCase();var e,r=!1;if(P[t])t=P[t],r=!0;else if("transparent"==t)return{r:0,g:0,b:0,a:0,format:"name"};if(e=I.rgb.exec(t))return{r:e[1],g:e[2],b:e[3]};if(e=I.rgba.exec(t))return{r:e[1],g:e[2],b:e[3],a:e[4]};if(e=I.hsl.exec(t))return{h:e[1],s:e[2],l:e[3]};if(e=I.hsla.exec(t))return{h:e[1],s:e[2],l:e[3],a:e[4]};if(e=I.hsv.exec(t))return{h:e[1],s:e[2],v:e[3]};if(e=I.hsva.exec(t))return{h:e[1],s:e[2],v:e[3],a:e[4]};if(e=I.hex8.exec(t))return{a:(a=e[1],F(a)/255),r:F(e[2]),g:F(e[3]),b:F(e[4]),format:r?"name":"hex8"};var a;if(e=I.hex6.exec(t))return{r:F(e[1]),g:F(e[2]),b:F(e[3]),format:r?"name":"hex"};if(e=I.hex3.exec(t))return{r:F(e[1]+""+e[1]),g:F(e[2]+""+e[2]),b:F(e[3]+""+e[3]),format:r?"name":"hex"};return!1}(t));"object"==typeof t&&(t.hasOwnProperty("r")&&t.hasOwnProperty("g")&&t.hasOwnProperty("b")?(i=t.r,s=t.g,o=t.b,e={r:255*R(i,255),g:255*R(s,255),b:255*R(o,255)},a=!0,n="%"===String(t.r).substr(-1)?"prgb":"rgb"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("v")?(t.s=O(t.s),t.v=O(t.v),e=function(t,e,r){t=6*R(t,360),e=R(e,100),r=R(r,100);var a=f.floor(t),n=t-a,i=r*(1-e),s=r*(1-n*e),o=r*(1-(1-n)*e),l=a%6;return{r:255*[r,s,i,i,o,r][l],g:255*[o,r,r,s,i,i][l],b:255*[i,i,o,r,r,s][l]}}(t.h,t.s,t.v),a=!0,n="hsv"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("l")&&(t.s=O(t.s),t.l=O(t.l),e=function(t,e,r){var a,n,i;function s(t,e,r){return r<0&&(r+=1),1>1)+720)%360;--e;)a.h=(a.h+n)%360,i.push(d(a));return i}function C(t,e){e=e||6;for(var r=d(t).toHsv(),a=r.h,n=r.s,i=r.v,s=[],o=1/e;e--;)s.push(d({h:a,s:n,v:i})),i=(i+o)%1;return s}d.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var t=this.toRgb();return(299*t.r+587*t.g+114*t.b)/1e3},setAlpha:function(t){return this._a=M(t),this._roundA=s(100*this._a)/100,this},toHsv:function(){var t=i(this._r,this._g,this._b);return{h:360*t.h,s:t.s,v:t.v,a:this._a}},toHsvString:function(){var t=i(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.v);return 1==this._a?"hsv("+e+", "+r+"%, "+a+"%)":"hsva("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHsl:function(){var t=n(this._r,this._g,this._b);return{h:360*t.h,s:t.s,l:t.l,a:this._a}},toHslString:function(){var t=n(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.l);return 1==this._a?"hsl("+e+", "+r+"%, "+a+"%)":"hsla("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHex:function(t){return e(this._r,this._g,this._b,t)},toHexString:function(t){return"#"+this.toHex(t)},toHex8:function(){return o(this._r,this._g,this._b,this._a)},toHex8String:function(){return"#"+this.toHex8()},toRgb:function(){return{r:s(this._r),g:s(this._g),b:s(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+s(this._r)+", "+s(this._g)+", "+s(this._b)+")":"rgba("+s(this._r)+", "+s(this._g)+", "+s(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:s(100*R(this._r,255))+"%",g:s(100*R(this._g,255))+"%",b:s(100*R(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%)":"rgba("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(A[e(this._r,this._g,this._b,!0)]||!1)},toFilter:function(t){var e="#"+o(this._r,this._g,this._b,this._a),r=e,a=this._gradientType?"GradientType = 1, ":"";if(t){var n=d(t);r=n.toHex8String()}return"progid:DXImageTransform.Microsoft.gradient("+a+"startColorstr="+e+",endColorstr="+r+")"},toString:function(t){var e=!!t;t=t||this._format;var r=!1,a=this._a<1&&0<=this._a,n=!e&&a&&("hex"===t||"hex6"===t||"hex3"===t||"name"===t);return n?"name"===t&&0===this._a?this.toName():this.toRgbString():("rgb"===t&&(r=this.toRgbString()),"prgb"===t&&(r=this.toPercentageRgbString()),"hex"!==t&&"hex6"!==t||(r=this.toHexString()),"hex3"===t&&(r=this.toHexString(!0)),"hex8"===t&&(r=this.toHex8String()),"name"===t&&(r=this.toName()),"hsl"===t&&(r=this.toHslString()),"hsv"===t&&(r=this.toHsvString()),r||this.toHexString())},_applyModification:function(t,e){var r=t.apply(null,[this].concat([].slice.call(e)));return this._r=r._r,this._g=r._g,this._b=r._b,this.setAlpha(r._a),this},lighten:function(){return this._applyModification(b,arguments)},brighten:function(){return this._applyModification(v,arguments)},darken:function(){return this._applyModification(m,arguments)},desaturate:function(){return this._applyModification(r,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(g,arguments)},spin:function(){return this._applyModification(y,arguments)},_applyCombination:function(t,e){return t.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(S,arguments)},complement:function(){return this._applyCombination(w,arguments)},monochromatic:function(){return this._applyCombination(C,arguments)},splitcomplement:function(){return this._applyCombination(k,arguments)},triad:function(){return this._applyCombination(_,arguments)},tetrad:function(){return this._applyCombination(x,arguments)}},d.fromRatio=function(t,e){if("object"==typeof t){var r={};for(var a in t)t.hasOwnProperty(a)&&(r[a]="a"===a?t[a]:O(t[a]));t=r}return d(t,e)},d.equals=function(t,e){return!(!t||!e)&&d(t).toRgbString()==d(e).toRgbString()},d.random=function(){return d.fromRatio({r:t(),g:t(),b:t()})},d.mix=function(t,e,r){r=0===r?0:r||50;var a,n=d(t).toRgb(),i=d(e).toRgb(),s=r/100,o=2*s-1,l=i.a-n.a,c=1-(a=((a=o*l==-1?o:(o+l)/(1+o*l))+1)/2),f={r:i.r*a+n.r*c,g:i.g*a+n.g*c,b:i.b*a+n.b*c,a:i.a*s+n.a*(1-s)};return d(f)},d.readability=function(t,e){var r=d(t),a=d(e),n=r.toRgb(),i=a.toRgb(),s=r.getBrightness(),o=a.getBrightness(),l=Math.max(n.r,i.r)-Math.min(n.r,i.r)+Math.max(n.g,i.g)-Math.min(n.g,i.g)+Math.max(n.b,i.b)-Math.min(n.b,i.b);return{brightness:Math.abs(s-o),color:l}},d.isReadable=function(t,e){var r=d.readability(t,e);return 125MIT
-
- javascript/spectrum.js
- spectrum.js
- 1.8.0
- MIT
-
-
css/spectrum.css
spectrum.css
@@ -28,4 +21,4 @@
Graphics licensed under CC-BY
4.0
-
\ No newline at end of file
+
diff --git a/version.php b/version.php
index 17f1101..a7f338f 100644
--- a/version.php
+++ b/version.php
@@ -25,8 +25,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'mod_gcanvas';
-$plugin->release = '4.4.1';
-$plugin->version = 2024051000;
+$plugin->release = '4.5.0';
+$plugin->version = 2024091000;
$plugin->requires = 2020061500;
-$plugin->supported = [39, 404];
+$plugin->supported = [39, 405];
$plugin->maturity = MATURITY_STABLE;