Merge branch 'master' into wip_leon_T7094_logo_image_upload_in_boilerplate
authorleon <leon@roojs.com>
Tue, 12 Jul 2022 04:57:25 +0000 (12:57 +0800)
committerleon <leon@roojs.com>
Tue, 12 Jul 2022 04:57:25 +0000 (12:57 +0800)
16 files changed:
-core.js roojs-ui.js > roojs-all.js [new file with mode: 0644]
Roo/ContentPanel.js
Roo/dialog/UploadCropbox.js [new file with mode: 0644]
Roo/dialog/namespace.js [new file with mode: 0644]
buildSDK/dependancy_ui.txt
css/alert.css [new file with mode: 0644]
css/button-groups.css [new file with mode: 0644]
css/buttons.css [new file with mode: 0644]
css/upload-cropbox.css [new file with mode: 0644]
examples/dialog/hello.html
examples/dialog/uploadCropbox.html [new file with mode: 0644]
examples/dialog/uploadCropbox.js [new file with mode: 0644]
roojs-all.js
roojs-debug.js
roojs-ui-debug.js
roojs-ui.js

diff --git a/-core.js roojs-ui.js > roojs-all.js b/-core.js roojs-ui.js > roojs-all.js
new file mode 100644 (file)
index 0000000..e07924d
--- /dev/null
@@ -0,0 +1,6983 @@
+\e[1mdiff --git a/Roo/ContentPanel.js b/Roo/ContentPanel.js\e[m
+\e[1mindex 0984532b54..cc1b9d0ce5 100644\e[m
+\e[1m--- a/Roo/ContentPanel.js\e[m
+\e[1m+++ b/Roo/ContentPanel.js\e[m
+\e[36m@@ -41,7 +41,6 @@\e[m
+  */\e[m
+ Roo.ContentPanel = function(el, config, content){\e[m
+     \e[m
+\e[31m-     \e[m
+     /*\e[m
+     if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory\e[m
+         config = el;\e[m
+\e[36m@@ -425,6 +424,14 @@\e[m \e[mlayout.addxtype({\e[m
+      */\e[m
+     \e[m
+     addxtype : function(cfg) {\e[m
+\e[32m+\e[m\e[32m        if(cfg.xtype.match(/^UploadCropbox$/)) {\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            this.cropbox = new Roo.factory(cfg);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            this.cropbox.render(this.el);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            return this.cropbox;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+         // add form..\e[m
+         if (cfg.xtype.match(/^Form$/)) {\e[m
+             \e[m
+\e[1mdiff --git a/Roo/dialog/UploadCropbox.js b/Roo/dialog/UploadCropbox.js\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..8cf986b2e5\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/Roo/dialog/UploadCropbox.js\e[m
+\e[36m@@ -0,0 +1,1791 @@\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m/*\e[m
+\e[32m+\e[m\e[32m* Licence: LGPL\e[m
+\e[32m+\e[m\e[32m*/\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m/**\e[m
+\e[32m+\e[m\e[32m * @class Roo.dialog.UploadCropbox\e[m
+\e[32m+\e[m\e[32m * @extends Roo.BoxComponent\e[m
+\e[32m+\e[m\e[32m * Dialog UploadCropbox class\e[m
+\e[32m+\e[m\e[32m * @cfg {String} emptyText show when image has been loaded\e[m
+\e[32m+\e[m\e[32m * @cfg {String} rotateNotify show when image too small to rotate\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} errorTimeout default 3000\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} minWidth default 300\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} minHeight default 300\e[m
+\e[32m+\e[m\e[32m * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} isDocument (true|false) default false\e[m
+\e[32m+\e[m\e[32m * @cfg {String} url action url\e[m
+\e[32m+\e[m\e[32m * @cfg {String} paramName default 'imageUpload'\e[m
+\e[32m+\e[m\e[32m * @cfg {String} method default POST\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} loadMask (true|false) default true\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} loadingText default 'Loading...'\e[m
+\e[32m+\e[m\e[32m *\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m * @constructor\e[m
+\e[32m+\e[m\e[32m * Create a new UploadCropbox\e[m
+\e[32m+\e[m\e[32m * @param {Object} config The config object\e[m
+\e[32m+\e[m\e[32m */\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m Roo.dialog.UploadCropbox = function(config){\e[m
+\e[32m+\e[m\e[32m    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    this.addEvents({\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event beforeselectfile\e[m
+\e[32m+\e[m\e[32m         * Fire before select file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "beforeselectfile" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event initial\e[m
+\e[32m+\e[m\e[32m         * Fire after initEvent\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "initial" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event crop\e[m
+\e[32m+\e[m\e[32m         * Fire after initEvent\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} data\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "crop" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event prepare\e[m
+\e[32m+\e[m\e[32m         * Fire when preparing the file data\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} file\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "prepare" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event exception\e[m
+\e[32m+\e[m\e[32m         * Fire when get exception\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {XMLHttpRequest} xhr\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "exception" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event beforeloadcanvas\e[m
+\e[32m+\e[m\e[32m         * Fire before load the canvas\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} src\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "beforeloadcanvas" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event trash\e[m
+\e[32m+\e[m\e[32m         * Fire when trash image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "trash" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event download\e[m
+\e[32m+\e[m\e[32m         * Fire when download the image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "download" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event footerbuttonclick\e[m
+\e[32m+\e[m\e[32m         * Fire when footerbuttonclick\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} type\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "footerbuttonclick" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event resize\e[m
+\e[32m+\e[m\e[32m         * Fire when resize\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "resize" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event rotate\e[m
+\e[32m+\e[m\e[32m         * Fire when rotate the image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} pos\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "rotate" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event inspect\e[m
+\e[32m+\e[m\e[32m         * Fire when inspect the file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} file\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "inspect" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event upload\e[m
+\e[32m+\e[m\e[32m         * Fire when xhr upload the file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} data\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "upload" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event arrange\e[m
+\e[32m+\e[m\e[32m         * Fire when arrange the file data\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} formData\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "arrange" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event loadcanvas\e[m
+\e[32m+\e[m\e[32m         * Fire after load the canvas\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox}\e[m
+\e[32m+\e[m\e[32m         * @param {Object} imgEl\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "loadcanvas" : true\e[m
+\e[32m+\e[m\e[32m    });\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;\e[m
+\e[32m+\e[m\e[32m};\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    emptyText : 'Click to upload image',\e[m
+\e[32m+\e[m\e[32m    rotateNotify : 'Image is too small to rotate',\e[m
+\e[32m+\e[m\e[32m    errorTimeout : 3000,\e[m
+\e[32m+\e[m\e[32m    scale : 0,\e[m
+\e[32m+\e[m\e[32m    baseScale : 1,\e[m
+\e[32m+\e[m\e[32m    rotate : 0,\e[m
+\e[32m+\e[m\e[32m    dragable : false,\e[m
+\e[32m+\e[m\e[32m    pinching : false,\e[m
+\e[32m+\e[m\e[32m    mouseX : 0,\e[m
+\e[32m+\e[m\e[32m    mouseY : 0,\e[m
+\e[32m+\e[m\e[32m    cropData : false,\e[m
+\e[32m+\e[m\e[32m    minWidth : 300,\e[m
+\e[32m+\e[m\e[32m    minHeight : 300,\e[m
+\e[32m+\e[m\e[32m    file : false,\e[m
+\e[32m+\e[m\e[32m    exif : {},\e[m
+\e[32m+\e[m\e[32m    baseRotate : 1,\e[m
+\e[32m+\e[m\e[32m    cropType : 'image/jpeg',\e[m
+\e[32m+\e[m\e[32m    buttons : false,\e[m
+\e[32m+\e[m\e[32m    canvasLoaded : false,\e[m
+\e[32m+\e[m\e[32m    isDocument : false,\e[m
+\e[32m+\e[m\e[32m    method : 'POST',\e[m
+\e[32m+\e[m\e[32m    paramName : 'imageUpload',\e[m
+\e[32m+\e[m\e[32m    loadMask : true,\e[m
+\e[32m+\e[m\e[32m    loadingText : 'Loading...',\e[m
+\e[32m+\e[m\e[32m    maskEl : false,\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getAutoCreate : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var cfg = {\e[m
+\e[32m+\e[m\e[32m            tag : 'div',\e[m
+\e[32m+\e[m\e[32m            cls : 'roo-upload-cropbox',\e[m
+\e[32m+\e[m\e[32m            cn : [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'input',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-selector',\e[m
+\e[32m+\e[m\e[32m                    type : 'file'\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'div',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-body',\e[m
+\e[32m+\e[m\e[32m                    style : 'cursor:pointer',\e[m
+\e[32m+\e[m\e[32m                    cn : [\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-preview'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-thumb'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-empty-notify',\e[m
+\e[32m+\e[m\e[32m                            html : this.emptyText\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',\e[m
+\e[32m+\e[m\e[32m                            html : this.rotateNotify\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[32m                    ]\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'div',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-footer',\e[m
+\e[32m+\e[m\e[32m                    cn : {\e[m
+\e[32m+\e[m\e[32m                        tag : 'div',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',\e[m
+\e[32m+\e[m\e[32m                        cn : []\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ]\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return cfg;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRender : function(ct, position)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        console.log("On Render");\e[m
+\e[32m+\e[m\e[32m        console.log(this);\e[m
+\e[32m+\e[m\e[32m        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.el){\e[m
+\e[32m+\e[m\e[32m            if (this.el.attr('xtype')) {\e[m
+\e[32m+\e[m\e[32m                this.el.attr('xtypex', this.el.attr('xtype'));\e[m
+\e[32m+\e[m\e[32m                this.el.dom.removeAttribute('xtype');\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.initEvents();\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        else {\e[m
+\e[32m+\e[m\e[32m            var cfg = Roo.apply({},  this.getAutoCreate());\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            cfg.id = this.id || Roo.id();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if (this.cls) {\e[m
+\e[32m+\e[m\e[32m                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if (this.style) { // fixme needs to support more complex style data.\e[m
+\e[32m+\e[m\e[32m                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.el = ct.createChild(cfg, position);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.initEvents();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (this.buttons.length) {\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            Roo.each(this.buttons, function(bb) {\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m            }, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl = this.el;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    initEvents : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.urlAPI = (window.createObjectURL && window) ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                (window.URL && URL.revokeObjectURL && URL) ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                (window.webkitURL && webkitURL);\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();\e[m
+\e[32m+\e[m\e[32m        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();\e[m
+\e[32m+\e[m\e[32m        this.selectorEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();\e[m
+\e[32m+\e[m\e[32m        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();\e[m
+\e[32m+\e[m\e[32m        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.errorEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();\e[m
+\e[32m+\e[m\e[32m        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.footerEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.bind();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.resize();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('initial', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    bind : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        window.addEventListener("resize", function() { _this.resize(); } );\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.bodyEl.on('click', this.beforeSelectFile, this);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(Roo.isTouch){\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchstart', this.onTouchStart, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchmove', this.onTouchMove, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchend', this.onTouchEnd, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!Roo.isTouch){\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('mousedown', this.onMouseDown, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('mousemove', this.onMouseMove, this);\e[m
+\e[32m+\e[m\e[32m            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on(mousewheel, this.onMouseWheel, this);\e[m
+\e[32m+\e[m\e[32m            Roo.get(document).on('mouseup', this.onMouseUp, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.selectorEl.on('change', this.onFileSelected, this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    reset : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        this.scale = 0;\e[m
+\e[32m+\e[m\e[32m        this.baseScale = 1;\e[m
+\e[32m+\e[m\e[32m        this.rotate = 0;\e[m
+\e[32m+\e[m\e[32m        this.baseRotate = 1;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[32m        this.mouseX = 0;\e[m
+\e[32m+\e[m\e[32m        this.mouseY = 0;\e[m
+\e[32m+\e[m\e[32m        this.cropData = false;\e[m
+\e[32m+\e[m\e[32m        this.notifyEl.dom.innerHTML = this.emptyText;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        // this.selectorEl.dom.value = '';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    resize : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('resize', this) != false){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onFooterButtonClick : function(e, el, o, type)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        switch (type) {\e[m
+\e[32m+\e[m\e[32m            case 'rotate-left' :\e[m
+\e[32m+\e[m\e[32m                this.onRotateLeft(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'rotate-right' :\e[m
+\e[32m+\e[m\e[32m                this.onRotateRight(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'picture' :\e[m
+\e[32m+\e[m\e[32m                this.beforeSelectFile(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'trash' :\e[m
+\e[32m+\e[m\e[32m                this.trash(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'crop' :\e[m
+\e[32m+\e[m\e[32m                this.crop(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'download' :\e[m
+\e[32m+\e[m\e[32m                this.download(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('footerbuttonclick', this, type);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    beforeSelectFile : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        e.preventDefault();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('beforeselectfile', this) != false){\e[m
+\e[32m+\e[m\e[32m            this.selectorEl.dom.click();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onFileSelected : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        e.preventDefault();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var file = this.selectorEl.dom.files[0];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('inspect', this, file) != false){\e[m
+\e[32m+\e[m\e[32m            this.prepare(file);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    trash : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.fireEvent('trash', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    download : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.fireEvent('download', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    loadCanvas : function(src)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('beforeloadcanvas', this, src) != false){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.reset();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl = document.createElement('img');\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var _this = this;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl.src = src;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onLoadCanvas : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;\e[m
+\e[32m+\e[m\e[32m        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            this.bodyEl.un('click', this.beforeSelectFile, this);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.notifyEl.hide();\e[m
+\e[32m+\e[m\e[32m            this.thumbEl.show();\e[m
+\e[32m+\e[m\e[32m            this.footerEl.show();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.baseRotateLevel();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m                this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.baseScaleLevel();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.draw();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.resize();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.canvasLoaded = true;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setCanvasPosition : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(!this.canvasEl){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);\e[m
+\e[32m+\e[m\e[32m        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.setLeft(pw);\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setTop(ph);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseDown : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.dragable = true;\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[32m            this.dragable = false;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseMove : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (!this.dragable){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var minX = Math.ceil(this.thumbEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m        var minY = Math.ceil(this.thumbEl.getTop(true));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);\e[m
+\e[32m+\e[m\e[32m        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        x = x - this.mouseX;\e[m
+\e[32m+\e[m\e[32m        y = y - this.mouseY;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var bgX = Math.ceil(x + this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m        var bgY = Math.ceil(y + this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        bgX = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX);\e[m
+\e[32m+\e[m\e[32m        bgY = (minY < bgY) ? minY : ((maxY > bgY) ? maxY : bgY);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.setLeft(bgX);\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setTop(bgY);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseUp : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseWheel : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    zoomable : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.minWidth < this.minHeight){\e[m
+\e[32m+\e[m\e[32m            minScale = this.thumbEl.getHeight() / this.minHeight;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);\e[m
+\e[32m+\e[m\e[32m        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 0 || this.rotate == 180) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight ||\e[m
+\e[32m+\e[m\e[32m                    (width < this.minWidth && height < this.minHeight)\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 90 || this.rotate == 270) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight ||\e[m
+\e[32m+\e[m\e[32m                    (width < this.minHeight && height < this.minWidth)\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                !this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 0 || this.rotate == 180) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width < this.minWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height < this.minHeight ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                !this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 90 || this.rotate == 270) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width < this.minHeight ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height < this.minWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return true;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateLeft : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            while (this.getScaleLevel() < minScale){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                this.scale = this.scale + 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()\e[m
+\e[32m+\e[m\e[32m                ){\e[m
+\e[32m+\e[m\e[32m                    continue;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                this.draw();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.onRotateFail();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('rotate', this, 'left');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateRight : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            while (this.getScaleLevel() < minScale){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                this.scale = this.scale + 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()\e[m
+\e[32m+\e[m\e[32m                ){\e[m
+\e[32m+\e[m\e[32m                    continue;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                this.draw();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.onRotateFail();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('rotate', this, 'right');\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateFail : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.errorEl.show(true);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    draw : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.previewEl.dom.innerHTML = '';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var canvasEl = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var contextEl = canvasEl.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m        var center = this.imageEl.OriginWidth / 2;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m            center = this.imageEl.OriginHeight / 2;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        contextEl.translate(center, center);\e[m
+\e[32m+\e[m\e[32m        contextEl.rotate(this.rotate * Math.PI / 180);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.canvasEl = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.contextEl = this.canvasEl.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        switch (this.rotate) {\e[m
+\e[32m+\e[m\e[32m            case 0 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 90 :\e[m\e[41m \e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 180 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 270 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.appendChild(this.canvasEl);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    crop : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var imageCanvas = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var imageContext = imageCanvas.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var center = imageCanvas.width / 2;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.translate(center, center);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.rotate(this.rotate * Math.PI / 180);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var canvas = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var context = canvas.getContext("2d");\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m        canvas.width = this.minWidth;\e[m
+\e[32m+\e[m\e[32m        canvas.height = this.minHeight;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        switch (this.rotate) {\e[m
+\e[32m+\e[m\e[32m            case 0 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 90 :\e[m\e[41m \e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 180 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32m                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 270 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.cropData = canvas.toDataURL(this.cropType);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('crop', this, this.cropData) !== false){\e[m
+\e[32m+\e[m\e[32m            this.process(this.file, this.cropData);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setThumbBoxSize : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var width, height;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument && typeof(this.imageEl) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);\e[m
+\e[32m+\e[m\e[32m            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.minWidth = width;\e[m
+\e[32m+\e[m\e[32m            this.minHeight = height;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.rotate == 90 || this.rotate == 270){\e[m
+\e[32m+\e[m\e[32m                this.minWidth = height;\e[m
+\e[32m+\e[m\e[32m                this.minHeight = width;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        height = 300;\e[m
+\e[32m+\e[m\e[32m        width = Math.ceil(this.minWidth * height / this.minHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.minWidth > this.minHeight){\e[m
+\e[32m+\e[m\e[32m            width = 300;\e[m
+\e[32m+\e[m\e[32m            height = Math.ceil(this.minHeight * width / this.minWidth);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setStyle({\e[m
+\e[32m+\e[m\e[32m            width : width + 'px',\e[m
+\e[32m+\e[m\e[32m            height : height + 'px'\e[m
+\e[32m+\e[m\e[32m        });\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setThumbBoxPosition : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );\e[m
+\e[32m+\e[m\e[32m        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setLeft(x);\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setTop(y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    baseRotateLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.baseRotate = 1;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                typeof(this.exif) != 'undefined' &&\e[m
+\e[32m+\e[m\e[32m                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&\e[m
+\e[32m+\e[m\e[32m                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    baseScaleLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var width, height;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.baseRotate == 6 || this.baseRotate == 8){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                    width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                    this.baseScale = width / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.baseRotate == 6 || this.baseRotate == 8){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            width = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = width / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){\e[m
+\e[32m+\e[m\e[32m                    width = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m                    this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m        this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){\e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getScaleLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        return this.baseScale * Math.pow(1.1, this.scale);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchStart : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            this.beforeSelectFile(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var touches = e.browserEvent.touches;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!touches){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(touches.length == 1){\e[m
+\e[32m+\e[m\e[32m            this.onMouseDown(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(touches.length != 2){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var coords = [];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for(var i = 0, finger; finger = touches[i]; i++){\e[m
+\e[32m+\e[m\e[32m            coords.push(finger.pageX, finger.pageY);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Math.pow(coords[0] - coords[2], 2);\e[m
+\e[32m+\e[m\e[32m        var y = Math.pow(coords[1] - coords[3], 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startDistance = Math.sqrt(x + y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.pinching = true;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchMove : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.pinching && !this.dragable){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var touches = e.browserEvent.touches;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!touches){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.dragable){\e[m
+\e[32m+\e[m\e[32m            this.onMouseMove(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var coords = [];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for(var i = 0, finger; finger = touches[i]; i++){\e[m
+\e[32m+\e[m\e[32m            coords.push(finger.pageX, finger.pageY);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Math.pow(coords[0] - coords[2], 2);\e[m
+\e[32m+\e[m\e[32m        var y = Math.pow(coords[1] - coords[3], 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.endDistance = Math.sqrt(x + y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchEnd : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    process : function(file, crop)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.mask(this.loadingText);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr = new XMLHttpRequest();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        file.xhr = this.xhr;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        this.xhr.open(this.method, this.url, true);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var headers = {\e[m
+\e[32m+\e[m\e[32m            "Accept": "application/json",\e[m
+\e[32m+\e[m\e[32m            "Cache-Control": "no-cache",\e[m
+\e[32m+\e[m\e[32m            "X-Requested-With": "XMLHttpRequest"\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for (var headerName in headers) {\e[m
+\e[32m+\e[m\e[32m            var headerValue = headers[headerName];\e[m
+\e[32m+\e[m\e[32m            if (headerValue) {\e[m
+\e[32m+\e[m\e[32m                this.xhr.setRequestHeader(headerName, headerValue);\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr.onload = function()\e[m
+\e[32m+\e[m\e[32m        {\e[m
+\e[32m+\e[m\e[32m            _this.xhrOnLoad(_this.xhr);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr.onerror = function()\e[m
+\e[32m+\e[m\e[32m        {\e[m
+\e[32m+\e[m\e[32m            _this.xhrOnError(_this.xhr);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var formData = new FormData();\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        formData.append('returnHTML', 'NO');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(crop){\e[m
+\e[32m+\e[m\e[32m            formData.append('crop', crop);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file) != 'undefined' && (typeof(file.id) == 'undefined' || file.id * 1 < 1)){\e[m
+\e[32m+\e[m\e[32m            formData.append(this.paramName, file, file.name);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file.filename) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            formData.append('filename', file.filename);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file.mimetype) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            formData.append('mimetype', file.mimetype);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('arrange', this, formData) != false){\e[m
+\e[32m+\e[m\e[32m            this.xhr.send(formData);\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    xhrOnLoad : function(xhr)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (xhr.readyState !== 4) {\e[m
+\e[32m+\e[m\e[32m            this.fireEvent('exception', this, xhr);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!response.success){\e[m
+\e[32m+\e[m\e[32m            this.fireEvent('exception', this, xhr);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('upload', this, response);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    xhrOnError : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        Roo.log('xhr on error');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m          \e[m
+\e[32m+\e[m\e[32m        Roo.log(response);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    prepare : function(file)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.mask(this.loadingText);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.file = false;\e[m
+\e[32m+\e[m\e[32m        this.exif = {};\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file) === 'string'){\e[m
+\e[32m+\e[m\e[32m            this.loadCanvas(file);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!file || !this.urlAPI){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.file = file;\e[m
+\e[32m+\e[m\e[32m        this.cropType = file.type;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('prepare', this, this.file) != false){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var reader = new FileReader();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            reader.onload = function (e) {\e[m
+\e[32m+\e[m\e[32m                if (e.target.error) {\e[m
+\e[32m+\e[m\e[32m                    Roo.log(e.target.error);\e[m
+\e[32m+\e[m\e[32m                    return;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var buffer = e.target.result,\e[m
+\e[32m+\e[m\e[32m                    dataView = new DataView(buffer),\e[m
+\e[32m+\e[m\e[32m                    offset = 2,\e[m
+\e[32m+\e[m\e[32m                    maxOffset = dataView.byteLength - 4,\e[m
+\e[32m+\e[m\e[32m                    markerBytes,\e[m
+\e[32m+\e[m\e[32m                    markerLength;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if (dataView.getUint16(0) === 0xffd8) {\e[m
+\e[32m+\e[m\e[32m                    while (offset < maxOffset) {\e[m
+\e[32m+\e[m\e[32m                        markerBytes = dataView.getUint16(offset);\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {\e[m
+\e[32m+\e[m\e[32m                            markerLength = dataView.getUint16(offset + 2) + 2;\e[m
+\e[32m+\e[m\e[32m                            if (offset + markerLength > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m                                Roo.log('Invalid meta data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32m                                break;\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            if(markerBytes == 0xffe1){\e[m
+\e[32m+\e[m\e[32m                                _this.parseExifData(\e[m
+\e[32m+\e[m\e[32m                                    dataView,\e[m
+\e[32m+\e[m\e[32m                                    offset,\e[m
+\e[32m+\e[m\e[32m                                    markerLength\e[m
+\e[32m+\e[m\e[32m                                );\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            offset += markerLength;\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            continue;\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                        break;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var url = _this.urlAPI.createObjectURL(_this.file);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                _this.loadCanvas(url);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            reader.readAsArrayBuffer(this.file);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifData : function(dataView, offset, length)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tiffOffset = offset + 10,\e[m
+\e[32m+\e[m\e[32m            littleEndian,\e[m
+\e[32m+\e[m\e[32m            dirOffset;\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint32(offset + 4) !== 0x45786966) {\e[m
+\e[32m+\e[m\e[32m            // No Exif data, might be XMP data instead\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        // Check for the ASCII code for "Exif" (0x45786966):\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint32(offset + 4) !== 0x45786966) {\e[m
+\e[32m+\e[m\e[32m            // No Exif data, might be XMP data instead\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        if (tiffOffset + 8 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check for the two null bytes:\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint16(offset + 8) !== 0x0000) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Missing byte alignment offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check the byte alignment:\e[m
+\e[32m+\e[m\e[32m        switch (dataView.getUint16(tiffOffset)) {\e[m
+\e[32m+\e[m\e[32m        case 0x4949:\e[m
+\e[32m+\e[m\e[32m            littleEndian = true;\e[m
+\e[32m+\e[m\e[32m            break;\e[m
+\e[32m+\e[m\e[32m        case 0x4D4D:\e[m
+\e[32m+\e[m\e[32m            littleEndian = false;\e[m
+\e[32m+\e[m\e[32m            break;\e[m
+\e[32m+\e[m\e[32m        default:\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid byte alignment marker.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check for the TIFF tag marker (0x002A):\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Missing TIFF marker.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\e[m
+\e[32m+\e[m\e[32m        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.parseExifTags(\e[m
+\e[32m+\e[m\e[32m            dataView,\e[m
+\e[32m+\e[m\e[32m            tiffOffset,\e[m
+\e[32m+\e[m\e[32m            tiffOffset + dirOffset,\e[m
+\e[32m+\e[m\e[32m            littleEndian\e[m
+\e[32m+\e[m\e[32m        );\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tagsNumber,\e[m
+\e[32m+\e[m\e[32m            dirEndOffset,\e[m
+\e[32m+\e[m\e[32m            i;\e[m
+\e[32m+\e[m\e[32m        if (dirOffset + 6 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid directory offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        tagsNumber = dataView.getUint16(dirOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;\e[m
+\e[32m+\e[m\e[32m        if (dirEndOffset + 4 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid directory size.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        for (i = 0; i < tagsNumber; i += 1) {\e[m
+\e[32m+\e[m\e[32m            this.parseExifTag(\e[m
+\e[32m+\e[m\e[32m                dataView,\e[m
+\e[32m+\e[m\e[32m                tiffOffset,\e[m
+\e[32m+\e[m\e[32m                dirOffset + 2 + 12 * i, // tag offset\e[m
+\e[32m+\e[m\e[32m                littleEndian\e[m
+\e[32m+\e[m\e[32m            );\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Return the offset to the next directory:\e[m
+\e[32m+\e[m\e[32m        return dataView.getUint32(dirEndOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifTag : function (dataView, tiffOffset, offset, littleEndian)\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tag = dataView.getUint16(offset, littleEndian);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.exif[tag] = this.getExifValue(\e[m
+\e[32m+\e[m\e[32m            dataView,\e[m
+\e[32m+\e[m\e[32m            tiffOffset,\e[m
+\e[32m+\e[m\e[32m            offset,\e[m
+\e[32m+\e[m\e[32m            dataView.getUint16(offset + 2, littleEndian), // tag type\e[m
+\e[32m+\e[m\e[32m            dataView.getUint32(offset + 4, littleEndian), // tag length\e[m
+\e[32m+\e[m\e[32m            littleEndian\e[m
+\e[32m+\e[m\e[32m        );\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],\e[m
+\e[32m+\e[m\e[32m            tagSize,\e[m
+\e[32m+\e[m\e[32m            dataOffset,\e[m
+\e[32m+\e[m\e[32m            values,\e[m
+\e[32m+\e[m\e[32m            i,\e[m
+\e[32m+\e[m\e[32m            str,\e[m
+\e[32m+\e[m\e[32m            c;\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        if (!tagType) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid tag type.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        tagSize = tagType.size * length;\e[m
+\e[32m+\e[m\e[32m        // Determine if the value is contained in the dataOffset bytes,\e[m
+\e[32m+\e[m\e[32m        // or if the value at the dataOffset is a pointer to the actual data:\e[m
+\e[32m+\e[m\e[32m        dataOffset = tagSize > 4 ?\e[m
+\e[32m+\e[m\e[32m                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);\e[m
+\e[32m+\e[m\e[32m        if (dataOffset + tagSize > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid data offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        if (length === 1) {\e[m
+\e[32m+\e[m\e[32m            return tagType.getValue(dataView, dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        values = [];\e[m
+\e[32m+\e[m\e[32m        for (i = 0; i < length; i += 1) {\e[m
+\e[32m+\e[m\e[32m            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (tagType.ascii) {\e[m
+\e[32m+\e[m\e[32m            str = '';\e[m
+\e[32m+\e[m\e[32m            // Concatenate the chars:\e[m
+\e[32m+\e[m\e[32m            for (i = 0; i < values.length; i += 1) {\e[m
+\e[32m+\e[m\e[32m                c = values[i];\e[m
+\e[32m+\e[m\e[32m                // Ignore the terminating NULL byte(s):\e[m
+\e[32m+\e[m\e[32m                if (c === '\u0000') {\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m                str += c;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m            return str;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        return values;\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m});\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.apply(Roo.dialog.UploadCropbox, {\e[m
+\e[32m+\e[m\e[32m    tags : {\e[m
+\e[32m+\e[m\e[32m        'Orientation': 0x0112\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    Orientation: {\e[m
+\e[32m+\e[m\e[32m            1: 0, //'top-left',\e[m
+\e[32m+\e[m\e[32m//            2: 'top-right',\e[m
+\e[32m+\e[m\e[32m            3: 180, //'bottom-right',\e[m
+\e[32m+\e[m\e[32m//            4: 'bottom-left',\e[m
+\e[32m+\e[m\e[32m//            5: 'left-top',\e[m
+\e[32m+\e[m\e[32m            6: 90, //'right-top',\e[m
+\e[32m+\e[m\e[32m//            7: 'right-bottom',\e[m
+\e[32m+\e[m\e[32m            8: 270 //'left-bottom'\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    exifTagTypes : {\e[m
+\e[32m+\e[m\e[32m        // byte, 8-bit unsigned int:\e[m
+\e[32m+\e[m\e[32m        1: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint8(dataOffset);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 1\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // ascii, 8-bit byte:\e[m
+\e[32m+\e[m\e[32m        2: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset) {\e[m
+\e[32m+\e[m\e[32m                return String.fromCharCode(dataView.getUint8(dataOffset));\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 1,\e[m
+\e[32m+\e[m\e[32m            ascii: true\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // short, 16 bit int:\e[m
+\e[32m+\e[m\e[32m        3: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint16(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 2\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // long, 32 bit int:\e[m
+\e[32m+\e[m\e[32m        4: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint32(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 4\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // rational = two long values, first is numerator, second is denominator:\e[m
+\e[32m+\e[m\e[32m        5: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint32(dataOffset, littleEndian) /\e[m
+\e[32m+\e[m\e[32m                    dataView.getUint32(dataOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 8\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // slong, 32 bit signed int:\e[m
+\e[32m+\e[m\e[32m        9: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getInt32(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 4\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // srational, two slongs, first is numerator, second is denominator:\e[m
+\e[32m+\e[m\e[32m        10: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getInt32(dataOffset, littleEndian) /\e[m
+\e[32m+\e[m\e[32m                    dataView.getInt32(dataOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 8\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    footer : {\e[m
+\e[32m+\e[m\e[32m        STANDARD : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-picture',\e[m
+\e[32m+\e[m\e[32m                action : 'picture',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-picture-o"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ],\e[m
+\e[32m+\e[m\e[32m        DOCUMENT : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-download',\e[m
+\e[32m+\e[m\e[32m                action : 'download',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-download"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-crop',\e[m
+\e[32m+\e[m\e[32m                action : 'crop',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-crop"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-trash',\e[m
+\e[32m+\e[m\e[32m                action : 'trash',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-trash"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ],\e[m
+\e[32m+\e[m\e[32m        ROTATOR : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ]\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[32m});\e[m
+\e[1mdiff --git a/buildSDK/dependancy_ui.txt b/buildSDK/dependancy_ui.txt\e[m
+\e[1mindex 5a8e5a9ac5..f89656e412 100644\e[m
+\e[1m--- a/buildSDK/dependancy_ui.txt\e[m
+\e[1m+++ b/buildSDK/dependancy_ui.txt\e[m
+\e[36m@@ -197,3 +197,6 @@\e[m \e[mRoo.XTemplate\e[m
\e[m
+ // is this ready yet? - is it used?\e[m
+ // Roo.Login\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.dialog.namespace\e[m
+\e[32m+\e[m\e[32mRoo.dialog.UploadCropbox\e[m
+\e[1mdiff --git a/css/alert.css b/css/alert.css\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..0cc7751f02\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/css/alert.css\e[m
+\e[36m@@ -0,0 +1,75 @@\e[m
+\e[32m+\e[m\e[32m.alert {\e[m
+\e[32m+\e[m\e[32m  padding: 15px;\e[m
+\e[32m+\e[m\e[32m  margin-bottom: 20px;\e[m
+\e[32m+\e[m\e[32m  border: 1px solid transparent;\e[m
+\e[32m+\e[m\e[32m  border-radius: 4px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert h4 {\e[m
+\e[32m+\e[m\e[32m  margin-top: 0;\e[m
+\e[32m+\e[m\e[32m  color: inherit;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert .alert-link {\e[m
+\e[32m+\e[m\e[32m  font-weight: bold;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert > p,\e[m
+\e[32m+\e[m\e[32m.alert > ul {\e[m
+\e[32m+\e[m\e[32m  margin-bottom: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert > p + p {\e[m
+\e[32m+\e[m\e[32m  margin-top: 5px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-dismissable,\e[m
+\e[32m+\e[m\e[32m.alert-dismissible {\e[m
+\e[32m+\e[m\e[32m  padding-right: 35px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-dismissable .close,\e[m
+\e[32m+\e[m\e[32m.alert-dismissible .close {\e[m
+\e[32m+\e[m\e[32m  position: relative;\e[m
+\e[32m+\e[m\e[32m  top: -2px;\e[m
+\e[32m+\e[m\e[32m  right: -21px;\e[m
+\e[32m+\e[m\e[32m  color: inherit;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-success {\e[m
+\e[32m+\e[m\e[32m  background-color: #dff0d8;\e[m
+\e[32m+\e[m\e[32m  border-color: #d6e9c6;\e[m
+\e[32m+\e[m\e[32m  color: #3c763d;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-success hr {\e[m
+\e[32m+\e[m\e[32m  border-top-color: #c9e2b3;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-success .alert-link {\e[m
+\e[32m+\e[m\e[32m  color: #2b542c;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-info {\e[m
+\e[32m+\e[m\e[32m  background-color: #d9edf7;\e[m
+\e[32m+\e[m\e[32m  border-color: #bce8f1;\e[m
+\e[32m+\e[m\e[32m  color: #31708f;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-info hr {\e[m
+\e[32m+\e[m\e[32m  border-top-color: #a6e1ec;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-info .alert-link {\e[m
+\e[32m+\e[m\e[32m  color: #245269;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-warning {\e[m
+\e[32m+\e[m\e[32m  background-color: #fcf8e3;\e[m
+\e[32m+\e[m\e[32m  border-color: #faebcc;\e[m
+\e[32m+\e[m\e[32m  color: #8a6d3b;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-warning hr {\e[m
+\e[32m+\e[m\e[32m  border-top-color: #f7e1b5;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-warning .alert-link {\e[m
+\e[32m+\e[m\e[32m  color: #66512c;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-danger {\e[m
+\e[32m+\e[m\e[32m  background-color: #f2dede;\e[m
+\e[32m+\e[m\e[32m  border-color: #ebccd1;\e[m
+\e[32m+\e[m\e[32m  color: #a94442;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-danger hr {\e[m
+\e[32m+\e[m\e[32m  border-top-color: #e4b9c0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.alert-danger .alert-link {\e[m
+\e[32m+\e[m\e[32m  color: #843534;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\ No newline at end of file\e[m
+\e[1mdiff --git a/css/button-groups.css b/css/button-groups.css\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..b725faf99b\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/css/button-groups.css\e[m
+\e[36m@@ -0,0 +1,171 @@\e[m
+\e[32m+\e[m\e[32m.btn-group,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical {\e[m
+\e[32m+\e[m\e[32m  position: relative;\e[m
+\e[32m+\e[m\e[32m  display: inline-block;\e[m
+\e[32m+\e[m\e[32m  vertical-align: middle;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn {\e[m
+\e[32m+\e[m\e[32m  position: relative;\e[m
+\e[32m+\e[m\e[32m  float: left;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:hover,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn:hover,\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:focus,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn:focus,\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:active,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn:active,\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn.active,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn.active {\e[m
+\e[32m+\e[m\e[32m  z-index: 2;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group .btn + .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group .btn + .btn-group,\e[m
+\e[32m+\e[m\e[32m.btn-group .btn-group + .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group .btn-group + .btn-group {\e[m
+\e[32m+\e[m\e[32m  margin-left: -1px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-toolbar {\e[m
+\e[32m+\e[m\e[32m  margin-left: -5px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-toolbar .btn,\e[m
+\e[32m+\e[m\e[32m.btn-toolbar .btn-group,\e[m
+\e[32m+\e[m\e[32m.btn-toolbar .input-group {\e[m
+\e[32m+\e[m\e[32m  float: left;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-toolbar > .btn,\e[m
+\e[32m+\e[m\e[32m.btn-toolbar > .btn-group,\e[m
+\e[32m+\e[m\e[32m.btn-toolbar > .input-group {\e[m
+\e[32m+\e[m\e[32m  margin-left: 5px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\e[m
+\e[32m+\e[m\e[32m  border-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:first-child {\e[m
+\e[32m+\e[m\e[32m  margin-left: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\e[m
+\e[32m+\e[m\e[32m  border-bottom-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-top-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn:last-child:not(:first-child),\e[m
+\e[32m+\e[m\e[32m.btn-group > .dropdown-toggle:not(:first-child) {\e[m
+\e[32m+\e[m\e[32m  border-bottom-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-top-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn-group {\e[m
+\e[32m+\e[m\e[32m  float: left;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\e[m
+\e[32m+\e[m\e[32m  border-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\e[m
+\e[32m+\e[m\e[32m  border-bottom-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-top-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\e[m
+\e[32m+\e[m\e[32m  border-bottom-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-top-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group .dropdown-toggle:active,\e[m
+\e[32m+\e[m\e[32m.btn-group.open .dropdown-toggle {\e[m
+\e[32m+\e[m\e[32m  outline: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn + .dropdown-toggle {\e[m
+\e[32m+\e[m\e[32m  padding-left: 8px;\e[m
+\e[32m+\e[m\e[32m  padding-right: 8px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group > .btn-lg + .dropdown-toggle {\e[m
+\e[32m+\e[m\e[32m  padding-left: 12px;\e[m
+\e[32m+\e[m\e[32m  padding-right: 12px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group.open .dropdown-toggle {\e[m
+\e[32m+\e[m\e[32m  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\e[m
+\e[32m+\e[m\e[32m  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group.open .dropdown-toggle.btn-link {\e[m
+\e[32m+\e[m\e[32m  -webkit-box-shadow: none;\e[m
+\e[32m+\e[m\e[32m  box-shadow: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn .caret {\e[m
+\e[32m+\e[m\e[32m  margin-left: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-lg .caret {\e[m
+\e[32m+\e[m\e[32m  border-width: 5px 5px 0;\e[m
+\e[32m+\e[m\e[32m  border-bottom-width: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.dropup .btn-lg .caret {\e[m
+\e[32m+\e[m\e[32m  border-width: 0 5px 5px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group > .btn {\e[m
+\e[32m+\e[m\e[32m  display: block;\e[m
+\e[32m+\e[m\e[32m  float: none;\e[m
+\e[32m+\e[m\e[32m  width: 100%;\e[m
+\e[32m+\e[m\e[32m  max-width: 100%;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group > .btn {\e[m
+\e[32m+\e[m\e[32m  float: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn + .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn + .btn-group,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group + .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group + .btn-group {\e[m
+\e[32m+\e[m\e[32m  margin-top: -1px;\e[m
+\e[32m+\e[m\e[32m  margin-left: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\e[m
+\e[32m+\e[m\e[32m  border-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn:first-child:not(:last-child) {\e[m
+\e[32m+\e[m\e[32m  border-top-right-radius: 4px;\e[m
+\e[32m+\e[m\e[32m  border-top-left-radius: 4px;\e[m
+\e[32m+\e[m\e[32m  border-bottom-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-bottom-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn:last-child:not(:first-child) {\e[m
+\e[32m+\e[m\e[32m  border-top-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-top-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-bottom-right-radius: 4px;\e[m
+\e[32m+\e[m\e[32m  border-bottom-left-radius: 4px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\e[m
+\e[32m+\e[m\e[32m  border-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\e[m
+\e[32m+\e[m\e[32m  border-bottom-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-bottom-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\e[m
+\e[32m+\e[m\e[32m  border-top-right-radius: 0;\e[m
+\e[32m+\e[m\e[32m  border-top-left-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-justified {\e[m
+\e[32m+\e[m\e[32m  display: table;\e[m
+\e[32m+\e[m\e[32m  width: 100%;\e[m
+\e[32m+\e[m\e[32m  table-layout: fixed;\e[m
+\e[32m+\e[m\e[32m  border-collapse: separate;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-justified > .btn,\e[m
+\e[32m+\e[m\e[32m.btn-group-justified > .btn-group {\e[m
+\e[32m+\e[m\e[32m  float: none;\e[m
+\e[32m+\e[m\e[32m  display: table-cell;\e[m
+\e[32m+\e[m\e[32m  width: 1%;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-justified > .btn-group .btn {\e[m
+\e[32m+\e[m\e[32m  width: 100%;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-group-justified > .btn-group .dropdown-menu {\e[m
+\e[32m+\e[m\e[32m  left: auto;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m[data-toggle="buttons"] > .btn input[type="radio"],\e[m
+\e[32m+\e[m\e[32m[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],\e[m
+\e[32m+\e[m\e[32m[data-toggle="buttons"] > .btn input[type="checkbox"],\e[m
+\e[32m+\e[m\e[32m[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {\e[m
+\e[32m+\e[m\e[32m  position: absolute;\e[m
+\e[32m+\e[m\e[32m  clip: rect(0, 0, 0, 0);\e[m
+\e[32m+\e[m\e[32m  pointer-events: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\ No newline at end of file\e[m
+\e[1mdiff --git a/css/buttons.css b/css/buttons.css\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..42ec098feb\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/css/buttons.css\e[m
+\e[36m@@ -0,0 +1,463 @@\e[m
+\e[32m+\e[m\e[32m.btn {\e[m
+\e[32m+\e[m\e[32m  display: inline-block;\e[m
+\e[32m+\e[m\e[32m  margin-bottom: 0;\e[m
+\e[32m+\e[m\e[32m  font-weight: normal;\e[m
+\e[32m+\e[m\e[32m  text-align: center;\e[m
+\e[32m+\e[m\e[32m  vertical-align: middle;\e[m
+\e[32m+\e[m\e[32m  touch-action: manipulation;\e[m
+\e[32m+\e[m\e[32m  cursor: pointer;\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m  border: 1px solid transparent;\e[m
+\e[32m+\e[m\e[32m  white-space: nowrap;\e[m
+\e[32m+\e[m\e[32m  padding: 6px 12px;\e[m
+\e[32m+\e[m\e[32m  font-size: 14px;\e[m
+\e[32m+\e[m\e[32m  line-height: 1.42857143;\e[m
+\e[32m+\e[m\e[32m  border-radius: 4px;\e[m
+\e[32m+\e[m\e[32m  -webkit-user-select: none;\e[m
+\e[32m+\e[m\e[32m  -moz-user-select: none;\e[m
+\e[32m+\e[m\e[32m  -ms-user-select: none;\e[m
+\e[32m+\e[m\e[32m  user-select: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn:focus,\e[m
+\e[32m+\e[m\e[32m.btn:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn.active:focus,\e[m
+\e[32m+\e[m\e[32m.btn.focus,\e[m
+\e[32m+\e[m\e[32m.btn:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn.active.focus {\e[m
+\e[32m+\e[m\e[32m  outline: 5px auto -webkit-focus-ring-color;\e[m
+\e[32m+\e[m\e[32m  outline-offset: -2px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn:hover,\e[m
+\e[32m+\e[m\e[32m.btn:focus,\e[m
+\e[32m+\e[m\e[32m.btn.focus {\e[m
+\e[32m+\e[m\e[32m  color: #333333;\e[m
+\e[32m+\e[m\e[32m  text-decoration: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn:active,\e[m
+\e[32m+\e[m\e[32m.btn.active {\e[m
+\e[32m+\e[m\e[32m  outline: 0;\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\e[m
+\e[32m+\e[m\e[32m  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn.disabled,\e[m
+\e[32m+\e[m\e[32m.btn[disabled],\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn {\e[m
+\e[32m+\e[m\e[32m  cursor: not-allowed;\e[m
+\e[32m+\e[m\e[32m  opacity: 0.65;\e[m
+\e[32m+\e[m\e[32m  filter: alpha(opacity=65);\e[m
+\e[32m+\e[m\e[32m  -webkit-box-shadow: none;\e[m
+\e[32m+\e[m\e[32m  box-shadow: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32ma.btn.disabled,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] a.btn {\e[m
+\e[32m+\e[m\e[32m  pointer-events: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default {\e[m
+\e[32m+\e[m\e[32m  color: #333333;\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  border-color: #cccccc;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default:focus,\e[m
+\e[32m+\e[m\e[32m.btn-default.focus {\e[m
+\e[32m+\e[m\e[32m  color: #333333;\e[m
+\e[32m+\e[m\e[32m  background-color: #e6e6e6;\e[m
+\e[32m+\e[m\e[32m  border-color: #8c8c8c;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default:hover {\e[m
+\e[32m+\e[m\e[32m  color: #333333;\e[m
+\e[32m+\e[m\e[32m  background-color: #e6e6e6;\e[m
+\e[32m+\e[m\e[32m  border-color: #adadad;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default:active,\e[m
+\e[32m+\e[m\e[32m.btn-default.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-default {\e[m
+\e[32m+\e[m\e[32m  color: #333333;\e[m
+\e[32m+\e[m\e[32m  background-color: #e6e6e6;\e[m
+\e[32m+\e[m\e[32m  border-color: #adadad;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default:active:hover,\e[m
+\e[32m+\e[m\e[32m.btn-default.active:hover,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-default:hover,\e[m
+\e[32m+\e[m\e[32m.btn-default:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn-default.active:focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-default:focus,\e[m
+\e[32m+\e[m\e[32m.btn-default:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn-default.active.focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-default.focus {\e[m
+\e[32m+\e[m\e[32m  color: #333333;\e[m
+\e[32m+\e[m\e[32m  background-color: #d4d4d4;\e[m
+\e[32m+\e[m\e[32m  border-color: #8c8c8c;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default:active,\e[m
+\e[32m+\e[m\e[32m.btn-default.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-default {\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default.disabled:hover,\e[m
+\e[32m+\e[m\e[32m.btn-default[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-default:hover,\e[m
+\e[32m+\e[m\e[32m.btn-default.disabled:focus,\e[m
+\e[32m+\e[m\e[32m.btn-default[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-default:focus,\e[m
+\e[32m+\e[m\e[32m.btn-default.disabled.focus,\e[m
+\e[32m+\e[m\e[32m.btn-default[disabled].focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-default.focus {\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  border-color: #cccccc;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-default .badge {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #333333;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #337ab7;\e[m
+\e[32m+\e[m\e[32m  border-color: #2e6da4;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary:focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #286090;\e[m
+\e[32m+\e[m\e[32m  border-color: #122b40;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary:hover {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #286090;\e[m
+\e[32m+\e[m\e[32m  border-color: #204d74;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary:active,\e[m
+\e[32m+\e[m\e[32m.btn-primary.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-primary {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #286090;\e[m
+\e[32m+\e[m\e[32m  border-color: #204d74;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary:active:hover,\e[m
+\e[32m+\e[m\e[32m.btn-primary.active:hover,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-primary:hover,\e[m
+\e[32m+\e[m\e[32m.btn-primary:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary.active:focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-primary:focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary.active.focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-primary.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #204d74;\e[m
+\e[32m+\e[m\e[32m  border-color: #122b40;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary:active,\e[m
+\e[32m+\e[m\e[32m.btn-primary.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-primary {\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary.disabled:hover,\e[m
+\e[32m+\e[m\e[32m.btn-primary[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-primary:hover,\e[m
+\e[32m+\e[m\e[32m.btn-primary.disabled:focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-primary:focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary.disabled.focus,\e[m
+\e[32m+\e[m\e[32m.btn-primary[disabled].focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-primary.focus {\e[m
+\e[32m+\e[m\e[32m  background-color: #337ab7;\e[m
+\e[32m+\e[m\e[32m  border-color: #2e6da4;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-primary .badge {\e[m
+\e[32m+\e[m\e[32m  color: #337ab7;\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #5cb85c;\e[m
+\e[32m+\e[m\e[32m  border-color: #4cae4c;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success:focus,\e[m
+\e[32m+\e[m\e[32m.btn-success.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #449d44;\e[m
+\e[32m+\e[m\e[32m  border-color: #255625;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success:hover {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #449d44;\e[m
+\e[32m+\e[m\e[32m  border-color: #398439;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success:active,\e[m
+\e[32m+\e[m\e[32m.btn-success.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-success {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #449d44;\e[m
+\e[32m+\e[m\e[32m  border-color: #398439;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success:active:hover,\e[m
+\e[32m+\e[m\e[32m.btn-success.active:hover,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-success:hover,\e[m
+\e[32m+\e[m\e[32m.btn-success:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn-success.active:focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-success:focus,\e[m
+\e[32m+\e[m\e[32m.btn-success:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn-success.active.focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-success.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #398439;\e[m
+\e[32m+\e[m\e[32m  border-color: #255625;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success:active,\e[m
+\e[32m+\e[m\e[32m.btn-success.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-success {\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success.disabled:hover,\e[m
+\e[32m+\e[m\e[32m.btn-success[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-success:hover,\e[m
+\e[32m+\e[m\e[32m.btn-success.disabled:focus,\e[m
+\e[32m+\e[m\e[32m.btn-success[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-success:focus,\e[m
+\e[32m+\e[m\e[32m.btn-success.disabled.focus,\e[m
+\e[32m+\e[m\e[32m.btn-success[disabled].focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-success.focus {\e[m
+\e[32m+\e[m\e[32m  background-color: #5cb85c;\e[m
+\e[32m+\e[m\e[32m  border-color: #4cae4c;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-success .badge {\e[m
+\e[32m+\e[m\e[32m  color: #5cb85c;\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #5bc0de;\e[m
+\e[32m+\e[m\e[32m  border-color: #46b8da;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info:focus,\e[m
+\e[32m+\e[m\e[32m.btn-info.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #31b0d5;\e[m
+\e[32m+\e[m\e[32m  border-color: #1b6d85;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info:hover {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #31b0d5;\e[m
+\e[32m+\e[m\e[32m  border-color: #269abc;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info:active,\e[m
+\e[32m+\e[m\e[32m.btn-info.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-info {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #31b0d5;\e[m
+\e[32m+\e[m\e[32m  border-color: #269abc;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info:active:hover,\e[m
+\e[32m+\e[m\e[32m.btn-info.active:hover,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-info:hover,\e[m
+\e[32m+\e[m\e[32m.btn-info:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn-info.active:focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-info:focus,\e[m
+\e[32m+\e[m\e[32m.btn-info:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn-info.active.focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-info.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #269abc;\e[m
+\e[32m+\e[m\e[32m  border-color: #1b6d85;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info:active,\e[m
+\e[32m+\e[m\e[32m.btn-info.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-info {\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info.disabled:hover,\e[m
+\e[32m+\e[m\e[32m.btn-info[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-info:hover,\e[m
+\e[32m+\e[m\e[32m.btn-info.disabled:focus,\e[m
+\e[32m+\e[m\e[32m.btn-info[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-info:focus,\e[m
+\e[32m+\e[m\e[32m.btn-info.disabled.focus,\e[m
+\e[32m+\e[m\e[32m.btn-info[disabled].focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-info.focus {\e[m
+\e[32m+\e[m\e[32m  background-color: #5bc0de;\e[m
+\e[32m+\e[m\e[32m  border-color: #46b8da;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-info .badge {\e[m
+\e[32m+\e[m\e[32m  color: #5bc0de;\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #f0ad4e;\e[m
+\e[32m+\e[m\e[32m  border-color: #eea236;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning:focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #ec971f;\e[m
+\e[32m+\e[m\e[32m  border-color: #985f0d;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning:hover {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #ec971f;\e[m
+\e[32m+\e[m\e[32m  border-color: #d58512;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning:active,\e[m
+\e[32m+\e[m\e[32m.btn-warning.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-warning {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #ec971f;\e[m
+\e[32m+\e[m\e[32m  border-color: #d58512;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning:active:hover,\e[m
+\e[32m+\e[m\e[32m.btn-warning.active:hover,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-warning:hover,\e[m
+\e[32m+\e[m\e[32m.btn-warning:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning.active:focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-warning:focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning.active.focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-warning.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #d58512;\e[m
+\e[32m+\e[m\e[32m  border-color: #985f0d;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning:active,\e[m
+\e[32m+\e[m\e[32m.btn-warning.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-warning {\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning.disabled:hover,\e[m
+\e[32m+\e[m\e[32m.btn-warning[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-warning:hover,\e[m
+\e[32m+\e[m\e[32m.btn-warning.disabled:focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-warning:focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning.disabled.focus,\e[m
+\e[32m+\e[m\e[32m.btn-warning[disabled].focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-warning.focus {\e[m
+\e[32m+\e[m\e[32m  background-color: #f0ad4e;\e[m
+\e[32m+\e[m\e[32m  border-color: #eea236;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-warning .badge {\e[m
+\e[32m+\e[m\e[32m  color: #f0ad4e;\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #d9534f;\e[m
+\e[32m+\e[m\e[32m  border-color: #d43f3a;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger:focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #c9302c;\e[m
+\e[32m+\e[m\e[32m  border-color: #761c19;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger:hover {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #c9302c;\e[m
+\e[32m+\e[m\e[32m  border-color: #ac2925;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger:active,\e[m
+\e[32m+\e[m\e[32m.btn-danger.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-danger {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #c9302c;\e[m
+\e[32m+\e[m\e[32m  border-color: #ac2925;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger:active:hover,\e[m
+\e[32m+\e[m\e[32m.btn-danger.active:hover,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-danger:hover,\e[m
+\e[32m+\e[m\e[32m.btn-danger:active:focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger.active:focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-danger:focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger:active.focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger.active.focus,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-danger.focus {\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  background-color: #ac2925;\e[m
+\e[32m+\e[m\e[32m  border-color: #761c19;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger:active,\e[m
+\e[32m+\e[m\e[32m.btn-danger.active,\e[m
+\e[32m+\e[m\e[32m.open > .dropdown-toggle.btn-danger {\e[m
+\e[32m+\e[m\e[32m  background-image: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger.disabled:hover,\e[m
+\e[32m+\e[m\e[32m.btn-danger[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-danger:hover,\e[m
+\e[32m+\e[m\e[32m.btn-danger.disabled:focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-danger:focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger.disabled.focus,\e[m
+\e[32m+\e[m\e[32m.btn-danger[disabled].focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-danger.focus {\e[m
+\e[32m+\e[m\e[32m  background-color: #d9534f;\e[m
+\e[32m+\e[m\e[32m  border-color: #d43f3a;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-danger .badge {\e[m
+\e[32m+\e[m\e[32m  color: #d9534f;\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-link {\e[m
+\e[32m+\e[m\e[32m  color: #337ab7;\e[m
+\e[32m+\e[m\e[32m  font-weight: normal;\e[m
+\e[32m+\e[m\e[32m  border-radius: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-link,\e[m
+\e[32m+\e[m\e[32m.btn-link:active,\e[m
+\e[32m+\e[m\e[32m.btn-link.active,\e[m
+\e[32m+\e[m\e[32m.btn-link[disabled],\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-link {\e[m
+\e[32m+\e[m\e[32m  background-color: transparent;\e[m
+\e[32m+\e[m\e[32m  -webkit-box-shadow: none;\e[m
+\e[32m+\e[m\e[32m  box-shadow: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-link,\e[m
+\e[32m+\e[m\e[32m.btn-link:hover,\e[m
+\e[32m+\e[m\e[32m.btn-link:focus,\e[m
+\e[32m+\e[m\e[32m.btn-link:active {\e[m
+\e[32m+\e[m\e[32m  border-color: transparent;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-link:hover,\e[m
+\e[32m+\e[m\e[32m.btn-link:focus {\e[m
+\e[32m+\e[m\e[32m  color: #23527c;\e[m
+\e[32m+\e[m\e[32m  text-decoration: underline;\e[m
+\e[32m+\e[m\e[32m  background-color: transparent;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-link[disabled]:hover,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-link:hover,\e[m
+\e[32m+\e[m\e[32m.btn-link[disabled]:focus,\e[m
+\e[32m+\e[m\e[32mfieldset[disabled] .btn-link:focus {\e[m
+\e[32m+\e[m\e[32m  color: #777777;\e[m
+\e[32m+\e[m\e[32m  text-decoration: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-lg,\e[m
+\e[32m+\e[m\e[32m.btn-group-lg > .btn {\e[m
+\e[32m+\e[m\e[32m  padding: 10px 16px;\e[m
+\e[32m+\e[m\e[32m  font-size: 18px;\e[m
+\e[32m+\e[m\e[32m  line-height: 1.3333333;\e[m
+\e[32m+\e[m\e[32m  border-radius: 6px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-sm,\e[m
+\e[32m+\e[m\e[32m.btn-group-sm > .btn {\e[m
+\e[32m+\e[m\e[32m  padding: 5px 10px;\e[m
+\e[32m+\e[m\e[32m  font-size: 12px;\e[m
+\e[32m+\e[m\e[32m  line-height: 1.5;\e[m
+\e[32m+\e[m\e[32m  border-radius: 3px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-xs,\e[m
+\e[32m+\e[m\e[32m.btn-group-xs > .btn {\e[m
+\e[32m+\e[m\e[32m  padding: 1px 5px;\e[m
+\e[32m+\e[m\e[32m  font-size: 12px;\e[m
+\e[32m+\e[m\e[32m  line-height: 1.5;\e[m
+\e[32m+\e[m\e[32m  border-radius: 3px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-block {\e[m
+\e[32m+\e[m\e[32m  display: block;\e[m
+\e[32m+\e[m\e[32m  width: 100%;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.btn-block + .btn-block {\e[m
+\e[32m+\e[m\e[32m  margin-top: 5px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32minput[type="submit"].btn-block,\e[m
+\e[32m+\e[m\e[32minput[type="reset"].btn-block,\e[m
+\e[32m+\e[m\e[32minput[type="button"].btn-block {\e[m
+\e[32m+\e[m\e[32m  width: 100%;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\ No newline at end of file\e[m
+\e[1mdiff --git a/css/upload-cropbox.css b/css/upload-cropbox.css\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..f8500935aa\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/css/upload-cropbox.css\e[m
+\e[36m@@ -0,0 +1,62 @@\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-selector {\e[m
+\e[32m+\e[m\e[32m  visibility: hidden;\e[m
+\e[32m+\e[m\e[32m  height: 0px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-dialog .modal-header,\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-dialog .modal-footer {\e[m
+\e[32m+\e[m\e[32m  padding-top: 5px;\e[m
+\e[32m+\e[m\e[32m  padding-bottom: 5px;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-body {\e[m
+\e[32m+\e[m\e[32m  background-color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  border: 1px solid #777777;\e[m
+\e[32m+\e[m\e[32m  width: 100%;\e[m
+\e[32m+\e[m\e[32m  height: 450px;\e[m
+\e[32m+\e[m\e[32m  max-height: 450px;\e[m
+\e[32m+\e[m\e[32m  position: relative;\e[m
+\e[32m+\e[m\e[32m  overflow: hidden;\e[m
+\e[32m+\e[m\e[32m  cursor: move;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-preview {\e[m
+\e[32m+\e[m\e[32m  position: absolute;\e[m
+\e[32m+\e[m\e[32m  top: 0px;\e[m
+\e[32m+\e[m\e[32m  left: 0px;\e[m
+\e[32m+\e[m\e[32m  text-align: center;\e[m
+\e[32m+\e[m\e[32m  margin: 0px;\e[m
+\e[32m+\e[m\e[32m  padding: 0px;\e[m
+\e[32m+\e[m\e[32m  border: none;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-body .roo-upload-cropbox-thumb {\e[m
+\e[32m+\e[m\e[32m  position: absolute;\e[m
+\e[32m+\e[m\e[32m  /*    top: 50%;\e[m
+\e[32m+\e[m\e[32m    left: 50%;\e[m
+\e[32m+\e[m\e[32m    transform: translate(-50%, -50%);*/\e[m
+\e[32m+\e[m\e[32m  box-sizing: border-box;\e[m
+\e[32m+\e[m\e[32m  border: 1px solid #777777;\e[m
+\e[32m+\e[m\e[32m  box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);\e[m
+\e[32m+\e[m\e[32m  background: none repeat scroll 0% 0% transparent;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-body .roo-upload-cropbox-empty-notify {\e[m
+\e[32m+\e[m\e[32m  height: 100%;\e[m
+\e[32m+\e[m\e[32m  background-color: rgba(0, 0, 0, 0.5);\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  font-weight: bold;\e[m
+\e[32m+\e[m\e[32m  font-size: 24px;\e[m
+\e[32m+\e[m\e[32m  text-align: center;\e[m
+\e[32m+\e[m\e[32m  padding-top: 50px;\e[m
+\e[32m+\e[m\e[32m  font-style: italic;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-btn-group button {\e[m
+\e[32m+\e[m\e[32m  background-color: #000000;\e[m
+\e[32m+\e[m\e[32m  color: #ffffff;\e[m
+\e[32m+\e[m\e[32m  border-color: #333333;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m\e[32m.roo-upload-cropbox-error-notify {\e[m
+\e[32m+\e[m\e[32m  border-radius: 0px;\e[m
+\e[32m+\e[m\e[32m  text-align: center;\e[m
+\e[32m+\e[m\e[32m  padding: 0px !important;\e[m
+\e[32m+\e[m\e[32m  margin: 0px !important;\e[m
+\e[32m+\e[m\e[32m  position: absolute;\e[m
+\e[32m+\e[m\e[32m  top: 0;\e[m
+\e[32m+\e[m\e[32m  left: 0;\e[m
+\e[32m+\e[m\e[32m}\e[m
+\ No newline at end of file\e[m
+\e[1mdiff --git a/examples/dialog/hello.html b/examples/dialog/hello.html\e[m
+\e[1mindex ab43ed9999..ec001bf313 100644\e[m
+\e[1m--- a/examples/dialog/hello.html\e[m
+\e[1m+++ b/examples/dialog/hello.html\e[m
+\e[36m@@ -1,27 +1,27 @@\e[m
+\e[31m-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\e[m\r
+\e[31m-<html>\e[m\r
+\e[31m-<head>\e[m\r
+\e[31m-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\e[m\r
+\e[31m-<title>Hello World Dialog Example</title>\e[m\r
+\e[32m+\e[m\e[32m<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\e[m
+\e[32m+\e[m\e[32m<html>\e[m
+\e[32m+\e[m\e[32m<head>\e[m
+\e[32m+\e[m\e[32m<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\e[m
+\e[32m+\e[m\e[32m<title>Hello World Dialog Example</title>\e[m
+  <link rel="stylesheet" type="text/css" href="../../css/roojs-debug.css"/>\e[m
+     <link rel="stylesheet" type="text/css" href="../../css/xtheme-slate.css"/>\e[m
\e[m
+      <script type="text/javascript" src="../../roojs-debug.js"></script>   \e[m
+\e[31m-  \e[m\r
+\e[31m-     <script language="javascript" src="hello.js"></script>\e[m\r
+\e[31m- \e[m\r
+\e[31m-<!-- Common Styles for the examples -->\e[m\r
+\e[31m-<link rel="stylesheet" type="text/css" href="../examples.css" />\e[m\r
+\e[31m-</head>\e[m\r
+\e[31m-<body>\e[m\r
+\e[31m-<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->\e[m\r
+\e[31m-\e[m\r
+\e[31m-<h1>Hello World Dialog</h1>\e[m\r
+\e[31m-<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>\e[m\r
+\e[31m-<input type="button" id="show-dialog-btn" value="Hello World" /><br /><br />\e[m\r
+\e[32m+\e[m\e[41m  \e[m
+\e[32m+\e[m\e[32m     <script language="javascript" src="hello.js"></script>\e[m
+\e[32m+\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m<!-- Common Styles for the examples -->\e[m
+\e[32m+\e[m\e[32m<link rel="stylesheet" type="text/css" href="../examples.css" />\e[m
+\e[32m+\e[m\e[32m</head>\e[m
+\e[32m+\e[m\e[32m<body>\e[m
+\e[32m+\e[m\e[32m<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m<h1>Hello World Dialog</h1>\e[m
+\e[32m+\e[m\e[32m<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>\e[m
+\e[32m+\e[m\e[32m<input type="button" id="show-dialog-btn" value="Hello World" /><br /><br />\e[m
+ <p>Note that the js is not minified so it is readable. See \e[m
+\e[31m-<button type="button" onclick="RooDocs.viewSource.show('/hello.js')">hello.js</button>for the full source code.</p>\e[m\r
+\e[31m-Here's snapshot of the code that creates the dialog:\e[m\r
+\e[32m+\e[m\e[32m<button type="button" onclick="RooDocs.viewSource.show('/hello.js')">hello.js</button>for the full source code.</p>\e[m
+\e[32m+\e[m\e[32mHere's snapshot of the code that creates the dialog:\e[m
+ <pre class="code"><code>Roo.BLANK_IMAGE_URL  = "../../images/default/s.gif";\e[m
\e[m
\e[m
+\e[36m@@ -121,29 +121,29 @@\e[m \e[mRoo.onReady(function() {\e[m
+     Roo.get('show-dialog-btn').on('click',function () {\e[m
+         HelloWorld.show({ _el : this});\e[m
+     });\e[m
+\e[31m-});\e[m\r
+\e[31m-</code></pre>\e[m\r
+\e[31m-\e[m\r
+\e[31m-    <!-- The dialog is created from existing markup.\e[m\r
+\e[31m-         The inline styles just hide it until it created and should be in a stylesheet -->\e[m\r
+\e[31m-    <div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">\e[m\r
+\e[31m-    <div class="x-dlg-hd">Hello Dialog</div>\e[m\r
+\e[31m-    <div class="x-dlg-bd">\e[m\r
+\e[31m-        <!-- Auto create tab 1 -->\e[m\r
+\e[31m-        <div class="x-dlg-tab" title="Hello World 1">\e[m\r
+\e[31m-            <!-- Nested "inner-tab" to safely add padding -->\e[m\r
+\e[31m-            <div class="inner-tab">\e[m\r
+\e[31m-                 Hello...<br><br><br>\e[m\r
+\e[31m-            </div>\e[m\r
+\e[31m-        </div>\e[m\r
+\e[31m-        <!-- Auto create tab 2 -->\e[m\r
+\e[31m-        <div class="x-dlg-tab" title="Hello World 2">\e[m\r
+\e[31m-            <div class="inner-tab">\e[m\r
+\e[31m-            ... World!\e[m\r
+\e[31m-            </div>\e[m\r
+\e[31m-        </div>\e[m\r
+\e[31m-        </div>\e[m\r
+\e[31m-    </div>\e[m\r
+\e[31m-</div>\e[m\r
+\e[31m-</body>\e[m\r
+\e[31m-</html>\e[m\r
+\e[32m+\e[m\e[32m});\e[m
+\e[32m+\e[m\e[32m</code></pre>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    <!-- The dialog is created from existing markup.\e[m
+\e[32m+\e[m\e[32m         The inline styles just hide it until it created and should be in a stylesheet -->\e[m
+\e[32m+\e[m\e[32m    <div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">\e[m
+\e[32m+\e[m\e[32m    <div class="x-dlg-hd">Hello Dialog</div>\e[m
+\e[32m+\e[m\e[32m    <div class="x-dlg-bd">\e[m
+\e[32m+\e[m\e[32m        <!-- Auto create tab 1 -->\e[m
+\e[32m+\e[m\e[32m        <div class="x-dlg-tab" title="Hello World 1">\e[m
+\e[32m+\e[m\e[32m            <!-- Nested "inner-tab" to safely add padding -->\e[m
+\e[32m+\e[m\e[32m            <div class="inner-tab">\e[m
+\e[32m+\e[m\e[32m                 Hello...<br><br><br>\e[m
+\e[32m+\e[m\e[32m            </div>\e[m
+\e[32m+\e[m\e[32m        </div>\e[m
+\e[32m+\e[m\e[32m        <!-- Auto create tab 2 -->\e[m
+\e[32m+\e[m\e[32m        <div class="x-dlg-tab" title="Hello World 2">\e[m
+\e[32m+\e[m\e[32m            <div class="inner-tab">\e[m
+\e[32m+\e[m\e[32m            ... World!\e[m
+\e[32m+\e[m\e[32m            </div>\e[m
+\e[32m+\e[m\e[32m        </div>\e[m
+\e[32m+\e[m\e[32m        </div>\e[m
+\e[32m+\e[m\e[32m    </div>\e[m
+\e[32m+\e[m\e[32m</div>\e[m
+\e[32m+\e[m\e[32m</body>\e[m
+\e[32m+\e[m\e[32m</html>\e[m
+\e[1mdiff --git a/examples/dialog/test-2.html b/examples/dialog/test-2.html\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..e26d6ee586\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/examples/dialog/test-2.html\e[m
+\e[36m@@ -0,0 +1,30 @@\e[m
+\e[32m+\e[m\e[32m<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\e[m
+\e[32m+\e[m\e[32m<html>\e[m
+\e[32m+\e[m\e[32m<head>\e[m
+\e[32m+\e[m\e[32m    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\e[m
+\e[32m+\e[m\e[32m    <title>Upload Cropbox Dialog Example</title>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css/roojs-debug.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css-bootstrap/font-awesome.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css/upload-cropbox.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css/alert.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css/buttons.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css/button-groups.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../examples.css" />\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m     <script type="text/javascript" src="../../roojs-debug.js"></script>\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m     <script language="javascript" src="test-2.js"></script>\e[m
+\e[32m+\e[m\e[32m     <script type="text/javascript" src="../examples.js"></script>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m</head>\e[m
+\e[32m+\e[m\e[32m<body>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m<h1>Upload Cropbox Dialog</h1>\e[m
+\e[32m+\e[m\e[32m<p>This example shows how to create a very simple BasicDialog with "UploadCropbox".</p>\e[m
+\e[32m+\e[m\e[32m<input type="button" id="show-dialog-btn" value="test" /><br /><br />\e[m
+\e[32m+\e[m\e[32m<p>Note that the js is not minified so it is readable. See\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m<button type="button" onclick="RooDocs.viewSource.show('../../../Roo/dialog/UploadCropbox.js')">UploadCropbox.js</button>for the full source code.</p>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m</div>\e[m
+\e[32m+\e[m\e[32m</body>\e[m
+\e[32m+\e[m\e[32m</html>\e[m
+\e[1mdiff --git a/examples/dialog/test-2.js b/examples/dialog/test-2.js\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..c4dcdedd7e\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/examples/dialog/test-2.js\e[m
+\e[36m@@ -0,0 +1,171 @@\e[m
+\e[32m+\e[m\e[32mvar uploadCropbox = {\e[m
+\e[32m+\e[m\e[32m    dialog : false,\e[m
+\e[32m+\e[m\e[32m    callback : false,\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    show : function(data, cb)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if (!this.dialog) {\e[m
+\e[32m+\e[m\e[32m            this.create();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        this.callback = cb;\e[m
+\e[32m+\e[m\e[32m        this.data = data;\e[m
+\e[32m+\e[m\e[32m        this.dialog.show();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    create : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[32m        this.dialog = Roo.factory({\e[m
+\e[32m+\e[m\e[32m            xns : Roo,\e[m
+\e[32m+\e[m\e[32m            xtype : 'LayoutDialog',\e[m
+\e[32m+\e[m\e[32m            width : 800,\e[m
+\e[32m+\e[m\e[32m            height : 600,\e[m
+\e[32m+\e[m\e[32m            center : {\e[m
+\e[32m+\e[m\e[32m                xns : Roo,\e[m
+\e[32m+\e[m\e[32m                xtype : 'LayoutRegion'\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            items : [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    xtype: 'ContentPanel',\e[m
+\e[32m+\e[m\e[32m                    xns: Roo,\e[m
+\e[32m+\e[m\e[32m                    region : "center",\e[m
+\e[32m+\e[m\e[32m                    items : [\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            xtype : 'UploadCropbox',\e[m
+\e[32m+\e[m\e[32m                            xns : Roo.dialog,\e[m
+\e[32m+\e[m\e[32m                            minWidth : 720,\e[m
+\e[32m+\e[m\e[32m                            minHeight: 480,\e[m
+\e[32m+\e[m\e[32m                            buttons: [],\e[m
+\e[32m+\e[m\e[32m                            listeners : {\e[m
+\e[32m+\e[m\e[32m                                render : function (_self)\e[m
+\e[32m+\e[m\e[32m                                {\e[m
+\e[32m+\e[m\e[32m                                    _this.cropbox = _self;\e[m
+\e[32m+\e[m\e[32m                                },\e[m
+\e[32m+\e[m\e[32m                                loadcanvas : function (_self, imageEl)\e[m
+\e[32m+\e[m\e[32m                                {\e[m
+\e[32m+\e[m\e[32m                                    if(imageEl.OriginWidth < 720) {\e[m
+\e[32m+\e[m\e[32m                                        Roo.Msg.show({\e[m
+\e[32m+\e[m\e[32m                                            title: 'Error',\e[m
+\e[32m+\e[m\e[32m                                            msg: "Image width should be at least 720",\e[m
+\e[32m+\e[m\e[32m                                            buttons: {ok : true},\e[m
+\e[32m+\e[m\e[32m                                            fn: function(res) {\e[m
+\e[32m+\e[m\e[32m                                                _this.cropbox.selectorEl.dom.click();\e[m
+\e[32m+\e[m\e[32m                                            }\e[m
+\e[32m+\e[m\e[32m                                        });\e[m
+\e[32m+\e[m\e[32m                                        return false;\e[m
+\e[32m+\e[m\e[32m                                    }\e[m
+\e[32m+\e[m\e[32m                                }\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[32m                    ]\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ],\e[m
+\e[32m+\e[m\e[32m            buttons : [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    xtype : 'Button',\e[m
+\e[32m+\e[m\e[32m                    xns : Roo,\e[m
+\e[32m+\e[m\e[32m                    text : 'Save',\e[m
+\e[32m+\e[m\e[32m                    listeners : {\e[m
+\e[32m+\e[m\e[32m                        click : function () {\e[m
+\e[32m+\e[m\e[32m                        }\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    xtype : 'Button',\e[m
+\e[32m+\e[m\e[32m                    xns : Roo,\e[m
+\e[32m+\e[m\e[32m                    text : 'Cancel',\e[m
+\e[32m+\e[m\e[32m                    listeners : {\e[m
+\e[32m+\e[m\e[32m                        click : function () {\e[m
+\e[32m+\e[m\e[32m                            _this.dialog.hide()\e[m
+\e[32m+\e[m\e[32m                        }\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ]\e[m
+\e[32m+\e[m\e[32m        });\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mvar test = {\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    dialog : false,\e[m
+\e[32m+\e[m\e[32m    callback : false,\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    show : function(data, cb)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if (!this.dialog) {\e[m
+\e[32m+\e[m\e[32m            this.create();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        this.callback = cb;\e[m
+\e[32m+\e[m\e[32m        this.data = data;\e[m
+\e[32m+\e[m\e[32m        this.dialog.show();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    create : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[32m        this.dialog = Roo.factory({\e[m
+\e[32m+\e[m\e[32m            xns : Roo,\e[m
+\e[32m+\e[m\e[32m            xtype : 'LayoutDialog',\e[m
+\e[32m+\e[m\e[32m            width : 600,\e[m
+\e[32m+\e[m\e[32m            height : 450,\e[m
+\e[32m+\e[m\e[32m            center : {\e[m
+\e[32m+\e[m\e[32m                xns : Roo,\e[m
+\e[32m+\e[m\e[32m                xtype : 'LayoutRegion'\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            items : [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    xns : Roo,\e[m
+\e[32m+\e[m\e[32m                    xtype: 'GridPanel',\e[m
+\e[32m+\e[m\e[32m                    region : "center",\e[m
+\e[32m+\e[m\e[32m                    grid : {\e[m
+\e[32m+\e[m\e[32m                        xns : Roo.grid,\e[m
+\e[32m+\e[m\e[32m                        xtype : 'Grid',\e[m
+\e[32m+\e[m\e[32m                        cm : [\e[m
+\e[32m+\e[m\e[32m                            {\e[m
+\e[32m+\e[m\e[32m                                xns : Roo.grid,\e[m
+\e[32m+\e[m\e[32m                                xtype : 'ColumnModel',\e[m
+\e[32m+\e[m\e[32m                                header : 'test'\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[32m                        ],\e[m
+\e[32m+\e[m\e[32m                        ds : {\e[m
+\e[32m+\e[m\e[32m                            xns: Roo.data,\e[m
+\e[32m+\e[m\e[32m                            xtype: 'Store'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        toolbar : {\e[m
+\e[32m+\e[m\e[32m                            xns: Roo,\e[m
+\e[32m+\e[m\e[32m                            xtype: 'Toolbar',\e[m
+\e[32m+\e[m\e[32m                            items : [\e[m
+\e[32m+\e[m\e[32m                                {\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                    xtype : 'Button',\e[m
+\e[32m+\e[m\e[32m                                    text : 'Add',\e[m
+\e[32m+\e[m\e[32m                                    listeners : {\e[m
+\e[32m+\e[m\e[32m                                        click : function () {\e[m
+\e[32m+\e[m\e[32m                                            uploadCropbox.show();\e[m
+\e[32m+\e[m\e[32m                                            document.body.onfocus = function(e) {\e[m
+\e[32m+\e[m\e[32m                                                document.body.onfocus = null;\e[m
+\e[32m+\e[m\e[32m                                                if(!uploadCropbox.cropbox.selectorEl.dom.files.length) {\e[m
+\e[32m+\e[m\e[32m                                                    uploadCropbox.dialog.hide();\e[m
+\e[32m+\e[m\e[32m                                                }\e[m
+\e[32m+\e[m\e[32m                                            }\e[m
+\e[32m+\e[m\e[32m                                            uploadCropbox.cropbox.selectorEl.dom.click();\e[m
+\e[32m+\e[m\e[32m                                        }\e[m
+\e[32m+\e[m\e[32m                                    }\e[m
+\e[32m+\e[m\e[32m                                }\e[m
+\e[32m+\e[m\e[32m                            ]\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ],\e[m
+\e[32m+\e[m\e[32m        });\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.onReady(function() {\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    Roo.get('show-dialog-btn').on('click',function () {\e[m
+\e[32m+\e[m\e[32m        test.show({});\e[m
+\e[32m+\e[m\e[32m        console.log(test);\e[m
+\e[32m+\e[m\e[32m    });\e[m
+\e[32m+\e[m\e[32m});\e[m
+\ No newline at end of file\e[m
+\e[1mdiff --git a/examples/dialog/test.html b/examples/dialog/test.html\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..ecb2a0afa3\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/examples/dialog/test.html\e[m
+\e[36m@@ -0,0 +1,29 @@\e[m
+\e[32m+\e[m\e[32m<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\e[m
+\e[32m+\e[m\e[32m<html>\e[m
+\e[32m+\e[m\e[32m<head>\e[m
+\e[32m+\e[m\e[32m    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\e[m
+\e[32m+\e[m\e[32m    <title>Upload Cropbox Dialog Example</title>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css/roojs-debug.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css-bootstrap/bootstrap.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css-bootstrap/font-awesome.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../../css-bootstrap/roojs-bootstrap-debug.css"/>\e[m
+\e[32m+\e[m\e[32m    <link rel="stylesheet" type="text/css" href="../examples.css" />\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m     <script type="text/javascript" src="../../roojs-debug.js"></script>\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m     <script type="text/javascript" src="../../roojs-bootstrap-debug.js"></script>\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m     <script language="javascript" src="test.js"></script>\e[m
+\e[32m+\e[m\e[32m     <script type="text/javascript" src="../examples.js"></script>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m</head>\e[m
+\e[32m+\e[m\e[32m<body>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m<h1>Upload Cropbox Bootstrap</h1>\e[m
+\e[32m+\e[m\e[32m<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>\e[m
+\e[32m+\e[m\e[32m<input type="button" id="show-dialog-btn" value="test" /><br /><br />\e[m
+\e[32m+\e[m\e[32m<p>Note that the js is not minified so it is readable. See\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m<button type="button" onclick="RooDocs.viewSource.show('../../../Roo/bootstrap/UploadCropbox.js')">test.js</button>for the full source code.</p>\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m</div>\e[m
+\e[32m+\e[m\e[32m</body>\e[m
+\e[32m+\e[m\e[32m</html>\e[m
+\e[1mdiff --git a/examples/dialog/test.js b/examples/dialog/test.js\e[m
+\e[1mnew file mode 100644\e[m
+\e[1mindex 0000000000..f08db909f3\e[m
+\e[1m--- /dev/null\e[m
+\e[1m+++ b/examples/dialog/test.js\e[m
+\e[36m@@ -0,0 +1,94 @@\e[m
+\e[32m+\e[m\e[32mvar test = {\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    dialog : false,\e[m
+\e[32m+\e[m\e[32m    callback : false,\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    show : function(data, cb)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if (!this.dialog) {\e[m
+\e[32m+\e[m\e[32m            this.create();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        this.callback = cb;\e[m
+\e[32m+\e[m\e[32m        this.data = data;\e[m
+\e[32m+\e[m\e[32m        this.dialog.show();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    create : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[32m        this.dialog = Roo.factory({\e[m
+\e[32m+\e[m\e[32m            xtype : 'Modal',\e[m
+\e[32m+\e[m\e[32m            xns : Roo.bootstrap,\e[m
+\e[32m+\e[m\e[32m            title : 'Upload an Image',\e[m
+\e[32m+\e[m\e[32m            buttons : Roo.bootstrap.Modal.OKCANCEL,\e[m
+\e[32m+\e[m\e[32m            items: [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    xtype : 'Row',\e[m
+\e[32m+\e[m\e[32m                    xns : Roo.bootstrap,\e[m
+\e[32m+\e[m\e[32m                    items: [\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            xtype : 'Column',\e[m
+\e[32m+\e[m\e[32m                            xns : Roo.bootstrap,\e[m
+\e[32m+\e[m\e[32m                            items: [\e[m
+\e[32m+\e[m\e[32m                                {\e[m
+\e[32m+\e[m\e[32m                                    xtype : 'UploadCropbox',\e[m
+\e[32m+\e[m\e[32m                                    xns : Roo.bootstrap,\e[m
+\e[32m+\e[m\e[32m                                    minWidth : 720,\e[m
+\e[32m+\e[m\e[32m                                    minHeight: 480,\e[m
+\e[32m+\e[m\e[32m                                    listeners : {\e[m
+\e[32m+\e[m\e[32m                                        arrange : function (_self, formData)\e[m
+\e[32m+\e[m\e[32m                                        {\e[m
+\e[32m+\e[m\e[32m                                            console.log("ARRANGE");\e[m
+\e[32m+\e[m\e[32m                                            console.log(formData);\e[m
+\e[32m+\e[m\e[32m                                        },\e[m
+\e[32m+\e[m\e[32m                                        crop : function (_self, data)\e[m
+\e[32m+\e[m\e[32m                                        {\e[m
+\e[32m+\e[m\e[32m                                            console.log("CROP");\e[m
+\e[32m+\e[m\e[32m                                            console.log(data);\e[m
+\e[32m+\e[m\e[32m                                        },\e[m
+\e[32m+\e[m\e[32m                                        resize : function (_self)\e[m
+\e[32m+\e[m\e[32m                                        {\e[m
+\e[32m+\e[m\e[32m                                            console.log("RESIZE");\e[m
+\e[32m+\e[m\e[32m                                        },\e[m
+\e[32m+\e[m\e[32m                                        rotate : function (_self)\e[m
+\e[32m+\e[m\e[32m                                        {\e[m
+\e[32m+\e[m\e[32m                                            console.log("ROTATE");\e[m
+\e[32m+\e[m\e[32m                                        },\e[m
+\e[32m+\e[m\e[32m                                        render : function (_self)\e[m
+\e[32m+\e[m\e[32m                                        {\e[m
+\e[32m+\e[m\e[32m                                            console.log("RENDER");\e[m
+\e[32m+\e[m\e[32m                                            console.log(_self);\e[m
+\e[32m+\e[m\e[32m                                            _this.cropbox = _self;\e[m
+\e[32m+\e[m\e[32m                                        }\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                                    }\e[m
+\e[32m+\e[m\e[32m                                }\e[m
+\e[32m+\e[m\e[32m                            ]\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[32m                    ]\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ],\e[m
+\e[32m+\e[m\e[32m            listeners : {\e[m
+\e[32m+\e[m\e[32m                btnclick : function (e)\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    console.log(e);\e[m
+\e[32m+\e[m\e[32m                    if(e == 'cancel') {\e[m
+\e[32m+\e[m\e[32m                        _this.dialog.hide();\e[m
+\e[32m+\e[m\e[32m                        return;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                    _this.cropbox.crop();\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        });\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[32m}\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.onReady(function() {\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    Roo.get('show-dialog-btn').on('click',function () {\e[m
+\e[32m+\e[m\e[32m        test.show({});\e[m
+\e[32m+\e[m\e[32m        console.log(test);\e[m
+\e[32m+\e[m\e[32m    });\e[m
+\e[32m+\e[m\e[32m});\e[m
+\ No newline at end of file\e[m
+\e[1mdiff --git a/roojs-all.js b/roojs-all.js\e[m
+\e[1mindex 9d9fc1f28f..f98434e789 100644\e[m
+\e[1m--- a/roojs-all.js\e[m
+\e[1m+++ b/roojs-all.js\e[m
+\e[36m@@ -2544,9 +2544,9 @@\e[m \e[mreturn this.el.getUpdateManager();},_handleRefresh:function(A,B,C){if(!C||!this.\e[m
+ te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B);\e[m
+ this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A);\e[m
+ }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();\e[m
+\e[31m-}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();\e[m
+\e[31m-this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,'');\e[m
+\e[31m-this.view=B;return B;}return false;}});\e[m
+\e[32m+\e[m\e[32m}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A);\e[m
+\e[32m+\e[m\e[32mthis.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));\e[m
+\e[32m+\e[m\e[32mvar B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}});\e[m
+ // Roo/GridPanel.js\e[m
+ Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B);\e[m
+ if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo);\e[m
+\e[36m@@ -2875,3 +2875,103 @@\e[m \e[mF.push("(typeof("+G+") == 'undefined')");});var H='(('+F.join(" || ")+") ? undef\e[m
+ }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){  with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){  with (values) { return ['"];\e[m
+ B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{}\e[m
+ );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);};\e[m
+\e[32m+\e[m\e[32m// Roo/dialog/namespace.js\e[m
+\e[32m+\e[m\e[32mRoo.dialog={};\e[m
+\e[32m+\e[m\e[32m// Roo/dialog/UploadCropbox.js\e[m
+\e[32m+\e[m\e[32mRoo.dialog.UploadCropbox=function(A){console.log("Dialog UploadCropbox Constructor");Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true}\e[m
+\e[32m+\e[m\e[32m);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,file:false,exif:{}\e[m
+\e[32m+\e[m\e[32m,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'}\e[m
+\e[32m+\e[m\e[32m,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){console.log("On Render");console.log(this);Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);\e[m
+\e[32m+\e[m\e[32mif(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;\e[m
+\e[32m+\e[m\e[32m}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style;}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);\e[m
+\e[32m+\e[m\e[32mC.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true));},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);\e[m
+\e[32m+\e[m\e[32mthis.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first();this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();\e[m
+\e[32m+\e[m\e[32mthis.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();\e[m
+\e[32m+\e[m\e[32mthis.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();\e[m
+\e[32m+\e[m\e[32mthis.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();\e[m
+\e[32m+\e[m\e[32m});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this);this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);\e[m
+\e[32m+\e[m\e[32mthis.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel';this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);\e[m
+\e[32m+\e[m\e[32m},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false;this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32mthis.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e);break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);\e[m
+\e[32m+\e[m\e[32mbreak;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A);},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();\e[m
+\e[32m+\e[m\e[32mif(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return;}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);\e[m
+\e[32m+\e[m\e[32m},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset();this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;\e[m
+\e[32m+\e[m\e[32mthis.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height;if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();\e[m
+\e[32m+\e[m\e[32mif(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition();this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);\e[m
+\e[32m+\e[m\e[32mvar ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2);this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.width<this.thumbEl.getWidth()||this.canvasEl.height<this.thumbEl.getHeight())){this.dragable=false;\e[m
+\e[32m+\e[m\e[32mreturn;}this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseMove:function(e){e.stopEvent();if(!this.canvasLoaded){return;}if(!this.dragable){return;}var A=Math.ceil(this.thumbEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32mvar B=Math.ceil(this.thumbEl.getTop(true));var C=Math.ceil(A+this.thumbEl.getWidth()-this.canvasEl.width);var D=Math.ceil(B+this.thumbEl.getHeight()-this.canvasEl.height);var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();\e[m
+\e[32m+\e[m\e[32mx=x-this.mouseX;y=y-this.mouseY;var E=Math.ceil(x+this.previewEl.getLeft(true));var F=Math.ceil(y+this.previewEl.getTop(true));E=(A<E)?A:((C>E)?C:E);F=(B<F)?B:((D>F)?D:F);this.previewEl.setLeft(E);this.previewEl.setTop(F);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();\e[m
+\e[32m+\e[m\e[32mthis.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent();this.startScale=this.scale;this.scale=(e.getWheelDelta()==1)?(this.scale+1):(this.scale-1);\e[m
+\e[32m+\e[m\e[32mif(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidth<this.minHeight){A=this.thumbEl.getHeight()/this.minHeight;}var B=Math.ceil(this.imageEl.OriginWidth*this.getScaleLevel()/A);\e[m
+\e[32m+\e[m\e[32mvar C=Math.ceil(this.imageEl.OriginHeight*this.getScaleLevel()/A);if(this.isDocument&&(this.rotate==0||this.rotate==180)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minWidth&&C<this.minHeight))){return false;}if(this.isDocument&&(this.rotate==90||this.rotate==270)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minHeight&&C<this.minWidth))){return false;\e[m
+\e[32m+\e[m\e[32m}if(!this.isDocument&&(this.rotate==0||this.rotate==180)&&(B<this.minWidth||B>this.imageEl.OriginWidth||C<this.minHeight||C>this.imageEl.OriginHeight)){return false;}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(B<this.minHeight||B>this.imageEl.OriginWidth||C<this.minWidth||C>this.imageEl.OriginHeight)){return false;\e[m
+\e[32m+\e[m\e[32m}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;\e[m
+\e[32m+\e[m\e[32m}this.rotate=(this.rotate<90)?270:this.rotate-90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate<90)?270:this.rotate-90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m}this.draw();this.fireEvent('rotate',this,'left');},onRotateRight:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;\e[m
+\e[32m+\e[m\e[32m}this.rotate=(this.rotate>180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas");\e[m
+\e[32m+\e[m\e[32mvar B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidth<this.imageEl.OriginHeight){A.width=this.imageEl.OriginHeight*this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32mA.height=this.imageEl.OriginHeight*this.getScaleLevel();C=this.imageEl.OriginHeight/2;}B.scale(this.getScaleLevel(),this.getScaleLevel());B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32mthis.canvasEl=document.createElement("canvas");this.contextEl=this.canvasEl.getContext("2d");switch(this.rotate){case 0:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;case 90:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32mif(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32mvar C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d");\e[m
+\e[32m+\e[m\e[32mD.width=this.minWidth;D.height=this.minHeight;switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32mvar sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;\e[m
+\e[32m+\e[m\e[32m}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[32msx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;\e[m
+\e[32m+\e[m\e[32m}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[32msx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;\e[m
+\e[32m+\e[m\e[32mE.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32mvar sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32mE.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType);if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight);\e[m
+\e[32m+\e[m\e[32mB=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=300;A=Math.ceil(this.minWidth*B/this.minHeight);\e[m
+\e[32m+\e[m\e[32mif(this.minWidth>this.minHeight){A=300;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2);var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);\e[m
+\e[32m+\e[m\e[32mthis.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];\e[m
+\e[32m+\e[m\e[32m}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32mthis.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getWidth()){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getHeight()){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m}}return;}A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getHeight()){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32mthis.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;}}return;},getScaleLevel:function(){return this.baseScale*Math.pow(1.1,this.scale);\e[m
+\e[32m+\e[m\e[32m},onTouchStart:function(e){if(!this.canvasLoaded){this.beforeSelectFile(e);return;}var A=e.browserEvent.touches;if(!A){return;}if(A.length==1){this.onMouseDown(e);return;}if(A.length!=2){return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}\e[m
+\e[32m+\e[m\e[32mvar x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.startDistance=Math.sqrt(x+y);this.startScale=this.scale;this.pinching=true;this.dragable=false;},onTouchMove:function(e){if(!this.pinching&&!this.dragable){return;}var A=e.browserEvent.touches;if(!A){return;\e[m
+\e[32m+\e[m\e[32m}if(this.dragable){this.onMouseMove(e);return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.endDistance=Math.sqrt(x+y);this.scale=this.startScale+Math.floor(Math.log(this.endDistance/this.startDistance)/Math.log(1.1));\e[m
+\e[32m+\e[m\e[32mif(!this.zoomable()){this.scale=this.startScale;return;}this.draw();},onTouchEnd:function(e){this.pinching=false;this.dragable=false;},process:function(A,B){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.xhr=new XMLHttpRequest();A.xhr=this.xhr;\e[m
+\e[32m+\e[m\e[32mthis.xhr.open(this.method,this.url,true);var C={"Accept":"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"};for(var D in C){var E=C[D];if(E){this.xhr.setRequestHeader(D,E);}}var F=this;this.xhr.onload=function(){F.xhrOnLoad(F.xhr);\e[m
+\e[32m+\e[m\e[32m};this.xhr.onerror=function(){F.xhrOnError(F.xhr);};var G=new FormData();G.append('returnHTML','NO');if(B){G.append('crop',B);}if(typeof(A)!='undefined'&&(typeof(A.id)=='undefined'||A.id*1<1)){G.append(this.paramName,A,A.name);}if(typeof(A.filename)!='undefined'){G.append('filename',A.filename);\e[m
+\e[32m+\e[m\e[32m}if(typeof(A.mimetype)!='undefined'){G.append('mimetype',A.mimetype);}if(this.fireEvent('arrange',this,G)!=false){this.xhr.send(G);};},xhrOnLoad:function(A){if(this.loadMask){this.maskEl.unmask();}if(A.readyState!==4){this.fireEvent('exception',this,A);return;\e[m
+\e[32m+\e[m\e[32m}var B=Roo.decode(A.responseText);if(!B.success){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);this.fireEvent('upload',this,B);},xhrOnError:function(){if(this.loadMask){this.maskEl.unmask();}Roo.log('xhr on error');var A=Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[32mRoo.log(A);},prepare:function(A){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.file=false;this.exif={};if(typeof(A)==='string'){this.loadCanvas(A);return;}if(!A||!this.urlAPI){return;}this.file=A;this.cropType=A.type;var B=this;if(this.fireEvent('prepare',this,this.file)!=false){var C=new FileReader();\e[m
+\e[32m+\e[m\e[32mC.onload=function(e){if(e.target.error){Roo.log(e.target.error);return;}var D=e.target.result,E=new DataView(D),F=2,G=E.byteLength-4,H,I;if(E.getUint16(0)===0xffd8){while(F<G){H=E.getUint16(F);if((H>=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32mbreak;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break;}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;\e[m
+\e[32m+\e[m\e[32m}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.');return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;\e[m
+\e[32m+\e[m\e[32mdefault:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return;}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;\e[m
+\e[32m+\e[m\e[32mif(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.');return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i<E;i+=1){this.parseExifTag(A,B,C+2+12*i,D);}return A.getUint32(F,D);\e[m
+\e[32m+\e[m\e[32m},parseExifTag:function(A,B,C,D){var E=A.getUint16(C,D);this.exif[E]=this.getExifValue(A,B,C,A.getUint16(C+2,D),A.getUint32(C+4,D),D);},getExifValue:function(A,B,C,D,E,F){var G=Roo.dialog.UploadCropbox.exifTagTypes[D],H,I,J,i,K,c;if(!G){Roo.log('Invalid Exif data: Invalid tag type.');\e[m
+\e[32m+\e[m\e[32mreturn;}H=G.size*E;I=H>4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.');return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i<E;i+=1){J[i]=G.getValue(A,I+i*G.size,F);}if(G.ascii){K='';for(i=0;i<J.length;\e[m
+\e[32m+\e[m\e[32mi+=1){c=J[i];if(c==='\u0000'){break;}K+=c;}return K;}return J;}});Roo.apply(Roo.dialog.UploadCropbox,{tags:{'Orientation':0x0112\e[m
+\e[32m+\e[m\e[32m},Orientation:{1:0,3:180,6:90,8:270},exifTagTypes:{1:{getValue:function(A,B){return A.getUint8(B);},size:1},2:{getValue:function(A,B){return String.fromCharCode(A.getUint8(B));\e[m
+\e[32m+\e[m\e[32m},size:1,ascii:true},3:{getValue:function(A,B,C){return A.getUint16(B,C);},size:2},4:{getValue:function(A,B,C){return A.getUint32(B,C);},size:4},5:{getValue:function(A,B,C){return A.getUint32(B,C)/A.getUint32(B+4,C);},size:8},9:{getValue:function(A,B,C){return A.getInt32(B,C);\e[m
+\e[32m+\e[m\e[32m},size:4},10:{getValue:function(A,B,C){return A.getInt32(B,C)/A.getInt32(B+4,C);},size:8}},footer:{STANDARD:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-picture-o"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}\e[m
+\e[32m+\e[m\e[32m]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-download"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-crop"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-trash"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}]}});\e[m
+\e[1mdiff --git a/roojs-debug.js b/roojs-debug.js\e[m
+\e[1mindex 5e539c7e68..d341c59730 100644\e[m
+\e[1m--- a/roojs-debug.js\e[m
+\e[1m+++ b/roojs-debug.js\e[m
+\e[36m@@ -60414,7 +60414,6 @@\e[m \e[mRoo.LayoutStateManager.prototype = {\e[m
+  */\e[m
+ Roo.ContentPanel = function(el, config, content){\e[m
+     \e[m
+\e[31m-     \e[m
+     /*\e[m
+     if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory\e[m
+         config = el;\e[m
+\e[36m@@ -60798,6 +60797,14 @@\e[m \e[mlayout.addxtype({\e[m
+      */\e[m
+     \e[m
+     addxtype : function(cfg) {\e[m
+\e[32m+\e[m\e[32m        if(cfg.xtype.match(/^UploadCropbox$/)) {\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            this.cropbox = new Roo.factory(cfg);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            this.cropbox.render(this.el);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            return this.cropbox;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+         // add form..\e[m
+         if (cfg.xtype.match(/^Form$/)) {\e[m
+             \e[m
+\e[36m@@ -68050,4 +68057,1795 @@\e[m \e[mRoo.extend(Roo.XTemplate, Roo.Template, {\e[m
+ Roo.XTemplate.from = function(el){\e[m
+     el = Roo.getDom(el);\e[m
+     return new Roo.XTemplate(el.value || el.innerHTML);\e[m
+\e[31m-};\e[m
+\ No newline at end of file\e[m
+\e[32m+\e[m\e[32m};Roo.dialog = {};\e[m
+\e[32m+\e[m\e[32m/*\e[m
+\e[32m+\e[m\e[32m* Licence: LGPL\e[m
+\e[32m+\e[m\e[32m*/\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m/**\e[m
+\e[32m+\e[m\e[32m * @class Roo.dialog.UploadCropbox\e[m
+\e[32m+\e[m\e[32m * @extends Roo.BoxComponent\e[m
+\e[32m+\e[m\e[32m * Dialog UploadCropbox class\e[m
+\e[32m+\e[m\e[32m * @cfg {String} emptyText show when image has been loaded\e[m
+\e[32m+\e[m\e[32m * @cfg {String} rotateNotify show when image too small to rotate\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} errorTimeout default 3000\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} minWidth default 300\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} minHeight default 300\e[m
+\e[32m+\e[m\e[32m * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} isDocument (true|false) default false\e[m
+\e[32m+\e[m\e[32m * @cfg {String} url action url\e[m
+\e[32m+\e[m\e[32m * @cfg {String} paramName default 'imageUpload'\e[m
+\e[32m+\e[m\e[32m * @cfg {String} method default POST\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} loadMask (true|false) default true\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} loadingText default 'Loading...'\e[m
+\e[32m+\e[m\e[32m *\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m * @constructor\e[m
+\e[32m+\e[m\e[32m * Create a new UploadCropbox\e[m
+\e[32m+\e[m\e[32m * @param {Object} config The config object\e[m
+\e[32m+\e[m\e[32m */\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m Roo.dialog.UploadCropbox = function(config){\e[m
+\e[32m+\e[m\e[32m    console.log("Dialog UploadCropbox Constructor");\e[m
+\e[32m+\e[m\e[32m    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    this.addEvents({\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event beforeselectfile\e[m
+\e[32m+\e[m\e[32m         * Fire before select file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "beforeselectfile" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event initial\e[m
+\e[32m+\e[m\e[32m         * Fire after initEvent\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "initial" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event crop\e[m
+\e[32m+\e[m\e[32m         * Fire after initEvent\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} data\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "crop" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event prepare\e[m
+\e[32m+\e[m\e[32m         * Fire when preparing the file data\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} file\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "prepare" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event exception\e[m
+\e[32m+\e[m\e[32m         * Fire when get exception\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {XMLHttpRequest} xhr\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "exception" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event beforeloadcanvas\e[m
+\e[32m+\e[m\e[32m         * Fire before load the canvas\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} src\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "beforeloadcanvas" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event trash\e[m
+\e[32m+\e[m\e[32m         * Fire when trash image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "trash" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event download\e[m
+\e[32m+\e[m\e[32m         * Fire when download the image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "download" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event footerbuttonclick\e[m
+\e[32m+\e[m\e[32m         * Fire when footerbuttonclick\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} type\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "footerbuttonclick" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event resize\e[m
+\e[32m+\e[m\e[32m         * Fire when resize\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "resize" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event rotate\e[m
+\e[32m+\e[m\e[32m         * Fire when rotate the image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} pos\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "rotate" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event inspect\e[m
+\e[32m+\e[m\e[32m         * Fire when inspect the file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} file\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "inspect" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event upload\e[m
+\e[32m+\e[m\e[32m         * Fire when xhr upload the file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} data\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "upload" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event arrange\e[m
+\e[32m+\e[m\e[32m         * Fire when arrange the file data\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} formData\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "arrange" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event loadcanvas\e[m
+\e[32m+\e[m\e[32m         * Fire after load the canvas\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox}\e[m
+\e[32m+\e[m\e[32m         * @param {Object} imgEl\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "loadcanvas" : true\e[m
+\e[32m+\e[m\e[32m    });\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;\e[m
+\e[32m+\e[m\e[32m};\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    emptyText : 'Click to upload image',\e[m
+\e[32m+\e[m\e[32m    rotateNotify : 'Image is too small to rotate',\e[m
+\e[32m+\e[m\e[32m    errorTimeout : 3000,\e[m
+\e[32m+\e[m\e[32m    scale : 0,\e[m
+\e[32m+\e[m\e[32m    baseScale : 1,\e[m
+\e[32m+\e[m\e[32m    rotate : 0,\e[m
+\e[32m+\e[m\e[32m    dragable : false,\e[m
+\e[32m+\e[m\e[32m    pinching : false,\e[m
+\e[32m+\e[m\e[32m    mouseX : 0,\e[m
+\e[32m+\e[m\e[32m    mouseY : 0,\e[m
+\e[32m+\e[m\e[32m    cropData : false,\e[m
+\e[32m+\e[m\e[32m    minWidth : 300,\e[m
+\e[32m+\e[m\e[32m    minHeight : 300,\e[m
+\e[32m+\e[m\e[32m    file : false,\e[m
+\e[32m+\e[m\e[32m    exif : {},\e[m
+\e[32m+\e[m\e[32m    baseRotate : 1,\e[m
+\e[32m+\e[m\e[32m    cropType : 'image/jpeg',\e[m
+\e[32m+\e[m\e[32m    buttons : false,\e[m
+\e[32m+\e[m\e[32m    canvasLoaded : false,\e[m
+\e[32m+\e[m\e[32m    isDocument : false,\e[m
+\e[32m+\e[m\e[32m    method : 'POST',\e[m
+\e[32m+\e[m\e[32m    paramName : 'imageUpload',\e[m
+\e[32m+\e[m\e[32m    loadMask : true,\e[m
+\e[32m+\e[m\e[32m    loadingText : 'Loading...',\e[m
+\e[32m+\e[m\e[32m    maskEl : false,\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getAutoCreate : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var cfg = {\e[m
+\e[32m+\e[m\e[32m            tag : 'div',\e[m
+\e[32m+\e[m\e[32m            cls : 'roo-upload-cropbox',\e[m
+\e[32m+\e[m\e[32m            cn : [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'input',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-selector',\e[m
+\e[32m+\e[m\e[32m                    type : 'file'\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'div',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-body',\e[m
+\e[32m+\e[m\e[32m                    style : 'cursor:pointer',\e[m
+\e[32m+\e[m\e[32m                    cn : [\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-preview'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-thumb'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-empty-notify',\e[m
+\e[32m+\e[m\e[32m                            html : this.emptyText\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',\e[m
+\e[32m+\e[m\e[32m                            html : this.rotateNotify\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[32m                    ]\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'div',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-footer',\e[m
+\e[32m+\e[m\e[32m                    cn : {\e[m
+\e[32m+\e[m\e[32m                        tag : 'div',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',\e[m
+\e[32m+\e[m\e[32m                        cn : []\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ]\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return cfg;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRender : function(ct, position)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        console.log("On Render");\e[m
+\e[32m+\e[m\e[32m        console.log(this);\e[m
+\e[32m+\e[m\e[32m        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.el){\e[m
+\e[32m+\e[m\e[32m            if (this.el.attr('xtype')) {\e[m
+\e[32m+\e[m\e[32m                this.el.attr('xtypex', this.el.attr('xtype'));\e[m
+\e[32m+\e[m\e[32m                this.el.dom.removeAttribute('xtype');\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.initEvents();\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        else {\e[m
+\e[32m+\e[m\e[32m            var cfg = Roo.apply({},  this.getAutoCreate());\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            cfg.id = this.id || Roo.id();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if (this.cls) {\e[m
+\e[32m+\e[m\e[32m                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if (this.style) { // fixme needs to support more complex style data.\e[m
+\e[32m+\e[m\e[32m                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.el = ct.createChild(cfg, position);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.initEvents();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (this.buttons.length) {\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            Roo.each(this.buttons, function(bb) {\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m            }, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl = this.el;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    initEvents : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.urlAPI = (window.createObjectURL && window) ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                (window.URL && URL.revokeObjectURL && URL) ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                (window.webkitURL && webkitURL);\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();\e[m
+\e[32m+\e[m\e[32m        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();\e[m
+\e[32m+\e[m\e[32m        this.selectorEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();\e[m
+\e[32m+\e[m\e[32m        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();\e[m
+\e[32m+\e[m\e[32m        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.errorEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();\e[m
+\e[32m+\e[m\e[32m        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.footerEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.bind();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.resize();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('initial', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    bind : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        window.addEventListener("resize", function() { _this.resize(); } );\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.bodyEl.on('click', this.beforeSelectFile, this);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(Roo.isTouch){\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchstart', this.onTouchStart, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchmove', this.onTouchMove, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchend', this.onTouchEnd, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!Roo.isTouch){\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('mousedown', this.onMouseDown, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('mousemove', this.onMouseMove, this);\e[m
+\e[32m+\e[m\e[32m            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on(mousewheel, this.onMouseWheel, this);\e[m
+\e[32m+\e[m\e[32m            Roo.get(document).on('mouseup', this.onMouseUp, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.selectorEl.on('change', this.onFileSelected, this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    reset : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        this.scale = 0;\e[m
+\e[32m+\e[m\e[32m        this.baseScale = 1;\e[m
+\e[32m+\e[m\e[32m        this.rotate = 0;\e[m
+\e[32m+\e[m\e[32m        this.baseRotate = 1;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[32m        this.mouseX = 0;\e[m
+\e[32m+\e[m\e[32m        this.mouseY = 0;\e[m
+\e[32m+\e[m\e[32m        this.cropData = false;\e[m
+\e[32m+\e[m\e[32m        this.notifyEl.dom.innerHTML = this.emptyText;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        // this.selectorEl.dom.value = '';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    resize : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('resize', this) != false){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onFooterButtonClick : function(e, el, o, type)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        switch (type) {\e[m
+\e[32m+\e[m\e[32m            case 'rotate-left' :\e[m
+\e[32m+\e[m\e[32m                this.onRotateLeft(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'rotate-right' :\e[m
+\e[32m+\e[m\e[32m                this.onRotateRight(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'picture' :\e[m
+\e[32m+\e[m\e[32m                this.beforeSelectFile(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'trash' :\e[m
+\e[32m+\e[m\e[32m                this.trash(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'crop' :\e[m
+\e[32m+\e[m\e[32m                this.crop(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'download' :\e[m
+\e[32m+\e[m\e[32m                this.download(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('footerbuttonclick', this, type);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    beforeSelectFile : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        e.preventDefault();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('beforeselectfile', this) != false){\e[m
+\e[32m+\e[m\e[32m            this.selectorEl.dom.click();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onFileSelected : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        e.preventDefault();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var file = this.selectorEl.dom.files[0];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('inspect', this, file) != false){\e[m
+\e[32m+\e[m\e[32m            this.prepare(file);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    trash : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.fireEvent('trash', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    download : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.fireEvent('download', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    loadCanvas : function(src)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('beforeloadcanvas', this, src) != false){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.reset();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl = document.createElement('img');\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var _this = this;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl.src = src;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onLoadCanvas : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;\e[m
+\e[32m+\e[m\e[32m        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            this.bodyEl.un('click', this.beforeSelectFile, this);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.notifyEl.hide();\e[m
+\e[32m+\e[m\e[32m            this.thumbEl.show();\e[m
+\e[32m+\e[m\e[32m            this.footerEl.show();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.baseRotateLevel();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m                this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.baseScaleLevel();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.draw();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.resize();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.canvasLoaded = true;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setCanvasPosition : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(!this.canvasEl){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);\e[m
+\e[32m+\e[m\e[32m        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.setLeft(pw);\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setTop(ph);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseDown : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.dragable = true;\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[32m            this.dragable = false;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseMove : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (!this.dragable){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var minX = Math.ceil(this.thumbEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m        var minY = Math.ceil(this.thumbEl.getTop(true));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);\e[m
+\e[32m+\e[m\e[32m        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        x = x - this.mouseX;\e[m
+\e[32m+\e[m\e[32m        y = y - this.mouseY;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var bgX = Math.ceil(x + this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m        var bgY = Math.ceil(y + this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        bgX = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX);\e[m
+\e[32m+\e[m\e[32m        bgY = (minY < bgY) ? minY : ((maxY > bgY) ? maxY : bgY);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.setLeft(bgX);\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setTop(bgY);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseUp : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseWheel : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    zoomable : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.minWidth < this.minHeight){\e[m
+\e[32m+\e[m\e[32m            minScale = this.thumbEl.getHeight() / this.minHeight;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);\e[m
+\e[32m+\e[m\e[32m        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 0 || this.rotate == 180) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight ||\e[m
+\e[32m+\e[m\e[32m                    (width < this.minWidth && height < this.minHeight)\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 90 || this.rotate == 270) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight ||\e[m
+\e[32m+\e[m\e[32m                    (width < this.minHeight && height < this.minWidth)\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                !this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 0 || this.rotate == 180) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width < this.minWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height < this.minHeight ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                !this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 90 || this.rotate == 270) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width < this.minHeight ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height < this.minWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return true;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateLeft : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            while (this.getScaleLevel() < minScale){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                this.scale = this.scale + 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()\e[m
+\e[32m+\e[m\e[32m                ){\e[m
+\e[32m+\e[m\e[32m                    continue;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                this.draw();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.onRotateFail();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('rotate', this, 'left');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateRight : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            while (this.getScaleLevel() < minScale){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                this.scale = this.scale + 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()\e[m
+\e[32m+\e[m\e[32m                ){\e[m
+\e[32m+\e[m\e[32m                    continue;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                this.draw();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.onRotateFail();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('rotate', this, 'right');\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateFail : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.errorEl.show(true);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    draw : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.previewEl.dom.innerHTML = '';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var canvasEl = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var contextEl = canvasEl.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m        var center = this.imageEl.OriginWidth / 2;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m            center = this.imageEl.OriginHeight / 2;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        contextEl.translate(center, center);\e[m
+\e[32m+\e[m\e[32m        contextEl.rotate(this.rotate * Math.PI / 180);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.canvasEl = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.contextEl = this.canvasEl.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        switch (this.rotate) {\e[m
+\e[32m+\e[m\e[32m            case 0 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 90 :\e[m\e[41m \e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 180 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 270 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.appendChild(this.canvasEl);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    crop : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var imageCanvas = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var imageContext = imageCanvas.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var center = imageCanvas.width / 2;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.translate(center, center);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.rotate(this.rotate * Math.PI / 180);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var canvas = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var context = canvas.getContext("2d");\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m        canvas.width = this.minWidth;\e[m
+\e[32m+\e[m\e[32m        canvas.height = this.minHeight;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        switch (this.rotate) {\e[m
+\e[32m+\e[m\e[32m            case 0 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 90 :\e[m\e[41m \e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 180 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32m                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 270 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.cropData = canvas.toDataURL(this.cropType);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('crop', this, this.cropData) !== false){\e[m
+\e[32m+\e[m\e[32m            this.process(this.file, this.cropData);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setThumbBoxSize : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var width, height;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument && typeof(this.imageEl) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);\e[m
+\e[32m+\e[m\e[32m            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.minWidth = width;\e[m
+\e[32m+\e[m\e[32m            this.minHeight = height;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.rotate == 90 || this.rotate == 270){\e[m
+\e[32m+\e[m\e[32m                this.minWidth = height;\e[m
+\e[32m+\e[m\e[32m                this.minHeight = width;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        height = 300;\e[m
+\e[32m+\e[m\e[32m        width = Math.ceil(this.minWidth * height / this.minHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.minWidth > this.minHeight){\e[m
+\e[32m+\e[m\e[32m            width = 300;\e[m
+\e[32m+\e[m\e[32m            height = Math.ceil(this.minHeight * width / this.minWidth);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setStyle({\e[m
+\e[32m+\e[m\e[32m            width : width + 'px',\e[m
+\e[32m+\e[m\e[32m            height : height + 'px'\e[m
+\e[32m+\e[m\e[32m        });\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setThumbBoxPosition : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );\e[m
+\e[32m+\e[m\e[32m        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setLeft(x);\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setTop(y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    baseRotateLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.baseRotate = 1;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                typeof(this.exif) != 'undefined' &&\e[m
+\e[32m+\e[m\e[32m                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&\e[m
+\e[32m+\e[m\e[32m                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    baseScaleLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var width, height;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.baseRotate == 6 || this.baseRotate == 8){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                    width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                    this.baseScale = width / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.baseRotate == 6 || this.baseRotate == 8){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            width = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = width / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){\e[m
+\e[32m+\e[m\e[32m                    width = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m                    this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m        this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){\e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getScaleLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        return this.baseScale * Math.pow(1.1, this.scale);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchStart : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            this.beforeSelectFile(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var touches = e.browserEvent.touches;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!touches){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(touches.length == 1){\e[m
+\e[32m+\e[m\e[32m            this.onMouseDown(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(touches.length != 2){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var coords = [];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for(var i = 0, finger; finger = touches[i]; i++){\e[m
+\e[32m+\e[m\e[32m            coords.push(finger.pageX, finger.pageY);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Math.pow(coords[0] - coords[2], 2);\e[m
+\e[32m+\e[m\e[32m        var y = Math.pow(coords[1] - coords[3], 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startDistance = Math.sqrt(x + y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.pinching = true;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchMove : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.pinching && !this.dragable){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var touches = e.browserEvent.touches;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!touches){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.dragable){\e[m
+\e[32m+\e[m\e[32m            this.onMouseMove(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var coords = [];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for(var i = 0, finger; finger = touches[i]; i++){\e[m
+\e[32m+\e[m\e[32m            coords.push(finger.pageX, finger.pageY);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Math.pow(coords[0] - coords[2], 2);\e[m
+\e[32m+\e[m\e[32m        var y = Math.pow(coords[1] - coords[3], 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.endDistance = Math.sqrt(x + y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchEnd : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    process : function(file, crop)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.mask(this.loadingText);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr = new XMLHttpRequest();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        file.xhr = this.xhr;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        this.xhr.open(this.method, this.url, true);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var headers = {\e[m
+\e[32m+\e[m\e[32m            "Accept": "application/json",\e[m
+\e[32m+\e[m\e[32m            "Cache-Control": "no-cache",\e[m
+\e[32m+\e[m\e[32m            "X-Requested-With": "XMLHttpRequest"\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for (var headerName in headers) {\e[m
+\e[32m+\e[m\e[32m            var headerValue = headers[headerName];\e[m
+\e[32m+\e[m\e[32m            if (headerValue) {\e[m
+\e[32m+\e[m\e[32m                this.xhr.setRequestHeader(headerName, headerValue);\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr.onload = function()\e[m
+\e[32m+\e[m\e[32m        {\e[m
+\e[32m+\e[m\e[32m            _this.xhrOnLoad(_this.xhr);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr.onerror = function()\e[m
+\e[32m+\e[m\e[32m        {\e[m
+\e[32m+\e[m\e[32m            _this.xhrOnError(_this.xhr);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var formData = new FormData();\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        formData.append('returnHTML', 'NO');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(crop){\e[m
+\e[32m+\e[m\e[32m            formData.append('crop', crop);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file) != 'undefined' && (typeof(file.id) == 'undefined' || file.id * 1 < 1)){\e[m
+\e[32m+\e[m\e[32m            formData.append(this.paramName, file, file.name);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file.filename) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            formData.append('filename', file.filename);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file.mimetype) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            formData.append('mimetype', file.mimetype);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('arrange', this, formData) != false){\e[m
+\e[32m+\e[m\e[32m            this.xhr.send(formData);\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    xhrOnLoad : function(xhr)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (xhr.readyState !== 4) {\e[m
+\e[32m+\e[m\e[32m            this.fireEvent('exception', this, xhr);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!response.success){\e[m
+\e[32m+\e[m\e[32m            this.fireEvent('exception', this, xhr);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('upload', this, response);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    xhrOnError : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        Roo.log('xhr on error');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m          \e[m
+\e[32m+\e[m\e[32m        Roo.log(response);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    prepare : function(file)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.mask(this.loadingText);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.file = false;\e[m
+\e[32m+\e[m\e[32m        this.exif = {};\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file) === 'string'){\e[m
+\e[32m+\e[m\e[32m            this.loadCanvas(file);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!file || !this.urlAPI){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.file = file;\e[m
+\e[32m+\e[m\e[32m        this.cropType = file.type;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('prepare', this, this.file) != false){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var reader = new FileReader();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            reader.onload = function (e) {\e[m
+\e[32m+\e[m\e[32m                if (e.target.error) {\e[m
+\e[32m+\e[m\e[32m                    Roo.log(e.target.error);\e[m
+\e[32m+\e[m\e[32m                    return;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var buffer = e.target.result,\e[m
+\e[32m+\e[m\e[32m                    dataView = new DataView(buffer),\e[m
+\e[32m+\e[m\e[32m                    offset = 2,\e[m
+\e[32m+\e[m\e[32m                    maxOffset = dataView.byteLength - 4,\e[m
+\e[32m+\e[m\e[32m                    markerBytes,\e[m
+\e[32m+\e[m\e[32m                    markerLength;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if (dataView.getUint16(0) === 0xffd8) {\e[m
+\e[32m+\e[m\e[32m                    while (offset < maxOffset) {\e[m
+\e[32m+\e[m\e[32m                        markerBytes = dataView.getUint16(offset);\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {\e[m
+\e[32m+\e[m\e[32m                            markerLength = dataView.getUint16(offset + 2) + 2;\e[m
+\e[32m+\e[m\e[32m                            if (offset + markerLength > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m                                Roo.log('Invalid meta data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32m                                break;\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            if(markerBytes == 0xffe1){\e[m
+\e[32m+\e[m\e[32m                                _this.parseExifData(\e[m
+\e[32m+\e[m\e[32m                                    dataView,\e[m
+\e[32m+\e[m\e[32m                                    offset,\e[m
+\e[32m+\e[m\e[32m                                    markerLength\e[m
+\e[32m+\e[m\e[32m                                );\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            offset += markerLength;\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            continue;\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                        break;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var url = _this.urlAPI.createObjectURL(_this.file);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                _this.loadCanvas(url);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            reader.readAsArrayBuffer(this.file);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifData : function(dataView, offset, length)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tiffOffset = offset + 10,\e[m
+\e[32m+\e[m\e[32m            littleEndian,\e[m
+\e[32m+\e[m\e[32m            dirOffset;\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint32(offset + 4) !== 0x45786966) {\e[m
+\e[32m+\e[m\e[32m            // No Exif data, might be XMP data instead\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        // Check for the ASCII code for "Exif" (0x45786966):\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint32(offset + 4) !== 0x45786966) {\e[m
+\e[32m+\e[m\e[32m            // No Exif data, might be XMP data instead\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        if (tiffOffset + 8 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check for the two null bytes:\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint16(offset + 8) !== 0x0000) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Missing byte alignment offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check the byte alignment:\e[m
+\e[32m+\e[m\e[32m        switch (dataView.getUint16(tiffOffset)) {\e[m
+\e[32m+\e[m\e[32m        case 0x4949:\e[m
+\e[32m+\e[m\e[32m            littleEndian = true;\e[m
+\e[32m+\e[m\e[32m            break;\e[m
+\e[32m+\e[m\e[32m        case 0x4D4D:\e[m
+\e[32m+\e[m\e[32m            littleEndian = false;\e[m
+\e[32m+\e[m\e[32m            break;\e[m
+\e[32m+\e[m\e[32m        default:\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid byte alignment marker.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check for the TIFF tag marker (0x002A):\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Missing TIFF marker.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\e[m
+\e[32m+\e[m\e[32m        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.parseExifTags(\e[m
+\e[32m+\e[m\e[32m            dataView,\e[m
+\e[32m+\e[m\e[32m            tiffOffset,\e[m
+\e[32m+\e[m\e[32m            tiffOffset + dirOffset,\e[m
+\e[32m+\e[m\e[32m            littleEndian\e[m
+\e[32m+\e[m\e[32m        );\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tagsNumber,\e[m
+\e[32m+\e[m\e[32m            dirEndOffset,\e[m
+\e[32m+\e[m\e[32m            i;\e[m
+\e[32m+\e[m\e[32m        if (dirOffset + 6 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid directory offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        tagsNumber = dataView.getUint16(dirOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;\e[m
+\e[32m+\e[m\e[32m        if (dirEndOffset + 4 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid directory size.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        for (i = 0; i < tagsNumber; i += 1) {\e[m
+\e[32m+\e[m\e[32m            this.parseExifTag(\e[m
+\e[32m+\e[m\e[32m                dataView,\e[m
+\e[32m+\e[m\e[32m                tiffOffset,\e[m
+\e[32m+\e[m\e[32m                dirOffset + 2 + 12 * i, // tag offset\e[m
+\e[32m+\e[m\e[32m                littleEndian\e[m
+\e[32m+\e[m\e[32m            );\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Return the offset to the next directory:\e[m
+\e[32m+\e[m\e[32m        return dataView.getUint32(dirEndOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifTag : function (dataView, tiffOffset, offset, littleEndian)\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tag = dataView.getUint16(offset, littleEndian);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.exif[tag] = this.getExifValue(\e[m
+\e[32m+\e[m\e[32m            dataView,\e[m
+\e[32m+\e[m\e[32m            tiffOffset,\e[m
+\e[32m+\e[m\e[32m            offset,\e[m
+\e[32m+\e[m\e[32m            dataView.getUint16(offset + 2, littleEndian), // tag type\e[m
+\e[32m+\e[m\e[32m            dataView.getUint32(offset + 4, littleEndian), // tag length\e[m
+\e[32m+\e[m\e[32m            littleEndian\e[m
+\e[32m+\e[m\e[32m        );\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],\e[m
+\e[32m+\e[m\e[32m            tagSize,\e[m
+\e[32m+\e[m\e[32m            dataOffset,\e[m
+\e[32m+\e[m\e[32m            values,\e[m
+\e[32m+\e[m\e[32m            i,\e[m
+\e[32m+\e[m\e[32m            str,\e[m
+\e[32m+\e[m\e[32m            c;\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        if (!tagType) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid tag type.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        tagSize = tagType.size * length;\e[m
+\e[32m+\e[m\e[32m        // Determine if the value is contained in the dataOffset bytes,\e[m
+\e[32m+\e[m\e[32m        // or if the value at the dataOffset is a pointer to the actual data:\e[m
+\e[32m+\e[m\e[32m        dataOffset = tagSize > 4 ?\e[m
+\e[32m+\e[m\e[32m                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);\e[m
+\e[32m+\e[m\e[32m        if (dataOffset + tagSize > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid data offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        if (length === 1) {\e[m
+\e[32m+\e[m\e[32m            return tagType.getValue(dataView, dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        values = [];\e[m
+\e[32m+\e[m\e[32m        for (i = 0; i < length; i += 1) {\e[m
+\e[32m+\e[m\e[32m            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (tagType.ascii) {\e[m
+\e[32m+\e[m\e[32m            str = '';\e[m
+\e[32m+\e[m\e[32m            // Concatenate the chars:\e[m
+\e[32m+\e[m\e[32m            for (i = 0; i < values.length; i += 1) {\e[m
+\e[32m+\e[m\e[32m                c = values[i];\e[m
+\e[32m+\e[m\e[32m                // Ignore the terminating NULL byte(s):\e[m
+\e[32m+\e[m\e[32m                if (c === '\u0000') {\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m                str += c;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m            return str;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        return values;\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m});\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.apply(Roo.dialog.UploadCropbox, {\e[m
+\e[32m+\e[m\e[32m    tags : {\e[m
+\e[32m+\e[m\e[32m        'Orientation': 0x0112\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    Orientation: {\e[m
+\e[32m+\e[m\e[32m            1: 0, //'top-left',\e[m
+\e[32m+\e[m\e[32m//            2: 'top-right',\e[m
+\e[32m+\e[m\e[32m            3: 180, //'bottom-right',\e[m
+\e[32m+\e[m\e[32m//            4: 'bottom-left',\e[m
+\e[32m+\e[m\e[32m//            5: 'left-top',\e[m
+\e[32m+\e[m\e[32m            6: 90, //'right-top',\e[m
+\e[32m+\e[m\e[32m//            7: 'right-bottom',\e[m
+\e[32m+\e[m\e[32m            8: 270 //'left-bottom'\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    exifTagTypes : {\e[m
+\e[32m+\e[m\e[32m        // byte, 8-bit unsigned int:\e[m
+\e[32m+\e[m\e[32m        1: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint8(dataOffset);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 1\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // ascii, 8-bit byte:\e[m
+\e[32m+\e[m\e[32m        2: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset) {\e[m
+\e[32m+\e[m\e[32m                return String.fromCharCode(dataView.getUint8(dataOffset));\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 1,\e[m
+\e[32m+\e[m\e[32m            ascii: true\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // short, 16 bit int:\e[m
+\e[32m+\e[m\e[32m        3: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint16(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 2\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // long, 32 bit int:\e[m
+\e[32m+\e[m\e[32m        4: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint32(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 4\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // rational = two long values, first is numerator, second is denominator:\e[m
+\e[32m+\e[m\e[32m        5: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint32(dataOffset, littleEndian) /\e[m
+\e[32m+\e[m\e[32m                    dataView.getUint32(dataOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 8\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // slong, 32 bit signed int:\e[m
+\e[32m+\e[m\e[32m        9: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getInt32(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 4\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // srational, two slongs, first is numerator, second is denominator:\e[m
+\e[32m+\e[m\e[32m        10: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getInt32(dataOffset, littleEndian) /\e[m
+\e[32m+\e[m\e[32m                    dataView.getInt32(dataOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 8\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    footer : {\e[m
+\e[32m+\e[m\e[32m        STANDARD : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-picture',\e[m
+\e[32m+\e[m\e[32m                action : 'picture',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-picture-o"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ],\e[m
+\e[32m+\e[m\e[32m        DOCUMENT : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-download',\e[m
+\e[32m+\e[m\e[32m                action : 'download',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-download"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-crop',\e[m
+\e[32m+\e[m\e[32m                action : 'crop',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-crop"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-trash',\e[m
+\e[32m+\e[m\e[32m                action : 'trash',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-trash"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ],\e[m
+\e[32m+\e[m\e[32m        ROTATOR : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ]\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[32m});\e[m
+\e[1mdiff --git a/roojs-ui-debug.js b/roojs-ui-debug.js\e[m
+\e[1mindex 4458d38422..4cc277300f 100644\e[m
+\e[1m--- a/roojs-ui-debug.js\e[m
+\e[1m+++ b/roojs-ui-debug.js\e[m
+\e[36m@@ -35922,7 +35922,6 @@\e[m \e[mRoo.LayoutStateManager.prototype = {\e[m
+  */\e[m
+ Roo.ContentPanel = function(el, config, content){\e[m
+     \e[m
+\e[31m-     \e[m
+     /*\e[m
+     if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory\e[m
+         config = el;\e[m
+\e[36m@@ -36306,6 +36305,14 @@\e[m \e[mlayout.addxtype({\e[m
+      */\e[m
+     \e[m
+     addxtype : function(cfg) {\e[m
+\e[32m+\e[m\e[32m        if(cfg.xtype.match(/^UploadCropbox$/)) {\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            this.cropbox = new Roo.factory(cfg);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            this.cropbox.render(this.el);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            return this.cropbox;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+         // add form..\e[m
+         if (cfg.xtype.match(/^Form$/)) {\e[m
+             \e[m
+\e[36m@@ -43558,4 +43565,1795 @@\e[m \e[mRoo.extend(Roo.XTemplate, Roo.Template, {\e[m
+ Roo.XTemplate.from = function(el){\e[m
+     el = Roo.getDom(el);\e[m
+     return new Roo.XTemplate(el.value || el.innerHTML);\e[m
+\e[31m-};\e[m
+\ No newline at end of file\e[m
+\e[32m+\e[m\e[32m};Roo.dialog = {};\e[m
+\e[32m+\e[m\e[32m/*\e[m
+\e[32m+\e[m\e[32m* Licence: LGPL\e[m
+\e[32m+\e[m\e[32m*/\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m/**\e[m
+\e[32m+\e[m\e[32m * @class Roo.dialog.UploadCropbox\e[m
+\e[32m+\e[m\e[32m * @extends Roo.BoxComponent\e[m
+\e[32m+\e[m\e[32m * Dialog UploadCropbox class\e[m
+\e[32m+\e[m\e[32m * @cfg {String} emptyText show when image has been loaded\e[m
+\e[32m+\e[m\e[32m * @cfg {String} rotateNotify show when image too small to rotate\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} errorTimeout default 3000\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} minWidth default 300\e[m
+\e[32m+\e[m\e[32m * @cfg {Number} minHeight default 300\e[m
+\e[32m+\e[m\e[32m * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} isDocument (true|false) default false\e[m
+\e[32m+\e[m\e[32m * @cfg {String} url action url\e[m
+\e[32m+\e[m\e[32m * @cfg {String} paramName default 'imageUpload'\e[m
+\e[32m+\e[m\e[32m * @cfg {String} method default POST\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} loadMask (true|false) default true\e[m
+\e[32m+\e[m\e[32m * @cfg {Boolean} loadingText default 'Loading...'\e[m
+\e[32m+\e[m\e[32m *\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m * @constructor\e[m
+\e[32m+\e[m\e[32m * Create a new UploadCropbox\e[m
+\e[32m+\e[m\e[32m * @param {Object} config The config object\e[m
+\e[32m+\e[m\e[32m */\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m Roo.dialog.UploadCropbox = function(config){\e[m
+\e[32m+\e[m\e[32m    console.log("Dialog UploadCropbox Constructor");\e[m
+\e[32m+\e[m\e[32m    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    this.addEvents({\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event beforeselectfile\e[m
+\e[32m+\e[m\e[32m         * Fire before select file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "beforeselectfile" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event initial\e[m
+\e[32m+\e[m\e[32m         * Fire after initEvent\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "initial" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event crop\e[m
+\e[32m+\e[m\e[32m         * Fire after initEvent\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} data\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "crop" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event prepare\e[m
+\e[32m+\e[m\e[32m         * Fire when preparing the file data\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} file\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "prepare" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event exception\e[m
+\e[32m+\e[m\e[32m         * Fire when get exception\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {XMLHttpRequest} xhr\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "exception" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event beforeloadcanvas\e[m
+\e[32m+\e[m\e[32m         * Fire before load the canvas\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} src\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "beforeloadcanvas" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event trash\e[m
+\e[32m+\e[m\e[32m         * Fire when trash image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "trash" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event download\e[m
+\e[32m+\e[m\e[32m         * Fire when download the image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "download" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event footerbuttonclick\e[m
+\e[32m+\e[m\e[32m         * Fire when footerbuttonclick\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} type\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "footerbuttonclick" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event resize\e[m
+\e[32m+\e[m\e[32m         * Fire when resize\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "resize" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event rotate\e[m
+\e[32m+\e[m\e[32m         * Fire when rotate the image\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {String} pos\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "rotate" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event inspect\e[m
+\e[32m+\e[m\e[32m         * Fire when inspect the file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} file\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "inspect" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event upload\e[m
+\e[32m+\e[m\e[32m         * Fire when xhr upload the file\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} data\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "upload" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event arrange\e[m
+\e[32m+\e[m\e[32m         * Fire when arrange the file data\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox} this\e[m
+\e[32m+\e[m\e[32m         * @param {Object} formData\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "arrange" : true,\e[m
+\e[32m+\e[m\e[32m        /**\e[m
+\e[32m+\e[m\e[32m         * @event loadcanvas\e[m
+\e[32m+\e[m\e[32m         * Fire after load the canvas\e[m
+\e[32m+\e[m\e[32m         * @param {Roo.dialog.UploadCropbox}\e[m
+\e[32m+\e[m\e[32m         * @param {Object} imgEl\e[m
+\e[32m+\e[m\e[32m         */\e[m
+\e[32m+\e[m\e[32m        "loadcanvas" : true\e[m
+\e[32m+\e[m\e[32m    });\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;\e[m
+\e[32m+\e[m\e[32m};\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    emptyText : 'Click to upload image',\e[m
+\e[32m+\e[m\e[32m    rotateNotify : 'Image is too small to rotate',\e[m
+\e[32m+\e[m\e[32m    errorTimeout : 3000,\e[m
+\e[32m+\e[m\e[32m    scale : 0,\e[m
+\e[32m+\e[m\e[32m    baseScale : 1,\e[m
+\e[32m+\e[m\e[32m    rotate : 0,\e[m
+\e[32m+\e[m\e[32m    dragable : false,\e[m
+\e[32m+\e[m\e[32m    pinching : false,\e[m
+\e[32m+\e[m\e[32m    mouseX : 0,\e[m
+\e[32m+\e[m\e[32m    mouseY : 0,\e[m
+\e[32m+\e[m\e[32m    cropData : false,\e[m
+\e[32m+\e[m\e[32m    minWidth : 300,\e[m
+\e[32m+\e[m\e[32m    minHeight : 300,\e[m
+\e[32m+\e[m\e[32m    file : false,\e[m
+\e[32m+\e[m\e[32m    exif : {},\e[m
+\e[32m+\e[m\e[32m    baseRotate : 1,\e[m
+\e[32m+\e[m\e[32m    cropType : 'image/jpeg',\e[m
+\e[32m+\e[m\e[32m    buttons : false,\e[m
+\e[32m+\e[m\e[32m    canvasLoaded : false,\e[m
+\e[32m+\e[m\e[32m    isDocument : false,\e[m
+\e[32m+\e[m\e[32m    method : 'POST',\e[m
+\e[32m+\e[m\e[32m    paramName : 'imageUpload',\e[m
+\e[32m+\e[m\e[32m    loadMask : true,\e[m
+\e[32m+\e[m\e[32m    loadingText : 'Loading...',\e[m
+\e[32m+\e[m\e[32m    maskEl : false,\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getAutoCreate : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var cfg = {\e[m
+\e[32m+\e[m\e[32m            tag : 'div',\e[m
+\e[32m+\e[m\e[32m            cls : 'roo-upload-cropbox',\e[m
+\e[32m+\e[m\e[32m            cn : [\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'input',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-selector',\e[m
+\e[32m+\e[m\e[32m                    type : 'file'\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'div',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-body',\e[m
+\e[32m+\e[m\e[32m                    style : 'cursor:pointer',\e[m
+\e[32m+\e[m\e[32m                    cn : [\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-preview'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-thumb'\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-empty-notify',\e[m
+\e[32m+\e[m\e[32m                            html : this.emptyText\e[m
+\e[32m+\e[m\e[32m                        },\e[m
+\e[32m+\e[m\e[32m                        {\e[m
+\e[32m+\e[m\e[32m                            tag : 'div',\e[m
+\e[32m+\e[m\e[32m                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',\e[m
+\e[32m+\e[m\e[32m                            html : this.rotateNotify\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[32m                    ]\e[m
+\e[32m+\e[m\e[32m                },\e[m
+\e[32m+\e[m\e[32m                {\e[m
+\e[32m+\e[m\e[32m                    tag : 'div',\e[m
+\e[32m+\e[m\e[32m                    cls : 'roo-upload-cropbox-footer',\e[m
+\e[32m+\e[m\e[32m                    cn : {\e[m
+\e[32m+\e[m\e[32m                        tag : 'div',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',\e[m
+\e[32m+\e[m\e[32m                        cn : []\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            ]\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return cfg;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRender : function(ct, position)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        console.log("On Render");\e[m
+\e[32m+\e[m\e[32m        console.log(this);\e[m
+\e[32m+\e[m\e[32m        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.el){\e[m
+\e[32m+\e[m\e[32m            if (this.el.attr('xtype')) {\e[m
+\e[32m+\e[m\e[32m                this.el.attr('xtypex', this.el.attr('xtype'));\e[m
+\e[32m+\e[m\e[32m                this.el.dom.removeAttribute('xtype');\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.initEvents();\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        else {\e[m
+\e[32m+\e[m\e[32m            var cfg = Roo.apply({},  this.getAutoCreate());\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            cfg.id = this.id || Roo.id();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if (this.cls) {\e[m
+\e[32m+\e[m\e[32m                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if (this.style) { // fixme needs to support more complex style data.\e[m
+\e[32m+\e[m\e[32m                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.el = ct.createChild(cfg, position);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.initEvents();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (this.buttons.length) {\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            Roo.each(this.buttons, function(bb) {\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m            }, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl = this.el;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    initEvents : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.urlAPI = (window.createObjectURL && window) ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                (window.URL && URL.revokeObjectURL && URL) ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                                (window.webkitURL && webkitURL);\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();\e[m
+\e[32m+\e[m\e[32m        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();\e[m
+\e[32m+\e[m\e[32m        this.selectorEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();\e[m
+\e[32m+\e[m\e[32m        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();\e[m
+\e[32m+\e[m\e[32m        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.errorEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();\e[m
+\e[32m+\e[m\e[32m        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';\e[m
+\e[32m+\e[m\e[32m        this.footerEl.hide();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.bind();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.resize();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('initial', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m    bind : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        window.addEventListener("resize", function() { _this.resize(); } );\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.bodyEl.on('click', this.beforeSelectFile, this);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(Roo.isTouch){\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchstart', this.onTouchStart, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchmove', this.onTouchMove, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('touchend', this.onTouchEnd, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!Roo.isTouch){\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('mousedown', this.onMouseDown, this);\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on('mousemove', this.onMouseMove, this);\e[m
+\e[32m+\e[m\e[32m            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';\e[m
+\e[32m+\e[m\e[32m            this.bodyEl.on(mousewheel, this.onMouseWheel, this);\e[m
+\e[32m+\e[m\e[32m            Roo.get(document).on('mouseup', this.onMouseUp, this);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.selectorEl.on('change', this.onFileSelected, this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    reset : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        this.scale = 0;\e[m
+\e[32m+\e[m\e[32m        this.baseScale = 1;\e[m
+\e[32m+\e[m\e[32m        this.rotate = 0;\e[m
+\e[32m+\e[m\e[32m        this.baseRotate = 1;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[32m        this.mouseX = 0;\e[m
+\e[32m+\e[m\e[32m        this.mouseY = 0;\e[m
+\e[32m+\e[m\e[32m        this.cropData = false;\e[m
+\e[32m+\e[m\e[32m        this.notifyEl.dom.innerHTML = this.emptyText;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        // this.selectorEl.dom.value = '';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    resize : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('resize', this) != false){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onFooterButtonClick : function(e, el, o, type)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        switch (type) {\e[m
+\e[32m+\e[m\e[32m            case 'rotate-left' :\e[m
+\e[32m+\e[m\e[32m                this.onRotateLeft(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'rotate-right' :\e[m
+\e[32m+\e[m\e[32m                this.onRotateRight(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'picture' :\e[m
+\e[32m+\e[m\e[32m                this.beforeSelectFile(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'trash' :\e[m
+\e[32m+\e[m\e[32m                this.trash(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'crop' :\e[m
+\e[32m+\e[m\e[32m                this.crop(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 'download' :\e[m
+\e[32m+\e[m\e[32m                this.download(e);\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('footerbuttonclick', this, type);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    beforeSelectFile : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        e.preventDefault();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('beforeselectfile', this) != false){\e[m
+\e[32m+\e[m\e[32m            this.selectorEl.dom.click();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onFileSelected : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        e.preventDefault();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var file = this.selectorEl.dom.files[0];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('inspect', this, file) != false){\e[m
+\e[32m+\e[m\e[32m            this.prepare(file);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    trash : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.fireEvent('trash', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    download : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.fireEvent('download', this);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    loadCanvas : function(src)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('beforeloadcanvas', this, src) != false){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.reset();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl = document.createElement('img');\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var _this = this;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.imageEl.src = src;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onLoadCanvas : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;\e[m
+\e[32m+\e[m\e[32m        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            this.bodyEl.un('click', this.beforeSelectFile, this);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.notifyEl.hide();\e[m
+\e[32m+\e[m\e[32m            this.thumbEl.show();\e[m
+\e[32m+\e[m\e[32m            this.footerEl.show();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.baseRotateLevel();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m                this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.baseScaleLevel();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.draw();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.resize();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.canvasLoaded = true;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setCanvasPosition : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(!this.canvasEl){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);\e[m
+\e[32m+\e[m\e[32m        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.setLeft(pw);\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setTop(ph);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseDown : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.dragable = true;\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[32m            this.dragable = false;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseMove : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (!this.dragable){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var minX = Math.ceil(this.thumbEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m        var minY = Math.ceil(this.thumbEl.getTop(true));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);\e[m
+\e[32m+\e[m\e[32m        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        x = x - this.mouseX;\e[m
+\e[32m+\e[m\e[32m        y = y - this.mouseY;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var bgX = Math.ceil(x + this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m        var bgY = Math.ceil(y + this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        bgX = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX);\e[m
+\e[32m+\e[m\e[32m        bgY = (minY < bgY) ? minY : ((maxY > bgY) ? maxY : bgY);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.setLeft(bgX);\e[m
+\e[32m+\e[m\e[32m        this.previewEl.setTop(bgY);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();\e[m
+\e[32m+\e[m\e[32m        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseUp : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onMouseWheel : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        e.stopEvent();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    zoomable : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.minWidth < this.minHeight){\e[m
+\e[32m+\e[m\e[32m            minScale = this.thumbEl.getHeight() / this.minHeight;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);\e[m
+\e[32m+\e[m\e[32m        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 0 || this.rotate == 180) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight ||\e[m
+\e[32m+\e[m\e[32m                    (width < this.minWidth && height < this.minHeight)\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 90 || this.rotate == 270) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight ||\e[m
+\e[32m+\e[m\e[32m                    (width < this.minHeight && height < this.minWidth)\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                !this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 0 || this.rotate == 180) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width < this.minWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height < this.minHeight ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                !this.isDocument &&\e[m
+\e[32m+\e[m\e[32m                (this.rotate == 90 || this.rotate == 270) &&\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                (\e[m
+\e[32m+\e[m\e[32m                    width < this.minHeight ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    width > this.imageEl.OriginWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height < this.minWidth ||\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                    height > this.imageEl.OriginHeight\e[m
+\e[32m+\e[m\e[32m                )\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return true;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateLeft : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            while (this.getScaleLevel() < minScale){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                this.scale = this.scale + 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()\e[m
+\e[32m+\e[m\e[32m                ){\e[m
+\e[32m+\e[m\e[32m                    continue;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                this.draw();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.onRotateFail();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('rotate', this, 'left');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateRight : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var minScale = this.thumbEl.getWidth() / this.minWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            while (this.getScaleLevel() < minScale){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                this.scale = this.scale + 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||\e[m
+\e[32m+\e[m\e[32m                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()\e[m
+\e[32m+\e[m\e[32m                ){\e[m
+\e[32m+\e[m\e[32m                    continue;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                this.draw();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.onRotateFail();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return false;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxSize();\e[m
+\e[32m+\e[m\e[32m            this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32m            this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('rotate', this, 'right');\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onRotateFail : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.errorEl.show(true);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    draw : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.previewEl.dom.innerHTML = '';\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var canvasEl = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var contextEl = canvasEl.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m        var center = this.imageEl.OriginWidth / 2;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m            center = this.imageEl.OriginHeight / 2;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        contextEl.translate(center, center);\e[m
+\e[32m+\e[m\e[32m        contextEl.rotate(this.rotate * Math.PI / 180);\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.canvasEl = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.contextEl = this.canvasEl.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        switch (this.rotate) {\e[m
+\e[32m+\e[m\e[32m            case 0 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 90 :\e[m\e[41m \e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 180 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 270 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32m                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.previewEl.appendChild(this.canvasEl);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    crop : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var imageCanvas = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var imageContext = imageCanvas.getContext("2d");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var center = imageCanvas.width / 2;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.translate(center, center);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.rotate(this.rotate * Math.PI / 180);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var canvas = document.createElement("canvas");\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var context = canvas.getContext("2d");\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m        canvas.width = this.minWidth;\e[m
+\e[32m+\e[m\e[32m        canvas.height = this.minHeight;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        switch (this.rotate) {\e[m
+\e[32m+\e[m\e[32m            case 0 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 90 :\e[m\e[41m \e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 180 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32m                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            case 270 :\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var targetWidth = this.minWidth - 2 * x;\e[m
+\e[32m+\e[m\e[32m                var targetHeight = this.minHeight - 2 * y;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var scale = 1;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if((x == 0 && y == 0) || (x == 0 && y > 0)){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y == 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(x > 0 && y > 0){\e[m
+\e[32m+\e[m\e[32m                    scale = targetWidth / width;\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                    if(width < height){\e[m
+\e[32m+\e[m\e[32m                        scale = targetHeight / height;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.scale(scale, scale);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32m                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32m                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m            default :\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m                break;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.cropData = canvas.toDataURL(this.cropType);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('crop', this, this.cropData) !== false){\e[m
+\e[32m+\e[m\e[32m            this.process(this.file, this.cropData);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setThumbBoxSize : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var width, height;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument && typeof(this.imageEl) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);\e[m
+\e[32m+\e[m\e[32m            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            this.minWidth = width;\e[m
+\e[32m+\e[m\e[32m            this.minHeight = height;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.rotate == 90 || this.rotate == 270){\e[m
+\e[32m+\e[m\e[32m                this.minWidth = height;\e[m
+\e[32m+\e[m\e[32m                this.minHeight = width;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        height = 300;\e[m
+\e[32m+\e[m\e[32m        width = Math.ceil(this.minWidth * height / this.minHeight);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.minWidth > this.minHeight){\e[m
+\e[32m+\e[m\e[32m            width = 300;\e[m
+\e[32m+\e[m\e[32m            height = Math.ceil(this.minHeight * width / this.minWidth);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setStyle({\e[m
+\e[32m+\e[m\e[32m            width : width + 'px',\e[m
+\e[32m+\e[m\e[32m            height : height + 'px'\e[m
+\e[32m+\e[m\e[32m        });\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    setThumbBoxPosition : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );\e[m
+\e[32m+\e[m\e[32m        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setLeft(x);\e[m
+\e[32m+\e[m\e[32m        this.thumbEl.setTop(y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    baseRotateLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.baseRotate = 1;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(\e[m
+\e[32m+\e[m\e[32m                typeof(this.exif) != 'undefined' &&\e[m
+\e[32m+\e[m\e[32m                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&\e[m
+\e[32m+\e[m\e[32m                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1\e[m
+\e[32m+\e[m\e[32m        ){\e[m
+\e[32m+\e[m\e[32m            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    baseScaleLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var width, height;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.isDocument){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.baseRotate == 6 || this.baseRotate == 8){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                    width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                    this.baseScale = width / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.baseRotate == 6 || this.baseRotate == 8){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            width = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = width / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[32m                height = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){\e[m
+\e[32m+\e[m\e[32m                    width = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m                    this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m        this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){\e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            height = this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32m            this.baseScale = height / this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){\e[m
+\e[32m+\e[m\e[32m                width = this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32m                this.baseScale = width / this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        return;\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getScaleLevel : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        return this.baseScale * Math.pow(1.1, this.scale);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchStart : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.canvasLoaded){\e[m
+\e[32m+\e[m\e[32m            this.beforeSelectFile(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var touches = e.browserEvent.touches;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!touches){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(touches.length == 1){\e[m
+\e[32m+\e[m\e[32m            this.onMouseDown(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(touches.length != 2){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var coords = [];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for(var i = 0, finger; finger = touches[i]; i++){\e[m
+\e[32m+\e[m\e[32m            coords.push(finger.pageX, finger.pageY);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Math.pow(coords[0] - coords[2], 2);\e[m
+\e[32m+\e[m\e[32m        var y = Math.pow(coords[1] - coords[3], 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startDistance = Math.sqrt(x + y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.startScale = this.scale;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.pinching = true;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchMove : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(!this.pinching && !this.dragable){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var touches = e.browserEvent.touches;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!touches){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.dragable){\e[m
+\e[32m+\e[m\e[32m            this.onMouseMove(e);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var coords = [];\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for(var i = 0, finger; finger = touches[i]; i++){\e[m
+\e[32m+\e[m\e[32m            coords.push(finger.pageX, finger.pageY);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var x = Math.pow(coords[0] - coords[2], 2);\e[m
+\e[32m+\e[m\e[32m        var y = Math.pow(coords[1] - coords[3], 2);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.endDistance = Math.sqrt(x + y);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!this.zoomable()){\e[m
+\e[32m+\e[m\e[32m            this.scale = this.startScale;\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.draw();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    onTouchEnd : function(e)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        this.pinching = false;\e[m
+\e[32m+\e[m\e[32m        this.dragable = false;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    process : function(file, crop)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.mask(this.loadingText);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr = new XMLHttpRequest();\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        file.xhr = this.xhr;\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        this.xhr.open(this.method, this.url, true);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var headers = {\e[m
+\e[32m+\e[m\e[32m            "Accept": "application/json",\e[m
+\e[32m+\e[m\e[32m            "Cache-Control": "no-cache",\e[m
+\e[32m+\e[m\e[32m            "X-Requested-With": "XMLHttpRequest"\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        for (var headerName in headers) {\e[m
+\e[32m+\e[m\e[32m            var headerValue = headers[headerName];\e[m
+\e[32m+\e[m\e[32m            if (headerValue) {\e[m
+\e[32m+\e[m\e[32m                this.xhr.setRequestHeader(headerName, headerValue);\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr.onload = function()\e[m
+\e[32m+\e[m\e[32m        {\e[m
+\e[32m+\e[m\e[32m            _this.xhrOnLoad(_this.xhr);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.xhr.onerror = function()\e[m
+\e[32m+\e[m\e[32m        {\e[m
+\e[32m+\e[m\e[32m            _this.xhrOnError(_this.xhr);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var formData = new FormData();\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        formData.append('returnHTML', 'NO');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(crop){\e[m
+\e[32m+\e[m\e[32m            formData.append('crop', crop);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file) != 'undefined' && (typeof(file.id) == 'undefined' || file.id * 1 < 1)){\e[m
+\e[32m+\e[m\e[32m            formData.append(this.paramName, file, file.name);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file.filename) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            formData.append('filename', file.filename);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file.mimetype) != 'undefined'){\e[m
+\e[32m+\e[m\e[32m            formData.append('mimetype', file.mimetype);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('arrange', this, formData) != false){\e[m
+\e[32m+\e[m\e[32m            this.xhr.send(formData);\e[m
+\e[32m+\e[m\e[32m        };\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    xhrOnLoad : function(xhr)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (xhr.readyState !== 4) {\e[m
+\e[32m+\e[m\e[32m            this.fireEvent('exception', this, xhr);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!response.success){\e[m
+\e[32m+\e[m\e[32m            this.fireEvent('exception', this, xhr);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.fireEvent('upload', this, response);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    xhrOnError : function()\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.unmask();\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        Roo.log('xhr on error');\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var response = Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[41m          \e[m
+\e[32m+\e[m\e[32m        Roo.log(response);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    prepare : function(file)\e[m
+\e[32m+\e[m\e[32m    {\e[m\e[41m   \e[m
+\e[32m+\e[m\e[32m        if(this.loadMask){\e[m
+\e[32m+\e[m\e[32m            this.maskEl.mask(this.loadingText);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.file = false;\e[m
+\e[32m+\e[m\e[32m        this.exif = {};\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(typeof(file) === 'string'){\e[m
+\e[32m+\e[m\e[32m            this.loadCanvas(file);\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(!file || !this.urlAPI){\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.file = file;\e[m
+\e[32m+\e[m\e[32m        this.cropType = file.type;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        var _this = this;\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if(this.fireEvent('prepare', this, this.file) != false){\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            var reader = new FileReader();\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            reader.onload = function (e) {\e[m
+\e[32m+\e[m\e[32m                if (e.target.error) {\e[m
+\e[32m+\e[m\e[32m                    Roo.log(e.target.error);\e[m
+\e[32m+\e[m\e[32m                    return;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var buffer = e.target.result,\e[m
+\e[32m+\e[m\e[32m                    dataView = new DataView(buffer),\e[m
+\e[32m+\e[m\e[32m                    offset = 2,\e[m
+\e[32m+\e[m\e[32m                    maxOffset = dataView.byteLength - 4,\e[m
+\e[32m+\e[m\e[32m                    markerBytes,\e[m
+\e[32m+\e[m\e[32m                    markerLength;\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                if (dataView.getUint16(0) === 0xffd8) {\e[m
+\e[32m+\e[m\e[32m                    while (offset < maxOffset) {\e[m
+\e[32m+\e[m\e[32m                        markerBytes = dataView.getUint16(offset);\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {\e[m
+\e[32m+\e[m\e[32m                            markerLength = dataView.getUint16(offset + 2) + 2;\e[m
+\e[32m+\e[m\e[32m                            if (offset + markerLength > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m                                Roo.log('Invalid meta data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32m                                break;\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            if(markerBytes == 0xffe1){\e[m
+\e[32m+\e[m\e[32m                                _this.parseExifData(\e[m
+\e[32m+\e[m\e[32m                                    dataView,\e[m
+\e[32m+\e[m\e[32m                                    offset,\e[m
+\e[32m+\e[m\e[32m                                    markerLength\e[m
+\e[32m+\e[m\e[32m                                );\e[m
+\e[32m+\e[m\e[32m                            }\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            offset += markerLength;\e[m
+\e[32m+\e[m\e[41m                            \e[m
+\e[32m+\e[m\e[32m                            continue;\e[m
+\e[32m+\e[m\e[32m                        }\e[m
+\e[32m+\e[m\e[41m                        \e[m
+\e[32m+\e[m\e[32m                        break;\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[41m                    \e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                var url = _this.urlAPI.createObjectURL(_this.file);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                _this.loadCanvas(url);\e[m
+\e[32m+\e[m\e[41m                \e[m
+\e[32m+\e[m\e[32m                return;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m            reader.readAsArrayBuffer(this.file);\e[m
+\e[32m+\e[m\e[41m            \e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifData : function(dataView, offset, length)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tiffOffset = offset + 10,\e[m
+\e[32m+\e[m\e[32m            littleEndian,\e[m
+\e[32m+\e[m\e[32m            dirOffset;\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint32(offset + 4) !== 0x45786966) {\e[m
+\e[32m+\e[m\e[32m            // No Exif data, might be XMP data instead\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        // Check for the ASCII code for "Exif" (0x45786966):\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint32(offset + 4) !== 0x45786966) {\e[m
+\e[32m+\e[m\e[32m            // No Exif data, might be XMP data instead\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        if (tiffOffset + 8 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check for the two null bytes:\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint16(offset + 8) !== 0x0000) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Missing byte alignment offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check the byte alignment:\e[m
+\e[32m+\e[m\e[32m        switch (dataView.getUint16(tiffOffset)) {\e[m
+\e[32m+\e[m\e[32m        case 0x4949:\e[m
+\e[32m+\e[m\e[32m            littleEndian = true;\e[m
+\e[32m+\e[m\e[32m            break;\e[m
+\e[32m+\e[m\e[32m        case 0x4D4D:\e[m
+\e[32m+\e[m\e[32m            littleEndian = false;\e[m
+\e[32m+\e[m\e[32m            break;\e[m
+\e[32m+\e[m\e[32m        default:\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid byte alignment marker.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Check for the TIFF tag marker (0x002A):\e[m
+\e[32m+\e[m\e[32m        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Missing TIFF marker.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\e[m
+\e[32m+\e[m\e[32m        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.parseExifTags(\e[m
+\e[32m+\e[m\e[32m            dataView,\e[m
+\e[32m+\e[m\e[32m            tiffOffset,\e[m
+\e[32m+\e[m\e[32m            tiffOffset + dirOffset,\e[m
+\e[32m+\e[m\e[32m            littleEndian\e[m
+\e[32m+\e[m\e[32m        );\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tagsNumber,\e[m
+\e[32m+\e[m\e[32m            dirEndOffset,\e[m
+\e[32m+\e[m\e[32m            i;\e[m
+\e[32m+\e[m\e[32m        if (dirOffset + 6 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid directory offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        tagsNumber = dataView.getUint16(dirOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;\e[m
+\e[32m+\e[m\e[32m        if (dirEndOffset + 4 > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid directory size.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        for (i = 0; i < tagsNumber; i += 1) {\e[m
+\e[32m+\e[m\e[32m            this.parseExifTag(\e[m
+\e[32m+\e[m\e[32m                dataView,\e[m
+\e[32m+\e[m\e[32m                tiffOffset,\e[m
+\e[32m+\e[m\e[32m                dirOffset + 2 + 12 * i, // tag offset\e[m
+\e[32m+\e[m\e[32m                littleEndian\e[m
+\e[32m+\e[m\e[32m            );\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        // Return the offset to the next directory:\e[m
+\e[32m+\e[m\e[32m        return dataView.getUint32(dirEndOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    parseExifTag : function (dataView, tiffOffset, offset, littleEndian)\e[m\e[41m \e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tag = dataView.getUint16(offset, littleEndian);\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        this.exif[tag] = this.getExifValue(\e[m
+\e[32m+\e[m\e[32m            dataView,\e[m
+\e[32m+\e[m\e[32m            tiffOffset,\e[m
+\e[32m+\e[m\e[32m            offset,\e[m
+\e[32m+\e[m\e[32m            dataView.getUint16(offset + 2, littleEndian), // tag type\e[m
+\e[32m+\e[m\e[32m            dataView.getUint32(offset + 4, littleEndian), // tag length\e[m
+\e[32m+\e[m\e[32m            littleEndian\e[m
+\e[32m+\e[m\e[32m        );\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)\e[m
+\e[32m+\e[m\e[32m    {\e[m
+\e[32m+\e[m\e[32m        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],\e[m
+\e[32m+\e[m\e[32m            tagSize,\e[m
+\e[32m+\e[m\e[32m            dataOffset,\e[m
+\e[32m+\e[m\e[32m            values,\e[m
+\e[32m+\e[m\e[32m            i,\e[m
+\e[32m+\e[m\e[32m            str,\e[m
+\e[32m+\e[m\e[32m            c;\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m        if (!tagType) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid tag type.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        tagSize = tagType.size * length;\e[m
+\e[32m+\e[m\e[32m        // Determine if the value is contained in the dataOffset bytes,\e[m
+\e[32m+\e[m\e[32m        // or if the value at the dataOffset is a pointer to the actual data:\e[m
+\e[32m+\e[m\e[32m        dataOffset = tagSize > 4 ?\e[m
+\e[32m+\e[m\e[32m                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);\e[m
+\e[32m+\e[m\e[32m        if (dataOffset + tagSize > dataView.byteLength) {\e[m
+\e[32m+\e[m\e[32m            Roo.log('Invalid Exif data: Invalid data offset.');\e[m
+\e[32m+\e[m\e[32m            return;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        if (length === 1) {\e[m
+\e[32m+\e[m\e[32m            return tagType.getValue(dataView, dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        values = [];\e[m
+\e[32m+\e[m\e[32m        for (i = 0; i < length; i += 1) {\e[m
+\e[32m+\e[m\e[32m            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[41m        \e[m
+\e[32m+\e[m\e[32m        if (tagType.ascii) {\e[m
+\e[32m+\e[m\e[32m            str = '';\e[m
+\e[32m+\e[m\e[32m            // Concatenate the chars:\e[m
+\e[32m+\e[m\e[32m            for (i = 0; i < values.length; i += 1) {\e[m
+\e[32m+\e[m\e[32m                c = values[i];\e[m
+\e[32m+\e[m\e[32m                // Ignore the terminating NULL byte(s):\e[m
+\e[32m+\e[m\e[32m                if (c === '\u0000') {\e[m
+\e[32m+\e[m\e[32m                    break;\e[m
+\e[32m+\e[m\e[32m                }\e[m
+\e[32m+\e[m\e[32m                str += c;\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m            return str;\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m        return values;\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m});\e[m
+\e[32m+\e[m
+\e[32m+\e[m\e[32mRoo.apply(Roo.dialog.UploadCropbox, {\e[m
+\e[32m+\e[m\e[32m    tags : {\e[m
+\e[32m+\e[m\e[32m        'Orientation': 0x0112\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    Orientation: {\e[m
+\e[32m+\e[m\e[32m            1: 0, //'top-left',\e[m
+\e[32m+\e[m\e[32m//            2: 'top-right',\e[m
+\e[32m+\e[m\e[32m            3: 180, //'bottom-right',\e[m
+\e[32m+\e[m\e[32m//            4: 'bottom-left',\e[m
+\e[32m+\e[m\e[32m//            5: 'left-top',\e[m
+\e[32m+\e[m\e[32m            6: 90, //'right-top',\e[m
+\e[32m+\e[m\e[32m//            7: 'right-bottom',\e[m
+\e[32m+\e[m\e[32m            8: 270 //'left-bottom'\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    exifTagTypes : {\e[m
+\e[32m+\e[m\e[32m        // byte, 8-bit unsigned int:\e[m
+\e[32m+\e[m\e[32m        1: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint8(dataOffset);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 1\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // ascii, 8-bit byte:\e[m
+\e[32m+\e[m\e[32m        2: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset) {\e[m
+\e[32m+\e[m\e[32m                return String.fromCharCode(dataView.getUint8(dataOffset));\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 1,\e[m
+\e[32m+\e[m\e[32m            ascii: true\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // short, 16 bit int:\e[m
+\e[32m+\e[m\e[32m        3: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint16(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 2\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // long, 32 bit int:\e[m
+\e[32m+\e[m\e[32m        4: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint32(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 4\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // rational = two long values, first is numerator, second is denominator:\e[m
+\e[32m+\e[m\e[32m        5: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getUint32(dataOffset, littleEndian) /\e[m
+\e[32m+\e[m\e[32m                    dataView.getUint32(dataOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 8\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // slong, 32 bit signed int:\e[m
+\e[32m+\e[m\e[32m        9: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getInt32(dataOffset, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 4\e[m
+\e[32m+\e[m\e[32m        },\e[m
+\e[32m+\e[m\e[32m        // srational, two slongs, first is numerator, second is denominator:\e[m
+\e[32m+\e[m\e[32m        10: {\e[m
+\e[32m+\e[m\e[32m            getValue: function (dataView, dataOffset, littleEndian) {\e[m
+\e[32m+\e[m\e[32m                return dataView.getInt32(dataOffset, littleEndian) /\e[m
+\e[32m+\e[m\e[32m                    dataView.getInt32(dataOffset + 4, littleEndian);\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            size: 8\e[m
+\e[32m+\e[m\e[32m        }\e[m
+\e[32m+\e[m\e[32m    },\e[m
+\e[32m+\e[m\e[41m    \e[m
+\e[32m+\e[m\e[32m    footer : {\e[m
+\e[32m+\e[m\e[32m        STANDARD : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-picture',\e[m
+\e[32m+\e[m\e[32m                action : 'picture',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-picture-o"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ],\e[m
+\e[32m+\e[m\e[32m        DOCUMENT : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-download',\e[m
+\e[32m+\e[m\e[32m                action : 'download',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-download"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-crop',\e[m
+\e[32m+\e[m\e[32m                action : 'crop',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-crop"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-trash',\e[m
+\e[32m+\e[m\e[32m                action : 'trash',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-trash"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ],\e[m
+\e[32m+\e[m\e[32m        ROTATOR : [\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-left',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-left',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-undo"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            },\e[m
+\e[32m+\e[m\e[32m            {\e[m
+\e[32m+\e[m\e[32m                tag : 'div',\e[m
+\e[32m+\e[m\e[32m                cls : 'btn-group roo-upload-cropbox-rotate-right',\e[m
+\e[32m+\e[m\e[32m                action : 'rotate-right',\e[m
+\e[32m+\e[m\e[32m                cn : [\e[m
+\e[32m+\e[m\e[32m                    {\e[m
+\e[32m+\e[m\e[32m                        tag : 'button',\e[m
+\e[32m+\e[m\e[32m                        cls : 'btn btn-default',\e[m
+\e[32m+\e[m\e[32m                        html : '<i class="fa fa-repeat"></i>'\e[m
+\e[32m+\e[m\e[32m                    }\e[m
+\e[32m+\e[m\e[32m                ]\e[m
+\e[32m+\e[m\e[32m            }\e[m
+\e[32m+\e[m\e[32m        ]\e[m
+\e[32m+\e[m\e[32m    }\e[m
+\e[32m+\e[m\e[32m});\e[m
+\e[1mdiff --git a/roojs-ui.js b/roojs-ui.js\e[m
+\e[1mindex 98443d0ddf..0cc67d83a4 100644\e[m
+\e[1m--- a/roojs-ui.js\e[m
+\e[1m+++ b/roojs-ui.js\e[m
+\e[36m@@ -1598,9 +1598,9 @@\e[m \e[mreturn this.el.getUpdateManager();},_handleRefresh:function(A,B,C){if(!C||!this.\e[m
+ te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B);\e[m
+ this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A);\e[m
+ }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();\e[m
+\e[31m-}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();\e[m
+\e[31m-this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,'');\e[m
+\e[31m-this.view=B;return B;}return false;}});\e[m
+\e[32m+\e[m\e[32m}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A);\e[m
+\e[32m+\e[m\e[32mthis.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));\e[m
+\e[32m+\e[m\e[32mvar B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}});\e[m
+ // Roo/GridPanel.js\e[m
+ Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B);\e[m
+ if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo);\e[m
+\e[36m@@ -1929,3 +1929,103 @@\e[m \e[mF.push("(typeof("+G+") == 'undefined')");});var H='(('+F.join(" || ")+") ? undef\e[m
+ }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){  with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){  with (values) { return ['"];\e[m
+ B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{}\e[m
+ );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);};\e[m
+\e[32m+\e[m\e[32m// Roo/dialog/namespace.js\e[m
+\e[32m+\e[m\e[32mRoo.dialog={};\e[m
+\e[32m+\e[m\e[32m// Roo/dialog/UploadCropbox.js\e[m
+\e[32m+\e[m\e[32mRoo.dialog.UploadCropbox=function(A){console.log("Dialog UploadCropbox Constructor");Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true}\e[m
+\e[32m+\e[m\e[32m);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,file:false,exif:{}\e[m
+\e[32m+\e[m\e[32m,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'}\e[m
+\e[32m+\e[m\e[32m,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){console.log("On Render");console.log(this);Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);\e[m
+\e[32m+\e[m\e[32mif(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;\e[m
+\e[32m+\e[m\e[32m}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style;}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);\e[m
+\e[32m+\e[m\e[32mC.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true));},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);\e[m
+\e[32m+\e[m\e[32mthis.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first();this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();\e[m
+\e[32m+\e[m\e[32mthis.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();\e[m
+\e[32m+\e[m\e[32mthis.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();\e[m
+\e[32m+\e[m\e[32mthis.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();\e[m
+\e[32m+\e[m\e[32m});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this);this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);\e[m
+\e[32m+\e[m\e[32mthis.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel';this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);\e[m
+\e[32m+\e[m\e[32m},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false;this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();\e[m
+\e[32m+\e[m\e[32mthis.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e);break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);\e[m
+\e[32m+\e[m\e[32mbreak;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A);},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();\e[m
+\e[32m+\e[m\e[32mif(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return;}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);\e[m
+\e[32m+\e[m\e[32m},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset();this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;\e[m
+\e[32m+\e[m\e[32mthis.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height;if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();\e[m
+\e[32m+\e[m\e[32mif(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition();this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);\e[m
+\e[32m+\e[m\e[32mvar ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2);this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.width<this.thumbEl.getWidth()||this.canvasEl.height<this.thumbEl.getHeight())){this.dragable=false;\e[m
+\e[32m+\e[m\e[32mreturn;}this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseMove:function(e){e.stopEvent();if(!this.canvasLoaded){return;}if(!this.dragable){return;}var A=Math.ceil(this.thumbEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32mvar B=Math.ceil(this.thumbEl.getTop(true));var C=Math.ceil(A+this.thumbEl.getWidth()-this.canvasEl.width);var D=Math.ceil(B+this.thumbEl.getHeight()-this.canvasEl.height);var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();\e[m
+\e[32m+\e[m\e[32mx=x-this.mouseX;y=y-this.mouseY;var E=Math.ceil(x+this.previewEl.getLeft(true));var F=Math.ceil(y+this.previewEl.getTop(true));E=(A<E)?A:((C>E)?C:E);F=(B<F)?B:((D>F)?D:F);this.previewEl.setLeft(E);this.previewEl.setTop(F);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();\e[m
+\e[32m+\e[m\e[32mthis.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent();this.startScale=this.scale;this.scale=(e.getWheelDelta()==1)?(this.scale+1):(this.scale-1);\e[m
+\e[32m+\e[m\e[32mif(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidth<this.minHeight){A=this.thumbEl.getHeight()/this.minHeight;}var B=Math.ceil(this.imageEl.OriginWidth*this.getScaleLevel()/A);\e[m
+\e[32m+\e[m\e[32mvar C=Math.ceil(this.imageEl.OriginHeight*this.getScaleLevel()/A);if(this.isDocument&&(this.rotate==0||this.rotate==180)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minWidth&&C<this.minHeight))){return false;}if(this.isDocument&&(this.rotate==90||this.rotate==270)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minHeight&&C<this.minWidth))){return false;\e[m
+\e[32m+\e[m\e[32m}if(!this.isDocument&&(this.rotate==0||this.rotate==180)&&(B<this.minWidth||B>this.imageEl.OriginWidth||C<this.minHeight||C>this.imageEl.OriginHeight)){return false;}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(B<this.minHeight||B>this.imageEl.OriginWidth||C<this.minWidth||C>this.imageEl.OriginHeight)){return false;\e[m
+\e[32m+\e[m\e[32m}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;\e[m
+\e[32m+\e[m\e[32m}this.rotate=(this.rotate<90)?270:this.rotate-90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate<90)?270:this.rotate-90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m}this.draw();this.fireEvent('rotate',this,'left');},onRotateRight:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;\e[m
+\e[32m+\e[m\e[32m}this.rotate=(this.rotate>180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas");\e[m
+\e[32m+\e[m\e[32mvar B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidth<this.imageEl.OriginHeight){A.width=this.imageEl.OriginHeight*this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32mA.height=this.imageEl.OriginHeight*this.getScaleLevel();C=this.imageEl.OriginHeight/2;}B.scale(this.getScaleLevel(),this.getScaleLevel());B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32mthis.canvasEl=document.createElement("canvas");this.contextEl=this.canvasEl.getContext("2d");switch(this.rotate){case 0:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;case 90:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();\e[m
+\e[32m+\e[m\e[32mif(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);\e[m
+\e[32m+\e[m\e[32mbreak;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition();\e[m
+\e[32m+\e[m\e[32m},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32mvar C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d");\e[m
+\e[32m+\e[m\e[32mD.width=this.minWidth;D.height=this.minHeight;switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32mvar sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;\e[m
+\e[32m+\e[m\e[32m}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[32msx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;\e[m
+\e[32m+\e[m\e[32m}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));\e[m
+\e[32m+\e[m\e[32msx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;\e[m
+\e[32m+\e[m\e[32mE.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());\e[m
+\e[32m+\e[m\e[32mvar H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/F;if(F<G){J=I/G;}}E.scale(J,J);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));\e[m
+\e[32m+\e[m\e[32mvar sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);\e[m
+\e[32m+\e[m\e[32mE.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType);if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight);\e[m
+\e[32m+\e[m\e[32mB=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=300;A=Math.ceil(this.minWidth*B/this.minHeight);\e[m
+\e[32m+\e[m\e[32mif(this.minWidth>this.minHeight){A=300;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2);var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);\e[m
+\e[32m+\e[m\e[32mthis.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];\e[m
+\e[32m+\e[m\e[32m}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();\e[m
+\e[32m+\e[m\e[32mthis.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getWidth()){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;\e[m
+\e[32m+\e[m\e[32m}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getHeight()){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginWidth;\e[m
+\e[32m+\e[m\e[32m}}return;}A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getHeight()){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getHeight();\e[m
+\e[32m+\e[m\e[32mthis.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;}}return;},getScaleLevel:function(){return this.baseScale*Math.pow(1.1,this.scale);\e[m
+\e[32m+\e[m\e[32m},onTouchStart:function(e){if(!this.canvasLoaded){this.beforeSelectFile(e);return;}var A=e.browserEvent.touches;if(!A){return;}if(A.length==1){this.onMouseDown(e);return;}if(A.length!=2){return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}\e[m
+\e[32m+\e[m\e[32mvar x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.startDistance=Math.sqrt(x+y);this.startScale=this.scale;this.pinching=true;this.dragable=false;},onTouchMove:function(e){if(!this.pinching&&!this.dragable){return;}var A=e.browserEvent.touches;if(!A){return;\e[m
+\e[32m+\e[m\e[32m}if(this.dragable){this.onMouseMove(e);return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.endDistance=Math.sqrt(x+y);this.scale=this.startScale+Math.floor(Math.log(this.endDistance/this.startDistance)/Math.log(1.1));\e[m
+\e[32m+\e[m\e[32mif(!this.zoomable()){this.scale=this.startScale;return;}this.draw();},onTouchEnd:function(e){this.pinching=false;this.dragable=false;},process:function(A,B){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.xhr=new XMLHttpRequest();A.xhr=this.xhr;\e[m
+\e[32m+\e[m\e[32mthis.xhr.open(this.method,this.url,true);var C={"Accept":"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"};for(var D in C){var E=C[D];if(E){this.xhr.setRequestHeader(D,E);}}var F=this;this.xhr.onload=function(){F.xhrOnLoad(F.xhr);\e[m
+\e[32m+\e[m\e[32m};this.xhr.onerror=function(){F.xhrOnError(F.xhr);};var G=new FormData();G.append('returnHTML','NO');if(B){G.append('crop',B);}if(typeof(A)!='undefined'&&(typeof(A.id)=='undefined'||A.id*1<1)){G.append(this.paramName,A,A.name);}if(typeof(A.filename)!='undefined'){G.append('filename',A.filename);\e[m
+\e[32m+\e[m\e[32m}if(typeof(A.mimetype)!='undefined'){G.append('mimetype',A.mimetype);}if(this.fireEvent('arrange',this,G)!=false){this.xhr.send(G);};},xhrOnLoad:function(A){if(this.loadMask){this.maskEl.unmask();}if(A.readyState!==4){this.fireEvent('exception',this,A);return;\e[m
+\e[32m+\e[m\e[32m}var B=Roo.decode(A.responseText);if(!B.success){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);this.fireEvent('upload',this,B);},xhrOnError:function(){if(this.loadMask){this.maskEl.unmask();}Roo.log('xhr on error');var A=Roo.decode(xhr.responseText);\e[m
+\e[32m+\e[m\e[32mRoo.log(A);},prepare:function(A){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.file=false;this.exif={};if(typeof(A)==='string'){this.loadCanvas(A);return;}if(!A||!this.urlAPI){return;}this.file=A;this.cropType=A.type;var B=this;if(this.fireEvent('prepare',this,this.file)!=false){var C=new FileReader();\e[m
+\e[32m+\e[m\e[32mC.onload=function(e){if(e.target.error){Roo.log(e.target.error);return;}var D=e.target.result,E=new DataView(D),F=2,G=E.byteLength-4,H,I;if(E.getUint16(0)===0xffd8){while(F<G){H=E.getUint16(F);if((H>=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');\e[m
+\e[32m+\e[m\e[32mbreak;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break;}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;\e[m
+\e[32m+\e[m\e[32m}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.');return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;\e[m
+\e[32m+\e[m\e[32mdefault:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return;}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;\e[m
+\e[32m+\e[m\e[32mif(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.');return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i<E;i+=1){this.parseExifTag(A,B,C+2+12*i,D);}return A.getUint32(F,D);\e[m
+\e[32m+\e[m\e[32m},parseExifTag:function(A,B,C,D){var E=A.getUint16(C,D);this.exif[E]=this.getExifValue(A,B,C,A.getUint16(C+2,D),A.getUint32(C+4,D),D);},getExifValue:function(A,B,C,D,E,F){var G=Roo.dialog.UploadCropbox.exifTagTypes[D],H,I,J,i,K,c;if(!G){Roo.log('Invalid Exif data: Invalid tag type.');\e[m
+\e[32m+\e[m\e[32mreturn;}H=G.size*E;I=H>4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.');return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i<E;i+=1){J[i]=G.getValue(A,I+i*G.size,F);}if(G.ascii){K='';for(i=0;i<J.length;\e[m
+\e[32m+\e[m\e[32mi+=1){c=J[i];if(c==='\u0000'){break;}K+=c;}return K;}return J;}});Roo.apply(Roo.dialog.UploadCropbox,{tags:{'Orientation':0x0112\e[m
+\e[32m+\e[m\e[32m},Orientation:{1:0,3:180,6:90,8:270},exifTagTypes:{1:{getValue:function(A,B){return A.getUint8(B);},size:1},2:{getValue:function(A,B){return String.fromCharCode(A.getUint8(B));\e[m
+\e[32m+\e[m\e[32m},size:1,ascii:true},3:{getValue:function(A,B,C){return A.getUint16(B,C);},size:2},4:{getValue:function(A,B,C){return A.getUint32(B,C);},size:4},5:{getValue:function(A,B,C){return A.getUint32(B,C)/A.getUint32(B+4,C);},size:8},9:{getValue:function(A,B,C){return A.getInt32(B,C);\e[m
+\e[32m+\e[m\e[32m},size:4},10:{getValue:function(A,B,C){return A.getInt32(B,C)/A.getInt32(B+4,C);},size:8}},footer:{STANDARD:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-picture-o"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}\e[m
+\e[32m+\e[m\e[32m]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-download"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-crop"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-trash"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}\e[m
+\e[32m+\e[m\e[32m]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}]}});\e[m
index 0984532..cc1b9d0 100644 (file)
@@ -41,7 +41,6 @@
  */
 Roo.ContentPanel = function(el, config, content){
     
-     
     /*
     if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory
         config = el;
@@ -425,6 +424,14 @@ layout.addxtype({
      */
     
     addxtype : function(cfg) {
+        if(cfg.xtype.match(/^UploadCropbox$/)) {
+
+            this.cropbox = new Roo.factory(cfg);
+
+            this.cropbox.render(this.el);
+
+            return this.cropbox;
+        }
         // add form..
         if (cfg.xtype.match(/^Form$/)) {
             
diff --git a/Roo/dialog/UploadCropbox.js b/Roo/dialog/UploadCropbox.js
new file mode 100644 (file)
index 0000000..1d43fef
--- /dev/null
@@ -0,0 +1,1800 @@
+
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.dialog.UploadCropbox
+ * @extends Roo.BoxComponent
+ * Dialog UploadCropbox class
+ * @cfg {String} emptyText show when image has been loaded
+ * @cfg {String} rotateNotify show when image too small to rotate
+ * @cfg {Number} errorTimeout default 3000
+ * @cfg {Number} minWidth default 300
+ * @cfg {Number} minHeight default 300
+ * @cfg {Number} outputMaxWidth default 1200
+ * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']
+ * @cfg {Boolean} isDocument (true|false) default false
+ * @cfg {String} url action url
+ * @cfg {String} paramName default 'imageUpload'
+ * @cfg {String} method default POST
+ * @cfg {Boolean} loadMask (true|false) default true
+ * @cfg {Boolean} loadingText default 'Loading...'
+ * 
+ * @constructor
+ * Create a new UploadCropbox
+ * @param {Object} config The config object
+ */
+
+ Roo.dialog.UploadCropbox = function(config){
+    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event beforeselectfile
+         * Fire before select file
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "beforeselectfile" : true,
+        /**
+         * @event initial
+         * Fire after initEvent
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "initial" : true,
+        /**
+         * @event crop
+         * Fire after initEvent
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} data
+         */
+        "crop" : true,
+        /**
+         * @event prepare
+         * Fire when preparing the file data
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} file
+         */
+        "prepare" : true,
+        /**
+         * @event exception
+         * Fire when get exception
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {XMLHttpRequest} xhr
+         */
+        "exception" : true,
+        /**
+         * @event beforeloadcanvas
+         * Fire before load the canvas
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} src
+         */
+        "beforeloadcanvas" : true,
+        /**
+         * @event trash
+         * Fire when trash image
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "trash" : true,
+        /**
+         * @event download
+         * Fire when download the image
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "download" : true,
+        /**
+         * @event footerbuttonclick
+         * Fire when footerbuttonclick
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} type
+         */
+        "footerbuttonclick" : true,
+        /**
+         * @event resize
+         * Fire when resize
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "resize" : true,
+        /**
+         * @event rotate
+         * Fire when rotate the image
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} pos
+         */
+        "rotate" : true,
+        /**
+         * @event inspect
+         * Fire when inspect the file
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} file
+         */
+        "inspect" : true,
+        /**
+         * @event upload
+         * Fire when xhr upload the file
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} data
+         */
+        "upload" : true,
+        /**
+         * @event arrange
+         * Fire when arrange the file data
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} formData
+         */
+        "arrange" : true,
+        /**
+         * @event loadcanvas
+         * Fire after load the canvas
+         * @param {Roo.dialog.UploadCropbox}
+         * @param {Object} imgEl
+         */
+        "loadcanvas" : true
+    });
+    
+    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;
+};
+
+Roo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {
+    
+    emptyText : 'Click to upload image',
+    rotateNotify : 'Image is too small to rotate',
+    errorTimeout : 3000,
+    scale : 0,
+    baseScale : 1,
+    rotate : 0,
+    dragable : false,
+    pinching : false,
+    mouseX : 0,
+    mouseY : 0,
+    cropData : false,
+    minWidth : 300,
+    minHeight : 300,
+    outputMaxWidth : 1200,
+    file : false,
+    exif : {},
+    baseRotate : 1,
+    cropType : 'image/jpeg',
+    buttons : false,
+    canvasLoaded : false,
+    isDocument : false,
+    method : 'POST',
+    paramName : 'imageUpload',
+    loadMask : true,
+    loadingText : 'Loading...',
+    maskEl : false,
+    
+    getAutoCreate : function()
+    {
+        var cfg = {
+            tag : 'div',
+            cls : 'roo-upload-cropbox',
+            cn : [
+                {
+                    tag : 'input',
+                    cls : 'roo-upload-cropbox-selector',
+                    type : 'file'
+                },
+                {
+                    tag : 'div',
+                    cls : 'roo-upload-cropbox-body',
+                    style : 'cursor:pointer',
+                    cn : [
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-preview'
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-thumb'
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-empty-notify',
+                            html : this.emptyText
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',
+                            html : this.rotateNotify
+                        }
+                    ]
+                },
+                {
+                    tag : 'div',
+                    cls : 'roo-upload-cropbox-footer',
+                    cn : {
+                        tag : 'div',
+                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
+                        cn : []
+                    }
+                }
+            ]
+        };
+        
+        return cfg;
+    },
+    
+    onRender : function(ct, position)
+    {
+        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);
+
+        if(this.el){
+            if (this.el.attr('xtype')) {
+                this.el.attr('xtypex', this.el.attr('xtype'));
+                this.el.dom.removeAttribute('xtype');
+                
+                this.initEvents();
+            }
+        }
+        else {
+            var cfg = Roo.apply({},  this.getAutoCreate());
+        
+            cfg.id = this.id || Roo.id();
+            
+            if (this.cls) {
+                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;
+            }
+            
+            if (this.style) { // fixme needs to support more complex style data.
+                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;
+            }
+            
+            this.el = ct.createChild(cfg, position);
+            
+            this.initEvents();
+        }
+        
+        if (this.buttons.length) {
+            
+            Roo.each(this.buttons, function(bb) {
+                
+                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);
+                
+                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));
+                
+            }, this);
+        }
+        
+        if(this.loadMask){
+            this.maskEl = this.el;
+        }
+    },
+    
+    initEvents : function()
+    {
+        this.urlAPI = (window.createObjectURL && window) || 
+                                (window.URL && URL.revokeObjectURL && URL) || 
+                                (window.webkitURL && webkitURL);
+                        
+        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();
+        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();
+        this.selectorEl.hide();
+        
+        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();
+        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();
+        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.thumbEl.hide();
+        
+        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();
+        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();
+        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.errorEl.hide();
+        
+        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();
+        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.footerEl.hide();
+        
+        this.setThumbBoxSize();
+        
+        this.bind();
+        
+        this.resize();
+        
+        this.fireEvent('initial', this);
+    },
+
+    bind : function()
+    {
+        var _this = this;
+        
+        window.addEventListener("resize", function() { _this.resize(); } );
+        
+        this.bodyEl.on('click', this.beforeSelectFile, this);
+        
+        if(Roo.isTouch){
+            this.bodyEl.on('touchstart', this.onTouchStart, this);
+            this.bodyEl.on('touchmove', this.onTouchMove, this);
+            this.bodyEl.on('touchend', this.onTouchEnd, this);
+        }
+        
+        if(!Roo.isTouch){
+            this.bodyEl.on('mousedown', this.onMouseDown, this);
+            this.bodyEl.on('mousemove', this.onMouseMove, this);
+            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
+            this.bodyEl.on(mousewheel, this.onMouseWheel, this);
+            Roo.get(document).on('mouseup', this.onMouseUp, this);
+        }
+        
+        this.selectorEl.on('change', this.onFileSelected, this);
+    },
+    
+    reset : function()
+    {    
+        this.scale = 0;
+        this.baseScale = 1;
+        this.rotate = 0;
+        this.baseRotate = 1;
+        this.dragable = false;
+        this.pinching = false;
+        this.mouseX = 0;
+        this.mouseY = 0;
+        this.cropData = false;
+        this.notifyEl.dom.innerHTML = this.emptyText;
+        
+        // this.selectorEl.dom.value = '';
+        
+    },
+    
+    resize : function()
+    {
+        if(this.fireEvent('resize', this) != false){
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+    },
+    
+    onFooterButtonClick : function(e, el, o, type)
+    {
+        switch (type) {
+            case 'rotate-left' :
+                this.onRotateLeft(e);
+                break;
+            case 'rotate-right' :
+                this.onRotateRight(e);
+                break;
+            case 'picture' :
+                this.beforeSelectFile(e);
+                break;
+            case 'trash' :
+                this.trash(e);
+                break;
+            case 'crop' :
+                this.crop(e);
+                break;
+            case 'download' :
+                this.download(e);
+                break;
+            default :
+                break;
+        }
+        
+        this.fireEvent('footerbuttonclick', this, type);
+    },
+    
+    beforeSelectFile : function(e)
+    {
+        e.preventDefault();
+        
+        if(this.fireEvent('beforeselectfile', this) != false){
+            this.selectorEl.dom.click();
+        }
+    },
+    
+    onFileSelected : function(e)
+    {
+        e.preventDefault();
+        
+        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
+            return;
+        }
+        
+        var file = this.selectorEl.dom.files[0];
+        
+        if(this.fireEvent('inspect', this, file) != false){
+            this.prepare(file);
+        }
+        
+    },
+    
+    trash : function(e)
+    {
+        this.fireEvent('trash', this);
+    },
+    
+    download : function(e)
+    {
+        this.fireEvent('download', this);
+    },
+    
+    loadCanvas : function(src)
+    {   
+        if(this.fireEvent('beforeloadcanvas', this, src) != false){
+            
+            this.reset();
+            
+            this.imageEl = document.createElement('img');
+            
+            var _this = this;
+            
+            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });
+            
+            this.imageEl.src = src;
+        }
+    },
+    
+    onLoadCanvas : function()
+    {   
+        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;
+        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;
+
+        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){
+        
+            this.bodyEl.un('click', this.beforeSelectFile, this);
+            
+            this.notifyEl.hide();
+            this.thumbEl.show();
+            this.footerEl.show();
+            
+            this.baseRotateLevel();
+            
+            if(this.isDocument){
+                this.setThumbBoxSize();
+            }
+            
+            this.setThumbBoxPosition();
+            
+            this.baseScaleLevel();
+            
+            this.draw();
+            
+            this.resize();
+            
+            this.canvasLoaded = true;
+        
+        }
+        
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+    },
+    
+    setCanvasPosition : function()
+    {   
+        if(!this.canvasEl){
+            return;
+        }
+        
+        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);
+        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);
+        
+        this.previewEl.setLeft(pw);
+        this.previewEl.setTop(ph);
+        
+    },
+    
+    onMouseDown : function(e)
+    {   
+        e.stopEvent();
+        
+        this.dragable = true;
+        this.pinching = false;
+        
+        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){
+            this.dragable = false;
+            return;
+        }
+        
+        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+        
+    },
+    
+    onMouseMove : function(e)
+    {   
+        e.stopEvent();
+        
+        if(!this.canvasLoaded){
+            return;
+        }
+        
+        if (!this.dragable){
+            return;
+        }
+        
+        var minX = Math.ceil(this.thumbEl.getLeft(true));
+        var minY = Math.ceil(this.thumbEl.getTop(true));
+        
+        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);
+        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);
+
+        if(minX > maxX) {
+            var tempX = minX;
+            minX = maxX;
+            maxX = tempX;
+        }
+
+        if(minY > maxY) {
+            var tempY = minY;
+            minY = maxY;
+            maxY = tempY;
+        }
+
+        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+        
+        x = x - this.mouseX;
+        y = y - this.mouseY;
+
+        var bgX = Math.ceil(x + this.previewEl.getLeft(true));
+        var bgY = Math.ceil(y + this.previewEl.getTop(true));
+        
+        bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX);
+        bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY);
+        
+        this.previewEl.setLeft(bgX);
+        this.previewEl.setTop(bgY);
+        
+        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+    },
+    
+    onMouseUp : function(e)
+    {   
+        e.stopEvent();
+        
+        this.dragable = false;
+    },
+    
+    onMouseWheel : function(e)
+    {   
+        e.stopEvent();
+        
+        this.startScale = this.scale;
+        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
+        
+        if(!this.zoomable()){
+            this.scale = this.startScale;
+            return;
+        }
+
+        
+        this.draw();
+        
+        return;
+    },
+    
+    zoomable : function()
+    {
+        var minScale = this.thumbEl.getWidth() / this.minWidth;
+        
+        if(this.minWidth < this.minHeight){
+            minScale = this.thumbEl.getHeight() / this.minHeight;
+        }
+        
+        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);
+        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);
+
+
+        var maxWidth = this.imageEl.OriginWidth;
+        var maxHeight = this.imageEl.OriginHeight;
+        
+        if(
+                this.isDocument &&
+                (this.rotate == 0 || this.rotate == 180) && 
+                (
+                    width > this.imageEl.OriginWidth || 
+                    height > this.imageEl.OriginHeight ||
+                    (width < this.minWidth && height < this.minHeight)
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                this.isDocument &&
+                (this.rotate == 90 || this.rotate == 270) && 
+                (
+                    width > this.imageEl.OriginWidth || 
+                    height > this.imageEl.OriginHeight ||
+                    (width < this.minHeight && height < this.minWidth)
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                !this.isDocument &&
+                (this.rotate == 0 || this.rotate == 180) && 
+                (
+                    (this.imageEl.OriginWidth >= this.minWidth) && width < this.minWidth ||
+                    (this.imageEl.OriginHeight >= this.minHeight) && height < this.minHeight ||
+                    width > maxWidth ||
+                    height > maxHeight
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                !this.isDocument &&
+                (this.rotate == 90 || this.rotate == 270) && 
+                (
+                    width < this.minHeight || 
+                    width > this.imageEl.OriginWidth || 
+                    height < this.minWidth || 
+                    height > this.imageEl.OriginHeight
+                )
+        ){
+            return false;
+        }
+        
+        return true;
+        
+    },
+    
+    onRotateLeft : function(e)
+    {   
+        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+            
+            var minScale = this.thumbEl.getWidth() / this.minWidth;
+            
+            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+            
+            this.startScale = this.scale;
+            
+            while (this.getScaleLevel() < minScale){
+            
+                this.scale = this.scale + 1;
+                
+                if(!this.zoomable()){
+                    break;
+                }
+                
+                if(
+                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+                ){
+                    continue;
+                }
+                
+                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+                this.draw();
+                
+                return;
+            }
+            
+            this.scale = this.startScale;
+            
+            this.onRotateFail();
+            
+            return false;
+        }
+        
+        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+        if(this.isDocument){
+            this.setThumbBoxSize();
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+        
+        this.draw();
+        
+        this.fireEvent('rotate', this, 'left');
+        
+    },
+    
+    onRotateRight : function(e)
+    {
+        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+            
+            var minScale = this.thumbEl.getWidth() / this.minWidth;
+        
+            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+            
+            this.startScale = this.scale;
+            
+            while (this.getScaleLevel() < minScale){
+            
+                this.scale = this.scale + 1;
+                
+                if(!this.zoomable()){
+                    break;
+                }
+                
+                if(
+                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+                ){
+                    continue;
+                }
+                
+                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+                this.draw();
+                
+                return;
+            }
+            
+            this.scale = this.startScale;
+            
+            this.onRotateFail();
+            
+            return false;
+        }
+        
+        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+        if(this.isDocument){
+            this.setThumbBoxSize();
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+        
+        this.draw();
+        
+        this.fireEvent('rotate', this, 'right');
+    },
+    
+    onRotateFail : function()
+    {
+        this.errorEl.show(true);
+        
+        var _this = this;
+        
+        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);
+    },
+    
+    draw : function()
+    {
+        this.previewEl.dom.innerHTML = '';
+        
+        var canvasEl = document.createElement("canvas");
+        
+        var contextEl = canvasEl.getContext("2d");
+        
+        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+        var center = this.imageEl.OriginWidth / 2;
+        
+        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){
+            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+            center = this.imageEl.OriginHeight / 2;
+        }
+        
+        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());
+        
+        contextEl.translate(center, center);
+        contextEl.rotate(this.rotate * Math.PI / 180);
+
+        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+        
+        this.canvasEl = document.createElement("canvas");
+        
+        this.contextEl = this.canvasEl.getContext("2d");
+        
+        switch (this.rotate) {
+            case 0 :
+                
+                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+                
+                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 90 : 
+                
+                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+                
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 180 :
+                
+                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+                
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 270 :
+                
+                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+        
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            default : 
+                break;
+        }
+        
+        this.previewEl.appendChild(this.canvasEl);
+        
+        this.setCanvasPosition();
+    },
+    
+    crop : function()
+    {
+        if(!this.canvasLoaded){
+            return;
+        }
+        
+        var imageCanvas = document.createElement("canvas");
+        
+        var imageContext = imageCanvas.getContext("2d");
+        
+        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+        
+        var center = imageCanvas.width / 2;
+        
+        imageContext.translate(center, center);
+        
+        imageContext.rotate(this.rotate * Math.PI / 180);
+        
+        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+        
+        var canvas = document.createElement("canvas");
+        
+        var context = canvas.getContext("2d");
+
+        canvas.width = this.thumbEl.getWidth() / this.getScaleLevel();
+        
+        canvas.height = this.thumbEl.getHeight() / this.getScaleLevel();
+
+        switch (this.rotate) {
+            case 0 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true);
+                var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true);
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+                if(canvas.width > this.outputMaxWidth) {
+                    var scale = this.outputMaxWidth / canvas.width;
+                    canvas.width = canvas.width * scale;
+                    canvas.height = canvas.height * scale;
+                    context.scale(scale, scale);
+                }
+
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 90 : 
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+                
+                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 180 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 270 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+                
+                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            default : 
+                break;
+        }
+        
+        this.cropData = canvas.toDataURL(this.cropType);
+        
+        if(this.fireEvent('crop', this, this.cropData) !== false){
+            this.process(this.file, this.cropData);
+        }
+        
+        return;
+        
+    },
+    
+    setThumbBoxSize : function()
+    {
+        var width, height;
+        
+        if(this.isDocument && typeof(this.imageEl) != 'undefined'){
+            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);
+            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);
+            
+            this.minWidth = width;
+            this.minHeight = height;
+            
+            if(this.rotate == 90 || this.rotate == 270){
+                this.minWidth = height;
+                this.minHeight = width;
+            }
+        }
+        
+        height = 300;
+        width = Math.ceil(this.minWidth * height / this.minHeight);
+        
+        if(this.minWidth > this.minHeight){
+            width = 300;
+            height = Math.ceil(this.minHeight * width / this.minWidth);
+        }
+        
+        this.thumbEl.setStyle({
+            width : width + 'px',
+            height : height + 'px'
+        });
+
+        return;
+            
+    },
+    
+    setThumbBoxPosition : function()
+    {
+        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );
+        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);
+        
+        this.thumbEl.setLeft(x);
+        this.thumbEl.setTop(y);
+        
+    },
+    
+    baseRotateLevel : function()
+    {
+        this.baseRotate = 1;
+        
+        if(
+                typeof(this.exif) != 'undefined' &&
+                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&
+                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1
+        ){
+            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
+        }
+        
+        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];
+        
+    },
+    
+    baseScaleLevel : function()
+    {
+        var width, height;
+        
+        if(this.isDocument){
+            
+            if(this.baseRotate == 6 || this.baseRotate == 8){
+            
+                height = this.thumbEl.getHeight();
+                this.baseScale = height / this.imageEl.OriginWidth;
+
+                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){
+                    width = this.thumbEl.getWidth();
+                    this.baseScale = width / this.imageEl.OriginHeight;
+                }
+
+                return;
+            }
+
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+
+            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){
+                width = this.thumbEl.getWidth();
+                this.baseScale = width / this.imageEl.OriginWidth;
+            }
+
+            return;
+        }
+        
+        if(this.baseRotate == 6 || this.baseRotate == 8){
+            
+            width = this.thumbEl.getHeight();
+            this.baseScale = width / this.imageEl.OriginHeight;
+            
+            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){
+                height = this.thumbEl.getWidth();
+                this.baseScale = height / this.imageEl.OriginHeight;
+            }
+            
+            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                height = this.thumbEl.getWidth();
+                this.baseScale = height / this.imageEl.OriginHeight;
+                
+                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){
+                    width = this.thumbEl.getHeight();
+                    this.baseScale = width / this.imageEl.OriginWidth;
+                }
+            }
+            
+            return;
+        }
+        
+        width = this.thumbEl.getWidth();
+        this.baseScale = width / this.imageEl.OriginWidth;
+        
+        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+        }
+        
+        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+            
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+            
+            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){
+                width = this.thumbEl.getWidth();
+                this.baseScale = width / this.imageEl.OriginWidth;
+            }
+            
+        }
+
+        if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) {
+            this.baseScale = width / this.minWidth;
+        }
+
+        return;
+    },
+    
+    getScaleLevel : function()
+    {
+        return this.baseScale * Math.pow(1.02, this.scale);
+    },
+    
+    onTouchStart : function(e)
+    {
+        if(!this.canvasLoaded){
+            this.beforeSelectFile(e);
+            return;
+        }
+        
+        var touches = e.browserEvent.touches;
+        
+        if(!touches){
+            return;
+        }
+        
+        if(touches.length == 1){
+            this.onMouseDown(e);
+            return;
+        }
+        
+        if(touches.length != 2){
+            return;
+        }
+        
+        var coords = [];
+        
+        for(var i = 0, finger; finger = touches[i]; i++){
+            coords.push(finger.pageX, finger.pageY);
+        }
+        
+        var x = Math.pow(coords[0] - coords[2], 2);
+        var y = Math.pow(coords[1] - coords[3], 2);
+        
+        this.startDistance = Math.sqrt(x + y);
+        
+        this.startScale = this.scale;
+        
+        this.pinching = true;
+        this.dragable = false;
+        
+    },
+    
+    onTouchMove : function(e)
+    {
+        if(!this.pinching && !this.dragable){
+            return;
+        }
+        
+        var touches = e.browserEvent.touches;
+        
+        if(!touches){
+            return;
+        }
+        
+        if(this.dragable){
+            this.onMouseMove(e);
+            return;
+        }
+        
+        var coords = [];
+        
+        for(var i = 0, finger; finger = touches[i]; i++){
+            coords.push(finger.pageX, finger.pageY);
+        }
+        
+        var x = Math.pow(coords[0] - coords[2], 2);
+        var y = Math.pow(coords[1] - coords[3], 2);
+        
+        this.endDistance = Math.sqrt(x + y);
+        
+        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));
+        
+        if(!this.zoomable()){
+            this.scale = this.startScale;
+            return;
+        }
+        
+        this.draw();
+        
+    },
+    
+    onTouchEnd : function(e)
+    {
+        this.pinching = false;
+        this.dragable = false;
+        
+    },
+    
+    process : function(file, crop)
+    {
+        if(this.loadMask){
+            this.maskEl.mask(this.loadingText);
+        }
+        
+        this.xhr = new XMLHttpRequest();
+        
+        file.xhr = this.xhr;
+
+        this.xhr.open(this.method, this.url, true);
+        
+        var headers = {
+            "Accept": "application/json",
+            "Cache-Control": "no-cache",
+            "X-Requested-With": "XMLHttpRequest"
+        };
+        
+        for (var headerName in headers) {
+            var headerValue = headers[headerName];
+            if (headerValue) {
+                this.xhr.setRequestHeader(headerName, headerValue);
+            }
+        }
+        
+        var _this = this;
+        
+        this.xhr.onload = function()
+        {
+            _this.xhrOnLoad(_this.xhr);
+        }
+        
+        this.xhr.onerror = function()
+        {
+            _this.xhrOnError(_this.xhr);
+        }
+        
+        var formData = new FormData();
+
+        formData.append('returnHTML', 'NO');
+
+        if(crop){
+            formData.append('crop', crop);
+            var blobBin = atob(crop.split(',')[1]);
+            var array = [];
+            for(var i = 0; i < blobBin.length; i++) {
+                array.push(blobBin.charCodeAt(i));
+            }
+            var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType});
+            formData.append(this.paramName, croppedFile, file.name);
+        }
+        
+        if(typeof(file.filename) != 'undefined'){
+            formData.append('filename', file.filename);
+        }
+        
+        if(typeof(file.mimetype) != 'undefined'){
+            formData.append('mimetype', file.mimetype);
+        }
+
+        if(this.fireEvent('arrange', this, formData) != false){
+            this.xhr.send(formData);
+        };
+    },
+    
+    xhrOnLoad : function(xhr)
+    {
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+        if (xhr.readyState !== 4) {
+            this.fireEvent('exception', this, xhr);
+            return;
+        }
+
+        var response = Roo.decode(xhr.responseText);
+        
+        if(!response.success){
+            this.fireEvent('exception', this, xhr);
+            return;
+        }
+        
+        var response = Roo.decode(xhr.responseText);
+        
+        this.fireEvent('upload', this, response);
+        
+    },
+    
+    xhrOnError : function()
+    {
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+        Roo.log('xhr on error');
+        
+        var response = Roo.decode(xhr.responseText);
+          
+        Roo.log(response);
+        
+    },
+    
+    prepare : function(file)
+    {   
+        if(this.loadMask){
+            this.maskEl.mask(this.loadingText);
+        }
+        
+        this.file = false;
+        this.exif = {};
+        
+        if(typeof(file) === 'string'){
+            this.loadCanvas(file);
+            return;
+        }
+        
+        if(!file || !this.urlAPI){
+            return;
+        }
+        
+        this.file = file;
+        if(typeof(file.type) != 'undefined' && file.type.length != 0) {
+            this.cropType = file.type;
+        }
+        
+        var _this = this;
+        
+        if(this.fireEvent('prepare', this, this.file) != false){
+            
+            var reader = new FileReader();
+            
+            reader.onload = function (e) {
+                if (e.target.error) {
+                    Roo.log(e.target.error);
+                    return;
+                }
+                
+                var buffer = e.target.result,
+                    dataView = new DataView(buffer),
+                    offset = 2,
+                    maxOffset = dataView.byteLength - 4,
+                    markerBytes,
+                    markerLength;
+                
+                if (dataView.getUint16(0) === 0xffd8) {
+                    while (offset < maxOffset) {
+                        markerBytes = dataView.getUint16(offset);
+                        
+                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {
+                            markerLength = dataView.getUint16(offset + 2) + 2;
+                            if (offset + markerLength > dataView.byteLength) {
+                                Roo.log('Invalid meta data: Invalid segment size.');
+                                break;
+                            }
+                            
+                            if(markerBytes == 0xffe1){
+                                _this.parseExifData(
+                                    dataView,
+                                    offset,
+                                    markerLength
+                                );
+                            }
+                            
+                            offset += markerLength;
+                            
+                            continue;
+                        }
+                        
+                        break;
+                    }
+                    
+                }
+                
+                var url = _this.urlAPI.createObjectURL(_this.file);
+                
+                _this.loadCanvas(url);
+                
+                return;
+            }
+            
+            reader.readAsArrayBuffer(this.file);
+            
+        }
+        
+    },
+    
+    parseExifData : function(dataView, offset, length)
+    {
+        var tiffOffset = offset + 10,
+            littleEndian,
+            dirOffset;
+    
+        if (dataView.getUint32(offset + 4) !== 0x45786966) {
+            // No Exif data, might be XMP data instead
+            return;
+        }
+        
+        // Check for the ASCII code for "Exif" (0x45786966):
+        if (dataView.getUint32(offset + 4) !== 0x45786966) {
+            // No Exif data, might be XMP data instead
+            return;
+        }
+        if (tiffOffset + 8 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid segment size.');
+            return;
+        }
+        // Check for the two null bytes:
+        if (dataView.getUint16(offset + 8) !== 0x0000) {
+            Roo.log('Invalid Exif data: Missing byte alignment offset.');
+            return;
+        }
+        // Check the byte alignment:
+        switch (dataView.getUint16(tiffOffset)) {
+        case 0x4949:
+            littleEndian = true;
+            break;
+        case 0x4D4D:
+            littleEndian = false;
+            break;
+        default:
+            Roo.log('Invalid Exif data: Invalid byte alignment marker.');
+            return;
+        }
+        // Check for the TIFF tag marker (0x002A):
+        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
+            Roo.log('Invalid Exif data: Missing TIFF marker.');
+            return;
+        }
+        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
+        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
+        
+        this.parseExifTags(
+            dataView,
+            tiffOffset,
+            tiffOffset + dirOffset,
+            littleEndian
+        );
+    },
+    
+    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)
+    {
+        var tagsNumber,
+            dirEndOffset,
+            i;
+        if (dirOffset + 6 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid directory offset.');
+            return;
+        }
+        tagsNumber = dataView.getUint16(dirOffset, littleEndian);
+        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
+        if (dirEndOffset + 4 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid directory size.');
+            return;
+        }
+        for (i = 0; i < tagsNumber; i += 1) {
+            this.parseExifTag(
+                dataView,
+                tiffOffset,
+                dirOffset + 2 + 12 * i, // tag offset
+                littleEndian
+            );
+        }
+        // Return the offset to the next directory:
+        return dataView.getUint32(dirEndOffset, littleEndian);
+    },
+    
+    parseExifTag : function (dataView, tiffOffset, offset, littleEndian) 
+    {
+        var tag = dataView.getUint16(offset, littleEndian);
+        
+        this.exif[tag] = this.getExifValue(
+            dataView,
+            tiffOffset,
+            offset,
+            dataView.getUint16(offset + 2, littleEndian), // tag type
+            dataView.getUint32(offset + 4, littleEndian), // tag length
+            littleEndian
+        );
+    },
+    
+    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)
+    {
+        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],
+            tagSize,
+            dataOffset,
+            values,
+            i,
+            str,
+            c;
+    
+        if (!tagType) {
+            Roo.log('Invalid Exif data: Invalid tag type.');
+            return;
+        }
+        
+        tagSize = tagType.size * length;
+        // Determine if the value is contained in the dataOffset bytes,
+        // or if the value at the dataOffset is a pointer to the actual data:
+        dataOffset = tagSize > 4 ?
+                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
+        if (dataOffset + tagSize > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid data offset.');
+            return;
+        }
+        if (length === 1) {
+            return tagType.getValue(dataView, dataOffset, littleEndian);
+        }
+        values = [];
+        for (i = 0; i < length; i += 1) {
+            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
+        }
+        
+        if (tagType.ascii) {
+            str = '';
+            // Concatenate the chars:
+            for (i = 0; i < values.length; i += 1) {
+                c = values[i];
+                // Ignore the terminating NULL byte(s):
+                if (c === '\u0000') {
+                    break;
+                }
+                str += c;
+            }
+            return str;
+        }
+        return values;
+    }
+    
+});
+
+Roo.apply(Roo.dialog.UploadCropbox, {
+    tags : {
+        'Orientation': 0x0112
+    },
+    
+    Orientation: {
+            1: 0, //'top-left',
+//            2: 'top-right',
+            3: 180, //'bottom-right',
+//            4: 'bottom-left',
+//            5: 'left-top',
+            6: 90, //'right-top',
+//            7: 'right-bottom',
+            8: 270 //'left-bottom'
+    },
+    
+    exifTagTypes : {
+        // byte, 8-bit unsigned int:
+        1: {
+            getValue: function (dataView, dataOffset) {
+                return dataView.getUint8(dataOffset);
+            },
+            size: 1
+        },
+        // ascii, 8-bit byte:
+        2: {
+            getValue: function (dataView, dataOffset) {
+                return String.fromCharCode(dataView.getUint8(dataOffset));
+            },
+            size: 1,
+            ascii: true
+        },
+        // short, 16 bit int:
+        3: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint16(dataOffset, littleEndian);
+            },
+            size: 2
+        },
+        // long, 32 bit int:
+        4: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint32(dataOffset, littleEndian);
+            },
+            size: 4
+        },
+        // rational = two long values, first is numerator, second is denominator:
+        5: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint32(dataOffset, littleEndian) /
+                    dataView.getUint32(dataOffset + 4, littleEndian);
+            },
+            size: 8
+        },
+        // slong, 32 bit signed int:
+        9: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getInt32(dataOffset, littleEndian);
+            },
+            size: 4
+        },
+        // srational, two slongs, first is numerator, second is denominator:
+        10: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getInt32(dataOffset, littleEndian) /
+                    dataView.getInt32(dataOffset + 4, littleEndian);
+            },
+            size: 8
+        }
+    },
+    
+    footer : {
+        STANDARD : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-picture',
+                action : 'picture',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-picture-o"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ],
+        DOCUMENT : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-download',
+                action : 'download',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-download"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-crop',
+                action : 'crop',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-crop"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-trash',
+                action : 'trash',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-trash"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ],
+        ROTATOR : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ]
+    }
+});
diff --git a/Roo/dialog/namespace.js b/Roo/dialog/namespace.js
new file mode 100644 (file)
index 0000000..b047375
--- /dev/null
@@ -0,0 +1 @@
+Roo.dialog = {};
\ No newline at end of file
index 5a8e5a9..f89656e 100644 (file)
@@ -197,3 +197,6 @@ Roo.XTemplate
 
 // is this ready yet? - is it used?
 // Roo.Login
+
+Roo.dialog.namespace
+Roo.dialog.UploadCropbox
diff --git a/css/alert.css b/css/alert.css
new file mode 100644 (file)
index 0000000..0cc7751
--- /dev/null
@@ -0,0 +1,75 @@
+.alert {
+  padding: 15px;
+  margin-bottom: 20px;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.alert h4 {
+  margin-top: 0;
+  color: inherit;
+}
+.alert .alert-link {
+  font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+  margin-bottom: 0;
+}
+.alert > p + p {
+  margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+  padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+  position: relative;
+  top: -2px;
+  right: -21px;
+  color: inherit;
+}
+.alert-success {
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
+  color: #3c763d;
+}
+.alert-success hr {
+  border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+  color: #2b542c;
+}
+.alert-info {
+  background-color: #d9edf7;
+  border-color: #bce8f1;
+  color: #31708f;
+}
+.alert-info hr {
+  border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+  color: #245269;
+}
+.alert-warning {
+  background-color: #fcf8e3;
+  border-color: #faebcc;
+  color: #8a6d3b;
+}
+.alert-warning hr {
+  border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+  color: #66512c;
+}
+.alert-danger {
+  background-color: #f2dede;
+  border-color: #ebccd1;
+  color: #a94442;
+}
+.alert-danger hr {
+  border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+  color: #843534;
+}
\ No newline at end of file
diff --git a/css/button-groups.css b/css/button-groups.css
new file mode 100644 (file)
index 0000000..b725faf
--- /dev/null
@@ -0,0 +1,171 @@
+.btn-group,
+.btn-group-vertical {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+  position: relative;
+  float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+  z-index: 2;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+  margin-left: -1px;
+}
+.btn-toolbar {
+  margin-left: -5px;
+}
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+  float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+  margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+  border-radius: 0;
+}
+.btn-group > .btn:first-child {
+  margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+  border-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+}
+.btn-group > .btn-group {
+  float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+  border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+  border-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+  outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+  padding-left: 8px;
+  padding-right: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+  padding-left: 12px;
+  padding-right: 12px;
+}
+.btn-group.open .dropdown-toggle {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn .caret {
+  margin-left: 0;
+}
+.btn-lg .caret {
+  border-width: 5px 5px 0;
+  border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+  border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+  display: block;
+  float: none;
+  width: 100%;
+  max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+  float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+  margin-top: -1px;
+  margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+  border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+  border-top-right-radius: 4px;
+  border-top-left-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+  border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.btn-group-justified {
+  display: table;
+  width: 100%;
+  table-layout: fixed;
+  border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+  float: none;
+  display: table-cell;
+  width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+  width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+  left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+  position: absolute;
+  clip: rect(0, 0, 0, 0);
+  pointer-events: none;
+}
\ No newline at end of file
diff --git a/css/buttons.css b/css/buttons.css
new file mode 100644 (file)
index 0000000..42ec098
--- /dev/null
@@ -0,0 +1,463 @@
+.btn {
+  display: inline-block;
+  margin-bottom: 0;
+  font-weight: normal;
+  text-align: center;
+  vertical-align: middle;
+  touch-action: manipulation;
+  cursor: pointer;
+  background-image: none;
+  border: 1px solid transparent;
+  white-space: nowrap;
+  padding: 6px 12px;
+  font-size: 14px;
+  line-height: 1.42857143;
+  border-radius: 4px;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+  color: #333333;
+  text-decoration: none;
+}
+.btn:active,
+.btn.active {
+  outline: 0;
+  background-image: none;
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+  cursor: not-allowed;
+  opacity: 0.65;
+  filter: alpha(opacity=65);
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+  pointer-events: none;
+}
+.btn-default {
+  color: #333333;
+  background-color: #ffffff;
+  border-color: #cccccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+  color: #333333;
+  background-color: #e6e6e6;
+  border-color: #8c8c8c;
+}
+.btn-default:hover {
+  color: #333333;
+  background-color: #e6e6e6;
+  border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+  color: #333333;
+  background-color: #e6e6e6;
+  border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+  color: #333333;
+  background-color: #d4d4d4;
+  border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+  background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+  background-color: #ffffff;
+  border-color: #cccccc;
+}
+.btn-default .badge {
+  color: #ffffff;
+  background-color: #333333;
+}
+.btn-primary {
+  color: #ffffff;
+  background-color: #337ab7;
+  border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+  color: #ffffff;
+  background-color: #286090;
+  border-color: #122b40;
+}
+.btn-primary:hover {
+  color: #ffffff;
+  background-color: #286090;
+  border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  color: #ffffff;
+  background-color: #286090;
+  border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+  color: #ffffff;
+  background-color: #204d74;
+  border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+  background-color: #337ab7;
+  border-color: #2e6da4;
+}
+.btn-primary .badge {
+  color: #337ab7;
+  background-color: #ffffff;
+}
+.btn-success {
+  color: #ffffff;
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+  color: #ffffff;
+  background-color: #449d44;
+  border-color: #255625;
+}
+.btn-success:hover {
+  color: #ffffff;
+  background-color: #449d44;
+  border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+  color: #ffffff;
+  background-color: #449d44;
+  border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+  color: #ffffff;
+  background-color: #398439;
+  border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+  background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success .badge {
+  color: #5cb85c;
+  background-color: #ffffff;
+}
+.btn-info {
+  color: #ffffff;
+  background-color: #5bc0de;
+  border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+  color: #ffffff;
+  background-color: #31b0d5;
+  border-color: #1b6d85;
+}
+.btn-info:hover {
+  color: #ffffff;
+  background-color: #31b0d5;
+  border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+  color: #ffffff;
+  background-color: #31b0d5;
+  border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+  color: #ffffff;
+  background-color: #269abc;
+  border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+  background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+  background-color: #5bc0de;
+  border-color: #46b8da;
+}
+.btn-info .badge {
+  color: #5bc0de;
+  background-color: #ffffff;
+}
+.btn-warning {
+  color: #ffffff;
+  background-color: #f0ad4e;
+  border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+  color: #ffffff;
+  background-color: #ec971f;
+  border-color: #985f0d;
+}
+.btn-warning:hover {
+  color: #ffffff;
+  background-color: #ec971f;
+  border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+  color: #ffffff;
+  background-color: #ec971f;
+  border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+  color: #ffffff;
+  background-color: #d58512;
+  border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+  background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+  background-color: #f0ad4e;
+  border-color: #eea236;
+}
+.btn-warning .badge {
+  color: #f0ad4e;
+  background-color: #ffffff;
+}
+.btn-danger {
+  color: #ffffff;
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+  color: #ffffff;
+  background-color: #c9302c;
+  border-color: #761c19;
+}
+.btn-danger:hover {
+  color: #ffffff;
+  background-color: #c9302c;
+  border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+  color: #ffffff;
+  background-color: #c9302c;
+  border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+  color: #ffffff;
+  background-color: #ac2925;
+  border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+  background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger .badge {
+  color: #d9534f;
+  background-color: #ffffff;
+}
+.btn-link {
+  color: #337ab7;
+  font-weight: normal;
+  border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+  background-color: transparent;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+  border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+  color: #23527c;
+  text-decoration: underline;
+  background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+  color: #777777;
+  text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.3333333;
+  border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+  padding: 1px 5px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-block {
+  display: block;
+  width: 100%;
+}
+.btn-block + .btn-block {
+  margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+  width: 100%;
+}
\ No newline at end of file
diff --git a/css/upload-cropbox.css b/css/upload-cropbox.css
new file mode 100644 (file)
index 0000000..f850093
--- /dev/null
@@ -0,0 +1,62 @@
+.roo-upload-cropbox-selector {
+  visibility: hidden;
+  height: 0px;
+}
+.roo-upload-cropbox-dialog .modal-header,
+.roo-upload-cropbox-dialog .modal-footer {
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+.roo-upload-cropbox-body {
+  background-color: #ffffff;
+  border: 1px solid #777777;
+  width: 100%;
+  height: 450px;
+  max-height: 450px;
+  position: relative;
+  overflow: hidden;
+  cursor: move;
+}
+.roo-upload-cropbox-preview {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  text-align: center;
+  margin: 0px;
+  padding: 0px;
+  border: none;
+}
+.roo-upload-cropbox-body .roo-upload-cropbox-thumb {
+  position: absolute;
+  /*    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);*/
+  box-sizing: border-box;
+  border: 1px solid #777777;
+  box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);
+  background: none repeat scroll 0% 0% transparent;
+}
+.roo-upload-cropbox-body .roo-upload-cropbox-empty-notify {
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  color: #ffffff;
+  font-weight: bold;
+  font-size: 24px;
+  text-align: center;
+  padding-top: 50px;
+  font-style: italic;
+}
+.roo-upload-cropbox-btn-group button {
+  background-color: #000000;
+  color: #ffffff;
+  border-color: #333333;
+}
+.roo-upload-cropbox-error-notify {
+  border-radius: 0px;
+  text-align: center;
+  padding: 0px !important;
+  margin: 0px !important;
+  position: absolute;
+  top: 0;
+  left: 0;
+}
\ No newline at end of file
index ab43ed9..ec001bf 100644 (file)
@@ -1,27 +1,27 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\r
-<html>\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
-<title>Hello World Dialog Example</title>\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Hello World Dialog Example</title>
  <link rel="stylesheet" type="text/css" href="../../css/roojs-debug.css"/>
     <link rel="stylesheet" type="text/css" href="../../css/xtheme-slate.css"/>
 
      <script type="text/javascript" src="../../roojs-debug.js"></script>   
-  \r
-     <script language="javascript" src="hello.js"></script>\r
\r
-<!-- Common Styles for the examples -->\r
-<link rel="stylesheet" type="text/css" href="../examples.css" />\r
-</head>\r
-<body>\r
-<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->\r
-\r
-<h1>Hello World Dialog</h1>\r
-<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>\r
-<input type="button" id="show-dialog-btn" value="Hello World" /><br /><br />\r
+  
+     <script language="javascript" src="hello.js"></script>
+<!-- Common Styles for the examples -->
+<link rel="stylesheet" type="text/css" href="../examples.css" />
+</head>
+<body>
+<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->
+
+<h1>Hello World Dialog</h1>
+<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>
+<input type="button" id="show-dialog-btn" value="Hello World" /><br /><br />
 <p>Note that the js is not minified so it is readable. See 
-<button type="button" onclick="RooDocs.viewSource.show('/hello.js')">hello.js</button>for the full source code.</p>\r
-Here's snapshot of the code that creates the dialog:\r
+<button type="button" onclick="RooDocs.viewSource.show('/hello.js')">hello.js</button>for the full source code.</p>
+Here's snapshot of the code that creates the dialog:
 <pre class="code"><code>Roo.BLANK_IMAGE_URL  = "../../images/default/s.gif";
 
 
@@ -121,29 +121,29 @@ Roo.onReady(function() {
     Roo.get('show-dialog-btn').on('click',function () {
         HelloWorld.show({ _el : this});
     });
-});\r
-</code></pre>\r
-\r
-    <!-- The dialog is created from existing markup.\r
-         The inline styles just hide it until it created and should be in a stylesheet -->\r
-    <div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">\r
-    <div class="x-dlg-hd">Hello Dialog</div>\r
-    <div class="x-dlg-bd">\r
-        <!-- Auto create tab 1 -->\r
-        <div class="x-dlg-tab" title="Hello World 1">\r
-            <!-- Nested "inner-tab" to safely add padding -->\r
-            <div class="inner-tab">\r
-                 Hello...<br><br><br>\r
-            </div>\r
-        </div>\r
-        <!-- Auto create tab 2 -->\r
-        <div class="x-dlg-tab" title="Hello World 2">\r
-            <div class="inner-tab">\r
-            ... World!\r
-            </div>\r
-        </div>\r
-        </div>\r
-    </div>\r
-</div>\r
-</body>\r
-</html>\r
+});
+</code></pre>
+
+    <!-- The dialog is created from existing markup.
+         The inline styles just hide it until it created and should be in a stylesheet -->
+    <div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">
+    <div class="x-dlg-hd">Hello Dialog</div>
+    <div class="x-dlg-bd">
+        <!-- Auto create tab 1 -->
+        <div class="x-dlg-tab" title="Hello World 1">
+            <!-- Nested "inner-tab" to safely add padding -->
+            <div class="inner-tab">
+                 Hello...<br><br><br>
+            </div>
+        </div>
+        <!-- Auto create tab 2 -->
+        <div class="x-dlg-tab" title="Hello World 2">
+            <div class="inner-tab">
+            ... World!
+            </div>
+        </div>
+        </div>
+    </div>
+</div>
+</body>
+</html>
diff --git a/examples/dialog/uploadCropbox.html b/examples/dialog/uploadCropbox.html
new file mode 100644 (file)
index 0000000..79ac18b
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <title>Upload Cropbox Dialog Example</title>
+
+    <link rel="stylesheet" type="text/css" href="../../css/roojs-debug.css"/>
+    <link rel="stylesheet" type="text/css" href="../../css-bootstrap/font-awesome.css"/>
+    <link rel="stylesheet" type="text/css" href="../../css/upload-cropbox.css"/>
+    <link rel="stylesheet" type="text/css" href="../../css/alert.css"/>
+    <link rel="stylesheet" type="text/css" href="../../css/buttons.css"/>
+    <link rel="stylesheet" type="text/css" href="../../css/button-groups.css"/>
+    <link rel="stylesheet" type="text/css" href="../examples.css" />
+
+     <script type="text/javascript" src="../../roojs-debug.js"></script>   
+     <script type="text/javascript" src="../../Roo/dialog/UploadCropbox.js"></script>
+     <script language="javascript" src="uploadCropbox.js"></script>
+     <script type="text/javascript" src="../examples.js"></script>
+
+</head>
+<body>
+
+<h1>Upload Cropbox Dialog</h1>
+<p>This example shows how to create a very simple BasicDialog with "UploadCropbox".</p>
+<input type="button" id="show-dialog-btn" value="test" /><br /><br />
+<p>Note that the js is not minified so it is readable. See 
+<button type="button" onclick="RooDocs.viewSource.show('../../../Roo/dialog/UploadCropbox.js')">UploadCropbox.js</button>for the full source code.</p>
+
+</div>
+</body>
+</html>
diff --git a/examples/dialog/uploadCropbox.js b/examples/dialog/uploadCropbox.js
new file mode 100644 (file)
index 0000000..7604320
--- /dev/null
@@ -0,0 +1,179 @@
+var uploadCropbox = {
+    dialog : false,
+    callback : false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show();
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xns : Roo,
+            xtype : 'LayoutDialog',
+            width : 800,
+            height : 600,
+            center : {
+                xns : Roo,
+                xtype : 'LayoutRegion'
+            },
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : "center",
+                    items : [
+                        {
+                            xtype : 'UploadCropbox',
+                            xns : Roo.dialog,
+                            minWidth : 720,
+                            minHeight : 480,
+                            outputMaxWidth : 1300,
+                            url: 'http://localhost/web.MediaOutreach/press.local.php/Roo/Images.php',
+                            buttons: [],
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.cropbox = _self;
+                                },
+                                loadcanvas : function (_self, imageEl)
+                                {
+                                    if(imageEl.OriginWidth < 720) {
+                                        Roo.Msg.show({
+                                            title: 'Error',
+                                            msg: "Image width should be at least 720",
+                                            buttons: {ok : true},
+                                            fn: function(res) {
+                                                _this.cropbox.selectorEl.dom.value = '';
+                                                _this.cropbox.selectorEl.dom.click();
+                                            }
+                                        });
+                                        return false;
+                                    }
+                                },
+                                arrange : function (_self, formData)
+                                {
+                                    formData.append("onid", "43024");
+                                    formData.append("ontable", "pressrelease_boilerplate");
+                                }
+                            }
+                        }
+                    ]
+                }
+            ],
+            buttons : [
+                {
+                    xtype : 'Button',
+                    xns : Roo,
+                    text : 'Save',
+                    listeners : {
+                        click : function () {
+                            _this.cropbox.crop();
+                            _this.dialog.hide();
+                        }   
+                    }
+                },
+                {
+                    xtype : 'Button',
+                    xns : Roo,
+                    text : 'Cancel',
+                    listeners : {
+                        click : function () {
+                            _this.dialog.hide();
+                        }   
+                    }
+                }
+            ]
+        });
+    }
+}
+
+var test = {
+
+    dialog : false,
+    callback : false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show();
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xns : Roo,
+            xtype : 'LayoutDialog',
+            width : 600,
+            height : 450,
+            center : {
+                xns : Roo,
+                xtype : 'LayoutRegion'
+            },
+            items : [
+                {
+                    xns : Roo,
+                    xtype: 'GridPanel',
+                    region : "center",
+                    grid : {
+                        xns : Roo.grid,
+                        xtype : 'Grid',
+                        cm : [
+                            {
+                                xns : Roo.grid,
+                                xtype : 'ColumnModel',
+                                header : 'test'
+                            }
+                        ],
+                        ds : {
+                            xns: Roo.data,
+                            xtype: 'Store'
+                        },
+                        toolbar : {
+                            xns: Roo,
+                            xtype: 'Toolbar',
+                            items : [
+                                { 
+                                    xtype : 'Button',
+                                    text : 'Add',
+                                    listeners : {
+                                        click : function () {
+                                            uploadCropbox.show();
+                                            document.body.onfocus = function(e) {
+                                                if(!uploadCropbox.cropbox.selectorEl.dom.files.length) {
+                                                    uploadCropbox.dialog.hide();
+                                                }
+                                            }
+                                            uploadCropbox.cropbox.selectorEl.dom.click();
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            ],
+        });
+    }
+}
+
+Roo.onReady(function() {
+    
+    Roo.get('show-dialog-btn').on('click',function () {
+        test.show({});
+    });
+});
\ No newline at end of file
index 39a3e49..15dee23 100644 (file)
@@ -2545,9 +2545,9 @@ return this.el.getUpdateManager();},_handleRefresh:function(A,B,C){if(!C||!this.
 te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B);
 this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A);
 }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();
-}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();
-this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,'');
-this.view=B;return B;}return false;}});
+}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A);
+this.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));
+var B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}});
 // Roo/GridPanel.js
 Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B);
 if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo);
@@ -2876,3 +2876,104 @@ F.push("(typeof("+G+") == 'undefined')");});var H='(('+F.join(" || ")+") ? undef
 }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){  with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){  with (values) { return ['"];
 B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{}
 );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);};
+// Roo/dialog/namespace.js
+Roo.dialog={};
+// Roo/dialog/UploadCropbox.js
+Roo.dialog.UploadCropbox=function(A){Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true}
+);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,outputMaxWidth:1200,file:false,exif:{}
+,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'}
+,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify}
+]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));
+this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style;
+}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);C.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true));
+},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first();
+this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
+this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
+this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
+this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this);
+this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);this.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel';
+this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false;
+this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();this.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e);
+break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);break;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A);
+},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return;
+}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset();
+this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;this.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height;
+if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();if(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition();
+this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);var ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2);
+this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.width<this.thumbEl.getWidth()||this.canvasEl.height<this.thumbEl.getHeight())){this.dragable=false;
+return;}this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseMove:function(e){e.stopEvent();if(!this.canvasLoaded){return;}if(!this.dragable){return;}var A=Math.ceil(this.thumbEl.getLeft(true));
+var B=Math.ceil(this.thumbEl.getTop(true));var C=Math.ceil(A+this.thumbEl.getWidth()-this.canvasEl.width);var D=Math.ceil(B+this.thumbEl.getHeight()-this.canvasEl.height);if(A>C){var E=A;A=C;C=E;}if(B>D){var F=B;B=D;D=F;}var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();
+var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();x=x-this.mouseX;y=y-this.mouseY;var G=Math.ceil(x+this.previewEl.getLeft(true));var H=Math.ceil(y+this.previewEl.getTop(true));G=(G<A)?A:((G>C)?C:G);H=(H<B)?B:((H>D)?D:H);this.previewEl.setLeft(G);
+this.previewEl.setTop(H);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent();
+this.startScale=this.scale;this.scale=(e.getWheelDelta()==1)?(this.scale+1):(this.scale-1);if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidth<this.minHeight){A=this.thumbEl.getHeight()/this.minHeight;
+}var B=Math.ceil(this.imageEl.OriginWidth*this.getScaleLevel()/A);var C=Math.ceil(this.imageEl.OriginHeight*this.getScaleLevel()/A);var D=this.imageEl.OriginWidth;var E=this.imageEl.OriginHeight;if(this.isDocument&&(this.rotate==0||this.rotate==180)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minWidth&&C<this.minHeight))){return false;
+}if(this.isDocument&&(this.rotate==90||this.rotate==270)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minHeight&&C<this.minWidth))){return false;}if(!this.isDocument&&(this.rotate==0||this.rotate==180)&&((this.imageEl.OriginWidth>=this.minWidth)&&B<this.minWidth||(this.imageEl.OriginHeight>=this.minHeight)&&C<this.minHeight||B>D||C>E)){return false;
+}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(B<this.minHeight||B>this.imageEl.OriginWidth||C<this.minWidth||C>this.imageEl.OriginHeight)){return false;}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;
+var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
+}this.rotate=(this.rotate<90)?270:this.rotate-90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate<90)?270:this.rotate-90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
+}this.draw();this.fireEvent('rotate',this,'left');},onRotateRight:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());
+var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
+}this.rotate=(this.rotate>180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
+}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas");
+var B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidth<this.imageEl.OriginHeight){A.width=this.imageEl.OriginHeight*this.getScaleLevel();
+A.height=this.imageEl.OriginHeight*this.getScaleLevel();C=this.imageEl.OriginHeight/2;}B.scale(this.getScaleLevel(),this.getScaleLevel());B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);
+this.canvasEl=document.createElement("canvas");this.contextEl=this.canvasEl.getContext("2d");switch(this.rotate){case 0:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;case 90:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();
+if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition();
+},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;
+var C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d");
+D.width=this.thumbEl.getWidth()/this.getScaleLevel();D.height=this.thumbEl.getHeight()/this.getScaleLevel();switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
+var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
+var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var sx=this.thumbEl.getLeft(true)-this.previewEl.getLeft(true);var sy=this.thumbEl.getTop(true)-this.previewEl.getTop(true);
+sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());if(D.width>this.outputMaxWidth){var H=this.outputMaxWidth/D.width;D.width=D.width*H;D.height=D.height*H;E.scale(H,H);}E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());
+var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
+var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
+}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
+sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
+var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
+var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
+}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
+sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;
+E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());
+var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());
+var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));
+var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);
+E.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType);if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight);
+B=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=300;A=Math.ceil(this.minWidth*B/this.minHeight);
+if(this.minWidth>this.minHeight){A=300;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2);var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);
+this.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
+}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();
+this.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;
+}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getWidth()){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;
+}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getHeight()){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginWidth;
+}}return;}A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getHeight()){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getHeight();
+this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;}}if(this.imageEl.OriginWidth<this.minWidth||this.imageEl.OriginHeight<this.minHeight){this.baseScale=A/this.minWidth;
+}return;},getScaleLevel:function(){return this.baseScale*Math.pow(1.02,this.scale);},onTouchStart:function(e){if(!this.canvasLoaded){this.beforeSelectFile(e);return;}var A=e.browserEvent.touches;if(!A){return;}if(A.length==1){this.onMouseDown(e);return;}if(A.length!=2){return;
+}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.startDistance=Math.sqrt(x+y);this.startScale=this.scale;this.pinching=true;this.dragable=false;},onTouchMove:function(e){if(!this.pinching&&!this.dragable){return;
+}var A=e.browserEvent.touches;if(!A){return;}if(this.dragable){this.onMouseMove(e);return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.endDistance=Math.sqrt(x+y);this.scale=this.startScale+Math.floor(Math.log(this.endDistance/this.startDistance)/Math.log(1.1));
+if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();},onTouchEnd:function(e){this.pinching=false;this.dragable=false;},process:function(A,B){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.xhr=new XMLHttpRequest();A.xhr=this.xhr;
+this.xhr.open(this.method,this.url,true);var C={"Accept":"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"};for(var D in C){var E=C[D];if(E){this.xhr.setRequestHeader(D,E);}}var F=this;this.xhr.onload=function(){F.xhrOnLoad(F.xhr);
+};this.xhr.onerror=function(){F.xhrOnError(F.xhr);};var G=new FormData();G.append('returnHTML','NO');if(B){G.append('crop',B);var H=atob(B.split(',')[1]);var I=[];for(var i=0;i<H.length;i++){I.push(H.charCodeAt(i));}var J=new Blob([new Uint8Array(I)],{type:this.cropType}
+);G.append(this.paramName,J,A.name);}if(typeof(A.filename)!='undefined'){G.append('filename',A.filename);}if(typeof(A.mimetype)!='undefined'){G.append('mimetype',A.mimetype);}if(this.fireEvent('arrange',this,G)!=false){this.xhr.send(G);};},xhrOnLoad:function(A){if(this.loadMask){this.maskEl.unmask();
+}if(A.readyState!==4){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);if(!B.success){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);this.fireEvent('upload',this,B);},xhrOnError:function(){if(this.loadMask){this.maskEl.unmask();
+}Roo.log('xhr on error');var A=Roo.decode(xhr.responseText);Roo.log(A);},prepare:function(A){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.file=false;this.exif={};if(typeof(A)==='string'){this.loadCanvas(A);return;}if(!A||!this.urlAPI){return;
+}this.file=A;if(typeof(A.type)!='undefined'&&A.type.length!=0){this.cropType=A.type;}var B=this;if(this.fireEvent('prepare',this,this.file)!=false){var C=new FileReader();C.onload=function(e){if(e.target.error){Roo.log(e.target.error);return;}var D=e.target.result,E=new DataView(D),F=2,G=E.byteLength-4,H,I;
+if(E.getUint16(0)===0xffd8){while(F<G){H=E.getUint16(F);if((H>=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');break;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break;
+}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.');
+return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;default:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return;
+}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;if(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.');
+return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i<E;i+=1){this.parseExifTag(A,B,C+2+12*i,D);}return A.getUint32(F,D);},parseExifTag:function(A,B,C,D){var E=A.getUint16(C,D);this.exif[E]=this.getExifValue(A,B,C,A.getUint16(C+2,D),A.getUint32(C+4,D),D);
+},getExifValue:function(A,B,C,D,E,F){var G=Roo.dialog.UploadCropbox.exifTagTypes[D],H,I,J,i,K,c;if(!G){Roo.log('Invalid Exif data: Invalid tag type.');return;}H=G.size*E;I=H>4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.');
+return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i<E;i+=1){J[i]=G.getValue(A,I+i*G.size,F);}if(G.ascii){K='';for(i=0;i<J.length;i+=1){c=J[i];if(c==='\u0000'){break;}K+=c;}return K;}return J;}});Roo.apply(Roo.dialog.UploadCropbox,{tags:{'Orientation':0x0112
+}
+,Orientation:{1:0,3:180,6:90,8:270},exifTagTypes:{1:{getValue:function(A,B){return A.getUint8(B);},size:1},2:{getValue:function(A,B){return String.fromCharCode(A.getUint8(B));},size:1,ascii:true},3:{getValue:function(A,B,C){return A.getUint16(B,C);},size:2}
+,4:{getValue:function(A,B,C){return A.getUint32(B,C);},size:4},5:{getValue:function(A,B,C){return A.getUint32(B,C)/A.getUint32(B+4,C);},size:8},9:{getValue:function(A,B,C){return A.getInt32(B,C);},size:4},10:{getValue:function(A,B,C){return A.getInt32(B,C)/A.getInt32(B+4,C);
+},size:8}},footer:{STANDARD:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-picture-o"></i>'}
+]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}
+]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-download"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-crop"></i>'}
+]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-trash"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
+]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
+]}]}});
index 779fa01..1142247 100644 (file)
@@ -60447,7 +60447,6 @@ Roo.LayoutStateManager.prototype = {
  */
 Roo.ContentPanel = function(el, config, content){
     
-     
     /*
     if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory
         config = el;
@@ -60831,6 +60830,14 @@ layout.addxtype({
      */
     
     addxtype : function(cfg) {
+        if(cfg.xtype.match(/^UploadCropbox$/)) {
+
+            this.cropbox = new Roo.factory(cfg);
+
+            this.cropbox.render(this.el);
+
+            return this.cropbox;
+        }
         // add form..
         if (cfg.xtype.match(/^Form$/)) {
             
@@ -68083,4 +68090,1803 @@ Roo.extend(Roo.XTemplate, Roo.Template, {
 Roo.XTemplate.from = function(el){
     el = Roo.getDom(el);
     return new Roo.XTemplate(el.value || el.innerHTML);
-};
\ No newline at end of file
+};Roo.dialog = {};
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.dialog.UploadCropbox
+ * @extends Roo.BoxComponent
+ * Dialog UploadCropbox class
+ * @cfg {String} emptyText show when image has been loaded
+ * @cfg {String} rotateNotify show when image too small to rotate
+ * @cfg {Number} errorTimeout default 3000
+ * @cfg {Number} minWidth default 300
+ * @cfg {Number} minHeight default 300
+ * @cfg {Number} outputMaxWidth default 1200
+ * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']
+ * @cfg {Boolean} isDocument (true|false) default false
+ * @cfg {String} url action url
+ * @cfg {String} paramName default 'imageUpload'
+ * @cfg {String} method default POST
+ * @cfg {Boolean} loadMask (true|false) default true
+ * @cfg {Boolean} loadingText default 'Loading...'
+ * 
+ * @constructor
+ * Create a new UploadCropbox
+ * @param {Object} config The config object
+ */
+
+ Roo.dialog.UploadCropbox = function(config){
+    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event beforeselectfile
+         * Fire before select file
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "beforeselectfile" : true,
+        /**
+         * @event initial
+         * Fire after initEvent
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "initial" : true,
+        /**
+         * @event crop
+         * Fire after initEvent
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} data
+         */
+        "crop" : true,
+        /**
+         * @event prepare
+         * Fire when preparing the file data
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} file
+         */
+        "prepare" : true,
+        /**
+         * @event exception
+         * Fire when get exception
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {XMLHttpRequest} xhr
+         */
+        "exception" : true,
+        /**
+         * @event beforeloadcanvas
+         * Fire before load the canvas
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} src
+         */
+        "beforeloadcanvas" : true,
+        /**
+         * @event trash
+         * Fire when trash image
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "trash" : true,
+        /**
+         * @event download
+         * Fire when download the image
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "download" : true,
+        /**
+         * @event footerbuttonclick
+         * Fire when footerbuttonclick
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} type
+         */
+        "footerbuttonclick" : true,
+        /**
+         * @event resize
+         * Fire when resize
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "resize" : true,
+        /**
+         * @event rotate
+         * Fire when rotate the image
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} pos
+         */
+        "rotate" : true,
+        /**
+         * @event inspect
+         * Fire when inspect the file
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} file
+         */
+        "inspect" : true,
+        /**
+         * @event upload
+         * Fire when xhr upload the file
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} data
+         */
+        "upload" : true,
+        /**
+         * @event arrange
+         * Fire when arrange the file data
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} formData
+         */
+        "arrange" : true,
+        /**
+         * @event loadcanvas
+         * Fire after load the canvas
+         * @param {Roo.dialog.UploadCropbox}
+         * @param {Object} imgEl
+         */
+        "loadcanvas" : true
+    });
+    
+    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;
+};
+
+Roo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {
+    
+    emptyText : 'Click to upload image',
+    rotateNotify : 'Image is too small to rotate',
+    errorTimeout : 3000,
+    scale : 0,
+    baseScale : 1,
+    rotate : 0,
+    dragable : false,
+    pinching : false,
+    mouseX : 0,
+    mouseY : 0,
+    cropData : false,
+    minWidth : 300,
+    minHeight : 300,
+    outputMaxWidth : 1200,
+    file : false,
+    exif : {},
+    baseRotate : 1,
+    cropType : 'image/jpeg',
+    buttons : false,
+    canvasLoaded : false,
+    isDocument : false,
+    method : 'POST',
+    paramName : 'imageUpload',
+    loadMask : true,
+    loadingText : 'Loading...',
+    maskEl : false,
+    
+    getAutoCreate : function()
+    {
+        var cfg = {
+            tag : 'div',
+            cls : 'roo-upload-cropbox',
+            cn : [
+                {
+                    tag : 'input',
+                    cls : 'roo-upload-cropbox-selector',
+                    type : 'file'
+                },
+                {
+                    tag : 'div',
+                    cls : 'roo-upload-cropbox-body',
+                    style : 'cursor:pointer',
+                    cn : [
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-preview'
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-thumb'
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-empty-notify',
+                            html : this.emptyText
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',
+                            html : this.rotateNotify
+                        }
+                    ]
+                },
+                {
+                    tag : 'div',
+                    cls : 'roo-upload-cropbox-footer',
+                    cn : {
+                        tag : 'div',
+                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
+                        cn : []
+                    }
+                }
+            ]
+        };
+        
+        return cfg;
+    },
+    
+    onRender : function(ct, position)
+    {
+        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);
+
+        if(this.el){
+            if (this.el.attr('xtype')) {
+                this.el.attr('xtypex', this.el.attr('xtype'));
+                this.el.dom.removeAttribute('xtype');
+                
+                this.initEvents();
+            }
+        }
+        else {
+            var cfg = Roo.apply({},  this.getAutoCreate());
+        
+            cfg.id = this.id || Roo.id();
+            
+            if (this.cls) {
+                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;
+            }
+            
+            if (this.style) { // fixme needs to support more complex style data.
+                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;
+            }
+            
+            this.el = ct.createChild(cfg, position);
+            
+            this.initEvents();
+        }
+        
+        if (this.buttons.length) {
+            
+            Roo.each(this.buttons, function(bb) {
+                
+                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);
+                
+                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));
+                
+            }, this);
+        }
+        
+        if(this.loadMask){
+            this.maskEl = this.el;
+        }
+    },
+    
+    initEvents : function()
+    {
+        this.urlAPI = (window.createObjectURL && window) || 
+                                (window.URL && URL.revokeObjectURL && URL) || 
+                                (window.webkitURL && webkitURL);
+                        
+        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();
+        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();
+        this.selectorEl.hide();
+        
+        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();
+        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();
+        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.thumbEl.hide();
+        
+        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();
+        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();
+        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.errorEl.hide();
+        
+        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();
+        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.footerEl.hide();
+        
+        this.setThumbBoxSize();
+        
+        this.bind();
+        
+        this.resize();
+        
+        this.fireEvent('initial', this);
+    },
+
+    bind : function()
+    {
+        var _this = this;
+        
+        window.addEventListener("resize", function() { _this.resize(); } );
+        
+        this.bodyEl.on('click', this.beforeSelectFile, this);
+        
+        if(Roo.isTouch){
+            this.bodyEl.on('touchstart', this.onTouchStart, this);
+            this.bodyEl.on('touchmove', this.onTouchMove, this);
+            this.bodyEl.on('touchend', this.onTouchEnd, this);
+        }
+        
+        if(!Roo.isTouch){
+            this.bodyEl.on('mousedown', this.onMouseDown, this);
+            this.bodyEl.on('mousemove', this.onMouseMove, this);
+            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
+            this.bodyEl.on(mousewheel, this.onMouseWheel, this);
+            Roo.get(document).on('mouseup', this.onMouseUp, this);
+        }
+        
+        this.selectorEl.on('change', this.onFileSelected, this);
+    },
+    
+    reset : function()
+    {    
+        this.scale = 0;
+        this.baseScale = 1;
+        this.rotate = 0;
+        this.baseRotate = 1;
+        this.dragable = false;
+        this.pinching = false;
+        this.mouseX = 0;
+        this.mouseY = 0;
+        this.cropData = false;
+        this.notifyEl.dom.innerHTML = this.emptyText;
+        
+        // this.selectorEl.dom.value = '';
+        
+    },
+    
+    resize : function()
+    {
+        if(this.fireEvent('resize', this) != false){
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+    },
+    
+    onFooterButtonClick : function(e, el, o, type)
+    {
+        switch (type) {
+            case 'rotate-left' :
+                this.onRotateLeft(e);
+                break;
+            case 'rotate-right' :
+                this.onRotateRight(e);
+                break;
+            case 'picture' :
+                this.beforeSelectFile(e);
+                break;
+            case 'trash' :
+                this.trash(e);
+                break;
+            case 'crop' :
+                this.crop(e);
+                break;
+            case 'download' :
+                this.download(e);
+                break;
+            default :
+                break;
+        }
+        
+        this.fireEvent('footerbuttonclick', this, type);
+    },
+    
+    beforeSelectFile : function(e)
+    {
+        e.preventDefault();
+        
+        if(this.fireEvent('beforeselectfile', this) != false){
+            this.selectorEl.dom.click();
+        }
+    },
+    
+    onFileSelected : function(e)
+    {
+        e.preventDefault();
+        
+        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
+            return;
+        }
+        
+        var file = this.selectorEl.dom.files[0];
+        
+        if(this.fireEvent('inspect', this, file) != false){
+            this.prepare(file);
+        }
+        
+    },
+    
+    trash : function(e)
+    {
+        this.fireEvent('trash', this);
+    },
+    
+    download : function(e)
+    {
+        this.fireEvent('download', this);
+    },
+    
+    loadCanvas : function(src)
+    {   
+        if(this.fireEvent('beforeloadcanvas', this, src) != false){
+            
+            this.reset();
+            
+            this.imageEl = document.createElement('img');
+            
+            var _this = this;
+            
+            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });
+            
+            this.imageEl.src = src;
+        }
+    },
+    
+    onLoadCanvas : function()
+    {   
+        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;
+        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;
+
+        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){
+        
+            this.bodyEl.un('click', this.beforeSelectFile, this);
+            
+            this.notifyEl.hide();
+            this.thumbEl.show();
+            this.footerEl.show();
+            
+            this.baseRotateLevel();
+            
+            if(this.isDocument){
+                this.setThumbBoxSize();
+            }
+            
+            this.setThumbBoxPosition();
+            
+            this.baseScaleLevel();
+            
+            this.draw();
+            
+            this.resize();
+            
+            this.canvasLoaded = true;
+        
+        }
+        
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+    },
+    
+    setCanvasPosition : function()
+    {   
+        if(!this.canvasEl){
+            return;
+        }
+        
+        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);
+        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);
+        
+        this.previewEl.setLeft(pw);
+        this.previewEl.setTop(ph);
+        
+    },
+    
+    onMouseDown : function(e)
+    {   
+        e.stopEvent();
+        
+        this.dragable = true;
+        this.pinching = false;
+        
+        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){
+            this.dragable = false;
+            return;
+        }
+        
+        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+        
+    },
+    
+    onMouseMove : function(e)
+    {   
+        e.stopEvent();
+        
+        if(!this.canvasLoaded){
+            return;
+        }
+        
+        if (!this.dragable){
+            return;
+        }
+        
+        var minX = Math.ceil(this.thumbEl.getLeft(true));
+        var minY = Math.ceil(this.thumbEl.getTop(true));
+        
+        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);
+        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);
+
+        if(minX > maxX) {
+            var tempX = minX;
+            minX = maxX;
+            maxX = tempX;
+        }
+
+        if(minY > maxY) {
+            var tempY = minY;
+            minY = maxY;
+            maxY = tempY;
+        }
+
+        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+        
+        x = x - this.mouseX;
+        y = y - this.mouseY;
+
+        var bgX = Math.ceil(x + this.previewEl.getLeft(true));
+        var bgY = Math.ceil(y + this.previewEl.getTop(true));
+        
+        bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX);
+        bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY);
+        
+        this.previewEl.setLeft(bgX);
+        this.previewEl.setTop(bgY);
+        
+        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+    },
+    
+    onMouseUp : function(e)
+    {   
+        e.stopEvent();
+        
+        this.dragable = false;
+    },
+    
+    onMouseWheel : function(e)
+    {   
+        e.stopEvent();
+        
+        this.startScale = this.scale;
+        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
+        
+        if(!this.zoomable()){
+            this.scale = this.startScale;
+            return;
+        }
+
+        
+        this.draw();
+        
+        return;
+    },
+    
+    zoomable : function()
+    {
+        var minScale = this.thumbEl.getWidth() / this.minWidth;
+        
+        if(this.minWidth < this.minHeight){
+            minScale = this.thumbEl.getHeight() / this.minHeight;
+        }
+        
+        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);
+        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);
+
+
+        var maxWidth = this.imageEl.OriginWidth;
+        var maxHeight = this.imageEl.OriginHeight;
+        
+        if(
+                this.isDocument &&
+                (this.rotate == 0 || this.rotate == 180) && 
+                (
+                    width > this.imageEl.OriginWidth || 
+                    height > this.imageEl.OriginHeight ||
+                    (width < this.minWidth && height < this.minHeight)
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                this.isDocument &&
+                (this.rotate == 90 || this.rotate == 270) && 
+                (
+                    width > this.imageEl.OriginWidth || 
+                    height > this.imageEl.OriginHeight ||
+                    (width < this.minHeight && height < this.minWidth)
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                !this.isDocument &&
+                (this.rotate == 0 || this.rotate == 180) && 
+                (
+                    (this.imageEl.OriginWidth >= this.minWidth) && width < this.minWidth ||
+                    (this.imageEl.OriginHeight >= this.minHeight) && height < this.minHeight ||
+                    width > maxWidth ||
+                    height > maxHeight
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                !this.isDocument &&
+                (this.rotate == 90 || this.rotate == 270) && 
+                (
+                    width < this.minHeight || 
+                    width > this.imageEl.OriginWidth || 
+                    height < this.minWidth || 
+                    height > this.imageEl.OriginHeight
+                )
+        ){
+            return false;
+        }
+        
+        return true;
+        
+    },
+    
+    onRotateLeft : function(e)
+    {   
+        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+            
+            var minScale = this.thumbEl.getWidth() / this.minWidth;
+            
+            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+            
+            this.startScale = this.scale;
+            
+            while (this.getScaleLevel() < minScale){
+            
+                this.scale = this.scale + 1;
+                
+                if(!this.zoomable()){
+                    break;
+                }
+                
+                if(
+                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+                ){
+                    continue;
+                }
+                
+                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+                this.draw();
+                
+                return;
+            }
+            
+            this.scale = this.startScale;
+            
+            this.onRotateFail();
+            
+            return false;
+        }
+        
+        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+        if(this.isDocument){
+            this.setThumbBoxSize();
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+        
+        this.draw();
+        
+        this.fireEvent('rotate', this, 'left');
+        
+    },
+    
+    onRotateRight : function(e)
+    {
+        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+            
+            var minScale = this.thumbEl.getWidth() / this.minWidth;
+        
+            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+            
+            this.startScale = this.scale;
+            
+            while (this.getScaleLevel() < minScale){
+            
+                this.scale = this.scale + 1;
+                
+                if(!this.zoomable()){
+                    break;
+                }
+                
+                if(
+                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+                ){
+                    continue;
+                }
+                
+                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+                this.draw();
+                
+                return;
+            }
+            
+            this.scale = this.startScale;
+            
+            this.onRotateFail();
+            
+            return false;
+        }
+        
+        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+        if(this.isDocument){
+            this.setThumbBoxSize();
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+        
+        this.draw();
+        
+        this.fireEvent('rotate', this, 'right');
+    },
+    
+    onRotateFail : function()
+    {
+        this.errorEl.show(true);
+        
+        var _this = this;
+        
+        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);
+    },
+    
+    draw : function()
+    {
+        this.previewEl.dom.innerHTML = '';
+        
+        var canvasEl = document.createElement("canvas");
+        
+        var contextEl = canvasEl.getContext("2d");
+        
+        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+        var center = this.imageEl.OriginWidth / 2;
+        
+        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){
+            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+            center = this.imageEl.OriginHeight / 2;
+        }
+        
+        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());
+        
+        contextEl.translate(center, center);
+        contextEl.rotate(this.rotate * Math.PI / 180);
+
+        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+        
+        this.canvasEl = document.createElement("canvas");
+        
+        this.contextEl = this.canvasEl.getContext("2d");
+        
+        switch (this.rotate) {
+            case 0 :
+                
+                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+                
+                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 90 : 
+                
+                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+                
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 180 :
+                
+                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+                
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 270 :
+                
+                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+        
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            default : 
+                break;
+        }
+        
+        this.previewEl.appendChild(this.canvasEl);
+        
+        this.setCanvasPosition();
+    },
+    
+    crop : function()
+    {
+        if(!this.canvasLoaded){
+            return;
+        }
+        
+        var imageCanvas = document.createElement("canvas");
+        
+        var imageContext = imageCanvas.getContext("2d");
+        
+        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+        
+        var center = imageCanvas.width / 2;
+        
+        imageContext.translate(center, center);
+        
+        imageContext.rotate(this.rotate * Math.PI / 180);
+        
+        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+        
+        var canvas = document.createElement("canvas");
+        
+        var context = canvas.getContext("2d");
+
+        canvas.width = this.thumbEl.getWidth() / this.getScaleLevel();
+        
+        canvas.height = this.thumbEl.getHeight() / this.getScaleLevel();
+
+        switch (this.rotate) {
+            case 0 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true);
+                var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true);
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+                if(canvas.width > this.outputMaxWidth) {
+                    var scale = this.outputMaxWidth / canvas.width;
+                    canvas.width = canvas.width * scale;
+                    canvas.height = canvas.height * scale;
+                    context.scale(scale, scale);
+                }
+
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 90 : 
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+                
+                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 180 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 270 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+                
+                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            default : 
+                break;
+        }
+        
+        this.cropData = canvas.toDataURL(this.cropType);
+        
+        if(this.fireEvent('crop', this, this.cropData) !== false){
+            this.process(this.file, this.cropData);
+        }
+        
+        return;
+        
+    },
+    
+    setThumbBoxSize : function()
+    {
+        var width, height;
+        
+        if(this.isDocument && typeof(this.imageEl) != 'undefined'){
+            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);
+            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);
+            
+            this.minWidth = width;
+            this.minHeight = height;
+            
+            if(this.rotate == 90 || this.rotate == 270){
+                this.minWidth = height;
+                this.minHeight = width;
+            }
+        }
+        
+        height = 300;
+        width = Math.ceil(this.minWidth * height / this.minHeight);
+        
+        if(this.minWidth > this.minHeight){
+            width = 300;
+            height = Math.ceil(this.minHeight * width / this.minWidth);
+        }
+        
+        this.thumbEl.setStyle({
+            width : width + 'px',
+            height : height + 'px'
+        });
+
+        return;
+            
+    },
+    
+    setThumbBoxPosition : function()
+    {
+        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );
+        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);
+        
+        this.thumbEl.setLeft(x);
+        this.thumbEl.setTop(y);
+        
+    },
+    
+    baseRotateLevel : function()
+    {
+        this.baseRotate = 1;
+        
+        if(
+                typeof(this.exif) != 'undefined' &&
+                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&
+                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1
+        ){
+            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
+        }
+        
+        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];
+        
+    },
+    
+    baseScaleLevel : function()
+    {
+        var width, height;
+        
+        if(this.isDocument){
+            
+            if(this.baseRotate == 6 || this.baseRotate == 8){
+            
+                height = this.thumbEl.getHeight();
+                this.baseScale = height / this.imageEl.OriginWidth;
+
+                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){
+                    width = this.thumbEl.getWidth();
+                    this.baseScale = width / this.imageEl.OriginHeight;
+                }
+
+                return;
+            }
+
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+
+            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){
+                width = this.thumbEl.getWidth();
+                this.baseScale = width / this.imageEl.OriginWidth;
+            }
+
+            return;
+        }
+        
+        if(this.baseRotate == 6 || this.baseRotate == 8){
+            
+            width = this.thumbEl.getHeight();
+            this.baseScale = width / this.imageEl.OriginHeight;
+            
+            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){
+                height = this.thumbEl.getWidth();
+                this.baseScale = height / this.imageEl.OriginHeight;
+            }
+            
+            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                height = this.thumbEl.getWidth();
+                this.baseScale = height / this.imageEl.OriginHeight;
+                
+                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){
+                    width = this.thumbEl.getHeight();
+                    this.baseScale = width / this.imageEl.OriginWidth;
+                }
+            }
+            
+            return;
+        }
+        
+        width = this.thumbEl.getWidth();
+        this.baseScale = width / this.imageEl.OriginWidth;
+        
+        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+        }
+        
+        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+            
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+            
+            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){
+                width = this.thumbEl.getWidth();
+                this.baseScale = width / this.imageEl.OriginWidth;
+            }
+            
+        }
+
+        if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) {
+            this.baseScale = width / this.minWidth;
+        }
+
+        return;
+    },
+    
+    getScaleLevel : function()
+    {
+        return this.baseScale * Math.pow(1.02, this.scale);
+    },
+    
+    onTouchStart : function(e)
+    {
+        if(!this.canvasLoaded){
+            this.beforeSelectFile(e);
+            return;
+        }
+        
+        var touches = e.browserEvent.touches;
+        
+        if(!touches){
+            return;
+        }
+        
+        if(touches.length == 1){
+            this.onMouseDown(e);
+            return;
+        }
+        
+        if(touches.length != 2){
+            return;
+        }
+        
+        var coords = [];
+        
+        for(var i = 0, finger; finger = touches[i]; i++){
+            coords.push(finger.pageX, finger.pageY);
+        }
+        
+        var x = Math.pow(coords[0] - coords[2], 2);
+        var y = Math.pow(coords[1] - coords[3], 2);
+        
+        this.startDistance = Math.sqrt(x + y);
+        
+        this.startScale = this.scale;
+        
+        this.pinching = true;
+        this.dragable = false;
+        
+    },
+    
+    onTouchMove : function(e)
+    {
+        if(!this.pinching && !this.dragable){
+            return;
+        }
+        
+        var touches = e.browserEvent.touches;
+        
+        if(!touches){
+            return;
+        }
+        
+        if(this.dragable){
+            this.onMouseMove(e);
+            return;
+        }
+        
+        var coords = [];
+        
+        for(var i = 0, finger; finger = touches[i]; i++){
+            coords.push(finger.pageX, finger.pageY);
+        }
+        
+        var x = Math.pow(coords[0] - coords[2], 2);
+        var y = Math.pow(coords[1] - coords[3], 2);
+        
+        this.endDistance = Math.sqrt(x + y);
+        
+        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));
+        
+        if(!this.zoomable()){
+            this.scale = this.startScale;
+            return;
+        }
+        
+        this.draw();
+        
+    },
+    
+    onTouchEnd : function(e)
+    {
+        this.pinching = false;
+        this.dragable = false;
+        
+    },
+    
+    process : function(file, crop)
+    {
+        if(this.loadMask){
+            this.maskEl.mask(this.loadingText);
+        }
+        
+        this.xhr = new XMLHttpRequest();
+        
+        file.xhr = this.xhr;
+
+        this.xhr.open(this.method, this.url, true);
+        
+        var headers = {
+            "Accept": "application/json",
+            "Cache-Control": "no-cache",
+            "X-Requested-With": "XMLHttpRequest"
+        };
+        
+        for (var headerName in headers) {
+            var headerValue = headers[headerName];
+            if (headerValue) {
+                this.xhr.setRequestHeader(headerName, headerValue);
+            }
+        }
+        
+        var _this = this;
+        
+        this.xhr.onload = function()
+        {
+            _this.xhrOnLoad(_this.xhr);
+        }
+        
+        this.xhr.onerror = function()
+        {
+            _this.xhrOnError(_this.xhr);
+        }
+        
+        var formData = new FormData();
+
+        formData.append('returnHTML', 'NO');
+
+        if(crop){
+            formData.append('crop', crop);
+            var blobBin = atob(crop.split(',')[1]);
+            var array = [];
+            for(var i = 0; i < blobBin.length; i++) {
+                array.push(blobBin.charCodeAt(i));
+            }
+            var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType});
+            formData.append(this.paramName, croppedFile, file.name);
+        }
+        
+        if(typeof(file.filename) != 'undefined'){
+            formData.append('filename', file.filename);
+        }
+        
+        if(typeof(file.mimetype) != 'undefined'){
+            formData.append('mimetype', file.mimetype);
+        }
+
+        if(this.fireEvent('arrange', this, formData) != false){
+            this.xhr.send(formData);
+        };
+    },
+    
+    xhrOnLoad : function(xhr)
+    {
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+        if (xhr.readyState !== 4) {
+            this.fireEvent('exception', this, xhr);
+            return;
+        }
+
+        var response = Roo.decode(xhr.responseText);
+        
+        if(!response.success){
+            this.fireEvent('exception', this, xhr);
+            return;
+        }
+        
+        var response = Roo.decode(xhr.responseText);
+        
+        this.fireEvent('upload', this, response);
+        
+    },
+    
+    xhrOnError : function()
+    {
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+        Roo.log('xhr on error');
+        
+        var response = Roo.decode(xhr.responseText);
+          
+        Roo.log(response);
+        
+    },
+    
+    prepare : function(file)
+    {   
+        if(this.loadMask){
+            this.maskEl.mask(this.loadingText);
+        }
+        
+        this.file = false;
+        this.exif = {};
+        
+        if(typeof(file) === 'string'){
+            this.loadCanvas(file);
+            return;
+        }
+        
+        if(!file || !this.urlAPI){
+            return;
+        }
+        
+        this.file = file;
+        if(typeof(file.type) != 'undefined' && file.type.length != 0) {
+            this.cropType = file.type;
+        }
+        
+        var _this = this;
+        
+        if(this.fireEvent('prepare', this, this.file) != false){
+            
+            var reader = new FileReader();
+            
+            reader.onload = function (e) {
+                if (e.target.error) {
+                    Roo.log(e.target.error);
+                    return;
+                }
+                
+                var buffer = e.target.result,
+                    dataView = new DataView(buffer),
+                    offset = 2,
+                    maxOffset = dataView.byteLength - 4,
+                    markerBytes,
+                    markerLength;
+                
+                if (dataView.getUint16(0) === 0xffd8) {
+                    while (offset < maxOffset) {
+                        markerBytes = dataView.getUint16(offset);
+                        
+                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {
+                            markerLength = dataView.getUint16(offset + 2) + 2;
+                            if (offset + markerLength > dataView.byteLength) {
+                                Roo.log('Invalid meta data: Invalid segment size.');
+                                break;
+                            }
+                            
+                            if(markerBytes == 0xffe1){
+                                _this.parseExifData(
+                                    dataView,
+                                    offset,
+                                    markerLength
+                                );
+                            }
+                            
+                            offset += markerLength;
+                            
+                            continue;
+                        }
+                        
+                        break;
+                    }
+                    
+                }
+                
+                var url = _this.urlAPI.createObjectURL(_this.file);
+                
+                _this.loadCanvas(url);
+                
+                return;
+            }
+            
+            reader.readAsArrayBuffer(this.file);
+            
+        }
+        
+    },
+    
+    parseExifData : function(dataView, offset, length)
+    {
+        var tiffOffset = offset + 10,
+            littleEndian,
+            dirOffset;
+    
+        if (dataView.getUint32(offset + 4) !== 0x45786966) {
+            // No Exif data, might be XMP data instead
+            return;
+        }
+        
+        // Check for the ASCII code for "Exif" (0x45786966):
+        if (dataView.getUint32(offset + 4) !== 0x45786966) {
+            // No Exif data, might be XMP data instead
+            return;
+        }
+        if (tiffOffset + 8 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid segment size.');
+            return;
+        }
+        // Check for the two null bytes:
+        if (dataView.getUint16(offset + 8) !== 0x0000) {
+            Roo.log('Invalid Exif data: Missing byte alignment offset.');
+            return;
+        }
+        // Check the byte alignment:
+        switch (dataView.getUint16(tiffOffset)) {
+        case 0x4949:
+            littleEndian = true;
+            break;
+        case 0x4D4D:
+            littleEndian = false;
+            break;
+        default:
+            Roo.log('Invalid Exif data: Invalid byte alignment marker.');
+            return;
+        }
+        // Check for the TIFF tag marker (0x002A):
+        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
+            Roo.log('Invalid Exif data: Missing TIFF marker.');
+            return;
+        }
+        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
+        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
+        
+        this.parseExifTags(
+            dataView,
+            tiffOffset,
+            tiffOffset + dirOffset,
+            littleEndian
+        );
+    },
+    
+    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)
+    {
+        var tagsNumber,
+            dirEndOffset,
+            i;
+        if (dirOffset + 6 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid directory offset.');
+            return;
+        }
+        tagsNumber = dataView.getUint16(dirOffset, littleEndian);
+        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
+        if (dirEndOffset + 4 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid directory size.');
+            return;
+        }
+        for (i = 0; i < tagsNumber; i += 1) {
+            this.parseExifTag(
+                dataView,
+                tiffOffset,
+                dirOffset + 2 + 12 * i, // tag offset
+                littleEndian
+            );
+        }
+        // Return the offset to the next directory:
+        return dataView.getUint32(dirEndOffset, littleEndian);
+    },
+    
+    parseExifTag : function (dataView, tiffOffset, offset, littleEndian) 
+    {
+        var tag = dataView.getUint16(offset, littleEndian);
+        
+        this.exif[tag] = this.getExifValue(
+            dataView,
+            tiffOffset,
+            offset,
+            dataView.getUint16(offset + 2, littleEndian), // tag type
+            dataView.getUint32(offset + 4, littleEndian), // tag length
+            littleEndian
+        );
+    },
+    
+    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)
+    {
+        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],
+            tagSize,
+            dataOffset,
+            values,
+            i,
+            str,
+            c;
+    
+        if (!tagType) {
+            Roo.log('Invalid Exif data: Invalid tag type.');
+            return;
+        }
+        
+        tagSize = tagType.size * length;
+        // Determine if the value is contained in the dataOffset bytes,
+        // or if the value at the dataOffset is a pointer to the actual data:
+        dataOffset = tagSize > 4 ?
+                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
+        if (dataOffset + tagSize > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid data offset.');
+            return;
+        }
+        if (length === 1) {
+            return tagType.getValue(dataView, dataOffset, littleEndian);
+        }
+        values = [];
+        for (i = 0; i < length; i += 1) {
+            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
+        }
+        
+        if (tagType.ascii) {
+            str = '';
+            // Concatenate the chars:
+            for (i = 0; i < values.length; i += 1) {
+                c = values[i];
+                // Ignore the terminating NULL byte(s):
+                if (c === '\u0000') {
+                    break;
+                }
+                str += c;
+            }
+            return str;
+        }
+        return values;
+    }
+    
+});
+
+Roo.apply(Roo.dialog.UploadCropbox, {
+    tags : {
+        'Orientation': 0x0112
+    },
+    
+    Orientation: {
+            1: 0, //'top-left',
+//            2: 'top-right',
+            3: 180, //'bottom-right',
+//            4: 'bottom-left',
+//            5: 'left-top',
+            6: 90, //'right-top',
+//            7: 'right-bottom',
+            8: 270 //'left-bottom'
+    },
+    
+    exifTagTypes : {
+        // byte, 8-bit unsigned int:
+        1: {
+            getValue: function (dataView, dataOffset) {
+                return dataView.getUint8(dataOffset);
+            },
+            size: 1
+        },
+        // ascii, 8-bit byte:
+        2: {
+            getValue: function (dataView, dataOffset) {
+                return String.fromCharCode(dataView.getUint8(dataOffset));
+            },
+            size: 1,
+            ascii: true
+        },
+        // short, 16 bit int:
+        3: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint16(dataOffset, littleEndian);
+            },
+            size: 2
+        },
+        // long, 32 bit int:
+        4: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint32(dataOffset, littleEndian);
+            },
+            size: 4
+        },
+        // rational = two long values, first is numerator, second is denominator:
+        5: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint32(dataOffset, littleEndian) /
+                    dataView.getUint32(dataOffset + 4, littleEndian);
+            },
+            size: 8
+        },
+        // slong, 32 bit signed int:
+        9: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getInt32(dataOffset, littleEndian);
+            },
+            size: 4
+        },
+        // srational, two slongs, first is numerator, second is denominator:
+        10: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getInt32(dataOffset, littleEndian) /
+                    dataView.getInt32(dataOffset + 4, littleEndian);
+            },
+            size: 8
+        }
+    },
+    
+    footer : {
+        STANDARD : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-picture',
+                action : 'picture',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-picture-o"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ],
+        DOCUMENT : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-download',
+                action : 'download',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-download"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-crop',
+                action : 'crop',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-crop"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-trash',
+                action : 'trash',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-trash"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ],
+        ROTATOR : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ]
+    }
+});
index 6623fbf..15429ff 100644 (file)
@@ -35955,7 +35955,6 @@ Roo.LayoutStateManager.prototype = {
  */
 Roo.ContentPanel = function(el, config, content){
     
-     
     /*
     if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory
         config = el;
@@ -36339,6 +36338,14 @@ layout.addxtype({
      */
     
     addxtype : function(cfg) {
+        if(cfg.xtype.match(/^UploadCropbox$/)) {
+
+            this.cropbox = new Roo.factory(cfg);
+
+            this.cropbox.render(this.el);
+
+            return this.cropbox;
+        }
         // add form..
         if (cfg.xtype.match(/^Form$/)) {
             
@@ -43591,4 +43598,1803 @@ Roo.extend(Roo.XTemplate, Roo.Template, {
 Roo.XTemplate.from = function(el){
     el = Roo.getDom(el);
     return new Roo.XTemplate(el.value || el.innerHTML);
-};
\ No newline at end of file
+};Roo.dialog = {};
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.dialog.UploadCropbox
+ * @extends Roo.BoxComponent
+ * Dialog UploadCropbox class
+ * @cfg {String} emptyText show when image has been loaded
+ * @cfg {String} rotateNotify show when image too small to rotate
+ * @cfg {Number} errorTimeout default 3000
+ * @cfg {Number} minWidth default 300
+ * @cfg {Number} minHeight default 300
+ * @cfg {Number} outputMaxWidth default 1200
+ * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']
+ * @cfg {Boolean} isDocument (true|false) default false
+ * @cfg {String} url action url
+ * @cfg {String} paramName default 'imageUpload'
+ * @cfg {String} method default POST
+ * @cfg {Boolean} loadMask (true|false) default true
+ * @cfg {Boolean} loadingText default 'Loading...'
+ * 
+ * @constructor
+ * Create a new UploadCropbox
+ * @param {Object} config The config object
+ */
+
+ Roo.dialog.UploadCropbox = function(config){
+    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event beforeselectfile
+         * Fire before select file
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "beforeselectfile" : true,
+        /**
+         * @event initial
+         * Fire after initEvent
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "initial" : true,
+        /**
+         * @event crop
+         * Fire after initEvent
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} data
+         */
+        "crop" : true,
+        /**
+         * @event prepare
+         * Fire when preparing the file data
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} file
+         */
+        "prepare" : true,
+        /**
+         * @event exception
+         * Fire when get exception
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {XMLHttpRequest} xhr
+         */
+        "exception" : true,
+        /**
+         * @event beforeloadcanvas
+         * Fire before load the canvas
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} src
+         */
+        "beforeloadcanvas" : true,
+        /**
+         * @event trash
+         * Fire when trash image
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "trash" : true,
+        /**
+         * @event download
+         * Fire when download the image
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "download" : true,
+        /**
+         * @event footerbuttonclick
+         * Fire when footerbuttonclick
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} type
+         */
+        "footerbuttonclick" : true,
+        /**
+         * @event resize
+         * Fire when resize
+         * @param {Roo.dialog.UploadCropbox} this
+         */
+        "resize" : true,
+        /**
+         * @event rotate
+         * Fire when rotate the image
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {String} pos
+         */
+        "rotate" : true,
+        /**
+         * @event inspect
+         * Fire when inspect the file
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} file
+         */
+        "inspect" : true,
+        /**
+         * @event upload
+         * Fire when xhr upload the file
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} data
+         */
+        "upload" : true,
+        /**
+         * @event arrange
+         * Fire when arrange the file data
+         * @param {Roo.dialog.UploadCropbox} this
+         * @param {Object} formData
+         */
+        "arrange" : true,
+        /**
+         * @event loadcanvas
+         * Fire after load the canvas
+         * @param {Roo.dialog.UploadCropbox}
+         * @param {Object} imgEl
+         */
+        "loadcanvas" : true
+    });
+    
+    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;
+};
+
+Roo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {
+    
+    emptyText : 'Click to upload image',
+    rotateNotify : 'Image is too small to rotate',
+    errorTimeout : 3000,
+    scale : 0,
+    baseScale : 1,
+    rotate : 0,
+    dragable : false,
+    pinching : false,
+    mouseX : 0,
+    mouseY : 0,
+    cropData : false,
+    minWidth : 300,
+    minHeight : 300,
+    outputMaxWidth : 1200,
+    file : false,
+    exif : {},
+    baseRotate : 1,
+    cropType : 'image/jpeg',
+    buttons : false,
+    canvasLoaded : false,
+    isDocument : false,
+    method : 'POST',
+    paramName : 'imageUpload',
+    loadMask : true,
+    loadingText : 'Loading...',
+    maskEl : false,
+    
+    getAutoCreate : function()
+    {
+        var cfg = {
+            tag : 'div',
+            cls : 'roo-upload-cropbox',
+            cn : [
+                {
+                    tag : 'input',
+                    cls : 'roo-upload-cropbox-selector',
+                    type : 'file'
+                },
+                {
+                    tag : 'div',
+                    cls : 'roo-upload-cropbox-body',
+                    style : 'cursor:pointer',
+                    cn : [
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-preview'
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-thumb'
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-empty-notify',
+                            html : this.emptyText
+                        },
+                        {
+                            tag : 'div',
+                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',
+                            html : this.rotateNotify
+                        }
+                    ]
+                },
+                {
+                    tag : 'div',
+                    cls : 'roo-upload-cropbox-footer',
+                    cn : {
+                        tag : 'div',
+                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
+                        cn : []
+                    }
+                }
+            ]
+        };
+        
+        return cfg;
+    },
+    
+    onRender : function(ct, position)
+    {
+        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);
+
+        if(this.el){
+            if (this.el.attr('xtype')) {
+                this.el.attr('xtypex', this.el.attr('xtype'));
+                this.el.dom.removeAttribute('xtype');
+                
+                this.initEvents();
+            }
+        }
+        else {
+            var cfg = Roo.apply({},  this.getAutoCreate());
+        
+            cfg.id = this.id || Roo.id();
+            
+            if (this.cls) {
+                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;
+            }
+            
+            if (this.style) { // fixme needs to support more complex style data.
+                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;
+            }
+            
+            this.el = ct.createChild(cfg, position);
+            
+            this.initEvents();
+        }
+        
+        if (this.buttons.length) {
+            
+            Roo.each(this.buttons, function(bb) {
+                
+                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);
+                
+                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));
+                
+            }, this);
+        }
+        
+        if(this.loadMask){
+            this.maskEl = this.el;
+        }
+    },
+    
+    initEvents : function()
+    {
+        this.urlAPI = (window.createObjectURL && window) || 
+                                (window.URL && URL.revokeObjectURL && URL) || 
+                                (window.webkitURL && webkitURL);
+                        
+        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();
+        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();
+        this.selectorEl.hide();
+        
+        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();
+        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();
+        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.thumbEl.hide();
+        
+        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();
+        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();
+        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.errorEl.hide();
+        
+        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();
+        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        this.footerEl.hide();
+        
+        this.setThumbBoxSize();
+        
+        this.bind();
+        
+        this.resize();
+        
+        this.fireEvent('initial', this);
+    },
+
+    bind : function()
+    {
+        var _this = this;
+        
+        window.addEventListener("resize", function() { _this.resize(); } );
+        
+        this.bodyEl.on('click', this.beforeSelectFile, this);
+        
+        if(Roo.isTouch){
+            this.bodyEl.on('touchstart', this.onTouchStart, this);
+            this.bodyEl.on('touchmove', this.onTouchMove, this);
+            this.bodyEl.on('touchend', this.onTouchEnd, this);
+        }
+        
+        if(!Roo.isTouch){
+            this.bodyEl.on('mousedown', this.onMouseDown, this);
+            this.bodyEl.on('mousemove', this.onMouseMove, this);
+            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
+            this.bodyEl.on(mousewheel, this.onMouseWheel, this);
+            Roo.get(document).on('mouseup', this.onMouseUp, this);
+        }
+        
+        this.selectorEl.on('change', this.onFileSelected, this);
+    },
+    
+    reset : function()
+    {    
+        this.scale = 0;
+        this.baseScale = 1;
+        this.rotate = 0;
+        this.baseRotate = 1;
+        this.dragable = false;
+        this.pinching = false;
+        this.mouseX = 0;
+        this.mouseY = 0;
+        this.cropData = false;
+        this.notifyEl.dom.innerHTML = this.emptyText;
+        
+        // this.selectorEl.dom.value = '';
+        
+    },
+    
+    resize : function()
+    {
+        if(this.fireEvent('resize', this) != false){
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+    },
+    
+    onFooterButtonClick : function(e, el, o, type)
+    {
+        switch (type) {
+            case 'rotate-left' :
+                this.onRotateLeft(e);
+                break;
+            case 'rotate-right' :
+                this.onRotateRight(e);
+                break;
+            case 'picture' :
+                this.beforeSelectFile(e);
+                break;
+            case 'trash' :
+                this.trash(e);
+                break;
+            case 'crop' :
+                this.crop(e);
+                break;
+            case 'download' :
+                this.download(e);
+                break;
+            default :
+                break;
+        }
+        
+        this.fireEvent('footerbuttonclick', this, type);
+    },
+    
+    beforeSelectFile : function(e)
+    {
+        e.preventDefault();
+        
+        if(this.fireEvent('beforeselectfile', this) != false){
+            this.selectorEl.dom.click();
+        }
+    },
+    
+    onFileSelected : function(e)
+    {
+        e.preventDefault();
+        
+        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
+            return;
+        }
+        
+        var file = this.selectorEl.dom.files[0];
+        
+        if(this.fireEvent('inspect', this, file) != false){
+            this.prepare(file);
+        }
+        
+    },
+    
+    trash : function(e)
+    {
+        this.fireEvent('trash', this);
+    },
+    
+    download : function(e)
+    {
+        this.fireEvent('download', this);
+    },
+    
+    loadCanvas : function(src)
+    {   
+        if(this.fireEvent('beforeloadcanvas', this, src) != false){
+            
+            this.reset();
+            
+            this.imageEl = document.createElement('img');
+            
+            var _this = this;
+            
+            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });
+            
+            this.imageEl.src = src;
+        }
+    },
+    
+    onLoadCanvas : function()
+    {   
+        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;
+        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;
+
+        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){
+        
+            this.bodyEl.un('click', this.beforeSelectFile, this);
+            
+            this.notifyEl.hide();
+            this.thumbEl.show();
+            this.footerEl.show();
+            
+            this.baseRotateLevel();
+            
+            if(this.isDocument){
+                this.setThumbBoxSize();
+            }
+            
+            this.setThumbBoxPosition();
+            
+            this.baseScaleLevel();
+            
+            this.draw();
+            
+            this.resize();
+            
+            this.canvasLoaded = true;
+        
+        }
+        
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+    },
+    
+    setCanvasPosition : function()
+    {   
+        if(!this.canvasEl){
+            return;
+        }
+        
+        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);
+        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);
+        
+        this.previewEl.setLeft(pw);
+        this.previewEl.setTop(ph);
+        
+    },
+    
+    onMouseDown : function(e)
+    {   
+        e.stopEvent();
+        
+        this.dragable = true;
+        this.pinching = false;
+        
+        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){
+            this.dragable = false;
+            return;
+        }
+        
+        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+        
+    },
+    
+    onMouseMove : function(e)
+    {   
+        e.stopEvent();
+        
+        if(!this.canvasLoaded){
+            return;
+        }
+        
+        if (!this.dragable){
+            return;
+        }
+        
+        var minX = Math.ceil(this.thumbEl.getLeft(true));
+        var minY = Math.ceil(this.thumbEl.getTop(true));
+        
+        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);
+        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);
+
+        if(minX > maxX) {
+            var tempX = minX;
+            minX = maxX;
+            maxX = tempX;
+        }
+
+        if(minY > maxY) {
+            var tempY = minY;
+            minY = maxY;
+            maxY = tempY;
+        }
+
+        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+        
+        x = x - this.mouseX;
+        y = y - this.mouseY;
+
+        var bgX = Math.ceil(x + this.previewEl.getLeft(true));
+        var bgY = Math.ceil(y + this.previewEl.getTop(true));
+        
+        bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX);
+        bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY);
+        
+        this.previewEl.setLeft(bgX);
+        this.previewEl.setTop(bgY);
+        
+        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
+        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
+    },
+    
+    onMouseUp : function(e)
+    {   
+        e.stopEvent();
+        
+        this.dragable = false;
+    },
+    
+    onMouseWheel : function(e)
+    {   
+        e.stopEvent();
+        
+        this.startScale = this.scale;
+        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
+        
+        if(!this.zoomable()){
+            this.scale = this.startScale;
+            return;
+        }
+
+        
+        this.draw();
+        
+        return;
+    },
+    
+    zoomable : function()
+    {
+        var minScale = this.thumbEl.getWidth() / this.minWidth;
+        
+        if(this.minWidth < this.minHeight){
+            minScale = this.thumbEl.getHeight() / this.minHeight;
+        }
+        
+        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);
+        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);
+
+
+        var maxWidth = this.imageEl.OriginWidth;
+        var maxHeight = this.imageEl.OriginHeight;
+        
+        if(
+                this.isDocument &&
+                (this.rotate == 0 || this.rotate == 180) && 
+                (
+                    width > this.imageEl.OriginWidth || 
+                    height > this.imageEl.OriginHeight ||
+                    (width < this.minWidth && height < this.minHeight)
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                this.isDocument &&
+                (this.rotate == 90 || this.rotate == 270) && 
+                (
+                    width > this.imageEl.OriginWidth || 
+                    height > this.imageEl.OriginHeight ||
+                    (width < this.minHeight && height < this.minWidth)
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                !this.isDocument &&
+                (this.rotate == 0 || this.rotate == 180) && 
+                (
+                    (this.imageEl.OriginWidth >= this.minWidth) && width < this.minWidth ||
+                    (this.imageEl.OriginHeight >= this.minHeight) && height < this.minHeight ||
+                    width > maxWidth ||
+                    height > maxHeight
+                )
+        ){
+            return false;
+        }
+        
+        if(
+                !this.isDocument &&
+                (this.rotate == 90 || this.rotate == 270) && 
+                (
+                    width < this.minHeight || 
+                    width > this.imageEl.OriginWidth || 
+                    height < this.minWidth || 
+                    height > this.imageEl.OriginHeight
+                )
+        ){
+            return false;
+        }
+        
+        return true;
+        
+    },
+    
+    onRotateLeft : function(e)
+    {   
+        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+            
+            var minScale = this.thumbEl.getWidth() / this.minWidth;
+            
+            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+            
+            this.startScale = this.scale;
+            
+            while (this.getScaleLevel() < minScale){
+            
+                this.scale = this.scale + 1;
+                
+                if(!this.zoomable()){
+                    break;
+                }
+                
+                if(
+                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+                ){
+                    continue;
+                }
+                
+                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+                this.draw();
+                
+                return;
+            }
+            
+            this.scale = this.startScale;
+            
+            this.onRotateFail();
+            
+            return false;
+        }
+        
+        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
+
+        if(this.isDocument){
+            this.setThumbBoxSize();
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+        
+        this.draw();
+        
+        this.fireEvent('rotate', this, 'left');
+        
+    },
+    
+    onRotateRight : function(e)
+    {
+        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
+            
+            var minScale = this.thumbEl.getWidth() / this.minWidth;
+        
+            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
+            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
+            
+            this.startScale = this.scale;
+            
+            while (this.getScaleLevel() < minScale){
+            
+                this.scale = this.scale + 1;
+                
+                if(!this.zoomable()){
+                    break;
+                }
+                
+                if(
+                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
+                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
+                ){
+                    continue;
+                }
+                
+                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+                this.draw();
+                
+                return;
+            }
+            
+            this.scale = this.startScale;
+            
+            this.onRotateFail();
+            
+            return false;
+        }
+        
+        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+
+        if(this.isDocument){
+            this.setThumbBoxSize();
+            this.setThumbBoxPosition();
+            this.setCanvasPosition();
+        }
+        
+        this.draw();
+        
+        this.fireEvent('rotate', this, 'right');
+    },
+    
+    onRotateFail : function()
+    {
+        this.errorEl.show(true);
+        
+        var _this = this;
+        
+        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);
+    },
+    
+    draw : function()
+    {
+        this.previewEl.dom.innerHTML = '';
+        
+        var canvasEl = document.createElement("canvas");
+        
+        var contextEl = canvasEl.getContext("2d");
+        
+        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+        var center = this.imageEl.OriginWidth / 2;
+        
+        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){
+            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+            center = this.imageEl.OriginHeight / 2;
+        }
+        
+        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());
+        
+        contextEl.translate(center, center);
+        contextEl.rotate(this.rotate * Math.PI / 180);
+
+        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+        
+        this.canvasEl = document.createElement("canvas");
+        
+        this.contextEl = this.canvasEl.getContext("2d");
+        
+        switch (this.rotate) {
+            case 0 :
+                
+                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+                
+                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 90 : 
+                
+                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+                
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 180 :
+                
+                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
+                
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            case 270 :
+                
+                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
+                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
+        
+                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                    break;
+                }
+                
+                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
+                
+                break;
+            default : 
+                break;
+        }
+        
+        this.previewEl.appendChild(this.canvasEl);
+        
+        this.setCanvasPosition();
+    },
+    
+    crop : function()
+    {
+        if(!this.canvasLoaded){
+            return;
+        }
+        
+        var imageCanvas = document.createElement("canvas");
+        
+        var imageContext = imageCanvas.getContext("2d");
+        
+        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
+        
+        var center = imageCanvas.width / 2;
+        
+        imageContext.translate(center, center);
+        
+        imageContext.rotate(this.rotate * Math.PI / 180);
+        
+        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
+        
+        var canvas = document.createElement("canvas");
+        
+        var context = canvas.getContext("2d");
+
+        canvas.width = this.thumbEl.getWidth() / this.getScaleLevel();
+        
+        canvas.height = this.thumbEl.getHeight() / this.getScaleLevel();
+
+        switch (this.rotate) {
+            case 0 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true);
+                var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true);
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+                if(canvas.width > this.outputMaxWidth) {
+                    var scale = this.outputMaxWidth / canvas.width;
+                    canvas.width = canvas.width * scale;
+                    canvas.height = canvas.height * scale;
+                    context.scale(scale, scale);
+                }
+
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 90 : 
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+                
+                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 180 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+
+                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            case 270 :
+                
+                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
+                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
+                
+                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
+                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
+                
+                var targetWidth = this.minWidth - 2 * x;
+                var targetHeight = this.minHeight - 2 * y;
+                
+                var scale = 1;
+                
+                if((x == 0 && y == 0) || (x == 0 && y > 0)){
+                    scale = targetWidth / width;
+                }
+                
+                if(x > 0 && y == 0){
+                    scale = targetHeight / height;
+                }
+                
+                if(x > 0 && y > 0){
+                    scale = targetWidth / width;
+                    
+                    if(width < height){
+                        scale = targetHeight / height;
+                    }
+                }
+                
+                context.scale(scale, scale);
+                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
+                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
+
+                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
+                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
+                
+                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
+                
+                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
+                
+                break;
+            default : 
+                break;
+        }
+        
+        this.cropData = canvas.toDataURL(this.cropType);
+        
+        if(this.fireEvent('crop', this, this.cropData) !== false){
+            this.process(this.file, this.cropData);
+        }
+        
+        return;
+        
+    },
+    
+    setThumbBoxSize : function()
+    {
+        var width, height;
+        
+        if(this.isDocument && typeof(this.imageEl) != 'undefined'){
+            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);
+            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);
+            
+            this.minWidth = width;
+            this.minHeight = height;
+            
+            if(this.rotate == 90 || this.rotate == 270){
+                this.minWidth = height;
+                this.minHeight = width;
+            }
+        }
+        
+        height = 300;
+        width = Math.ceil(this.minWidth * height / this.minHeight);
+        
+        if(this.minWidth > this.minHeight){
+            width = 300;
+            height = Math.ceil(this.minHeight * width / this.minWidth);
+        }
+        
+        this.thumbEl.setStyle({
+            width : width + 'px',
+            height : height + 'px'
+        });
+
+        return;
+            
+    },
+    
+    setThumbBoxPosition : function()
+    {
+        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );
+        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);
+        
+        this.thumbEl.setLeft(x);
+        this.thumbEl.setTop(y);
+        
+    },
+    
+    baseRotateLevel : function()
+    {
+        this.baseRotate = 1;
+        
+        if(
+                typeof(this.exif) != 'undefined' &&
+                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&
+                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1
+        ){
+            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
+        }
+        
+        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];
+        
+    },
+    
+    baseScaleLevel : function()
+    {
+        var width, height;
+        
+        if(this.isDocument){
+            
+            if(this.baseRotate == 6 || this.baseRotate == 8){
+            
+                height = this.thumbEl.getHeight();
+                this.baseScale = height / this.imageEl.OriginWidth;
+
+                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){
+                    width = this.thumbEl.getWidth();
+                    this.baseScale = width / this.imageEl.OriginHeight;
+                }
+
+                return;
+            }
+
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+
+            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){
+                width = this.thumbEl.getWidth();
+                this.baseScale = width / this.imageEl.OriginWidth;
+            }
+
+            return;
+        }
+        
+        if(this.baseRotate == 6 || this.baseRotate == 8){
+            
+            width = this.thumbEl.getHeight();
+            this.baseScale = width / this.imageEl.OriginHeight;
+            
+            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){
+                height = this.thumbEl.getWidth();
+                this.baseScale = height / this.imageEl.OriginHeight;
+            }
+            
+            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+                height = this.thumbEl.getWidth();
+                this.baseScale = height / this.imageEl.OriginHeight;
+                
+                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){
+                    width = this.thumbEl.getHeight();
+                    this.baseScale = width / this.imageEl.OriginWidth;
+                }
+            }
+            
+            return;
+        }
+        
+        width = this.thumbEl.getWidth();
+        this.baseScale = width / this.imageEl.OriginWidth;
+        
+        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+        }
+        
+        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
+            
+            height = this.thumbEl.getHeight();
+            this.baseScale = height / this.imageEl.OriginHeight;
+            
+            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){
+                width = this.thumbEl.getWidth();
+                this.baseScale = width / this.imageEl.OriginWidth;
+            }
+            
+        }
+
+        if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) {
+            this.baseScale = width / this.minWidth;
+        }
+
+        return;
+    },
+    
+    getScaleLevel : function()
+    {
+        return this.baseScale * Math.pow(1.02, this.scale);
+    },
+    
+    onTouchStart : function(e)
+    {
+        if(!this.canvasLoaded){
+            this.beforeSelectFile(e);
+            return;
+        }
+        
+        var touches = e.browserEvent.touches;
+        
+        if(!touches){
+            return;
+        }
+        
+        if(touches.length == 1){
+            this.onMouseDown(e);
+            return;
+        }
+        
+        if(touches.length != 2){
+            return;
+        }
+        
+        var coords = [];
+        
+        for(var i = 0, finger; finger = touches[i]; i++){
+            coords.push(finger.pageX, finger.pageY);
+        }
+        
+        var x = Math.pow(coords[0] - coords[2], 2);
+        var y = Math.pow(coords[1] - coords[3], 2);
+        
+        this.startDistance = Math.sqrt(x + y);
+        
+        this.startScale = this.scale;
+        
+        this.pinching = true;
+        this.dragable = false;
+        
+    },
+    
+    onTouchMove : function(e)
+    {
+        if(!this.pinching && !this.dragable){
+            return;
+        }
+        
+        var touches = e.browserEvent.touches;
+        
+        if(!touches){
+            return;
+        }
+        
+        if(this.dragable){
+            this.onMouseMove(e);
+            return;
+        }
+        
+        var coords = [];
+        
+        for(var i = 0, finger; finger = touches[i]; i++){
+            coords.push(finger.pageX, finger.pageY);
+        }
+        
+        var x = Math.pow(coords[0] - coords[2], 2);
+        var y = Math.pow(coords[1] - coords[3], 2);
+        
+        this.endDistance = Math.sqrt(x + y);
+        
+        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));
+        
+        if(!this.zoomable()){
+            this.scale = this.startScale;
+            return;
+        }
+        
+        this.draw();
+        
+    },
+    
+    onTouchEnd : function(e)
+    {
+        this.pinching = false;
+        this.dragable = false;
+        
+    },
+    
+    process : function(file, crop)
+    {
+        if(this.loadMask){
+            this.maskEl.mask(this.loadingText);
+        }
+        
+        this.xhr = new XMLHttpRequest();
+        
+        file.xhr = this.xhr;
+
+        this.xhr.open(this.method, this.url, true);
+        
+        var headers = {
+            "Accept": "application/json",
+            "Cache-Control": "no-cache",
+            "X-Requested-With": "XMLHttpRequest"
+        };
+        
+        for (var headerName in headers) {
+            var headerValue = headers[headerName];
+            if (headerValue) {
+                this.xhr.setRequestHeader(headerName, headerValue);
+            }
+        }
+        
+        var _this = this;
+        
+        this.xhr.onload = function()
+        {
+            _this.xhrOnLoad(_this.xhr);
+        }
+        
+        this.xhr.onerror = function()
+        {
+            _this.xhrOnError(_this.xhr);
+        }
+        
+        var formData = new FormData();
+
+        formData.append('returnHTML', 'NO');
+
+        if(crop){
+            formData.append('crop', crop);
+            var blobBin = atob(crop.split(',')[1]);
+            var array = [];
+            for(var i = 0; i < blobBin.length; i++) {
+                array.push(blobBin.charCodeAt(i));
+            }
+            var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType});
+            formData.append(this.paramName, croppedFile, file.name);
+        }
+        
+        if(typeof(file.filename) != 'undefined'){
+            formData.append('filename', file.filename);
+        }
+        
+        if(typeof(file.mimetype) != 'undefined'){
+            formData.append('mimetype', file.mimetype);
+        }
+
+        if(this.fireEvent('arrange', this, formData) != false){
+            this.xhr.send(formData);
+        };
+    },
+    
+    xhrOnLoad : function(xhr)
+    {
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+        if (xhr.readyState !== 4) {
+            this.fireEvent('exception', this, xhr);
+            return;
+        }
+
+        var response = Roo.decode(xhr.responseText);
+        
+        if(!response.success){
+            this.fireEvent('exception', this, xhr);
+            return;
+        }
+        
+        var response = Roo.decode(xhr.responseText);
+        
+        this.fireEvent('upload', this, response);
+        
+    },
+    
+    xhrOnError : function()
+    {
+        if(this.loadMask){
+            this.maskEl.unmask();
+        }
+        
+        Roo.log('xhr on error');
+        
+        var response = Roo.decode(xhr.responseText);
+          
+        Roo.log(response);
+        
+    },
+    
+    prepare : function(file)
+    {   
+        if(this.loadMask){
+            this.maskEl.mask(this.loadingText);
+        }
+        
+        this.file = false;
+        this.exif = {};
+        
+        if(typeof(file) === 'string'){
+            this.loadCanvas(file);
+            return;
+        }
+        
+        if(!file || !this.urlAPI){
+            return;
+        }
+        
+        this.file = file;
+        if(typeof(file.type) != 'undefined' && file.type.length != 0) {
+            this.cropType = file.type;
+        }
+        
+        var _this = this;
+        
+        if(this.fireEvent('prepare', this, this.file) != false){
+            
+            var reader = new FileReader();
+            
+            reader.onload = function (e) {
+                if (e.target.error) {
+                    Roo.log(e.target.error);
+                    return;
+                }
+                
+                var buffer = e.target.result,
+                    dataView = new DataView(buffer),
+                    offset = 2,
+                    maxOffset = dataView.byteLength - 4,
+                    markerBytes,
+                    markerLength;
+                
+                if (dataView.getUint16(0) === 0xffd8) {
+                    while (offset < maxOffset) {
+                        markerBytes = dataView.getUint16(offset);
+                        
+                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {
+                            markerLength = dataView.getUint16(offset + 2) + 2;
+                            if (offset + markerLength > dataView.byteLength) {
+                                Roo.log('Invalid meta data: Invalid segment size.');
+                                break;
+                            }
+                            
+                            if(markerBytes == 0xffe1){
+                                _this.parseExifData(
+                                    dataView,
+                                    offset,
+                                    markerLength
+                                );
+                            }
+                            
+                            offset += markerLength;
+                            
+                            continue;
+                        }
+                        
+                        break;
+                    }
+                    
+                }
+                
+                var url = _this.urlAPI.createObjectURL(_this.file);
+                
+                _this.loadCanvas(url);
+                
+                return;
+            }
+            
+            reader.readAsArrayBuffer(this.file);
+            
+        }
+        
+    },
+    
+    parseExifData : function(dataView, offset, length)
+    {
+        var tiffOffset = offset + 10,
+            littleEndian,
+            dirOffset;
+    
+        if (dataView.getUint32(offset + 4) !== 0x45786966) {
+            // No Exif data, might be XMP data instead
+            return;
+        }
+        
+        // Check for the ASCII code for "Exif" (0x45786966):
+        if (dataView.getUint32(offset + 4) !== 0x45786966) {
+            // No Exif data, might be XMP data instead
+            return;
+        }
+        if (tiffOffset + 8 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid segment size.');
+            return;
+        }
+        // Check for the two null bytes:
+        if (dataView.getUint16(offset + 8) !== 0x0000) {
+            Roo.log('Invalid Exif data: Missing byte alignment offset.');
+            return;
+        }
+        // Check the byte alignment:
+        switch (dataView.getUint16(tiffOffset)) {
+        case 0x4949:
+            littleEndian = true;
+            break;
+        case 0x4D4D:
+            littleEndian = false;
+            break;
+        default:
+            Roo.log('Invalid Exif data: Invalid byte alignment marker.');
+            return;
+        }
+        // Check for the TIFF tag marker (0x002A):
+        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
+            Roo.log('Invalid Exif data: Missing TIFF marker.');
+            return;
+        }
+        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
+        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
+        
+        this.parseExifTags(
+            dataView,
+            tiffOffset,
+            tiffOffset + dirOffset,
+            littleEndian
+        );
+    },
+    
+    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)
+    {
+        var tagsNumber,
+            dirEndOffset,
+            i;
+        if (dirOffset + 6 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid directory offset.');
+            return;
+        }
+        tagsNumber = dataView.getUint16(dirOffset, littleEndian);
+        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
+        if (dirEndOffset + 4 > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid directory size.');
+            return;
+        }
+        for (i = 0; i < tagsNumber; i += 1) {
+            this.parseExifTag(
+                dataView,
+                tiffOffset,
+                dirOffset + 2 + 12 * i, // tag offset
+                littleEndian
+            );
+        }
+        // Return the offset to the next directory:
+        return dataView.getUint32(dirEndOffset, littleEndian);
+    },
+    
+    parseExifTag : function (dataView, tiffOffset, offset, littleEndian) 
+    {
+        var tag = dataView.getUint16(offset, littleEndian);
+        
+        this.exif[tag] = this.getExifValue(
+            dataView,
+            tiffOffset,
+            offset,
+            dataView.getUint16(offset + 2, littleEndian), // tag type
+            dataView.getUint32(offset + 4, littleEndian), // tag length
+            littleEndian
+        );
+    },
+    
+    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)
+    {
+        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],
+            tagSize,
+            dataOffset,
+            values,
+            i,
+            str,
+            c;
+    
+        if (!tagType) {
+            Roo.log('Invalid Exif data: Invalid tag type.');
+            return;
+        }
+        
+        tagSize = tagType.size * length;
+        // Determine if the value is contained in the dataOffset bytes,
+        // or if the value at the dataOffset is a pointer to the actual data:
+        dataOffset = tagSize > 4 ?
+                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
+        if (dataOffset + tagSize > dataView.byteLength) {
+            Roo.log('Invalid Exif data: Invalid data offset.');
+            return;
+        }
+        if (length === 1) {
+            return tagType.getValue(dataView, dataOffset, littleEndian);
+        }
+        values = [];
+        for (i = 0; i < length; i += 1) {
+            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
+        }
+        
+        if (tagType.ascii) {
+            str = '';
+            // Concatenate the chars:
+            for (i = 0; i < values.length; i += 1) {
+                c = values[i];
+                // Ignore the terminating NULL byte(s):
+                if (c === '\u0000') {
+                    break;
+                }
+                str += c;
+            }
+            return str;
+        }
+        return values;
+    }
+    
+});
+
+Roo.apply(Roo.dialog.UploadCropbox, {
+    tags : {
+        'Orientation': 0x0112
+    },
+    
+    Orientation: {
+            1: 0, //'top-left',
+//            2: 'top-right',
+            3: 180, //'bottom-right',
+//            4: 'bottom-left',
+//            5: 'left-top',
+            6: 90, //'right-top',
+//            7: 'right-bottom',
+            8: 270 //'left-bottom'
+    },
+    
+    exifTagTypes : {
+        // byte, 8-bit unsigned int:
+        1: {
+            getValue: function (dataView, dataOffset) {
+                return dataView.getUint8(dataOffset);
+            },
+            size: 1
+        },
+        // ascii, 8-bit byte:
+        2: {
+            getValue: function (dataView, dataOffset) {
+                return String.fromCharCode(dataView.getUint8(dataOffset));
+            },
+            size: 1,
+            ascii: true
+        },
+        // short, 16 bit int:
+        3: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint16(dataOffset, littleEndian);
+            },
+            size: 2
+        },
+        // long, 32 bit int:
+        4: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint32(dataOffset, littleEndian);
+            },
+            size: 4
+        },
+        // rational = two long values, first is numerator, second is denominator:
+        5: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getUint32(dataOffset, littleEndian) /
+                    dataView.getUint32(dataOffset + 4, littleEndian);
+            },
+            size: 8
+        },
+        // slong, 32 bit signed int:
+        9: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getInt32(dataOffset, littleEndian);
+            },
+            size: 4
+        },
+        // srational, two slongs, first is numerator, second is denominator:
+        10: {
+            getValue: function (dataView, dataOffset, littleEndian) {
+                return dataView.getInt32(dataOffset, littleEndian) /
+                    dataView.getInt32(dataOffset + 4, littleEndian);
+            },
+            size: 8
+        }
+    },
+    
+    footer : {
+        STANDARD : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-picture',
+                action : 'picture',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-picture-o"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ],
+        DOCUMENT : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-download',
+                action : 'download',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-download"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-crop',
+                action : 'crop',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-crop"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-trash',
+                action : 'trash',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-trash"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ],
+        ROTATOR : [
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-left',
+                action : 'rotate-left',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-undo"></i>'
+                    }
+                ]
+            },
+            {
+                tag : 'div',
+                cls : 'btn-group roo-upload-cropbox-rotate-right',
+                action : 'rotate-right',
+                cn : [
+                    {
+                        tag : 'button',
+                        cls : 'btn btn-default',
+                        html : '<i class="fa fa-repeat"></i>'
+                    }
+                ]
+            }
+        ]
+    }
+});
index 40ce72d..3297f8a 100644 (file)
@@ -1599,9 +1599,9 @@ return this.el.getUpdateManager();},_handleRefresh:function(A,B,C){if(!C||!this.
 te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B);
 this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A);
 }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();
-}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();
-this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,'');
-this.view=B;return B;}return false;}});
+}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A);
+this.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));
+var B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}});
 // Roo/GridPanel.js
 Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B);
 if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo);
@@ -1930,3 +1930,104 @@ F.push("(typeof("+G+") == 'undefined')");});var H='(('+F.join(" || ")+") ? undef
 }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){  with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){  with (values) { return ['"];
 B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{}
 );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);};
+// Roo/dialog/namespace.js
+Roo.dialog={};
+// Roo/dialog/UploadCropbox.js
+Roo.dialog.UploadCropbox=function(A){Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true}
+);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,outputMaxWidth:1200,file:false,exif:{}
+,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'}
+,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify}
+]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));
+this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style;
+}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);C.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true));
+},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first();
+this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
+this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
+this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
+this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this);
+this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);this.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel';
+this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false;
+this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();this.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e);
+break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);break;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A);
+},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return;
+}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset();
+this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;this.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height;
+if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();if(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition();
+this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);var ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2);
+this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.width<this.thumbEl.getWidth()||this.canvasEl.height<this.thumbEl.getHeight())){this.dragable=false;
+return;}this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseMove:function(e){e.stopEvent();if(!this.canvasLoaded){return;}if(!this.dragable){return;}var A=Math.ceil(this.thumbEl.getLeft(true));
+var B=Math.ceil(this.thumbEl.getTop(true));var C=Math.ceil(A+this.thumbEl.getWidth()-this.canvasEl.width);var D=Math.ceil(B+this.thumbEl.getHeight()-this.canvasEl.height);if(A>C){var E=A;A=C;C=E;}if(B>D){var F=B;B=D;D=F;}var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();
+var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();x=x-this.mouseX;y=y-this.mouseY;var G=Math.ceil(x+this.previewEl.getLeft(true));var H=Math.ceil(y+this.previewEl.getTop(true));G=(G<A)?A:((G>C)?C:G);H=(H<B)?B:((H>D)?D:H);this.previewEl.setLeft(G);
+this.previewEl.setTop(H);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent();
+this.startScale=this.scale;this.scale=(e.getWheelDelta()==1)?(this.scale+1):(this.scale-1);if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidth<this.minHeight){A=this.thumbEl.getHeight()/this.minHeight;
+}var B=Math.ceil(this.imageEl.OriginWidth*this.getScaleLevel()/A);var C=Math.ceil(this.imageEl.OriginHeight*this.getScaleLevel()/A);var D=this.imageEl.OriginWidth;var E=this.imageEl.OriginHeight;if(this.isDocument&&(this.rotate==0||this.rotate==180)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minWidth&&C<this.minHeight))){return false;
+}if(this.isDocument&&(this.rotate==90||this.rotate==270)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minHeight&&C<this.minWidth))){return false;}if(!this.isDocument&&(this.rotate==0||this.rotate==180)&&((this.imageEl.OriginWidth>=this.minWidth)&&B<this.minWidth||(this.imageEl.OriginHeight>=this.minHeight)&&C<this.minHeight||B>D||C>E)){return false;
+}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(B<this.minHeight||B>this.imageEl.OriginWidth||C<this.minWidth||C>this.imageEl.OriginHeight)){return false;}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;
+var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
+}this.rotate=(this.rotate<90)?270:this.rotate-90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate<90)?270:this.rotate-90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
+}this.draw();this.fireEvent('rotate',this,'left');},onRotateRight:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());
+var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
+}this.rotate=(this.rotate>180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
+}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas");
+var B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidth<this.imageEl.OriginHeight){A.width=this.imageEl.OriginHeight*this.getScaleLevel();
+A.height=this.imageEl.OriginHeight*this.getScaleLevel();C=this.imageEl.OriginHeight/2;}B.scale(this.getScaleLevel(),this.getScaleLevel());B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);
+this.canvasEl=document.createElement("canvas");this.contextEl=this.canvasEl.getContext("2d");switch(this.rotate){case 0:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;case 90:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();
+if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
+break;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition();
+},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;
+var C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d");
+D.width=this.thumbEl.getWidth()/this.getScaleLevel();D.height=this.thumbEl.getHeight()/this.getScaleLevel();switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
+var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
+var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var sx=this.thumbEl.getLeft(true)-this.previewEl.getLeft(true);var sy=this.thumbEl.getTop(true)-this.previewEl.getTop(true);
+sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());if(D.width>this.outputMaxWidth){var H=this.outputMaxWidth/D.width;D.width=D.width*H;D.height=D.height*H;E.scale(H,H);}E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());
+var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
+var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
+}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
+sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
+var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
+var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
+}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
+sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;
+E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());
+var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());
+var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));
+var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);
+E.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType);if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight);
+B=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=300;A=Math.ceil(this.minWidth*B/this.minHeight);
+if(this.minWidth>this.minHeight){A=300;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2);var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);
+this.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
+}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();
+this.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;
+}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getWidth()){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;
+}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getHeight()){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginWidth;
+}}return;}A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getHeight()){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getHeight();
+this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;}}if(this.imageEl.OriginWidth<this.minWidth||this.imageEl.OriginHeight<this.minHeight){this.baseScale=A/this.minWidth;
+}return;},getScaleLevel:function(){return this.baseScale*Math.pow(1.02,this.scale);},onTouchStart:function(e){if(!this.canvasLoaded){this.beforeSelectFile(e);return;}var A=e.browserEvent.touches;if(!A){return;}if(A.length==1){this.onMouseDown(e);return;}if(A.length!=2){return;
+}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.startDistance=Math.sqrt(x+y);this.startScale=this.scale;this.pinching=true;this.dragable=false;},onTouchMove:function(e){if(!this.pinching&&!this.dragable){return;
+}var A=e.browserEvent.touches;if(!A){return;}if(this.dragable){this.onMouseMove(e);return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.endDistance=Math.sqrt(x+y);this.scale=this.startScale+Math.floor(Math.log(this.endDistance/this.startDistance)/Math.log(1.1));
+if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();},onTouchEnd:function(e){this.pinching=false;this.dragable=false;},process:function(A,B){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.xhr=new XMLHttpRequest();A.xhr=this.xhr;
+this.xhr.open(this.method,this.url,true);var C={"Accept":"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"};for(var D in C){var E=C[D];if(E){this.xhr.setRequestHeader(D,E);}}var F=this;this.xhr.onload=function(){F.xhrOnLoad(F.xhr);
+};this.xhr.onerror=function(){F.xhrOnError(F.xhr);};var G=new FormData();G.append('returnHTML','NO');if(B){G.append('crop',B);var H=atob(B.split(',')[1]);var I=[];for(var i=0;i<H.length;i++){I.push(H.charCodeAt(i));}var J=new Blob([new Uint8Array(I)],{type:this.cropType}
+);G.append(this.paramName,J,A.name);}if(typeof(A.filename)!='undefined'){G.append('filename',A.filename);}if(typeof(A.mimetype)!='undefined'){G.append('mimetype',A.mimetype);}if(this.fireEvent('arrange',this,G)!=false){this.xhr.send(G);};},xhrOnLoad:function(A){if(this.loadMask){this.maskEl.unmask();
+}if(A.readyState!==4){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);if(!B.success){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);this.fireEvent('upload',this,B);},xhrOnError:function(){if(this.loadMask){this.maskEl.unmask();
+}Roo.log('xhr on error');var A=Roo.decode(xhr.responseText);Roo.log(A);},prepare:function(A){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.file=false;this.exif={};if(typeof(A)==='string'){this.loadCanvas(A);return;}if(!A||!this.urlAPI){return;
+}this.file=A;if(typeof(A.type)!='undefined'&&A.type.length!=0){this.cropType=A.type;}var B=this;if(this.fireEvent('prepare',this,this.file)!=false){var C=new FileReader();C.onload=function(e){if(e.target.error){Roo.log(e.target.error);return;}var D=e.target.result,E=new DataView(D),F=2,G=E.byteLength-4,H,I;
+if(E.getUint16(0)===0xffd8){while(F<G){H=E.getUint16(F);if((H>=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');break;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break;
+}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.');
+return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;default:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return;
+}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;if(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.');
+return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i<E;i+=1){this.parseExifTag(A,B,C+2+12*i,D);}return A.getUint32(F,D);},parseExifTag:function(A,B,C,D){var E=A.getUint16(C,D);this.exif[E]=this.getExifValue(A,B,C,A.getUint16(C+2,D),A.getUint32(C+4,D),D);
+},getExifValue:function(A,B,C,D,E,F){var G=Roo.dialog.UploadCropbox.exifTagTypes[D],H,I,J,i,K,c;if(!G){Roo.log('Invalid Exif data: Invalid tag type.');return;}H=G.size*E;I=H>4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.');
+return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i<E;i+=1){J[i]=G.getValue(A,I+i*G.size,F);}if(G.ascii){K='';for(i=0;i<J.length;i+=1){c=J[i];if(c==='\u0000'){break;}K+=c;}return K;}return J;}});Roo.apply(Roo.dialog.UploadCropbox,{tags:{'Orientation':0x0112
+}
+,Orientation:{1:0,3:180,6:90,8:270},exifTagTypes:{1:{getValue:function(A,B){return A.getUint8(B);},size:1},2:{getValue:function(A,B){return String.fromCharCode(A.getUint8(B));},size:1,ascii:true},3:{getValue:function(A,B,C){return A.getUint16(B,C);},size:2}
+,4:{getValue:function(A,B,C){return A.getUint32(B,C);},size:4},5:{getValue:function(A,B,C){return A.getUint32(B,C)/A.getUint32(B+4,C);},size:8},9:{getValue:function(A,B,C){return A.getInt32(B,C);},size:4},10:{getValue:function(A,B,C){return A.getInt32(B,C)/A.getInt32(B+4,C);
+},size:8}},footer:{STANDARD:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-picture-o"></i>'}
+]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}
+]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-download"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-crop"></i>'}
+]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-trash"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
+]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
+]}]}});