diff --git a/build/closure/closure_compiled_binary.js b/build/closure/closure_compiled_binary.js
deleted file mode 100644
index d789535d..00000000
--- a/build/closure/closure_compiled_binary.js
+++ /dev/null
@@ -1,215 +0,0 @@
-var Constants={DEFAULT:{HEIGHT:32,WIDTH:32,FPS:12},MODEL_VERSION:2,MAX_HEIGHT:1024,MAX_WIDTH:1024,MINIMUM_ZOOM:1,PREVIEW_FILM_SIZE:120,ANIMATED_PREVIEW_WIDTH:200,DEFAULT_PEN_COLOR:"#000000",TRANSPARENT_COLOR:"rgba(0, 0, 0, 0)",NO_PALETTE_ID:"__no-palette",PREFERRED_COLOR_FORMAT:"rgb",SELECTION_TRANSPARENT_COLOR:"rgba(255, 255, 255, 0.6)",TOOL_TARGET_HIGHLIGHT_COLOR:"rgba(255, 255, 255, 0.2)",STATIC:{URL:{SAVE:"http://3.piskel-app.appspot.com/store",GET:"http://3.piskel-app.appspot.com/get"}},APPENGINE:{URL:{SAVE:"save"}},
-IMAGE_SERVICE_UPLOAD_URL:"http://piskel-imgstore-a.appspot.com/__/upload",IMAGE_SERVICE_GET_URL:"http://piskel-imgstore-a.appspot.com/img/",ZOOMED_OUT_BACKGROUND_COLOR:"#A0A0A0",LEFT_BUTTON:0,MIDDLE_BUTTON:1,RIGHT_BUTTON:2,MOUSEMOVE_THROTTLING:10,ABSTRACT_FUNCTION:function(){throw"abstract method should be implemented";}};var Events={TOOL_SELECTED:"TOOL_SELECTED",TOOL_RELEASED:"TOOL_RELEASED",SELECT_PRIMARY_COLOR:"SELECT_PRIMARY_COLOR",SELECT_SECONDARY_COLOR:"SELECT_SECONDARY_COLOR",PRIMARY_COLOR_SELECTED:"PRIMARY_COLOR_SELECTED",SECONDARY_COLOR_SELECTED:"SECONDARY_COLOR_SELECTED",CURSOR_MOVED:"CURSOR_MOVED",DRAG_START:"DRAG_START",DRAG_END:"DRAG_END",DIALOG_DISPLAY:"DIALOG_DISPLAY",DIALOG_HIDE:"DIALOG_HIDE",PALETTE_LIST_UPDATED:"PALETTE_LIST_UPDATED",USER_SETTINGS_CHANGED:"USER_SETTINGS_CHANGED",CLOSE_SETTINGS_DRAWER:"CLOSE_SETTINGS_DRAWER",
-PISKEL_RESET:"PISKEL_RESET",PISKEL_SAVE_STATE:"PISKEL_SAVE_STATE",PISKEL_SAVED:"PISKEL_SAVED",FRAME_SIZE_CHANGED:"FRAME_SIZE_CHANGED",SELECTION_CREATED:"SELECTION_CREATED",SELECTION_MOVE_REQUEST:"SELECTION_MOVE_REQUEST",SELECTION_DISMISSED:"SELECTION_DISMISSED",SHOW_NOTIFICATION:"SHOW_NOTIFICATION",HIDE_NOTIFICATION:"HIDE_NOTIFICATION",ZOOM_CHANGED:"ZOOM_CHANGED"};(function(){$.namespace("pskl").app={init:function(){this.isAppEngineVersion=!!pskl.appEngineToken_;this.shortcutService=new pskl.service.keyboard.ShortcutService;this.shortcutService.init();var a=this.readSizeFromURL_(),b=new pskl.model.piskel.Descriptor("New Piskel",""),b=new pskl.model.Piskel(a.width,a.height,b),c=new pskl.model.Layer("Layer 1"),a=new pskl.model.Frame(a.width,a.height);c.addFrame(a);b.addLayer(c);this.corePiskelController=new pskl.controller.piskel.PiskelController(b);this.corePiskelController.init();
-this.piskelController=new pskl.controller.piskel.PublicPiskelController(this.corePiskelController);this.piskelController.init();this.paletteController=new pskl.controller.PaletteController;this.paletteController.init();this.palettesListController=new pskl.controller.PalettesListController;this.palettesListController.init();this.cursorCoordinatesController=new pskl.controller.CursorCoordinatesController(this.piskelController);this.cursorCoordinatesController.init();this.drawingController=new pskl.controller.DrawingController(this.piskelController,
-this.paletteController,$("#drawing-canvas-container"));this.drawingController.init();this.animationController=new pskl.controller.AnimatedPreviewController(this.piskelController,$("#preview-canvas-container"));this.animationController.init();this.minimapController=new pskl.controller.MinimapController(this.piskelController,this.animationController,this.drawingController,$("#preview-canvas-container"));this.minimapController.init();this.previewsController=new pskl.controller.PreviewFilmController(this.piskelController,
-$("#preview-list"));this.previewsController.init();this.layersListController=new pskl.controller.LayersListController(this.piskelController);this.layersListController.init();this.settingsController=new pskl.controller.settings.SettingsController(this.piskelController);this.settingsController.init();this.dialogsController=new pskl.controller.dialogs.DialogsController(this.piskelController);this.dialogsController.init();this.toolController=new pskl.controller.ToolController;this.toolController.init();
-this.selectionManager=new pskl.selection.SelectionManager(this.piskelController);this.selectionManager.init();this.historyService=new pskl.service.HistoryService(this.corePiskelController);this.historyService.init();this.notificationController=new pskl.controller.NotificationController;this.notificationController.init();this.localStorageService=new pskl.service.LocalStorageService(this.piskelController);this.localStorageService.init();this.imageUploadService=new pskl.service.ImageUploadService;this.imageUploadService.init();
-this.cheatsheetService=new pskl.service.keyboard.CheatsheetService;this.cheatsheetService.init();this.savedStatusService=new pskl.service.SavedStatusService(this.piskelController);this.savedStatusService.init();this.storageService=this.isAppEngineVersion?new pskl.service.AppEngineStorageService(this.piskelController):new pskl.service.GithubStorageService(this.piskelController);this.storageService.init();a=new pskl.rendering.DrawingLoop;a.addCallback(this.render,this);a.start();this.initTooltips_();
-this.isAppEngineVersion?this.finishInitAppEngine_():this.finishInitGithub_()},finishInitGithub_:function(){var a=this.readFramesheetIdFromURL_();a&&($.publish(Events.SHOW_NOTIFICATION,[{content:"Loading animation with id : ["+a+"]"}]),this.loadFramesheetFromService(a))},finishInitAppEngine_:function(){pskl.appEnginePiskelData_&&pskl.appEnginePiskelData_.piskel&&pskl.utils.serialization.Deserializer.deserialize(pskl.appEnginePiskelData_.piskel,function(a){a.setDescriptor(pskl.appEnginePiskelData_.descriptor);
-pskl.app.piskelController.setPiskel(a);pskl.app.animationController.setFPS(pskl.appEnginePiskelData_.fps)})},isLoggedIn:function(){return pskl.appEnginePiskelData_&&pskl.appEnginePiskelData_.isLoggedIn},initTooltips_:function(){$("body").tooltip({selector:"[rel=tooltip]"})},render:function(a){this.drawingController.render(a);this.animationController.render(a);this.previewsController.render(a)},readSizeFromURL_:function(){var a,b=this.readUrlParameter_("size").split("x");!b||2!=b.length||isNaN(b[0])||
-isNaN(b[1])?a={height:Constants.DEFAULT.HEIGHT,width:Constants.DEFAULT.WIDTH}:(a=parseInt(b[0],10),b=parseInt(b[1],10),a={height:Math.min(b,Constants.MAX_HEIGHT),width:Math.min(a,Constants.MAX_WIDTH)});return a},readFramesheetIdFromURL_:function(){return this.readUrlParameter_("frameId")},readUrlParameter_:function(a){for(var b=window.location.search.substring(1).split("&"),c=0;cConstants.MOUSEMOVE_THROTTLING){var a=this.renderer.getCoordinates(b.clientX,b.clientY),e=this.piskelController.getCurrentFrame();this.isClicked?this.currentToolBehavior.moveToolAt(a.x,
-a.y,this.getCurrentColor_(b),e,this.overlayFrame,b):this.currentToolBehavior.moveUnactiveToolAt(a.x,a.y,this.getCurrentColor_(b),e,this.overlayFrame,b);$.publish(Events.CURSOR_MOVED,[a.x,a.y]);this.previousMousemoveTime=c}};a.DrawingController.prototype.onMousewheel_=function(b){b=b.originalEvent;b=b.wheelDeltaY||-2*b.deltaY;var c=this.renderer.getZoom(),a=this.calculateZoom_()/10;0b&&this.compositeRenderer.setZoom(c-a);$.publish(Events.ZOOM_CHANGED)};a.DrawingController.prototype.onMouseup_=
-function(b){if(this.isClicked){this.isClicked=!1;this.setCurrentButton(b);var c=this.renderer.getCoordinates(b.clientX,b.clientY);this.currentToolBehavior.releaseToolAt(c.x,c.y,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,b);$.publish(Events.TOOL_RELEASED)}};a.DrawingController.prototype.getSpriteCoordinates=function(b){return this.renderer.getCoordinates(b.clientX,b.clientY)};a.DrawingController.prototype.setCurrentButton=function(b){this.currentMouseButton_=
-b.button};a.DrawingController.prototype.getCurrentColor_=function(){return this.currentMouseButton_==Constants.RIGHT_BUTTON?this.paletteController.getSecondaryColor():this.currentMouseButton_==Constants.LEFT_BUTTON?this.paletteController.getPrimaryColor():Constants.DEFAULT_PEN_COLOR};a.DrawingController.prototype.onCanvasContextMenu_=function(b){if($(b.target).closest("#drawing-canvas-container").length)return b.preventDefault(),b.stopPropagation(),b.cancelBubble=!0,!1};a.DrawingController.prototype.render=
-function(){var b=this.piskelController.getCurrentFrame();b.isSameSize(this.overlayFrame)||(this.overlayFrame=pskl.model.Frame.createEmptyFromFrame(b));this.layersRenderer.render();this.renderer.render(b);this.overlayRenderer.render(this.overlayFrame)};a.DrawingController.prototype.calculateZoom_=function(){var b=this.piskelController.getCurrentFrame().getHeight(),c=this.piskelController.getCurrentFrame().getWidth();return Math.min(this.getAvailableWidth_()/c,this.getAvailableHeight_()/b)};a.DrawingController.prototype.getAvailableHeight_=
-function(){return $("#main-wrapper").height()};a.DrawingController.prototype.getAvailableWidth_=function(){var b=$(".left-column").outerWidth(!0),c=$(".right-column").outerWidth(!0),a=$("#tool-section").outerWidth(!0),e=$("#application-action-section").outerWidth(!0);return $("#main-wrapper").width()-b-c-a-e-10};a.DrawingController.prototype.getContainerHeight_=function(){return this.calculateZoom_()*this.piskelController.getCurrentFrame().getHeight()};a.DrawingController.prototype.getContainerWidth_=
-function(){return this.calculateZoom_()*this.piskelController.getCurrentFrame().getWidth()};a.DrawingController.prototype.centerColumnWrapperHorizontally_=function(){var b=this.getContainerHeight_(),b=Math.floor(($("#main-wrapper").height()-b)/2);$("#column-wrapper").css({top:b+"px"})};a.DrawingController.prototype.getRenderer=function(){return this.compositeRenderer};a.DrawingController.prototype.setOffset=function(b,c){this.compositeRenderer.setOffset(b,c);$.publish(Events.ZOOM_CHANGED)}})();(function(){var a=$.namespace("pskl.controller");a.LayersListController=function(b){this.piskelController=b};a.LayersListController.prototype.init=function(){this.layerItemTemplate_=pskl.utils.Template.get("layer-item-template");this.rootEl=document.querySelectorAll(".layers-list-container")[0];this.layersListEl=document.querySelectorAll(".layers-list")[0];this.rootEl.addEventListener("click",this.onClick_.bind(this));$.subscribe(Events.PISKEL_RESET,this.renderLayerList_.bind(this));this.renderLayerList_()};
-a.LayersListController.prototype.renderLayerList_=function(){this.layersListEl.innerHTML="";this.piskelController.getLayers().forEach(this.addLayerItem.bind(this))};a.LayersListController.prototype.addLayerItem=function(b,c){var a=this.piskelController.getCurrentLayer()===b,a=pskl.utils.Template.replace(this.layerItemTemplate_,{layername:b.getName(),layerindex:c,"isselected:current-layer-item":a}),a=pskl.utils.Template.createFromHTML(a);this.layersListEl.insertBefore(a,this.layersListEl.firstChild)};
-a.LayersListController.prototype.onClick_=function(b){b=b.target||b.srcElement;if(b.classList.contains("button"))this.onButtonClick_(b);else b.classList.contains("layer-item")?(b=b.dataset.layerIndex,this.piskelController.setCurrentLayerIndex(parseInt(b,10))):b.classList.contains("edit-icon")&&(b=b.parentNode.dataset.layerIndex,this.renameLayerAt_(b))};a.LayersListController.prototype.renameLayerAt_=function(b){var c=this.piskelController.getLayerAt(b);if(c=window.prompt("Please enter the layer name",
-c.getName()))this.piskelController.renameLayerAt(b,c),this.renderLayerList_()};a.LayersListController.prototype.onButtonClick_=function(b){b=b.getAttribute("data-action");"up"==b?this.piskelController.moveLayerUp():"down"==b?this.piskelController.moveLayerDown():"add"==b?this.piskelController.createLayer():"delete"==b&&this.piskelController.removeCurrentLayer()}})();(function(){var a=$.namespace("pskl.controller");a.MinimapController=function(b,c,a,e){this.piskelController=b;this.animationController=c;this.drawingController=a;this.container=e;this.isClicked=!1};a.MinimapController.prototype.init=function(){this.cropFrame=document.createElement("DIV");this.cropFrame.className="minimap-crop-frame";this.cropFrame.style.display="none";$(this.container).append(this.cropFrame);$(this.container).mousedown(this.onMinimapMousedown_.bind(this));$("body").mousemove(this.onMinimapMousemove_.bind(this));
-$("body").mouseup(this.onMinimapMouseup_.bind(this));$.subscribe(Events.ZOOM_CHANGED,$.proxy(this.renderMinimap_,this))};a.MinimapController.prototype.renderMinimap_=function(){var b=this.getDrawingAreaZoomRatio_();1x";
-document.body.appendChild(a);$(a).find(".close").click($.proxy(this.removeMessage_,this));c.behavior&&c.behavior(a)};a.NotificationController.prototype.removeMessage_=function(b){b=$("#user-message");b.length&&b.remove()}})();(function(){var a=$.namespace("pskl.controller");a.PaletteController=function(){this.primaryColor=Constants.DEFAULT_PEN_COLOR;this.secondaryColor=Constants.TRANSPARENT_COLOR};a.PaletteController.prototype.init=function(){$.subscribe(Events.SELECT_PRIMARY_COLOR,this.onColorSelected_.bind(this,{isPrimary:!0}));$.subscribe(Events.SELECT_SECONDARY_COLOR,this.onColorSelected_.bind(this,{isPrimary:!1}));pskl.app.shortcutService.addShortcut("X",this.swapColors.bind(this));pskl.app.shortcutService.addShortcut("D",
-this.resetColors.bind(this));var b={showPalette:!0,showButtons:!1,showInput:!0,palette:[["rgba(0,0,0,0)"]],clickoutFiresChange:!0,beforeShow:function(b){b.setAlpha(1)}},c=$("#color-picker");c.spectrum($.extend({color:Constants.DEFAULT_PEN_COLOR},b));c.change({isPrimary:!0},$.proxy(this.onPickerChange_,this));this.setTitleOnPicker_(Constants.DEFAULT_PEN_COLOR,c);c=$("#secondary-color-picker");c.spectrum($.extend({color:Constants.TRANSPARENT_COLOR},b));c.change({isPrimary:!1},$.proxy(this.onPickerChange_,
-this));this.setTitleOnPicker_(Constants.TRANSPARENT_COLOR,c);$(".swap-colors-icon").click(this.swapColors.bind(this))};a.PaletteController.prototype.onPickerChange_=function(b,c){var a=$(b.target);b.data.isPrimary?this.setPrimaryColor(a.val()):this.setSecondaryColor(a.val())};a.PaletteController.prototype.onColorSelected_=function(b,c,a){$(c.target);b.isPrimary?this.setPrimaryColor(a):this.setSecondaryColor(a)};a.PaletteController.prototype.setPrimaryColor=function(b){this.primaryColor=b;this.updateColorPicker_(b,
-$("#color-picker"));$.publish(Events.PRIMARY_COLOR_SELECTED,[b])};a.PaletteController.prototype.setSecondaryColor=function(b){this.secondaryColor=b;this.updateColorPicker_(b,$("#secondary-color-picker"));$.publish(Events.SECONDARY_COLOR_SELECTED,[b])};a.PaletteController.prototype.getPrimaryColor=function(){return this.primaryColor};a.PaletteController.prototype.getSecondaryColor=function(){return this.secondaryColor};a.PaletteController.prototype.swapColors=function(){var b=this.getPrimaryColor();
-this.setPrimaryColor(this.getSecondaryColor());this.setSecondaryColor(b)};a.PaletteController.prototype.resetColors=function(){this.setPrimaryColor(Constants.DEFAULT_PEN_COLOR);this.setSecondaryColor(Constants.TRANSPARENT_COLOR)};a.PaletteController.prototype.updateColorPicker_=function(b,c){b==Constants.TRANSPARENT_COLOR?(c.spectrum("set",Constants.TRANSPARENT_COLOR),c.val(Constants.TRANSPARENT_COLOR)):c.spectrum("set",b);this.setTitleOnPicker_(b,c)};a.PaletteController.prototype.setTitleOnPicker_=
-function(b,c){c.next(".sp-replacer").attr("title",b)}})();(function(){var a=$.namespace("pskl.controller");a.PalettesListController=function(){};a.PalettesListController.prototype.init=function(){this.paletteColorTemplate_=pskl.utils.Template.get("palette-color-template");this.colorListContainer_=document.querySelector(".palettes-list-colors");this.colorPaletteSelect_=document.querySelector(".palettes-list-select");this.paletteListOptGroup_=document.querySelector(".palettes-list-select-group");this.colorPaletteSelect_.addEventListener("change",this.onPaletteSelected_.bind(this));
-this.colorListContainer_.addEventListener("mouseup",this.onColorContainerMouseup.bind(this));this.colorListContainer_.addEventListener("contextmenu",this.onColorContainerContextMenu.bind(this));$.subscribe(Events.PALETTE_LIST_UPDATED,this.onPaletteListUpdated.bind(this));$.subscribe(Events.PRIMARY_COLOR_SELECTED,this.onColorUpdated.bind(this,"primary"));$.subscribe(Events.SECONDARY_COLOR_SELECTED,this.onColorUpdated.bind(this,"secondary"));this.fillPaletteList();this.selectPaletteFromUserSettings();
-this.fillColorListContainer()};a.PalettesListController.prototype.fillPaletteList=function(){var b=[{id:Constants.NO_PALETTE_ID,name:"No palette"}],b=b.concat(this.retrievePalettes()),b=b.map(function(b){return pskl.utils.Template.replace('',b)}).join("");this.paletteListOptGroup_.innerHTML=b};a.PalettesListController.prototype.fillColorListContainer=function(){var b="",c=this.getSelectedPalette();c&&(b=c.colors.map(function(b){return pskl.utils.Template.replace(this.paletteColorTemplate_,
-{color:b})}.bind(this)).join(""));this.colorListContainer_.innerHTML=b};a.PalettesListController.prototype.getSelectedPalette=function(b){b=this.colorPaletteSelect_.value;var c=this.retrievePalettes();return this.getPaletteById(b,c)};a.PalettesListController.prototype.selectPalette=function(b){this.colorPaletteSelect_.value=b};a.PalettesListController.prototype.selectPaletteFromUserSettings=function(){this.selectPalette(pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE))};a.PalettesListController.prototype.onPaletteSelected_=
-function(b){b=this.colorPaletteSelect_.value;"__manage-palettes"===b?($.publish(Events.DIALOG_DISPLAY,"manage-palettes"),this.selectPaletteFromUserSettings()):pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE,b);this.fillColorListContainer()};a.PalettesListController.prototype.onColorContainerContextMenu=function(b){b.preventDefault()};a.PalettesListController.prototype.onColorContainerMouseup=function(b){var c=b.target.dataset.color;c&&(b.button==Constants.LEFT_BUTTON?$.publish(Events.SELECT_PRIMARY_COLOR,
-[c]):b.button==Constants.RIGHT_BUTTON&&$.publish(Events.SELECT_SECONDARY_COLOR,[c]))};a.PalettesListController.prototype.onColorUpdated=function(b,c,a){if(c=this.colorListContainer_.querySelector('.palettes-list-color[data-color="'+a+'"]'))"primary"===b?(this.removeClass_("primary",".palettes-list-color"),c.classList.add("primary"),c.classList.remove("secondary")):"secondary"===b&&(this.removeClass_("secondary",".palettes-list-color"),c.classList.add("secondary"),c.classList.remove("primary"))};a.PalettesListController.prototype.removeClass_=
-function(b,c){var a=document.querySelector(c+"."+b);a&&a.classList.remove(b)};a.PalettesListController.prototype.onPaletteListUpdated=function(){this.fillPaletteList();this.selectPaletteFromUserSettings();this.fillColorListContainer()};a.PalettesListController.prototype.getPaletteById=function(b,c){var a=null;c.forEach(function(c){c.id===b&&(a=c)});return a};a.PalettesListController.prototype.retrievePalettes=function(){var b=window.localStorage.getItem("piskel.palettes");return JSON.parse(b)||[]}})();(function(){var a=$.namespace("pskl.controller");a.PreviewFilmController=function(b,c){this.piskelController=b;this.container=c;this.refreshZoom_();this.redrawFlag=!0};a.PreviewFilmController.prototype.init=function(){$.subscribe(Events.TOOL_RELEASED,this.flagForRedraw_.bind(this));$.subscribe(Events.PISKEL_RESET,this.flagForRedraw_.bind(this));$.subscribe(Events.USER_SETTINGS_CHANGED,this.flagForRedraw_.bind(this));$.subscribe(Events.PISKEL_RESET,this.refreshZoom_.bind(this));$("#preview-list-scroller").scroll(this.updateScrollerOverflows.bind(this));
-this.container.get(0).addEventListener("click",this.onContainerClick_.bind(this));this.updateScrollerOverflows()};a.PreviewFilmController.prototype.flagForRedraw_=function(){this.redrawFlag=!0};a.PreviewFilmController.prototype.refreshZoom_=function(){this.zoom=this.calculateZoom_()};a.PreviewFilmController.prototype.render=function(){this.redrawFlag&&(this.createPreviews_(),this.redrawFlag=!1)};a.PreviewFilmController.prototype.updateScrollerOverflows=function(){var b=$("#preview-list-scroller"),
-c=b.height(),a=b.scrollTop(),e=$("#preview-list").height(),f=$(".top-overflow").height(),g=b=!1;cf&&(b=!0),e-a-c>f&&(g=!0));c=$("#preview-list-wrapper");c.toggleClass("top-overflow-visible",b);c.toggleClass("bottom-overflow-visible",g)};a.PreviewFilmController.prototype.onContainerClick_=function(b){var c=pskl.utils.Dom.getParentWithData(b.target,"tileAction");c&&(b=c.dataset.tileAction,c=parseInt(c.dataset.tileNumber,10),"clone"===b?(this.piskelController.duplicateFrameAt(c),this.piskelController.setCurrentFrameIndex(c+
-1),this.updateScrollerOverflows()):"delete"===b?(this.piskelController.removeFrameAt(c),this.updateScrollerOverflows()):"select"===b?this.piskelController.setCurrentFrameIndex(c):"newframe"===b&&(this.piskelController.addFrame(),this.piskelController.setCurrentFrameIndex(this.piskelController.getFrameCount()-1),this.updateScrollerOverflows()))};a.PreviewFilmController.prototype.createPreviews_=function(){this.container.html("");$(".tooltip").remove();for(var b=this.piskelController.getFrameCount(),
-c=0;cAdd new frame
";this.container.append(c);1{{name}}',
-b)}.bind(this)).join("");this.palettesList.innerHTML=b};a.PaletteManagerController.prototype.createPaletteHeadMarkup=function(){var b=this.getSelectedPalette(),b={name:b.name,"save:disabled":!this.isPaletteModified(b),"revert:disabled":!this.isPaletteModified(b),"delete:disabled":2>this.palettes.length},b=pskl.utils.Template.replace(this.paletteHeadTemplate,b);this.paletteHead.innerHTML=b};a.PaletteManagerController.prototype.isPaletteModified=function(b){var a=!1,e=this.getPaletteById(b.id,this.originalPalettes);
-e?(a=e.name!==b.name,b=b.colors.join("")!==e.colors.join(""),a=a||b):a=!0;return a};a.PaletteManagerController.prototype.createPaletteBodyMarkup=function(){var b=this.getSelectedPalette(),b=this.getColorCardsMarkup(b.colors),b=b+pskl.utils.Template.replace(this.newColorTemplate,{classname:"palette-manager-new-color"});this.paletteBody.innerHTML=b};a.PaletteManagerController.prototype.initPaletteDetailsEvents=function(){this.paletteBody.querySelector(".palette-manager-new-color").addEventListener("click",
-this.onNewCardClick.bind(this));2>this.palettes.length&&this.paletteHead.querySelector('.palette-manager-palette-button[data-action="delete"]').setAttribute("disabled","disabled")};a.PaletteManagerController.prototype.onNewCardClick=function(){var b=this.getSelectedPalette();this.addColorInSelectedPalette(b&&0.palette-manager-color-square"};a.PaletteManagerController.prototype.initPaletteCardsSpectrum=function(){var b=this,a=$(this.getSpectrumSelector_());a.spectrum({clickoutFiresChange:!0,showInput:!0,showButtons:!1,change:function(a){var d=parseInt(this.parentNode.dataset.colorId,10);b.updateColorInSelectedPalette(d,a)},beforeShow:function(){var e=parseInt(this.parentNode.dataset.colorId,10),e=b.getSelectedPalette().colors[e];a.spectrum("set",e)}});
-this.spectrumContainers.push(a)};a.PaletteManagerController.prototype.destroySpectrumPickers=function(){this.spectrumContainers.forEach(function(b){b.spectrum("destroy")});this.spectrumContainers=[]};a.PaletteManagerController.prototype.updateColorInSelectedPalette=function(b,a){var e=this.getSelectedPalette(),f="#"+a.toHex().toUpperCase();e.colors.splice(b,1,f);this.redraw()};a.PaletteManagerController.prototype.addColorInSelectedPalette=function(b){this.getSelectedPalette().colors.push(b);this.redraw()};
-a.PaletteManagerController.prototype.removeColorInSelectedPalette=function(b){this.getSelectedPalette().colors.splice(b,1);this.redraw()};a.PaletteManagerController.prototype.renameSelectedPalette=function(){var b=this.getSelectedPalette(),a=window.prompt('Please enter a new name for palette "'+b.name+'"',b.name);a&&(b.name=a,this.redraw())};a.PaletteManagerController.prototype.getSelectedPalette=function(){return this.getPaletteById(this.selectedPaletteId,this.palettes)};a.PaletteManagerController.prototype.getColorCardsMarkup=
-function(a){return a.map(function(a,c){var f={colorId:c,hex:a,rgb:b(a).toRgbString(),hsl:b(a).toHslString()};return pskl.utils.Template.replace(this.colorCardTemplate,f)}.bind(this)).join("")};a.PaletteManagerController.prototype.getPaletteById=function(b,a){var e=null;a.forEach(function(a){a.id===b&&(e=a)});return e};a.PaletteManagerController.prototype.removePaletteById=function(b,a){var e=this.getPaletteById(b,a);e&&(e=a.indexOf(e),a.splice(e,1))};a.PaletteManagerController.prototype.deselectCurrentPalette=
-function(){var b=this.palettesList.querySelector(".selected");b&&(this.selectedPaletteId=null,b.classList.remove("selected"))};a.PaletteManagerController.prototype.revertChanges=function(){var b=this.getSelectedPalette(),a=this.getPaletteById(b.id,this.originalPalettes);b.name=a.name;b.colors=a.colors.slice(0);this.redraw()};a.PaletteManagerController.prototype.deleteSelectedPalette=function(){var b=this.getSelectedPalette();1=b&&0"};a.GifExportController.prototype.getSelectedZoom_=function(){var b=this.uploadForm.get(0).querySelectorAll("[name=gif-zoom-level]"),b=Array.prototype.slice.call(b,0).filter(function(b){return!!b.checked});if(1==b.length)return b[0].value;throw"Unexpected error when retrieving selected zoom";};a.GifExportController.prototype.createRadioElements_=function(){for(var b=a.GifExportController.RESOLUTIONS,c=0;c{{shortLink}}",
-{link:b,shortLink:this.shorten_(b,60,"...")});this.uploadStatusContainerEl.innerHTML="Your image is now available at : "+d}};a.GifExportController.prototype.shorten_=function(b,a,d){b.length>a&&(b=b.substring(0,a),b+=d);return b}})();(function(){var a=$.namespace("pskl.controller.settings");a.ImportController=function(b){this.piskelController=b;this.importedImage_=null};a.ImportController.prototype.init=function(){this.importForm=$("[name=import-form]");this.hiddenFileInput=$("[name=file-upload-input]");this.fileInputButton=$(".file-input-button");this.fileInputStatus=$(".file-input-status");this.fileInputStatus.html("No file selected ...");this.importPreview=$(".import-section-preview");this.resizeWidth=$("[name=resize-width]");
-this.resizeHeight=$("[name=resize-height]");this.smoothResize=$("[name=smooth-resize-checkbox]");this.submitButton=$("[name=import-submit]");this.importForm.submit(this.onImportFormSubmit_.bind(this));this.hiddenFileInput.change(this.onFileUploadChange_.bind(this));this.fileInputButton.click(this.onFileInputClick_.bind(this));this.resizeWidth.keyup(this.onResizeInputKeyUp_.bind(this,"width"));this.resizeHeight.keyup(this.onResizeInputKeyUp_.bind(this,"height"))};a.ImportController.prototype.reset_=
-function(){this.importForm.get(0).reset();this.fileInputStatus.html("No file selected ...");$.publish(Events.CLOSE_SETTINGS_DRAWER)};a.ImportController.prototype.onResizeInputKeyUp_=function(b,a){this.importedImage_&&this.synchronizeResizeFields_(a.target.value,b)};a.ImportController.prototype.synchronizeResizeFields_=function(b,a){b=parseInt(b,10);isNaN(b)&&(b=0);var d=this.importedImage_.height,e=this.importedImage_.width;"width"===a?this.resizeHeight.val(Math.round(b*d/e)):this.resizeWidth.val(Math.round(b*
-e/d))};a.ImportController.prototype.onImportFormSubmit_=function(b){b.originalEvent.preventDefault();this.importImageToPiskel_()};a.ImportController.prototype.onFileUploadChange_=function(b){this.importFromFile_()};a.ImportController.prototype.onFileInputClick_=function(b){this.hiddenFileInput.click()};a.ImportController.prototype.importFromFile_=function(){var b=this.hiddenFileInput.get(0).files;if(1==b.length)if(b=b[0],this.isImage_(b))this.readImageFile_(b),this.enableDisabledSections_();else throw this.reset_(),
-"File is not an image : "+b.type;};a.ImportController.prototype.enableDisabledSections_=function(){this.resizeWidth.removeAttr("disabled");this.resizeHeight.removeAttr("disabled");this.smoothResize.removeAttr("disabled");this.submitButton.removeAttr("disabled");this.fileInputButton.removeClass("button-primary");this.fileInputButton.blur();$(".import-section-disabled").removeClass("import-section-disabled")};a.ImportController.prototype.readImageFile_=function(b){pskl.utils.FileUtils.readFile(b,this.processImageSource_.bind(this))};
-a.ImportController.prototype.processImageSource_=function(b){this.importedImage_=new Image;this.importedImage_.onload=this.onImageLoaded_.bind(this);this.importedImage_.src=b};a.ImportController.prototype.onImageLoaded_=function(b){b=this.importedImage_.width;var a=this.importedImage_.height;this.importedImage_.onload=function(){};var d=this.hiddenFileInput.val(),d=this.extractFileNameFromPath_(d);this.fileInputStatus.html(d);this.resizeWidth.val(b);this.resizeHeight.val(a);this.importPreview.width("auto");
-this.importPreview.html("");this.importPreview.append(this.createImagePreview_())};a.ImportController.prototype.createImagePreview_=function(){var b=document.createElement("IMG");b.src=this.importedImage_.src;b.setAttribute("height",60);return b};a.ImportController.prototype.extractFileNameFromPath_=function(b){var a=[],a=-1!==b.indexOf("/")?b.split("/"):-1!==b.indexOf("\\")?b.split("\\"):[b];return a[a.length-1]};a.ImportController.prototype.importImageToPiskel_=function(){var b=this.importedImage_;
-if(b&&window.confirm("You are about to create a new Piskel, unsaved changes will be lost.")){var a=new window.SuperGif({gif:b});a.load({success:function(){var b=a.getFrames().map(function(b){return pskl.CanvasUtils.createFromImageData(b.data)});this.createPiskelFromImages_(b)}.bind(this),error:function(){this.createPiskelFromImages_([b])}.bind(this)})}};a.ImportController.prototype.createFramesFromImages_=function(b){var a=this.resizeWidth.val(),d=this.resizeHeight.val(),e=!!this.smoothResize.prop("checked");
-return b.map(function(b){b=pskl.utils.ImageResizer.resize(b,a,d,e);return pskl.utils.FrameUtils.createFromImage(b)})};a.ImportController.prototype.createPiskelFromImages_=function(b){b=this.createFramesFromImages_(b);b=pskl.model.Layer.fromFrames("Layer 1",b);var a=new pskl.model.piskel.Descriptor("Imported piskel","");b=pskl.model.Piskel.fromLayers([b],a);pskl.app.piskelController.setPiskel(b);pskl.app.animationController.setFPS(Constants.DEFAULT.FPS);this.reset_()};a.ImportController.prototype.isImage_=
-function(b){return 0===b.type.indexOf("image")}})();(function(){var a=$.namespace("pskl.controller.settings");a.LocalStorageController=function(){};a.LocalStorageController.prototype.init=function(){this.localStorageItemTemplate_=pskl.utils.Template.get("local-storage-item-template");this.service_=pskl.app.localStorageService;this.piskelsList=$(".local-piskels-list");this.fillLocalPiskelsList_();this.piskelsList.click(this.onPiskelsListClick_.bind(this))};a.LocalStorageController.prototype.onPiskelsListClick_=function(b){var a=b.target.getAttribute("data-action");
-b=b.target.getAttribute("data-name");"load"===a?window.confirm("This will erase your current piskel. Continue ?")&&(this.service_.load(b),$.publish(Events.CLOSE_SETTINGS_DRAWER)):"delete"===a&&window.confirm("This will permanently DELETE this piskel from your computer. Continue ?")&&(this.service_.remove(b),$.publish(Events.CLOSE_SETTINGS_DRAWER))};a.LocalStorageController.prototype.fillLocalPiskelsList_=function(){var b="",a=this.service_.getKeys(),d=function(b){return 10>b?"0"+b:""+b};a.sort(function(b,
-a){return b.datea.date?-1:0});a.forEach(function(a){var c=new Date(a.date),c=pskl.utils.Template.replace("{{Y}}/{{M}}/{{D}} {{H}}:{{m}}",{Y:c.getFullYear(),M:d(c.getMonth()+1),D:d(c.getDate()),H:d(c.getHours()),m:d(c.getMinutes())});b+=pskl.utils.Template.replace(this.localStorageItemTemplate_,{name:a.name,date:c})}.bind(this));this.piskelsList.get(0).tBodies[0].innerHTML=b}})();(function(){var a=$.namespace("pskl.controller.settings");a.PngExportController=function(b){this.piskelController=b};a.PngExportController.prototype.init=function(){this.previewContainerEl=document.querySelectorAll(".png-export-preview")[0];this.uploadStatusContainerEl=document.querySelectorAll(".png-upload-status")[0];document.querySelector(".png-upload-button").addEventListener("click",this.onPngUploadButtonClick_.bind(this));document.querySelector(".png-download-button").addEventListener("click",
-this.onPngDownloadButtonClick_.bind(this));document.querySelector(".zip-generate-button").addEventListener("click",this.onZipButtonClick_.bind(this));this.updatePreview_(this.getFramesheetAsBase64Png())};a.PngExportController.prototype.onPngDownloadButtonClick_=function(b){var a=this.getPiskelName_()+".png";(new pskl.rendering.PiskelRenderer(this.piskelController)).renderAsCanvas().toBlob(function(b){pskl.utils.FileUtils.downloadAsFile(a,b)})};a.PngExportController.prototype.onPngUploadButtonClick_=
-function(b){this.previewContainerEl.classList.add("preview-upload-ongoing");pskl.app.imageUploadService.upload(this.getFramesheetAsBase64Png(),this.onImageUploadCompleted_.bind(this))};a.PngExportController.prototype.onZipButtonClick_=function(){for(var b=new window.JSZip,a=0;a{{shortLink}}",{link:b,shortLink:this.shorten_(b,60,"...")});this.uploadStatusContainerEl.innerHTML="Your image is now available at : "+d}};a.PngExportController.prototype.updatePreview_=
-function(b){this.previewContainerEl.innerHTML=""};a.PngExportController.prototype.shorten_=function(b,a,d){b.length>a&&(b=b.substring(0,a),b+=d);return b}})();(function(){var a=$.namespace("pskl.controller.settings");a.ResizeController=function(b){this.piskelController=b};a.ResizeController.prototype.init=function(){this.resizeWidth=$("[name=resize-width]");this.resizeHeight=$("[name=resize-height]");this.resizeWidth.val(this.piskelController.getWidth());this.resizeHeight.val(this.piskelController.getHeight());this.cancelButton=$(".resize-cancel-button");this.cancelButton.click(this.onCancelButtonClicked_.bind(this));this.resizeForm=$("[name=resize-form]");
-this.resizeForm.submit(this.onResizeFormSubmit_.bind(this))};a.ResizeController.prototype.onResizeFormSubmit_=function(b){b.originalEvent.preventDefault();b=parseInt(this.resizeWidth.val(),10);for(var a=parseInt(this.resizeHeight.val(),10),d=[],e=this.piskelController.getLayers(),f=0;f-h&&(m-=h,b+=k);n undefined.";if(isNaN(a.zoom))throw"Bad FrameRenderer initialization. not well defined.";this.container=b;this.zoom=a.zoom;this.offset={x:0,y:0};this.margin={x:0,y:0};this.supportGridRendering=a.supportGridRendering;this.classes=d||
-[];this.classes.push("canvas");this.displayCanvas=this.canvas=null;this.setDisplaySize(a.width,a.height);this.setGridWidth(pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH));this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND));$.subscribe(Events.USER_SETTINGS_CHANGED,$.proxy(this.onUserSettingsChange_,this))};pskl.utils.inherit(pskl.rendering.frame.FrameRenderer,pskl.rendering.AbstractRenderer);a.FrameRenderer.prototype.render=function(b){b&&(this.clear(),this.renderFrame_(b))};
-a.FrameRenderer.prototype.clear=function(){pskl.CanvasUtils.clear(this.canvas);pskl.CanvasUtils.clear(this.displayCanvas)};a.FrameRenderer.prototype.setZoom=function(b){if(b>Constants.MINIMUM_ZOOM){var a=this.offset.x+this.displayWidth/(2*this.zoom),d=this.offset.y+this.displayHeight/(2*this.zoom);this.zoom=b;this.setOffset(a-this.displayWidth/(2*this.zoom),d-this.displayHeight/(2*this.zoom))}};a.FrameRenderer.prototype.getZoom=function(){return this.zoom};a.FrameRenderer.prototype.setDisplaySize=
-function(b,a){this.displayWidth=b;this.displayHeight=a;this.displayCanvas&&($(this.displayCanvas).remove(),this.displayCanvas=null);this.createDisplayCanvas_()};a.FrameRenderer.prototype.getDisplaySize=function(){return{height:this.displayHeight,width:this.displayWidth}};a.FrameRenderer.prototype.getOffset=function(){return{x:this.offset.x,y:this.offset.y}};a.FrameRenderer.prototype.moveOffset=function(b,a){this.setOffset(this.offset.x+b,this.offset.y+a)};a.FrameRenderer.prototype.setOffset=function(b,
-a){this.canvas&&(b=pskl.utils.Math.minmax(b,0,this.canvas.width-this.displayWidth/this.zoom),a=pskl.utils.Math.minmax(a,0,this.canvas.height-this.displayHeight/this.zoom));this.offset.x=b;this.offset.y=a};a.FrameRenderer.prototype.setGridWidth=function(b){this.gridWidth_=b};a.FrameRenderer.prototype.getGridWidth=function(){return this.supportGridRendering?this.gridWidth_:0};a.FrameRenderer.prototype.updateMargins_=function(){this.margin.x=Math.max(0,this.displayWidth-this.zoom*this.canvas.width)/
-2;this.margin.y=Math.max(0,this.displayHeight-this.zoom*this.canvas.height)/2};a.FrameRenderer.prototype.createDisplayCanvas_=function(){this.displayCanvas=pskl.CanvasUtils.createCanvas(this.displayWidth,this.displayHeight,this.classes);pskl.CanvasUtils.disableImageSmoothing(this.displayCanvas);this.container.append(this.displayCanvas)};a.FrameRenderer.prototype.onUserSettingsChange_=function(b,a,d){a==pskl.UserSettings.CANVAS_BACKGROUND?this.updateBackgroundClass_(d):a==pskl.UserSettings.GRID_WIDTH&&
-this.setGridWidth(d)};a.FrameRenderer.prototype.updateBackgroundClass_=function(b){var a=this.container.data("current-background-class");a&&this.container.removeClass(a);this.container.addClass(b);this.container.data("current-background-class",b)};a.FrameRenderer.prototype.renderPixel_=function(b,a,d,e){b!=Constants.TRANSPARENT_COLOR&&(e.fillStyle=b,e.fillRect(a,d,1,1))};a.FrameRenderer.prototype.getCoordinates=function(b,a){var d=this.container.offset();b-=d.left;a-=d.top;b-=this.margin.x;a-=this.margin.y;
-d=this.zoom;b+=this.offset.x*d;a+=this.offset.y*d;return{x:Math.floor(b/d),y:Math.floor(a/d)}};a.FrameRenderer.prototype.renderFrame_=function(b){this.canvas&&b.getWidth()==this.canvas.width&&b.getHeight()==this.canvas.height||(this.canvas=pskl.CanvasUtils.createCanvas(b.getWidth(),b.getHeight()));for(var a=this.canvas.getContext("2d"),d=0,e=b.getWidth();da)throw"Could not find previous SNAPSHOT saved in history stateQueue";var d=this.stateQueue[a].piskel;"string"===typeof d&&(this.stateQueue[a].piskel=JSON.parse(d),d=this.stateQueue[a].piskel);this.loadPiskel(d,this.onPiskelLoadedCallback.bind(this,b,a))}};a.HistoryService.prototype.isLoadStateAllowed_=function(b){var a=50";this.piskelController=b};a.LocalStorageService.prototype.init=function(){};a.LocalStorageService.prototype.save=function(b,a,d){this.removeFromKeys_(b);this.addToKeys_(b,a,Date.now());window.localStorage.setItem("piskel."+b,d)};a.LocalStorageService.prototype.load=function(b){var a=this.getPiskel(b),d=this.getKey_(b);pskl.utils.serialization.Deserializer.deserialize(JSON.parse(a),
-function(a){a.setDescriptor(new pskl.model.piskel.Descriptor(b,d.description,!0));pskl.app.piskelController.setPiskel(a)})};a.LocalStorageService.prototype.remove=function(a){this.removeFromKeys_(a);window.localStorage.removeItem("piskel."+a)};a.LocalStorageService.prototype.saveKeys_=function(a){window.localStorage.setItem("piskel.keys",JSON.stringify(a))};a.LocalStorageService.prototype.removeFromKeys_=function(a){var c=this.getKeys().filter(function(c){return c.name!==a});this.saveKeys_(c)};a.LocalStorageService.prototype.getKey_=
-function(a){var c=this.getKeys().filter(function(c){return c.name===a});return 0=b?b-48+"":65<=b&&90>=b?(b-65+10).toString(36):a[b]}}})();(function(){var a=$.namespace("pskl.service.keyboard");a.ShortcutService=function(){this.shortcuts_={}};a.ShortcutService.prototype.init=function(){$(document.body).keydown($.proxy(this.onKeyUp_,this))};a.ShortcutService.prototype.addShortcut=function(a,c){var d=this.parseKey_(a.toLowerCase()),e=d.key,d=d.meta;this.shortcuts_[e]=this.shortcuts_[e]||{};this.shortcuts_[e][d]?console.error("[ShortcutService] >>> Shortcut ["+(("normal"!==d?d+" + ":"")+e)+"] already registered"):this.shortcuts_[e][d]=
-c};a.ShortcutService.prototype.removeShortcut=function(a){var c=this.parseKey_(a.toLowerCase());a=c.key;c=c.meta;this.shortcuts_[a]=this.shortcuts_[a]||{};this.shortcuts_[a][c]=null};a.ShortcutService.prototype.parseKey_=function(a){var c="normal";0===a.indexOf("ctrl+")?(c="ctrl",a=a.replace("ctrl+","")):0===a.indexOf("shift+")?(c="shift",a=a.replace("shift+","")):0===a.indexOf("alt+")&&(c="alt",a=a.replace("alt+",""));return{meta:c,key:a}};a.ShortcutService.prototype.onKeyUp_=function(a){if(!this.isInInput_(a)){var c=
-a.which;a.target.nodeName.toUpperCase();var c=pskl.service.keyboard.KeycodeTranslator.toChar(c),d=this.shortcuts_[c];d&&(d=this.isCtrlKeyPressed_(a)?d.ctrl:this.isShiftKeyPressed_(a)?d.shift:this.isAltKeyPressed_(a)?d.alt:d.normal)&&(d(c),a.preventDefault())}};a.ShortcutService.prototype.isInInput_=function(a){a=a.target.nodeName.toUpperCase();return"INPUT"===a||"TEXTAREA"===a};a.ShortcutService.prototype.isCtrlKeyPressed_=function(a){return this.isMac_()?a.metaKey:a.ctrlKey};a.ShortcutService.prototype.isShiftKeyPressed_=
-function(a){return a.shiftKey};a.ShortcutService.prototype.isAltKeyPressed_=function(a){return a.altKey};a.ShortcutService.prototype.isMac_=function(){return-1!=navigator.appVersion.indexOf("Mac")}})();(function(){$.namespace("pskl").CanvasUtils={createCanvas:function(a,b,c){var d=document.createElement("canvas");d.setAttribute("width",a);d.setAttribute("height",b);"string"==typeof c&&(c=[c]);if(Array.isArray(c))for(a=0;aa[h+3]?Constants.TRANSPARENT_COLOR:pskl.utils.FrameUtils.rgbToHex(k,l,m)}}return pskl.model.Frame.fromPixelGrid(e)},rgbToHex:function(a,c,d){return"#"+this.componentToHex(a)+this.componentToHex(c)+this.componentToHex(d)},componentToHex:function(a){a=a.toString(16);return 1==a.length?"0"+a:a}}})();(function(){$.namespace("pskl.utils").ImageResizer={resize:function(a,b,c,d){var e=pskl.CanvasUtils.createCanvas(b,c),f=e.getContext("2d");f.save();d||pskl.CanvasUtils.disableImageSmoothing(e);f.translate(e.width/2,e.height/2);f.scale(b/a.width,c/a.height);f.drawImage(a,-a.width/2,-a.height/2);f.restore();return e},resizeNearestNeighbour:function(a,b,c,d){c=c||0;for(var e=pskl.CanvasUtils.createCanvas(b*a.width,b*a.height),f=e.getContext("2d"),g=pskl.CanvasUtils.getImageDataFromCanvas(a),h={},k=0,
-l=0,m,n,q=0;qn;n++){var q=m.col+h[n],p=m.row+g[n];try{a.containsPixel(q,p)&&a.getPixel(q,p)==k&&f.push({col:q,row:p})}catch(r){}}if(b>10*c){console.log("loop breaker called");break}}return e}},calculateZoomForContainer:function(a,b,c){return this.calculateZoom(a.height(),a.width(),b,c)},calculateZoom:function(a,b,c,d){return Math.min(Math.floor(a/c),Math.floor(b/d))}}})();(function(){$.namespace("pskl.utils").Template={get:function(a){var b=document.getElementById(a);if(b)return b.innerHTML;console.error("Could not find template for id :",a)},createFromHTML:function(a){var b=document.createElement("div");b.innerHTML=a;return b.children[0]},replace:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];-1!==c.indexOf(":")&&(!0===d?d=c.split(":")[1]:!1===d&&(d=""));a=a.replace(RegExp("\\{\\{"+c+"\\}\\}","g"),d)}return a}}})();(function(){var a=$.namespace("pskl.utils"),b=navigator.userAgent;a.UserAgent={isIE:/MSIE/i.test(b),isChrome:/Chrome/i.test(b),isFirefox:/Firefox/i.test(b)};a.UserAgent.version=function(){if(pskl.utils.UserAgent.isIE)return parseInt(/MSIE\s?(\d+)/i.exec(b)[1],10);if(pskl.utils.UserAgent.isChrome)return parseInt(/Chrome\/(\d+)/i.exec(b)[1],10);if(pskl.utils.UserAgent.isFirefox)return parseInt(/Firefox\/(\d+)/i.exec(b)[1],10)}()})();(function(){$.namespace("pskl").UserSettings={GRID_WIDTH:"GRID_WIDTH",CANVAS_BACKGROUND:"CANVAS_BACKGROUND",SELECTED_PALETTE:"SELECTED_PALETTE",KEY_TO_DEFAULT_VALUE_MAP_:{GRID_WIDTH:0,CANVAS_BACKGROUND:"lowcont-dark-canvas-background",SELECTED_PALETTE:Constants.NO_PALETTE_ID},cache_:{},get:function(a){this.checkKeyValidity_(a);a in this.cache_||(this.cache_[a]=this.readFromLocalStorage_(a)||this.readFromDefaults_(a));return this.cache_[a]},set:function(a,b){this.checkKeyValidity_(a);this.cache_[a]=
-b;this.writeToLocalStorage_(a,b);$.publish(Events.USER_SETTINGS_CHANGED,[a,b])},readFromLocalStorage_:function(a){a=window.localStorage[a];"undefined"!=typeof a&&(a=JSON.parse(a));return a},writeToLocalStorage_:function(a,b){window.localStorage[a]=JSON.stringify(b)},readFromDefaults_:function(a){return this.KEY_TO_DEFAULT_VALUE_MAP_[a]},checkKeyValidity_:function(a){a in this.KEY_TO_DEFAULT_VALUE_MAP_||console.log("UserSettings key <"+a+"> not find in supported keys.")}}})();jQuery.namespace=function(){var a=arguments,b=null,c,d,e;for(c=0;c