Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / ext-all-debug.js
index 1b11a0e..00231c8 100644 (file)
-/*
- * Ext JS Library 3.1.0
- * Copyright(c) 2006-2009 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
+
+(function(){
+
+var EXTUTIL = Ext.util,
+    EACH = Ext.each,
+    TRUE = true,
+    FALSE = false;
+
+EXTUTIL.Observable = function(){
+    
+    var me = this, e = me.events;
+    if(me.listeners){
+        me.on(me.listeners);
+        delete me.listeners;
+    }
+    me.events = e || {};
+};
+
+EXTUTIL.Observable.prototype = {
+    
+    filterOptRe : /^(?:scope|delay|buffer|single)$/,
+
+    
+    fireEvent : function(){
+        var a = Array.prototype.slice.call(arguments, 0),
+            ename = a[0].toLowerCase(),
+            me = this,
+            ret = TRUE,
+            ce = me.events[ename],
+            cc,
+            q,
+            c;
+        if (me.eventsSuspended === TRUE) {
+            if (q = me.eventQueue) {
+                q.push(a);
+            }
+        }
+        else if(typeof ce == 'object') {
+            if (ce.bubble){
+                if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
+                    return FALSE;
+                }
+                c = me.getBubbleTarget && me.getBubbleTarget();
+                if(c && c.enableBubble) {
+                    cc = c.events[ename];
+                    if(!cc || typeof cc != 'object' || !cc.bubble) {
+                        c.enableBubble(ename);
+                    }
+                    return c.fireEvent.apply(c, a);
+                }
+            }
+            else {
+                a.shift();
+                ret = ce.fire.apply(ce, a);
+            }
+        }
+        return ret;
+    },
+
+    
+    addListener : function(eventName, fn, scope, o){
+        var me = this,
+            e,
+            oe,
+            ce;
+            
+        if (typeof eventName == 'object') {
+            o = eventName;
+            for (e in o) {
+                oe = o[e];
+                if (!me.filterOptRe.test(e)) {
+                    me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
+                }
+            }
+        } else {
+            eventName = eventName.toLowerCase();
+            ce = me.events[eventName] || TRUE;
+            if (typeof ce == 'boolean') {
+                me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
+            }
+            ce.addListener(fn, scope, typeof o == 'object' ? o : {});
+        }
+    },
+
+    
+    removeListener : function(eventName, fn, scope){
+        var ce = this.events[eventName.toLowerCase()];
+        if (typeof ce == 'object') {
+            ce.removeListener(fn, scope);
+        }
+    },
+
+    
+    purgeListeners : function(){
+        var events = this.events,
+            evt,
+            key;
+        for(key in events){
+            evt = events[key];
+            if(typeof evt == 'object'){
+                evt.clearListeners();
+            }
+        }
+    },
+
+    
+    addEvents : function(o){
+        var me = this;
+        me.events = me.events || {};
+        if (typeof o == 'string') {
+            var a = arguments,
+                i = a.length;
+            while(i--) {
+                me.events[a[i]] = me.events[a[i]] || TRUE;
+            }
+        } else {
+            Ext.applyIf(me.events, o);
+        }
+    },
+
+    
+    hasListener : function(eventName){
+        var e = this.events[eventName.toLowerCase()];
+        return typeof e == 'object' && e.listeners.length > 0;
+    },
+
+    
+    suspendEvents : function(queueSuspended){
+        this.eventsSuspended = TRUE;
+        if(queueSuspended && !this.eventQueue){
+            this.eventQueue = [];
+        }
+    },
+
+    
+    resumeEvents : function(){
+        var me = this,
+            queued = me.eventQueue || [];
+        me.eventsSuspended = FALSE;
+        delete me.eventQueue;
+        EACH(queued, function(e) {
+            me.fireEvent.apply(me, e);
+        });
+    }
+};
+
+var OBSERVABLE = EXTUTIL.Observable.prototype;
+
+OBSERVABLE.on = OBSERVABLE.addListener;
+
+OBSERVABLE.un = OBSERVABLE.removeListener;
+
+
+EXTUTIL.Observable.releaseCapture = function(o){
+    o.fireEvent = OBSERVABLE.fireEvent;
+};
+
+function createTargeted(h, o, scope){
+    return function(){
+        if(o.target == arguments[0]){
+            h.apply(scope, Array.prototype.slice.call(arguments, 0));
+        }
+    };
+};
+
+function createBuffered(h, o, l, scope){
+    l.task = new EXTUTIL.DelayedTask();
+    return function(){
+        l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
+    };
+};
+
+function createSingle(h, e, fn, scope){
+    return function(){
+        e.removeListener(fn, scope);
+        return h.apply(scope, arguments);
+    };
+};
+
+function createDelayed(h, o, l, scope){
+    return function(){
+        var task = new EXTUTIL.DelayedTask(),
+            args = Array.prototype.slice.call(arguments, 0);
+        if(!l.tasks) {
+            l.tasks = [];
+        }
+        l.tasks.push(task);
+        task.delay(o.delay || 10, function(){
+            l.tasks.remove(task);
+            h.apply(scope, args);
+        }, scope);
+    };
+};
+
+EXTUTIL.Event = function(obj, name){
+    this.name = name;
+    this.obj = obj;
+    this.listeners = [];
+};
+
+EXTUTIL.Event.prototype = {
+    addListener : function(fn, scope, options){
+        var me = this,
+            l;
+        scope = scope || me.obj;
+        if(!me.isListening(fn, scope)){
+            l = me.createListener(fn, scope, options);
+            if(me.firing){ 
+                me.listeners = me.listeners.slice(0);
+            }
+            me.listeners.push(l);
+        }
+    },
+
+    createListener: function(fn, scope, o){
+        o = o || {};
+        scope = scope || this.obj;
+        var l = {
+            fn: fn,
+            scope: scope,
+            options: o
+        }, h = fn;
+        if(o.target){
+            h = createTargeted(h, o, scope);
+        }
+        if(o.delay){
+            h = createDelayed(h, o, l, scope);
+        }
+        if(o.single){
+            h = createSingle(h, this, fn, scope);
+        }
+        if(o.buffer){
+            h = createBuffered(h, o, l, scope);
+        }
+        l.fireFn = h;
+        return l;
+    },
+
+    findListener : function(fn, scope){
+        var list = this.listeners,
+            i = list.length,
+            l;
+
+        scope = scope || this.obj;
+        while(i--){
+            l = list[i];
+            if(l){
+                if(l.fn == fn && l.scope == scope){
+                    return i;
+                }
+            }
+        }
+        return -1;
+    },
+
+    isListening : function(fn, scope){
+        return this.findListener(fn, scope) != -1;
+    },
+
+    removeListener : function(fn, scope){
+        var index,
+            l,
+            k,
+            me = this,
+            ret = FALSE;
+        if((index = me.findListener(fn, scope)) != -1){
+            if (me.firing) {
+                me.listeners = me.listeners.slice(0);
+            }
+            l = me.listeners[index];
+            if(l.task) {
+                l.task.cancel();
+                delete l.task;
+            }
+            k = l.tasks && l.tasks.length;
+            if(k) {
+                while(k--) {
+                    l.tasks[k].cancel();
+                }
+                delete l.tasks;
+            }
+            me.listeners.splice(index, 1);
+            ret = TRUE;
+        }
+        return ret;
+    },
+
+    
+    clearListeners : function(){
+        var me = this,
+            l = me.listeners,
+            i = l.length;
+        while(i--) {
+            me.removeListener(l[i].fn, l[i].scope);
+        }
+    },
+
+    fire : function(){
+        var me = this,
+            listeners = me.listeners,
+            len = listeners.length,
+            i = 0,
+            l;
+
+        if(len > 0){
+            me.firing = TRUE;
+            var args = Array.prototype.slice.call(arguments, 0);
+            for (; i < len; i++) {
+                l = listeners[i];
+                if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
+                    return (me.firing = FALSE);
+                }
+            }
+        }
+        me.firing = FALSE;
+        return TRUE;
+    }
+
+};
+})();
 
 Ext.DomHelper = function(){
     var tempTableEl = null,
         emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
         tableRe = /^table|tbody|tr|td$/i,
+        confRe = /tag|children|cn|html$/i,
+        tableElRe = /td|tr|tbody/i,
+        cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
+        endRe = /end/i,
         pub,
         
         afterbegin = 'afterbegin',
@@ -34,10 +352,9 @@ Ext.DomHelper = function(){
             attr,
             val,
             key,
-            keyVal,
             cn;
 
-        if(Ext.isString(o)){
+        if(typeof o == "string"){
             b = o;
         } else if (Ext.isArray(o)) {
             for (var i=0; i < o.length; i++) {
@@ -47,19 +364,20 @@ Ext.DomHelper = function(){
             };
         } else {
             b += '<' + (o.tag = o.tag || 'div');
-            Ext.iterate(o, function(attr, val){
-                if(!/tag|children|cn|html$/i.test(attr)){
-                    if (Ext.isObject(val)) {
+            for (attr in o) {
+                val = o[attr];
+                if(!confRe.test(attr)){
+                    if (typeof val == "object") {
                         b += ' ' + attr + '="';
-                        Ext.iterate(val, function(key, keyVal){
-                            b += key + ':' + keyVal + ';';
-                        });
+                        for (key in val) {
+                            b += key + ':' + val[key] + ';';
+                        };
                         b += '"';
                     }else{
                         b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
                     }
                 }
-            });
+            };
             
             if (emptyTags.test(o.tag)) {
                 b += '/>';
@@ -105,7 +423,7 @@ Ext.DomHelper = function(){
         tempTableEl = tempTableEl || document.createElement('div');
 
         if(tag == 'td' && (where == afterbegin || where == beforeend) ||
-           !/td|tr|tbody/i.test(tag) && (where == beforebegin || where == afterend)) {
+           !tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
             return;
         }
         before = where == beforebegin ? el :
@@ -134,24 +452,23 @@ Ext.DomHelper = function(){
         markup : function(o){
             return createHtml(o);
         },
-        
+
         
         applyStyles : function(el, styles){
-            if(styles){
-                var i = 0,
-                    len,
-                    style;
+            if (styles) {
+                var matches;
 
                 el = Ext.fly(el);
-                if(Ext.isFunction(styles)){
+                if (typeof styles == "function") {
                     styles = styles.call();
                 }
-                if(Ext.isString(styles)){
-                    styles = styles.trim().split(/\s*(?::|;)\s*/);
-                    for(len = styles.length; i < len;){
-                        el.setStyle(styles[i++], styles[i++]);
+                if (typeof styles == "string") {
+                    
+                    cssRe.lastIndex = 0;
+                    while ((matches = cssRe.exec(styles))) {
+                        el.setStyle(matches[1], matches[2]);
                     }
-                }else if (Ext.isObject(styles)){
+                } else if (typeof styles == "object") {
                     el.setStyle(styles);
                 }
             }
@@ -185,7 +502,7 @@ Ext.DomHelper = function(){
                 }
             } else {
                 range = el.ownerDocument.createRange();
-                setStart = 'setStart' + (/end/i.test(where) ? 'After' : 'Before');
+                setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
                 if (hash[where]) {
                     range[setStart](el);
                     frag = range.createContextualFragment(html);
@@ -241,128 +558,24 @@ Ext.DomHelper = function(){
     };
     return pub;
 }();
-Ext.apply(Ext.DomHelper,
-function(){
-       var pub,
-               afterbegin = 'afterbegin',
-       afterend = 'afterend',
-       beforebegin = 'beforebegin',
-       beforeend = 'beforeend';
-
-       
-    function doInsert(el, o, returnElement, pos, sibling, append){
-        el = Ext.getDom(el);
-        var newNode;
-        if (pub.useDom) {
-            newNode = createDom(o, null);
-            if (append) {
-                   el.appendChild(newNode);
-            } else {
-                       (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
-            }
-        } else {
-            newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
-        }
-        return returnElement ? Ext.get(newNode, true) : newNode;
-    }
-
-       
-    
-    function createDom(o, parentNode){
-        var el,
-               doc = document,
-               useSet,
-               attr,
-               val,
-               cn;
-
-        if (Ext.isArray(o)) {                       
-            el = doc.createDocumentFragment(); 
-               Ext.each(o, function(v) {
-                createDom(v, el);
-            });
-        } else if (Ext.isString(o)) {         
-            el = doc.createTextNode(o);
-        } else {
-            el = doc.createElement( o.tag || 'div' );
-            useSet = !!el.setAttribute; 
-            Ext.iterate(o, function(attr, val){
-                if(!/tag|children|cn|html|style/.test(attr)){
-                       if(attr == 'cls'){
-                           el.className = val;
-                       }else{
-                        if(useSet){
-                            el.setAttribute(attr, val);
-                        }else{
-                            el[attr] = val;
-                        }
-                       }
-                }
-            });
-            Ext.DomHelper.applyStyles(el, o.style);
 
-            if ((cn = o.children || o.cn)) {
-                createDom(cn, el);
-            } else if (o.html) {
-                el.innerHTML = o.html;
-            }
-        }
-        if(parentNode){
-           parentNode.appendChild(el);
-        }
-        return el;
-    }
-
-       pub = {
-               
-           createTemplate : function(o){
-               var html = Ext.DomHelper.createHtml(o);
-               return new Ext.Template(html);
-           },
-
-               
-           useDom : false,
-
-           
-           insertBefore : function(el, o, returnElement){
-               return doInsert(el, o, returnElement, beforebegin);
-           },
-
-           
-           insertAfter : function(el, o, returnElement){
-               return doInsert(el, o, returnElement, afterend, 'nextSibling');
-           },
-
-           
-           insertFirst : function(el, o, returnElement){
-               return doInsert(el, o, returnElement, afterbegin, 'firstChild');
-           },
-
-           
-           append: function(el, o, returnElement){
-            return doInsert(el, o, returnElement, beforeend, '', true);
-        },
-
-           
-        createDom: createDom
-       };
-       return pub;
-}());
 Ext.Template = function(html){
     var me = this,
-       a = arguments,
-       buf = [];
+        a = arguments,
+        buf = [],
+        v;
 
     if (Ext.isArray(html)) {
         html = html.join("");
     } else if (a.length > 1) {
-           Ext.each(a, function(v) {
-            if (Ext.isObject(v)) {
+        for(var i = 0, len = a.length; i < len; i++){
+            v = a[i];
+            if(typeof v == 'object'){
                 Ext.apply(me, v);
             } else {
                 buf.push(v);
             }
-        });
+        };
         html = buf.join('');
     }
 
@@ -380,18 +593,18 @@ Ext.Template.prototype = {
 
     
     applyTemplate : function(values){
-               var me = this;
+        var me = this;
 
         return me.compiled ?
-                       me.compiled(values) :
-                               me.html.replace(me.re, function(m, name){
-                               return values[name] !== undefined ? values[name] : "";
-                       });
-       },
+                me.compiled(values) :
+                me.html.replace(me.re, function(m, name){
+                    return values[name] !== undefined ? values[name] : "";
+                });
+    },
 
     
     set : function(html, compile){
-           var me = this;
+        var me = this;
         me.html = html;
         me.compiled = null;
         return compile ? me.compile() : me;
@@ -400,13 +613,13 @@ Ext.Template.prototype = {
     
     compile : function(){
         var me = this,
-               sep = Ext.isGecko ? "+" : ",";
+            sep = Ext.isGecko ? "+" : ",";
 
-        function fn(m, name){                        
-               name = "values['" + name + "']";
-               return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
+        function fn(m, name){
+            name = "values['" + name + "']";
+            return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
         }
-                
+
         eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
              me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
              (Ext.isGecko ?  "';};" : "'].join('');};"));
@@ -454,95 +667,7 @@ Ext.Template.from = function(el, config){
     el = Ext.getDom(el);
     return new Ext.Template(el.value || el.innerHTML, config || '');
 };
-Ext.apply(Ext.Template.prototype, {
-    
-    disableFormats : false,                            
-    
 
-    
-    re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
-
-    
-    applyTemplate : function(values){
-               var me = this,
-                       useF = me.disableFormats !== true,
-               fm = Ext.util.Format, 
-               tpl = me;           
-           
-        if(me.compiled){
-            return me.compiled(values);
-        }
-        function fn(m, name, format, args){
-            if (format && useF) {
-                if (format.substr(0, 5) == "this.") {
-                    return tpl.call(format.substr(5), values[name], values);
-                } else {
-                    if (args) {
-                        
-                        
-                        
-                        var re = /^\s*['"](.*)["']\s*$/;
-                        args = args.split(',');
-                        for(var i = 0, len = args.length; i < len; i++){
-                            args[i] = args[i].replace(re, "$1");
-                        }
-                        args = [values[name]].concat(args);
-                    } else {
-                        args = [values[name]];
-                    }
-                    return fm[format].apply(fm, args);
-                }
-            } else {
-                return values[name] !== undefined ? values[name] : "";
-            }
-        }
-        return me.html.replace(me.re, fn);
-    },
-               
-    
-    compile : function(){
-        var me = this,
-               fm = Ext.util.Format,
-               useF = me.disableFormats !== true,
-               sep = Ext.isGecko ? "+" : ",",
-               body;
-        
-        function fn(m, name, format, args){
-            if(format && useF){
-                args = args ? ',' + args : "";
-                if(format.substr(0, 5) != "this."){
-                    format = "fm." + format + '(';
-                }else{
-                    format = 'this.call("'+ format.substr(5) + '", ';
-                    args = ", values";
-                }
-            }else{
-                args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
-            }
-            return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
-        }
-        
-        
-        if(Ext.isGecko){
-            body = "this.compiled = function(values){ return '" +
-                   me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
-                    "';};";
-        }else{
-            body = ["this.compiled = function(values){ return ['"];
-            body.push(me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
-            body.push("'].join('');};");
-            body = body.join('');
-        }
-        eval(body);
-        return me;
-    },
-    
-    
-    call : function(fnName, value, allValues){
-        return this[fnName](value, allValues);
-    }
-});
-Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate; 
 
 Ext.DomQuery = function(){
     var cache = {}, 
@@ -556,18 +681,20 @@ Ext.DomQuery = function(){
        nthRe = /(\d*)n\+?(\d*)/, 
        nthRe2 = /\D/,
        
-           
-           
-           isIE = window.ActiveXObject ? true : false,
-           key = 30803;
-           
-    
        
-       eval("var batch = 30803;");     
+       
+       isIE = window.ActiveXObject ? true : false,
+       key = 30803;
+    
+    
+    
+    eval("var batch = 30803;");        
 
-    function child(p, index){
+    
+    
+    function child(parent, index){
         var i = 0,
-               n = p.firstChild;
+            n = parent.firstChild;
         while(n){
             if(n.nodeType == 1){
                if(++i == index){
@@ -577,53 +704,65 @@ Ext.DomQuery = function(){
             n = n.nextSibling;
         }
         return null;
-    };
+    }
 
-    function next(n){
+    
+    function next(n){  
         while((n = n.nextSibling) && n.nodeType != 1);
         return n;
-    };
+    }
 
+    
     function prev(n){
         while((n = n.previousSibling) && n.nodeType != 1);
         return n;
-    };
+    }
 
-    function children(d){
-        var n = d.firstChild, ni = -1,
-               nx;
-           while(n){
-               nx = n.nextSibling;
-               if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
-                   d.removeChild(n);
-               }else{
-                   n.nodeIndex = ++ni;
-               }
-               n = nx;
-           }
-           return this;
-       };
-
-    function byClassName(c, a, v){
-        if(!v){
-            return c;
+    
+    
+    function children(parent){
+        var n = parent.firstChild,
+           nodeIndex = -1,
+           nextNode;
+       while(n){
+           nextNode = n.nextSibling;
+           
+           if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
+               parent.removeChild(n);
+           }else{
+               
+               n.nodeIndex = ++nodeIndex;
+           }
+           n = nextNode;
+       }
+       return this;
+    }
+
+
+    
+    
+    function byClassName(nodeSet, cls){
+        if(!cls){
+            return nodeSet;
         }
-        var r = [], ri = -1, cn;
-        for(var i = 0, ci; ci = c[i]; i++){
-            if((' '+ci.className+' ').indexOf(v) != -1){
-                r[++ri] = ci;
+        var result = [], ri = -1;
+        for(var i = 0, ci; ci = nodeSet[i]; i++){
+            if((' '+ci.className+' ').indexOf(cls) != -1){
+                result[++ri] = ci;
             }
         }
-        return r;
+        return result;
     };
 
     function attrValue(n, attr){
+       
         if(!n.tagName && typeof n.length != "undefined"){
             n = n[0];
         }
         if(!n){
             return null;
         }
+
         if(attr == "for"){
             return n.htmlFor;
         }
@@ -634,15 +773,23 @@ Ext.DomQuery = function(){
 
     };
 
+
+    
+    
+    
     function getNodes(ns, mode, tagName){
         var result = [], ri = -1, cs;
         if(!ns){
             return result;
         }
         tagName = tagName || "*";
+       
         if(typeof ns.getElementsByTagName != "undefined"){
             ns = [ns];
         }
+       
+       
+       
         if(!mode){
             for(var i = 0, ni; ni = ns[i]; i++){
                 cs = ni.getElementsByTagName(tagName);
@@ -650,7 +797,9 @@ Ext.DomQuery = function(){
                     result[++ri] = ci;
                 }
             }
-        }else if(mode == "/" || mode == ">"){
+       
+       
+        } else if(mode == "/" || mode == ">"){
             var utag = tagName.toUpperCase();
             for(var i = 0, ni, cn; ni = ns[i]; i++){
                 cn = ni.childNodes;
@@ -660,6 +809,8 @@ Ext.DomQuery = function(){
                     }
                 }
             }
+       
+       
         }else if(mode == "+"){
             var utag = tagName.toUpperCase();
             for(var i = 0, n; n = ns[i]; i++){
@@ -668,6 +819,8 @@ Ext.DomQuery = function(){
                     result[++ri] = n;
                 }
             }
+       
+       
         }else if(mode == "~"){
             var utag = tagName.toUpperCase();
             for(var i = 0, n; n = ns[i]; i++){
@@ -679,7 +832,7 @@ Ext.DomQuery = function(){
             }
         }
         return result;
-    };
+    }
 
     function concat(a, b){
         if(b.slice){
@@ -698,69 +851,87 @@ Ext.DomQuery = function(){
         if(!tagName){
             return cs;
         }
-        var r = [], ri = -1;
+        var result = [], ri = -1;
         tagName = tagName.toLowerCase();
         for(var i = 0, ci; ci = cs[i]; i++){
-            if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
-                r[++ri] = ci;
+            if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
+                result[++ri] = ci;
             }
         }
-        return r;
-    };
+        return result;
+    }
 
-    function byId(cs, attr, id){
+    function byId(cs, id){
         if(cs.tagName || cs == document){
             cs = [cs];
         }
         if(!id){
             return cs;
         }
-        var r = [], ri = -1;
-        for(var i = 0,ci; ci = cs[i]; i++){
+        var result = [], ri = -1;
+        for(var i = 0, ci; ci = cs[i]; i++){
             if(ci && ci.id == id){
-                r[++ri] = ci;
-                return r;
+                result[++ri] = ci;
+                return result;
             }
         }
-        return r;
-    };
+        return result;
+    }
 
+    
+    
     function byAttribute(cs, attr, value, op, custom){
-        var r = [], 
-               ri = -1, 
-               st = custom=="{",
-               f = Ext.DomQuery.operators[op];
+        var result = [], 
+            ri = -1, 
+            useGetStyle = custom == "{",           
+            fn = Ext.DomQuery.operators[op],       
+            a,
+            xml,
+            hasXml;
+            
         for(var i = 0, ci; ci = cs[i]; i++){
+           
             if(ci.nodeType != 1){
                 continue;
             }
-            var a;
-            if(st){
-                a = Ext.DomQuery.getStyle(ci, attr);
+            
+            if(!hasXml){
+                xml = Ext.DomQuery.isXml(ci);
+                hasXml = true;
             }
-            else if(attr == "class" || attr == "className"){
-                a = ci.className;
-            }else if(attr == "for"){
-                a = ci.htmlFor;
-            }else if(attr == "href"){
-                a = ci.getAttribute("href", 2);
+           
+            
+            if(!xml){
+                if(useGetStyle){
+                    a = Ext.DomQuery.getStyle(ci, attr);
+                } else if (attr == "class" || attr == "className"){
+                    a = ci.className;
+                } else if (attr == "for"){
+                    a = ci.htmlFor;
+                } else if (attr == "href"){
+                   
+                   
+                    a = ci.getAttribute("href", 2);
+                } else{
+                    a = ci.getAttribute(attr);
+                }
             }else{
                 a = ci.getAttribute(attr);
             }
-            if((f && f(a, value)) || (!f && a)){
-                r[++ri] = ci;
+            if((fn && fn(a, value)) || (!fn && a)){
+                result[++ri] = ci;
             }
         }
-        return r;
-    };
+        return result;
+    }
 
     function byPseudo(cs, name, value){
         return Ext.DomQuery.pseudos[name](cs, value);
-    };
+    }
 
     function nodupIEXml(cs){
         var d = ++key, 
-               r;
+            r;
         cs[0].setAttribute("_nodup", d);
         r = [cs[0]];
         for(var i = 1, len = cs.length; i < len; i++){
@@ -811,7 +982,7 @@ Ext.DomQuery = function(){
 
     function quickDiffIEXml(c1, c2){
         var d = ++key,
-               r = [];
+            r = [];
         for(var i = 0, len = c1.length; i < len; i++){
             c1[i].setAttribute("_qdiff", d);
         }        
@@ -853,7 +1024,7 @@ Ext.DomQuery = function(){
            return d.getElementById(id);
         }
         ns = getNodes(ns, mode, "*");
-        return byId(ns, null, id);
+        return byId(ns, id);
     }
 
     return {
@@ -864,104 +1035,135 @@ Ext.DomQuery = function(){
         compile : function(path, type){
             type = type || "select";
 
+           
             var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
-               q = path, mode, lq,
-               tk = Ext.DomQuery.matchers,
-               tklen = tk.length,
-               mm,
+                       mode,           
+                       lastPath,
+               matchers = Ext.DomQuery.matchers,
+               matchersLn = matchers.length,
+               modeMatch,
                
-               lmode = q.match(modeRe);
+               lmode = path.match(modeRe);
             
             if(lmode && lmode[1]){
                 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
-                q = q.replace(lmode[1], "");
+                path = path.replace(lmode[1], "");
             }
+           
             
             while(path.substr(0, 1)=="/"){
                 path = path.substr(1);
             }
 
-            while(q && lq != q){
-                lq = q;
-                var tm = q.match(tagTokenRe);
+            while(path && lastPath != path){
+                lastPath = path;
+                var tokenMatch = path.match(tagTokenRe);
                 if(type == "select"){
-                    if(tm){
-                        if(tm[1] == "#"){
-                            fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
+                    if(tokenMatch){
+                       
+                        if(tokenMatch[1] == "#"){
+                            fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';                        
                         }else{
-                            fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
+                            fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
                         }
-                        q = q.replace(tm[0], "");
-                    }else if(q.substr(0, 1) != '@'){
+                        path = path.replace(tokenMatch[0], "");
+                    }else if(path.substr(0, 1) != '@'){
                         fn[fn.length] = 'n = getNodes(n, mode, "*");';
                     }
+               
                 }else{
-                    if(tm){
-                        if(tm[1] == "#"){
-                            fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
+                    if(tokenMatch){
+                        if(tokenMatch[1] == "#"){
+                            fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
                         }else{
-                            fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
+                            fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
                         }
-                        q = q.replace(tm[0], "");
+                        path = path.replace(tokenMatch[0], "");
                     }
                 }
-                while(!(mm = q.match(modeRe))){
+                while(!(modeMatch = path.match(modeRe))){
                     var matched = false;
-                    for(var j = 0; j < tklen; j++){
-                        var t = tk[j];
-                        var m = q.match(t.re);
+                    for(var j = 0; j < matchersLn; j++){
+                        var t = matchers[j];
+                        var m = path.match(t.re);
                         if(m){
                             fn[fn.length] = t.select.replace(tplRe, function(x, i){
-                                                    return m[i];
-                                                });
-                            q = q.replace(m[0], "");
+                               return m[i];
+                           });
+                            path = path.replace(m[0], "");
                             matched = true;
                             break;
                         }
                     }
                     
                     if(!matched){
-                        throw 'Error parsing selector, parsing failed at "' + q + '"';
+                        throw 'Error parsing selector, parsing failed at "' + path + '"';
                     }
                 }
-                if(mm[1]){
-                    fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
-                    q = q.replace(mm[1], "");
+                if(modeMatch[1]){
+                    fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
+                    path = path.replace(modeMatch[1], "");
                 }
             }
+           
             fn[fn.length] = "return nodup(n);\n}";
+           
+           
             eval(fn.join(""));
             return f;
         },
 
         
-        select : function(path, root, type){
-            if(!root || root == document){
-                root = document;
-            }
+       jsSelect: function(path, root, type){
+           
+           root = root || document;
+           
             if(typeof root == "string"){
                 root = document.getElementById(root);
             }
             var paths = path.split(","),
                results = [];
-            for(var i = 0, len = paths.length; i < len; i++){
-                var p = paths[i].replace(trimRe, "");
-                if(!cache[p]){
-                    cache[p] = Ext.DomQuery.compile(p);
-                    if(!cache[p]){
-                        throw p + " is not a valid selector";
+               
+           
+            for(var i = 0, len = paths.length; i < len; i++){          
+                var subPath = paths[i].replace(trimRe, "");
+               
+                if(!cache[subPath]){
+                    cache[subPath] = Ext.DomQuery.compile(subPath);
+                    if(!cache[subPath]){
+                        throw subPath + " is not a valid selector";
                     }
                 }
-                var result = cache[p](root);
+                var result = cache[subPath](root);
                 if(result && result != document){
                     results = results.concat(result);
                 }
             }
+           
+           
+           
             if(paths.length > 1){
                 return nodup(results);
             }
             return results;
         },
+       isXml: function(el) {
+           var docEl = (el ? el.ownerDocument || el : 0).documentElement;
+           return docEl ? docEl.nodeName !== "HTML" : false;
+       },
+        select : document.querySelectorAll ? function(path, root, type) {
+           root = root || document;
+           if (!Ext.DomQuery.isXml(root)) {
+               try {
+                   var cs = root.querySelectorAll(path);
+                   return Ext.toArray(cs);
+               }
+               catch (ex) {}           
+           }       
+           return Ext.DomQuery.jsSelect.call(this, path, root, type);
+       } : function(path, root, type) {
+           return Ext.DomQuery.jsSelect.call(this, path, root, type);
+       },
 
         
         selectNode : function(path, root){
@@ -976,7 +1178,11 @@ Ext.DomQuery = function(){
             }
             var n = valueCache[path](root), v;
             n = n[0] ? n[0] : n;
-            
+                   
+           
+           
+           
+           
             if (typeof n.normalize == 'function') n.normalize();
             
             v = (n && n.firstChild ? n.firstChild.nodeValue : null);
@@ -1012,7 +1218,7 @@ Ext.DomQuery = function(){
         
         matchers : [{
                 re: /^\.([\w-]+)/,
-                select: 'n = byClassName(n, null, " {1} ");'
+                select: 'n = byClassName(n, " {1} ");'
             }, {
                 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
                 select: 'n = byPseudo(n, "{1}", "{2}");'
@@ -1021,7 +1227,7 @@ Ext.DomQuery = function(){
                 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
             }, {
                 re: /^#([\w-]+)/,
-                select: 'n = byId(n, null, "{1}");'
+                select: 'n = byId(n, "{1}");'
             },{
                 re: /^@([\w-]+)/,
                 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
@@ -1269,8030 +1475,9886 @@ Ext.util.DelayedTask = function(fn, scope, args){
             id = null;
         }
     };
-};(function(){
+};
+(function(){
+var DOC = document;
 
-var EXTUTIL = Ext.util,
-    TOARRAY = Ext.toArray,
-    EACH = Ext.each,
-    ISOBJECT = Ext.isObject,
-    TRUE = true,
-    FALSE = false;
+Ext.Element = function(element, forceNew){
+    var dom = typeof element == "string" ?
+              DOC.getElementById(element) : element,
+        id;
 
-EXTUTIL.Observable = function(){
-    
-    var me = this, e = me.events;
-    if(me.listeners){
-        me.on(me.listeners);
-        delete me.listeners;
+    if(!dom) return null;
+
+    id = dom.id;
+
+    if(!forceNew && id && Ext.elCache[id]){ 
+        return Ext.elCache[id].el;
     }
-    me.events = e || {};
-};
 
-EXTUTIL.Observable.prototype = {
     
-    filterOptRe : /^(?:scope|delay|buffer|single)$/,
+    this.dom = dom;
 
     
-    fireEvent : function(){
-        var a = TOARRAY(arguments),
-            ename = a[0].toLowerCase(),
-            me = this,
-            ret = TRUE,
-            ce = me.events[ename],
-            q,
-            c;
-        if (me.eventsSuspended === TRUE) {
-            if (q = me.eventQueue) {
-                q.push(a);
-            }
-        }
-        else if(ISOBJECT(ce) && ce.bubble){
-            if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
-                return FALSE;
-            }
-            c = me.getBubbleTarget && me.getBubbleTarget();
-            if(c && c.enableBubble) {
-                if(!c.events[ename] || !Ext.isObject(c.events[ename]) || !c.events[ename].bubble) {
-                    c.enableBubble(ename);
+    this.id = id || Ext.id(dom);
+};
+
+var DH = Ext.DomHelper,
+    El = Ext.Element,
+    EC = Ext.elCache;
+
+El.prototype = {
+    
+    set : function(o, useSet){
+        var el = this.dom,
+            attr,
+            val,
+            useSet = (useSet !== false) && !!el.setAttribute;
+
+        for (attr in o) {
+            if (o.hasOwnProperty(attr)) {
+                val = o[attr];
+                if (attr == 'style') {
+                    DH.applyStyles(el, val);
+                } else if (attr == 'cls') {
+                    el.className = val;
+                } else if (useSet) {
+                    el.setAttribute(attr, val);
+                } else {
+                    el[attr] = val;
                 }
-                return c.fireEvent.apply(c, a);
-            }
-        }
-        else {
-            if (ISOBJECT(ce)) {
-                a.shift();
-                ret = ce.fire.apply(ce, a);
             }
         }
-        return ret;
+        return this;
     },
 
+
     
-    addListener : function(eventName, fn, scope, o){
+    
+    
+    
+    
+    
+    
+    
+    
+    
+
+
+    
+    
+    
+
+
+
+    
+    
+    
+    
+    
+    
+
+
+    
+    
+    
+    
+    
+    
+
+
+    
+    
+    
+
+
+    
+    
+    
+    
+    
+    
+    
+
+    
+    defaultUnit : "px",
+
+    
+    is : function(simpleSelector){
+        return Ext.DomQuery.is(this.dom, simpleSelector);
+    },
+
+    
+    focus : function(defer,  dom) {
         var me = this,
-            e,
-            oe,
-            isF,
-        ce;
-        if (ISOBJECT(eventName)) {
-            o = eventName;
-            for (e in o){
-                oe = o[e];
-                if (!me.filterOptRe.test(e)) {
-                    me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
-                }
-            }
-        } else {
-            eventName = eventName.toLowerCase();
-            ce = me.events[eventName] || TRUE;
-            if (Ext.isBoolean(ce)) {
-                me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
+            dom = dom || me.dom;
+        try{
+            if(Number(defer)){
+                me.focus.defer(defer, null, [null, dom]);
+            }else{
+                dom.focus();
             }
-            ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
-        }
+        }catch(e){}
+        return me;
+    },
+
+    
+    blur : function() {
+        try{
+            this.dom.blur();
+        }catch(e){}
+        return this;
+    },
+
+    
+    getValue : function(asNumber){
+        var val = this.dom.value;
+        return asNumber ? parseInt(val, 10) : val;
+    },
+
+    
+    addListener : function(eventName, fn, scope, options){
+        Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);
+        return this;
     },
 
     
     removeListener : function(eventName, fn, scope){
-        var ce = this.events[eventName.toLowerCase()];
-        if (ISOBJECT(ce)) {
-            ce.removeListener(fn, scope);
+        Ext.EventManager.removeListener(this.dom,  eventName, fn, scope || this);
+        return this;
+    },
+
+    
+    removeAllListeners : function(){
+        Ext.EventManager.removeAll(this.dom);
+        return this;
+    },
+
+    
+    purgeAllListeners : function() {
+        Ext.EventManager.purgeElement(this, true);
+        return this;
+    },
+    
+    addUnits : function(size){
+        if(size === "" || size == "auto" || size === undefined){
+            size = size || '';
+        } else if(!isNaN(size) || !unitPattern.test(size)){
+            size = size + (this.defaultUnit || 'px');
         }
+        return size;
     },
 
     
-    purgeListeners : function(){
-        var events = this.events,
-            evt,
-            key;
-        for(key in events){
-            evt = events[key];
-            if(ISOBJECT(evt)){
-                evt.clearListeners();
-            }
+    load : function(url, params, cb){
+        Ext.Ajax.request(Ext.apply({
+            params: params,
+            url: url.url || url,
+            callback: cb,
+            el: this.dom,
+            indicatorText: url.indicatorText || ''
+        }, Ext.isObject(url) ? url : {}));
+        return this;
+    },
+
+    
+    isBorderBox : function(){
+        return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()];
+    },
+
+    
+    remove : function(){
+        var me = this,
+            dom = me.dom;
+
+        if (dom) {
+            delete me.dom;
+            Ext.removeNode(dom);
         }
     },
 
     
-    addEvents : function(o){
+    hover : function(overFn, outFn, scope, options){
         var me = this;
-        me.events = me.events || {};
-        if (Ext.isString(o)) {
-            var a = arguments,
-                i = a.length;
-            while(i--) {
-                me.events[a[i]] = me.events[a[i]] || TRUE;
-            }
-        } else {
-            Ext.applyIf(me.events, o);
-        }
+        me.on('mouseenter', overFn, scope || me.dom, options);
+        me.on('mouseleave', outFn, scope || me.dom, options);
+        return me;
     },
 
     
-    hasListener : function(eventName){
-        var e = this.events[eventName];
-        return ISOBJECT(e) && e.listeners.length > 0;
+    contains : function(el){
+        return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
     },
 
     
-    suspendEvents : function(queueSuspended){
-        this.eventsSuspended = TRUE;
-        if(queueSuspended && !this.eventQueue){
-            this.eventQueue = [];
+    getAttributeNS : function(ns, name){
+        return this.getAttribute(name, ns);
+    },
+
+    
+    getAttribute : Ext.isIE ? function(name, ns){
+        var d = this.dom,
+            type = typeof d[ns + ":" + name];
+
+        if(['undefined', 'unknown'].indexOf(type) == -1){
+            return d[ns + ":" + name];
         }
+        return d[name];
+    } : function(name, ns){
+        var d = this.dom;
+        return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
     },
 
     
-    resumeEvents : function(){
-        var me = this,
-            queued = me.eventQueue || [];
-        me.eventsSuspended = FALSE;
-        delete me.eventQueue;
-        EACH(queued, function(e) {
-            me.fireEvent.apply(me, e);
-        });
+    update : function(html) {
+        if (this.dom) {
+            this.dom.innerHTML = html;
+        }
+        return this;
     }
 };
 
-var OBSERVABLE = EXTUTIL.Observable.prototype;
+var ep = El.prototype;
 
-OBSERVABLE.on = OBSERVABLE.addListener;
+El.addMethods = function(o){
+   Ext.apply(ep, o);
+};
 
-OBSERVABLE.un = OBSERVABLE.removeListener;
 
+ep.on = ep.addListener;
 
-EXTUTIL.Observable.releaseCapture = function(o){
-    o.fireEvent = OBSERVABLE.fireEvent;
-};
 
-function createTargeted(h, o, scope){
-    return function(){
-        if(o.target == arguments[0]){
-            h.apply(scope, TOARRAY(arguments));
-        }
-    };
-};
+ep.un = ep.removeListener;
 
-function createBuffered(h, o, fn, scope){
-    fn.task = new EXTUTIL.DelayedTask();
-    return function(){
-        fn.task.delay(o.buffer, h, scope, TOARRAY(arguments));
-    };
-}
 
-function createSingle(h, e, fn, scope){
-    return function(){
-        e.removeListener(fn, scope);
-        return h.apply(scope, arguments);
-    };
-}
+ep.autoBoxAdjust = true;
 
-function createDelayed(h, o, fn, scope){
-    return function(){
-        var task = new EXTUTIL.DelayedTask();
-        if(!fn.tasks) {
-            fn.tasks = [];
-        }
-        fn.tasks.push(task);
-        task.delay(o.delay || 10, h, scope, TOARRAY(arguments));
-    };
-};
 
-EXTUTIL.Event = function(obj, name){
-    this.name = name;
-    this.obj = obj;
-    this.listeners = [];
-};
+var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
+    docEl;
 
-EXTUTIL.Event.prototype = {
-    addListener : function(fn, scope, options){
-        var me = this,
-            l;
-        scope = scope || me.obj;
-        if(!me.isListening(fn, scope)){
-            l = me.createListener(fn, scope, options);
-            if(me.firing){ 
-                me.listeners = me.listeners.slice(0);
-            }
-            me.listeners.push(l);
-        }
-    },
 
-    createListener: function(fn, scope, o){
-        o = o || {}, scope = scope || this.obj;
-        var l = {
-            fn: fn,
-            scope: scope,
-            options: o
-        }, h = fn;
-        if(o.target){
-            h = createTargeted(h, o, scope);
+
+
+El.get = function(el){
+    var ex,
+        elm,
+        id;
+    if(!el){ return null; }
+    if (typeof el == "string") { 
+        if (!(elm = DOC.getElementById(el))) {
+            return null;
         }
-        if(o.delay){
-            h = createDelayed(h, o, fn, scope);
+        if (EC[el] && EC[el].el) {
+            ex = EC[el].el;
+            ex.dom = elm;
+        } else {
+            ex = El.addToCache(new El(elm));
         }
-        if(o.single){
-            h = createSingle(h, this, fn, scope);
+        return ex;
+    } else if (el.tagName) { 
+        if(!(id = el.id)){
+            id = Ext.id(el);
         }
-        if(o.buffer){
-            h = createBuffered(h, o, fn, scope);
+        if (EC[id] && EC[id].el) {
+            ex = EC[id].el;
+            ex.dom = el;
+        } else {
+            ex = El.addToCache(new El(el));
         }
-        l.fireFn = h;
-        return l;
-    },
+        return ex;
+    } else if (el instanceof El) {
+        if(el != docEl){
+            
+            
 
-    findListener : function(fn, scope){
-        var list = this.listeners,
-            i = list.length,
-            l,
-            s;
-        while(i--) {
-            l = list[i];
-            if(l) {
-                s = l.scope;
-                if(l.fn == fn && (s == scope || s == this.obj)){
-                    return i;
-                }
+            
+            if (Ext.isIE && (el.id == undefined || el.id == '')) {
+                el.dom = el.dom;
+            } else {
+                el.dom = DOC.getElementById(el.id) || el.dom;
             }
         }
-        return -1;
-    },
+        return el;
+    } else if(el.isComposite) {
+        return el;
+    } else if(Ext.isArray(el)) {
+        return El.select(el);
+    } else if(el == DOC) {
+        
+        if(!docEl){
+            var f = function(){};
+            f.prototype = El.prototype;
+            docEl = new f();
+            docEl.dom = DOC;
+        }
+        return docEl;
+    }
+    return null;
+};
 
-    isListening : function(fn, scope){
-        return this.findListener(fn, scope) != -1;
-    },
+El.addToCache = function(el, id){
+    id = id || el.id;
+    EC[id] = {
+        el:  el,
+        data: {},
+        events: {}
+    };
+    return el;
+};
 
-    removeListener : function(fn, scope){
-        var index,
-            l,
-            k,
-            me = this,
-            ret = FALSE;
-        if((index = me.findListener(fn, scope)) != -1){
-            if (me.firing) {
-                me.listeners = me.listeners.slice(0);
+
+El.data = function(el, key, value){
+    el = El.get(el);
+    if (!el) {
+        return null;
+    }
+    var c = EC[el.id].data;
+    if(arguments.length == 2){
+        return c[key];
+    }else{
+        return (c[key] = value);
+    }
+};
+
+
+
+
+function garbageCollect(){
+    if(!Ext.enableGarbageCollector){
+        clearInterval(El.collectorThreadId);
+    } else {
+        var eid,
+            el,
+            d,
+            o;
+
+        for(eid in EC){
+            o = EC[eid];
+            if(o.skipGC){
+                continue;
             }
-            l = me.listeners[index].fn;
+            el = o.el;
+            d = el.dom;
             
-            if(l.task) {
-                l.task.cancel();
-                delete l.task;
-            }
             
-            k = l.tasks && l.tasks.length;
-            if(k) {
-                while(k--) {
-                    l.tasks[k].cancel();
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
+                if(Ext.enableListenerCollection){
+                    Ext.EventManager.removeAll(d);
                 }
-                delete l.tasks;
+                delete EC[eid];
             }
-            me.listeners.splice(index, 1);
-            ret = TRUE;
         }
-        return ret;
-    },
-
-    
-    clearListeners : function(){
-        var me = this,
-            l = me.listeners,
-            i = l.length;
-        while(i--) {
-            me.removeListener(l[i].fn, l[i].scope);
+        
+        if (Ext.isIE) {
+            var t = {};
+            for (eid in EC) {
+                t[eid] = EC[eid];
+            }
+            EC = Ext.elCache = t;
         }
-    },
+    }
+}
+El.collectorThreadId = setInterval(garbageCollect, 30000);
 
-    fire : function(){
-        var me = this,
-            args = TOARRAY(arguments),
-            listeners = me.listeners,
-            len = listeners.length,
-            i = 0,
-            l;
+var flyFn = function(){};
+flyFn.prototype = El.prototype;
 
-        if(len > 0){
-            me.firing = TRUE;
-            for (; i < len; i++) {
-                l = listeners[i];
-                if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
-                    return (me.firing = FALSE);
-                }
-            }
-        }
-        me.firing = FALSE;
-        return TRUE;
+
+El.Flyweight = function(dom){
+    this.dom = dom;
+};
+
+El.Flyweight.prototype = new flyFn();
+El.Flyweight.prototype.isFlyweight = true;
+El._flyweights = {};
+
+
+El.fly = function(el, named){
+    var ret = null;
+    named = named || '_global';
+
+    if (el = Ext.getDom(el)) {
+        (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
+        ret = El._flyweights[named];
     }
+    return ret;
 };
-})();
-Ext.apply(Ext.util.Observable.prototype, function(){
-    
-    
-    
-    function getMethodEvent(method){
-        var e = (this.methodEvents = this.methodEvents ||
-        {})[method], returnValue, v, cancel, obj = this;
 
-        if (!e) {
-            this.methodEvents[method] = e = {};
-            e.originalFn = this[method];
-            e.methodName = method;
-            e.before = [];
-            e.after = [];
 
-            var makeCall = function(fn, scope, args){
-                if (!Ext.isEmpty(v = fn.apply(scope || obj, args))) {
-                    if (Ext.isObject(v)) {
-                        returnValue = !Ext.isEmpty(v.returnValue) ? v.returnValue : v;
-                        cancel = !!v.cancel;
-                    }
-                    else
-                        if (v === false) {
-                            cancel = true;
-                        }
-                        else {
-                            returnValue = v;
-                        }
-                }
-            };
+Ext.get = El.get;
 
-            this[method] = function(){
-                var args = Ext.toArray(arguments);
-                returnValue = v = undefined;
-                cancel = false;
 
-                Ext.each(e.before, function(b){
-                    makeCall(b.fn, b.scope, args);
-                    if (cancel) {
-                        return returnValue;
-                    }
-                });
+Ext.fly = El.fly;
 
-                if (!Ext.isEmpty(v = e.originalFn.apply(obj, args))) {
-                    returnValue = v;
-                }
-                Ext.each(e.after, function(a){
-                    makeCall(a.fn, a.scope, args);
-                    if (cancel) {
-                        return returnValue;
-                    }
-                });
-                return returnValue;
-            };
-        }
-        return e;
-    }
 
-    return {
-        
-        
-        
-        beforeMethod : function(method, fn, scope){
-            getMethodEvent.call(this, method).before.push({
-                fn: fn,
-                scope: scope
-            });
-        },
+var noBoxAdjust = Ext.isStrict ? {
+    select:1
+} : {
+    input:1, select:1, textarea:1
+};
+if(Ext.isIE || Ext.isGecko){
+    noBoxAdjust['button'] = 1;
+}
 
-        
-        afterMethod : function(method, fn, scope){
-            getMethodEvent.call(this, method).after.push({
-                fn: fn,
-                scope: scope
-            });
-        },
+})();
 
-        removeMethodListener: function(method, fn, scope){
-            var e = getMethodEvent.call(this, method), found = false;
-            Ext.each(e.before, function(b, i, arr){
-                if (b.fn == fn && b.scope == scope) {
-                    arr.splice(i, 1);
-                    found = true;
-                    return false;
-                }
-            });
-            if (!found) {
-                Ext.each(e.after, function(a, i, arr){
-                    if (a.fn == fn && a.scope == scope) {
-                        arr.splice(i, 1);
-                        return false;
-                    }
-                });
+Ext.Element.addMethods(function(){
+       var PARENTNODE = 'parentNode',
+               NEXTSIBLING = 'nextSibling',
+               PREVIOUSSIBLING = 'previousSibling',
+               DQ = Ext.DomQuery,
+               GET = Ext.get;
+       
+       return {
+               
+           findParent : function(simpleSelector, maxDepth, returnEl){
+               var p = this.dom,
+                       b = document.body, 
+                       depth = 0,                      
+                       stopEl;         
+            if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
+                return null;
+            }
+               maxDepth = maxDepth || 50;
+               if (isNaN(maxDepth)) {
+                   stopEl = Ext.getDom(maxDepth);
+                   maxDepth = Number.MAX_VALUE;
+               }
+               while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
+                   if(DQ.is(p, simpleSelector)){
+                       return returnEl ? GET(p) : p;
+                   }
+                   depth++;
+                   p = p.parentNode;
+               }
+               return null;
+           },
+       
+           
+           findParentNode : function(simpleSelector, maxDepth, returnEl){
+               var p = Ext.fly(this.dom.parentNode, '_internal');
+               return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
+           },
+       
+           
+           up : function(simpleSelector, maxDepth){
+               return this.findParentNode(simpleSelector, maxDepth, true);
+           },
+       
+           
+           select : function(selector){
+               return Ext.Element.select(selector, this.dom);
+           },
+       
+           
+           query : function(selector){
+               return DQ.select(selector, this.dom);
+           },
+       
+           
+           child : function(selector, returnDom){
+               var n = DQ.selectNode(selector, this.dom);
+               return returnDom ? n : GET(n);
+           },
+       
+           
+           down : function(selector, returnDom){
+               var n = DQ.selectNode(" > " + selector, this.dom);
+               return returnDom ? n : GET(n);
+           },
+       
+                
+           parent : function(selector, returnDom){
+               return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
+           },
+       
+            
+           next : function(selector, returnDom){
+               return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
+           },
+       
+           
+           prev : function(selector, returnDom){
+               return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
+           },
+       
+       
+           
+           first : function(selector, returnDom){
+               return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
+           },
+       
+           
+           last : function(selector, returnDom){
+               return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
+           },
+           
+           matchNode : function(dir, start, selector, returnDom){
+               var n = this.dom[start];
+               while(n){
+                   if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
+                       return !returnDom ? GET(n) : n;
+                   }
+                   n = n[dir];
+               }
+               return null;
+           }   
+    };
+}());
+Ext.Element.addMethods(
+function() {
+       var GETDOM = Ext.getDom,
+               GET = Ext.get,
+               DH = Ext.DomHelper;
+       
+       return {
+           
+           appendChild: function(el){        
+               return GET(el).appendTo(this);        
+           },
+       
+           
+           appendTo: function(el){        
+               GETDOM(el).appendChild(this.dom);        
+               return this;
+           },
+       
+           
+           insertBefore: function(el){                   
+               (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
+               return this;
+           },
+       
+           
+           insertAfter: function(el){
+               (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
+               return this;
+           },
+       
+           
+           insertFirst: function(el, returnDom){
+            el = el || {};
+            if(el.nodeType || el.dom || typeof el == 'string'){ 
+                el = GETDOM(el);
+                this.dom.insertBefore(el, this.dom.firstChild);
+                return !returnDom ? GET(el) : el;
+            }else{ 
+                return this.createChild(el, this.dom.firstChild, returnDom);
             }
         },
+       
+           
+           replace: function(el){
+               el = GET(el);
+               this.insertBefore(el);
+               el.remove();
+               return this;
+           },
+       
+           
+           replaceWith: function(el){
+                   var me = this;
+                
+            if(el.nodeType || el.dom || typeof el == 'string'){
+                el = GETDOM(el);
+                me.dom.parentNode.insertBefore(el, me.dom);
+            }else{
+                el = DH.insertBefore(me.dom, el);
+            }
+               
+               delete Ext.elCache[me.id];
+               Ext.removeNode(me.dom);      
+               me.id = Ext.id(me.dom = el);
+               Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);     
+            return me;
+           },
+           
+               
+               createChild: function(config, insertBefore, returnDom){
+                   config = config || {tag:'div'};
+                   return insertBefore ? 
+                          DH.insertBefore(insertBefore, config, returnDom !== true) :  
+                          DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
+               },
+               
+               
+               wrap: function(config, returnDom){        
+                   var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
+                   newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
+                   return newEl;
+               },
+               
+               
+               insertHtml : function(where, html, returnEl){
+                   var el = DH.insertHtml(where, this.dom, html);
+                   return returnEl ? Ext.get(el) : el;
+               }
+       };
+}());
+Ext.Element.addMethods(function(){
+    
+    var supports = Ext.supports,
+        propCache = {},
+        camelRe = /(-[a-z])/gi,
+        view = document.defaultView,
+        opacityRe = /alpha\(opacity=(.*)\)/i,
+        trimRe = /^\s+|\s+$/g,
+        EL = Ext.Element,
+        spacesRe = /\s+/,
+        wordsRe = /\w/g,
+        PADDING = "padding",
+        MARGIN = "margin",
+        BORDER = "border",
+        LEFT = "-left",
+        RIGHT = "-right",
+        TOP = "-top",
+        BOTTOM = "-bottom",
+        WIDTH = "-width",
+        MATH = Math,
+        HIDDEN = 'hidden',
+        ISCLIPPED = 'isClipped',
+        OVERFLOW = 'overflow',
+        OVERFLOWX = 'overflow-x',
+        OVERFLOWY = 'overflow-y',
+        ORIGINALCLIP = 'originalClip',
+        
+        borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
+        paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
+        margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
+        data = Ext.Element.data;
+
+
+    
+    function camelFn(m, a) {
+        return a.charAt(1).toUpperCase();
+    }
+
+    function chkCache(prop) {
+        return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn));
+    }
 
+    return {
         
-        relayEvents : function(o, events){
+        adjustWidth : function(width) {
             var me = this;
-            function createHandler(ename){
-                return function(){
-                    return me.fireEvent.apply(me, [ename].concat(Ext.toArray(arguments)));
-                };
+            var isNum = (typeof width == "number");
+            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
+               width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
             }
-            Ext.each(events, function(ename){
-                me.events[ename] = me.events[ename] || true;
-                o.on(ename, createHandler(ename), me);
-            });
+            return (isNum && width < 0) ? 0 : width;
         },
 
         
-        enableBubble : function(events){
+        adjustHeight : function(height) {
             var me = this;
-            if(!Ext.isEmpty(events)){
-                events = Ext.isArray(events) ? events : Ext.toArray(arguments);
-                Ext.each(events, function(ename){
-                    ename = ename.toLowerCase();
-                    var ce = me.events[ename] || true;
-                    if (Ext.isBoolean(ce)) {
-                        ce = new Ext.util.Event(me, ename);
-                        me.events[ename] = ce;
-                    }
-                    ce.bubble = true;
-                });
+            var isNum = (typeof height == "number");
+            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
+               height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
             }
-        }
-    };
-}());
-
-
-
-Ext.util.Observable.capture = function(o, fn, scope){
-    o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
-};
-
+            return (isNum && height < 0) ? 0 : height;
+        },
 
 
-Ext.util.Observable.observeClass = function(c, listeners){
-    if(c){
-      if(!c.fireEvent){
-          Ext.apply(c, new Ext.util.Observable());
-          Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
-      }
-      if(Ext.isObject(listeners)){
-          c.on(listeners);
-      }
-      return c;
-   }
-};
-Ext.EventManager = function(){
-    var docReadyEvent,
-        docReadyProcId,
-        docReadyState = false,
-        E = Ext.lib.Event,
-        D = Ext.lib.Dom,
-        DOC = document,
-        WINDOW = window,
-        IEDEFERED = "ie-deferred-loader",
-        DOMCONTENTLOADED = "DOMContentLoaded",
-        propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
         
-        specialElCache = [];
-
-     function getId(el){
-        var id = false,
-            i = 0,
-            len = specialElCache.length,
-            id = false,
-            skip = false,
-            o;
-        if(el){
-            if(el.getElementById || el.navigator){
-                
-                for(; i < len; ++i){
-                    o = specialElCache[i];
-                    if(o.el === el){
-                        id = o.id;
-                        break;
-                    }
-                }
-                if(!id){
-                    
-                    id = Ext.id(el);
-                    specialElCache.push({
-                        id: id,
-                        el: el
-                    });
-                    skip = true;
+        addClass : function(className){
+            var me = this,
+                i,
+                len,
+                v,
+                cls = [];
+            
+            if (!Ext.isArray(className)) {
+                if (typeof className == 'string' && !this.hasClass(className)) {
+                    me.dom.className += " " + className;
                 }
-            }else{
-                id = Ext.id(el);
             }
-            if(!Ext.elCache[id]){
-                Ext.Element.addToCache(new Ext.Element(el), id);
-                if(skip){
-                    Ext.elCache[id].skipGC = true;
+            else {
+                for (i = 0, len = className.length; i < len; i++) {
+                    v = className[i];
+                    if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
+                        cls.push(v);
+                    }
+                }
+                if (cls.length) {
+                    me.dom.className += " " + cls.join(" ");
                 }
             }
-        }
-        return id;
-     };
-
-    
-    function addListener(el, ename, fn, wrap, scope){
-        el = Ext.getDom(el);
-        var id = getId(el),
-            es = Ext.elCache[id].events,
-            wfn;
-
-        wfn = E.on(el, ename, wrap);
-        es[ename] = es[ename] || [];
-        es[ename].push([fn, wrap, scope, wfn]);
+            return me;
+        },
 
         
-        
-        if(ename == "mousewheel" && el.addEventListener){ 
-            var args = ["DOMMouseScroll", wrap, false];
-            el.addEventListener.apply(el, args);
-            Ext.EventManager.addListener(WINDOW, 'unload', function(){
-                el.removeEventListener.apply(el, args);
-            });
-        }
-        if(ename == "mousedown" && el == document){ 
-            Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
-        }
-    };
-
-    function fireDocReady(){
-        if(!docReadyState){
-            Ext.isReady = docReadyState = true;
-            if(docReadyProcId){
-                clearInterval(docReadyProcId);
-            }
-            if(Ext.isGecko || Ext.isOpera) {
-                DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
+        removeClass : function(className){
+            var me = this,
+                i,
+                idx,
+                len,
+                cls,
+                elClasses;
+            if (!Ext.isArray(className)){
+                className = [className];
             }
-            if(Ext.isIE){
-                var defer = DOC.getElementById(IEDEFERED);
-                if(defer){
-                    defer.onreadystatechange = null;
-                    defer.parentNode.removeChild(defer);
+            if (me.dom && me.dom.className) {
+                elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
+                for (i = 0, len = className.length; i < len; i++) {
+                    cls = className[i];
+                    if (typeof cls == 'string') {
+                        cls = cls.replace(trimRe, '');
+                        idx = elClasses.indexOf(cls);
+                        if (idx != -1) {
+                            elClasses.splice(idx, 1);
+                        }
+                    }
                 }
+                me.dom.className = elClasses.join(" ");
             }
-            if(docReadyEvent){
-                docReadyEvent.fire();
-                docReadyEvent.listeners = []; 
-            }
-        }
-    };
-
-    function initDocReady(){
-        var COMPLETE = "complete";
+            return me;
+        },
 
-        docReadyEvent = new Ext.util.Event();
-        if (Ext.isGecko || Ext.isOpera) {
-            DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
-        } else if (Ext.isIE){
-            DOC.write("<s"+'cript id=' + IEDEFERED + ' defer="defer" src="/'+'/:"></s'+"cript>");
-            DOC.getElementById(IEDEFERED).onreadystatechange = function(){
-                if(this.readyState == COMPLETE){
-                    fireDocReady();
+        
+        radioClass : function(className){
+            var cn = this.dom.parentNode.childNodes,
+                v,
+                i,
+                len;
+            className = Ext.isArray(className) ? className : [className];
+            for (i = 0, len = cn.length; i < len; i++) {
+                v = cn[i];
+                if (v && v.nodeType == 1) {
+                    Ext.fly(v, '_internal').removeClass(className);
                 }
             };
-        } else if (Ext.isWebKit){
-            docReadyProcId = setInterval(function(){
-                if(DOC.readyState == COMPLETE) {
-                    fireDocReady();
-                 }
-            }, 10);
-        }
-        
-        E.on(WINDOW, "load", fireDocReady);
-    };
-
-    function createTargeted(h, o){
-        return function(){
-            var args = Ext.toArray(arguments);
-            if(o.target == Ext.EventObject.setEvent(args[0]).target){
-                h.apply(this, args);
-            }
-        };
-    };
-
-    function createBuffered(h, o, fn){
-        fn.task = new Ext.util.DelayedTask(h);
-        var w = function(e){
-            
-            fn.task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
-        };
-        return w;
-    };
-
-    function createSingle(h, el, ename, fn, scope){
-        return function(e){
-            Ext.EventManager.removeListener(el, ename, fn, scope);
-            h(e);
-        };
-    };
-
-    function createDelayed(h, o, fn){
-        return function(e){
-            var task = new Ext.util.DelayedTask(h);
-            if(!fn.tasks) {
-                fn.tasks = [];
-            }
-            fn.tasks.push(task);
-            task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
-        };
-    };
-
-    function listen(element, ename, opt, fn, scope){
-        var o = !Ext.isObject(opt) ? {} : opt,
-            el = Ext.getDom(element);
-
-        fn = fn || o.fn;
-        scope = scope || o.scope;
-
-        if(!el){
-            throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
-        }
-        function h(e){
-            
-            if(!Ext){
-                return;
-            }
-            e = Ext.EventObject.setEvent(e);
-            var t;
-            if (o.delegate) {
-                if(!(t = e.getTarget(o.delegate, el))){
-                    return;
-                }
-            } else {
-                t = e.target;
-            }
-            if (o.stopEvent) {
-                e.stopEvent();
-            }
-            if (o.preventDefault) {
-               e.preventDefault();
-            }
-            if (o.stopPropagation) {
-                e.stopPropagation();
-            }
-            if (o.normalized) {
-                e = e.browserEvent;
-            }
+            return this.addClass(className);
+        },
 
-            fn.call(scope || el, e, t, o);
-        };
-        if(o.target){
-            h = createTargeted(h, o);
-        }
-        if(o.delay){
-            h = createDelayed(h, o, fn);
-        }
-        if(o.single){
-            h = createSingle(h, el, ename, fn, scope);
-        }
-        if(o.buffer){
-            h = createBuffered(h, o, fn);
-        }
+        
+        toggleClass : function(className){
+            return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
+        },
 
-        addListener(el, ename, fn, h, scope);
-        return h;
-    };
+        
+        hasClass : function(className){
+            return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
+        },
 
-    var pub = {
         
-        addListener : function(element, eventName, fn, scope, options){
-            if(Ext.isObject(eventName)){
-                var o = eventName, e, val;
-                for(e in o){
-                    val = o[e];
-                    if(!propRe.test(e)){
-                        if(Ext.isFunction(val)){
-                            
-                            listen(element, e, o, val, o.scope);
-                        }else{
-                            
-                            listen(element, e, val);
-                        }
-                    }
-                }
-            } else {
-                listen(element, eventName, options, fn, scope);
-            }
+        replaceClass : function(oldClassName, newClassName){
+            return this.removeClass(oldClassName).addClass(newClassName);
+        },
+
+        isStyle : function(style, val) {
+            return this.getStyle(style) == val;
         },
 
         
-        removeListener : function(el, eventName, fn, scope){
-            el = Ext.getDom(el);
-            var id = getId(el),
-                f = el && (Ext.elCache[id].events)[eventName] || [],
-                wrap, i, l, k, wf;
+        getStyle : function(){
+            return view && view.getComputedStyle ?
+                function(prop){
+                    var el = this.dom,
+                        v,
+                        cs,
+                        out,
+                        display;
 
-            for (i = 0, len = f.length; i < len; i++) {
-                if (Ext.isArray(f[i]) && f[i][0] == fn && (!scope || f[i][2] == scope)) {
-                    if(fn.task) {
-                        fn.task.cancel();
-                        delete fn.task;
-                    }
-                    k = fn.tasks && fn.tasks.length;
-                    if(k) {
-                        while(k--) {
-                            fn.tasks[k].cancel();
-                        }
-                        delete fn.tasks;
-                    }
-                    wf = wrap = f[i][1];
-                    if (E.extAdapter) {
-                        wf = f[i][3];
+                    if(el == document){
+                        return null;
                     }
-                    E.un(el, eventName, wf);
-                    f.splice(i,1);
-                    if (f.length === 0) {
-                        delete Ext.elCache[id].events[eventName];
+                    prop = chkCache(prop);
+                    out = (v = el.style[prop]) ? v :
+                           (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
+                           
+                    
+                    
+                    if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){
+                        display = el.style.display;
+                        el.style.display = 'inline-block';
+                        out = view.getComputedStyle(el, '').marginRight;
+                        el.style.display = display;
                     }
-                    for (k in Ext.elCache[id].events) {
-                        return false;
+                    
+                    if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){
+                        out = 'transparent';
                     }
-                    Ext.elCache[id].events = {};
-                    return false;
-                }
-            }
-
-            
-            if(eventName == "mousewheel" && el.addEventListener && wrap){
-                el.removeEventListener("DOMMouseScroll", wrap, false);
-            }
-
-            if(eventName == "mousedown" && el == DOC && wrap){ 
-                Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
-            }
-        },
-
-        
-        removeAll : function(el){
-            el = Ext.getDom(el);
-            var id = getId(el),
-                ec = Ext.elCache[id] || {},
-                es = ec.events || {},
-                f, i, len, ename, fn, k;
+                    return out;
+                } :
+                function(prop){
+                    var el = this.dom,
+                        m,
+                        cs;
 
-            for(ename in es){
-                if(es.hasOwnProperty(ename)){
-                    f = es[ename];
-                    for (i = 0, len = f.length; i < len; i++) {
-                        fn = f[i][0];
-                        if(fn.task) {
-                            fn.task.cancel();
-                            delete fn.task;
-                        }
-                        if(fn.tasks && (k = fn.tasks.length)) {
-                            while(k--) {
-                                fn.tasks[k].cancel();
+                    if(el == document) return null;
+                    if (prop == 'opacity') {
+                        if (el.style.filter.match) {
+                            if(m = el.style.filter.match(opacityRe)){
+                                var fv = parseFloat(m[1]);
+                                if(!isNaN(fv)){
+                                    return fv ? fv / 100 : 0;
+                                }
                             }
-                            delete fn.tasks;
                         }
-                        E.un(el, ename, E.extAdapter ? f[i][3] : f[i][1]);
+                        return 1;
                     }
-                }
-            }
-            if (Ext.elCache[id]) {
-                Ext.elCache[id].events = {};
-            }
-        },
+                    prop = chkCache(prop);
+                    return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
+                };
+        }(),
 
-        getListeners : function(el, eventName) {
-            el = Ext.getDom(el);
-            var id = getId(el),
-                ec = Ext.elCache[id] || {},
-                es = ec.events || {},
-                results = [];
-            if (es && es[eventName]) {
-                return es[eventName];
-            } else {
-                return null;
-            }
-        },
+        
+        getColor : function(attr, defaultValue, prefix){
+            var v = this.getStyle(attr),
+                color = (typeof prefix != 'undefined') ? prefix : '#',
+                h;
 
-        purgeElement : function(el, recurse, eventName) {
-            el = Ext.getDom(el);
-            var id = getId(el),
-                ec = Ext.elCache[id] || {},
-                es = ec.events || {},
-                i, f, len;
-            if (eventName) {
-                if (es && es.hasOwnProperty(eventName)) {
-                    f = es[eventName];
-                    for (i = 0, len = f.length; i < len; i++) {
-                        Ext.EventManager.removeListener(el, eventName, f[i][0]);
-                    }
-                }
-            } else {
-                Ext.EventManager.removeAll(el);
+            if(!v || (/transparent|inherit/.test(v))) {
+                return defaultValue;
             }
-            if (recurse && el && el.childNodes) {
-                for (i = 0, len = el.childNodes.length; i < len; i++) {
-                    Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
-                }
+            if(/^r/.test(v)){
+                Ext.each(v.slice(4, v.length -1).split(','), function(s){
+                    h = parseInt(s, 10);
+                    color += (h < 16 ? '0' : '') + h.toString(16);
+                });
+            }else{
+                v = v.replace('#', '');
+                color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
             }
+            return(color.length > 5 ? color.toLowerCase() : defaultValue);
         },
 
-        _unload : function() {
-            var el;
-            for (el in Ext.elCache) {
-                Ext.EventManager.removeAll(el);
-            }
-        },
         
-        onDocumentReady : function(fn, scope, options){
-            if(docReadyState){ 
-                docReadyEvent.addListener(fn, scope, options);
-                docReadyEvent.fire();
-                docReadyEvent.listeners = []; 
-            } else {
-                if(!docReadyEvent) initDocReady();
-                options = options || {};
-                options.delay = options.delay || 1;
-                docReadyEvent.addListener(fn, scope, options);
+        setStyle : function(prop, value){
+            var tmp, style;
+            
+            if (typeof prop != 'object') {
+                tmp = {};
+                tmp[prop] = value;
+                prop = tmp;
             }
-        }
-    };
-     
-    pub.on = pub.addListener;
-    
-    pub.un = pub.removeListener;
-
-    pub.stoppedMouseDownEvent = new Ext.util.Event();
-    return pub;
-}();
-
-Ext.onReady = Ext.EventManager.onDocumentReady;
-
-
-
-(function(){
-
-    var initExtCss = function(){
-        
-        var bd = document.body || document.getElementsByTagName('body')[0];
-        if(!bd){ return false; }
-        var cls = [' ',
-                Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
-                : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
-                : Ext.isOpera ? "ext-opera"
-                : Ext.isWebKit ? "ext-webkit" : ""];
-
-        if(Ext.isSafari){
-            cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
-        }else if(Ext.isChrome){
-            cls.push("ext-chrome");
-        }
-
-        if(Ext.isMac){
-            cls.push("ext-mac");
-        }
-        if(Ext.isLinux){
-            cls.push("ext-linux");
-        }
-
-        if(Ext.isStrict || Ext.isBorderBox){ 
-            var p = bd.parentNode;
-            if(p){
-                p.className += Ext.isStrict ? ' ext-strict' : ' ext-border-box';
+            for (style in prop) {
+                value = prop[style];
+                style == 'opacity' ?
+                    this.setOpacity(value) :
+                    this.dom.style[chkCache(style)] = value;
             }
-        }
-        bd.className += cls.join(' ');
-        return true;
-    }
-
-    if(!initExtCss()){
-        Ext.onReady(initExtCss);
-    }
-})();
-
-
-
-Ext.EventObject = function(){
-    var E = Ext.lib.Event,
-        
-        safariKeys = {
-            3 : 13, 
-            63234 : 37, 
-            63235 : 39, 
-            63232 : 38, 
-            63233 : 40, 
-            63276 : 33, 
-            63277 : 34, 
-            63272 : 46, 
-            63273 : 36, 
-            63275 : 35  
+            return this;
         },
+
         
-        btnMap = Ext.isIE ? {1:0,4:1,2:2} :
-                (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
+         setOpacity : function(opacity, animate){
+            var me = this,
+                s = me.dom.style;
 
-    Ext.EventObjectImpl = function(e){
-        if(e){
-            this.setEvent(e.browserEvent || e);
-        }
-    };
+            if(!animate || !me.anim){
+                if(Ext.isIE){
+                    var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
+                    val = s.filter.replace(opacityRe, '').replace(trimRe, '');
 
-    Ext.EventObjectImpl.prototype = {
-           
-        setEvent : function(e){
-            var me = this;
-            if(e == me || (e && e.browserEvent)){ 
-                return e;
-            }
-            me.browserEvent = e;
-            if(e){
-                
-                me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
-                if(e.type == 'click' && me.button == -1){
-                    me.button = 0;
+                    s.zoom = 1;
+                    s.filter = val + (val.length > 0 ? ' ' : '') + opac;
+                }else{
+                    s.opacity = opacity;
                 }
-                me.type = e.type;
-                me.shiftKey = e.shiftKey;
-                
-                me.ctrlKey = e.ctrlKey || e.metaKey || false;
-                me.altKey = e.altKey;
-                
-                me.keyCode = e.keyCode;
-                me.charCode = e.charCode;
-                
-                me.target = E.getTarget(e);
-                
-                me.xy = E.getXY(e);
             }else{
-                me.button = -1;
-                me.shiftKey = false;
-                me.ctrlKey = false;
-                me.altKey = false;
-                me.keyCode = 0;
-                me.charCode = 0;
-                me.target = null;
-                me.xy = [0, 0];
+                me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
             }
             return me;
         },
 
         
-        stopEvent : function(){
-            var me = this;
-            if(me.browserEvent){
-                if(me.browserEvent.type == 'mousedown'){
-                    Ext.EventManager.stoppedMouseDownEvent.fire(me);
+        clearOpacity : function(){
+            var style = this.dom.style;
+            if(Ext.isIE){
+                if(!Ext.isEmpty(style.filter)){
+                    style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
                 }
-                E.stopEvent(me.browserEvent);
+            }else{
+                style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
             }
+            return this;
         },
 
         
-        preventDefault : function(){
-            if(this.browserEvent){
-                E.preventDefault(this.browserEvent);
-            }
-        },
+        getHeight : function(contentHeight){
+            var me = this,
+                dom = me.dom,
+                hidden = Ext.isIE && me.isStyle('display', 'none'),
+                h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
 
-        
-        stopPropagation : function(){
-            var me = this;
-            if(me.browserEvent){
-                if(me.browserEvent.type == 'mousedown'){
-                    Ext.EventManager.stoppedMouseDownEvent.fire(me);
-                }
-                E.stopPropagation(me.browserEvent);
-            }
+            h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
+            return h < 0 ? 0 : h;
         },
 
         
-        getCharCode : function(){
-            return this.charCode || this.keyCode;
+        getWidth : function(contentWidth){
+            var me = this,
+                dom = me.dom,
+                hidden = Ext.isIE && me.isStyle('display', 'none'),
+                w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
+            w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
+            return w < 0 ? 0 : w;
         },
 
         
-        getKey : function(){
-            return this.normalizeKey(this.keyCode || this.charCode)
+        setWidth : function(width, animate){
+            var me = this;
+            width = me.adjustWidth(width);
+            !animate || !me.anim ?
+                me.dom.style.width = me.addUnits(width) :
+                me.anim({width : {to : width}}, me.preanim(arguments, 1));
+            return me;
         },
 
         
-        normalizeKey: function(k){
-            return Ext.isSafari ? (safariKeys[k] || k) : k;
+         setHeight : function(height, animate){
+            var me = this;
+            height = me.adjustHeight(height);
+            !animate || !me.anim ?
+                me.dom.style.height = me.addUnits(height) :
+                me.anim({height : {to : height}}, me.preanim(arguments, 1));
+            return me;
         },
 
         
-        getPageX : function(){
-            return this.xy[0];
+        getBorderWidth : function(side){
+            return this.addStyles(side, borders);
         },
 
         
-        getPageY : function(){
-            return this.xy[1];
+        getPadding : function(side){
+            return this.addStyles(side, paddings);
         },
 
         
-        getXY : function(){
-            return this.xy;
-        },
+        clip : function(){
+            var me = this,
+                dom = me.dom;
 
-        
-        getTarget : function(selector, maxDepth, returnEl){
-            return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
+            if(!data(dom, ISCLIPPED)){
+                data(dom, ISCLIPPED, true);
+                data(dom, ORIGINALCLIP, {
+                    o: me.getStyle(OVERFLOW),
+                    x: me.getStyle(OVERFLOWX),
+                    y: me.getStyle(OVERFLOWY)
+                });
+                me.setStyle(OVERFLOW, HIDDEN);
+                me.setStyle(OVERFLOWX, HIDDEN);
+                me.setStyle(OVERFLOWY, HIDDEN);
+            }
+            return me;
         },
 
         
-        getRelatedTarget : function(){
-            return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
-        },
+        unclip : function(){
+            var me = this,
+                dom = me.dom;
 
-        
-        getWheelDelta : function(){
-            var e = this.browserEvent;
-            var delta = 0;
-            if(e.wheelDelta){ 
-                delta = e.wheelDelta/120;
-            }else if(e.detail){ 
-                delta = -e.detail/3;
+            if(data(dom, ISCLIPPED)){
+                data(dom, ISCLIPPED, false);
+                var o = data(dom, ORIGINALCLIP);
+                if(o.o){
+                    me.setStyle(OVERFLOW, o.o);
+                }
+                if(o.x){
+                    me.setStyle(OVERFLOWX, o.x);
+                }
+                if(o.y){
+                    me.setStyle(OVERFLOWY, o.y);
+                }
             }
-            return delta;
+            return me;
         },
 
         
-        within : function(el, related, allowEl){
-            if(el){
-                var t = this[related ? "getRelatedTarget" : "getTarget"]();
-                return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
+        addStyles : function(sides, styles){
+            var ttlSize = 0,
+                sidesArr = sides.match(wordsRe),
+                side,
+                size,
+                i,
+                len = sidesArr.length;
+            for (i = 0; i < len; i++) {
+                side = sidesArr[i];
+                size = side && parseInt(this.getStyle(styles[side]), 10);
+                if (size) {
+                    ttlSize += MATH.abs(size);
+                }
             }
-            return false;
-        }
-     };
-
-    return new Ext.EventObjectImpl();
-}();
-
+            return ttlSize;
+        },
 
-Ext.apply(Ext.EventManager, function(){
-   var resizeEvent,
-       resizeTask,
-       textEvent,
-       textSize,
-       D = Ext.lib.Dom,
-       propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
-       curWidth = 0,
-       curHeight = 0,
-       
-       
-       
-       useKeydown = Ext.isWebKit ?
-                   Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
-                   !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
-
-   return {
-       
-       doResizeEvent: function(){
-           var h = D.getViewHeight(),
-               w = D.getViewWidth();
-
-           
-           if(curHeight != h || curWidth != w){
-               resizeEvent.fire(curWidth = w, curHeight = h);
-           }
-       },
-
-       
-       onWindowResize : function(fn, scope, options){
-           if(!resizeEvent){
-               resizeEvent = new Ext.util.Event();
-               resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
-               Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
-           }
-           resizeEvent.addListener(fn, scope, options);
-       },
-
-       
-       fireWindowResize : function(){
-           if(resizeEvent){
-               if((Ext.isIE||Ext.isAir) && resizeTask){
-                   resizeTask.delay(50);
-               }else{
-                   resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
-               }
-           }
-       },
-
-       
-       onTextResize : function(fn, scope, options){
-           if(!textEvent){
-               textEvent = new Ext.util.Event();
-               var textEl = new Ext.Element(document.createElement('div'));
-               textEl.dom.className = 'x-text-resize';
-               textEl.dom.innerHTML = 'X';
-               textEl.appendTo(document.body);
-               textSize = textEl.dom.offsetHeight;
-               setInterval(function(){
-                   if(textEl.dom.offsetHeight != textSize){
-                       textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
-                   }
-               }, this.textResizeInterval);
-           }
-           textEvent.addListener(fn, scope, options);
-       },
-
-       
-       removeResizeListener : function(fn, scope){
-           if(resizeEvent){
-               resizeEvent.removeListener(fn, scope);
-           }
-       },
-
-       
-       fireResize : function(){
-           if(resizeEvent){
-               resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
-           }
-       },
-
-        
-       textResizeInterval : 50,
-
-       
-       ieDeferSrc : false,
-
-       
-       
-       useKeydown: useKeydown
-   };
-}());
-
-Ext.EventManager.on = Ext.EventManager.addListener;
-
-
-Ext.apply(Ext.EventObjectImpl.prototype, {
-   
-   BACKSPACE: 8,
-   
-   TAB: 9,
-   
-   NUM_CENTER: 12,
-   
-   ENTER: 13,
-   
-   RETURN: 13,
-   
-   SHIFT: 16,
-   
-   CTRL: 17,
-   CONTROL : 17, 
-   
-   ALT: 18,
-   
-   PAUSE: 19,
-   
-   CAPS_LOCK: 20,
-   
-   ESC: 27,
-   
-   SPACE: 32,
-   
-   PAGE_UP: 33,
-   PAGEUP : 33, 
-   
-   PAGE_DOWN: 34,
-   PAGEDOWN : 34, 
-   
-   END: 35,
-   
-   HOME: 36,
-   
-   LEFT: 37,
-   
-   UP: 38,
-   
-   RIGHT: 39,
-   
-   DOWN: 40,
-   
-   PRINT_SCREEN: 44,
-   
-   INSERT: 45,
-   
-   DELETE: 46,
-   
-   ZERO: 48,
-   
-   ONE: 49,
-   
-   TWO: 50,
-   
-   THREE: 51,
-   
-   FOUR: 52,
-   
-   FIVE: 53,
-   
-   SIX: 54,
-   
-   SEVEN: 55,
-   
-   EIGHT: 56,
-   
-   NINE: 57,
-   
-   A: 65,
-   
-   B: 66,
-   
-   C: 67,
-   
-   D: 68,
-   
-   E: 69,
-   
-   F: 70,
-   
-   G: 71,
-   
-   H: 72,
-   
-   I: 73,
-   
-   J: 74,
-   
-   K: 75,
-   
-   L: 76,
-   
-   M: 77,
-   
-   N: 78,
-   
-   O: 79,
-   
-   P: 80,
-   
-   Q: 81,
-   
-   R: 82,
-   
-   S: 83,
-   
-   T: 84,
-   
-   U: 85,
-   
-   V: 86,
-   
-   W: 87,
-   
-   X: 88,
-   
-   Y: 89,
-   
-   Z: 90,
-   
-   CONTEXT_MENU: 93,
-   
-   NUM_ZERO: 96,
-   
-   NUM_ONE: 97,
-   
-   NUM_TWO: 98,
-   
-   NUM_THREE: 99,
-   
-   NUM_FOUR: 100,
-   
-   NUM_FIVE: 101,
-   
-   NUM_SIX: 102,
-   
-   NUM_SEVEN: 103,
-   
-   NUM_EIGHT: 104,
-   
-   NUM_NINE: 105,
-   
-   NUM_MULTIPLY: 106,
-   
-   NUM_PLUS: 107,
-   
-   NUM_MINUS: 109,
-   
-   NUM_PERIOD: 110,
-   
-   NUM_DIVISION: 111,
-   
-   F1: 112,
-   
-   F2: 113,
-   
-   F3: 114,
-   
-   F4: 115,
-   
-   F5: 116,
-   
-   F6: 117,
-   
-   F7: 118,
-   
-   F8: 119,
-   
-   F9: 120,
-   
-   F10: 121,
-   
-   F11: 122,
-   
-   F12: 123,
-
-   
-   isNavKeyPress : function(){
-       var me = this,
-           k = this.normalizeKey(me.keyCode);
-       return (k >= 33 && k <= 40) ||  
-       k == me.RETURN ||
-       k == me.TAB ||
-       k == me.ESC;
-   },
-
-   isSpecialKey : function(){
-       var k = this.normalizeKey(this.keyCode);
-       return (this.type == 'keypress' && this.ctrlKey) ||
-       this.isNavKeyPress() ||
-       (k == this.BACKSPACE) || 
-       (k >= 16 && k <= 20) || 
-       (k >= 44 && k <= 45);   
-   },
-
-   getPoint : function(){
-       return new Ext.lib.Point(this.xy[0], this.xy[1]);
-   },
+        margins : margins
+    };
+}()
+);
 
-   
-   hasModifier : function(){
-       return ((this.ctrlKey || this.altKey) || this.shiftKey);
-   }
-});
 (function(){
-var DOC = document;
-
-Ext.Element = function(element, forceNew){
-    var dom = typeof element == "string" ?
-              DOC.getElementById(element) : element,
-        id;
-
-    if(!dom) return null;
-
-    id = dom.id;
-
-    if(!forceNew && id && Ext.elCache[id]){ 
-        return Ext.elCache[id].el;
-    }
-
-    
-    this.dom = dom;
-
-    
-    this.id = id || Ext.id(dom);
-};
-
 var D = Ext.lib.Dom,
-    DH = Ext.DomHelper,
-    E = Ext.lib.Event,
-    A = Ext.lib.Anim,
-    El = Ext.Element,
-    EC = Ext.elCache;
-
-El.prototype = {
-    
-    set : function(o, useSet){
-        var el = this.dom,
-            attr,
-            val,
-            useSet = (useSet !== false) && !!el.setAttribute;
+        LEFT = "left",
+        RIGHT = "right",
+        TOP = "top",
+        BOTTOM = "bottom",
+        POSITION = "position",
+        STATIC = "static",
+        RELATIVE = "relative",
+        AUTO = "auto",
+        ZINDEX = "z-index";
 
-        for(attr in o){
-            if (o.hasOwnProperty(attr)) {
-                val = o[attr];
-                if (attr == 'style') {
-                    DH.applyStyles(el, val);
-                } else if (attr == 'cls') {
-                    el.className = val;
-                } else if (useSet) {
-                    el.setAttribute(attr, val);
-                } else {
-                    el[attr] = val;
-                }
-            }
-        }
-        return this;
+Ext.Element.addMethods({
+       
+    getX : function(){
+        return D.getX(this.dom);
     },
 
-
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-
-
-    
-    
-    
-
-
-
-    
-    
-    
-    
-    
-    
-
-
-    
-    
-    
-    
-    
-    
-
-
-    
-    
-    
-
-
-    
-    
-    
-    
-    
-    
-    
-
     
-    defaultUnit : "px",
+    getY : function(){
+        return D.getY(this.dom);
+    },
 
     
-    is : function(simpleSelector){
-        return Ext.DomQuery.is(this.dom, simpleSelector);
+    getXY : function(){
+        return D.getXY(this.dom);
     },
 
     
-    focus : function(defer,  dom) {
-        var me = this,
-            dom = dom || me.dom;
-        try{
-            if(Number(defer)){
-                me.focus.defer(defer, null, [null, dom]);
-            }else{
-                dom.focus();
-            }
-        }catch(e){}
-        return me;
+    getOffsetsTo : function(el){
+        var o = this.getXY(),
+               e = Ext.fly(el, '_internal').getXY();
+        return [o[0]-e[0],o[1]-e[1]];
     },
 
     
-    blur : function() {
-        try{
-            this.dom.blur();
-        }catch(e){}
-        return this;
+    setX : function(x, animate){           
+           return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
     },
 
     
-    getValue : function(asNumber){
-        var val = this.dom.value;
-        return asNumber ? parseInt(val, 10) : val;
+    setY : function(y, animate){           
+           return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
     },
 
     
-    addListener : function(eventName, fn, scope, options){
-        Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);
+    setLeft : function(left){
+        this.setStyle(LEFT, this.addUnits(left));
         return this;
     },
 
     
-    removeListener : function(eventName, fn, scope){
-        Ext.EventManager.removeListener(this.dom,  eventName, fn, scope || this);
+    setTop : function(top){
+        this.setStyle(TOP, this.addUnits(top));
         return this;
     },
 
     
-    removeAllListeners : function(){
-        Ext.EventManager.removeAll(this.dom);
+    setRight : function(right){
+        this.setStyle(RIGHT, this.addUnits(right));
         return this;
     },
 
     
-    purgeAllListeners : function() {
-        Ext.EventManager.purgeElement(this, true);
+    setBottom : function(bottom){
+        this.setStyle(BOTTOM, this.addUnits(bottom));
         return this;
     },
+
     
-    addUnits : function(size){
-        if(size === "" || size == "auto" || size === undefined){
-            size = size || '';
-        } else if(!isNaN(size) || !unitPattern.test(size)){
-            size = size + (this.defaultUnit || 'px');
+    setXY : function(pos, animate){
+           var me = this;
+        if(!animate || !me.anim){
+            D.setXY(me.dom, pos);
+        }else{
+            me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
         }
-        return size;
+        return me;
     },
 
     
-    load : function(url, params, cb){
-        Ext.Ajax.request(Ext.apply({
-            params: params,
-            url: url.url || url,
-            callback: cb,
-            el: this.dom,
-            indicatorText: url.indicatorText || ''
-        }, Ext.isObject(url) ? url : {}));
-        return this;
+    setLocation : function(x, y, animate){
+        return this.setXY([x, y], this.animTest(arguments, animate, 2));
     },
 
     
-    isBorderBox : function(){
-        return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;
-    },
-
+    moveTo : function(x, y, animate){
+        return this.setXY([x, y], this.animTest(arguments, animate, 2));        
+    },    
     
-    remove : function(){
-        var me = this,
-            dom = me.dom;
-
-        if (dom) {
-            delete me.dom;
-            Ext.removeNode(dom);
-        }
+    
+    getLeft : function(local){
+           return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
     },
 
     
-    hover : function(overFn, outFn, scope, options){
-        var me = this;
-        me.on('mouseenter', overFn, scope || me.dom, options);
-        me.on('mouseleave', outFn, scope || me.dom, options);
-        return me;
+    getRight : function(local){
+           var me = this;
+           return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
     },
 
     
-    contains : function(el){
-        return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
+    getTop : function(local) {
+           return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
     },
 
     
-    getAttributeNS : function(ns, name){
-        return this.getAttribute(name, ns);
+    getBottom : function(local){
+           var me = this;
+           return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
     },
 
     
-    getAttribute : Ext.isIE ? function(name, ns){
-        var d = this.dom,
-            type = typeof d[ns + ":" + name];
-
-        if(['undefined', 'unknown'].indexOf(type) == -1){
-            return d[ns + ":" + name];
+    position : function(pos, zIndex, x, y){
+           var me = this;
+           
+        if(!pos && me.isStyle(POSITION, STATIC)){           
+            me.setStyle(POSITION, RELATIVE);           
+        } else if(pos) {
+            me.setStyle(POSITION, pos);
         }
-        return d[name];
-    } : function(name, ns){
-        var d = this.dom;
-        return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
+        if(zIndex){
+            me.setStyle(ZINDEX, zIndex);
+        }
+        if(x || y) me.setXY([x || false, y || false]);
     },
 
     
-    update : function(html) {
-        if (this.dom) {
-            this.dom.innerHTML = html;
-        }
+    clearPositioning : function(value){
+        value = value || '';
+        this.setStyle({
+            left : value,
+            right : value,
+            top : value,
+            bottom : value,
+            "z-index" : "",
+            position : STATIC
+        });
         return this;
-    }
-};
-
-var ep = El.prototype;
-
-El.addMethods = function(o){
-   Ext.apply(ep, o);
-};
-
-
-ep.on = ep.addListener;
-
-
-ep.un = ep.removeListener;
-
-
-ep.autoBoxAdjust = true;
-
-
-var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
-    docEl;
-
-
-
+    },
 
-El.get = function(el){
-    var ex,
-        elm,
-        id;
-    if(!el){ return null; }
-    if (typeof el == "string") { 
-        if (!(elm = DOC.getElementById(el))) {
-            return null;
-        }
-        if (EC[el] && EC[el].el) {
-            ex = EC[el].el;
-            ex.dom = elm;
-        } else {
-            ex = El.addToCache(new El(elm));
-        }
-        return ex;
-    } else if (el.tagName) { 
-        if(!(id = el.id)){
-            id = Ext.id(el);
-        }
-        if (EC[id] && EC[id].el) {
-            ex = EC[id].el;
-            ex.dom = el;
-        } else {
-            ex = El.addToCache(new El(el));
+    
+    getPositioning : function(){
+        var l = this.getStyle(LEFT);
+        var t = this.getStyle(TOP);
+        return {
+            "position" : this.getStyle(POSITION),
+            "left" : l,
+            "right" : l ? "" : this.getStyle(RIGHT),
+            "top" : t,
+            "bottom" : t ? "" : this.getStyle(BOTTOM),
+            "z-index" : this.getStyle(ZINDEX)
+        };
+    },
+    
+    
+    setPositioning : function(pc){
+           var me = this,
+               style = me.dom.style;
+               
+        me.setStyle(pc);
+        
+        if(pc.right == AUTO){
+            style.right = "";
         }
-        return ex;
-    } else if (el instanceof El) {
-        if(el != docEl){
-            el.dom = DOC.getElementById(el.id) || el.dom; 
-                                                          
+        if(pc.bottom == AUTO){
+            style.bottom = "";
         }
-        return el;
-    } else if(el.isComposite) {
-        return el;
-    } else if(Ext.isArray(el)) {
-        return El.select(el);
-    } else if(el == DOC) {
         
-        if(!docEl){
-            var f = function(){};
-            f.prototype = El.prototype;
-            docEl = new f();
-            docEl.dom = DOC;
-        }
-        return docEl;
-    }
-    return null;
-};
-
-El.addToCache = function(el, id){
-    id = id || el.id;    
-    EC[id] = {
-        el:  el,
-        data: {},
-        events: {}
-    };
-    return el;
-};
-
+        return me;
+    },    
+       
+    
+    translatePoints : function(x, y){               
+           y = isNaN(x[1]) ? y : x[1];
+        x = isNaN(x[0]) ? x : x[0];
+        var me = this,
+               relative = me.isStyle(POSITION, RELATIVE),
+               o = me.getXY(),
+               l = parseInt(me.getStyle(LEFT), 10),
+               t = parseInt(me.getStyle(TOP), 10);
+        
+        l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
+        t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);        
 
-El.data = function(el, key, value){
-    el = El.get(el);
-    if (!el) {
-        return null;
-    }
-    var c = EC[el.id].data;
-    if(arguments.length == 2){
-        return c[key];
-    }else{
-        return (c[key] = value);
+        return {left: (x - o[0] + l), top: (y - o[1] + t)}; 
+    },
+    
+    animTest : function(args, animate, i) {
+        return !!animate && this.preanim ? this.preanim(args, i) : false;
     }
-};
-
-
+});
+})();
+Ext.Element.addMethods({
+    
+    isScrollable : function(){
+        var dom = this.dom;
+        return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
+    },
 
+    
+    scrollTo : function(side, value){
+        this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
+        return this;
+    },
 
-function garbageCollect(){
-    if(!Ext.enableGarbageCollector){
-        clearInterval(El.collectorThreadId);
-    } else {
-        var eid,
-            el,
-            d,
-            o;
+    
+    getScroll : function(){
+        var d = this.dom, 
+            doc = document,
+            body = doc.body,
+            docElement = doc.documentElement,
+            l,
+            t,
+            ret;
 
-        for(eid in EC){
-            o = EC[eid];
-            if(o.skipGC){
-                continue;
-            }
-            el = o.el;
-            d = el.dom;
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
-                if(Ext.enableListenerCollection){
-                    Ext.EventManager.removeAll(d);
-                }
-                delete EC[eid];
-            }
-        }
-        
-        if (Ext.isIE) {
-            var t = {};
-            for (eid in EC) {
-                t[eid] = EC[eid];
+        if(d == doc || d == body){
+            if(Ext.isIE && Ext.isStrict){
+                l = docElement.scrollLeft; 
+                t = docElement.scrollTop;
+            }else{
+                l = window.pageXOffset;
+                t = window.pageYOffset;
             }
-            EC = Ext.elCache = t;
+            ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
+        }else{
+            ret = {left: d.scrollLeft, top: d.scrollTop};
         }
+        return ret;
     }
-}
-El.collectorThreadId = setInterval(garbageCollect, 30000);
+});
 
-var flyFn = function(){};
-flyFn.prototype = El.prototype;
+Ext.Element.VISIBILITY = 1;
 
+Ext.Element.DISPLAY = 2;
 
-El.Flyweight = function(dom){
-    this.dom = dom;
-};
 
-El.Flyweight.prototype = new flyFn();
-El.Flyweight.prototype.isFlyweight = true;
-El._flyweights = {};
+Ext.Element.OFFSETS = 3;
 
 
-El.fly = function(el, named){
-    var ret = null;
-    named = named || '_global';
+Ext.Element.ASCLASS = 4;
 
-    if (el = Ext.getDom(el)) {
-        (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
-        ret = El._flyweights[named];
-    }
-    return ret;
-};
 
+Ext.Element.visibilityCls = 'x-hide-nosize';
 
-Ext.get = El.get;
+Ext.Element.addMethods(function(){
+    var El = Ext.Element,
+        OPACITY = "opacity",
+        VISIBILITY = "visibility",
+        DISPLAY = "display",
+        HIDDEN = "hidden",
+        OFFSETS = "offsets",
+        ASCLASS = "asclass",
+        NONE = "none",
+        NOSIZE = 'nosize',
+        ORIGINALDISPLAY = 'originalDisplay',
+        VISMODE = 'visibilityMode',
+        ISVISIBLE = 'isVisible',
+        data = El.data,
+        getDisplay = function(dom){
+            var d = data(dom, ORIGINALDISPLAY);
+            if(d === undefined){
+                data(dom, ORIGINALDISPLAY, d = '');
+            }
+            return d;
+        },
+        getVisMode = function(dom){
+            var m = data(dom, VISMODE);
+            if(m === undefined){
+                data(dom, VISMODE, m = 1);
+            }
+            return m;
+        };
 
+    return {
+        
+        originalDisplay : "",
+        visibilityMode : 1,
 
-Ext.fly = El.fly;
+        
+        setVisibilityMode : function(visMode){
+            data(this.dom, VISMODE, visMode);
+            return this;
+        },
 
+        
+        animate : function(args, duration, onComplete, easing, animType){
+            this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
+            return this;
+        },
 
-var noBoxAdjust = Ext.isStrict ? {
-    select:1
-} : {
-    input:1, select:1, textarea:1
-};
-if(Ext.isIE || Ext.isGecko){
-    noBoxAdjust['button'] = 1;
-}
+        
+        anim : function(args, opt, animType, defaultDur, defaultEase, cb){
+            animType = animType || 'run';
+            opt = opt || {};
+            var me = this,
+                anim = Ext.lib.Anim[animType](
+                    me.dom,
+                    args,
+                    (opt.duration || defaultDur) || .35,
+                    (opt.easing || defaultEase) || 'easeOut',
+                    function(){
+                        if(cb) cb.call(me);
+                        if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
+                    },
+                    me
+                );
+            opt.anim = anim;
+            return anim;
+        },
 
+        
+        preanim : function(a, i){
+            return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
+        },
 
-Ext.EventManager.on(window, 'unload', function(){
-    delete EC;
-    delete El._flyweights;
-});
-})();
+        
+        isVisible : function() {
+            var me = this,
+                dom = me.dom,
+                visible = data(dom, ISVISIBLE);
 
-Ext.Element.addMethods({
-    
-    swallowEvent : function(eventName, preventDefault){
-        var me = this;
-        function fn(e){
-            e.stopPropagation();
-            if(preventDefault){
-                e.preventDefault();
+            if(typeof visible == 'boolean'){ 
+                return visible;
             }
-        }
-        if(Ext.isArray(eventName)){
-            Ext.each(eventName, function(e) {
-                 me.on(e, fn);
-            });
-            return me;
-        }
-        me.on(eventName, fn);
-        return me;
-    },
+            
+            visible = !me.isStyle(VISIBILITY, HIDDEN) &&
+                      !me.isStyle(DISPLAY, NONE) &&
+                      !((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls));
 
-    
-    relayEvent : function(eventName, observable){
-        this.on(eventName, function(e){
-            observable.fireEvent(eventName, e);
-        });
-    },
+            data(dom, ISVISIBLE, visible);
+            return visible;
+        },
 
-    
-    clean : function(forceReclean){
-        var me = this,
-            dom = me.dom,
-            n = dom.firstChild,
-            ni = -1;
+        
+        setVisible : function(visible, animate){
+            var me = this, isDisplay, isVisibility, isOffsets, isNosize,
+                dom = me.dom,
+                visMode = getVisMode(dom);
 
-        if(Ext.Element.data(dom, 'isCleaned') && forceReclean !== true){
-            return me;
-        }
 
-        while(n){
-            var nx = n.nextSibling;
-            if(n.nodeType == 3 && !/\S/.test(n.nodeValue)){
-                dom.removeChild(n);
-            }else{
-                n.nodeIndex = ++ni;
+            
+            if (typeof animate == 'string'){
+                switch (animate) {
+                    case DISPLAY:
+                        visMode = El.DISPLAY;
+                        break;
+                    case VISIBILITY:
+                        visMode = El.VISIBILITY;
+                        break;
+                    case OFFSETS:
+                        visMode = El.OFFSETS;
+                        break;
+                    case NOSIZE:
+                    case ASCLASS:
+                        visMode = El.ASCLASS;
+                        break;
+                }
+                me.setVisibilityMode(visMode);
+                animate = false;
             }
-            n = nx;
-        }
-        Ext.Element.data(dom, 'isCleaned', true);
-        return me;
-    },
-
-    
-    load : function(){
-        var um = this.getUpdater();
-        um.update.apply(um, arguments);
-        return this;
-    },
-
-    
-    getUpdater : function(){
-        return this.updateManager || (this.updateManager = new Ext.Updater(this));
-    },
 
-    
-    update : function(html, loadScripts, callback){
-        if (!this.dom) {
-            return this;
-        }
-        html = html || "";
+            if (!animate || !me.anim) {
+                if(visMode == El.ASCLASS ){
 
-        if(loadScripts !== true){
-            this.dom.innerHTML = html;
-            if(Ext.isFunction(callback)){
-                callback();
-            }
-            return this;
-        }
+                    me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls);
 
-        var id = Ext.id(),
-            dom = this.dom;
+                } else if (visMode == El.DISPLAY){
 
-        html += '<span id="' + id + '"></span>';
+                    return me.setDisplayed(visible);
 
-        Ext.lib.Event.onAvailable(id, function(){
-            var DOC = document,
-                hd = DOC.getElementsByTagName("head")[0],
-                re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
-                srcRe = /\ssrc=([\'\"])(.*?)\1/i,
-                typeRe = /\stype=([\'\"])(.*?)\1/i,
-                match,
-                attrs,
-                srcMatch,
-                typeMatch,
-                el,
-                s;
+                } else if (visMode == El.OFFSETS){
 
-            while((match = re.exec(html))){
-                attrs = match[1];
-                srcMatch = attrs ? attrs.match(srcRe) : false;
-                if(srcMatch && srcMatch[2]){
-                   s = DOC.createElement("script");
-                   s.src = srcMatch[2];
-                   typeMatch = attrs.match(typeRe);
-                   if(typeMatch && typeMatch[2]){
-                       s.type = typeMatch[2];
-                   }
-                   hd.appendChild(s);
-                }else if(match[2] && match[2].length > 0){
-                    if(window.execScript) {
-                       window.execScript(match[2]);
+                    if (!visible){
+                        me.hideModeStyles = {
+                            position: me.getStyle('position'),
+                            top: me.getStyle('top'),
+                            left: me.getStyle('left')
+                        };
+                        me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'});
                     } else {
-                       window.eval(match[2]);
+                        me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''});
+                        delete me.hideModeStyles;
                     }
+
+                }else{
+                    me.fixDisplay();
+                    dom.style.visibility = visible ? "visible" : HIDDEN;
                 }
+            }else{
+                
+                if(visible){
+                    me.setOpacity(.01);
+                    me.setVisible(true);
+                }
+                me.anim({opacity: { to: (visible?1:0) }},
+                        me.preanim(arguments, 1),
+                        null,
+                        .35,
+                        'easeIn',
+                        function(){
+                            visible || me.setVisible(false).setOpacity(1);
+                        });
             }
-            el = DOC.getElementById(id);
-            if(el){Ext.removeNode(el);}
-            if(Ext.isFunction(callback)){
-                callback();
-            }
-        });
-        dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
-        return this;
-    },
-
-    
-    removeAllListeners : function(){
-        this.removeAnchor();
-        Ext.EventManager.removeAll(this.dom);
-        return this;
-    },
+            data(dom, ISVISIBLE, visible);  
+            return me;
+        },
 
-    
-    createProxy : function(config, renderTo, matchBox){
-        config = Ext.isObject(config) ? config : {tag : "div", cls: config};
 
-        var me = this,
-            proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
-                               Ext.DomHelper.insertBefore(me.dom, config, true);
+        
+        hasMetrics  : function(){
+            var dom = this.dom;
+            return this.isVisible() || (getVisMode(dom) == El.VISIBILITY);
+        },
 
-        if(matchBox && me.setBox && me.getBox){ 
-           proxy.setBox(me.getBox());
-        }
-        return proxy;
-    }
-});
+        
+        toggle : function(animate){
+            var me = this;
+            me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
+            return me;
+        },
 
-Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
+        
+        setDisplayed : function(value) {
+            if(typeof value == "boolean"){
+               value = value ? getDisplay(this.dom) : NONE;
+            }
+            this.setStyle(DISPLAY, value);
+            return this;
+        },
 
-Ext.Element.addMethods({
-    
-    getAnchorXY : function(anchor, local, s){
         
+        fixDisplay : function(){
+            var me = this;
+            if(me.isStyle(DISPLAY, NONE)){
+                me.setStyle(VISIBILITY, HIDDEN);
+                me.setStyle(DISPLAY, getDisplay(this.dom)); 
+                if(me.isStyle(DISPLAY, NONE)){ 
+                    me.setStyle(DISPLAY, "block");
+                }
+            }
+        },
+
         
-               anchor = (anchor || "tl").toLowerCase();
-        s = s || {};
+        hide : function(animate){
+            
+            if (typeof animate == 'string'){
+                this.setVisible(false, animate);
+                return this;
+            }
+            this.setVisible(false, this.preanim(arguments, 0));
+            return this;
+        },
+
         
-        var me = this,        
-               vp = me.dom == document.body || me.dom == document,
-               w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
-               h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),                              
-               xy,             
-               r = Math.round,
-               o = me.getXY(),
-               scroll = me.getScroll(),
-               extraX = vp ? scroll.left : !local ? o[0] : 0,
-               extraY = vp ? scroll.top : !local ? o[1] : 0,
-               hash = {
-                       c  : [r(w * 0.5), r(h * 0.5)],
-                       t  : [r(w * 0.5), 0],
-                       l  : [0, r(h * 0.5)],
-                       r  : [w, r(h * 0.5)],
-                       b  : [r(w * 0.5), h],
-                       tl : [0, 0],    
-                       bl : [0, h],
-                       br : [w, h],
-                       tr : [w, 0]
-               };
-        
-        xy = hash[anchor];     
-        return [xy[0] + extraX, xy[1] + extraY]; 
-    },
-
-    
-    anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){        
-           var me = this,
-            dom = me.dom,
-            scroll = !Ext.isEmpty(monitorScroll),
-            action = function(){
-                Ext.fly(dom).alignTo(el, alignment, offsets, animate);
-                Ext.callback(callback, Ext.fly(dom));
-            },
-            anchor = this.getAnchor();
-            
-        
-        this.removeAnchor();
-        Ext.apply(anchor, {
-            fn: action,
-            scroll: scroll
-        });
-
-        Ext.EventManager.onWindowResize(action, null);
-        
-        if(scroll){
-            Ext.EventManager.on(window, 'scroll', action, null,
-                {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
-        }
-        action.call(me); 
-        return me;
-    },
-    
-    
-    removeAnchor : function(){
-        var me = this,
-            anchor = this.getAnchor();
+        show : function(animate){
             
-        if(anchor && anchor.fn){
-            Ext.EventManager.removeResizeListener(anchor.fn);
-            if(anchor.scroll){
-                Ext.EventManager.un(window, 'scroll', anchor.fn);
-            }
-            delete anchor.fn;
-        }
-        return me;
-    },
-    
-    
-    getAnchor : function(){
-        var data = Ext.Element.data,
-            dom = this.dom;
-            if (!dom) {
-                return;
+            if (typeof animate == 'string'){
+                this.setVisible(true, animate);
+                return this;
             }
-            var anchor = data(dom, '_anchor');
-            
-        if(!anchor){
-            anchor = data(dom, '_anchor', {});
+            this.setVisible(true, this.preanim(arguments, 0));
+            return this;
         }
-        return anchor;
-    },
-
+    };
+}());(function(){
     
-    getAlignToXY : function(el, p, o){     
-        el = Ext.get(el);
-        
-        if(!el || !el.dom){
-            throw "Element.alignToXY with an element that doesn't exist";
-        }
-        
-        o = o || [0,0];
-        p = (!p || p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();       
-                
-        var me = this,
-               d = me.dom,
-               a1,
-               a2,
-               x,
-               y,
-               
-               w,
-               h,
-               r,
-               dw = Ext.lib.Dom.getViewWidth() -10, 
-               dh = Ext.lib.Dom.getViewHeight()-10, 
-               p1y,
-               p1x,            
-               p2y,
-               p2x,
-               swapY,
-               swapX,
-               doc = document,
-               docElement = doc.documentElement,
-               docBody = doc.body,
-               scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
-               scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
-               c = false, 
-               p1 = "", 
-               p2 = "",
-               m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
-        
-        if(!m){
-           throw "Element.alignTo with an invalid alignment " + p;
-        }
+    var NULL = null,
+        UNDEFINED = undefined,
+        TRUE = true,
+        FALSE = false,
+        SETX = "setX",
+        SETY = "setY",
+        SETXY = "setXY",
+        LEFT = "left",
+        BOTTOM = "bottom",
+        TOP = "top",
+        RIGHT = "right",
+        HEIGHT = "height",
+        WIDTH = "width",
+        POINTS = "points",
+        HIDDEN = "hidden",
+        ABSOLUTE = "absolute",
+        VISIBLE = "visible",
+        MOTION = "motion",
+        POSITION = "position",
+        EASEOUT = "easeOut",
         
-        p1 = m[1]; 
-        p2 = m[2]; 
-        c = !!m[3];
-
+        flyEl = new Ext.Element.Flyweight(),
+        queues = {},
+        getObject = function(o){
+            return o || {};
+        },
+        fly = function(dom){
+            flyEl.dom = dom;
+            flyEl.id = Ext.id(dom);
+            return flyEl;
+        },
         
+        getQueue = function(id){
+            if(!queues[id]){
+                queues[id] = [];
+            }
+            return queues[id];
+        },
+        setQueue = function(id, value){
+            queues[id] = value;
+        };
         
-        a1 = me.getAnchorXY(p1, true);
-        a2 = el.getAnchorXY(p2, false);
-
-        x = a2[0] - a1[0] + o[0];
-        y = a2[1] - a1[1] + o[1];
 
-        if(c){    
-              w = me.getWidth();
-           h = me.getHeight();
-           r = el.getRegion();       
-           
-           
-           
-           p1y = p1.charAt(0);
-           p1x = p1.charAt(p1.length-1);
-           p2y = p2.charAt(0);
-           p2x = p2.charAt(p2.length-1);
-           swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
-           swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));          
-           
+Ext.enableFx = TRUE;
 
-           if (x + w > dw + scrollX) {
-                x = swapX ? r.left-w : dw+scrollX-w;
-           }
-           if (x < scrollX) {
-               x = swapX ? r.right : scrollX;
-           }
-           if (y + h > dh + scrollY) {
-                y = swapY ? r.top-h : dh+scrollY-h;
-            }
-           if (y < scrollY){
-               y = swapY ? r.bottom : scrollY;
-           }
-        }
-        return [x,y];
-    },
 
+Ext.Fx = {
     
-    alignTo : function(element, position, offsets, animate){
-           var me = this;
-        return me.setXY(me.getAlignToXY(element, position, offsets),
-                               me.preanim && !!animate ? me.preanim(arguments, 3) : false);
-    },
     
     
-    adjustForConstraints : function(xy, parent, offsets){
-        return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
+    switchStatements : function(key, fn, argHash){
+        return fn.apply(this, argHash[key]);
     },
-
     
-    getConstrainToXY : function(el, local, offsets, proposedXY){   
-           var os = {top:0, left:0, bottom:0, right: 0};
-
-        return function(el, local, offsets, proposedXY){
-            el = Ext.get(el);
-            offsets = offsets ? Ext.applyIf(offsets, os) : os;
-
-            var vw, vh, vx = 0, vy = 0;
-            if(el.dom == document.body || el.dom == document){
-                vw =Ext.lib.Dom.getViewWidth();
-                vh = Ext.lib.Dom.getViewHeight();
-            }else{
-                vw = el.dom.clientWidth;
-                vh = el.dom.clientHeight;
-                if(!local){
-                    var vxy = el.getXY();
-                    vx = vxy[0];
-                    vy = vxy[1];
-                }
-            }
-
-            var s = el.getScroll();
-
-            vx += offsets.left + s.left;
-            vy += offsets.top + s.top;
-
-            vw -= offsets.right;
-            vh -= offsets.bottom;
-
-            var vr = vx+vw;
-            var vb = vy+vh;
-
-            var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
-            var x = xy[0], y = xy[1];
-            var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
-
+    
+    slideIn : function(anchor, o){ 
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            st = dom.style,
+            xy,
+            r,
+            b,              
+            wrap,               
+            after,
+            st,
+            args, 
+            pt,
+            bw,
+            bh;
             
-            var moved = false;
+        anchor = anchor || "t";
 
+        me.queueFx(o, function(){            
+            xy = fly(dom).getXY();
             
-            if((x + w) > vr){
-                x = vr - w;
-                moved = true;
-            }
-            if((y + h) > vb){
-                y = vb - h;
-                moved = true;
-            }
+            fly(dom).fixDisplay();            
             
-            if(x < vx){
-                x = vx;
-                moved = true;
-            }
-            if(y < vy){
-                y = vy;
-                moved = true;
+            
+            r = fly(dom).getFxRestore();      
+            b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
+            b.right = b.x + b.width;
+            b.bottom = b.y + b.height;
+            
+            
+            fly(dom).setWidth(b.width).setHeight(b.height);            
+            
+            
+            wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
+            
+            st.visibility = VISIBLE;
+            st.position = ABSOLUTE;
+            
+            
+            function after(){
+                 fly(dom).fxUnwrap(wrap, r.pos, o);
+                 st.width = r.width;
+                 st.height = r.height;
+                 fly(dom).afterFx(o);
             }
-            return moved ? [x, y] : false;
-        };
-    }(),
-           
-           
-               
-
+            
+            
+            pt = {to: [b.x, b.y]}; 
+            bw = {to: b.width};
+            bh = {to: b.height};
+                
+            function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){                    
+                var ret = {};
+                fly(wrap).setWidth(ww).setHeight(wh);
+                if(fly(wrap)[sXY]){
+                    fly(wrap)[sXY](sXYval);                  
+                }
+                style[s1] = style[s2] = "0";                    
+                if(w){
+                    ret.width = w;
+                }
+                if(h){
+                    ret.height = h;
+                }
+                if(p){
+                    ret.points = p;
+                }
+                return ret;
+            };
 
+            args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
+                    t  : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
+                    l  : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
+                    r  : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
+                    b  : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
+                    tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
+                    bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
+                    br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
+                    tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
+                });
+            
+            st.visibility = VISIBLE;
+            fly(wrap).show();
 
+            arguments.callee.anim = fly(wrap).fxanim(args,
+                o,
+                MOTION,
+                .5,
+                EASEOUT, 
+                after);
+        });
+        return me;
+    },
+    
+    
+    slideOut : function(anchor, o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            st = dom.style,
+            xy = me.getXY(),
+            wrap,
+            r,
+            b,
+            a,
+            zero = {to: 0}; 
+                    
+        anchor = anchor || "t";
 
+        me.queueFx(o, function(){
+            
+            
+            r = fly(dom).getFxRestore(); 
+            b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
+            b.right = b.x + b.width;
+            b.bottom = b.y + b.height;
+                
+            
+            fly(dom).setWidth(b.width).setHeight(b.height);
 
+            
+            wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
+                
+            st.visibility = VISIBLE;
+            st.position = ABSOLUTE;
+            fly(wrap).setWidth(b.width).setHeight(b.height);            
 
+            function after(){
+                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();                
+                fly(dom).fxUnwrap(wrap, r.pos, o);
+                st.width = r.width;
+                st.height = r.height;
+                fly(dom).afterFx(o);
+            }            
+            
+            function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){                    
+                var ret = {};
+                
+                style[s1] = style[s2] = "0";
+                ret[p1] = v1;               
+                if(p2){
+                    ret[p2] = v2;               
+                }
+                if(p3){
+                    ret[p3] = v3;
+                }
+                
+                return ret;
+            };
+            
+            a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
+                t  : [st, LEFT, BOTTOM, HEIGHT, zero],
+                l  : [st, RIGHT, TOP, WIDTH, zero],
+                r  : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
+                b  : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
+                tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
+                bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
+                br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
+                tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
+            });
+            
+            arguments.callee.anim = fly(wrap).fxanim(a,
+                o,
+                MOTION,
+                .5,
+                EASEOUT, 
+                after);
+        });
+        return me;
+    },
 
+    
+    puff : function(o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            st = dom.style,
+            width,
+            height,
+            r;
 
+        me.queueFx(o, function(){
+            width = fly(dom).getWidth();
+            height = fly(dom).getHeight();
+            fly(dom).clearOpacity();
+            fly(dom).show();
 
+            
+            r = fly(dom).getFxRestore();                   
+            
+            function after(){
+                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();                  
+                fly(dom).clearOpacity();  
+                fly(dom).setPositioning(r.pos);
+                st.width = r.width;
+                st.height = r.height;
+                st.fontSize = '';
+                fly(dom).afterFx(o);
+            }   
 
+            arguments.callee.anim = fly(dom).fxanim({
+                    width : {to : fly(dom).adjustWidth(width * 2)},
+                    height : {to : fly(dom).adjustHeight(height * 2)},
+                    points : {by : [-width * .5, -height * .5]},
+                    opacity : {to : 0},
+                    fontSize: {to : 200, unit: "%"}
+                },
+                o,
+                MOTION,
+                .5,
+                EASEOUT,
+                 after);
+        });
+        return me;
+    },
 
+    
+    switchOff : function(o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            st = dom.style,
+            r;
 
+        me.queueFx(o, function(){
+            fly(dom).clearOpacity();
+            fly(dom).clip();
 
+            
+            r = fly(dom).getFxRestore();
+                
+            function after(){
+                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();  
+                fly(dom).clearOpacity();
+                fly(dom).setPositioning(r.pos);
+                st.width = r.width;
+                st.height = r.height;   
+                fly(dom).afterFx(o);
+            };
 
+            fly(dom).fxanim({opacity : {to : 0.3}}, 
+                NULL, 
+                NULL, 
+                .1, 
+                NULL, 
+                function(){                                 
+                    fly(dom).clearOpacity();
+                        (function(){                            
+                            fly(dom).fxanim({
+                                height : {to : 1},
+                                points : {by : [0, fly(dom).getHeight() * .5]}
+                            }, 
+                            o, 
+                            MOTION, 
+                            0.3, 
+                            'easeIn', 
+                            after);
+                        }).defer(100);
+                });
+        });
+        return me;
+    },
 
+     
+    highlight : function(color, o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            attr = o.attr || "backgroundColor",
+            a = {},
+            restore;
 
+        me.queueFx(o, function(){
+            fly(dom).clearOpacity();
+            fly(dom).show();
 
+            function after(){
+                dom.style[attr] = restore;
+                fly(dom).afterFx(o);
+            }            
+            restore = dom.style[attr];
+            a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
+            arguments.callee.anim = fly(dom).fxanim(a,
+                o,
+                'color',
+                1,
+                'easeIn', 
+                after);
+        });
+        return me;
+    },
 
+   
+    frame : function(color, count, o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            proxy,
+            active;
 
+        me.queueFx(o, function(){
+            color = color || '#C3DAF9';
+            if(color.length == 6){
+                color = '#' + color;
+            }            
+            count = count || 1;
+            fly(dom).show();
 
+            var xy = fly(dom).getXY(),
+                b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
+                queue = function(){
+                    proxy = fly(document.body || document.documentElement).createChild({
+                        style:{
+                            position : ABSOLUTE,
+                            'z-index': 35000, 
+                            border : '0px solid ' + color
+                        }
+                    });
+                    return proxy.queueFx({}, animFn);
+                };
+            
+            
+            arguments.callee.anim = {
+                isAnimated: true,
+                stop: function() {
+                    count = 0;
+                    proxy.stopFx();
+                }
+            };
+            
+            function animFn(){
+                var scale = Ext.isBorderBox ? 2 : 1;
+                active = proxy.anim({
+                    top : {from : b.y, to : b.y - 20},
+                    left : {from : b.x, to : b.x - 20},
+                    borderWidth : {from : 0, to : 10},
+                    opacity : {from : 1, to : 0},
+                    height : {from : b.height, to : b.height + 20 * scale},
+                    width : {from : b.width, to : b.width + 20 * scale}
+                },{
+                    duration: o.duration || 1,
+                    callback: function() {
+                        proxy.remove();
+                        --count > 0 ? queue() : fly(dom).afterFx(o);
+                    }
+                });
+                arguments.callee.anim = {
+                    isAnimated: true,
+                    stop: function(){
+                        active.stop();
+                    }
+                };
+            };
+            queue();
+        });
+        return me;
+    },
 
+   
+    pause : function(seconds){        
+        var dom = this.dom,
+            t;
 
+        this.queueFx({}, function(){
+            t = setTimeout(function(){
+                fly(dom).afterFx({});
+            }, seconds * 1000);
+            arguments.callee.anim = {
+                isAnimated: true,
+                stop: function(){
+                    clearTimeout(t);
+                    fly(dom).afterFx({});
+                }
+            };
+        });
+        return this;
+    },
 
+   
+    fadeIn : function(o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            to = o.endOpacity || 1;
+        
+        me.queueFx(o, function(){
+            fly(dom).setOpacity(0);
+            fly(dom).fixDisplay();
+            dom.style.visibility = VISIBLE;
+            arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
+                o, NULL, .5, EASEOUT, function(){
+                if(to == 1){
+                    fly(dom).clearOpacity();
+                }
+                fly(dom).afterFx(o);
+            });
+        });
+        return me;
+    },
 
+   
+    fadeOut : function(o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            style = dom.style,
+            to = o.endOpacity || 0;         
+        
+        me.queueFx(o, function(){  
+            arguments.callee.anim = fly(dom).fxanim({ 
+                opacity : {to : to}},
+                o, 
+                NULL, 
+                .5, 
+                EASEOUT, 
+                function(){
+                    if(to == 0){
+                        Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ? 
+                            style.display = "none" :
+                            style.visibility = HIDDEN;
+                            
+                        fly(dom).clearOpacity();
+                    }
+                    fly(dom).afterFx(o);
+            });
+        });
+        return me;
+    },
 
+   
+    scale : function(w, h, o){
+        this.shift(Ext.apply({}, o, {
+            width: w,
+            height: h
+        }));
+        return this;
+    },
 
+   
+    shift : function(o){
+        o = getObject(o);
+        var dom = this.dom,
+            a = {};
+                
+        this.queueFx(o, function(){
+            for (var prop in o) {
+                if (o[prop] != UNDEFINED) {                                                 
+                    a[prop] = {to : o[prop]};                   
+                }
+            } 
+            
+            a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
+            a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;   
+            
+            if (a.x || a.y || a.xy) {
+                a.points = a.xy || 
+                           {to : [ a.x ? a.x.to : fly(dom).getX(),
+                                   a.y ? a.y.to : fly(dom).getY()]};                  
+            }
 
+            arguments.callee.anim = fly(dom).fxanim(a,
+                o, 
+                MOTION, 
+                .35, 
+                EASEOUT, 
+                function(){
+                    fly(dom).afterFx(o);
+                });
+        });
+        return this;
+    },
 
+    
+    ghost : function(anchor, o){
+        o = getObject(o);
+        var me = this,
+            dom = me.dom,
+            st = dom.style,
+            a = {opacity: {to: 0}, points: {}},
+            pt = a.points,
+            r,
+            w,
+            h;
+            
+        anchor = anchor || "b";
 
+        me.queueFx(o, function(){
+            
+            r = fly(dom).getFxRestore();
+            w = fly(dom).getWidth();
+            h = fly(dom).getHeight();
+            
+            function after(){
+                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();   
+                fly(dom).clearOpacity();
+                fly(dom).setPositioning(r.pos);
+                st.width = r.width;
+                st.height = r.height;
+                fly(dom).afterFx(o);
+            }
+                
+            pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
+               t  : [0, -h],
+               l  : [-w, 0],
+               r  : [w, 0],
+               b  : [0, h],
+               tl : [-w, -h],
+               bl : [-w, h],
+               br : [w, h],
+               tr : [w, -h] 
+            });
+                
+            arguments.callee.anim = fly(dom).fxanim(a,
+                o,
+                MOTION,
+                .5,
+                EASEOUT, after);
+        });
+        return me;
+    },
 
+    
+    syncFx : function(){
+        var me = this;
+        me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
+            block : FALSE,
+            concurrent : TRUE,
+            stopFx : FALSE
+        });
+        return me;
+    },
 
+    
+    sequenceFx : function(){
+        var me = this;
+        me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
+            block : FALSE,
+            concurrent : FALSE,
+            stopFx : FALSE
+        });
+        return me;
+    },
 
+    
+    nextFx : function(){        
+        var ef = getQueue(this.dom.id)[0];
+        if(ef){
+            ef.call(this);
+        }
+    },
 
+    
+    hasActiveFx : function(){
+        return getQueue(this.dom.id)[0];
+    },
 
+    
+    stopFx : function(finish){
+        var me = this,
+            id = me.dom.id;
+        if(me.hasActiveFx()){
+            var cur = getQueue(id)[0];
+            if(cur && cur.anim){
+                if(cur.anim.isAnimated){
+                    setQueue(id, [cur]); 
+                    cur.anim.stop(finish !== undefined ? finish : TRUE);
+                }else{
+                    setQueue(id, []);
+                }
+            }
+        }
+        return me;
+    },
 
+    
+    beforeFx : function(o){
+        if(this.hasActiveFx() && !o.concurrent){
+           if(o.stopFx){
+               this.stopFx();
+               return TRUE;
+           }
+           return FALSE;
+        }
+        return TRUE;
+    },
 
+    
+    hasFxBlock : function(){
+        var q = getQueue(this.dom.id);
+        return q && q[0] && q[0].block;
+    },
 
+    
+    queueFx : function(o, fn){
+        var me = fly(this.dom);
+        if(!me.hasFxBlock()){
+            Ext.applyIf(o, me.fxDefaults);
+            if(!o.concurrent){
+                var run = me.beforeFx(o);
+                fn.block = o.block;
+                getQueue(me.dom.id).push(fn);
+                if(run){
+                    me.nextFx();
+                }
+            }else{
+                fn.call(me);
+            }
+        }
+        return me;
+    },
 
+    
+    fxWrap : function(pos, o, vis){ 
+        var dom = this.dom,
+            wrap,
+            wrapXY;
+        if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){            
+            if(o.fixPosition){
+                wrapXY = fly(dom).getXY();
+            }
+            var div = document.createElement("div");
+            div.style.visibility = vis;
+            wrap = dom.parentNode.insertBefore(div, dom);
+            fly(wrap).setPositioning(pos);
+            if(fly(wrap).isStyle(POSITION, "static")){
+                fly(wrap).position("relative");
+            }
+            fly(dom).clearPositioning('auto');
+            fly(wrap).clip();
+            wrap.appendChild(dom);
+            if(wrapXY){
+                fly(wrap).setXY(wrapXY);
+            }
+        }
+        return wrap;
+    },
 
+    
+    fxUnwrap : function(wrap, pos, o){      
+        var dom = this.dom;
+        fly(dom).clearPositioning();
+        fly(dom).setPositioning(pos);
+        if(!o.wrap){
+            var pn = fly(wrap).dom.parentNode;
+            pn.insertBefore(dom, wrap); 
+            fly(wrap).remove();
+        }
+    },
 
+    
+    getFxRestore : function(){
+        var st = this.dom.style;
+        return {pos: this.getPositioning(), width: st.width, height : st.height};
+    },
 
+    
+    afterFx : function(o){
+        var dom = this.dom,
+            id = dom.id;
+        if(o.afterStyle){
+            fly(dom).setStyle(o.afterStyle);            
+        }
+        if(o.afterCls){
+            fly(dom).addClass(o.afterCls);
+        }
+        if(o.remove == TRUE){
+            fly(dom).remove();
+        }
+        if(o.callback){
+            o.callback.call(o.scope, fly(dom));
+        }
+        if(!o.concurrent){
+            getQueue(id).shift();
+            fly(dom).nextFx();
+        }
+    },
 
+    
+    fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
+        animType = animType || 'run';
+        opt = opt || {};
+        var anim = Ext.lib.Anim[animType](
+                this.dom, 
+                args,
+                (opt.duration || defaultDur) || .35,
+                (opt.easing || defaultEase) || EASEOUT,
+                cb,            
+                this
+            );
+        opt.anim = anim;
+        return anim;
+    }
+};
 
 
+Ext.Fx.resize = Ext.Fx.scale;
 
 
 
+Ext.Element.addMethods(Ext.Fx);
+})();
 
+Ext.CompositeElementLite = function(els, root){
+    
+    this.elements = [];
+    this.add(els, root);
+    this.el = new Ext.Element.Flyweight();
+};
 
+Ext.CompositeElementLite.prototype = {
+    isComposite: true,
 
+    
+    getElement : function(el){
+        
+        var e = this.el;
+        e.dom = el;
+        e.id = el.id;
+        return e;
+    },
 
+    
+    transformElement : function(el){
+        return Ext.getDom(el);
+    },
 
     
+    getCount : function(){
+        return this.elements.length;
+    },
     
-    getCenterXY : function(){
-        return this.getAlignToXY(document, 'c-c');
+    add : function(els, root){
+        var me = this,
+            elements = me.elements;
+        if(!els){
+            return this;
+        }
+        if(typeof els == "string"){
+            els = Ext.Element.selectorFunction(els, root);
+        }else if(els.isComposite){
+            els = els.elements;
+        }else if(!Ext.isIterable(els)){
+            els = [els];
+        }
+
+        for(var i = 0, len = els.length; i < len; ++i){
+            elements.push(me.transformElement(els[i]));
+        }
+        return me;
     },
 
+    invoke : function(fn, args){
+        var me = this,
+            els = me.elements,
+            len = els.length,
+            e,
+            i;
+
+        for(i = 0; i < len; i++) {
+            e = els[i];
+            if(e){
+                Ext.Element.prototype[fn].apply(me.getElement(e), args);
+            }
+        }
+        return me;
+    },
     
-    center : function(centerIn){
-        return this.alignTo(centerIn || document, 'c-c');        
-    }    
-});
+    item : function(index){
+        var me = this,
+            el = me.elements[index],
+            out = null;
 
-Ext.Element.addMethods(function(){
-       var PARENTNODE = 'parentNode',
-               NEXTSIBLING = 'nextSibling',
-               PREVIOUSSIBLING = 'previousSibling',
-               DQ = Ext.DomQuery,
-               GET = Ext.get;
-       
-       return {
-               
-           findParent : function(simpleSelector, maxDepth, returnEl){
-               var p = this.dom,
-                       b = document.body, 
-                       depth = 0,                      
-                       stopEl;         
-            if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
-                return null;
+        if(el){
+            out = me.getElement(el);
+        }
+        return out;
+    },
+
+    
+    addListener : function(eventName, handler, scope, opt){
+        var els = this.elements,
+            len = els.length,
+            i, e;
+
+        for(i = 0; i<len; i++) {
+            e = els[i];
+            if(e) {
+                Ext.EventManager.on(e, eventName, handler, scope || e, opt);
             }
-               maxDepth = maxDepth || 50;
-               if (isNaN(maxDepth)) {
-                   stopEl = Ext.getDom(maxDepth);
-                   maxDepth = Number.MAX_VALUE;
-               }
-               while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
-                   if(DQ.is(p, simpleSelector)){
-                       return returnEl ? GET(p) : p;
-                   }
-                   depth++;
-                   p = p.parentNode;
-               }
-               return null;
-           },
-       
-           
-           findParentNode : function(simpleSelector, maxDepth, returnEl){
-               var p = Ext.fly(this.dom.parentNode, '_internal');
-               return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
-           },
-       
-           
-           up : function(simpleSelector, maxDepth){
-               return this.findParentNode(simpleSelector, maxDepth, true);
-           },
-       
-           
-           select : function(selector){
-               return Ext.Element.select(selector, this.dom);
-           },
-       
-           
-           query : function(selector){
-               return DQ.select(selector, this.dom);
-           },
-       
-           
-           child : function(selector, returnDom){
-               var n = DQ.selectNode(selector, this.dom);
-               return returnDom ? n : GET(n);
-           },
-       
-           
-           down : function(selector, returnDom){
-               var n = DQ.selectNode(" > " + selector, this.dom);
-               return returnDom ? n : GET(n);
-           },
-       
-                
-           parent : function(selector, returnDom){
-               return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
-           },
-       
-            
-           next : function(selector, returnDom){
-               return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
-           },
-       
-           
-           prev : function(selector, returnDom){
-               return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
-           },
-       
-       
-           
-           first : function(selector, returnDom){
-               return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
-           },
-       
-           
-           last : function(selector, returnDom){
-               return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
-           },
-           
-           matchNode : function(dir, start, selector, returnDom){
-               var n = this.dom[start];
-               while(n){
-                   if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
-                       return !returnDom ? GET(n) : n;
-                   }
-                   n = n[dir];
-               }
-               return null;
-           }   
-    }
-}());
-Ext.Element.addMethods({
+        }
+        return this;
+    },
     
-    select : function(selector, unique){
-        return Ext.Element.select(selector, unique, this.dom);
-    }
-});
-Ext.Element.addMethods(
-function() {
-       var GETDOM = Ext.getDom,
-               GET = Ext.get,
-               DH = Ext.DomHelper;
-       
-       return {
-           
-           appendChild: function(el){        
-               return GET(el).appendTo(this);        
-           },
-       
-           
-           appendTo: function(el){        
-               GETDOM(el).appendChild(this.dom);        
-               return this;
-           },
-       
-           
-           insertBefore: function(el){                   
-               (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
-               return this;
-           },
-       
-           
-           insertAfter: function(el){
-               (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
-               return this;
-           },
-       
-           
-           insertFirst: function(el, returnDom){
-            el = el || {};
-            if(el.nodeType || el.dom || typeof el == 'string'){ 
-                el = GETDOM(el);
-                this.dom.insertBefore(el, this.dom.firstChild);
-                return !returnDom ? GET(el) : el;
-            }else{ 
-                return this.createChild(el, this.dom.firstChild, returnDom);
-            }
-        },
-       
-           
-           replace: function(el){
-               el = GET(el);
-               this.insertBefore(el);
-               el.remove();
-               return this;
-           },
-       
-           
-           replaceWith: function(el){
-                   var me = this;
-                
-            if(el.nodeType || el.dom || typeof el == 'string'){
-                el = GETDOM(el);
-                me.dom.parentNode.insertBefore(el, me.dom);
-            }else{
-                el = DH.insertBefore(me.dom, el);
-            }
-               
-               delete Ext.elCache[me.id];
-               Ext.removeNode(me.dom);      
-               me.id = Ext.id(me.dom = el);
-               Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);     
-            return me;
-           },
-           
-               
-               createChild: function(config, insertBefore, returnDom){
-                   config = config || {tag:'div'};
-                   return insertBefore ? 
-                          DH.insertBefore(insertBefore, config, returnDom !== true) :  
-                          DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
-               },
-               
-               
-               wrap: function(config, returnDom){        
-                   var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
-                   newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
-                   return newEl;
-               },
-               
-               
-               insertHtml : function(where, html, returnEl){
-                   var el = DH.insertHtml(where, this.dom, html);
-                   return returnEl ? Ext.get(el) : el;
-               }
-       }
-}());
-Ext.apply(Ext.Element.prototype, function() {
-       var GETDOM = Ext.getDom,
-               GET = Ext.get,
-               DH = Ext.DomHelper;
-       
-       return {        
-               
-           insertSibling: function(el, where, returnDom){
-               var me = this,
-                       rt,
-                isAfter = (where || 'before').toLowerCase() == 'after',
-                insertEl;
-                       
-               if(Ext.isArray(el)){
-                insertEl = me;
-                   Ext.each(el, function(e) {
-                           rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
-                    if(isAfter){
-                        insertEl = rt;
-                    }
-                   });
-                   return rt;
-               }
-                       
-               el = el || {};
-               
-            if(el.nodeType || el.dom){
-                rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
-                if (!returnDom) {
-                    rt = GET(rt);
-                }
-            }else{
-                if (isAfter && !me.dom.nextSibling) {
-                    rt = DH.append(me.dom.parentNode, el, !returnDom);
-                } else {                    
-                    rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
+    each : function(fn, scope){
+        var me = this,
+            els = me.elements,
+            len = els.length,
+            i, e;
+
+        for(i = 0; i<len; i++) {
+            e = els[i];
+            if(e){
+                e = this.getElement(e);
+                if(fn.call(scope || e, e, me, i) === false){
+                    break;
                 }
             }
-               return rt;
-           }
-    };
-}());
-Ext.Element.addMethods(function(){
+        }
+        return me;
+    },
+
     
-    var propCache = {},
-        camelRe = /(-[a-z])/gi,
-        classReCache = {},
-        view = document.defaultView,
-        propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
-        opacityRe = /alpha\(opacity=(.*)\)/i,
-        trimRe = /^\s+|\s+$/g,
-        EL = Ext.Element,
-        PADDING = "padding",
-        MARGIN = "margin",
-        BORDER = "border",
-        LEFT = "-left",
-        RIGHT = "-right",
-        TOP = "-top",
-        BOTTOM = "-bottom",
-        WIDTH = "-width",
-        MATH = Math,
-        HIDDEN = 'hidden',
-        ISCLIPPED = 'isClipped',
-        OVERFLOW = 'overflow',
-        OVERFLOWX = 'overflow-x',
-        OVERFLOWY = 'overflow-y',
-        ORIGINALCLIP = 'originalClip',
+    fill : function(els){
+        var me = this;
+        me.elements = [];
+        me.add(els);
+        return me;
+    },
+
+    
+    filter : function(selector){
+        var els = [],
+            me = this,
+            fn = Ext.isFunction(selector) ? selector
+                : function(el){
+                    return el.is(selector);
+                };
+
+        me.each(function(el, self, i) {
+            if (fn(el, i) !== false) {
+                els[els.length] = me.transformElement(el);
+            }
+        });
         
-        borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
-        paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
-        margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
-        data = Ext.Element.data;
+        me.elements = els;
+        return me;
+    },
 
+    
+    indexOf : function(el){
+        return this.elements.indexOf(this.transformElement(el));
+    },
 
     
-    function camelFn(m, a) {
-        return a.charAt(1).toUpperCase();
+    replaceElement : function(el, replacement, domReplace){
+        var index = !isNaN(el) ? el : this.indexOf(el),
+            d;
+        if(index > -1){
+            replacement = Ext.getDom(replacement);
+            if(domReplace){
+                d = this.elements[index];
+                d.parentNode.insertBefore(replacement, d);
+                Ext.removeNode(d);
+            }
+            this.elements.splice(index, 1, replacement);
+        }
+        return this;
+    },
+
+    
+    clear : function(){
+        this.elements = [];
     }
+};
 
-    function chkCache(prop) {
-        return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
+Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
+
+
+Ext.CompositeElementLite.importElementMethods = function() {
+    var fnName,
+        ElProto = Ext.Element.prototype,
+        CelProto = Ext.CompositeElementLite.prototype;
+
+    for (fnName in ElProto) {
+        if (typeof ElProto[fnName] == 'function'){
+            (function(fnName) {
+                CelProto[fnName] = CelProto[fnName] || function() {
+                    return this.invoke(fnName, arguments);
+                };
+            }).call(CelProto, fnName);
+
+        }
     }
+};
 
-    return {
-        
-        adjustWidth : function(width) {
-            var me = this;
-            var isNum = Ext.isNumber(width);
-            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
-               width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
-            }
-            return (isNum && width < 0) ? 0 : width;
-        },
+Ext.CompositeElementLite.importElementMethods();
 
-        
-        adjustHeight : function(height) {
-            var me = this;
-            var isNum = Ext.isNumber(height);
-            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
-               height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
-            }
-            return (isNum && height < 0) ? 0 : height;
-        },
+if(Ext.DomQuery){
+    Ext.Element.selectorFunction = Ext.DomQuery.select;
+}
+
+
+Ext.Element.select = function(selector, root){
+    var els;
+    if(typeof selector == "string"){
+        els = Ext.Element.selectorFunction(selector, root);
+    }else if(selector.length !== undefined){
+        els = selector;
+    }else{
+        throw "Invalid selector";
+    }
+    return new Ext.CompositeElementLite(els);
+};
+
+Ext.select = Ext.Element.select;
+(function(){
+    var BEFOREREQUEST = "beforerequest",
+        REQUESTCOMPLETE = "requestcomplete",
+        REQUESTEXCEPTION = "requestexception",
+        UNDEFINED = undefined,
+        LOAD = 'load',
+        POST = 'POST',
+        GET = 'GET',
+        WINDOW = window;
 
+    
+    Ext.data.Connection = function(config){
+        Ext.apply(this, config);
+        this.addEvents(
+            
+            BEFOREREQUEST,
+            
+            REQUESTCOMPLETE,
+            
+            REQUESTEXCEPTION
+        );
+        Ext.data.Connection.superclass.constructor.call(this);
+    };
 
+    Ext.extend(Ext.data.Connection, Ext.util.Observable, {
         
-        addClass : function(className){
-            var me = this, i, len, v;
-            className = Ext.isArray(className) ? className : [className];
-            for (i=0, len = className.length; i < len; i++) {
-                v = className[i];
-                if (v) {
-                    me.dom.className += (!me.hasClass(v) && v ? " " + v : "");
-                };
-            };
-            return me;
-        },
+        
+        
+        
+        
+        timeout : 30000,
+        
+        autoAbort:false,
 
         
-        radioClass : function(className){
-            var cn = this.dom.parentNode.childNodes, v;
-            className = Ext.isArray(className) ? className : [className];
-            for (var i=0, len = cn.length; i < len; i++) {
-                v = cn[i];
-                if(v && v.nodeType == 1) {
-                    Ext.fly(v, '_internal').removeClass(className);
-                }
-            };
-            return this.addClass(className);
-        },
+        disableCaching: true,
 
         
-        removeClass : function(className){
-            var me = this, v;
-            className = Ext.isArray(className) ? className : [className];
-            if (me.dom && me.dom.className) {
-                for (var i=0, len=className.length; i < len; i++) {
-                    v = className[i];
-                    if(v) {
-                        me.dom.className = me.dom.className.replace(
-                            classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"), " "
-                        );
+        disableCachingParam: '_dc',
+
+        
+        request : function(o){
+            var me = this;
+            if(me.fireEvent(BEFOREREQUEST, me, o)){
+                if (o.el) {
+                    if(!Ext.isEmpty(o.indicatorText)){
+                        me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
                     }
-                };
+                    if(me.indicatorText) {
+                        Ext.getDom(o.el).innerHTML = me.indicatorText;
+                    }
+                    o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
+                        Ext.getDom(o.el).innerHTML = response.responseText;
+                    });
+                }
+
+                var p = o.params,
+                    url = o.url || me.url,
+                    method,
+                    cb = {success: me.handleResponse,
+                          failure: me.handleFailure,
+                          scope: me,
+                          argument: {options: o},
+                          timeout : Ext.num(o.timeout, me.timeout)
+                    },
+                    form,
+                    serForm;
+
+
+                if (Ext.isFunction(p)) {
+                    p = p.call(o.scope||WINDOW, o);
+                }
+
+                p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);
+
+                if (Ext.isFunction(url)) {
+                    url = url.call(o.scope || WINDOW, o);
+                }
+
+                if((form = Ext.getDom(o.form))){
+                    url = url || form.action;
+                     if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) {
+                         return me.doFormUpload.call(me, o, p, url);
+                     }
+                    serForm = Ext.lib.Ajax.serializeForm(form);
+                    p = p ? (p + '&' + serForm) : serForm;
+                }
+
+                method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
+
+                if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
+                    var dcp = o.disableCachingParam || me.disableCachingParam;
+                    url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
+                }
+
+                o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
+
+                if(o.autoAbort === true || me.autoAbort) {
+                    me.abort();
+                }
+
+                if((method == GET || o.xmlData || o.jsonData) && p){
+                    url = Ext.urlAppend(url, p);
+                    p = '';
+                }
+                return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
+            }else{
+                return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
             }
-            return me;
         },
 
         
-        toggleClass : function(className){
-            return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
+        isLoading : function(transId){
+            return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
         },
 
         
-        hasClass : function(className){
-            return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
+        abort : function(transId){
+            if(transId || this.isLoading()){
+                Ext.lib.Ajax.abort(transId || this.transId);
+            }
         },
 
         
-        replaceClass : function(oldClassName, newClassName){
-            return this.removeClass(oldClassName).addClass(newClassName);
+        handleResponse : function(response){
+            this.transId = false;
+            var options = response.argument.options;
+            response.argument = options ? options.argument : null;
+            this.fireEvent(REQUESTCOMPLETE, this, response, options);
+            if(options.success){
+                options.success.call(options.scope, response, options);
+            }
+            if(options.callback){
+                options.callback.call(options.scope, options, true, response);
+            }
         },
 
-        isStyle : function(style, val) {
-            return this.getStyle(style) == val;
+        
+        handleFailure : function(response, e){
+            this.transId = false;
+            var options = response.argument.options;
+            response.argument = options ? options.argument : null;
+            this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
+            if(options.failure){
+                options.failure.call(options.scope, response, options);
+            }
+            if(options.callback){
+                options.callback.call(options.scope, options, false, response);
+            }
         },
 
         
-        getStyle : function(){
-            return view && view.getComputedStyle ?
-                function(prop){
-                    var el = this.dom,
-                        v,
-                        cs,
-                        out,
-                        display,
-                        wk = Ext.isWebKit,
-                        display;
-                        
-                    if(el == document){
-                        return null;
-                    }
-                    prop = chkCache(prop);
-                    
-                    if(wk && /marginRight/.test(prop)){
-                        display = this.getStyle('display');
-                        el.style.display = 'inline-block';
-                    }
-                    out = (v = el.style[prop]) ? v :
-                           (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
-
-                    
-                    if(wk){
-                        if(out == 'rgba(0, 0, 0, 0)'){
-                            out = 'transparent';
-                        }else if(display){
-                            el.style.display = display;
-                        }
-                    }
-                    return out;
-                } :
-                function(prop){
-                    var el = this.dom,
-                        m,
-                        cs;
-
-                    if(el == document) return null;
-                    if (prop == 'opacity') {
-                        if (el.style.filter.match) {
-                            if(m = el.style.filter.match(opacityRe)){
-                                var fv = parseFloat(m[1]);
-                                if(!isNaN(fv)){
-                                    return fv ? fv / 100 : 0;
-                                }
-                            }
-                        }
-                        return 1;
-                    }
-                    prop = chkCache(prop);
-                    return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
+        doFormUpload : function(o, ps, url){
+            var id = Ext.id(),
+                doc = document,
+                frame = doc.createElement('iframe'),
+                form = Ext.getDom(o.form),
+                hiddens = [],
+                hd,
+                encoding = 'multipart/form-data',
+                buf = {
+                    target: form.target,
+                    method: form.method,
+                    encoding: form.encoding,
+                    enctype: form.enctype,
+                    action: form.action
                 };
-        }(),
 
-        
-        getColor : function(attr, defaultValue, prefix){
-            var v = this.getStyle(attr),
-                color = Ext.isDefined(prefix) ? prefix : '#',
-                h;
+            
+            Ext.fly(frame).set({
+                id: id,
+                name: id,
+                cls: 'x-hidden',
+                src: Ext.SSL_SECURE_URL
+            }); 
 
-            if(!v || /transparent|inherit/.test(v)){
-                return defaultValue;
+            doc.body.appendChild(frame);
+
+            
+            if(Ext.isIE){
+               document.frames[id].name = id;
             }
-            if(/^r/.test(v)){
-                Ext.each(v.slice(4, v.length -1).split(','), function(s){
-                    h = parseInt(s, 10);
-                    color += (h < 16 ? '0' : '') + h.toString(16);
+
+
+            Ext.fly(form).set({
+                target: id,
+                method: POST,
+                enctype: encoding,
+                encoding: encoding,
+                action: url || buf.action
+            });
+
+            
+            Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
+                hd = doc.createElement('input');
+                Ext.fly(hd).set({
+                    type: 'hidden',
+                    value: v,
+                    name: k
                 });
-            }else{
-                v = v.replace('#', '');
-                color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
-            }
-            return(color.length > 5 ? color.toLowerCase() : defaultValue);
-        },
+                form.appendChild(hd);
+                hiddens.push(hd);
+            });
 
-        
-        setStyle : function(prop, value){
-            var tmp,
-                style,
-                camel;
-            if (!Ext.isObject(prop)) {
-                tmp = {};
-                tmp[prop] = value;
-                prop = tmp;
-            }
-            for (style in prop) {
-                value = prop[style];
-                style == 'opacity' ?
-                    this.setOpacity(value) :
-                    this.dom.style[chkCache(style)] = value;
-            }
-            return this;
-        },
+            function cb(){
+                var me = this,
+                    
+                    r = {responseText : '',
+                         responseXML : null,
+                         argument : o.argument},
+                    doc,
+                    firstChild;
 
-        
-         setOpacity : function(opacity, animate){
-            var me = this,
-                s = me.dom.style;
+                try{
+                    doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
+                    if(doc){
+                        if(doc.body){
+                            if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ 
+                                r.responseText = firstChild.value;
+                            }else{
+                                r.responseText = doc.body.innerHTML;
+                            }
+                        }
+                        
+                        r.responseXML = doc.XMLDocument || doc;
+                    }
+                }
+                catch(e) {}
 
-            if(!animate || !me.anim){
-                if(Ext.isIE){
-                    var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
-                    val = s.filter.replace(opacityRe, '').replace(trimRe, '');
+                Ext.EventManager.removeListener(frame, LOAD, cb, me);
 
-                    s.zoom = 1;
-                    s.filter = val + (val.length > 0 ? ' ' : '') + opac;
-                }else{
-                    s.opacity = opacity;
+                me.fireEvent(REQUESTCOMPLETE, me, r, o);
+
+                function runCallback(fn, scope, args){
+                    if(Ext.isFunction(fn)){
+                        fn.apply(scope, args);
+                    }
                 }
-            }else{
-                me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
-            }
-            return me;
-        },
 
-        
-        clearOpacity : function(){
-            var style = this.dom.style;
-            if(Ext.isIE){
-                if(!Ext.isEmpty(style.filter)){
-                    style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
+                runCallback(o.success, o.scope, [r, o]);
+                runCallback(o.callback, o.scope, [o, true, r]);
+
+                if(!me.debugUploads){
+                    setTimeout(function(){Ext.removeNode(frame);}, 100);
                 }
-            }else{
-                style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
             }
-            return this;
-        },
-
-        
-        getHeight : function(contentHeight){
-            var me = this,
-                dom = me.dom,
-                hidden = Ext.isIE && me.isStyle('display', 'none'),
-                h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
 
-            h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
-            return h < 0 ? 0 : h;
-        },
+            Ext.EventManager.on(frame, LOAD, cb, this);
+            form.submit();
 
-        
-        getWidth : function(contentWidth){
-            var me = this,
-                dom = me.dom,
-                hidden = Ext.isIE && me.isStyle('display', 'none'),
-                w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
-            w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
-            return w < 0 ? 0 : w;
-        },
+            Ext.fly(form).set(buf);
+            Ext.each(hiddens, function(h) {
+                Ext.removeNode(h);
+            });
+        }
+    });
+})();
 
-        
-        setWidth : function(width, animate){
-            var me = this;
-            width = me.adjustWidth(width);
-            !animate || !me.anim ?
-                me.dom.style.width = me.addUnits(width) :
-                me.anim({width : {to : width}}, me.preanim(arguments, 1));
-            return me;
-        },
 
-        
-         setHeight : function(height, animate){
-            var me = this;
-            height = me.adjustHeight(height);
-            !animate || !me.anim ?
-                me.dom.style.height = me.addUnits(height) :
-                me.anim({height : {to : height}}, me.preanim(arguments, 1));
-            return me;
-        },
+Ext.Ajax = new Ext.data.Connection({
+    
+    
+    
+    
+    
+    
 
-        
-        getBorderWidth : function(side){
-            return this.addStyles(side, borders);
-        },
+    
 
-        
-        getPadding : function(side){
-            return this.addStyles(side, paddings);
-        },
+    
+    
+    
+    
+    
+    
 
-        
-        clip : function(){
-            var me = this,
-                dom = me.dom;
+    
+    autoAbort : false,
 
-            if(!data(dom, ISCLIPPED)){
-                data(dom, ISCLIPPED, true);
-                data(dom, ORIGINALCLIP, {
-                    o: me.getStyle(OVERFLOW),
-                    x: me.getStyle(OVERFLOWX),
-                    y: me.getStyle(OVERFLOWY)
-                });
-                me.setStyle(OVERFLOW, HIDDEN);
-                me.setStyle(OVERFLOWX, HIDDEN);
-                me.setStyle(OVERFLOWY, HIDDEN);
-            }
-            return me;
-        },
+    
+    serializeForm : function(form){
+        return Ext.lib.Ajax.serializeForm(form);
+    }
+});
 
-        
-        unclip : function(){
-            var me = this,
-                dom = me.dom;
+Ext.util.JSON = new (function(){
+    var useHasOwn = !!{}.hasOwnProperty,
+        isNative = function() {
+            var useNative = null;
 
-            if(data(dom, ISCLIPPED)){
-                data(dom, ISCLIPPED, false);
-                var o = data(dom, ORIGINALCLIP);
-                if(o.o){
-                    me.setStyle(OVERFLOW, o.o);
-                }
-                if(o.x){
-                    me.setStyle(OVERFLOWX, o.x);
+            return function() {
+                if (useNative === null) {
+                    useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
                 }
-                if(o.y){
-                    me.setStyle(OVERFLOWY, o.y);
+        
+                return useNative;
+            };
+        }(),
+        pad = function(n) {
+            return n < 10 ? "0" + n : n;
+        },
+        doDecode = function(json){
+            return eval("(" + json + ")");    
+        },
+        doEncode = function(o){
+            if(!Ext.isDefined(o) || o === null){
+                return "null";
+            }else if(Ext.isArray(o)){
+                return encodeArray(o);
+            }else if(Ext.isDate(o)){
+                return Ext.util.JSON.encodeDate(o);
+            }else if(Ext.isString(o)){
+                return encodeString(o);
+            }else if(typeof o == "number"){
+                
+                return isFinite(o) ? String(o) : "null";
+            }else if(Ext.isBoolean(o)){
+                return String(o);
+            }else {
+                var a = ["{"], b, i, v;
+                for (i in o) {
+                    
+                    if(!o.getElementsByTagName){
+                        if(!useHasOwn || o.hasOwnProperty(i)) {
+                            v = o[i];
+                            switch (typeof v) {
+                            case "undefined":
+                            case "function":
+                            case "unknown":
+                                break;
+                            default:
+                                if(b){
+                                    a.push(',');
+                                }
+                                a.push(doEncode(i), ":",
+                                        v === null ? "null" : doEncode(v));
+                                b = true;
+                            }
+                        }
+                    }
                 }
+                a.push("}");
+                return a.join("");
+            }    
+        },
+        m = {
+            "\b": '\\b',
+            "\t": '\\t',
+            "\n": '\\n',
+            "\f": '\\f',
+            "\r": '\\r',
+            '"' : '\\"',
+            "\\": '\\\\'
+        },
+        encodeString = function(s){
+            if (/["\\\x00-\x1f]/.test(s)) {
+                return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
+                    var c = m[b];
+                    if(c){
+                        return c;
+                    }
+                    c = b.charCodeAt();
+                    return "\\u00" +
+                        Math.floor(c / 16).toString(16) +
+                        (c % 16).toString(16);
+                }) + '"';
             }
-            return me;
+            return '"' + s + '"';
         },
-
-        
-        addStyles : function(sides, styles){
-            var val = 0,
-                m = sides.match(/\w/g),
-                s;
-            for (var i=0, len=m.length; i<len; i++) {
-                s = m[i] && parseInt(this.getStyle(styles[m[i]]), 10);
-                if (s) {
-                    val += MATH.abs(s);
+        encodeArray = function(o){
+            var a = ["["], b, i, l = o.length, v;
+                for (i = 0; i < l; i += 1) {
+                    v = o[i];
+                    switch (typeof v) {
+                        case "undefined":
+                        case "function":
+                        case "unknown":
+                            break;
+                        default:
+                            if (b) {
+                                a.push(',');
+                            }
+                            a.push(v === null ? "null" : Ext.util.JSON.encode(v));
+                            b = true;
+                    }
                 }
+                a.push("]");
+                return a.join("");
+        };
+
+    
+    this.encodeDate = function(o){
+        return '"' + o.getFullYear() + "-" +
+                pad(o.getMonth() + 1) + "-" +
+                pad(o.getDate()) + "T" +
+                pad(o.getHours()) + ":" +
+                pad(o.getMinutes()) + ":" +
+                pad(o.getSeconds()) + '"';
+    };
+
+    
+    this.encode = function() {
+        var ec;
+        return function(o) {
+            if (!ec) {
+                
+                ec = isNative() ? JSON.stringify : doEncode;
             }
-            return val;
-        },
+            return ec(o);
+        };
+    }();
 
-        margins : margins
-    }
-}()
-);
 
+    
+    this.decode = function() {
+        var dc;
+        return function(json) {
+            if (!dc) {
+                
+                dc = isNative() ? JSON.parse : doDecode;
+            }
+            return dc(json);
+        };
+    }();
 
+})();
 
-Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
+Ext.encode = Ext.util.JSON.encode;
 
-Ext.Element.addMethods(function(){
-    var INTERNAL = "_internal",
-        pxMatch = /(\d+)px/;
-    return {
-        
-        applyStyles : function(style){
-            Ext.DomHelper.applyStyles(this.dom, style);
-            return this;
-        },
+Ext.decode = Ext.util.JSON.decode;
 
+Ext.EventManager = function(){
+    var docReadyEvent,
+        docReadyProcId,
+        docReadyState = false,
+        DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
+        E = Ext.lib.Event,
+        D = Ext.lib.Dom,
+        DOC = document,
+        WINDOW = window,
+        DOMCONTENTLOADED = "DOMContentLoaded",
+        COMPLETE = 'complete',
+        propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
         
-        getStyles : function(){
-            var ret = {};
-            Ext.each(arguments, function(v) {
-               ret[v] = this.getStyle(v);
-            },
-            this);
-            return ret;
-        },
+        specialElCache = [];
 
-        
-        getStyleSize : function(){
-            var me = this,
-                w,
-                h,
-                d = this.dom,
-                s = d.style;
-            if(s.width && s.width != 'auto'){
-                w = parseInt(s.width, 10);
-                if(me.isBorderBox()){
-                   w -= me.getFrameWidth('lr');
+     function getId(el){
+        var id = false,
+            i = 0,
+            len = specialElCache.length,
+            skip = false,
+            o;
+            
+        if (el) {
+            if (el.getElementById || el.navigator) {
+                
+                for(; i < len; ++i){
+                    o = specialElCache[i];
+                    if(o.el === el){
+                        id = o.id;
+                        break;
+                    }
+                }
+                if(!id){
+                    
+                    id = Ext.id(el);
+                    specialElCache.push({
+                        id: id,
+                        el: el
+                    });
+                    skip = true;
                 }
+            }else{
+                id = Ext.id(el);
             }
-            if(s.height && s.height != 'auto'){
-                h = parseInt(s.height, 10);
-                if(me.isBorderBox()){
-                   h -= me.getFrameWidth('tb');
+            if(!Ext.elCache[id]){
+                Ext.Element.addToCache(new Ext.Element(el), id);
+                if(skip){
+                    Ext.elCache[id].skipGC = true;
                 }
             }
-            return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
-        },
+        }
+        return id;
+     }
+
+    
+    function addListener(el, ename, fn, task, wrap, scope){
+        el = Ext.getDom(el);
+        var id = getId(el),
+            es = Ext.elCache[id].events,
+            wfn;
+
+        wfn = E.on(el, ename, wrap);
+        es[ename] = es[ename] || [];
 
         
-        setOverflow : function(v){
-            var dom = this.dom;
-            if(v=='auto' && Ext.isMac && Ext.isGecko2){ 
-                dom.style.overflow = 'hidden';
-                (function(){dom.style.overflow = 'auto';}).defer(1);
-            }else{
-                dom.style.overflow = v;
-            }
-        },
+        es[ename].push([fn, wrap, scope, wfn, task]);
 
-       
-        boxWrap : function(cls){
-            cls = cls || 'x-box';
-            var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));        
-            Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
-            return el;
-        },
+        
+        
 
         
-        setSize : function(width, height, animate){
-            var me = this;
-            if(Ext.isObject(width)){ 
-                height = width.height;
-                width = width.width;
-            }
-            width = me.adjustWidth(width);
-            height = me.adjustHeight(height);
-            if(!animate || !me.anim){
-                me.dom.style.width = me.addUnits(width);
-                me.dom.style.height = me.addUnits(height);
-            }else{
-                me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
-            }
-            return me;
-        },
+        if(el.addEventListener && ename == "mousewheel"){
+            var args = ["DOMMouseScroll", wrap, false];
+            el.addEventListener.apply(el, args);
+            Ext.EventManager.addListener(WINDOW, 'unload', function(){
+                el.removeEventListener.apply(el, args);
+            });
+        }
 
         
-        getComputedHeight : function(){
-            var me = this,
-                h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
-            if(!h){
-                h = parseInt(me.getStyle('height'), 10) || 0;
-                if(!me.isBorderBox()){
-                    h += me.getFrameWidth('tb');
-                }
-            }
-            return h;
-        },
+        if(el == DOC && ename == "mousedown"){
+            Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
+        }
+    }
 
+    function doScrollChk(){
         
-        getComputedWidth : function(){
-            var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
-            if(!w){
-                w = parseInt(this.getStyle('width'), 10) || 0;
-                if(!this.isBorderBox()){
-                    w += this.getFrameWidth('lr');
-                }
-            }
-            return w;
-        },
+        if(window != top){
+            return false;
+        }
 
-        
-        getFrameWidth : function(sides, onlyContentBox){
-            return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
-        },
+        try{
+            DOC.documentElement.doScroll('left');
+        }catch(e){
+             return false;
+        }
 
-        
-        addClassOnOver : function(className){
-            this.hover(
-                function(){
-                    Ext.fly(this, INTERNAL).addClass(className);
-                },
-                function(){
-                    Ext.fly(this, INTERNAL).removeClass(className);
-                }
-            );
-            return this;
-        },
+        fireDocReady();
+        return true;
+    }
+    
+    function checkReadyState(e){
 
-        
-        addClassOnFocus : function(className){
-            this.on("focus", function(){
-                Ext.fly(this, INTERNAL).addClass(className);
-            }, this.dom);
-            this.on("blur", function(){
-                Ext.fly(this, INTERNAL).removeClass(className);
-            }, this.dom);
-            return this;
-        },
+        if(Ext.isIE && doScrollChk()){
+            return true;
+        }
+        if(DOC.readyState == COMPLETE){
+            fireDocReady();
+            return true;
+        }
+        docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
+        return false;
+    }
 
-        
-        addClassOnClick : function(className){
-            var dom = this.dom;
-            this.on("mousedown", function(){
-                Ext.fly(dom, INTERNAL).addClass(className);
-                var d = Ext.getDoc(),
-                    fn = function(){
-                        Ext.fly(dom, INTERNAL).removeClass(className);
-                        d.removeListener("mouseup", fn);
-                    };
-                d.on("mouseup", fn);
-            });
-            return this;
-        },
+    var styles;
+    function checkStyleSheets(e){
+        styles || (styles = Ext.query('style, link[rel=stylesheet]'));
+        if(styles.length == DOC.styleSheets.length){
+            fireDocReady();
+            return true;
+        }
+        docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
+        return false;
+    }
 
+    function OperaDOMContentLoaded(e){
+        DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
+        checkStyleSheets();
+    }
+
+    function fireDocReady(e){
+        if(!docReadyState){
+            docReadyState = true; 
+
+            if(docReadyProcId){
+                clearTimeout(docReadyProcId);
+            }
+            if(DETECT_NATIVE) {
+                DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
+            }
+            if(Ext.isIE && checkReadyState.bindIE){  
+                DOC.detachEvent('onreadystatechange', checkReadyState);
+            }
+            E.un(WINDOW, "load", arguments.callee);
+        }
+        if(docReadyEvent && !Ext.isReady){
+            Ext.isReady = true;
+            docReadyEvent.fire();
+            docReadyEvent.listeners = [];
+        }
+
+    }
+
+    function initDocReady(){
+        docReadyEvent || (docReadyEvent = new Ext.util.Event());
+        if (DETECT_NATIVE) {
+            DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
+        }
         
-        getViewSize : function(contentBox){
-            var doc = document,
-                me = this,
-                d = me.dom,
-                extdom = Ext.lib.Dom,
-                isDoc = (d == doc || d == doc.body),
-                isBB, w, h, tbBorder = 0, lrBorder = 0,
-                tbPadding = 0, lrPadding = 0;
-            if (isDoc) {
-                return { width: extdom.getViewWidth(), height: extdom.getViewHeight() };
+        if (Ext.isIE){
+            
+            
+            if(!checkReadyState()){
+                checkReadyState.bindIE = true;
+                DOC.attachEvent('onreadystatechange', checkReadyState);
             }
-            isBB = me.isBorderBox();
-            tbBorder = me.getBorderWidth('tb');
-            lrBorder = me.getBorderWidth('lr');
-            tbPadding = me.getPadding('tb');
-            lrPadding = me.getPadding('lr');
 
+        }else if(Ext.isOpera ){
             
+
             
-            if (w = me.getStyle('width').match(pxMatch)){
-                if ((w = parseInt(w[1], 10)) && isBB){
-                    
-                    w -= (lrBorder + lrPadding);
-                }
-                if (!contentBox){
-                    w += lrPadding;
-                }
-            } else {
-                if (!(w = d.clientWidth) && (w = d.offsetWidth)){
-                    w -= lrBorder;
-                }
-                if (w && contentBox){
-                    w -= lrPadding;
-                }
+            (DOC.readyState == COMPLETE && checkStyleSheets()) ||
+                DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);
+
+        }else if (Ext.isWebKit){
+            
+            checkReadyState();
+        }
+        
+        E.on(WINDOW, "load", fireDocReady);
+    }
+
+    function createTargeted(h, o){
+        return function(){
+            var args = Ext.toArray(arguments);
+            if(o.target == Ext.EventObject.setEvent(args[0]).target){
+                h.apply(this, args);
             }
+        };
+    }
 
+    function createBuffered(h, o, task){
+        return function(e){
             
+            task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
+        };
+    }
+
+    function createSingle(h, el, ename, fn, scope){
+        return function(e){
+            Ext.EventManager.removeListener(el, ename, fn, scope);
+            h(e);
+        };
+    }
+
+    function createDelayed(h, o, fn){
+        return function(e){
+            var task = new Ext.util.DelayedTask(h);
+            if(!fn.tasks) {
+                fn.tasks = [];
+            }
+            fn.tasks.push(task);
+            task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
+        };
+    }
+
+    function listen(element, ename, opt, fn, scope){
+        var o = (!opt || typeof opt == "boolean") ? {} : opt,
+            el = Ext.getDom(element), task;
+
+        fn = fn || o.fn;
+        scope = scope || o.scope;
+
+        if(!el){
+            throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
+        }
+        function h(e){
             
-            if (h = me.getStyle('height').match(pxMatch)){
-                if ((h = parseInt(h[1], 10)) && isBB){
-                    
-                    h -= (tbBorder + tbPadding);
-                }
-                if (!contentBox){
-                    h += tbPadding;
+            if(!Ext){
+                return;
+            }
+            e = Ext.EventObject.setEvent(e);
+            var t;
+            if (o.delegate) {
+                if(!(t = e.getTarget(o.delegate, el))){
+                    return;
                 }
             } else {
-                if (!(h = d.clientHeight) && (h = d.offsetHeight)){
-                    h -= tbBorder;
-                }
-                if (h && contentBox){
-                    h -= tbPadding;
-                }
+                t = e.target;
+            }
+            if (o.stopEvent) {
+                e.stopEvent();
+            }
+            if (o.preventDefault) {
+               e.preventDefault();
+            }
+            if (o.stopPropagation) {
+                e.stopPropagation();
+            }
+            if (o.normalized === false) {
+                e = e.browserEvent;
             }
 
-            return {
-                width : w,
-                height : h
-            };
-        },
+            fn.call(scope || el, e, t, o);
+        }
+        if(o.target){
+            h = createTargeted(h, o);
+        }
+        if(o.delay){
+            h = createDelayed(h, o, fn);
+        }
+        if(o.single){
+            h = createSingle(h, el, ename, fn, scope);
+        }
+        if(o.buffer){
+            task = new Ext.util.DelayedTask(h);
+            h = createBuffered(h, o, task);
+        }
 
-        
-        getSize : function(contentSize){
-            return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
-        },
+        addListener(el, ename, fn, task, h, scope);
+        return h;
+    }
 
+    var pub = {
         
-        repaint : function(){
-            var dom = this.dom;
-            this.addClass("x-repaint");
-            setTimeout(function(){
-                Ext.fly(dom).removeClass("x-repaint");
-            }, 1);
-            return this;
+        addListener : function(element, eventName, fn, scope, options){
+            if(typeof eventName == 'object'){
+                var o = eventName, e, val;
+                for(e in o){
+                    val = o[e];
+                    if(!propRe.test(e)){
+                        if(Ext.isFunction(val)){
+                            
+                            listen(element, e, o, val, o.scope);
+                        }else{
+                            
+                            listen(element, e, val);
+                        }
+                    }
+                }
+            } else {
+                listen(element, eventName, options, fn, scope);
+            }
         },
 
         
-        unselectable : function(){
-            this.dom.unselectable = "on";
-            return this.swallowEvent("selectstart", true).
-                        applyStyles("-moz-user-select:none;-khtml-user-select:none;").
-                        addClass("x-unselectable");
+        removeListener : function(el, eventName, fn, scope){
+            el = Ext.getDom(el);
+            var id = getId(el),
+                f = el && (Ext.elCache[id].events)[eventName] || [],
+                wrap, i, l, k, len, fnc;
+
+            for (i = 0, len = f.length; i < len; i++) {
+
+                
+                if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
+                    if(fnc[4]) {
+                        fnc[4].cancel();
+                    }
+                    k = fn.tasks && fn.tasks.length;
+                    if(k) {
+                        while(k--) {
+                            fn.tasks[k].cancel();
+                        }
+                        delete fn.tasks;
+                    }
+                    wrap = fnc[1];
+                    E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);
+
+                    
+                    if(wrap && el.addEventListener && eventName == "mousewheel"){
+                        el.removeEventListener("DOMMouseScroll", wrap, false);
+                    }
+
+                    
+                    if(wrap && el == DOC && eventName == "mousedown"){
+                        Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
+                    }
+
+                    f.splice(i, 1);
+                    if (f.length === 0) {
+                        delete Ext.elCache[id].events[eventName];
+                    }
+                    for (k in Ext.elCache[id].events) {
+                        return false;
+                    }
+                    Ext.elCache[id].events = {};
+                    return false;
+                }
+            }
         },
 
         
-        getMargins : function(side){
-            var me = this,
-                key,
-                hash = {t:"top", l:"left", r:"right", b: "bottom"},
-                o = {};
+        removeAll : function(el){
+            el = Ext.getDom(el);
+            var id = getId(el),
+                ec = Ext.elCache[id] || {},
+                es = ec.events || {},
+                f, i, len, ename, fn, k, wrap;
 
-            if (!side) {
-                for (key in me.margins){
-                    o[hash[key]] = parseInt(me.getStyle(me.margins[key]), 10) || 0;
+            for(ename in es){
+                if(es.hasOwnProperty(ename)){
+                    f = es[ename];
+                    
+                    for (i = 0, len = f.length; i < len; i++) {
+                        fn = f[i];
+                        if(fn[4]) {
+                            fn[4].cancel();
+                        }
+                        if(fn[0].tasks && (k = fn[0].tasks.length)) {
+                            while(k--) {
+                                fn[0].tasks[k].cancel();
+                            }
+                            delete fn.tasks;
+                        }
+                        wrap =  fn[1];
+                        E.un(el, ename, E.extAdapter ? fn[3] : wrap);
+
+                        
+                        if(el.addEventListener && wrap && ename == "mousewheel"){
+                            el.removeEventListener("DOMMouseScroll", wrap, false);
+                        }
+
+                        
+                        if(wrap && el == DOC &&  ename == "mousedown"){
+                            Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
+                        }
+                    }
                 }
-                return o;
-            } else {
-                return me.addStyles.call(me, side, me.margins);
             }
-        }
-    };
-}());
+            if (Ext.elCache[id]) {
+                Ext.elCache[id].events = {};
+            }
+        },
 
-(function(){
-var D = Ext.lib.Dom,
-        LEFT = "left",
-        RIGHT = "right",
-        TOP = "top",
-        BOTTOM = "bottom",
-        POSITION = "position",
-        STATIC = "static",
-        RELATIVE = "relative",
-        AUTO = "auto",
-        ZINDEX = "z-index";
+        getListeners : function(el, eventName) {
+            el = Ext.getDom(el);
+            var id = getId(el),
+                ec = Ext.elCache[id] || {},
+                es = ec.events || {},
+                results = [];
+            if (es && es[eventName]) {
+                return es[eventName];
+            } else {
+                return null;
+            }
+        },
 
-Ext.Element.addMethods({
-       
-    getX : function(){
-        return D.getX(this.dom);
-    },
+        purgeElement : function(el, recurse, eventName) {
+            el = Ext.getDom(el);
+            var id = getId(el),
+                ec = Ext.elCache[id] || {},
+                es = ec.events || {},
+                i, f, len;
+            if (eventName) {
+                if (es && es.hasOwnProperty(eventName)) {
+                    f = es[eventName];
+                    for (i = 0, len = f.length; i < len; i++) {
+                        Ext.EventManager.removeListener(el, eventName, f[i][0]);
+                    }
+                }
+            } else {
+                Ext.EventManager.removeAll(el);
+            }
+            if (recurse && el && el.childNodes) {
+                for (i = 0, len = el.childNodes.length; i < len; i++) {
+                    Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
+                }
+            }
+        },
 
-    
-    getY : function(){
-        return D.getY(this.dom);
-    },
+        _unload : function() {
+            var el;
+            for (el in Ext.elCache) {
+                Ext.EventManager.removeAll(el);
+            }
+            delete Ext.elCache;
+            delete Ext.Element._flyweights;
 
-    
-    getXY : function(){
-        return D.getXY(this.dom);
-    },
+            
+            var c,
+                conn,
+                tid,
+                ajax = Ext.lib.Ajax;
+            (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
+            for (tid in conn) {
+                c = conn[tid];
+                if (c) {
+                    ajax.abort({conn: c, tId: tid});
+                }
+            }
+        },
+        
+        onDocumentReady : function(fn, scope, options){
+            if (Ext.isReady) { 
+                docReadyEvent || (docReadyEvent = new Ext.util.Event());
+                docReadyEvent.addListener(fn, scope, options);
+                docReadyEvent.fire();
+                docReadyEvent.listeners = [];
+            } else {
+                if (!docReadyEvent) {
+                    initDocReady();
+                }
+                options = options || {};
+                options.delay = options.delay || 1;
+                docReadyEvent.addListener(fn, scope, options);
+            }
+        },
 
+        
+        fireDocReady  : fireDocReady
+    };
+     
+    pub.on = pub.addListener;
     
-    getOffsetsTo : function(el){
-        var o = this.getXY(),
-               e = Ext.fly(el, '_internal').getXY();
-        return [o[0]-e[0],o[1]-e[1]];
-    },
+    pub.un = pub.removeListener;
 
-    
-    setX : function(x, animate){           
-           return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
-    },
+    pub.stoppedMouseDownEvent = new Ext.util.Event();
+    return pub;
+}();
 
-    
-    setY : function(y, animate){           
-           return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
-    },
+Ext.onReady = Ext.EventManager.onDocumentReady;
 
-    
-    setLeft : function(left){
-        this.setStyle(LEFT, this.addUnits(left));
-        return this;
-    },
 
-    
-    setTop : function(top){
-        this.setStyle(TOP, this.addUnits(top));
-        return this;
-    },
 
-    
-    setRight : function(right){
-        this.setStyle(RIGHT, this.addUnits(right));
-        return this;
-    },
+(function(){
+    var initExtCss = function() {
+        
+        var bd = document.body || document.getElementsByTagName('body')[0];
+        if (!bd) {
+            return false;
+        }
+        
+        var cls = [' ',
+                Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
+                : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
+                : Ext.isOpera ? "ext-opera"
+                : Ext.isWebKit ? "ext-webkit" : ""];
 
-    
-    setBottom : function(bottom){
-        this.setStyle(BOTTOM, this.addUnits(bottom));
-        return this;
-    },
+        if (Ext.isSafari) {
+            cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
+        } else if(Ext.isChrome) {
+            cls.push("ext-chrome");
+        }
 
-    
-    setXY : function(pos, animate){
-           var me = this;
-        if(!animate || !me.anim){
-            D.setXY(me.dom, pos);
-        }else{
-            me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
+        if (Ext.isMac) {
+            cls.push("ext-mac");
+        }
+        if (Ext.isLinux) {
+            cls.push("ext-linux");
         }
-        return me;
-    },
 
+        
+        if (Ext.isStrict || Ext.isBorderBox) {
+            var p = bd.parentNode;
+            if (p) {
+                Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box');
+            }
+        }
+        
+        
+        if (Ext.enableForcedBoxModel && !Ext.isIE) {
+            Ext.isForcedBorderBox = true;
+            cls.push("ext-forced-border-box");
+        }
+        
+        Ext.fly(bd, '_internal').addClass(cls);
+        return true;
+    };
     
-    setLocation : function(x, y, animate){
-        return this.setXY([x, y], this.animTest(arguments, animate, 2));
-    },
+    if (!initExtCss()) {
+        Ext.onReady(initExtCss);
+    }
+})();
 
+
+(function(){
+    var supports = Ext.apply(Ext.supports, {
+        
+        correctRightMargin: true,
+        
+        
+        correctTransparentColor: true,
+        
+        
+        cssFloat: true
+    });
     
-    moveTo : function(x, y, animate){
-        return this.setXY([x, y], this.animTest(arguments, animate, 2));        
-    },    
-    
+    var supportTests = function(){
+            var div = document.createElement('div'),
+                doc = document,
+                view,
+                last;
+                
+            div.innerHTML = '<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';
+            doc.body.appendChild(div);
+            last = div.lastChild;
+            
+            if((view = doc.defaultView)){
+                if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){
+                    supports.correctRightMargin = false;
+                }
+                if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){
+                    supports.correctTransparentColor = false;
+                }
+            }
+            supports.cssFloat = !!last.style.cssFloat;
+            doc.body.removeChild(div);
+    };
     
-    getLeft : function(local){
-           return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
-    },
+    if (Ext.isReady) {
+        supportTests();    
+    } else {
+        Ext.onReady(supportTests);
+    }
+})();
 
-    
-    getRight : function(local){
-           var me = this;
-           return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
-    },
 
-    
-    getTop : function(local) {
-           return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
-    },
 
-    
-    getBottom : function(local){
-           var me = this;
-           return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
-    },
+Ext.EventObject = function(){
+    var E = Ext.lib.Event,
+        clickRe = /(dbl)?click/,
+        
+        safariKeys = {
+            3 : 13, 
+            63234 : 37, 
+            63235 : 39, 
+            63232 : 38, 
+            63233 : 40, 
+            63276 : 33, 
+            63277 : 34, 
+            63272 : 46, 
+            63273 : 36, 
+            63275 : 35  
+        },
+        
+        btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2};
 
-    
-    position : function(pos, zIndex, x, y){
-           var me = this;
-           
-        if(!pos && me.isStyle(POSITION, STATIC)){           
-            me.setStyle(POSITION, RELATIVE);           
-        } else if(pos) {
-            me.setStyle(POSITION, pos);
-        }
-        if(zIndex){
-            me.setStyle(ZINDEX, zIndex);
+    Ext.EventObjectImpl = function(e){
+        if(e){
+            this.setEvent(e.browserEvent || e);
         }
-        if(x || y) me.setXY([x || false, y || false]);
-    },
+    };
 
-    
-    clearPositioning : function(value){
-        value = value || '';
-        this.setStyle({
-            left : value,
-            right : value,
-            top : value,
-            bottom : value,
-            "z-index" : "",
-            position : STATIC
-        });
-        return this;
-    },
+    Ext.EventObjectImpl.prototype = {
+           
+        setEvent : function(e){
+            var me = this;
+            if(e == me || (e && e.browserEvent)){ 
+                return e;
+            }
+            me.browserEvent = e;
+            if(e){
+                
+                me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
+                if(clickRe.test(e.type) && me.button == -1){
+                    me.button = 0;
+                }
+                me.type = e.type;
+                me.shiftKey = e.shiftKey;
+                
+                me.ctrlKey = e.ctrlKey || e.metaKey || false;
+                me.altKey = e.altKey;
+                
+                me.keyCode = e.keyCode;
+                me.charCode = e.charCode;
+                
+                me.target = E.getTarget(e);
+                
+                me.xy = E.getXY(e);
+            }else{
+                me.button = -1;
+                me.shiftKey = false;
+                me.ctrlKey = false;
+                me.altKey = false;
+                me.keyCode = 0;
+                me.charCode = 0;
+                me.target = null;
+                me.xy = [0, 0];
+            }
+            return me;
+        },
 
-    
-    getPositioning : function(){
-        var l = this.getStyle(LEFT);
-        var t = this.getStyle(TOP);
-        return {
-            "position" : this.getStyle(POSITION),
-            "left" : l,
-            "right" : l ? "" : this.getStyle(RIGHT),
-            "top" : t,
-            "bottom" : t ? "" : this.getStyle(BOTTOM),
-            "z-index" : this.getStyle(ZINDEX)
-        };
-    },
-    
-    
-    setPositioning : function(pc){
-           var me = this,
-               style = me.dom.style;
-               
-        me.setStyle(pc);
         
-        if(pc.right == AUTO){
-            style.right = "";
-        }
-        if(pc.bottom == AUTO){
-            style.bottom = "";
-        }
+        stopEvent : function(){
+            var me = this;
+            if(me.browserEvent){
+                if(me.browserEvent.type == 'mousedown'){
+                    Ext.EventManager.stoppedMouseDownEvent.fire(me);
+                }
+                E.stopEvent(me.browserEvent);
+            }
+        },
+
         
-        return me;
-    },    
-       
-    
-    translatePoints : function(x, y){               
-           y = isNaN(x[1]) ? y : x[1];
-        x = isNaN(x[0]) ? x : x[0];
-        var me = this,
-               relative = me.isStyle(POSITION, RELATIVE),
-               o = me.getXY(),
-               l = parseInt(me.getStyle(LEFT), 10),
-               t = parseInt(me.getStyle(TOP), 10);
+        preventDefault : function(){
+            if(this.browserEvent){
+                E.preventDefault(this.browserEvent);
+            }
+        },
+
         
-        l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
-        t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);        
+        stopPropagation : function(){
+            var me = this;
+            if(me.browserEvent){
+                if(me.browserEvent.type == 'mousedown'){
+                    Ext.EventManager.stoppedMouseDownEvent.fire(me);
+                }
+                E.stopPropagation(me.browserEvent);
+            }
+        },
 
-        return {left: (x - o[0] + l), top: (y - o[1] + t)}; 
-    },
-    
-    animTest : function(args, animate, i) {
-        return !!animate && this.preanim ? this.preanim(args, i) : false;
-    }
-});
-})();
-Ext.Element.addMethods({
-    
-    setBox : function(box, adjust, animate){
-        var me = this,
-               w = box.width, 
-               h = box.height;
-        if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
-           w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
-           h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
-        }
-        me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
-        return me;
-    },
+        
+        getCharCode : function(){
+            return this.charCode || this.keyCode;
+        },
 
-    
-       getBox : function(contentBox, local) {      
-           var me = this,
-               xy,
-               left,
-               top,
-               getBorderWidth = me.getBorderWidth,
-               getPadding = me.getPadding, 
-               l,
-               r,
-               t,
-               b;
-        if(!local){
-            xy = me.getXY();
-        }else{
-            left = parseInt(me.getStyle("left"), 10) || 0;
-            top = parseInt(me.getStyle("top"), 10) || 0;
-            xy = [left, top];
-        }
-        var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
-        if(!contentBox){
-            bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
-        }else{
-            l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
-            r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
-            t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
-            b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
-            bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)};
-        }
-        bx.right = bx.x + bx.width;
-        bx.bottom = bx.y + bx.height;
-        return bx;
-       },
-       
-    
-     move : function(direction, distance, animate){
-        var me = this,         
-               xy = me.getXY(),
-               x = xy[0],
-               y = xy[1],              
-               left = [x - distance, y],
-               right = [x + distance, y],
-               top = [x, y - distance],
-               bottom = [x, y + distance],
-               hash = {
-                       l :     left,
-                       left : left,
-                       r : right,
-                       right : right,
-                       t : top,
-                       top : top,
-                       up : top,
-                       b : bottom, 
-                       bottom : bottom,
-                       down : bottom                           
-               };
         
-           direction = direction.toLowerCase();    
-           me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
-    },
-    
-    
-     setLeftTop : function(left, top){
-           var me = this,
-               style = me.dom.style;
-        style.left = me.addUnits(left);
-        style.top = me.addUnits(top);
-        return me;
-    },
-    
-    
-    getRegion : function(){
-        return Ext.lib.Dom.getRegion(this.dom);
-    },
-    
-    
-    setBounds : function(x, y, width, height, animate){
-           var me = this;
-        if (!animate || !me.anim) {
-            me.setSize(width, height);
-            me.setLocation(x, y);
-        } else {
-            me.anim({points: {to: [x, y]}, 
-                        width: {to: me.adjustWidth(width)}, 
-                        height: {to: me.adjustHeight(height)}},
-                     me.preanim(arguments, 4), 
-                     'motion');
-        }
-        return me;
-    },
+        getKey : function(){
+            return this.normalizeKey(this.keyCode || this.charCode);
+        },
 
-    
-    setRegion : function(region, animate) {
-        return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
-    }
-});
-Ext.Element.addMethods({
-    
-    isScrollable : function(){
-        var dom = this.dom;
-        return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
-    },
+        
+        normalizeKey: function(k){
+            return Ext.isSafari ? (safariKeys[k] || k) : k;
+        },
 
-    
-    scrollTo : function(side, value){
-        this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
-        return this;
-    },
+        
+        getPageX : function(){
+            return this.xy[0];
+        },
 
-    
-    getScroll : function(){
-        var d = this.dom, 
-            doc = document,
-            body = doc.body,
-            docElement = doc.documentElement,
-            l,
-            t,
-            ret;
+        
+        getPageY : function(){
+            return this.xy[1];
+        },
 
-        if(d == doc || d == body){
-            if(Ext.isIE && Ext.isStrict){
-                l = docElement.scrollLeft; 
-                t = docElement.scrollTop;
-            }else{
-                l = window.pageXOffset;
-                t = window.pageYOffset;
-            }
-            ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
-        }else{
-            ret = {left: d.scrollLeft, top: d.scrollTop};
-        }
-        return ret;
-    }
-});
-Ext.Element.addMethods({
-    
-    scrollTo : function(side, value, animate){
-        var top = /top/i.test(side), 
-               me = this,
-               dom = me.dom,
-            prop;
-        if (!animate || !me.anim) {
-            prop = 'scroll' + (top ? 'Top' : 'Left'), 
-            dom[prop] = value;
-        }else{
-            prop = 'scroll' + (top ? 'Left' : 'Top'), 
-            me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}},
-                        me.preanim(arguments, 2), 'scroll');
-        }
-        return me;
-    },
-    
-    
-    scrollIntoView : function(container, hscroll){
-        var c = Ext.getDom(container) || Ext.getBody().dom,
-               el = this.dom,
-               o = this.getOffsetsTo(c),
-            l = o[0] + c.scrollLeft,
-            t = o[1] + c.scrollTop,
-            b = t + el.offsetHeight,
-            r = l + el.offsetWidth,
-               ch = c.clientHeight,
-               ct = parseInt(c.scrollTop, 10),
-               cl = parseInt(c.scrollLeft, 10),
-               cb = ct + ch,
-               cr = cl + c.clientWidth;
+        
+        getXY : function(){
+            return this.xy;
+        },
 
-        if (el.offsetHeight > ch || t < ct) {
-               c.scrollTop = t;
-        } else if (b > cb){
-            c.scrollTop = b-ch;
-        }
-        c.scrollTop = c.scrollTop; 
+        
+        getTarget : function(selector, maxDepth, returnEl){
+            return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
+        },
 
-        if(hscroll !== false){
-                       if(el.offsetWidth > c.clientWidth || l < cl){
-                c.scrollLeft = l;
-            }else if(r > cr){
-                c.scrollLeft = r - c.clientWidth;
+        
+        getRelatedTarget : function(){
+            return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
+        },
+
+        
+        getWheelDelta : function(){
+            var e = this.browserEvent;
+            var delta = 0;
+            if(e.wheelDelta){ 
+                delta = e.wheelDelta/120;
+            }else if(e.detail){ 
+                delta = -e.detail/3;
             }
-            c.scrollLeft = c.scrollLeft;
+            return delta;
+        },
+
+        
+        within : function(el, related, allowEl){
+            if(el){
+                var t = this[related ? "getRelatedTarget" : "getTarget"]();
+                return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
+            }
+            return false;
         }
-        return this;
-    },
+     };
 
+    return new Ext.EventObjectImpl();
+}();
+
+Ext.Loader = Ext.apply({}, {
     
-    scrollChildIntoView : function(child, hscroll){
-        Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
+    load: function(fileList, callback, scope, preserveOrder) {
+        var scope       = scope || this,
+            head        = document.getElementsByTagName("head")[0],
+            fragment    = document.createDocumentFragment(),
+            numFiles    = fileList.length,
+            loadedFiles = 0,
+            me          = this;
+        
+        
+        var loadFileIndex = function(index) {
+            head.appendChild(
+                me.buildScriptTag(fileList[index], onFileLoaded)
+            );
+        };
+        
+        
+        var onFileLoaded = function() {
+            loadedFiles ++;
+            
+            
+            if (numFiles == loadedFiles && typeof callback == 'function') {
+                callback.call(scope);
+            } else {
+                if (preserveOrder === true) {
+                    loadFileIndex(loadedFiles);
+                }
+            }
+        };
+        
+        if (preserveOrder === true) {
+            loadFileIndex.call(this, 0);
+        } else {
+            
+            Ext.each(fileList, function(file, index) {
+                fragment.appendChild(
+                    this.buildScriptTag(file, onFileLoaded)
+                );  
+            }, this);
+            
+            head.appendChild(fragment);
+        }
     },
     
     
-     scroll : function(direction, distance, animate){
-         if(!this.isScrollable()){
-             return;
-         }
-         var el = this.dom,
-            l = el.scrollLeft, t = el.scrollTop,
-            w = el.scrollWidth, h = el.scrollHeight,
-            cw = el.clientWidth, ch = el.clientHeight,
-            scrolled = false, v,
-            hash = {
-                l: Math.min(l + distance, w-cw),
-                r: v = Math.max(l - distance, 0),
-                t: Math.max(t - distance, 0),
-                b: Math.min(t + distance, h-ch)
+    buildScriptTag: function(filename, callback) {
+        var script  = document.createElement('script');
+        script.type = "text/javascript";
+        script.src  = filename;
+        
+        
+        if (script.readyState) {
+            script.onreadystatechange = function() {
+                if (script.readyState == "loaded" || script.readyState == "complete") {
+                    script.onreadystatechange = null;
+                    callback();
+                }
             };
-            hash.d = hash.b;
-            hash.u = hash.t;
-            
-         direction = direction.substr(0, 1);
-         if((v = hash[direction]) > -1){
-            scrolled = true;
-            this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
-         }
-         return scrolled;
+        } else {
+            script.onload = callback;
+        }    
+        
+        return script;
     }
 });
 
-Ext.Element.VISIBILITY = 1;
-
-Ext.Element.DISPLAY = 2;
 
-Ext.Element.addMethods(function(){
-    var VISIBILITY = "visibility",
-        DISPLAY = "display",
-        HIDDEN = "hidden",
-        NONE = "none",      
-        ORIGINALDISPLAY = 'originalDisplay',
-        VISMODE = 'visibilityMode',
-        ELDISPLAY = Ext.Element.DISPLAY,
-        data = Ext.Element.data,
-        getDisplay = function(dom){
-            var d = data(dom, ORIGINALDISPLAY);
-            if(d === undefined){
-                data(dom, ORIGINALDISPLAY, d = '');
-            }
-            return d;
-        },
-        getVisMode = function(dom){
-            var m = data(dom, VISMODE);
-            if(m === undefined){
-                data(dom, VISMODE, m = 1)
-            }
-            return m;
-        };
+Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
+       "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
     
+
+Ext.apply(Ext, function(){
+    var E = Ext,
+        idSeed = 0,
+        scrollWidth = null;
+
     return {
         
-        originalDisplay : "",
-        visibilityMode : 1,
-        
+        emptyFn : function(){},
+
         
-        setVisibilityMode : function(visMode){  
-            data(this.dom, VISMODE, visMode);
-            return this;
+        BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
+                            'http:/' + '/www.extjs.com/s.gif' :
+                            'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
+
+        extendX : function(supr, fn){
+            return Ext.extend(supr, fn(supr.prototype));
         },
+
         
-        
-        animate : function(args, duration, onComplete, easing, animType){       
-            this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
-            return this;
+        getDoc : function(){
+            return Ext.get(document);
         },
-    
+
         
-        anim : function(args, opt, animType, defaultDur, defaultEase, cb){
-            animType = animType || 'run';
-            opt = opt || {};
-            var me = this,              
-                anim = Ext.lib.Anim[animType](
-                    me.dom, 
-                    args,
-                    (opt.duration || defaultDur) || .35,
-                    (opt.easing || defaultEase) || 'easeOut',
-                    function(){
-                        if(cb) cb.call(me);
-                        if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
-                    },
-                    me
-                );
-            opt.anim = anim;
-            return anim;
+        num : function(v, defaultValue){
+            v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v);
+            return isNaN(v) ? defaultValue : v;
         },
-    
+
         
-        preanim : function(a, i){
-            return !a[i] ? false : (Ext.isObject(a[i]) ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
+        value : function(v, defaultValue, allowBlank){
+            return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
         },
+
         
-        
-        isVisible : function() {
-            return !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE);
+        escapeRe : function(s) {
+            return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
+        },
+
+        sequence : function(o, name, fn, scope){
+            o[name] = o[name].createSequence(fn, scope);
         },
+
         
+        addBehaviors : function(o){
+            if(!Ext.isReady){
+                Ext.onReady(function(){
+                    Ext.addBehaviors(o);
+                });
+            } else {
+                var cache = {}, 
+                    parts,
+                    b,
+                    s;
+                for (b in o) {
+                    if ((parts = b.split('@'))[1]) { 
+                        s = parts[0];
+                        if(!cache[s]){
+                            cache[s] = Ext.select(s);
+                        }
+                        cache[s].on(parts[1], o[b]);
+                    }
+                }
+                cache = null;
+            }
+        },
+
         
-         setVisible : function(visible, animate){
-            var me = this,
-                dom = me.dom,
-                isDisplay = getVisMode(this.dom) == ELDISPLAY;
+        getScrollBarWidth: function(force){
+            if(!Ext.isReady){
+                return 0;
+            }
+
+            if(force === true || scrollWidth === null){
+                    
+                var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
+                    child = div.child('div', true);
+                var w1 = child.offsetWidth;
+                div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
+                var w2 = child.offsetWidth;
+                div.remove();
                 
-            if (!animate || !me.anim) {
-                if(isDisplay){
-                    me.setDisplayed(visible);
+                scrollWidth = w1 - w2 + 2;
+            }
+            return scrollWidth;
+        },
+
+
+        
+        combine : function(){
+            var as = arguments, l = as.length, r = [];
+            for(var i = 0; i < l; i++){
+                var a = as[i];
+                if(Ext.isArray(a)){
+                    r = r.concat(a);
+                }else if(a.length !== undefined && !a.substr){
+                    r = r.concat(Array.prototype.slice.call(a, 0));
                 }else{
-                    me.fixDisplay();
-                    dom.style.visibility = visible ? "visible" : HIDDEN;
+                    r.push(a);
                 }
-            }else{
-                
-                if(visible){
-                    me.setOpacity(.01);
-                    me.setVisible(true);
-                }
-                me.anim({opacity: { to: (visible?1:0) }},
-                        me.preanim(arguments, 1),
-                        null,
-                        .35,
-                        'easeIn',
-                        function(){
-                             if(!visible){
-                                 dom.style[isDisplay ? DISPLAY : VISIBILITY] = (isDisplay) ? NONE : HIDDEN;                     
-                                 Ext.fly(dom).setOpacity(1);
-                             }
-                        });
             }
-            return me;
+            return r;
         },
-    
+
         
-        toggle : function(animate){
-            var me = this;
-            me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
-            return me;
+        copyTo : function(dest, source, names){
+            if(typeof names == 'string'){
+                names = names.split(/[,;\s]/);
+            }
+            Ext.each(names, function(name){
+                if(source.hasOwnProperty(name)){
+                    dest[name] = source[name];
+                }
+            }, this);
+            return dest;
         },
-    
+
         
-        setDisplayed : function(value) {            
-            if(typeof value == "boolean"){
-               value = value ? getDisplay(this.dom) : NONE;
+        destroy : function(){
+            Ext.each(arguments, function(arg){
+                if(arg){
+                    if(Ext.isArray(arg)){
+                        this.destroy.apply(this, arg);
+                    }else if(typeof arg.destroy == 'function'){
+                        arg.destroy();
+                    }else if(arg.dom){
+                        arg.remove();
+                    }
+                }
+            }, this);
+        },
+
+        
+        destroyMembers : function(o, arg1, arg2, etc){
+            for(var i = 1, a = arguments, len = a.length; i < len; i++) {
+                Ext.destroy(o[a[i]]);
+                delete o[a[i]];
             }
-            this.setStyle(DISPLAY, value);
-            return this;
         },
+
         
+        clean : function(arr){
+            var ret = [];
+            Ext.each(arr, function(v){
+                if(!!v){
+                    ret.push(v);
+                }
+            });
+            return ret;
+        },
+
         
-        fixDisplay : function(){
-            var me = this;
-            if(me.isStyle(DISPLAY, NONE)){
-                me.setStyle(VISIBILITY, HIDDEN);
-                me.setStyle(DISPLAY, getDisplay(this.dom)); 
-                if(me.isStyle(DISPLAY, NONE)){ 
-                    me.setStyle(DISPLAY, "block");
+        unique : function(arr){
+            var ret = [],
+                collect = {};
+
+            Ext.each(arr, function(v) {
+                if(!collect[v]){
+                    ret.push(v);
                 }
+                collect[v] = true;
+            });
+            return ret;
+        },
+
+        
+        flatten : function(arr){
+            var worker = [];
+            function rFlatten(a) {
+                Ext.each(a, function(v) {
+                    if(Ext.isArray(v)){
+                        rFlatten(v);
+                    }else{
+                        worker.push(v);
+                    }
+                });
+                return worker;
             }
+            return rFlatten(arr);
         },
-    
+
         
-        hide : function(animate){
-            this.setVisible(false, this.preanim(arguments, 0));
-            return this;
+        min : function(arr, comp){
+            var ret = arr[0];
+            comp = comp || function(a,b){ return a < b ? -1 : 1; };
+            Ext.each(arr, function(v) {
+                ret = comp(ret, v) == -1 ? ret : v;
+            });
+            return ret;
         },
-    
+
         
-        show : function(animate){
-            this.setVisible(true, this.preanim(arguments, 0));
-            return this;
-        }
-    }
-}());
-Ext.Element.addMethods(
-function(){
-    var VISIBILITY = "visibility",
-        DISPLAY = "display",
-        HIDDEN = "hidden",
-        NONE = "none",
-           XMASKED = "x-masked",
-               XMASKEDRELATIVE = "x-masked-relative",
-        data = Ext.Element.data;
-               
-       return {
-               
-           isVisible : function(deep) {
-               var vis = !this.isStyle(VISIBILITY,HIDDEN) && !this.isStyle(DISPLAY,NONE),
-                       p = this.dom.parentNode;
-               if(deep !== true || !vis){
-                   return vis;
-               }               
-               while(p && !/body/i.test(p.tagName)){
-                   if(!Ext.fly(p, '_isVisible').isVisible()){
-                       return false;
-                   }
-                   p = p.parentNode;
-               }
-               return true;
-           },
-           
-           
-           isDisplayed : function() {
-               return !this.isStyle(DISPLAY, NONE);
-           },
-           
-               
-           enableDisplayMode : function(display){          
-               this.setVisibilityMode(Ext.Element.DISPLAY);
-               if(!Ext.isEmpty(display)){
-                data(this.dom, 'originalDisplay', display);
-            }
-               return this;
-           },
-           
-               
-           mask : function(msg, msgCls){
-                   var me = this,
-                       dom = me.dom,
-                       dh = Ext.DomHelper,
-                       EXTELMASKMSG = "ext-el-mask-msg",
-                el, 
-                mask;
-                       
-               if(me.getStyle("position") == "static"){
-                   me.addClass(XMASKEDRELATIVE);
-               }
-               if((el = data(dom, 'maskMsg'))){
-                   el.remove();
-               }
-               if((el = data(dom, 'mask'))){
-                   el.remove();
-               }
-       
-            mask = dh.append(dom, {cls : "ext-el-mask"}, true);
-               data(dom, 'mask', mask);
-       
-               me.addClass(XMASKED);
-               mask.setDisplayed(true);
-               if(typeof msg == 'string'){
-                var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
-                data(dom, 'maskMsg', mm);
-                   mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
-                   mm.dom.firstChild.innerHTML = msg;
-                   mm.setDisplayed(true);
-                   mm.center(me);
-               }
-               if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto'){ 
-                   mask.setSize(undefined, me.getHeight());
-               }
-               return mask;
-           },
-       
-           
-           unmask : function(){
-                   var me = this,
-                dom = me.dom,
-                       mask = data(dom, 'mask'),
-                       maskMsg = data(dom, 'maskMsg');
-               if(mask){
-                   if(maskMsg){
-                       maskMsg.remove();
-                    data(dom, 'maskMsg', undefined);
-                   }
-                   mask.remove();
-                data(dom, 'mask', undefined);
-               }
-               me.removeClass([XMASKED, XMASKEDRELATIVE]);
-           },
-       
-           
-           isMasked : function(){
-            var m = data(this.dom, 'mask');
-               return m && m.isVisible();
-           },
-           
-           
-           createShim : function(){
-               var el = document.createElement('iframe'),              
-                       shim;
-               el.frameBorder = '0';
-               el.className = 'ext-shim';
-               el.src = Ext.SSL_SECURE_URL;
-               shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
-               shim.autoBoxAdjust = false;
-               return shim;
-           }
-    };
-}());
-Ext.Element.addMethods({
-    
-    addKeyListener : function(key, fn, scope){
-        var config;
-        if(!Ext.isObject(key) || Ext.isArray(key)){
-            config = {
-                key: key,
-                fn: fn,
-                scope: scope
-            };
-        }else{
-            config = {
-                key : key.key,
-                shift : key.shift,
-                ctrl : key.ctrl,
-                alt : key.alt,
-                fn: fn,
-                scope: scope
-            };
-        }
-        return new Ext.KeyMap(this, config);
-    },
+        max : function(arr, comp){
+            var ret = arr[0];
+            comp = comp || function(a,b){ return a > b ? 1 : -1; };
+            Ext.each(arr, function(v) {
+                ret = comp(ret, v) == 1 ? ret : v;
+            });
+            return ret;
+        },
 
-    
-    addKeyMap : function(config){
-        return new Ext.KeyMap(this, config);
-    }
-});(function(){
-    
-    var NULL = null,
-        UNDEFINED = undefined,
-        TRUE = true,
-        FALSE = false,
-        SETX = "setX",
-        SETY = "setY",
-        SETXY = "setXY",
-        LEFT = "left",
-        BOTTOM = "bottom",
-        TOP = "top",
-        RIGHT = "right",
-        HEIGHT = "height",
-        WIDTH = "width",
-        POINTS = "points",
-        HIDDEN = "hidden",
-        ABSOLUTE = "absolute",
-        VISIBLE = "visible",
-        MOTION = "motion",
-        POSITION = "position",
-        EASEOUT = "easeOut",
         
-        flyEl = new Ext.Element.Flyweight(),
-        queues = {},
-        getObject = function(o){
-            return o || {};
+        mean : function(arr){
+           return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
         },
-        fly = function(dom){
-            flyEl.dom = dom;
-            flyEl.id = Ext.id(dom);
-            return flyEl;
+
+        
+        sum : function(arr){
+           var ret = 0;
+           Ext.each(arr, function(v) {
+               ret += v;
+           });
+           return ret;
         },
+
         
-        getQueue = function(id){
-            if(!queues[id]){
-                queues[id] = [];
-            }
-            return queues[id];
+        partition : function(arr, truth){
+            var ret = [[],[]];
+            Ext.each(arr, function(v, i, a) {
+                ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
+            });
+            return ret;
         },
-        setQueue = function(id, value){
-            queues[id] = value;
-        };
+
         
+        invoke : function(arr, methodName){
+            var ret = [],
+                args = Array.prototype.slice.call(arguments, 2);
+            Ext.each(arr, function(v,i) {
+                if (v && typeof v[methodName] == 'function') {
+                    ret.push(v[methodName].apply(v, args));
+                } else {
+                    ret.push(undefined);
+                }
+            });
+            return ret;
+        },
 
-Ext.enableFx = TRUE;
+        
+        pluck : function(arr, prop){
+            var ret = [];
+            Ext.each(arr, function(v) {
+                ret.push( v[prop] );
+            });
+            return ret;
+        },
 
+        
+        zip : function(){
+            var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
+                arrs = parts[0],
+                fn = parts[1][0],
+                len = Ext.max(Ext.pluck(arrs, "length")),
+                ret = [];
 
-Ext.Fx = {
-    
-    
-    
-    switchStatements : function(key, fn, argHash){
-        return fn.apply(this, argHash[key]);
-    },
-    
-    
-    slideIn : function(anchor, o){ 
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            st = dom.style,
-            xy,
-            r,
-            b,              
-            wrap,               
-            after,
-            st,
-            args, 
-            pt,
-            bw,
-            bh;
-            
-        anchor = anchor || "t";
+            for (var i = 0; i < len; i++) {
+                ret[i] = [];
+                if(fn){
+                    ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
+                }else{
+                    for (var j = 0, aLen = arrs.length; j < aLen; j++){
+                        ret[i].push( arrs[j][i] );
+                    }
+                }
+            }
+            return ret;
+        },
 
-        me.queueFx(o, function(){            
-            xy = fly(dom).getXY();
-            
-            fly(dom).fixDisplay();            
-            
-            
-            r = fly(dom).getFxRestore();      
-            b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
-            b.right = b.x + b.width;
-            b.bottom = b.y + b.height;
-            
-            
-            fly(dom).setWidth(b.width).setHeight(b.height);            
-            
-            
-            wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
-            
-            st.visibility = VISIBLE;
-            st.position = ABSOLUTE;
-            
-            
-            function after(){
-                 fly(dom).fxUnwrap(wrap, r.pos, o);
-                 st.width = r.width;
-                 st.height = r.height;
-                 fly(dom).afterFx(o);
+        
+        getCmp : function(id){
+            return Ext.ComponentMgr.get(id);
+        },
+
+        
+        useShims: E.isIE6 || (E.isMac && E.isGecko2),
+
+        
+        
+        type : function(o){
+            if(o === undefined || o === null){
+                return false;
             }
-            
-            
-            pt = {to: [b.x, b.y]}; 
-            bw = {to: b.width};
-            bh = {to: b.height};
-                
-            function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){                    
-                var ret = {};
-                fly(wrap).setWidth(ww).setHeight(wh);
-                if(fly(wrap)[sXY]){
-                    fly(wrap)[sXY](sXYval);                  
+            if(o.htmlElement){
+                return 'element';
+            }
+            var t = typeof o;
+            if(t == 'object' && o.nodeName) {
+                switch(o.nodeType) {
+                    case 1: return 'element';
+                    case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
                 }
-                style[s1] = style[s2] = "0";                    
-                if(w){
-                    ret.width = w
-                };
-                if(h){
-                    ret.height = h;
+            }
+            if(t == 'object' || t == 'function') {
+                switch(o.constructor) {
+                    case Array: return 'array';
+                    case RegExp: return 'regexp';
+                    case Date: return 'date';
                 }
-                if(p){
-                    ret.points = p;
+                if(typeof o.length == 'number' && typeof o.item == 'function') {
+                    return 'nodelist';
                 }
-                return ret;
-            };
+            }
+            return t;
+        },
 
-            args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
-                    t  : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
-                    l  : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
-                    r  : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
-                    b  : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
-                    tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
-                    bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
-                    br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
-                    tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
-                });
-            
-            st.visibility = VISIBLE;
-            fly(wrap).show();
+        intercept : function(o, name, fn, scope){
+            o[name] = o[name].createInterceptor(fn, scope);
+        },
 
-            arguments.callee.anim = fly(wrap).fxanim(args,
-                o,
-                MOTION,
-                .5,
-                EASEOUT, 
-                after);
-        });
-        return me;
-    },
-    
+        
+        callback : function(cb, scope, args, delay){
+            if(typeof cb == 'function'){
+                if(delay){
+                    cb.defer(delay, scope, args || []);
+                }else{
+                    cb.apply(scope, args || []);
+                }
+            }
+        }
+    };
+}());
+
+
+Ext.apply(Function.prototype, {
     
-    slideOut : function(anchor, o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            st = dom.style,
-            xy = me.getXY(),
-            wrap,
-            r,
-            b,
-            a,
-            zero = {to: 0}; 
-                    
-        anchor = anchor || "t";
+    createSequence : function(fcn, scope){
+        var method = this;
+        return (typeof fcn != 'function') ?
+                this :
+                function(){
+                    var retval = method.apply(this || window, arguments);
+                    fcn.apply(scope || this || window, arguments);
+                    return retval;
+                };
+    }
+});
 
-        me.queueFx(o, function(){
-            
-            
-            r = fly(dom).getFxRestore(); 
-            b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
-            b.right = b.x + b.width;
-            b.bottom = b.y + b.height;
-                
-            
-            fly(dom).setWidth(b.width).setHeight(b.height);
 
-            
-            wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
-                
-            st.visibility = VISIBLE;
-            st.position = ABSOLUTE;
-            fly(wrap).setWidth(b.width).setHeight(b.height);            
 
-            function after(){
-                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();                
-                fly(dom).fxUnwrap(wrap, r.pos, o);
-                st.width = r.width;
-                st.height = r.height;
-                fly(dom).afterFx(o);
-            }            
-            
-            function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){                    
-                var ret = {};
-                
-                style[s1] = style[s2] = "0";
-                ret[p1] = v1;               
-                if(p2){
-                    ret[p2] = v2;               
-                }
-                if(p3){
-                    ret[p3] = v3;
-                }
-                
-                return ret;
-            };
-            
-            a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
-                t  : [st, LEFT, BOTTOM, HEIGHT, zero],
-                l  : [st, RIGHT, TOP, WIDTH, zero],
-                r  : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
-                b  : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
-                tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
-                bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
-                br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
-                tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
-            });
-            
-            arguments.callee.anim = fly(wrap).fxanim(a,
-                o,
-                MOTION,
-                .5,
-                EASEOUT, 
-                after);
-        });
-        return me;
+Ext.applyIf(String, {
+
+    
+    escape : function(string) {
+        return string.replace(/('|\\)/g, "\\$1");
     },
 
     
-    puff : function(o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            st = dom.style,
-            width,
-            height,
-            r;
+    leftPad : function (val, size, ch) {
+        var result = String(val);
+        if(!ch) {
+            ch = " ";
+        }
+        while (result.length < size) {
+            result = ch + result;
+        }
+        return result;
+    }
+});
 
-        me.queueFx(o, function(){
-            width = fly(dom).getWidth();
-            height = fly(dom).getHeight();
-            fly(dom).clearOpacity();
-            fly(dom).show();
 
-            
-            r = fly(dom).getFxRestore();                   
-            
-            function after(){
-                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();                  
-                fly(dom).clearOpacity();  
-                fly(dom).setPositioning(r.pos);
-                st.width = r.width;
-                st.height = r.height;
-                st.fontSize = '';
-                fly(dom).afterFx(o);
-            }   
+String.prototype.toggle = function(value, other){
+    return this == value ? other : value;
+};
 
-            arguments.callee.anim = fly(dom).fxanim({
-                    width : {to : fly(dom).adjustWidth(width * 2)},
-                    height : {to : fly(dom).adjustHeight(height * 2)},
-                    points : {by : [-width * .5, -height * .5]},
-                    opacity : {to : 0},
-                    fontSize: {to : 200, unit: "%"}
-                },
-                o,
-                MOTION,
-                .5,
-                EASEOUT,
-                 after);
-        });
-        return me;
-    },
 
-    
-    switchOff : function(o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            st = dom.style,
-            r;
+String.prototype.trim = function(){
+    var re = /^\s+|\s+$/g;
+    return function(){ return this.replace(re, ""); };
+}();
 
-        me.queueFx(o, function(){
-            fly(dom).clearOpacity();
-            fly(dom).clip();
 
-            
-            r = fly(dom).getFxRestore();
-                
-            function after(){
-                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();  
-                fly(dom).clearOpacity();
-                fly(dom).setPositioning(r.pos);
-                st.width = r.width;
-                st.height = r.height;   
-                fly(dom).afterFx(o);
-            };
 
-            fly(dom).fxanim({opacity : {to : 0.3}}, 
-                NULL, 
-                NULL, 
-                .1, 
-                NULL, 
-                function(){                                 
-                    fly(dom).clearOpacity();
-                        (function(){                            
-                            fly(dom).fxanim({
-                                height : {to : 1},
-                                points : {by : [0, fly(dom).getHeight() * .5]}
-                            }, 
-                            o, 
-                            MOTION, 
-                            0.3, 
-                            'easeIn', 
-                            after);
-                        }).defer(100);
-                });
-        });
-        return me;
-    },
+Date.prototype.getElapsed = function(date) {
+    return Math.abs((date || new Date()).getTime()-this.getTime());
+};
 
-     
-    highlight : function(color, o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            attr = o.attr || "backgroundColor",
-            a = {},
-            restore;
 
-        me.queueFx(o, function(){
-            fly(dom).clearOpacity();
-            fly(dom).show();
 
-            function after(){
-                dom.style[attr] = restore;
-                fly(dom).afterFx(o);
-            }            
-            restore = dom.style[attr];
-            a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
-            arguments.callee.anim = fly(dom).fxanim(a,
-                o,
-                'color',
-                1,
-                'easeIn', 
-                after);
-        });
-        return me;
-    },
-
-   
-    frame : function(color, count, o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            proxy,
-            active;
-
-        me.queueFx(o, function(){
-            color = color || '#C3DAF9';
-            if(color.length == 6){
-                color = '#' + color;
-            }            
-            count = count || 1;
-            fly(dom).show();
-
-            var xy = fly(dom).getXY(),
-                b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
-                queue = function(){
-                    proxy = fly(document.body || document.documentElement).createChild({
-                        style:{
-                            position : ABSOLUTE,
-                            'z-index': 35000, 
-                            border : '0px solid ' + color
-                        }
-                    });
-                    return proxy.queueFx({}, animFn);
-                };
-            
-            
-            arguments.callee.anim = {
-                isAnimated: true,
-                stop: function() {
-                    count = 0;
-                    proxy.stopFx();
-                }
-            };
-            
-            function animFn(){
-                var scale = Ext.isBorderBox ? 2 : 1;
-                active = proxy.anim({
-                    top : {from : b.y, to : b.y - 20},
-                    left : {from : b.x, to : b.x - 20},
-                    borderWidth : {from : 0, to : 10},
-                    opacity : {from : 1, to : 0},
-                    height : {from : b.height, to : b.height + 20 * scale},
-                    width : {from : b.width, to : b.width + 20 * scale}
-                },{
-                    duration: o.duration || 1,
-                    callback: function() {
-                        proxy.remove();
-                        --count > 0 ? queue() : fly(dom).afterFx(o);
-                    }
-                });
-                arguments.callee.anim = {
-                    isAnimated: true,
-                    stop: function(){
-                        active.stop();
-                    }
-                };
-            };
-            queue();
-        });
-        return me;
-    },
-
-   
-    pause : function(seconds){        
-        var dom = this.dom,
-            t;
+Ext.applyIf(Number.prototype, {
+    
+    constrain : function(min, max){
+        return Math.min(Math.max(this, min), max);
+    }
+});
+Ext.lib.Dom.getRegion = function(el) {
+    return Ext.lib.Region.getRegion(el);
+};     Ext.lib.Region = function(t, r, b, l) {
+               var me = this;
+        me.top = t;
+        me[1] = t;
+        me.right = r;
+        me.bottom = b;
+        me.left = l;
+        me[0] = l;
+    };
 
-        this.queueFx({}, function(){
-            t = setTimeout(function(){
-                fly(dom).afterFx({});
-            }, seconds * 1000);
-            arguments.callee.anim = {
-                isAnimated: true,
-                stop: function(){
-                    clearTimeout(t);
-                    fly(dom).afterFx({});
-                }
-            };
-        });
-        return this;
-    },
+    Ext.lib.Region.prototype = {
+        contains : function(region) {
+               var me = this;
+            return ( region.left >= me.left &&
+                     region.right <= me.right &&
+                     region.top >= me.top &&
+                     region.bottom <= me.bottom );
 
-   
-    fadeIn : function(o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            to = o.endOpacity || 1;
-        
-        me.queueFx(o, function(){
-            fly(dom).setOpacity(0);
-            fly(dom).fixDisplay();
-            dom.style.visibility = VISIBLE;
-            arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
-                o, NULL, .5, EASEOUT, function(){
-                if(to == 1){
-                    fly(dom).clearOpacity();
-                }
-                fly(dom).afterFx(o);
-            });
-        });
-        return me;
-    },
+        },
 
-   
-    fadeOut : function(o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            style = dom.style,
-            to = o.endOpacity || 0;         
-        
-        me.queueFx(o, function(){  
-            arguments.callee.anim = fly(dom).fxanim({ 
-                opacity : {to : to}},
-                o, 
-                NULL, 
-                .5, 
-                EASEOUT, 
-                function(){
-                    if(to == 0){
-                        Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ? 
-                            style.display = "none" :
-                            style.visibility = HIDDEN;
-                            
-                        fly(dom).clearOpacity();
-                    }
-                    fly(dom).afterFx(o);
-            });
-        });
-        return me;
-    },
+        getArea : function() {
+               var me = this;
+            return ( (me.bottom - me.top) * (me.right - me.left) );
+        },
 
-   
-    scale : function(w, h, o){
-        this.shift(Ext.apply({}, o, {
-            width: w,
-            height: h
-        }));
-        return this;
-    },
+        intersect : function(region) {
+            var me = this,
+               t = Math.max(me.top, region.top),
+               r = Math.min(me.right, region.right),
+               b = Math.min(me.bottom, region.bottom),
+               l = Math.max(me.left, region.left);
 
-   
-    shift : function(o){
-        o = getObject(o);
-        var dom = this.dom,
-            a = {};
-                
-        this.queueFx(o, function(){
-            for (var prop in o) {
-                if (o[prop] != UNDEFINED) {                                                 
-                    a[prop] = {to : o[prop]};                   
-                }
-            } 
-            
-            a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
-            a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;   
-            
-            if (a.x || a.y || a.xy) {
-                a.points = a.xy || 
-                           {to : [ a.x ? a.x.to : fly(dom).getX(),
-                                   a.y ? a.y.to : fly(dom).getY()]};                  
+            if (b >= t && r >= l) {
+                return new Ext.lib.Region(t, r, b, l);
             }
+        },
+        
+        union : function(region) {
+               var me = this,
+               t = Math.min(me.top, region.top),
+               r = Math.max(me.right, region.right),
+               b = Math.max(me.bottom, region.bottom),
+               l = Math.min(me.left, region.left);
 
-            arguments.callee.anim = fly(dom).fxanim(a,
-                o, 
-                MOTION, 
-                .35, 
-                EASEOUT, 
-                function(){
-                    fly(dom).afterFx(o);
-                });
-        });
-        return this;
-    },
+            return new Ext.lib.Region(t, r, b, l);
+        },
 
-    
-    ghost : function(anchor, o){
-        o = getObject(o);
-        var me = this,
-            dom = me.dom,
-            st = dom.style,
-            a = {opacity: {to: 0}, points: {}},
-            pt = a.points,
-            r,
-            w,
-            h;
-            
-        anchor = anchor || "b";
+        constrainTo : function(r) {
+               var me = this;
+            me.top = me.top.constrain(r.top, r.bottom);
+            me.bottom = me.bottom.constrain(r.top, r.bottom);
+            me.left = me.left.constrain(r.left, r.right);
+            me.right = me.right.constrain(r.left, r.right);
+            return me;
+        },
 
-        me.queueFx(o, function(){
-            
-            r = fly(dom).getFxRestore();
-            w = fly(dom).getWidth();
-            h = fly(dom).getHeight();
-            
-            function after(){
-                o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();   
-                fly(dom).clearOpacity();
-                fly(dom).setPositioning(r.pos);
-                st.width = r.width;
-                st.height = r.height;
-                fly(dom).afterFx(o);
-            }
-                
-            pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
-               t  : [0, -h],
-               l  : [-w, 0],
-               r  : [w, 0],
-               b  : [0, h],
-               tl : [-w, -h],
-               bl : [-w, h],
-               br : [w, h],
-               tr : [w, -h] 
-            });
-                
-            arguments.callee.anim = fly(dom).fxanim(a,
-                o,
-                MOTION,
-                .5,
-                EASEOUT, after);
-        });
-        return me;
-    },
+        adjust : function(t, l, b, r) {
+               var me = this;
+            me.top += t;
+            me.left += l;
+            me.right += r;
+            me.bottom += b;
+            return me;
+        }
+    };
 
-    
-    syncFx : function(){
-        var me = this;
-        me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
-            block : FALSE,
-            concurrent : TRUE,
-            stopFx : FALSE
-        });
-        return me;
-    },
+    Ext.lib.Region.getRegion = function(el) {
+        var p = Ext.lib.Dom.getXY(el),
+               t = p[1],
+               r = p[0] + el.offsetWidth,
+               b = p[1] + el.offsetHeight,
+               l = p[0];
 
-    
-    sequenceFx : function(){
+        return new Ext.lib.Region(t, r, b, l);
+    }; Ext.lib.Point = function(x, y) {
+        if (Ext.isArray(x)) {
+            y = x[1];
+            x = x[0];
+        }
         var me = this;
-        me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
-            block : FALSE,
-            concurrent : FALSE,
-            stopFx : FALSE
-        });
-        return me;
-    },
+        me.x = me.right = me.left = me[0] = x;
+        me.y = me.top = me.bottom = me[1] = y;
+    };
 
-    
-    nextFx : function(){        
-        var ef = getQueue(this.dom.id)[0];
-        if(ef){
-            ef.call(this);
-        }
-    },
+    Ext.lib.Point.prototype = new Ext.lib.Region();
 
-    
-    hasActiveFx : function(){
-        return getQueue(this.dom.id)[0];
-    },
+Ext.apply(Ext.DomHelper,
+function(){
+    var pub,
+        afterbegin = 'afterbegin',
+        afterend = 'afterend',
+        beforebegin = 'beforebegin',
+        beforeend = 'beforeend',
+        confRe = /tag|children|cn|html$/i;
 
     
-    stopFx : function(finish){
-        var me = this,
-            id = me.dom.id;
-        if(me.hasActiveFx()){
-            var cur = getQueue(id)[0];
-            if(cur && cur.anim){
-                if(cur.anim.isAnimated){
-                    setQueue(id, [cur]); 
-                    cur.anim.stop(finish !== undefined ? finish : TRUE);
-                }else{
-                    setQueue(id, []);
-                }
+    function doInsert(el, o, returnElement, pos, sibling, append){
+        el = Ext.getDom(el);
+        var newNode;
+        if (pub.useDom) {
+            newNode = createDom(o, null);
+            if (append) {
+                el.appendChild(newNode);
+            } else {
+                (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
             }
+        } else {
+            newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
         }
-        return me;
-    },
+        return returnElement ? Ext.get(newNode, true) : newNode;
+    }
 
     
-    beforeFx : function(o){
-        if(this.hasActiveFx() && !o.concurrent){
-           if(o.stopFx){
-               this.stopFx();
-               return TRUE;
-           }
-           return FALSE;
-        }
-        return TRUE;
-    },
-
     
-    hasFxBlock : function(){
-        var q = getQueue(this.dom.id);
-        return q && q[0] && q[0].block;
-    },
+    function createDom(o, parentNode){
+        var el,
+            doc = document,
+            useSet,
+            attr,
+            val,
+            cn;
 
-    
-    queueFx : function(o, fn){
-        var me = fly(this.dom);
-        if(!me.hasFxBlock()){
-            Ext.applyIf(o, me.fxDefaults);
-            if(!o.concurrent){
-                var run = me.beforeFx(o);
-                fn.block = o.block;
-                getQueue(me.dom.id).push(fn);
-                if(run){
-                    me.nextFx();
+        if (Ext.isArray(o)) {                       
+            el = doc.createDocumentFragment(); 
+            for (var i = 0, l = o.length; i < l; i++) {
+                createDom(o[i], el);
+            }
+        } else if (typeof o == 'string') {         
+            el = doc.createTextNode(o);
+        } else {
+            el = doc.createElement( o.tag || 'div' );
+            useSet = !!el.setAttribute; 
+            for (var attr in o) {
+                if(!confRe.test(attr)){
+                    val = o[attr];
+                    if(attr == 'cls'){
+                        el.className = val;
+                    }else{
+                        if(useSet){
+                            el.setAttribute(attr, val);
+                        }else{
+                            el[attr] = val;
+                        }
+                    }
                 }
-            }else{
-                fn.call(me);
             }
-        }
-        return me;
-    },
+            Ext.DomHelper.applyStyles(el, o.style);
 
-    
-    fxWrap : function(pos, o, vis){ 
-        var dom = this.dom,
-            wrap,
-            wrapXY;
-        if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){            
-            if(o.fixPosition){
-                wrapXY = fly(dom).getXY();
-            }
-            var div = document.createElement("div");
-            div.style.visibility = vis;
-            wrap = dom.parentNode.insertBefore(div, dom);
-            fly(wrap).setPositioning(pos);
-            if(fly(wrap).isStyle(POSITION, "static")){
-                fly(wrap).position("relative");
-            }
-            fly(dom).clearPositioning('auto');
-            fly(wrap).clip();
-            wrap.appendChild(dom);
-            if(wrapXY){
-                fly(wrap).setXY(wrapXY);
+            if ((cn = o.children || o.cn)) {
+                createDom(cn, el);
+            } else if (o.html) {
+                el.innerHTML = o.html;
             }
         }
-        return wrap;
-    },
-
-    
-    fxUnwrap : function(wrap, pos, o){      
-        var dom = this.dom;
-        fly(dom).clearPositioning();
-        fly(dom).setPositioning(pos);
-        if(!o.wrap){
-            var pn = fly(wrap).dom.parentNode;
-            pn.insertBefore(dom, wrap); 
-            fly(wrap).remove();
-        }
-    },
-
-    
-    getFxRestore : function(){
-        var st = this.dom.style;
-        return {pos: this.getPositioning(), width: st.width, height : st.height};
-    },
-
-    
-    afterFx : function(o){
-        var dom = this.dom,
-            id = dom.id;
-        if(o.afterStyle){
-            fly(dom).setStyle(o.afterStyle);            
-        }
-        if(o.afterCls){
-            fly(dom).addClass(o.afterCls);
-        }
-        if(o.remove == TRUE){
-            fly(dom).remove();
-        }
-        if(o.callback){
-            o.callback.call(o.scope, fly(dom));
-        }
-        if(!o.concurrent){
-            getQueue(id).shift();
-            fly(dom).nextFx();
+        if(parentNode){
+           parentNode.appendChild(el);
         }
-    },
-
-    
-    fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
-        animType = animType || 'run';
-        opt = opt || {};
-        var anim = Ext.lib.Anim[animType](
-                this.dom, 
-                args,
-                (opt.duration || defaultDur) || .35,
-                (opt.easing || defaultEase) || EASEOUT,
-                cb,            
-                this
-            );
-        opt.anim = anim;
-        return anim;
+        return el;
     }
-};
 
+    pub = {
+        
+        createTemplate : function(o){
+            var html = Ext.DomHelper.createHtml(o);
+            return new Ext.Template(html);
+        },
 
-Ext.Fx.resize = Ext.Fx.scale;
+        
+        useDom : false,
 
+        
+        insertBefore : function(el, o, returnElement){
+            return doInsert(el, o, returnElement, beforebegin);
+        },
 
+        
+        insertAfter : function(el, o, returnElement){
+            return doInsert(el, o, returnElement, afterend, 'nextSibling');
+        },
 
-Ext.Element.addMethods(Ext.Fx);
-})();
+        
+        insertFirst : function(el, o, returnElement){
+            return doInsert(el, o, returnElement, afterbegin, 'firstChild');
+        },
 
-Ext.CompositeElementLite = function(els, root){
-    
-    this.elements = [];
-    this.add(els, root);
-    this.el = new Ext.Element.Flyweight();
-};
+        
+        append: function(el, o, returnElement){
+            return doInsert(el, o, returnElement, beforeend, '', true);
+        },
 
-Ext.CompositeElementLite.prototype = {
-    isComposite: true,    
-    
-    
-    getElement : function(el){
         
-        var e = this.el;
-        e.dom = el;
-        e.id = el.id;
-        return e;
-    },
-    
-    
-    transformElement : function(el){
-        return Ext.getDom(el);
-    },
+        createDom: createDom
+    };
+    return pub;
+}());
+
+Ext.apply(Ext.Template.prototype, {
     
+    disableFormats : false,
     
-    getCount : function(){
-        return this.elements.length;
-    },    
+
     
-    add : function(els, root){
+    re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
+    argsRe : /^\s*['"](.*)["']\s*$/,
+    compileARe : /\\/g,
+    compileBRe : /(\r\n|\n)/g,
+    compileCRe : /'/g,
+
+    /**
+     * Returns an HTML fragment of this template with the specified values applied.
+     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+     * @return {String} The HTML fragment
+     * @hide repeat doc
+     */
+    applyTemplate : function(values){
         var me = this,
-            elements = me.elements;
-        if(!els){
-            return this;
-        }
-        if(Ext.isString(els)){
-            els = Ext.Element.selectorFunction(els, root);
-        }else if(els.isComposite){
-            els = els.elements;
-        }else if(!Ext.isIterable(els)){
-            els = [els];
+            useF = me.disableFormats !== true,
+            fm = Ext.util.Format,
+            tpl = me;
+
+        if(me.compiled){
+            return me.compiled(values);
         }
-        
-        for(var i = 0, len = els.length; i < len; ++i){
-            elements.push(me.transformElement(els[i]));
-        }
-        return me;
-    },
-    
-    invoke : function(fn, args){
-        var me = this,
-            els = me.elements,
-            len = els.length, 
-            e;
-            
-        for(i = 0; i<len; i++) {
-            e = els[i];
-            if(e){
-                Ext.Element.prototype[fn].apply(me.getElement(e), args);
+        function fn(m, name, format, args){
+            if (format && useF) {
+                if (format.substr(0, 5) == "this.") {
+                    return tpl.call(format.substr(5), values[name], values);
+                } else {
+                    if (args) {
+                        // quoted values are required for strings in compiled templates,
+                        // but for non compiled we need to strip them
+                        // quoted reversed for jsmin
+                        var re = me.argsRe;
+                        args = args.split(',');
+                        for(var i = 0, len = args.length; i < len; i++){
+                            args[i] = args[i].replace(re, "$1");
+                        }
+                        args = [values[name]].concat(args);
+                    } else {
+                        args = [values[name]];
+                    }
+                    return fm[format].apply(fm, args);
+                }
+            } else {
+                return values[name] !== undefined ? values[name] : "";
             }
         }
-        return me;
-    },
-    
-    item : function(index){
-        var me = this,
-            el = me.elements[index],
-            out = null;
-
-        if(el){
-            out = me.getElement(el);
-        }
-        return out;
+        return me.html.replace(me.re, fn);
     },
 
-    
-    addListener : function(eventName, handler, scope, opt){
-        var els = this.elements,
-            len = els.length,
-            i, e;
-        
-        for(i = 0; i<len; i++) {
-            e = els[i];
-            if(e) {
-                Ext.EventManager.on(e, eventName, handler, scope || e, opt);
-            }
-        }
-        return this;
-    },
-    
-    each : function(fn, scope){       
+    /**
+     * Compiles the template into an internal function, eliminating the RegEx overhead.
+     * @return {Ext.Template} this
+     * @hide repeat doc
+     */
+    compile : function(){
         var me = this,
-            els = me.elements,
-            len = els.length,
-            i, e;
-        
-        for(i = 0; i<len; i++) {
-            e = els[i];
-            if(e){
-                e = this.getElement(e);
-                if(fn.call(scope || e, e, me, i)){
-                    break;
+            fm = Ext.util.Format,
+            useF = me.disableFormats !== true,
+            sep = Ext.isGecko ? "+" : ",",
+            body;
+
+        function fn(m, name, format, args){
+            if(format && useF){
+                args = args ? ',' + args : "";
+                if(format.substr(0, 5) != "this."){
+                    format = "fm." + format + '(';
+                }else{
+                    format = 'this.call("'+ format.substr(5) + '", ';
+                    args = ", values";
                 }
+            }else{
+                args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
             }
+            return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
         }
-        return me;
-    },
-    
-    
-    fill : function(els){
-        var me = this;
-        me.elements = [];
-        me.add(els);
-        return me;
-    },
-    
-    
-    filter : function(selector){
-        var els = [],
-            me = this,
-            elements = me.elements,
-            fn = Ext.isFunction(selector) ? selector
-                : function(el){
-                    return el.is(selector);
-                };
-                
-        
-        me.each(function(el, self, i){
-            if(fn(el, i) !== false){
-                els[els.length] = me.transformElement(el);
-            }
-        });
-        me.elements = els;
-        return me;
-    },
-    
-    
-    indexOf : function(el){
-        return this.elements.indexOf(this.transformElement(el));
-    },
-    
-        
-    replaceElement : function(el, replacement, domReplace){
-        var index = !isNaN(el) ? el : this.indexOf(el),
-            d;
-        if(index > -1){
-            replacement = Ext.getDom(replacement);
-            if(domReplace){
-                d = this.elements[index];
-                d.parentNode.insertBefore(replacement, d);
-                Ext.removeNode(d);
-            }
-            this.elements.splice(index, 1, replacement);
+
+        // branched to use + in gecko and [].join() in others
+        if(Ext.isGecko){
+            body = "this.compiled = function(values){ return '" +
+                   me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
+                    "';};";
+        }else{
+            body = ["this.compiled = function(values){ return ['"];
+            body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
+            body.push("'].join('');};");
+            body = body.join('');
         }
-        return this;
+        eval(body);
+        return me;
     },
-    
-    
-    clear : function(){
-        this.elements = [];
-    }
-};
-
-Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
 
-(function(){
-var fnName,
-    ElProto = Ext.Element.prototype,
-    CelProto = Ext.CompositeElementLite.prototype;
-    
-for(fnName in ElProto){
-    if(Ext.isFunction(ElProto[fnName])){
-        (function(fnName){ 
-            CelProto[fnName] = CelProto[fnName] || function(){
-                return this.invoke(fnName, arguments);
-            };
-        }).call(CelProto, fnName);
-        
+    // private function used to call members
+    call : function(fnName, value, allValues){
+        return this[fnName](value, allValues);
     }
+});
+Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
+/**
+ * @class Ext.util.Functions
+ * @singleton
+ */
+Ext.util.Functions = {
+    /**
+     * Creates an interceptor function. The passed function is called before the original one. If it returns false,
+     * the original one is not called. The resulting function returns the results of the original function.
+     * The passed function is called with the parameters of the original function. Example usage:
+     * <pre><code>
+var sayHi = function(name){
+    alert('Hi, ' + name);
 }
-})();
 
-if(Ext.DomQuery){
-    Ext.Element.selectorFunction = Ext.DomQuery.select;
-} 
+sayHi('Fred'); // alerts "Hi, Fred"
 
+// create a new function that validates input without
+// directly modifying the original function:
+var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
+    return name == 'Brian';
+});
 
-Ext.Element.select = function(selector, root){
-    var els;
-    if(typeof selector == "string"){
-        els = Ext.Element.selectorFunction(selector, root);
-    }else if(selector.length !== undefined){
-        els = selector;
-    }else{
-        throw "Invalid selector";
-    }
-    return new Ext.CompositeElementLite(els);
-};
-
-Ext.select = Ext.Element.select;
-Ext.apply(Ext.CompositeElementLite.prototype, {        
-       addElements : function(els, root){
-        if(!els){
-            return this;
+sayHiToFriend('Fred');  // no alert
+sayHiToFriend('Brian'); // alerts "Hi, Brian"
+       </code></pre>
+     * @param {Function} origFn The original function.
+     * @param {Function} newFn The function to call before the original
+     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
+     * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
+     * @return {Function} The new function
+     */
+    createInterceptor: function(origFn, newFn, scope) { 
+        var method = origFn;
+        if (!Ext.isFunction(newFn)) {
+            return origFn;
         }
-        if(typeof els == "string"){
-            els = Ext.Element.selectorFunction(els, root);
+        else {
+            return function() {
+                var me = this,
+                    args = arguments;
+                newFn.target = me;
+                newFn.method = origFn;
+                return (newFn.apply(scope || me || window, args) !== false) ?
+                        origFn.apply(me || window, args) :
+                        null;
+            };
         }
-        var yels = this.elements;        
-           Ext.each(els, function(e) {
-               yels.push(Ext.get(e));
-        });
-        return this;
-    },
-    
-    
-    first : function(){
-        return this.item(0);
-    },   
-    
-    
-    last : function(){
-        return this.item(this.getCount()-1);
-    },
-    
-    
-    contains : function(el){
-        return this.indexOf(el) != -1;
     },
-    
-    
-    removeElement : function(keys, removeDom){
-        var me = this,
-               els = this.elements,        
-               el;             
-           Ext.each(keys, function(val){
-                   if ((el = (els[val] || els[val = me.indexOf(val)]))) {
-                       if(removeDom){
-                    if(el.dom){
-                        el.remove();
-                    }else{
-                        Ext.removeNode(el);
-                    }
-                }
-                       els.splice(val, 1);                     
-                       }
-           });
-        return this;
-    }    
-});
 
-Ext.CompositeElement = function(els, root){
-    this.elements = [];
-    this.add(els, root);
-};
+    /**
+     * Creates a delegate (callback) that sets the scope to obj.
+     * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
+     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
+     * callback points to obj. Example usage:
+     * <pre><code>
+var sayHi = function(name){
+    // Note this use of "this.text" here.  This function expects to
+    // execute within a scope that contains a text property.  In this
+    // example, the "this" variable is pointing to the btn object that
+    // was passed in createDelegate below.
+    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
+}
 
-Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
-    
-    
-    getElement : function(el){
-        
-        return el;
+var btn = new Ext.Button({
+    text: 'Say Hi',
+    renderTo: Ext.getBody()
+});
+
+// This callback will execute in the scope of the
+// button instance. Clicking the button alerts
+// "Hi, Fred. You clicked the "Say Hi" button."
+btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
+       </code></pre>
+     * @param {Function} fn The function to delegate.
+     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+     * <b>If omitted, defaults to the browser window.</b>
+     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+     * if a number the args are inserted at the specified position
+     * @return {Function} The new function
+     */
+    createDelegate: function(fn, obj, args, appendArgs) {
+        if (!Ext.isFunction(fn)) {
+            return fn;
+        }
+        return function() {
+            var callArgs = args || arguments;
+            if (appendArgs === true) {
+                callArgs = Array.prototype.slice.call(arguments, 0);
+                callArgs = callArgs.concat(args);
+            }
+            else if (Ext.isNumber(appendArgs)) {
+                callArgs = Array.prototype.slice.call(arguments, 0);
+                // copy arguments first
+                var applyArgs = [appendArgs, 0].concat(args);
+                // create method call params
+                Array.prototype.splice.apply(callArgs, applyArgs);
+                // splice them in
+            }
+            return fn.apply(obj || window, callArgs);
+        };
     },
-    
-    
-    transformElement : function(el){
-        return Ext.get(el);
-    }
 
-    
+    /**
+     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
+     * <pre><code>
+var sayHi = function(name){
+    alert('Hi, ' + name);
+}
 
-    
+// executes immediately:
+sayHi('Fred');
+
+// executes after 2 seconds:
+Ext.defer(sayHi, 2000, this, ['Fred']);
+
+// this syntax is sometimes useful for deferring
+// execution of an anonymous function:
+Ext.defer(function(){
+    alert('Anonymous');
+}, 100);
+       </code></pre>
+     * @param {Function} fn The function to defer.
+     * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
+     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+     * <b>If omitted, defaults to the browser window.</b>
+     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+     * if a number the args are inserted at the specified position
+     * @return {Number} The timeout id that can be used with clearTimeout
+     */
+    defer: function(fn, millis, obj, args, appendArgs) {
+        fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
+        if (millis > 0) {
+            return setTimeout(fn, millis);
+        }
+        fn();
+        return 0;
+    },
+
+
+    /**
+     * Create a combined function call sequence of the original function + the passed function.
+     * The resulting function returns the results of the original function.
+     * The passed fcn is called with the parameters of the original function. Example usage:
+     * 
+
+var sayHi = function(name){
+    alert('Hi, ' + name);
+}
 
-    
+sayHi('Fred'); // alerts "Hi, Fred"
+
+var sayGoodbye = Ext.createSequence(sayHi, function(name){
+    alert('Bye, ' + name);
 });
 
+sayGoodbye('Fred'); // both alerts show
 
-Ext.Element.select = function(selector, unique, root){
-    var els;
-    if(typeof selector == "string"){
-        els = Ext.Element.selectorFunction(selector, root);
-    }else if(selector.length !== undefined){
-        els = selector;
-    }else{
-        throw "Invalid selector";
+     * @param {Function} origFn The original function.
+     * @param {Function} newFn The function to sequence
+     * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
+     * If omitted, defaults to the scope in which the original function is called or the browser window.
+     * @return {Function} The new function
+     */
+    createSequence: function(origFn, newFn, scope) {
+        if (!Ext.isFunction(newFn)) {
+            return origFn;
+        }
+        else {
+            return function() {
+                var retval = origFn.apply(this || window, arguments);
+                newFn.apply(scope || this || window, arguments);
+                return retval;
+            };
+        }
     }
-
-    return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
 };
 
+/**
+ * Shorthand for {@link Ext.util.Functions#defer}   
+ * @param {Function} fn The function to defer.
+ * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Number} The timeout id that can be used with clearTimeout
+ * @member Ext
+ * @method defer
+ */
 
-Ext.select = Ext.Element.select;(function(){
-    var BEFOREREQUEST = "beforerequest",
-        REQUESTCOMPLETE = "requestcomplete",
-        REQUESTEXCEPTION = "requestexception",
-        UNDEFINED = undefined,
-        LOAD = 'load',
-        POST = 'POST',
-        GET = 'GET',
-        WINDOW = window;
-    
-    
-    Ext.data.Connection = function(config){    
-        Ext.apply(this, config);
-        this.addEvents(
-            
-            BEFOREREQUEST,
-            
-            REQUESTCOMPLETE,
-            
-            REQUESTEXCEPTION
-        );
-        Ext.data.Connection.superclass.constructor.call(this);
-    };
+Ext.defer = Ext.util.Functions.defer;
+
+/**
+ * Shorthand for {@link Ext.util.Functions#createInterceptor}   
+ * @param {Function} origFn The original function.
+ * @param {Function} newFn The function to call before the original
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
+ * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
+ * @return {Function} The new function
+ * @member Ext
+ * @method defer
+ */
 
-    Ext.extend(Ext.data.Connection, Ext.util.Observable, {
-        
-        
-        
-        
-        
-        timeout : 30000,
-        
-        autoAbort:false,
-    
-        
-        disableCaching: true,
-        
-        
-        disableCachingParam: '_dc',
-        
-        
-        request : function(o){
-            var me = this;
-            if(me.fireEvent(BEFOREREQUEST, me, o)){
-                if (o.el) {
-                    if(!Ext.isEmpty(o.indicatorText)){
-                        me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
-                    }
-                    if(me.indicatorText) {
-                        Ext.getDom(o.el).innerHTML = me.indicatorText;                        
+Ext.createInterceptor = Ext.util.Functions.createInterceptor;
+
+/**
+ * Shorthand for {@link Ext.util.Functions#createSequence}
+ * @param {Function} origFn The original function.
+ * @param {Function} newFn The function to sequence
+ * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
+ * If omitted, defaults to the scope in which the original function is called or the browser window.
+ * @return {Function} The new function
+ * @member Ext
+ * @method defer
+ */
+
+Ext.createSequence = Ext.util.Functions.createSequence;
+
+/**
+ * Shorthand for {@link Ext.util.Functions#createDelegate}
+ * @param {Function} fn The function to delegate.
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Function} The new function
+ * @member Ext
+ * @method defer
+ */
+Ext.createDelegate = Ext.util.Functions.createDelegate;
+/**
+ * @class Ext.util.Observable
+ */
+Ext.apply(Ext.util.Observable.prototype, function(){
+    // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
+    // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
+    // private
+    function getMethodEvent(method){
+        var e = (this.methodEvents = this.methodEvents ||
+        {})[method], returnValue, v, cancel, obj = this;
+
+        if (!e) {
+            this.methodEvents[method] = e = {};
+            e.originalFn = this[method];
+            e.methodName = method;
+            e.before = [];
+            e.after = [];
+
+            var makeCall = function(fn, scope, args){
+                if((v = fn.apply(scope || obj, args)) !== undefined){
+                    if (typeof v == 'object') {
+                        if(v.returnValue !== undefined){
+                            returnValue = v.returnValue;
+                        }else{
+                            returnValue = v;
+                        }
+                        cancel = !!v.cancel;
                     }
-                    o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
-                        Ext.getDom(o.el).innerHTML = response.responseText;
-                    });
-                }
-                
-                var p = o.params,
-                    url = o.url || me.url,                
-                    method,
-                    cb = {success: me.handleResponse,
-                          failure: me.handleFailure,
-                          scope: me,
-                          argument: {options: o},
-                          timeout : o.timeout || me.timeout
-                    },
-                    form,                    
-                    serForm;                    
-                  
-                     
-                if (Ext.isFunction(p)) {
-                    p = p.call(o.scope||WINDOW, o);
-                }
-                                                           
-                p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);    
-                
-                if (Ext.isFunction(url)) {
-                    url = url.call(o.scope || WINDOW, o);
-                }
-    
-                if((form = Ext.getDom(o.form))){
-                    url = url || form.action;
-                     if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) { 
-                         return me.doFormUpload.call(me, o, p, url);
-                     }
-                    serForm = Ext.lib.Ajax.serializeForm(form);                    
-                    p = p ? (p + '&' + serForm) : serForm;
+                    else
+                        if (v === false) {
+                            cancel = true;
+                        }
+                        else {
+                            returnValue = v;
+                        }
                 }
-                
-                method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
-                
-                if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
-                    var dcp = o.disableCachingParam || me.disableCachingParam;
-                    url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
+            };
+
+            this[method] = function(){
+                var args = Array.prototype.slice.call(arguments, 0),
+                    b;
+                returnValue = v = undefined;
+                cancel = false;
+
+                for(var i = 0, len = e.before.length; i < len; i++){
+                    b = e.before[i];
+                    makeCall(b.fn, b.scope, args);
+                    if (cancel) {
+                        return returnValue;
+                    }
                 }
-                
-                o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
-                
-                if(o.autoAbort === true || me.autoAbort) {
-                    me.abort();
+
+                if((v = e.originalFn.apply(obj, args)) !== undefined){
+                    returnValue = v;
                 }
-                 
-                if((method == GET || o.xmlData || o.jsonData) && p){
-                    url = Ext.urlAppend(url, p);  
-                    p = '';
+
+                for(var i = 0, len = e.after.length; i < len; i++){
+                    b = e.after[i];
+                    makeCall(b.fn, b.scope, args);
+                    if (cancel) {
+                        return returnValue;
+                    }
                 }
-                return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
-            }else{                
-                return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
-            }
-        },
-    
-        
-        isLoading : function(transId){
-            return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;            
+                return returnValue;
+            };
+        }
+        return e;
+    }
+
+    return {
+        // these are considered experimental
+        // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
+        // adds an 'interceptor' called before the original method
+        beforeMethod : function(method, fn, scope){
+            getMethodEvent.call(this, method).before.push({
+                fn: fn,
+                scope: scope
+            });
         },
-    
-        
-        abort : function(transId){
-            if(transId || this.isLoading()){
-                Ext.lib.Ajax.abort(transId || this.transId);
-            }
+
+        // adds a 'sequence' called after the original method
+        afterMethod : function(method, fn, scope){
+            getMethodEvent.call(this, method).after.push({
+                fn: fn,
+                scope: scope
+            });
         },
 
-        
-        handleResponse : function(response){
-            this.transId = false;
-            var options = response.argument.options;
-            response.argument = options ? options.argument : null;
-            this.fireEvent(REQUESTCOMPLETE, this, response, options);
-            if(options.success){
-                options.success.call(options.scope, response, options);
+        removeMethodListener: function(method, fn, scope){
+            var e = this.getMethodEvent(method);
+            for(var i = 0, len = e.before.length; i < len; i++){
+                if(e.before[i].fn == fn && e.before[i].scope == scope){
+                    e.before.splice(i, 1);
+                    return;
+                }
             }
-            if(options.callback){
-                options.callback.call(options.scope, options, true, response);
+            for(var i = 0, len = e.after.length; i < len; i++){
+                if(e.after[i].fn == fn && e.after[i].scope == scope){
+                    e.after.splice(i, 1);
+                    return;
+                }
             }
         },
 
-        
-        handleFailure : function(response, e){
-            this.transId = false;
-            var options = response.argument.options;
-            response.argument = options ? options.argument : null;
-            this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
-            if(options.failure){
-                options.failure.call(options.scope, response, options);
+        /**
+         * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
+         * @param {Object} o The Observable whose events this object is to relay.
+         * @param {Array} events Array of event names to relay.
+         */
+        relayEvents : function(o, events){
+            var me = this;
+            function createHandler(ename){
+                return function(){
+                    return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
+                };
             }
-            if(options.callback){
-                options.callback.call(options.scope, options, false, response);
+            for(var i = 0, len = events.length; i < len; i++){
+                var ename = events[i];
+                me.events[ename] = me.events[ename] || true;
+                o.on(ename, createHandler(ename), me);
             }
         },
 
-        
-        doFormUpload : function(o, ps, url){
-            var id = Ext.id(),
-                doc = document,
-                frame = doc.createElement('iframe'),
-                form = Ext.getDom(o.form),
-                hiddens = [],
-                hd,
-                encoding = 'multipart/form-data',
-                buf = {
-                    target: form.target,
-                    method: form.method,
-                    encoding: form.encoding,
-                    enctype: form.enctype,
-                    action: form.action
-                };
+        /**
+         * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
+         * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
+         * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
+         * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
+         * access the required target more quickly.</p>
+         * <p>Example:</p><pre><code>
+Ext.override(Ext.form.Field, {
+    
+    initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
+        this.enableBubble('change');
+    }),
 
-            Ext.fly(frame).set({
-                id: id,
-                name: id,
-                cls: 'x-hidden',
-                src: Ext.SSL_SECURE_URL 
-            });
-            doc.body.appendChild(frame);
+    
+    getBubbleTarget : function() {
+        if (!this.formPanel) {
+            this.formPanel = this.findParentByType('form');
+        }
+        return this.formPanel;
+    }
+});
 
+var myForm = new Ext.formPanel({
+    title: 'User Details',
+    items: [{
+        ...
+    }],
+    listeners: {
+        change: function() {
             
-            if(Ext.isIE){
-               document.frames[id].name = id;
+            myForm.header.setStyle('color', 'red');
+        }
+    }
+});
+</code></pre>
+         * @param {String/Array} events The event name to bubble, or an Array of event names.
+         */
+        enableBubble : function(events){
+            var me = this;
+            if(!Ext.isEmpty(events)){
+                events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
+                for(var i = 0, len = events.length; i < len; i++){
+                    var ename = events[i];
+                    ename = ename.toLowerCase();
+                    var ce = me.events[ename] || true;
+                    if (typeof ce == 'boolean') {
+                        ce = new Ext.util.Event(me, ename);
+                        me.events[ename] = ce;
+                    }
+                    ce.bubble = true;
+                }
             }
+        }
+    };
+}());
 
-            Ext.fly(form).set({
-                target: id,
-                method: POST,
-                enctype: encoding,
-                encoding: encoding,
-                action: url || buf.action
-            });
 
-            
-            Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
-                hd = doc.createElement('input');
-                Ext.fly(hd).set({
-                    type: 'hidden',
-                    value: v,
-                    name: k
-                });
-                form.appendChild(hd);
-                hiddens.push(hd);
-            });
 
-            function cb(){
-                var me = this,
-                    
-                    r = {responseText : '',
-                         responseXML : null,
-                         argument : o.argument},
-                    doc,
-                    firstChild;
+Ext.util.Observable.capture = function(o, fn, scope){
+    o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
+};
+
+
+
+Ext.util.Observable.observeClass = function(c, listeners){
+    if(c){
+      if(!c.fireEvent){
+          Ext.apply(c, new Ext.util.Observable());
+          Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
+      }
+      if(typeof listeners == 'object'){
+          c.on(listeners);
+      }
+      return c;
+   }
+};
+
+Ext.apply(Ext.EventManager, function(){
+   var resizeEvent,
+       resizeTask,
+       textEvent,
+       textSize,
+       D = Ext.lib.Dom,
+       propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
+       curWidth = 0,
+       curHeight = 0,
+       
+       
+       
+       useKeydown = Ext.isWebKit ?
+                   Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
+                   !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
+
+   return {
+       
+       doResizeEvent: function(){
+           var h = D.getViewHeight(),
+               w = D.getViewWidth();
+
+            
+            if(curHeight != h || curWidth != w){
+               resizeEvent.fire(curWidth = w, curHeight = h);
+            }
+       },
+
+       
+       onWindowResize : function(fn, scope, options){
+           if(!resizeEvent){
+               resizeEvent = new Ext.util.Event();
+               resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
+               Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
+           }
+           resizeEvent.addListener(fn, scope, options);
+       },
+
+       
+       fireWindowResize : function(){
+           if(resizeEvent){
+               resizeTask.delay(100);
+           }
+       },
+
+       
+       onTextResize : function(fn, scope, options){
+           if(!textEvent){
+               textEvent = new Ext.util.Event();
+               var textEl = new Ext.Element(document.createElement('div'));
+               textEl.dom.className = 'x-text-resize';
+               textEl.dom.innerHTML = 'X';
+               textEl.appendTo(document.body);
+               textSize = textEl.dom.offsetHeight;
+               setInterval(function(){
+                   if(textEl.dom.offsetHeight != textSize){
+                       textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
+                   }
+               }, this.textResizeInterval);
+           }
+           textEvent.addListener(fn, scope, options);
+       },
+
+       
+       removeResizeListener : function(fn, scope){
+           if(resizeEvent){
+               resizeEvent.removeListener(fn, scope);
+           }
+       },
+
+       
+       fireResize : function(){
+           if(resizeEvent){
+               resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
+           }
+       },
+
+        
+       textResizeInterval : 50,
+
+       
+       ieDeferSrc : false,
+       
+       
+       getKeyEvent : function(){
+           return useKeydown ? 'keydown' : 'keypress';
+       },
+
+       
+       
+       useKeydown: useKeydown
+   };
+}());
+
+Ext.EventManager.on = Ext.EventManager.addListener;
+
+
+Ext.apply(Ext.EventObjectImpl.prototype, {
+   
+   BACKSPACE: 8,
+   
+   TAB: 9,
+   
+   NUM_CENTER: 12,
+   
+   ENTER: 13,
+   
+   RETURN: 13,
+   
+   SHIFT: 16,
+   
+   CTRL: 17,
+   CONTROL : 17, 
+   
+   ALT: 18,
+   
+   PAUSE: 19,
+   
+   CAPS_LOCK: 20,
+   
+   ESC: 27,
+   
+   SPACE: 32,
+   
+   PAGE_UP: 33,
+   PAGEUP : 33, 
+   
+   PAGE_DOWN: 34,
+   PAGEDOWN : 34, 
+   
+   END: 35,
+   
+   HOME: 36,
+   
+   LEFT: 37,
+   
+   UP: 38,
+   
+   RIGHT: 39,
+   
+   DOWN: 40,
+   
+   PRINT_SCREEN: 44,
+   
+   INSERT: 45,
+   
+   DELETE: 46,
+   
+   ZERO: 48,
+   
+   ONE: 49,
+   
+   TWO: 50,
+   
+   THREE: 51,
+   
+   FOUR: 52,
+   
+   FIVE: 53,
+   
+   SIX: 54,
+   
+   SEVEN: 55,
+   
+   EIGHT: 56,
+   
+   NINE: 57,
+   
+   A: 65,
+   
+   B: 66,
+   
+   C: 67,
+   
+   D: 68,
+   
+   E: 69,
+   
+   F: 70,
+   
+   G: 71,
+   
+   H: 72,
+   
+   I: 73,
+   
+   J: 74,
+   
+   K: 75,
+   
+   L: 76,
+   
+   M: 77,
+   
+   N: 78,
+   
+   O: 79,
+   
+   P: 80,
+   
+   Q: 81,
+   
+   R: 82,
+   
+   S: 83,
+   
+   T: 84,
+   
+   U: 85,
+   
+   V: 86,
+   
+   W: 87,
+   
+   X: 88,
+   
+   Y: 89,
+   
+   Z: 90,
+   
+   CONTEXT_MENU: 93,
+   
+   NUM_ZERO: 96,
+   
+   NUM_ONE: 97,
+   
+   NUM_TWO: 98,
+   
+   NUM_THREE: 99,
+   
+   NUM_FOUR: 100,
+   
+   NUM_FIVE: 101,
+   
+   NUM_SIX: 102,
+   
+   NUM_SEVEN: 103,
+   
+   NUM_EIGHT: 104,
+   
+   NUM_NINE: 105,
+   
+   NUM_MULTIPLY: 106,
+   
+   NUM_PLUS: 107,
+   
+   NUM_MINUS: 109,
+   
+   NUM_PERIOD: 110,
+   
+   NUM_DIVISION: 111,
+   
+   F1: 112,
+   
+   F2: 113,
+   
+   F3: 114,
+   
+   F4: 115,
+   
+   F5: 116,
+   
+   F6: 117,
+   
+   F7: 118,
+   
+   F8: 119,
+   
+   F9: 120,
+   
+   F10: 121,
+   
+   F11: 122,
+   
+   F12: 123,
+
+   
+   isNavKeyPress : function(){
+       var me = this,
+           k = this.normalizeKey(me.keyCode);
+       return (k >= 33 && k <= 40) ||  
+       k == me.RETURN ||
+       k == me.TAB ||
+       k == me.ESC;
+   },
+
+   isSpecialKey : function(){
+       var k = this.normalizeKey(this.keyCode);
+       return (this.type == 'keypress' && this.ctrlKey) ||
+       this.isNavKeyPress() ||
+       (k == this.BACKSPACE) || 
+       (k >= 16 && k <= 20) || 
+       (k >= 44 && k <= 46);   
+   },
+
+   getPoint : function(){
+       return new Ext.lib.Point(this.xy[0], this.xy[1]);
+   },
+
+   
+   hasModifier : function(){
+       return ((this.ctrlKey || this.altKey) || this.shiftKey);
+   }
+});
+Ext.Element.addMethods({
+    
+    swallowEvent : function(eventName, preventDefault) {
+        var me = this;
+        function fn(e) {
+            e.stopPropagation();
+            if (preventDefault) {
+                e.preventDefault();
+            }
+        }
+        
+        if (Ext.isArray(eventName)) {
+            Ext.each(eventName, function(e) {
+                 me.on(e, fn);
+            });
+            return me;
+        }
+        me.on(eventName, fn);
+        return me;
+    },
+
+    
+    relayEvent : function(eventName, observable) {
+        this.on(eventName, function(e) {
+            observable.fireEvent(eventName, e);
+        });
+    },
+
+    
+    clean : function(forceReclean) {
+        var me  = this,
+            dom = me.dom,
+            n   = dom.firstChild,
+            ni  = -1;
+
+        if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
+            return me;
+        }
+
+        while (n) {
+            var nx = n.nextSibling;
+            if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) {
+                dom.removeChild(n);
+            } else {
+                n.nodeIndex = ++ni;
+            }
+            n = nx;
+        }
+        
+        Ext.Element.data(dom, 'isCleaned', true);
+        return me;
+    },
+
+    
+    load : function() {
+        var updateManager = this.getUpdater();
+        updateManager.update.apply(updateManager, arguments);
+        
+        return this;
+    },
+
+    
+    getUpdater : function() {
+        return this.updateManager || (this.updateManager = new Ext.Updater(this));
+    },
+
+    
+    update : function(html, loadScripts, callback) {
+        if (!this.dom) {
+            return this;
+        }
+        html = html || "";
+
+        if (loadScripts !== true) {
+            this.dom.innerHTML = html;
+            if (typeof callback == 'function') {
+                callback();
+            }
+            return this;
+        }
+
+        var id  = Ext.id(),
+            dom = this.dom;
+
+        html += '<span id="' + id + '"></span>';
+
+        Ext.lib.Event.onAvailable(id, function() {
+            var DOC    = document,
+                hd     = DOC.getElementsByTagName("head")[0],
+                re     = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
+                srcRe  = /\ssrc=([\'\"])(.*?)\1/i,
+                typeRe = /\stype=([\'\"])(.*?)\1/i,
+                match,
+                attrs,
+                srcMatch,
+                typeMatch,
+                el,
+                s;
+
+            while ((match = re.exec(html))) {
+                attrs = match[1];
+                srcMatch = attrs ? attrs.match(srcRe) : false;
+                if (srcMatch && srcMatch[2]) {
+                   s = DOC.createElement("script");
+                   s.src = srcMatch[2];
+                   typeMatch = attrs.match(typeRe);
+                   if (typeMatch && typeMatch[2]) {
+                       s.type = typeMatch[2];
+                   }
+                   hd.appendChild(s);
+                } else if (match[2] && match[2].length > 0) {
+                    if (window.execScript) {
+                       window.execScript(match[2]);
+                    } else {
+                       window.eval(match[2]);
+                    }
+                }
+            }
+            
+            el = DOC.getElementById(id);
+            if (el) {
+                Ext.removeNode(el);
+            }
+            
+            if (typeof callback == 'function') {
+                callback();
+            }
+        });
+        dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
+        return this;
+    },
+
+    
+    removeAllListeners : function() {
+        this.removeAnchor();
+        Ext.EventManager.removeAll(this.dom);
+        return this;
+    },
+
+    
+    createProxy : function(config, renderTo, matchBox) {
+        config = (typeof config == 'object') ? config : {tag : "div", cls: config};
+
+        var me = this,
+            proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
+                               Ext.DomHelper.insertBefore(me.dom, config, true);
+
+        if (matchBox && me.setBox && me.getBox) { 
+           proxy.setBox(me.getBox());
+        }
+        return proxy;
+    }
+});
+
+Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
+
+Ext.Element.addMethods({
+    
+    getAnchorXY : function(anchor, local, s){
+        
+        
+               anchor = (anchor || "tl").toLowerCase();
+        s = s || {};
+        
+        var me = this,        
+               vp = me.dom == document.body || me.dom == document,
+               w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
+               h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),                              
+               xy,             
+               r = Math.round,
+               o = me.getXY(),
+               scroll = me.getScroll(),
+               extraX = vp ? scroll.left : !local ? o[0] : 0,
+               extraY = vp ? scroll.top : !local ? o[1] : 0,
+               hash = {
+                       c  : [r(w * 0.5), r(h * 0.5)],
+                       t  : [r(w * 0.5), 0],
+                       l  : [0, r(h * 0.5)],
+                       r  : [w, r(h * 0.5)],
+                       b  : [r(w * 0.5), h],
+                       tl : [0, 0],    
+                       bl : [0, h],
+                       br : [w, h],
+                       tr : [w, 0]
+               };
+        
+        xy = hash[anchor];     
+        return [xy[0] + extraX, xy[1] + extraY]; 
+    },
+
+    
+    anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){        
+           var me = this,
+            dom = me.dom,
+            scroll = !Ext.isEmpty(monitorScroll),
+            action = function(){
+                Ext.fly(dom).alignTo(el, alignment, offsets, animate);
+                Ext.callback(callback, Ext.fly(dom));
+            },
+            anchor = this.getAnchor();
+            
+        
+        this.removeAnchor();
+        Ext.apply(anchor, {
+            fn: action,
+            scroll: scroll
+        });
+
+        Ext.EventManager.onWindowResize(action, null);
+        
+        if(scroll){
+            Ext.EventManager.on(window, 'scroll', action, null,
+                {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
+        }
+        action.call(me); 
+        return me;
+    },
+    
+    
+    removeAnchor : function(){
+        var me = this,
+            anchor = this.getAnchor();
+            
+        if(anchor && anchor.fn){
+            Ext.EventManager.removeResizeListener(anchor.fn);
+            if(anchor.scroll){
+                Ext.EventManager.un(window, 'scroll', anchor.fn);
+            }
+            delete anchor.fn;
+        }
+        return me;
+    },
+    
+    
+    getAnchor : function(){
+        var data = Ext.Element.data,
+            dom = this.dom;
+            if (!dom) {
+                return;
+            }
+            var anchor = data(dom, '_anchor');
+            
+        if(!anchor){
+            anchor = data(dom, '_anchor', {});
+        }
+        return anchor;
+    },
+
+    
+    getAlignToXY : function(el, p, o){     
+        el = Ext.get(el);
+        
+        if(!el || !el.dom){
+            throw "Element.alignToXY with an element that doesn't exist";
+        }
+        
+        o = o || [0,0];
+        p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();       
+                
+        var me = this,
+               d = me.dom,
+               a1,
+               a2,
+               x,
+               y,
+               
+               w,
+               h,
+               r,
+               dw = Ext.lib.Dom.getViewWidth() -10, 
+               dh = Ext.lib.Dom.getViewHeight()-10, 
+               p1y,
+               p1x,            
+               p2y,
+               p2x,
+               swapY,
+               swapX,
+               doc = document,
+               docElement = doc.documentElement,
+               docBody = doc.body,
+               scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
+               scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
+               c = false, 
+               p1 = "", 
+               p2 = "",
+               m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
+        
+        if(!m){
+           throw "Element.alignTo with an invalid alignment " + p;
+        }
+        
+        p1 = m[1]; 
+        p2 = m[2]; 
+        c = !!m[3];
+
+        
+        
+        a1 = me.getAnchorXY(p1, true);
+        a2 = el.getAnchorXY(p2, false);
+
+        x = a2[0] - a1[0] + o[0];
+        y = a2[1] - a1[1] + o[1];
+
+        if(c){    
+              w = me.getWidth();
+           h = me.getHeight();
+           r = el.getRegion();       
+           
+           
+           
+           p1y = p1.charAt(0);
+           p1x = p1.charAt(p1.length-1);
+           p2y = p2.charAt(0);
+           p2x = p2.charAt(p2.length-1);
+           swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
+           swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));          
+           
+
+           if (x + w > dw + scrollX) {
+                x = swapX ? r.left-w : dw+scrollX-w;
+           }
+           if (x < scrollX) {
+               x = swapX ? r.right : scrollX;
+           }
+           if (y + h > dh + scrollY) {
+                y = swapY ? r.top-h : dh+scrollY-h;
+            }
+           if (y < scrollY){
+               y = swapY ? r.bottom : scrollY;
+           }
+        }
+        return [x,y];
+    },
+
+    
+    alignTo : function(element, position, offsets, animate){
+           var me = this;
+        return me.setXY(me.getAlignToXY(element, position, offsets),
+                               me.preanim && !!animate ? me.preanim(arguments, 3) : false);
+    },
+    
+    
+    adjustForConstraints : function(xy, parent, offsets){
+        return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
+    },
+
+    
+    getConstrainToXY : function(el, local, offsets, proposedXY){   
+           var os = {top:0, left:0, bottom:0, right: 0};
+
+        return function(el, local, offsets, proposedXY){
+            el = Ext.get(el);
+            offsets = offsets ? Ext.applyIf(offsets, os) : os;
+
+            var vw, vh, vx = 0, vy = 0;
+            if(el.dom == document.body || el.dom == document){
+                vw =Ext.lib.Dom.getViewWidth();
+                vh = Ext.lib.Dom.getViewHeight();
+            }else{
+                vw = el.dom.clientWidth;
+                vh = el.dom.clientHeight;
+                if(!local){
+                    var vxy = el.getXY();
+                    vx = vxy[0];
+                    vy = vxy[1];
+                }
+            }
+
+            var s = el.getScroll();
+
+            vx += offsets.left + s.left;
+            vy += offsets.top + s.top;
+
+            vw -= offsets.right;
+            vh -= offsets.bottom;
+
+            var vr = vx + vw,
+                vb = vy + vh,
+                xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
+                x = xy[0], y = xy[1],
+                offset = this.getConstrainOffset(),
+                w = this.dom.offsetWidth + offset, 
+                h = this.dom.offsetHeight + offset;
+
+            
+            var moved = false;
+
+            
+            if((x + w) > vr){
+                x = vr - w;
+                moved = true;
+            }
+            if((y + h) > vb){
+                y = vb - h;
+                moved = true;
+            }
+            
+            if(x < vx){
+                x = vx;
+                moved = true;
+            }
+            if(y < vy){
+                y = vy;
+                moved = true;
+            }
+            return moved ? [x, y] : false;
+        };
+    }(),
+           
+           
+               
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+    getConstrainOffset : function(){
+        return 0;
+    },
+    
+    
+    getCenterXY : function(){
+        return this.getAlignToXY(document, 'c-c');
+    },
+
+    
+    center : function(centerIn){
+        return this.alignTo(centerIn || document, 'c-c');        
+    }    
+});
+
+Ext.Element.addMethods({
+    
+    select : function(selector, unique){
+        return Ext.Element.select(selector, unique, this.dom);
+    }
+});
+Ext.apply(Ext.Element.prototype, function() {
+       var GETDOM = Ext.getDom,
+               GET = Ext.get,
+               DH = Ext.DomHelper;
+       
+       return {        
+               
+           insertSibling: function(el, where, returnDom){
+               var me = this,
+                       rt,
+                isAfter = (where || 'before').toLowerCase() == 'after',
+                insertEl;
+                       
+               if(Ext.isArray(el)){
+                insertEl = me;
+                   Ext.each(el, function(e) {
+                           rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
+                    if(isAfter){
+                        insertEl = rt;
+                    }
+                   });
+                   return rt;
+               }
+                       
+               el = el || {};
+               
+            if(el.nodeType || el.dom){
+                rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
+                if (!returnDom) {
+                    rt = GET(rt);
+                }
+            }else{
+                if (isAfter && !me.dom.nextSibling) {
+                    rt = DH.append(me.dom.parentNode, el, !returnDom);
+                } else {                    
+                    rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
+                }
+            }
+               return rt;
+           }
+    };
+}());
+
+
+Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
+
+Ext.Element.addMethods(function(){
+    var INTERNAL = "_internal",
+        pxMatch = /(\d+\.?\d+)px/;
+    return {
+        
+        applyStyles : function(style){
+            Ext.DomHelper.applyStyles(this.dom, style);
+            return this;
+        },
+
+        
+        getStyles : function(){
+            var ret = {};
+            Ext.each(arguments, function(v) {
+               ret[v] = this.getStyle(v);
+            },
+            this);
+            return ret;
+        },
+
+        
+        setOverflow : function(v){
+            var dom = this.dom;
+            if(v=='auto' && Ext.isMac && Ext.isGecko2){ 
+                dom.style.overflow = 'hidden';
+                (function(){dom.style.overflow = 'auto';}).defer(1);
+            }else{
+                dom.style.overflow = v;
+            }
+        },
+
+       
+        boxWrap : function(cls){
+            cls = cls || 'x-box';
+            var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));        
+            Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
+            return el;
+        },
+
+        
+        setSize : function(width, height, animate){
+            var me = this;
+            if(typeof width == 'object'){ 
+                height = width.height;
+                width = width.width;
+            }
+            width = me.adjustWidth(width);
+            height = me.adjustHeight(height);
+            if(!animate || !me.anim){
+                me.dom.style.width = me.addUnits(width);
+                me.dom.style.height = me.addUnits(height);
+            }else{
+                me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
+            }
+            return me;
+        },
+
+        
+        getComputedHeight : function(){
+            var me = this,
+                h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
+            if(!h){
+                h = parseFloat(me.getStyle('height')) || 0;
+                if(!me.isBorderBox()){
+                    h += me.getFrameWidth('tb');
+                }
+            }
+            return h;
+        },
+
+        
+        getComputedWidth : function(){
+            var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
+            if(!w){
+                w = parseFloat(this.getStyle('width')) || 0;
+                if(!this.isBorderBox()){
+                    w += this.getFrameWidth('lr');
+                }
+            }
+            return w;
+        },
+
+        
+        getFrameWidth : function(sides, onlyContentBox){
+            return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
+        },
+
+        
+        addClassOnOver : function(className){
+            this.hover(
+                function(){
+                    Ext.fly(this, INTERNAL).addClass(className);
+                },
+                function(){
+                    Ext.fly(this, INTERNAL).removeClass(className);
+                }
+            );
+            return this;
+        },
+
+        
+        addClassOnFocus : function(className){
+            this.on("focus", function(){
+                Ext.fly(this, INTERNAL).addClass(className);
+            }, this.dom);
+            this.on("blur", function(){
+                Ext.fly(this, INTERNAL).removeClass(className);
+            }, this.dom);
+            return this;
+        },
+
+        
+        addClassOnClick : function(className){
+            var dom = this.dom;
+            this.on("mousedown", function(){
+                Ext.fly(dom, INTERNAL).addClass(className);
+                var d = Ext.getDoc(),
+                    fn = function(){
+                        Ext.fly(dom, INTERNAL).removeClass(className);
+                        d.removeListener("mouseup", fn);
+                    };
+                d.on("mouseup", fn);
+            });
+            return this;
+        },
+
+        
+
+        getViewSize : function(){
+            var doc = document,
+                d = this.dom,
+                isDoc = (d == doc || d == doc.body);
+
+            
+            if (isDoc) {
+                var extdom = Ext.lib.Dom;
+                return {
+                    width : extdom.getViewWidth(),
+                    height : extdom.getViewHeight()
+                };
+
+            
+            } else {
+                return {
+                    width : d.clientWidth,
+                    height : d.clientHeight
+                };
+            }
+        },
+
+        
+
+        getStyleSize : function(){
+            var me = this,
+                w, h,
+                doc = document,
+                d = this.dom,
+                isDoc = (d == doc || d == doc.body),
+                s = d.style;
+
+            
+            if (isDoc) {
+                var extdom = Ext.lib.Dom;
+                return {
+                    width : extdom.getViewWidth(),
+                    height : extdom.getViewHeight()
+                };
+            }
+            
+            if(s.width && s.width != 'auto'){
+                w = parseFloat(s.width);
+                if(me.isBorderBox()){
+                   w -= me.getFrameWidth('lr');
+                }
+            }
+            
+            if(s.height && s.height != 'auto'){
+                h = parseFloat(s.height);
+                if(me.isBorderBox()){
+                   h -= me.getFrameWidth('tb');
+                }
+            }
+            
+            return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
+        },
+
+        
+        getSize : function(contentSize){
+            return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
+        },
+
+        
+        repaint : function(){
+            var dom = this.dom;
+            this.addClass("x-repaint");
+            setTimeout(function(){
+                Ext.fly(dom).removeClass("x-repaint");
+            }, 1);
+            return this;
+        },
+
+        
+        unselectable : function(){
+            this.dom.unselectable = "on";
+            return this.swallowEvent("selectstart", true).
+                        applyStyles("-moz-user-select:none;-khtml-user-select:none;").
+                        addClass("x-unselectable");
+        },
+
+        
+        getMargins : function(side){
+            var me = this,
+                key,
+                hash = {t:"top", l:"left", r:"right", b: "bottom"},
+                o = {};
+
+            if (!side) {
+                for (key in me.margins){
+                    o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
+                }
+                return o;
+            } else {
+                return me.addStyles.call(me, side, me.margins);
+            }
+        }
+    };
+}());
+
+Ext.Element.addMethods({
+    
+    setBox : function(box, adjust, animate){
+        var me = this,
+               w = box.width, 
+               h = box.height;
+        if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
+           w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
+           h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
+        }
+        me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
+        return me;
+    },
+
+    
+       getBox : function(contentBox, local) {      
+           var me = this,
+               xy,
+               left,
+               top,
+               getBorderWidth = me.getBorderWidth,
+               getPadding = me.getPadding, 
+               l,
+               r,
+               t,
+               b;
+        if(!local){
+            xy = me.getXY();
+        }else{
+            left = parseInt(me.getStyle("left"), 10) || 0;
+            top = parseInt(me.getStyle("top"), 10) || 0;
+            xy = [left, top];
+        }
+        var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
+        if(!contentBox){
+            bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
+        }else{
+            l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
+            r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
+            t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
+            b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
+            bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)};
+        }
+        bx.right = bx.x + bx.width;
+        bx.bottom = bx.y + bx.height;
+        return bx;
+       },
+       
+    
+     move : function(direction, distance, animate){
+        var me = this,         
+               xy = me.getXY(),
+               x = xy[0],
+               y = xy[1],              
+               left = [x - distance, y],
+               right = [x + distance, y],
+               top = [x, y - distance],
+               bottom = [x, y + distance],
+               hash = {
+                       l :     left,
+                       left : left,
+                       r : right,
+                       right : right,
+                       t : top,
+                       top : top,
+                       up : top,
+                       b : bottom, 
+                       bottom : bottom,
+                       down : bottom                           
+               };
+        
+           direction = direction.toLowerCase();    
+           me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
+    },
+    
+    
+     setLeftTop : function(left, top){
+           var me = this,
+               style = me.dom.style;
+        style.left = me.addUnits(left);
+        style.top = me.addUnits(top);
+        return me;
+    },
+    
+    
+    getRegion : function(){
+        return Ext.lib.Dom.getRegion(this.dom);
+    },
+    
+    
+    setBounds : function(x, y, width, height, animate){
+           var me = this;
+        if (!animate || !me.anim) {
+            me.setSize(width, height);
+            me.setLocation(x, y);
+        } else {
+            me.anim({points: {to: [x, y]}, 
+                        width: {to: me.adjustWidth(width)}, 
+                        height: {to: me.adjustHeight(height)}},
+                     me.preanim(arguments, 4), 
+                     'motion');
+        }
+        return me;
+    },
+
+    
+    setRegion : function(region, animate) {
+        return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
+    }
+});
+Ext.Element.addMethods({
+    
+    scrollTo : function(side, value, animate) {
+        
+        var top = /top/i.test(side),
+            me = this,
+            dom = me.dom,
+            prop;
+        if (!animate || !me.anim) {
+            
+            prop = 'scroll' + (top ? 'Top' : 'Left');
+            dom[prop] = value;
+        }
+        else {
+            
+            prop = 'scroll' + (top ? 'Left' : 'Top');
+            me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll');
+        }
+        return me;
+    },
+    
+    
+    scrollIntoView : function(container, hscroll) {
+        var c = Ext.getDom(container) || Ext.getBody().dom,
+            el = this.dom,
+            o = this.getOffsetsTo(c),
+            l = o[0] + c.scrollLeft,
+            t = o[1] + c.scrollTop,
+            b = t + el.offsetHeight,
+            r = l + el.offsetWidth,
+            ch = c.clientHeight,
+            ct = parseInt(c.scrollTop, 10),
+            cl = parseInt(c.scrollLeft, 10),
+            cb = ct + ch,
+            cr = cl + c.clientWidth;
+
+        if (el.offsetHeight > ch || t < ct) {
+            c.scrollTop = t;
+        }
+        else if (b > cb) {
+            c.scrollTop = b-ch;
+        }
+        
+        c.scrollTop = c.scrollTop;
+
+        if (hscroll !== false) {
+            if (el.offsetWidth > c.clientWidth || l < cl) {
+                c.scrollLeft = l;
+            }
+            else if (r > cr) {
+                c.scrollLeft = r - c.clientWidth;
+            }
+            c.scrollLeft = c.scrollLeft;
+        }
+        return this;
+    },
+
+    
+    scrollChildIntoView : function(child, hscroll) {
+        Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
+    },
+    
+    
+     scroll : function(direction, distance, animate) {
+        if (!this.isScrollable()) {
+            return false;
+        }
+        var el = this.dom,
+            l = el.scrollLeft, t = el.scrollTop,
+            w = el.scrollWidth, h = el.scrollHeight,
+            cw = el.clientWidth, ch = el.clientHeight,
+            scrolled = false, v,
+            hash = {
+                l: Math.min(l + distance, w-cw),
+                r: v = Math.max(l - distance, 0),
+                t: Math.max(t - distance, 0),
+                b: Math.min(t + distance, h-ch)
+            };
+            hash.d = hash.b;
+            hash.u = hash.t;
+        
+        direction = direction.substr(0, 1);
+        if ((v = hash[direction]) > -1) {
+            scrolled = true;
+            this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
+        }
+        return scrolled;
+    }
+});
+Ext.Element.addMethods(
+    function() {
+        var VISIBILITY      = "visibility",
+            DISPLAY         = "display",
+            HIDDEN          = "hidden",
+            NONE            = "none",
+            XMASKED         = "x-masked",
+            XMASKEDRELATIVE = "x-masked-relative",
+            data            = Ext.Element.data;
+
+        return {
+            
+            isVisible : function(deep) {
+                var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
+                    p   = this.dom.parentNode;
+                
+                if (deep !== true || !vis) {
+                    return vis;
+                }
+                
+                while (p && !(/^body/i.test(p.tagName))) {
+                    if (!Ext.fly(p, '_isVisible').isVisible()) {
+                        return false;
+                    }
+                    p = p.parentNode;
+                }
+                return true;
+            },
+
+            
+            isDisplayed : function() {
+                return !this.isStyle(DISPLAY, NONE);
+            },
+
+            
+            enableDisplayMode : function(display) {
+                this.setVisibilityMode(Ext.Element.DISPLAY);
+                
+                if (!Ext.isEmpty(display)) {
+                    data(this.dom, 'originalDisplay', display);
+                }
+                
+                return this;
+            },
+
+            
+            mask : function(msg, msgCls) {
+                var me  = this,
+                    dom = me.dom,
+                    dh  = Ext.DomHelper,
+                    EXTELMASKMSG = "ext-el-mask-msg",
+                    el,
+                    mask;
+
+                if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) {
+                    me.addClass(XMASKEDRELATIVE);
+                }
+                if (el = data(dom, 'maskMsg')) {
+                    el.remove();
+                }
+                if (el = data(dom, 'mask')) {
+                    el.remove();
+                }
+
+                mask = dh.append(dom, {cls : "ext-el-mask"}, true);
+                data(dom, 'mask', mask);
+
+                me.addClass(XMASKED);
+                mask.setDisplayed(true);
+                
+                if (typeof msg == 'string') {
+                    var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
+                    data(dom, 'maskMsg', mm);
+                    mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
+                    mm.dom.firstChild.innerHTML = msg;
+                    mm.setDisplayed(true);
+                    mm.center(me);
+                }
+                
+                
+                if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
+                    mask.setSize(undefined, me.getHeight());
+                }
+                
+                return mask;
+            },
+
+            
+            unmask : function() {
+                var me      = this,
+                    dom     = me.dom,
+                    mask    = data(dom, 'mask'),
+                    maskMsg = data(dom, 'maskMsg');
+
+                if (mask) {
+                    if (maskMsg) {
+                        maskMsg.remove();
+                        data(dom, 'maskMsg', undefined);
+                    }
+                    
+                    mask.remove();
+                    data(dom, 'mask', undefined);
+                    me.removeClass([XMASKED, XMASKEDRELATIVE]);
+                }
+            },
+
+            
+            isMasked : function() {
+                var m = data(this.dom, 'mask');
+                return m && m.isVisible();
+            },
+
+            
+            createShim : function() {
+                var el = document.createElement('iframe'),
+                    shim;
+                
+                el.frameBorder = '0';
+                el.className = 'ext-shim';
+                el.src = Ext.SSL_SECURE_URL;
+                shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
+                shim.autoBoxAdjust = false;
+                return shim;
+            }
+        };
+    }()
+);
+Ext.Element.addMethods({
+    
+    addKeyListener : function(key, fn, scope){
+        var config;
+        if(typeof key != 'object' || Ext.isArray(key)){
+            config = {
+                key: key,
+                fn: fn,
+                scope: scope
+            };
+        }else{
+            config = {
+                key : key.key,
+                shift : key.shift,
+                ctrl : key.ctrl,
+                alt : key.alt,
+                fn: fn,
+                scope: scope
+            };
+        }
+        return new Ext.KeyMap(this, config);
+    },
+
+    
+    addKeyMap : function(config){
+        return new Ext.KeyMap(this, config);
+    }
+});
+
+
+
+Ext.CompositeElementLite.importElementMethods();
+Ext.apply(Ext.CompositeElementLite.prototype, {
+    addElements : function(els, root){
+        if(!els){
+            return this;
+        }
+        if(typeof els == "string"){
+            els = Ext.Element.selectorFunction(els, root);
+        }
+        var yels = this.elements;
+        Ext.each(els, function(e) {
+            yels.push(Ext.get(e));
+        });
+        return this;
+    },
+
+    
+    first : function(){
+        return this.item(0);
+    },
+
+    
+    last : function(){
+        return this.item(this.getCount()-1);
+    },
+
+    
+    contains : function(el){
+        return this.indexOf(el) != -1;
+    },
+
+    
+    removeElement : function(keys, removeDom){
+        var me = this,
+            els = this.elements,
+            el;
+        Ext.each(keys, function(val){
+            if ((el = (els[val] || els[val = me.indexOf(val)]))) {
+                if(removeDom){
+                    if(el.dom){
+                        el.remove();
+                    }else{
+                        Ext.removeNode(el);
+                    }
+                }
+                els.splice(val, 1);
+            }
+        });
+        return this;
+    }
+});
+
+Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
+    
+    constructor : function(els, root){
+        this.elements = [];
+        this.add(els, root);
+    },
+    
+    
+    getElement : function(el){
+        
+        return el;
+    },
+    
+    
+    transformElement : function(el){
+        return Ext.get(el);
+    }
+
+    
+
+    
+
+    
+});
+
+
+Ext.Element.select = function(selector, unique, root){
+    var els;
+    if(typeof selector == "string"){
+        els = Ext.Element.selectorFunction(selector, root);
+    }else if(selector.length !== undefined){
+        els = selector;
+    }else{
+        throw "Invalid selector";
+    }
+
+    return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
+};
+
+
+Ext.select = Ext.Element.select;
+Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
+function() {
+    var BEFOREUPDATE = "beforeupdate",
+        UPDATE = "update",
+        FAILURE = "failure";
+
+    
+    function processSuccess(response){
+        var me = this;
+        me.transaction = null;
+        if (response.argument.form && response.argument.reset) {
+            try { 
+                response.argument.form.reset();
+            } catch(e){}
+        }
+        if (me.loadScripts) {
+            me.renderer.render(me.el, response, me,
+               updateComplete.createDelegate(me, [response]));
+        } else {
+            me.renderer.render(me.el, response, me);
+            updateComplete.call(me, response);
+        }
+    }
+
+    
+    function updateComplete(response, type, success){
+        this.fireEvent(type || UPDATE, this.el, response);
+        if(Ext.isFunction(response.argument.callback)){
+            response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
+        }
+    }
+
+    
+    function processFailure(response){
+        updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
+    }
+
+    return {
+        constructor: function(el, forceNew){
+            var me = this;
+            el = Ext.get(el);
+            if(!forceNew && el.updateManager){
+                return el.updateManager;
+            }
+            
+            me.el = el;
+            
+            me.defaultUrl = null;
+
+            me.addEvents(
+                
+                BEFOREUPDATE,
+                
+                UPDATE,
+                
+                FAILURE
+            );
+
+            Ext.apply(me, Ext.Updater.defaults);
+            
+            
+            
+            
+            
+            
+
+            
+            me.transaction = null;
+            
+            me.refreshDelegate = me.refresh.createDelegate(me);
+            
+            me.updateDelegate = me.update.createDelegate(me);
+            
+            me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
+
+            
+            me.renderer = me.renderer || me.getDefaultRenderer();
+
+            Ext.Updater.superclass.constructor.call(me);
+        },
+
+        
+        setRenderer : function(renderer){
+            this.renderer = renderer;
+        },
+
+        
+        getRenderer : function(){
+           return this.renderer;
+        },
+
+        
+        getDefaultRenderer: function() {
+            return new Ext.Updater.BasicRenderer();
+        },
+
+        
+        setDefaultUrl : function(defaultUrl){
+            this.defaultUrl = defaultUrl;
+        },
+
+        
+        getEl : function(){
+            return this.el;
+        },
+
+        
+        update : function(url, params, callback, discardUrl){
+            var me = this,
+                cfg,
+                callerScope;
+
+            if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
+                if(Ext.isObject(url)){ 
+                    cfg = url;
+                    url = cfg.url;
+                    params = params || cfg.params;
+                    callback = callback || cfg.callback;
+                    discardUrl = discardUrl || cfg.discardUrl;
+                    callerScope = cfg.scope;
+                    if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
+                    if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
+                    if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
+                    if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
+                }
+                me.showLoading();
+
+                if(!discardUrl){
+                    me.defaultUrl = url;
+                }
+                if(Ext.isFunction(url)){
+                    url = url.call(me);
+                }
+
+                var o = Ext.apply({}, {
+                    url : url,
+                    params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
+                    success: processSuccess,
+                    failure: processFailure,
+                    scope: me,
+                    callback: undefined,
+                    timeout: (me.timeout*1000),
+                    disableCaching: me.disableCaching,
+                    argument: {
+                        "options": cfg,
+                        "url": url,
+                        "form": null,
+                        "callback": callback,
+                        "scope": callerScope || window,
+                        "params": params
+                    }
+                }, cfg);
+
+                me.transaction = Ext.Ajax.request(o);
+            }
+        },
+
+        
+        formUpdate : function(form, url, reset, callback){
+            var me = this;
+            if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
+                if(Ext.isFunction(url)){
+                    url = url.call(me);
+                }
+                form = Ext.getDom(form);
+                me.transaction = Ext.Ajax.request({
+                    form: form,
+                    url:url,
+                    success: processSuccess,
+                    failure: processFailure,
+                    scope: me,
+                    timeout: (me.timeout*1000),
+                    argument: {
+                        "url": url,
+                        "form": form,
+                        "callback": callback,
+                        "reset": reset
+                    }
+                });
+                me.showLoading.defer(1, me);
+            }
+        },
+
+        
+        startAutoRefresh : function(interval, url, params, callback, refreshNow){
+            var me = this;
+            if(refreshNow){
+                me.update(url || me.defaultUrl, params, callback, true);
+            }
+            if(me.autoRefreshProcId){
+                clearInterval(me.autoRefreshProcId);
+            }
+            me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
+        },
+
+        
+        stopAutoRefresh : function(){
+            if(this.autoRefreshProcId){
+                clearInterval(this.autoRefreshProcId);
+                delete this.autoRefreshProcId;
+            }
+        },
+
+        
+        isAutoRefreshing : function(){
+           return !!this.autoRefreshProcId;
+        },
+
+        
+        showLoading : function(){
+            if(this.showLoadIndicator){
+                this.el.dom.innerHTML = this.indicatorText;
+            }
+        },
+
+        
+        abort : function(){
+            if(this.transaction){
+                Ext.Ajax.abort(this.transaction);
+            }
+        },
+
+        
+        isUpdating : function(){
+            return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
+        },
+
+        
+        refresh : function(callback){
+            if(this.defaultUrl){
+                this.update(this.defaultUrl, null, callback, true);
+            }
+        }
+    };
+}());
+
+
+Ext.Updater.defaults = {
+   
+    timeout : 30,
+    
+    disableCaching : false,
+    
+    showLoadIndicator : true,
+    
+    indicatorText : '<div class="loading-indicator">Loading...</div>',
+     
+    loadScripts : false,
+    
+    sslBlankUrl : Ext.SSL_SECURE_URL
+};
+
+
+
+Ext.Updater.updateElement = function(el, url, params, options){
+    var um = Ext.get(el).getUpdater();
+    Ext.apply(um, options);
+    um.update(url, params, options ? options.callback : null);
+};
+
+
+Ext.Updater.BasicRenderer = function(){};
+
+Ext.Updater.BasicRenderer.prototype = {
+    
+     render : function(el, response, updateManager, callback){
+        el.update(response.responseText, updateManager.loadScripts, callback);
+    }
+};
+
+
+
+(function() {
+
+
+Date.useStrict = false;
+
+
+
+
+
+function xf(format) {
+    var args = Array.prototype.slice.call(arguments, 1);
+    return format.replace(/\{(\d+)\}/g, function(m, i) {
+        return args[i];
+    });
+}
+
+
+
+Date.formatCodeToRegex = function(character, currentGroup) {
+    
+    var p = Date.parseCodes[character];
+
+    if (p) {
+      p = typeof p == 'function'? p() : p;
+      Date.parseCodes[character] = p; 
+    }
+
+    return p ? Ext.applyIf({
+      c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
+    }, p) : {
+        g:0,
+        c:null,
+        s:Ext.escapeRe(character) 
+    };
+};
+
+
+var $f = Date.formatCodeToRegex;
+
+Ext.apply(Date, {
+    
+    parseFunctions: {
+        "M$": function(input, strict) {
+            
+            
+            var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
+            var r = (input || '').match(re);
+            return r? new Date(((r[1] || '') + r[2]) * 1) : null;
+        }
+    },
+    parseRegexes: [],
+
+    
+    formatFunctions: {
+        "M$": function() {
+            
+            return '\\/Date(' + this.getTime() + ')\\/';
+        }
+    },
+
+    y2kYear : 50,
 
-                try{
-                    doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
-                    if(doc){
-                        if(doc.body){
-                            if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ 
-                                r.responseText = firstChild.value;
-                            }else{
-                                r.responseText = doc.body.innerHTML;
-                            }
-                        }
+    
+    MILLI : "ms",
+
+    
+    SECOND : "s",
+
+    
+    MINUTE : "mi",
+
+    
+    HOUR : "h",
+
+    
+    DAY : "d",
+
+    
+    MONTH : "mo",
+
+    
+    YEAR : "y",
+
+    
+    defaults: {},
+
+    
+    dayNames : [
+        "Sunday",
+        "Monday",
+        "Tuesday",
+        "Wednesday",
+        "Thursday",
+        "Friday",
+        "Saturday"
+    ],
+
+    
+    monthNames : [
+        "January",
+        "February",
+        "March",
+        "April",
+        "May",
+        "June",
+        "July",
+        "August",
+        "September",
+        "October",
+        "November",
+        "December"
+    ],
+
+    
+    monthNumbers : {
+        Jan:0,
+        Feb:1,
+        Mar:2,
+        Apr:3,
+        May:4,
+        Jun:5,
+        Jul:6,
+        Aug:7,
+        Sep:8,
+        Oct:9,
+        Nov:10,
+        Dec:11
+    },
+
+    
+    getShortMonthName : function(month) {
+        return Date.monthNames[month].substring(0, 3);
+    },
+
+    
+    getShortDayName : function(day) {
+        return Date.dayNames[day].substring(0, 3);
+    },
+
+    
+    getMonthNumber : function(name) {
+        
+        return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
+    },
+
+    
+    formatCodes : {
+        d: "String.leftPad(this.getDate(), 2, '0')",
+        D: "Date.getShortDayName(this.getDay())", 
+        j: "this.getDate()",
+        l: "Date.dayNames[this.getDay()]",
+        N: "(this.getDay() ? this.getDay() : 7)",
+        S: "this.getSuffix()",
+        w: "this.getDay()",
+        z: "this.getDayOfYear()",
+        W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
+        F: "Date.monthNames[this.getMonth()]",
+        m: "String.leftPad(this.getMonth() + 1, 2, '0')",
+        M: "Date.getShortMonthName(this.getMonth())", 
+        n: "(this.getMonth() + 1)",
+        t: "this.getDaysInMonth()",
+        L: "(this.isLeapYear() ? 1 : 0)",
+        o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
+        Y: "String.leftPad(this.getFullYear(), 4, '0')",
+        y: "('' + this.getFullYear()).substring(2, 4)",
+        a: "(this.getHours() < 12 ? 'am' : 'pm')",
+        A: "(this.getHours() < 12 ? 'AM' : 'PM')",
+        g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
+        G: "this.getHours()",
+        h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
+        H: "String.leftPad(this.getHours(), 2, '0')",
+        i: "String.leftPad(this.getMinutes(), 2, '0')",
+        s: "String.leftPad(this.getSeconds(), 2, '0')",
+        u: "String.leftPad(this.getMilliseconds(), 3, '0')",
+        O: "this.getGMTOffset()",
+        P: "this.getGMTOffset(true)",
+        T: "this.getTimezone()",
+        Z: "(this.getTimezoneOffset() * -60)",
+
+        c: function() { 
+            for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
+                var e = c.charAt(i);
+                code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); 
+            }
+            return code.join(" + ");
+        },
+        
+
+        U: "Math.round(this.getTime() / 1000)"
+    },
+
+    
+    isValid : function(y, m, d, h, i, s, ms) {
+        
+        h = h || 0;
+        i = i || 0;
+        s = s || 0;
+        ms = ms || 0;
+
+        
+        var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);
+
+        return y == dt.getFullYear() &&
+            m == dt.getMonth() + 1 &&
+            d == dt.getDate() &&
+            h == dt.getHours() &&
+            i == dt.getMinutes() &&
+            s == dt.getSeconds() &&
+            ms == dt.getMilliseconds();
+    },
+
+    
+    parseDate : function(input, format, strict) {
+        var p = Date.parseFunctions;
+        if (p[format] == null) {
+            Date.createParser(format);
+        }
+        return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
+    },
+
+    
+    getFormatCode : function(character) {
+        var f = Date.formatCodes[character];
+
+        if (f) {
+          f = typeof f == 'function'? f() : f;
+          Date.formatCodes[character] = f; 
+        }
+
+        
+        return f || ("'" + String.escape(character) + "'");
+    },
+
+    
+    createFormat : function(format) {
+        var code = [],
+            special = false,
+            ch = '';
+
+        for (var i = 0; i < format.length; ++i) {
+            ch = format.charAt(i);
+            if (!special && ch == "\\") {
+                special = true;
+            } else if (special) {
+                special = false;
+                code.push("'" + String.escape(ch) + "'");
+            } else {
+                code.push(Date.getFormatCode(ch));
+            }
+        }
+        Date.formatFunctions[format] = new Function("return " + code.join('+'));
+    },
+
+    
+    createParser : function() {
+        var code = [
+            "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
+                "def = Date.defaults,",
+                "results = String(input).match(Date.parseRegexes[{0}]);", 
+
+            "if(results){",
+                "{1}",
+
+                "if(u != null){", 
+                    "v = new Date(u * 1000);", 
+                "}else{",
+                    
+                    
+                    
+                    "dt = (new Date()).clearTime();",
+
+                    
+                    "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
+                    "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
+                    "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
+
+                    
+                    "h  = Ext.num(h, Ext.num(def.h, dt.getHours()));",
+                    "i  = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
+                    "s  = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
+                    "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
+
+                    "if(z >= 0 && y >= 0){",
+                        
                         
-                        r.responseXML = doc.XMLDocument || doc;
-                    }
-                }
-                catch(e) {}
 
-                Ext.EventManager.removeListener(frame, LOAD, cb, me);
+                        
+                        
+                        "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
 
-                me.fireEvent(REQUESTCOMPLETE, me, r, o);
+                        
+                        "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
+                    "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", 
+                        "v = null;", 
+                    "}else{",
+                        
+                        
+                        "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
+                    "}",
+                "}",
+            "}",
 
-                function runCallback(fn, scope, args){
-                    if(Ext.isFunction(fn)){
-                        fn.apply(scope, args);
-                    }
-                }
+            "if(v){",
+                
+                "if(zz != null){",
+                    
+                    "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
+                "}else if(o){",
+                    
+                    "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
+                "}",
+            "}",
 
-                runCallback(o.success, o.scope, [r, o]);
-                runCallback(o.callback, o.scope, [o, true, r]);
+            "return v;"
+        ].join('\n');
 
-                if(!me.debugUploads){
-                    setTimeout(function(){Ext.removeNode(frame);}, 100);
+        return function(format) {
+            var regexNum = Date.parseRegexes.length,
+                currentGroup = 1,
+                calc = [],
+                regex = [],
+                special = false,
+                ch = "",
+                i = 0,
+                obj,
+                last;
+
+            for (; i < format.length; ++i) {
+                ch = format.charAt(i);
+                if (!special && ch == "\\") {
+                    special = true;
+                } else if (special) {
+                    special = false;
+                    regex.push(String.escape(ch));
+                } else {
+                    obj = $f(ch, currentGroup);
+                    currentGroup += obj.g;
+                    regex.push(obj.s);
+                    if (obj.g && obj.c) {
+                        if (obj.calcLast) {
+                            last = obj.c;
+                        } else {
+                            calc.push(obj.c);
+                        }
+                    }
                 }
             }
+            
+            if (last) {
+                calc.push(last);
+            }
 
-            Ext.EventManager.on(frame, LOAD, cb, this);
-            form.submit();
+            Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
+            Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
+        };
+    }(),
 
-            Ext.fly(form).set(buf);
-            Ext.each(hiddens, function(h) {
-                Ext.removeNode(h);
-            });
+    
+    parseCodes : {
+        
+        d: {
+            g:1,
+            c:"d = parseInt(results[{0}], 10);\n",
+            s:"(\\d{2})" 
+        },
+        j: {
+            g:1,
+            c:"d = parseInt(results[{0}], 10);\n",
+            s:"(\\d{1,2})" 
+        },
+        D: function() {
+            for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); 
+            return {
+                g:0,
+                c:null,
+                s:"(?:" + a.join("|") +")"
+            };
+        },
+        l: function() {
+            return {
+                g:0,
+                c:null,
+                s:"(?:" + Date.dayNames.join("|") + ")"
+            };
+        },
+        N: {
+            g:0,
+            c:null,
+            s:"[1-7]" 
+        },
+        S: {
+            g:0,
+            c:null,
+            s:"(?:st|nd|rd|th)"
+        },
+        w: {
+            g:0,
+            c:null,
+            s:"[0-6]" 
+        },
+        z: {
+            g:1,
+            c:"z = parseInt(results[{0}], 10);\n",
+            s:"(\\d{1,3})" 
+        },
+        W: {
+            g:0,
+            c:null,
+            s:"(?:\\d{2})" 
+        },
+        F: function() {
+            return {
+                g:1,
+                c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", 
+                s:"(" + Date.monthNames.join("|") + ")"
+            };
+        },
+        M: function() {
+            for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); 
+            return Ext.applyIf({
+                s:"(" + a.join("|") + ")"
+            }, $f("F"));
+        },
+        m: {
+            g:1,
+            c:"m = parseInt(results[{0}], 10) - 1;\n",
+            s:"(\\d{2})" 
+        },
+        n: {
+            g:1,
+            c:"m = parseInt(results[{0}], 10) - 1;\n",
+            s:"(\\d{1,2})" 
+        },
+        t: {
+            g:0,
+            c:null,
+            s:"(?:\\d{2})" 
+        },
+        L: {
+            g:0,
+            c:null,
+            s:"(?:1|0)"
+        },
+        o: function() {
+            return $f("Y");
+        },
+        Y: {
+            g:1,
+            c:"y = parseInt(results[{0}], 10);\n",
+            s:"(\\d{4})" 
+        },
+        y: {
+            g:1,
+            c:"var ty = parseInt(results[{0}], 10);\n"
+                + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", 
+            s:"(\\d{1,2})"
+        },
+        
+        a: function(){
+            return $f("A");
+        },
+        A: {
+            
+            calcLast: true,
+            g:1,
+            c:"if (/(am)/i.test(results[{0}])) {\n"
+                + "if (!h || h == 12) { h = 0; }\n"
+                + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
+            s:"(AM|PM|am|pm)"
+        },
+        g: function() {
+            return $f("G");
+        },
+        G: {
+            g:1,
+            c:"h = parseInt(results[{0}], 10);\n",
+            s:"(\\d{1,2})" 
+        },
+        h: function() {
+            return $f("H");
+        },
+        H: {
+            g:1,
+            c:"h = parseInt(results[{0}], 10);\n",
+            s:"(\\d{2})" 
+        },
+        i: {
+            g:1,
+            c:"i = parseInt(results[{0}], 10);\n",
+            s:"(\\d{2})" 
+        },
+        s: {
+            g:1,
+            c:"s = parseInt(results[{0}], 10);\n",
+            s:"(\\d{2})" 
+        },
+        u: {
+            g:1,
+            c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
+            s:"(\\d+)" 
+        },
+        O: {
+            g:1,
+            c:[
+                "o = results[{0}];",
+                "var sn = o.substring(0,1),", 
+                    "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", 
+                    "mn = o.substring(3,5) % 60;", 
+                "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" 
+            ].join("\n"),
+            s: "([+\-]\\d{4})" 
+        },
+        P: {
+            g:1,
+            c:[
+                "o = results[{0}];",
+                "var sn = o.substring(0,1),", 
+                    "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", 
+                    "mn = o.substring(4,6) % 60;", 
+                "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" 
+            ].join("\n"),
+            s: "([+\-]\\d{2}:\\d{2})" 
+        },
+        T: {
+            g:0,
+            c:null,
+            s:"[A-Z]{1,4}" 
+        },
+        Z: {
+            g:1,
+            c:"zz = results[{0}] * 1;\n" 
+                  + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
+            s:"([+\-]?\\d{1,5})" 
+        },
+        c: function() {
+            var calc = [],
+                arr = [
+                    $f("Y", 1), 
+                    $f("m", 2), 
+                    $f("d", 3), 
+                    $f("h", 4), 
+                    $f("i", 5), 
+                    $f("s", 6), 
+                    {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, 
+                    {c:[ 
+                        "if(results[8]) {", 
+                            "if(results[8] == 'Z'){",
+                                "zz = 0;", 
+                            "}else if (results[8].indexOf(':') > -1){",
+                                $f("P", 8).c, 
+                            "}else{",
+                                $f("O", 8).c, 
+                            "}",
+                        "}"
+                    ].join('\n')}
+                ];
+
+            for (var i = 0, l = arr.length; i < l; ++i) {
+                calc.push(arr[i].c);
+            }
+
+            return {
+                g:1,
+                c:calc.join(""),
+                s:[
+                    arr[0].s, 
+                    "(?:", "-", arr[1].s, 
+                        "(?:", "-", arr[2].s, 
+                            "(?:",
+                                "(?:T| )?", 
+                                arr[3].s, ":", arr[4].s,  
+                                "(?::", arr[5].s, ")?", 
+                                "(?:(?:\\.|,)(\\d+))?", 
+                                "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", 
+                            ")?",
+                        ")?",
+                    ")?"
+                ].join("")
+            };
+        },
+        U: {
+            g:1,
+            c:"u = parseInt(results[{0}], 10);\n",
+            s:"(-?\\d+)" 
         }
-    });
-})();
+    }
+});
 
+}());
 
-Ext.Ajax = new Ext.data.Connection({
-    
-    
-    
-    
-    
+Ext.apply(Date.prototype, {
     
+    dateFormat : function(format) {
+        if (Date.formatFunctions[format] == null) {
+            Date.createFormat(format);
+        }
+        return Date.formatFunctions[format].call(this);
+    },
 
     
+    getTimezone : function() {
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
+    },
 
     
+    getGMTOffset : function(colon) {
+        return (this.getTimezoneOffset() > 0 ? "-" : "+")
+            + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
+            + (colon ? ":" : "")
+            + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
+    },
+
     
+    getDayOfYear: function() {
+        var num = 0,
+            d = this.clone(),
+            m = this.getMonth(),
+            i;
+
+        for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
+            num += d.getDaysInMonth();
+        }
+        return num + this.getDate() - 1;
+    },
+
     
+    getWeekOfYear : function() {
+        
+        var ms1d = 864e5, 
+            ms7d = 7 * ms1d; 
+
+        return function() { 
+            var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, 
+                AWN = Math.floor(DC3 / 7), 
+                Wyr = new Date(AWN * ms7d).getUTCFullYear();
+
+            return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
+        };
+    }(),
+
     
+    isLeapYear : function() {
+        var year = this.getFullYear();
+        return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
+    },
+
     
+    getFirstDayOfMonth : function() {
+        var day = (this.getDay() - (this.getDate() - 1)) % 7;
+        return (day < 0) ? (day + 7) : day;
+    },
+
     
+    getLastDayOfMonth : function() {
+        return this.getLastDateOfMonth().getDay();
+    },
+
 
     
-    autoAbort : false,
+    getFirstDateOfMonth : function() {
+        return new Date(this.getFullYear(), this.getMonth(), 1);
+    },
 
     
-    serializeForm : function(form){
-        return Ext.lib.Ajax.serializeForm(form);
-    }
-});
+    getLastDateOfMonth : function() {
+        return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
+    },
 
-Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable, 
-function() {
-       var BEFOREUPDATE = "beforeupdate",
-               UPDATE = "update",
-               FAILURE = "failure";
-               
-       
-    function processSuccess(response){     
-           var me = this;
-        me.transaction = null;
-        if (response.argument.form && response.argument.reset) {
-            try { 
-                response.argument.form.reset();
-            } catch(e){}
-        }
-        if (me.loadScripts) {
-            me.renderer.render(me.el, response, me,
-               updateComplete.createDelegate(me, [response]));
-        } else {
-            me.renderer.render(me.el, response, me);
-            updateComplete.call(me, response);
-        }
-    }
     
+    getDaysInMonth: function() {
+        var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+        return function() { 
+            var m = this.getMonth();
+
+            return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
+        };
+    }(),
+
     
-    function updateComplete(response, type, success){
-        this.fireEvent(type || UPDATE, this.el, response);
-        if(Ext.isFunction(response.argument.callback)){
-            response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
+    getSuffix : function() {
+        switch (this.getDate()) {
+            case 1:
+            case 21:
+            case 31:
+                return "st";
+            case 2:
+            case 22:
+                return "nd";
+            case 3:
+            case 23:
+                return "rd";
+            default:
+                return "th";
         }
-    }
+    },
 
     
-    function processFailure(response){             
-        updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
-    }
-           
-       return {
-           constructor: function(el, forceNew){
-                   var me = this;
-               el = Ext.get(el);
-               if(!forceNew && el.updateManager){
-                   return el.updateManager;
-               }
-               
-               me.el = el;
-               
-               me.defaultUrl = null;
-       
-               me.addEvents(
-                   
-                   BEFOREUPDATE,
-                   
-                   UPDATE,
-                   
-                   FAILURE
-               );
-       
-               Ext.apply(me, Ext.Updater.defaults);
-               
-               
-               
-               
-               
-               
-       
-               
-               me.transaction = null;
-               
-               me.refreshDelegate = me.refresh.createDelegate(me);
-               
-               me.updateDelegate = me.update.createDelegate(me);
-               
-               me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);     
-               
-                       
-               me.renderer = me.renderer || me.getDefaultRenderer();
-               
-               Ext.Updater.superclass.constructor.call(me);
-           },
+    clone : function() {
+        return new Date(this.getTime());
+    },
+
+    
+    isDST : function() {
         
-               
-           setRenderer : function(renderer){
-               this.renderer = renderer;
-           },  
         
-           
-           getRenderer : function(){
-              return this.renderer;
-           },
+        return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
+    },
 
-           
-           getDefaultRenderer: function() {
-               return new Ext.Updater.BasicRenderer();
-           },
-                
-           
-           setDefaultUrl : function(defaultUrl){
-               this.defaultUrl = defaultUrl;
-           },
-        
-           
-           getEl : function(){
-               return this.el;
-           },
-       
-               
-           update : function(url, params, callback, discardUrl){
-                   var me = this,
-                       cfg, 
-                       callerScope;
-                       
-               if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){               
-                   if(Ext.isObject(url)){ 
-                       cfg = url;
-                       url = cfg.url;
-                       params = params || cfg.params;
-                       callback = callback || cfg.callback;
-                       discardUrl = discardUrl || cfg.discardUrl;
-                       callerScope = cfg.scope;                        
-                       if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
-                       if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
-                       if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
-                       if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
-                   }
-                   me.showLoading();
-       
-                   if(!discardUrl){
-                       me.defaultUrl = url;
-                   }
-                   if(Ext.isFunction(url)){
-                       url = url.call(me);
-                   }
-       
-                   var o = Ext.apply({}, {
-                       url : url,
-                       params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
-                       success: processSuccess,
-                       failure: processFailure,
-                       scope: me,
-                       callback: undefined,
-                       timeout: (me.timeout*1000),
-                       disableCaching: me.disableCaching,
-                       argument: {
-                           "options": cfg,
-                           "url": url,
-                           "form": null,
-                           "callback": callback,
-                           "scope": callerScope || window,
-                           "params": params
-                       }
-                   }, cfg);
-       
-                   me.transaction = Ext.Ajax.request(o);
-               }
-           },          
+    
+    clearTime : function(clone) {
+        if (clone) {
+            return this.clone().clearTime();
+        }
 
-               
-           formUpdate : function(form, url, reset, callback){
-                   var me = this;
-               if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
-                   if(Ext.isFunction(url)){
-                       url = url.call(me);
-                   }
-                   form = Ext.getDom(form)
-                   me.transaction = Ext.Ajax.request({
-                       form: form,
-                       url:url,
-                       success: processSuccess,
-                       failure: processFailure,
-                       scope: me,
-                       timeout: (me.timeout*1000),
-                       argument: {
-                           "url": url,
-                           "form": form,
-                           "callback": callback,
-                           "reset": reset
-                       }
-                   });
-                   me.showLoading.defer(1, me);
-               }
-           },
-                       
-           
-           startAutoRefresh : function(interval, url, params, callback, refreshNow){
-                   var me = this;
-               if(refreshNow){
-                   me.update(url || me.defaultUrl, params, callback, true);
-               }
-               if(me.autoRefreshProcId){
-                   clearInterval(me.autoRefreshProcId);
-               }
-               me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
-           },
-       
-           
-           stopAutoRefresh : function(){
-               if(this.autoRefreshProcId){
-                   clearInterval(this.autoRefreshProcId);
-                   delete this.autoRefreshProcId;
-               }
-           },
-       
-           
-           isAutoRefreshing : function(){
-              return !!this.autoRefreshProcId;
-           },
-       
-           
-           showLoading : function(){
-               if(this.showLoadIndicator){
-               this.el.dom.innerHTML = this.indicatorText;
-               }
-           },
-       
-           
-           abort : function(){
-               if(this.transaction){
-                   Ext.Ajax.abort(this.transaction);
-               }
-           },
-       
-           
-           isUpdating : function(){        
-               return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;        
-           },
-           
-           
-           refresh : function(callback){
-               if(this.defaultUrl){
-                       this.update(this.defaultUrl, null, callback, true);
-               }
-           }
-    }
-}());
+        
+        var d = this.getDate();
 
+        
+        this.setHours(0);
+        this.setMinutes(0);
+        this.setSeconds(0);
+        this.setMilliseconds(0);
 
-Ext.Updater.defaults = {
-   
-    timeout : 30,    
-    
-    disableCaching : false,
-    
-    showLoadIndicator : true,
-    
-    indicatorText : '<div class="loading-indicator">Loading...</div>',
-     
-    loadScripts : false,
-    
-    sslBlankUrl : Ext.SSL_SECURE_URL      
-};
+        if (this.getDate() != d) { 
+            
+            
 
+            
+            for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
 
+            this.setDate(d);
+            this.setHours(c.getHours());
+        }
 
-Ext.Updater.updateElement = function(el, url, params, options){
-    var um = Ext.get(el).getUpdater();
-    Ext.apply(um, options);
-    um.update(url, params, options ? options.callback : null);
-};
+        return this;
+    },
 
+    
+    add : function(interval, value) {
+        var d = this.clone();
+        if (!interval || value === 0) return d;
 
-Ext.Updater.BasicRenderer = function(){};
+        switch(interval.toLowerCase()) {
+            case Date.MILLI:
+                d.setMilliseconds(this.getMilliseconds() + value);
+                break;
+            case Date.SECOND:
+                d.setSeconds(this.getSeconds() + value);
+                break;
+            case Date.MINUTE:
+                d.setMinutes(this.getMinutes() + value);
+                break;
+            case Date.HOUR:
+                d.setHours(this.getHours() + value);
+                break;
+            case Date.DAY:
+                d.setDate(this.getDate() + value);
+                break;
+            case Date.MONTH:
+                var day = this.getDate();
+                if (day > 28) {
+                    day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
+                }
+                d.setDate(day);
+                d.setMonth(this.getMonth() + value);
+                break;
+            case Date.YEAR:
+                d.setFullYear(this.getFullYear() + value);
+                break;
+        }
+        return d;
+    },
 
-Ext.Updater.BasicRenderer.prototype = {
     
-     render : function(el, response, updateManager, callback){      
-        el.update(response.responseText, updateManager.loadScripts, callback);
+    between : function(start, end) {
+        var t = this.getTime();
+        return start.getTime() <= t && t <= end.getTime();
     }
-};
+});
 
 
 
-(function() {
+Date.prototype.format = Date.prototype.dateFormat;
 
 
-Date.useStrict = false;
 
+if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
+    Ext.apply(Date.prototype, {
+        _xMonth : Date.prototype.setMonth,
+        _xDate  : Date.prototype.setDate,
 
+        
+        
+        setMonth : function(num) {
+            if (num <= -1) {
+                var n = Math.ceil(-num),
+                    back_year = Math.ceil(n / 12),
+                    month = (n % 12) ? 12 - n % 12 : 0;
 
+                this.setFullYear(this.getFullYear() - back_year);
 
+                return this._xMonth(month);
+            } else {
+                return this._xMonth(num);
+            }
+        },
 
-function xf(format) {
-    var args = Array.prototype.slice.call(arguments, 1);
-    return format.replace(/\{(\d+)\}/g, function(m, i) {
-        return args[i];
+        
+        
+        
+        setDate : function(d) {
+            
+            
+            return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
+        }
     });
 }
 
 
 
-Date.formatCodeToRegex = function(character, currentGroup) {
-    
-    var p = Date.parseCodes[character];
 
-    if (p) {
-      p = typeof p == 'function'? p() : p;
-      Date.parseCodes[character] = p; 
-    }
 
-    return p? Ext.applyIf({
-      c: p.c? xf(p.c, currentGroup || "{0}") : p.c
-    }, p) : {
-        g:0,
-        c:null,
-        s:Ext.escapeRe(character) 
+Ext.util.MixedCollection = function(allowFunctions, keyFn){
+    this.items = [];
+    this.map = {};
+    this.keys = [];
+    this.length = 0;
+    this.addEvents(
+        
+        'clear',
+        
+        'add',
+        
+        'replace',
+        
+        'remove',
+        'sort'
+    );
+    this.allowFunctions = allowFunctions === true;
+    if(keyFn){
+        this.getKey = keyFn;
     }
-}
+    Ext.util.MixedCollection.superclass.constructor.call(this);
+};
 
+Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
 
-var $f = Date.formatCodeToRegex;
+    
+    allowFunctions : false,
 
-Ext.apply(Date, {
     
-    parseFunctions: {
-        "M$": function(input, strict) {
-            
-            
-            var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
-            var r = (input || '').match(re);
-            return r? new Date(((r[1] || '') + r[2]) * 1) : null;
+    add : function(key, o){
+        if(arguments.length == 1){
+            o = arguments[0];
+            key = this.getKey(o);
+        }
+        if(typeof key != 'undefined' && key !== null){
+            var old = this.map[key];
+            if(typeof old != 'undefined'){
+                return this.replace(key, o);
+            }
+            this.map[key] = o;
         }
+        this.length++;
+        this.items.push(o);
+        this.keys.push(key);
+        this.fireEvent('add', this.length-1, o, key);
+        return o;
     },
-    parseRegexes: [],
 
     
-    formatFunctions: {
-        "M$": function() {
-            
-            return '\\/Date(' + this.getTime() + ')\\/';
+    getKey : function(o){
+         return o.id;
+    },
+
+    
+    replace : function(key, o){
+        if(arguments.length == 1){
+            o = arguments[0];
+            key = this.getKey(o);
+        }
+        var old = this.map[key];
+        if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
+             return this.add(key, o);
         }
+        var index = this.indexOfKey(key);
+        this.items[index] = o;
+        this.map[key] = o;
+        this.fireEvent('replace', key, old, o);
+        return o;
     },
 
-    y2kYear : 50,
+    
+    addAll : function(objs){
+        if(arguments.length > 1 || Ext.isArray(objs)){
+            var args = arguments.length > 1 ? arguments : objs;
+            for(var i = 0, len = args.length; i < len; i++){
+                this.add(args[i]);
+            }
+        }else{
+            for(var key in objs){
+                if(this.allowFunctions || typeof objs[key] != 'function'){
+                    this.add(key, objs[key]);
+                }
+            }
+        }
+    },
 
     
-    MILLI : "ms",
+    each : function(fn, scope){
+        var items = [].concat(this.items); 
+        for(var i = 0, len = items.length; i < len; i++){
+            if(fn.call(scope || items[i], items[i], i, len) === false){
+                break;
+            }
+        }
+    },
 
     
-    SECOND : "s",
+    eachKey : function(fn, scope){
+        for(var i = 0, len = this.keys.length; i < len; i++){
+            fn.call(scope || window, this.keys[i], this.items[i], i, len);
+        }
+    },
 
     
-    MINUTE : "mi",
+    find : function(fn, scope){
+        for(var i = 0, len = this.items.length; i < len; i++){
+            if(fn.call(scope || window, this.items[i], this.keys[i])){
+                return this.items[i];
+            }
+        }
+        return null;
+    },
+
+    
+    insert : function(index, key, o){
+        if(arguments.length == 2){
+            o = arguments[1];
+            key = this.getKey(o);
+        }
+        if(this.containsKey(key)){
+            this.suspendEvents();
+            this.removeKey(key);
+            this.resumeEvents();
+        }
+        if(index >= this.length){
+            return this.add(key, o);
+        }
+        this.length++;
+        this.items.splice(index, 0, o);
+        if(typeof key != 'undefined' && key !== null){
+            this.map[key] = o;
+        }
+        this.keys.splice(index, 0, key);
+        this.fireEvent('add', index, o, key);
+        return o;
+    },
+
+    
+    remove : function(o){
+        return this.removeAt(this.indexOf(o));
+    },
+
+    
+    removeAt : function(index){
+        if(index < this.length && index >= 0){
+            this.length--;
+            var o = this.items[index];
+            this.items.splice(index, 1);
+            var key = this.keys[index];
+            if(typeof key != 'undefined'){
+                delete this.map[key];
+            }
+            this.keys.splice(index, 1);
+            this.fireEvent('remove', o, key);
+            return o;
+        }
+        return false;
+    },
 
     
-    HOUR : "h",
+    removeKey : function(key){
+        return this.removeAt(this.indexOfKey(key));
+    },
 
     
-    DAY : "d",
+    getCount : function(){
+        return this.length;
+    },
 
     
-    MONTH : "mo",
+    indexOf : function(o){
+        return this.items.indexOf(o);
+    },
 
     
-    YEAR : "y",
+    indexOfKey : function(key){
+        return this.keys.indexOf(key);
+    },
 
     
-    defaults: {},
+    item : function(key){
+        var mk = this.map[key],
+            item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
+        return typeof item != 'function' || this.allowFunctions ? item : null; 
+    },
 
     
-    dayNames : [
-        "Sunday",
-        "Monday",
-        "Tuesday",
-        "Wednesday",
-        "Thursday",
-        "Friday",
-        "Saturday"
-    ],
+    itemAt : function(index){
+        return this.items[index];
+    },
 
     
-    monthNames : [
-        "January",
-        "February",
-        "March",
-        "April",
-        "May",
-        "June",
-        "July",
-        "August",
-        "September",
-        "October",
-        "November",
-        "December"
-    ],
+    key : function(key){
+        return this.map[key];
+    },
 
     
-    monthNumbers : {
-        Jan:0,
-        Feb:1,
-        Mar:2,
-        Apr:3,
-        May:4,
-        Jun:5,
-        Jul:6,
-        Aug:7,
-        Sep:8,
-        Oct:9,
-        Nov:10,
-        Dec:11
+    contains : function(o){
+        return this.indexOf(o) != -1;
     },
 
     
-    getShortMonthName : function(month) {
-        return Date.monthNames[month].substring(0, 3);
+    containsKey : function(key){
+        return typeof this.map[key] != 'undefined';
     },
 
     
-    getShortDayName : function(day) {
-        return Date.dayNames[day].substring(0, 3);
+    clear : function(){
+        this.length = 0;
+        this.items = [];
+        this.keys = [];
+        this.map = {};
+        this.fireEvent('clear');
     },
 
     
-    getMonthNumber : function(name) {
-        
-        return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
+    first : function(){
+        return this.items[0];
     },
 
     
-    formatCodes : {
-        d: "String.leftPad(this.getDate(), 2, '0')",
-        D: "Date.getShortDayName(this.getDay())", 
-        j: "this.getDate()",
-        l: "Date.dayNames[this.getDay()]",
-        N: "(this.getDay() ? this.getDay() : 7)",
-        S: "this.getSuffix()",
-        w: "this.getDay()",
-        z: "this.getDayOfYear()",
-        W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
-        F: "Date.monthNames[this.getMonth()]",
-        m: "String.leftPad(this.getMonth() + 1, 2, '0')",
-        M: "Date.getShortMonthName(this.getMonth())", 
-        n: "(this.getMonth() + 1)",
-        t: "this.getDaysInMonth()",
-        L: "(this.isLeapYear() ? 1 : 0)",
-        o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
-        Y: "this.getFullYear()",
-        y: "('' + this.getFullYear()).substring(2, 4)",
-        a: "(this.getHours() < 12 ? 'am' : 'pm')",
-        A: "(this.getHours() < 12 ? 'AM' : 'PM')",
-        g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
-        G: "this.getHours()",
-        h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
-        H: "String.leftPad(this.getHours(), 2, '0')",
-        i: "String.leftPad(this.getMinutes(), 2, '0')",
-        s: "String.leftPad(this.getSeconds(), 2, '0')",
-        u: "String.leftPad(this.getMilliseconds(), 3, '0')",
-        O: "this.getGMTOffset()",
-        P: "this.getGMTOffset(true)",
-        T: "this.getTimezone()",
-        Z: "(this.getTimezoneOffset() * -60)",
-
-        c: function() { 
-            for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
-                var e = c.charAt(i);
-                code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); 
-            }
-            return code.join(" + ");
-        },
-        
-
-        U: "Math.round(this.getTime() / 1000)"
+    last : function(){
+        return this.items[this.length-1];
     },
 
     
-    isValid : function(y, m, d, h, i, s, ms) {
-        
-        h = h || 0;
-        i = i || 0;
-        s = s || 0;
-        ms = ms || 0;
+    _sort : function(property, dir, fn){
+        var i, len,
+            dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
 
-        var dt = new Date(y, m - 1, d, h, i, s, ms);
+            
+            c     = [],
+            keys  = this.keys,
+            items = this.items;
 
-        return y == dt.getFullYear() &&
-            m == dt.getMonth() + 1 &&
-            d == dt.getDate() &&
-            h == dt.getHours() &&
-            i == dt.getMinutes() &&
-            s == dt.getSeconds() &&
-            ms == dt.getMilliseconds();
-    },
+        
+        fn = fn || function(a, b) {
+            return a - b;
+        };
 
-    
-    parseDate : function(input, format, strict) {
-        var p = Date.parseFunctions;
-        if (p[format] == null) {
-            Date.createParser(format);
+        
+        for(i = 0, len = items.length; i < len; i++){
+            c[c.length] = {
+                key  : keys[i],
+                value: items[i],
+                index: i
+            };
         }
-        return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
-    },
 
-    
-    getFormatCode : function(character) {
-        var f = Date.formatCodes[character];
+        
+        c.sort(function(a, b){
+            var v = fn(a[property], b[property]) * dsc;
+            if(v === 0){
+                v = (a.index < b.index ? -1 : 1);
+            }
+            return v;
+        });
 
-        if (f) {
-          f = typeof f == 'function'? f() : f;
-          Date.formatCodes[character] = f; 
+        
+        for(i = 0, len = c.length; i < len; i++){
+            items[i] = c[i].value;
+            keys[i]  = c[i].key;
         }
 
-        
-        return f || ("'" + String.escape(character) + "'");
+        this.fireEvent('sort', this);
     },
 
     
-    createFormat : function(format) {
-        var code = [],
-            special = false,
-            ch = '';
-
-        for (var i = 0; i < format.length; ++i) {
-            ch = format.charAt(i);
-            if (!special && ch == "\\") {
-                special = true;
-            } else if (special) {
-                special = false;
-                code.push("'" + String.escape(ch) + "'");
-            } else {
-                code.push(Date.getFormatCode(ch))
-            }
-        }
-        Date.formatFunctions[format] = new Function("return " + code.join('+'));
+    sort : function(dir, fn){
+        this._sort('value', dir, fn);
     },
 
     
-    createParser : function() {
-        var code = [
-            "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
-                "def = Date.defaults,",
-                "results = String(input).match(Date.parseRegexes[{0}]);", 
-
-            "if(results){",
-                "{1}",
-
-                "if(u != null){", 
-                    "v = new Date(u * 1000);", 
-                "}else{",
-                    
-                    
-                    
-                    "dt = (new Date()).clearTime();",
-
-                    
-                    "y = y >= 0? y : Ext.num(def.y, dt.getFullYear());",
-                    "m = m >= 0? m : Ext.num(def.m - 1, dt.getMonth());",
-                    "d = d >= 0? d : Ext.num(def.d, dt.getDate());",
+    reorder: function(mapping) {
+        this.suspendEvents();
 
-                    
-                    "h  = h || Ext.num(def.h, dt.getHours());",
-                    "i  = i || Ext.num(def.i, dt.getMinutes());",
-                    "s  = s || Ext.num(def.s, dt.getSeconds());",
-                    "ms = ms || Ext.num(def.ms, dt.getMilliseconds());",
+        var items = this.items,
+            index = 0,
+            length = items.length,
+            order = [],
+            remaining = [],
+            oldIndex;
 
-                    "if(z >= 0 && y >= 0){",
-                        
-                        
+        
+        for (oldIndex in mapping) {
+            order[mapping[oldIndex]] = items[oldIndex];
+        }
 
-                        
-                        "v = new Date(y, 0, 1, h, i, s, ms);",
+        for (index = 0; index < length; index++) {
+            if (mapping[index] == undefined) {
+                remaining.push(items[index]);
+            }
+        }
 
-                        
-                        "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
-                    "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", 
-                        "v = null;", 
-                    "}else{",
-                        
-                        "v = new Date(y, m, d, h, i, s, ms);",
-                    "}",
-                "}",
-            "}",
+        for (index = 0; index < length; index++) {
+            if (order[index] == undefined) {
+                order[index] = remaining.shift();
+            }
+        }
 
-            "if(v){",
-                
-                "if(zz != null){",
-                    
-                    "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
-                "}else if(o){",
-                    
-                    "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
-                "}",
-            "}",
+        this.clear();
+        this.addAll(order);
 
-            "return v;"
-        ].join('\n');
+        this.resumeEvents();
+        this.fireEvent('sort', this);
+    },
 
-        return function(format) {
-            var regexNum = Date.parseRegexes.length,
-                currentGroup = 1,
-                calc = [],
-                regex = [],
-                special = false,
-                ch = "";
+    
+    keySort : function(dir, fn){
+        this._sort('key', dir, fn || function(a, b){
+            var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
+            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+        });
+    },
 
-            for (var i = 0; i < format.length; ++i) {
-                ch = format.charAt(i);
-                if (!special && ch == "\\") {
-                    special = true;
-                } else if (special) {
-                    special = false;
-                    regex.push(String.escape(ch));
-                } else {
-                    var obj = $f(ch, currentGroup);
-                    currentGroup += obj.g;
-                    regex.push(obj.s);
-                    if (obj.g && obj.c) {
-                        calc.push(obj.c);
-                    }
-                }
+    
+    getRange : function(start, end){
+        var items = this.items;
+        if(items.length < 1){
+            return [];
+        }
+        start = start || 0;
+        end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
+        var i, r = [];
+        if(start <= end){
+            for(i = start; i <= end; i++) {
+                r[r.length] = items[i];
+            }
+        }else{
+            for(i = start; i >= end; i--) {
+                r[r.length] = items[i];
             }
+        }
+        return r;
+    },
 
-            Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", "i");
-            Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
+    
+    filter : function(property, value, anyMatch, caseSensitive){
+        if(Ext.isEmpty(value, false)){
+            return this.clone();
         }
-    }(),
+        value = this.createValueMatcher(value, anyMatch, caseSensitive);
+        return this.filterBy(function(o){
+            return o && value.test(o[property]);
+        });
+    },
 
     
-    parseCodes : {
-        
-        d: {
-            g:1,
-            c:"d = parseInt(results[{0}], 10);\n",
-            s:"(\\d{2})" 
-        },
-        j: {
-            g:1,
-            c:"d = parseInt(results[{0}], 10);\n",
-            s:"(\\d{1,2})" 
-        },
-        D: function() {
-            for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); 
-            return {
-                g:0,
-                c:null,
-                s:"(?:" + a.join("|") +")"
-            }
-        },
-        l: function() {
-            return {
-                g:0,
-                c:null,
-                s:"(?:" + Date.dayNames.join("|") + ")"
-            }
-        },
-        N: {
-            g:0,
-            c:null,
-            s:"[1-7]" 
-        },
-        S: {
-            g:0,
-            c:null,
-            s:"(?:st|nd|rd|th)"
-        },
-        w: {
-            g:0,
-            c:null,
-            s:"[0-6]" 
-        },
-        z: {
-            g:1,
-            c:"z = parseInt(results[{0}], 10);\n",
-            s:"(\\d{1,3})" 
-        },
-        W: {
-            g:0,
-            c:null,
-            s:"(?:\\d{2})" 
-        },
-        F: function() {
-            return {
-                g:1,
-                c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", 
-                s:"(" + Date.monthNames.join("|") + ")"
+    filterBy : function(fn, scope){
+        var r = new Ext.util.MixedCollection();
+        r.getKey = this.getKey;
+        var k = this.keys, it = this.items;
+        for(var i = 0, len = it.length; i < len; i++){
+            if(fn.call(scope||this, it[i], k[i])){
+                r.add(k[i], it[i]);
             }
-        },
-        M: function() {
-            for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); 
-            return Ext.applyIf({
-                s:"(" + a.join("|") + ")"
-            }, $f("F"));
-        },
-        m: {
-            g:1,
-            c:"m = parseInt(results[{0}], 10) - 1;\n",
-            s:"(\\d{2})" 
-        },
-        n: {
-            g:1,
-            c:"m = parseInt(results[{0}], 10) - 1;\n",
-            s:"(\\d{1,2})" 
-        },
-        t: {
-            g:0,
-            c:null,
-            s:"(?:\\d{2})" 
-        },
-        L: {
-            g:0,
-            c:null,
-            s:"(?:1|0)"
-        },
-        o: function() {
-            return $f("Y");
-        },
-        Y: {
-            g:1,
-            c:"y = parseInt(results[{0}], 10);\n",
-            s:"(\\d{4})" 
-        },
-        y: {
-            g:1,
-            c:"var ty = parseInt(results[{0}], 10);\n"
-                + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", 
-            s:"(\\d{1,2})"
-        },
-        a: {
-            g:1,
-            c:"if (results[{0}] == 'am') {\n"
-                + "if (!h || h == 12) { h = 0; }\n"
-                + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
-            s:"(am|pm)"
-        },
-        A: {
-            g:1,
-            c:"if (results[{0}] == 'AM') {\n"
-                + "if (!h || h == 12) { h = 0; }\n"
-                + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
-            s:"(AM|PM)"
-        },
-        g: function() {
-            return $f("G");
-        },
-        G: {
-            g:1,
-            c:"h = parseInt(results[{0}], 10);\n",
-            s:"(\\d{1,2})" 
-        },
-        h: function() {
-            return $f("H");
-        },
-        H: {
-            g:1,
-            c:"h = parseInt(results[{0}], 10);\n",
-            s:"(\\d{2})" 
-        },
-        i: {
-            g:1,
-            c:"i = parseInt(results[{0}], 10);\n",
-            s:"(\\d{2})" 
-        },
-        s: {
-            g:1,
-            c:"s = parseInt(results[{0}], 10);\n",
-            s:"(\\d{2})" 
-        },
-        u: {
-            g:1,
-            c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
-            s:"(\\d+)" 
-        },
-        O: {
-            g:1,
-            c:[
-                "o = results[{0}];",
-                "var sn = o.substring(0,1),", 
-                    "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", 
-                    "mn = o.substring(3,5) % 60;", 
-                "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" 
-            ].join("\n"),
-            s: "([+\-]\\d{4})" 
-        },
-        P: {
-            g:1,
-            c:[
-                "o = results[{0}];",
-                "var sn = o.substring(0,1),", 
-                    "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", 
-                    "mn = o.substring(4,6) % 60;", 
-                "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" 
-            ].join("\n"),
-            s: "([+\-]\\d{2}:\\d{2})" 
-        },
-        T: {
-            g:0,
-            c:null,
-            s:"[A-Z]{1,4}" 
-        },
-        Z: {
-            g:1,
-            c:"zz = results[{0}] * 1;\n" 
-                  + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
-            s:"([+\-]?\\d{1,5})" 
-        },
-        c: function() {
-            var calc = [],
-                arr = [
-                    $f("Y", 1), 
-                    $f("m", 2), 
-                    $f("d", 3), 
-                    $f("h", 4), 
-                    $f("i", 5), 
-                    $f("s", 6), 
-                    {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, 
-                    {c:[ 
-                        "if(results[8]) {", 
-                            "if(results[8] == 'Z'){",
-                                "zz = 0;", 
-                            "}else if (results[8].indexOf(':') > -1){",
-                                $f("P", 8).c, 
-                            "}else{",
-                                $f("O", 8).c, 
-                            "}",
-                        "}"
-                    ].join('\n')}
-                ];
+        }
+        return r;
+    },
+
+    
+    findIndex : function(property, value, start, anyMatch, caseSensitive){
+        if(Ext.isEmpty(value, false)){
+            return -1;
+        }
+        value = this.createValueMatcher(value, anyMatch, caseSensitive);
+        return this.findIndexBy(function(o){
+            return o && value.test(o[property]);
+        }, null, start);
+    },
 
-            for (var i = 0, l = arr.length; i < l; ++i) {
-                calc.push(arr[i].c);
+    
+    findIndexBy : function(fn, scope, start){
+        var k = this.keys, it = this.items;
+        for(var i = (start||0), len = it.length; i < len; i++){
+            if(fn.call(scope||this, it[i], k[i])){
+                return i;
             }
+        }
+        return -1;
+    },
 
-            return {
-                g:1,
-                c:calc.join(""),
-                s:[
-                    arr[0].s, 
-                    "(?:", "-", arr[1].s, 
-                        "(?:", "-", arr[2].s, 
-                            "(?:",
-                                "(?:T| )?", 
-                                arr[3].s, ":", arr[4].s,  
-                                "(?::", arr[5].s, ")?", 
-                                "(?:(?:\\.|,)(\\d+))?", 
-                                "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", 
-                            ")?",
-                        ")?",
-                    ")?"
-                ].join("")
+    
+    createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
+        if (!value.exec) { 
+            var er = Ext.escapeRe;
+            value = String(value);
+
+            if (anyMatch === true) {
+                value = er(value);
+            } else {
+                value = '^' + er(value);
+                if (exactMatch === true) {
+                    value += '$';
+                }
             }
-        },
-        U: {
-            g:1,
-            c:"u = parseInt(results[{0}], 10);\n",
-            s:"(-?\\d+)" 
+            value = new RegExp(value, caseSensitive ? '' : 'i');
+         }
+         return value;
+    },
+
+    
+    clone : function(){
+        var r = new Ext.util.MixedCollection();
+        var k = this.keys, it = this.items;
+        for(var i = 0, len = it.length; i < len; i++){
+            r.add(k[i], it[i]);
         }
+        r.getKey = this.getKey;
+        return r;
     }
 });
 
-}());
+Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
 
-Ext.apply(Date.prototype, {
+Ext.AbstractManager = Ext.extend(Object, {
+    typeName: 'type',
     
-    dateFormat : function(format) {
-        if (Date.formatFunctions[format] == null) {
-            Date.createFormat(format);
+    constructor: function(config) {
+        Ext.apply(this, config || {});
+        
+        
+        this.all = new Ext.util.MixedCollection();
+        
+        this.types = {};
+    },
+    
+    
+    get : function(id){
+        return this.all.get(id);
+    },
+    
+    
+    register: function(item) {
+        this.all.add(item);
+    },
+    
+    
+    unregister: function(item) {
+        this.all.remove(item);        
+    },
+    
+    
+    registerType : function(type, cls){
+        this.types[type] = cls;
+        cls[this.typeName] = type;
+    },
+    
+    
+    isRegistered : function(type){
+        return this.types[type] !== undefined;    
+    },
+    
+    
+    create: function(config, defaultType) {
+        var type        = config[this.typeName] || config.type || defaultType,
+            Constructor = this.types[type];
+        
+        if (Constructor == undefined) {
+            throw new Error(String.format("The '{0}' type has not been registered with this manager", type));
         }
-        return Date.formatFunctions[format].call(this);
+        
+        return new Constructor(config);
     },
-
     
-    getTimezone : function() {
+    
+    onAvailable : function(id, fn, scope){
+        var all = this.all;
         
+        all.on("add", function(index, o){
+            if (o.id == id) {
+                fn.call(scope || o, o);
+                all.un("add", fn, scope);
+            }
+        });
+    }
+});
+Ext.util.Format = function() {
+    var trimRe         = /^\s+|\s+$/g,
+        stripTagsRE    = /<\/?[^>]+>/gi,
+        stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
+        nl2brRe        = /\r?\n/g;
+
+    return {
         
+        ellipsis : function(value, len, word) {
+            if (value && value.length > len) {
+                if (word) {
+                    var vs    = value.substr(0, len - 2),
+                        index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
+                    if (index == -1 || index < (len - 15)) {
+                        return value.substr(0, len - 3) + "...";
+                    } else {
+                        return vs.substr(0, index) + "...";
+                    }
+                } else {
+                    return value.substr(0, len - 3) + "...";
+                }
+            }
+            return value;
+        },
+
         
+        undef : function(value) {
+            return value !== undefined ? value : "";
+        },
+
         
+        defaultValue : function(value, defaultValue) {
+            return value !== undefined && value !== '' ? value : defaultValue;
+        },
+
         
+        htmlEncode : function(value) {
+            return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
+        },
+
         
+        htmlDecode : function(value) {
+            return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
+        },
+
         
+        trim : function(value) {
+            return String(value).replace(trimRe, "");
+        },
+
         
+        substr : function(value, start, length) {
+            return String(value).substr(start, length);
+        },
+
         
+        lowercase : function(value) {
+            return String(value).toLowerCase();
+        },
+
         
+        uppercase : function(value) {
+            return String(value).toUpperCase();
+        },
+
         
+        capitalize : function(value) {
+            return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
+        },
+
         
-        return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
-    },
+        call : function(value, fn) {
+            if (arguments.length > 2) {
+                var args = Array.prototype.slice.call(arguments, 2);
+                args.unshift(value);
+                return eval(fn).apply(window, args);
+            } else {
+                return eval(fn).call(window, value);
+            }
+        },
 
-    
-    getGMTOffset : function(colon) {
-        return (this.getTimezoneOffset() > 0 ? "-" : "+")
-            + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
-            + (colon ? ":" : "")
-            + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
-    },
+        
+        usMoney : function(v) {
+            v = (Math.round((v-0)*100))/100;
+            v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
+            v = String(v);
+            var ps = v.split('.'),
+                whole = ps[0],
+                sub = ps[1] ? '.'+ ps[1] : '.00',
+                r = /(\d+)(\d{3})/;
+            while (r.test(whole)) {
+                whole = whole.replace(r, '$1' + ',' + '$2');
+            }
+            v = whole + sub;
+            if (v.charAt(0) == '-') {
+                return '-$' + v.substr(1);
+            }
+            return "$" +  v;
+        },
 
-    
-    getDayOfYear: function() {
-        var num = 0,
-            d = this.clone(),
-            m = this.getMonth(),
-            i;
+        
+        date : function(v, format) {
+            if (!v) {
+                return "";
+            }
+            if (!Ext.isDate(v)) {
+                v = new Date(Date.parse(v));
+            }
+            return v.dateFormat(format || "m/d/Y");
+        },
 
-        for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
-            num += d.getDaysInMonth();
-        }
-        return num + this.getDate() - 1;
-    },
+        
+        dateRenderer : function(format) {
+            return function(v) {
+                return Ext.util.Format.date(v, format);
+            };
+        },
 
-    
-    getWeekOfYear : function() {
         
-        var ms1d = 864e5, 
-            ms7d = 7 * ms1d; 
+        stripTags : function(v) {
+            return !v ? v : String(v).replace(stripTagsRE, "");
+        },
 
-        return function() { 
-            var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, 
-                AWN = Math.floor(DC3 / 7), 
-                Wyr = new Date(AWN * ms7d).getUTCFullYear();
+        
+        stripScripts : function(v) {
+            return !v ? v : String(v).replace(stripScriptsRe, "");
+        },
 
-            return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
-        }
-    }(),
+        
+        fileSize : function(size) {
+            if (size < 1024) {
+                return size + " bytes";
+            } else if (size < 1048576) {
+                return (Math.round(((size*10) / 1024))/10) + " KB";
+            } else {
+                return (Math.round(((size*10) / 1048576))/10) + " MB";
+            }
+        },
 
-    
-    isLeapYear : function() {
-        var year = this.getFullYear();
-        return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
-    },
+        
+        math : function(){
+            var fns = {};
+            
+            return function(v, a){
+                if (!fns[a]) {
+                    fns[a] = new Function('v', 'return v ' + a + ';');
+                }
+                return fns[a](v);
+            };
+        }(),
 
-    
-    getFirstDayOfMonth : function() {
-        var day = (this.getDay() - (this.getDate() - 1)) % 7;
-        return (day < 0) ? (day + 7) : day;
-    },
+        
+        round : function(value, precision) {
+            var result = Number(value);
+            if (typeof precision == 'number') {
+                precision = Math.pow(10, precision);
+                result = Math.round(value * precision) / precision;
+            }
+            return result;
+        },
 
-    
-    getLastDayOfMonth : function() {
-        return this.getLastDateOfMonth().getDay();
-    },
+        
+        number: function(v, format) {
+            if (!format) {
+                return v;
+            }
+            v = Ext.num(v, NaN);
+            if (isNaN(v)) {
+                return '';
+            }
+            var comma = ',',
+                dec   = '.',
+                i18n  = false,
+                neg   = v < 0;
 
+            v = Math.abs(v);
+            if (format.substr(format.length - 2) == '/i') {
+                format = format.substr(0, format.length - 2);
+                i18n   = true;
+                comma  = '.';
+                dec    = ',';
+            }
 
-    
-    getFirstDateOfMonth : function() {
-        return new Date(this.getFullYear(), this.getMonth(), 1);
-    },
+            var hasComma = format.indexOf(comma) != -1,
+                psplit   = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
 
-    
-    getLastDateOfMonth : function() {
-        return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
-    },
+            if (1 < psplit.length) {
+                v = v.toFixed(psplit[1].length);
+            } else if(2 < psplit.length) {
+                throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
+            } else {
+                v = v.toFixed(0);
+            }
 
-    
-    getDaysInMonth: function() {
-        var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+            var fnum = v.toString();
 
-        return function() { 
-            var m = this.getMonth();
+            psplit = fnum.split('.');
 
-            return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
-        }
-    }(),
+            if (hasComma) {
+                var cnum = psplit[0], 
+                    parr = [], 
+                    j    = cnum.length, 
+                    m    = Math.floor(j / 3),
+                    n    = cnum.length % 3 || 3,
+                    i;
 
-    
-    getSuffix : function() {
-        switch (this.getDate()) {
-            case 1:
-            case 21:
-            case 31:
-                return "st";
-            case 2:
-            case 22:
-                return "nd";
-            case 3:
-            case 23:
-                return "rd";
-            default:
-                return "th";
-        }
-    },
+                for (i = 0; i < j; i += n) {
+                    if (i != 0) {
+                        n = 3;
+                    }
+                    
+                    parr[parr.length] = cnum.substr(i, n);
+                    m -= 1;
+                }
+                fnum = parr.join(comma);
+                if (psplit[1]) {
+                    fnum += dec + psplit[1];
+                }
+            } else {
+                if (psplit[1]) {
+                    fnum = psplit[0] + dec + psplit[1];
+                }
+            }
 
-    
-    clone : function() {
-        return new Date(this.getTime());
-    },
+            return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
+        },
 
-    
-    isDST : function() {
         
+        numberRenderer : function(format) {
+            return function(v) {
+                return Ext.util.Format.number(v, format);
+            };
+        },
+
         
-        return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
-    },
+        plural : function(v, s, p) {
+            return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
+        },
 
-    
-    clearTime : function(clone) {
-        if (clone) {
-            return this.clone().clearTime();
+        
+        nl2br : function(v) {
+            return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
         }
+    };
+}();
 
-        
-        var d = this.getDate();
+Ext.XTemplate = function(){
+    Ext.XTemplate.superclass.constructor.apply(this, arguments);
 
-        
-        this.setHours(0);
-        this.setMinutes(0);
-        this.setSeconds(0);
-        this.setMilliseconds(0);
+    var me = this,
+        s = me.html,
+        re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
+        nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
+        ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
+        execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
+        m,
+        id = 0,
+        tpls = [],
+        VALUES = 'values',
+        PARENT = 'parent',
+        XINDEX = 'xindex',
+        XCOUNT = 'xcount',
+        RETURN = 'return ',
+        WITHVALUES = 'with(values){ ';
 
-        if (this.getDate() != d) { 
-            
-            
+    s = ['<tpl>', s, '</tpl>'].join('');
 
-            
-            for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
+    while((m = s.match(re))){
+        var m2 = m[0].match(nameRe),
+            m3 = m[0].match(ifRe),
+            m4 = m[0].match(execRe),
+            exp = null,
+            fn = null,
+            exec = null,
+            name = m2 && m2[1] ? m2[1] : '';
 
-            this.setDate(d);
-            this.setHours(c.getHours());
-        }
+       if (m3) {
+           exp = m3 && m3[1] ? m3[1] : null;
+           if(exp){
+               fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
+           }
+       }
+       if (m4) {
+           exp = m4 && m4[1] ? m4[1] : null;
+           if(exp){
+               exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
+           }
+       }
+       if(name){
+           switch(name){
+               case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
+               case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
+               default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
+           }
+       }
+       tpls.push({
+            id: id,
+            target: name,
+            exec: exec,
+            test: fn,
+            body: m[1]||''
+        });
+       s = s.replace(m[0], '{xtpl'+ id + '}');
+       ++id;
+    }
+    for(var i = tpls.length-1; i >= 0; --i){
+        me.compileTpl(tpls[i]);
+    }
+    me.master = tpls[tpls.length-1];
+    me.tpls = tpls;
+};
+Ext.extend(Ext.XTemplate, Ext.Template, {
+    
+    re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
+    
+    codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
 
-        return this;
+    
+    applySubTemplate : function(id, values, parent, xindex, xcount){
+        var me = this,
+            len,
+            t = me.tpls[id],
+            vs,
+            buf = [];
+        if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
+            (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
+            return '';
+        }
+        vs = t.target ? t.target.call(me, values, parent) : values;
+        len = vs.length;
+        parent = t.target ? values : parent;
+        if(t.target && Ext.isArray(vs)){
+            for(var i = 0, len = vs.length; i < len; i++){
+                buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
+            }
+            return buf.join('');
+        }
+        return t.compiled.call(me, vs, parent, xindex, xcount);
     },
 
     
-    add : function(interval, value) {
-        var d = this.clone();
-        if (!interval || value === 0) return d;
+    compileTpl : function(tpl){
+        var fm = Ext.util.Format,
+            useF = this.disableFormats !== true,
+            sep = Ext.isGecko ? "+" : ",",
+            body;
 
-        switch(interval.toLowerCase()) {
-            case Date.MILLI:
-                d.setMilliseconds(this.getMilliseconds() + value);
-                break;
-            case Date.SECOND:
-                d.setSeconds(this.getSeconds() + value);
-                break;
-            case Date.MINUTE:
-                d.setMinutes(this.getMinutes() + value);
-                break;
-            case Date.HOUR:
-                d.setHours(this.getHours() + value);
-                break;
-            case Date.DAY:
-                d.setDate(this.getDate() + value);
-                break;
-            case Date.MONTH:
-                var day = this.getDate();
-                if (day > 28) {
-                    day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
+        function fn(m, name, format, args, math){
+            if(name.substr(0, 4) == 'xtpl'){
+                return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
+            }
+            var v;
+            if(name === '.'){
+                v = 'values';
+            }else if(name === '#'){
+                v = 'xindex';
+            }else if(name.indexOf('.') != -1){
+                v = name;
+            }else{
+                v = "values['" + name + "']";
+            }
+            if(math){
+                v = '(' + v + math + ')';
+            }
+            if (format && useF) {
+                args = args ? ',' + args : "";
+                if(format.substr(0, 5) != "this."){
+                    format = "fm." + format + '(';
+                }else{
+                    format = 'this.call("'+ format.substr(5) + '", ';
+                    args = ", values";
                 }
-                d.setDate(day);
-                d.setMonth(this.getMonth() + value);
-                break;
-            case Date.YEAR:
-                d.setFullYear(this.getFullYear() + value);
-                break;
+            } else {
+                args= ''; format = "("+v+" === undefined ? '' : ";
+            }
+            return "'"+ sep + format + v + args + ")"+sep+"'";
         }
-        return d;
+
+        function codeFn(m, code){
+            
+            return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
+        }
+
+        
+        if(Ext.isGecko){
+            body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
+                   tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
+                    "';};";
+        }else{
+            body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
+            body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
+            body.push("'].join('');};");
+            body = body.join('');
+        }
+        eval(body);
+        return this;
     },
 
     
-    between : function(start, end) {
-        var t = this.getTime();
-        return start.getTime() <= t && t <= end.getTime();
-    }
-});
+    applyTemplate : function(values){
+        return this.master.compiled.call(this, values, {}, 1, 1);
+    },
 
+    
+    compile : function(){return this;}
 
+    
+    
+    
 
-Date.prototype.format = Date.prototype.dateFormat;
+});
 
+Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
 
 
-if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
-    Ext.apply(Date.prototype, {
-        _xMonth : Date.prototype.setMonth,
-        _xDate  : Date.prototype.setDate,
+Ext.XTemplate.from = function(el){
+    el = Ext.getDom(el);
+    return new Ext.XTemplate(el.value || el.innerHTML);
+};
 
-        
-        
-        setMonth : function(num) {
-            if (num <= -1) {
-                var n = Math.ceil(-num),
-                    back_year = Math.ceil(n / 12),
-                    month = (n % 12) ? 12 - n % 12 : 0;
+Ext.util.CSS = function(){
+       var rules = null;
+       var doc = document;
 
-                this.setFullYear(this.getFullYear() - back_year);
+    var camelRe = /(-[a-z])/gi;
+    var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
 
-                return this._xMonth(month);
-            } else {
-                return this._xMonth(num);
-            }
-        },
+   return {
+   
+   createStyleSheet : function(cssText, id){
+       var ss;
+       var head = doc.getElementsByTagName("head")[0];
+       var rules = doc.createElement("style");
+       rules.setAttribute("type", "text/css");
+       if(id){
+           rules.setAttribute("id", id);
+       }
+       if(Ext.isIE){
+           head.appendChild(rules);
+           ss = rules.styleSheet;
+           ss.cssText = cssText;
+       }else{
+           try{
+                rules.appendChild(doc.createTextNode(cssText));
+           }catch(e){
+               rules.cssText = cssText;
+           }
+           head.appendChild(rules);
+           ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
+       }
+       this.cacheStyleSheet(ss);
+       return ss;
+   },
 
-        
-        
-        
-        setDate : function(d) {
-            
-            
-            return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
-        }
-    });
-}
+   
+   removeStyleSheet : function(id){
+       var existing = doc.getElementById(id);
+       if(existing){
+           existing.parentNode.removeChild(existing);
+       }
+   },
 
+   
+   swapStyleSheet : function(id, url){
+       this.removeStyleSheet(id);
+       var ss = doc.createElement("link");
+       ss.setAttribute("rel", "stylesheet");
+       ss.setAttribute("type", "text/css");
+       ss.setAttribute("id", id);
+       ss.setAttribute("href", url);
+       doc.getElementsByTagName("head")[0].appendChild(ss);
+   },
+   
+   
+   refreshCache : function(){
+       return this.getRules(true);
+   },
 
+   
+   cacheStyleSheet : function(ss){
+       if(!rules){
+           rules = {};
+       }
+       try{
+           var ssRules = ss.cssRules || ss.rules;
+           for(var j = ssRules.length-1; j >= 0; --j){
+               rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
+           }
+       }catch(e){}
+   },
+   
+   
+   getRules : function(refreshCache){
+               if(rules === null || refreshCache){
+                       rules = {};
+                       var ds = doc.styleSheets;
+                       for(var i =0, len = ds.length; i < len; i++){
+                           try{
+                       this.cacheStyleSheet(ds[i]);
+                   }catch(e){} 
+               }
+               }
+               return rules;
+       },
+       
+       
+   getRule : function(selector, refreshCache){
+               var rs = this.getRules(refreshCache);
+               if(!Ext.isArray(selector)){
+                   return rs[selector.toLowerCase()];
+               }
+               for(var i = 0; i < selector.length; i++){
+                       if(rs[selector[i]]){
+                               return rs[selector[i].toLowerCase()];
+                       }
+               }
+               return null;
+       },
+       
+       
+       
+   updateRule : function(selector, property, value){
+               if(!Ext.isArray(selector)){
+                       var rule = this.getRule(selector);
+                       if(rule){
+                               rule.style[property.replace(camelRe, camelFn)] = value;
+                               return true;
+                       }
+               }else{
+                       for(var i = 0; i < selector.length; i++){
+                               if(this.updateRule(selector[i], property, value)){
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+   };  
+}();
+Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {
+    
+    constructor : function(el, config){
+        this.el = Ext.get(el);
+        this.el.unselectable();
 
+        Ext.apply(this, config);
 
-Ext.util.MixedCollection = function(allowFunctions, keyFn){
-    this.items = [];
-    this.map = {};
-    this.keys = [];
-    this.length = 0;
-    this.addEvents(
-        
-        'clear',
+        this.addEvents(
         
-        'add',
+        "mousedown",
         
-        'replace',
+        "click",
         
-        'remove',
-        'sort'
-    );
-    this.allowFunctions = allowFunctions === true;
-    if(keyFn){
-        this.getKey = keyFn;
-    }
-    Ext.util.MixedCollection.superclass.constructor.call(this);
-};
-
-Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
-
-    
-    allowFunctions : false,
+        "mouseup"
+        );
 
-    
-    add : function(key, o){
-        if(arguments.length == 1){
-            o = arguments[0];
-            key = this.getKey(o);
+        if(!this.disabled){
+            this.disabled = true;
+            this.enable();
         }
-        if(typeof key != 'undefined' && key !== null){
-            var old = this.map[key];
-            if(typeof old != 'undefined'){
-                return this.replace(key, o);
-            }
-            this.map[key] = o;
+
+        
+        if(this.handler){
+            this.on("click", this.handler,  this.scope || this);
         }
-        this.length++;
-        this.items.push(o);
-        this.keys.push(key);
-        this.fireEvent('add', this.length-1, o, key);
-        return o;
-    },
 
-    
-    getKey : function(o){
-         return o.id;
+        Ext.util.ClickRepeater.superclass.constructor.call(this);        
     },
-
     
-    replace : function(key, o){
-        if(arguments.length == 1){
-            o = arguments[0];
-            key = this.getKey(o);
-        }
-        var old = this.map[key];
-        if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
-             return this.add(key, o);
-        }
-        var index = this.indexOfKey(key);
-        this.items[index] = o;
-        this.map[key] = o;
-        this.fireEvent('replace', key, old, o);
-        return o;
-    },
+    interval : 20,
+    delay: 250,
+    preventDefault : true,
+    stopDefault : false,
+    timer : 0,
 
     
-    addAll : function(objs){
-        if(arguments.length > 1 || Ext.isArray(objs)){
-            var args = arguments.length > 1 ? arguments : objs;
-            for(var i = 0, len = args.length; i < len; i++){
-                this.add(args[i]);
+    enable: function(){
+        if(this.disabled){
+            this.el.on('mousedown', this.handleMouseDown, this);
+            if (Ext.isIE){
+                this.el.on('dblclick', this.handleDblClick, this);
             }
-        }else{
-            for(var key in objs){
-                if(this.allowFunctions || typeof objs[key] != 'function'){
-                    this.add(key, objs[key]);
-                }
+            if(this.preventDefault || this.stopDefault){
+                this.el.on('click', this.eventOptions, this);
             }
         }
+        this.disabled = false;
     },
 
     
-    each : function(fn, scope){
-        var items = [].concat(this.items); 
-        for(var i = 0, len = items.length; i < len; i++){
-            if(fn.call(scope || items[i], items[i], i, len) === false){
-                break;
+    disable: function( force){
+        if(force || !this.disabled){
+            clearTimeout(this.timer);
+            if(this.pressClass){
+                this.el.removeClass(this.pressClass);
             }
+            Ext.getDoc().un('mouseup', this.handleMouseUp, this);
+            this.el.removeAllListeners();
         }
+        this.disabled = true;
     },
 
     
-    eachKey : function(fn, scope){
-        for(var i = 0, len = this.keys.length; i < len; i++){
-            fn.call(scope || window, this.keys[i], this.items[i], i, len);
-        }
-    },
-
-    
-    find : function(fn, scope){
-        for(var i = 0, len = this.items.length; i < len; i++){
-            if(fn.call(scope || window, this.items[i], this.keys[i])){
-                return this.items[i];
-            }
-        }
-        return null;
+    setDisabled: function(disabled){
+        this[disabled ? 'disable' : 'enable']();
     },
 
-    
-    insert : function(index, key, o){
-        if(arguments.length == 2){
-            o = arguments[1];
-            key = this.getKey(o);
-        }
-        if(this.containsKey(key)){
-            this.suspendEvents();
-            this.removeKey(key);
-            this.resumeEvents();
-        }
-        if(index >= this.length){
-            return this.add(key, o);
+    eventOptions: function(e){
+        if(this.preventDefault){
+            e.preventDefault();
         }
-        this.length++;
-        this.items.splice(index, 0, o);
-        if(typeof key != 'undefined' && key !== null){
-            this.map[key] = o;
+        if(this.stopDefault){
+            e.stopEvent();
         }
-        this.keys.splice(index, 0, key);
-        this.fireEvent('add', index, o, key);
-        return o;
     },
 
     
-    remove : function(o){
-        return this.removeAt(this.indexOf(o));
+    destroy : function() {
+        this.disable(true);
+        Ext.destroy(this.el);
+        this.purgeListeners();
     },
 
-    
-    removeAt : function(index){
-        if(index < this.length && index >= 0){
-            this.length--;
-            var o = this.items[index];
-            this.items.splice(index, 1);
-            var key = this.keys[index];
-            if(typeof key != 'undefined'){
-                delete this.map[key];
-            }
-            this.keys.splice(index, 1);
-            this.fireEvent('remove', o, key);
-            return o;
-        }
-        return false;
-    },
+    handleDblClick : function(e){
+        clearTimeout(this.timer);
+        this.el.blur();
 
-    
-    removeKey : function(key){
-        return this.removeAt(this.indexOfKey(key));
+        this.fireEvent("mousedown", this, e);
+        this.fireEvent("click", this, e);
     },
 
     
-    getCount : function(){
-        return this.length;
-    },
+    handleMouseDown : function(e){
+        clearTimeout(this.timer);
+        this.el.blur();
+        if(this.pressClass){
+            this.el.addClass(this.pressClass);
+        }
+        this.mousedownTime = new Date();
 
-    
-    indexOf : function(o){
-        return this.items.indexOf(o);
-    },
+        Ext.getDoc().on("mouseup", this.handleMouseUp, this);
+        this.el.on("mouseout", this.handleMouseOut, this);
 
-    
-    indexOfKey : function(key){
-        return this.keys.indexOf(key);
-    },
+        this.fireEvent("mousedown", this, e);
+        this.fireEvent("click", this, e);
 
-    
-    item : function(key){
-        var mk = this.map[key],
-            item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
-        return !Ext.isFunction(item) || this.allowFunctions ? item : null; 
+        
+        if (this.accelerate) {
+            this.delay = 400;
+        }
+        this.timer = this.click.defer(this.delay || this.interval, this, [e]);
     },
 
     
-    itemAt : function(index){
-        return this.items[index];
+    click : function(e){
+        this.fireEvent("click", this, e);
+        this.timer = this.click.defer(this.accelerate ?
+            this.easeOutExpo(this.mousedownTime.getElapsed(),
+                400,
+                -390,
+                12000) :
+            this.interval, this, [e]);
     },
 
-    
-    key : function(key){
-        return this.map[key];
+    easeOutExpo : function (t, b, c, d) {
+        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
     },
 
     
-    contains : function(o){
-        return this.indexOf(o) != -1;
+    handleMouseOut : function(){
+        clearTimeout(this.timer);
+        if(this.pressClass){
+            this.el.removeClass(this.pressClass);
+        }
+        this.el.on("mouseover", this.handleMouseReturn, this);
     },
 
     
-    containsKey : function(key){
-        return typeof this.map[key] != 'undefined';
+    handleMouseReturn : function(){
+        this.el.un("mouseover", this.handleMouseReturn, this);
+        if(this.pressClass){
+            this.el.addClass(this.pressClass);
+        }
+        this.click();
     },
 
     
-    clear : function(){
-        this.length = 0;
-        this.items = [];
-        this.keys = [];
-        this.map = {};
-        this.fireEvent('clear');
-    },
+    handleMouseUp : function(e){
+        clearTimeout(this.timer);
+        this.el.un("mouseover", this.handleMouseReturn, this);
+        this.el.un("mouseout", this.handleMouseOut, this);
+        Ext.getDoc().un("mouseup", this.handleMouseUp, this);
+        this.el.removeClass(this.pressClass);
+        this.fireEvent("mouseup", this, e);
+    }
+});
+Ext.KeyNav = function(el, config){
+    this.el = Ext.get(el);
+    Ext.apply(this, config);
+    if(!this.disabled){
+        this.disabled = true;
+        this.enable();
+    }
+};
 
+Ext.KeyNav.prototype = {
     
-    first : function(){
-        return this.items[0];
-    },
-
+    disabled : false,
     
-    last : function(){
-        return this.items[this.length-1];
-    },
-
+    defaultEventAction: "stopEvent",
     
-    _sort : function(property, dir, fn){
-        var i,
-            len,
-            dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
-            c = [], k = this.keys, items = this.items;
+    forceKeyDown : false,
 
-        fn = fn || function(a, b){
-            return a-b;
-        };
-        for(i = 0, len = items.length; i < len; i++){
-            c[c.length] = {key: k[i], value: items[i], index: i};
-        }
-        c.sort(function(a, b){
-            var v = fn(a[property], b[property]) * dsc;
-            if(v === 0){
-                v = (a.index < b.index ? -1 : 1);
+    
+    relay : function(e){
+        var k = e.getKey(),
+            h = this.keyToHandler[k];
+        if(h && this[h]){
+            if(this.doRelay(e, this[h], h) !== true){
+                e[this.defaultEventAction]();
             }
-            return v;
-        });
-        for(i = 0, len = c.length; i < len; i++){
-            items[i] = c[i].value;
-            k[i] = c[i].key;
         }
-        this.fireEvent('sort', this);
     },
 
     
-    sort : function(dir, fn){
-        this._sort('value', dir, fn);
+    doRelay : function(e, h, hname){
+        return h.call(this.scope || this, e, hname);
     },
 
     
-    keySort : function(dir, fn){
-        this._sort('key', dir, fn || function(a, b){
-            var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
-            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
-        });
-    },
+    enter : false,
+    left : false,
+    right : false,
+    up : false,
+    down : false,
+    tab : false,
+    esc : false,
+    pageUp : false,
+    pageDown : false,
+    del : false,
+    home : false,
+    end : false,
 
     
-    getRange : function(start, end){
-        var items = this.items;
-        if(items.length < 1){
-            return [];
-        }
-        start = start || 0;
-        end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
-        var i, r = [];
-        if(start <= end){
-            for(i = start; i <= end; i++) {
-                r[r.length] = items[i];
-            }
-        }else{
-            for(i = start; i >= end; i--) {
-                r[r.length] = items[i];
-            }
-        }
-        return r;
+    keyToHandler : {
+        37 : "left",
+        39 : "right",
+        38 : "up",
+        40 : "down",
+        33 : "pageUp",
+        34 : "pageDown",
+        46 : "del",
+        36 : "home",
+        35 : "end",
+        13 : "enter",
+        27 : "esc",
+        9  : "tab"
     },
-
     
-    filter : function(property, value, anyMatch, caseSensitive){
-        if(Ext.isEmpty(value, false)){
-            return this.clone();
+    stopKeyUp: function(e) {
+        var k = e.getKey();
+
+        if (k >= 37 && k <= 40) {
+            
+            
+            e.stopEvent();
         }
-        value = this.createValueMatcher(value, anyMatch, caseSensitive);
-        return this.filterBy(function(o){
-            return o && value.test(o[property]);
-        });
     },
-
     
-    filterBy : function(fn, scope){
-        var r = new Ext.util.MixedCollection();
-        r.getKey = this.getKey;
-        var k = this.keys, it = this.items;
-        for(var i = 0, len = it.length; i < len; i++){
-            if(fn.call(scope||this, it[i], k[i])){
-                r.add(k[i], it[i]);
-            }
-        }
-        return r;
+    
+    destroy: function(){
+        this.disable();    
     },
 
-    
-    findIndex : function(property, value, start, anyMatch, caseSensitive){
-        if(Ext.isEmpty(value, false)){
-            return -1;
-        }
-        value = this.createValueMatcher(value, anyMatch, caseSensitive);
-        return this.findIndexBy(function(o){
-            return o && value.test(o[property]);
-        }, null, start);
+       
+       enable: function() {
+        if (this.disabled) {
+            if (Ext.isSafari2) {
+                
+                this.el.on('keyup', this.stopKeyUp, this);
+            }
+
+            this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
+            this.disabled = false;
+        }
     },
 
-    
-    findIndexBy : function(fn, scope, start){
-        var k = this.keys, it = this.items;
-        for(var i = (start||0), len = it.length; i < len; i++){
-            if(fn.call(scope||this, it[i], k[i])){
-                return i;
+       
+       disable: function() {
+        if (!this.disabled) {
+            if (Ext.isSafari2) {
+                
+                this.el.un('keyup', this.stopKeyUp, this);
             }
+
+            this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
+            this.disabled = true;
         }
-        return -1;
     },
-
     
-    createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
-        if (!value.exec) { 
-            var er = Ext.escapeRe;
-            value = String(value);
-            if (anyMatch === true) {
-                value = er(value);
-            } else {
-                value = '^' + er(value);
-                if (exactMatch === true) {
-                    value += '$';
-                }
-            }
-            value = new RegExp(value, caseSensitive ? '' : 'i');
-         }
-         return value;
+    
+    setDisabled : function(disabled){
+        this[disabled ? "disable" : "enable"]();
     },
+    
+    
+    isKeydown: function(){
+        return this.forceKeyDown || Ext.EventManager.useKeydown;
+    }
+};
+
+Ext.KeyMap = function(el, config, eventName){
+    this.el  = Ext.get(el);
+    this.eventName = eventName || "keydown";
+    this.bindings = [];
+    if(config){
+        this.addBinding(config);
+    }
+    this.enable();
+};
 
+Ext.KeyMap.prototype = {
     
-    clone : function(){
-        var r = new Ext.util.MixedCollection();
-        var k = this.keys, it = this.items;
-        for(var i = 0, len = it.length; i < len; i++){
-            r.add(k[i], it[i]);
+    stopEvent : false,
+
+    
+       addBinding : function(config){
+        if(Ext.isArray(config)){
+            Ext.each(config, function(c){
+                this.addBinding(c);
+            }, this);
+            return;
         }
-        r.getKey = this.getKey;
-        return r;
-    }
-});
+        var keyCode = config.key,
+            fn = config.fn || config.handler,
+            scope = config.scope;
 
-Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
-Ext.util.JSON = new (function(){
-    var useHasOwn = !!{}.hasOwnProperty,
-        isNative = function() {
-            var useNative = null;
+       if (config.stopEvent) {
+           this.stopEvent = config.stopEvent;    
+       }       
 
-            return function() {
-                if (useNative === null) {
-                    useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
-                }
+        if(typeof keyCode == "string"){
+            var ks = [];
+            var keyString = keyCode.toUpperCase();
+            for(var j = 0, len = keyString.length; j < len; j++){
+                ks.push(keyString.charCodeAt(j));
+            }
+            keyCode = ks;
+        }
+        var keyArray = Ext.isArray(keyCode);
         
-                return useNative;
-            };
-        }(),
-        pad = function(n) {
-            return n < 10 ? "0" + n : n;
-        },
-        doDecode = function(json){
-            return eval("(" + json + ')');    
-        },
-        doEncode = function(o){
-            if(!Ext.isDefined(o) || o === null){
-                return "null";
-            }else if(Ext.isArray(o)){
-                return encodeArray(o);
-            }else if(Ext.isDate(o)){
-                return Ext.util.JSON.encodeDate(o);
-            }else if(Ext.isString(o)){
-                return encodeString(o);
-            }else if(typeof o == "number"){
-                
-                return isFinite(o) ? String(o) : "null";
-            }else if(Ext.isBoolean(o)){
-                return String(o);
-            }else {
-                var a = ["{"], b, i, v;
-                for (i in o) {
-                    
-                    if(!o.getElementsByTagName){
-                        if(!useHasOwn || o.hasOwnProperty(i)) {
-                            v = o[i];
-                            switch (typeof v) {
-                            case "undefined":
-                            case "function":
-                            case "unknown":
-                                break;
-                            default:
-                                if(b){
-                                    a.push(',');
-                                }
-                                a.push(doEncode(i), ":",
-                                        v === null ? "null" : doEncode(v));
-                                b = true;
-                            }
+        var handler = function(e){
+            if(this.checkModifiers(config, e)){
+                var k = e.getKey();
+                if(keyArray){
+                    for(var i = 0, len = keyCode.length; i < len; i++){
+                        if(keyCode[i] == k){
+                          if(this.stopEvent){
+                              e.stopEvent();
+                          }
+                          fn.call(scope || window, k, e);
+                          return;
                         }
                     }
-                }
-                a.push("}");
-                return a.join("");
-            }    
-        },
-        m = {
-            "\b": '\\b',
-            "\t": '\\t',
-            "\n": '\\n',
-            "\f": '\\f',
-            "\r": '\\r',
-            '"' : '\\"',
-            "\\": '\\\\'
-        },
-        encodeString = function(s){
-            if (/["\\\x00-\x1f]/.test(s)) {
-                return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
-                    var c = m[b];
-                    if(c){
-                        return c;
-                    }
-                    c = b.charCodeAt();
-                    return "\\u00" +
-                        Math.floor(c / 16).toString(16) +
-                        (c % 16).toString(16);
-                }) + '"';
-            }
-            return '"' + s + '"';
-        },
-        encodeArray = function(o){
-            var a = ["["], b, i, l = o.length, v;
-                for (i = 0; i < l; i += 1) {
-                    v = o[i];
-                    switch (typeof v) {
-                        case "undefined":
-                        case "function":
-                        case "unknown":
-                            break;
-                        default:
-                            if (b) {
-                                a.push(',');
-                            }
-                            a.push(v === null ? "null" : Ext.util.JSON.encode(v));
-                            b = true;
+                }else{
+                    if(k == keyCode){
+                        if(this.stopEvent){
+                           e.stopEvent();
+                        }
+                        fn.call(scope || window, k, e);
                     }
                 }
-                a.push("]");
-                return a.join("");
+            }
         };
-
-    this.encodeDate = function(o){
-        return '"' + o.getFullYear() + "-" +
-                pad(o.getMonth() + 1) + "-" +
-                pad(o.getDate()) + "T" +
-                pad(o.getHours()) + ":" +
-                pad(o.getMinutes()) + ":" +
-                pad(o.getSeconds()) + '"';
-    };
-
+        this.bindings.push(handler);
+       },
     
-    this.encode = function() {
-        var ec;
-        return function(o) {
-            if (!ec) {
-                
-                ec = isNative() ? JSON.stringify : doEncode;
+    
+    checkModifiers: function(config, e){
+        var val, key, keys = ['shift', 'ctrl', 'alt'];
+        for (var i = 0, len = keys.length; i < len; ++i){
+            key = keys[i];
+            val = config[key];
+            if(!(val === undefined || (val === e[key + 'Key']))){
+                return false;
             }
-            return ec(o);
-        };
-    }();
-
+        }
+        return true;
+    },
 
     
-    this.decode = function() {
-        var dc;
-        return function(json) {
-            if (!dc) {
-                
-                dc = isNative() ? JSON.parse : doDecode;
-            }
-            return dc(json);
-        };
-    }();
+    on : function(key, fn, scope){
+        var keyCode, shift, ctrl, alt;
+        if(typeof key == "object" && !Ext.isArray(key)){
+            keyCode = key.key;
+            shift = key.shift;
+            ctrl = key.ctrl;
+            alt = key.alt;
+        }else{
+            keyCode = key;
+        }
+        this.addBinding({
+            key: keyCode,
+            shift: shift,
+            ctrl: ctrl,
+            alt: alt,
+            fn: fn,
+            scope: scope
+        });
+    },
 
-})();
+    
+    handleKeyDown : function(e){
+           if(this.enabled){ 
+           var b = this.bindings;
+           for(var i = 0, len = b.length; i < len; i++){
+               b[i].call(this, e);
+           }
+           }
+       },
 
-Ext.encode = Ext.util.JSON.encode;
+       
+       isEnabled : function(){
+           return this.enabled;
+       },
 
-Ext.decode = Ext.util.JSON.decode;
+       
+       enable: function(){
+               if(!this.enabled){
+                   this.el.on(this.eventName, this.handleKeyDown, this);
+                   this.enabled = true;
+               }
+       },
 
-Ext.util.Format = function(){
-    var trimRe = /^\s+|\s+$/g,
-        stripTagsRE = /<\/?[^>]+>/gi,
-        stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
-        nl2brRe = /\r?\n/g;
-        
+       
+       disable: function(){
+               if(this.enabled){
+                   this.el.removeListener(this.eventName, this.handleKeyDown, this);
+                   this.enabled = false;
+               }
+       },
+    
+    
+    setDisabled : function(disabled){
+        this[disabled ? "disable" : "enable"]();
+    }
+};
+Ext.util.TextMetrics = function(){
+    var shared;
     return {
         
-        ellipsis : function(value, len, word){
-            if(value && value.length > len){
-                if(word){
-                    var vs = value.substr(0, len - 2),
-                        index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
-                    if(index == -1 || index < (len - 15)){
-                        return value.substr(0, len - 3) + "...";
-                    }else{
-                        return vs.substr(0, index) + "...";
-                    }
-                } else{
-                    return value.substr(0, len - 3) + "...";
-                }
+        measure : function(el, text, fixedWidth){
+            if(!shared){
+                shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
             }
-            return value;
+            shared.bind(el);
+            shared.setFixedWidth(fixedWidth || 'auto');
+            return shared.getSize(text);
         },
 
         
-        undef : function(value){
-            return value !== undefined ? value : "";
-        },
+        createInstance : function(el, fixedWidth){
+            return Ext.util.TextMetrics.Instance(el, fixedWidth);
+        }
+    };
+}();
 
-        
-        defaultValue : function(value, defaultValue){
-            return value !== undefined && value !== '' ? value : defaultValue;
-        },
+Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
+    var ml = new Ext.Element(document.createElement('div'));
+    document.body.appendChild(ml.dom);
+    ml.position('absolute');
+    ml.setLeftTop(-1000, -1000);
+    ml.hide();
 
-        
-        htmlEncode : function(value){
-            return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
-        },
+    if(fixedWidth){
+        ml.setWidth(fixedWidth);
+    }
 
+    var instance = {
         
-        htmlDecode : function(value){
-            return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
+        getSize : function(text){
+            ml.update(text);
+            var s = ml.getSize();
+            ml.update('');
+            return s;
         },
 
         
-        trim : function(value){
-            return String(value).replace(trimRe, "");
+        bind : function(el){
+            ml.setStyle(
+                Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
+            );
         },
 
         
-        substr : function(value, start, length){
-            return String(value).substr(start, length);
+        setFixedWidth : function(width){
+            ml.setWidth(width);
         },
 
         
-        lowercase : function(value){
-            return String(value).toLowerCase();
+        getWidth : function(text){
+            ml.dom.style.width = 'auto';
+            return this.getSize(text).width;
         },
 
         
-        uppercase : function(value){
-            return String(value).toUpperCase();
-        },
+        getHeight : function(text){
+            return this.getSize(text).height;
+        }
+    };
 
-        
-        capitalize : function(value){
-            return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
-        },
+    instance.bind(bindTo);
 
-        
-        call : function(value, fn){
-            if(arguments.length > 2){
-                var args = Array.prototype.slice.call(arguments, 2);
-                args.unshift(value);
-                return eval(fn).apply(window, args);
-            }else{
-                return eval(fn).call(window, value);
-            }
-        },
+    return instance;
+};
 
-        
-        usMoney : function(v){
-            v = (Math.round((v-0)*100))/100;
-            v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
-            v = String(v);
-            var ps = v.split('.'),
-                whole = ps[0],
-                sub = ps[1] ? '.'+ ps[1] : '.00',
-                r = /(\d+)(\d{3})/;
-            while (r.test(whole)) {
-                whole = whole.replace(r, '$1' + ',' + '$2');
-            }
-            v = whole + sub;
-            if(v.charAt(0) == '-'){
-                return '-$' + v.substr(1);
-            }
-            return "$" +  v;
-        },
+Ext.Element.addMethods({
+    
+    getTextWidth : function(text, min, max){
+        return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
+    }
+});
 
-        
-        date : function(v, format){
-            if(!v){
-                return "";
+Ext.util.Cookies = {
+    
+    set : function(name, value){
+        var argv = arguments;
+        var argc = arguments.length;
+        var expires = (argc > 2) ? argv[2] : null;
+        var path = (argc > 3) ? argv[3] : '/';
+        var domain = (argc > 4) ? argv[4] : null;
+        var secure = (argc > 5) ? argv[5] : false;
+        document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
+    },
+
+    
+    get : function(name){
+        var arg = name + "=";
+        var alen = arg.length;
+        var clen = document.cookie.length;
+        var i = 0;
+        var j = 0;
+        while(i < clen){
+            j = i + alen;
+            if(document.cookie.substring(i, j) == arg){
+                return Ext.util.Cookies.getCookieVal(j);
             }
-            if(!Ext.isDate(v)){
-                v = new Date(Date.parse(v));
+            i = document.cookie.indexOf(" ", i) + 1;
+            if(i === 0){
+                break;
             }
-            return v.dateFormat(format || "m/d/Y");
-        },
+        }
+        return null;
+    },
+
+    
+    clear : function(name){
+        if(Ext.util.Cookies.get(name)){
+            document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
+        }
+    },
+    
+    getCookieVal : function(offset){
+        var endstr = document.cookie.indexOf(";", offset);
+        if(endstr == -1){
+            endstr = document.cookie.length;
+        }
+        return unescape(document.cookie.substring(offset, endstr));
+    }
+};
+Ext.handleError = function(e) {
+    throw e;
+};
+
+
+Ext.Error = function(message) {
+    
+    this.message = (this.lang[message]) ? this.lang[message] : message;
+};
+
+Ext.Error.prototype = new Error();
+Ext.apply(Ext.Error.prototype, {
+    
+    lang: {},
+
+    name: 'Ext.Error',
+    
+    getName : function() {
+        return this.name;
+    },
+    
+    getMessage : function() {
+        return this.message;
+    },
+    
+    toJson : function() {
+        return Ext.encode(this);
+    }
+});
+
+Ext.ComponentMgr = function(){
+    var all = new Ext.util.MixedCollection();
+    var types = {};
+    var ptypes = {};
 
+    return {
         
-        dateRenderer : function(format){
-            return function(v){
-                return Ext.util.Format.date(v, format);
-            };
+        register : function(c){
+            all.add(c);
         },
+
         
-        
-        stripTags : function(v){
-            return !v ? v : String(v).replace(stripTagsRE, "");
+        unregister : function(c){
+            all.remove(c);
         },
 
         
-        stripScripts : function(v){
-            return !v ? v : String(v).replace(stripScriptsRe, "");
+        get : function(id){
+            return all.get(id);
         },
 
         
-        fileSize : function(size){
-            if(size < 1024) {
-                return size + " bytes";
-            } else if(size < 1048576) {
-                return (Math.round(((size*10) / 1024))/10) + " KB";
-            } else {
-                return (Math.round(((size*10) / 1048576))/10) + " MB";
-            }
+        onAvailable : function(id, fn, scope){
+            all.on("add", function(index, o){
+                if(o.id == id){
+                    fn.call(scope || o, o);
+                    all.un("add", fn, scope);
+                }
+            });
         },
 
         
-        math : function(){
-            var fns = {};
-            return function(v, a){
-                if(!fns[a]){
-                    fns[a] = new Function('v', 'return v ' + a + ';');
-                }
-                return fns[a](v);
-            }
-        }(),
-
+        all : all,
         
-        round : function(value, precision) {
-            var result = Number(value);
-            if (typeof precision == 'number') {
-                precision = Math.pow(10, precision);
-                result = Math.round(value * precision) / precision;
-            }
-            return result;
+        
+        types : types,
+        
+        
+        ptypes: ptypes,
+        
+        
+        isRegistered : function(xtype){
+            return types[xtype] !== undefined;    
         },
+        
+        
+        isPluginRegistered : function(ptype){
+            return ptypes[ptype] !== undefined;    
+        },        
 
         
-        number: function(v, format) {
-            if(!format){
-                       return v;
-                   }
-                   v = Ext.num(v, NaN);
-            if (isNaN(v)){
-                return '';
-            }
-                   var comma = ',',
-                       dec = '.',
-                       i18n = false,
-                       neg = v < 0;
-               
-                   v = Math.abs(v);
-                   if(format.substr(format.length - 2) == '/i'){
-                       format = format.substr(0, format.length - 2);
-                       i18n = true;
-                       comma = '.';
-                       dec = ',';
-                   }
-               
-                   var hasComma = format.indexOf(comma) != -1, 
-                       psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
-               
-                   if(1 < psplit.length){
-                       v = v.toFixed(psplit[1].length);
-                   }else if(2 < psplit.length){
-                       throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
-                   }else{
-                       v = v.toFixed(0);
-                   }
-               
-                   var fnum = v.toString();
-                   if(hasComma){
-                       psplit = fnum.split('.');
-               
-                       var cnum = psplit[0], parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;
-               
-                       for(var i = 0; i < j; i += n){
-                           if(i != 0){
-                               n = 3;
-                           }
-                           parr[parr.length] = cnum.substr(i, n);
-                           m -= 1;
-                       }
-                       fnum = parr.join(comma);
-                       if(psplit[1]){
-                           fnum += dec + psplit[1];
-                       }
-                   }
-               
-                   return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
+        registerType : function(xtype, cls){
+            types[xtype] = cls;
+            cls.xtype = xtype;
         },
 
         
-        numberRenderer : function(format){
-            return function(v){
-                return Ext.util.Format.number(v, format);
-            };
+        create : function(config, defaultType){
+            return config.render ? config : new types[config.xtype || defaultType](config);
         },
 
         
-        plural : function(v, s, p){
-            return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
+        registerPlugin : function(ptype, cls){
+            ptypes[ptype] = cls;
+            cls.ptype = ptype;
         },
+
         
-        
-        nl2br : function(v){
-            return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
+        createPlugin : function(config, defaultType){
+            var PluginCls = ptypes[config.ptype || defaultType];
+            if (PluginCls.init) {
+                return PluginCls;                
+            } else {
+                return new PluginCls(config);
+            }            
         }
-    }
+    };
 }();
 
-Ext.XTemplate = function(){
-    Ext.XTemplate.superclass.constructor.apply(this, arguments);
-
-    var me = this,
-       s = me.html,
-       re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
-       nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
-       ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
-       execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
-       m,
-       id = 0,
-       tpls = [],
-       VALUES = 'values',
-       PARENT = 'parent',
-       XINDEX = 'xindex',
-       XCOUNT = 'xcount',
-       RETURN = 'return ',
-       WITHVALUES = 'with(values){ ';
 
-    s = ['<tpl>', s, '</tpl>'].join('');
+Ext.reg = Ext.ComponentMgr.registerType; 
 
-    while((m = s.match(re))){
-               var m2 = m[0].match(nameRe),
-                       m3 = m[0].match(ifRe),
-                       m4 = m[0].match(execRe),
-                       exp = null,
-                       fn = null,
-                       exec = null,
-                       name = m2 && m2[1] ? m2[1] : '';
+Ext.preg = Ext.ComponentMgr.registerPlugin;
 
-       if (m3) {
-           exp = m3 && m3[1] ? m3[1] : null;
-           if(exp){
-               fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
-           }
-       }
-       if (m4) {
-           exp = m4 && m4[1] ? m4[1] : null;
-           if(exp){
-               exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
-           }
-       }
-       if(name){
-           switch(name){
-               case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
-               case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
-               default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
-           }
-       }
-       tpls.push({
-            id: id,
-            target: name,
-            exec: exec,
-            test: fn,
-            body: m[1]||''
-        });
-       s = s.replace(m[0], '{xtpl'+ id + '}');
-       ++id;
+Ext.create = Ext.ComponentMgr.create;
+Ext.Component = function(config){
+    config = config || {};
+    if(config.initialConfig){
+        if(config.isAction){           
+            this.baseAction = config;
+        }
+        config = config.initialConfig; 
+    }else if(config.tagName || config.dom || Ext.isString(config)){ 
+        config = {applyTo: config, id: config.id || config};
     }
-       Ext.each(tpls, function(t) {
-        me.compileTpl(t);
-    });
-    me.master = tpls[tpls.length-1];
-    me.tpls = tpls;
-};
-Ext.extend(Ext.XTemplate, Ext.Template, {
-    
-    re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
-    
-    codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
 
     
-    applySubTemplate : function(id, values, parent, xindex, xcount){
-        var me = this,
-               len,
-               t = me.tpls[id],
-               vs,
-               buf = [];
-        if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
-            (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
-            return '';
-        }
-        vs = t.target ? t.target.call(me, values, parent) : values;
-        len = vs.length;
-        parent = t.target ? values : parent;
-        if(t.target && Ext.isArray(vs)){
-               Ext.each(vs, function(v, i) {
-                buf[buf.length] = t.compiled.call(me, v, parent, i+1, len);
-            });
-            return buf.join('');
-        }
-        return t.compiled.call(me, vs, parent, xindex, xcount);
-    },
+    this.initialConfig = config;
 
-    
-    compileTpl : function(tpl){
-        var fm = Ext.util.Format,
-                       useF = this.disableFormats !== true,
-            sep = Ext.isGecko ? "+" : ",",
-            body;
+    Ext.apply(this, config);
+    this.addEvents(
+        
+        'added',
+        
+        'disable',
+        
+        'enable',
+        
+        'beforeshow',
+        
+        'show',
+        
+        'beforehide',
+        
+        'hide',
+        
+        'removed',
+        
+        'beforerender',
+        
+        'render',
+        
+        'afterrender',
+        
+        'beforedestroy',
+        
+        'destroy',
+        
+        'beforestaterestore',
+        
+        'staterestore',
+        
+        'beforestatesave',
+        
+        'statesave'
+    );
+    this.getId();
+    Ext.ComponentMgr.register(this);
+    Ext.Component.superclass.constructor.call(this);
 
-        function fn(m, name, format, args, math){
-            if(name.substr(0, 4) == 'xtpl'){
-                return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
-            }
-            var v;
-            if(name === '.'){
-                v = 'values';
-            }else if(name === '#'){
-                v = 'xindex';
-            }else if(name.indexOf('.') != -1){
-                v = name;
-            }else{
-                v = "values['" + name + "']";
-            }
-            if(math){
-                v = '(' + v + math + ')';
-            }
-            if (format && useF) {
-                args = args ? ',' + args : "";
-                if(format.substr(0, 5) != "this."){
-                    format = "fm." + format + '(';
-                }else{
-                    format = 'this.call("'+ format.substr(5) + '", ';
-                    args = ", values";
-                }
-            } else {
-                args= ''; format = "("+v+" === undefined ? '' : ";
-            }
-            return "'"+ sep + format + v + args + ")"+sep+"'";
-        }
+    if(this.baseAction){
+        this.baseAction.addComponent(this);
+    }
 
-        function codeFn(m, code){
-            
-            return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
-        }
+    this.initComponent();
 
-        
-        if(Ext.isGecko){
-            body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
-                   tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
-                    "';};";
+    if(this.plugins){
+        if(Ext.isArray(this.plugins)){
+            for(var i = 0, len = this.plugins.length; i < len; i++){
+                this.plugins[i] = this.initPlugin(this.plugins[i]);
+            }
         }else{
-            body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
-            body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
-            body.push("'].join('');};");
-            body = body.join('');
+            this.plugins = this.initPlugin(this.plugins);
         }
-        eval(body);
-        return this;
-    },
+    }
 
-    
-    applyTemplate : function(values){
-        return this.master.compiled.call(this, values, {}, 1, 1);
-    },
+    if(this.stateful !== false){
+        this.initState();
+    }
+
+    if(this.applyTo){
+        this.applyToMarkup(this.applyTo);
+        delete this.applyTo;
+    }else if(this.renderTo){
+        this.render(this.renderTo);
+        delete this.renderTo;
+    }
+};
 
+
+Ext.Component.AUTO_ID = 1000;
+
+Ext.extend(Ext.Component, Ext.util.Observable, {
+    
+    
+    
+    
+    
+    
     
-    compile : function(){return this;}
 
     
     
     
+    
+    
+    
+    
+    
+    
+    disabled : false,
+    
+    hidden : false,
+    
+    
+    
+    
+    
+    
+    
+    autoEl : 'div',
 
-});
+    
+    disabledClass : 'x-item-disabled',
+    
+    allowDomMove : true,
+    
+    autoShow : false,
+    
+    hideMode : 'display',
+    
+    hideParent : false,
+    
+    
+    
+    
+    
+    rendered : false,
 
-Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
+    
+    
 
+    
 
-Ext.XTemplate.from = function(el){
-    el = Ext.getDom(el);
-    return new Ext.XTemplate(el.value || el.innerHTML);
-};
-Ext.util.CSS = function(){
-       var rules = null;
-       var doc = document;
+    
+    tplWriteMode : 'overwrite',
 
-    var camelRe = /(-[a-z])/gi;
-    var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
+    
+    
+    
+    bubbleEvents: [],
 
-   return {
-   
-   createStyleSheet : function(cssText, id){
-       var ss;
-       var head = doc.getElementsByTagName("head")[0];
-       var rules = doc.createElement("style");
-       rules.setAttribute("type", "text/css");
-       if(id){
-           rules.setAttribute("id", id);
-       }
-       if(Ext.isIE){
-           head.appendChild(rules);
-           ss = rules.styleSheet;
-           ss.cssText = cssText;
-       }else{
-           try{
-                rules.appendChild(doc.createTextNode(cssText));
-           }catch(e){
-               rules.cssText = cssText;
-           }
-           head.appendChild(rules);
-           ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
-       }
-       this.cacheStyleSheet(ss);
-       return ss;
-   },
 
-   
-   removeStyleSheet : function(id){
-       var existing = doc.getElementById(id);
-       if(existing){
-           existing.parentNode.removeChild(existing);
-       }
-   },
+    
+    ctype : 'Ext.Component',
 
-   
-   swapStyleSheet : function(id, url){
-       this.removeStyleSheet(id);
-       var ss = doc.createElement("link");
-       ss.setAttribute("rel", "stylesheet");
-       ss.setAttribute("type", "text/css");
-       ss.setAttribute("id", id);
-       ss.setAttribute("href", url);
-       doc.getElementsByTagName("head")[0].appendChild(ss);
-   },
-   
-   
-   refreshCache : function(){
-       return this.getRules(true);
-   },
+    
+    actionMode : 'el',
 
-   
-   cacheStyleSheet : function(ss){
-       if(!rules){
-           rules = {};
-       }
-       try{
-           var ssRules = ss.cssRules || ss.rules;
-           for(var j = ssRules.length-1; j >= 0; --j){
-               rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
-           }
-       }catch(e){}
-   },
-   
-   
-   getRules : function(refreshCache){
-               if(rules === null || refreshCache){
-                       rules = {};
-                       var ds = doc.styleSheets;
-                       for(var i =0, len = ds.length; i < len; i++){
-                           try{
-                       this.cacheStyleSheet(ds[i]);
-                   }catch(e){} 
-               }
-               }
-               return rules;
-       },
-       
-       
-   getRule : function(selector, refreshCache){
-               var rs = this.getRules(refreshCache);
-               if(!Ext.isArray(selector)){
-                   return rs[selector.toLowerCase()];
-               }
-               for(var i = 0; i < selector.length; i++){
-                       if(rs[selector[i]]){
-                               return rs[selector[i].toLowerCase()];
-                       }
-               }
-               return null;
-       },
-       
-       
-       
-   updateRule : function(selector, property, value){
-               if(!Ext.isArray(selector)){
-                       var rule = this.getRule(selector);
-                       if(rule){
-                               rule.style[property.replace(camelRe, camelFn)] = value;
-                               return true;
-                       }
-               }else{
-                       for(var i = 0; i < selector.length; i++){
-                               if(this.updateRule(selector[i], property, value)){
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-   };  
-}();
-Ext.util.ClickRepeater = function(el, config)
-{
-    this.el = Ext.get(el);
-    this.el.unselectable();
+    
+    getActionEl : function(){
+        return this[this.actionMode];
+    },
 
-    Ext.apply(this, config);
+    initPlugin : function(p){
+        if(p.ptype && !Ext.isFunction(p.init)){
+            p = Ext.ComponentMgr.createPlugin(p);
+        }else if(Ext.isString(p)){
+            p = Ext.ComponentMgr.createPlugin({
+                ptype: p
+            });
+        }
+        p.init(this);
+        return p;
+    },
 
-    this.addEvents(
-    
-        "mousedown",
-    
-        "click",
     
-        "mouseup"
-    );
-
-    if(!this.disabled){
-        this.disabled = true;
-        this.enable();
-    }
+    initComponent : function(){
+        
+        if(this.listeners){
+            this.on(this.listeners);
+            delete this.listeners;
+        }
+        this.enableBubble(this.bubbleEvents);
+    },
 
     
-    if(this.handler){
-        this.on("click", this.handler,  this.scope || this);
-    }
+    render : function(container, position){
+        if(!this.rendered && this.fireEvent('beforerender', this) !== false){
+            if(!container && this.el){
+                this.el = Ext.get(this.el);
+                container = this.el.dom.parentNode;
+                this.allowDomMove = false;
+            }
+            this.container = Ext.get(container);
+            if(this.ctCls){
+                this.container.addClass(this.ctCls);
+            }
+            this.rendered = true;
+            if(position !== undefined){
+                if(Ext.isNumber(position)){
+                    position = this.container.dom.childNodes[position];
+                }else{
+                    position = Ext.getDom(position);
+                }
+            }
+            this.onRender(this.container, position || null);
+            if(this.autoShow){
+                this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
+            }
+            if(this.cls){
+                this.el.addClass(this.cls);
+                delete this.cls;
+            }
+            if(this.style){
+                this.el.applyStyles(this.style);
+                delete this.style;
+            }
+            if(this.overCls){
+                this.el.addClassOnOver(this.overCls);
+            }
+            this.fireEvent('render', this);
 
-    Ext.util.ClickRepeater.superclass.constructor.call(this);
-};
 
-Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
-    interval : 20,
-    delay: 250,
-    preventDefault : true,
-    stopDefault : false,
-    timer : 0,
+            
+            
+            var contentTarget = this.getContentTarget();
+            if (this.html){
+                contentTarget.update(Ext.DomHelper.markup(this.html));
+                delete this.html;
+            }
+            if (this.contentEl){
+                var ce = Ext.getDom(this.contentEl);
+                Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
+                contentTarget.appendChild(ce);
+            }
+            if (this.tpl) {
+                if (!this.tpl.compile) {
+                    this.tpl = new Ext.XTemplate(this.tpl);
+                }
+                if (this.data) {
+                    this.tpl[this.tplWriteMode](contentTarget, this.data);
+                    delete this.data;
+                }
+            }
+            this.afterRender(this.container);
+
 
-    
-    enable: function(){
-        if(this.disabled){
-            this.el.on('mousedown', this.handleMouseDown, this);
-            if(this.preventDefault || this.stopDefault){
-                this.el.on('click', this.eventOptions, this);
+            if(this.hidden){
+                
+                this.doHide();
             }
-        }
-        this.disabled = false;
-    },
-    
-    
-    disable: function( force){
-        if(force || !this.disabled){
-            clearTimeout(this.timer);
-            if(this.pressClass){
-                this.el.removeClass(this.pressClass);
+            if(this.disabled){
+                
+                this.disable(true);
             }
-            Ext.getDoc().un('mouseup', this.handleMouseUp, this);
-            this.el.removeAllListeners();
+
+            if(this.stateful !== false){
+                this.initStateEvents();
+            }
+            this.fireEvent('afterrender', this);
         }
-        this.disabled = true;
-    },
-    
-    
-    setDisabled: function(disabled){
-        this[disabled ? 'disable' : 'enable']();    
+        return this;
     },
+
+
     
-    eventOptions: function(e){
-        if(this.preventDefault){
-            e.preventDefault();
+    update: function(htmlOrData, loadScripts, cb) {
+        var contentTarget = this.getContentTarget();
+        if (this.tpl && typeof htmlOrData !== "string") {
+            this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
+        } else {
+            var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
+            contentTarget.update(html, loadScripts, cb);
         }
-        if(this.stopDefault){
-            e.stopEvent();
-        }       
-    },
-    
-    
-    destroy : function() {
-        this.disable(true);
-        Ext.destroy(this.el);
-        this.purgeListeners();
     },
-    
-    
-    handleMouseDown : function(){
-        clearTimeout(this.timer);
-        this.el.blur();
-        if(this.pressClass){
-            this.el.addClass(this.pressClass);
-        }
-        this.mousedownTime = new Date();
-
-        Ext.getDoc().on("mouseup", this.handleMouseUp, this);
-        this.el.on("mouseout", this.handleMouseOut, this);
 
-        this.fireEvent("mousedown", this);
-        this.fireEvent("click", this);
-
-
-        if (this.accelerate) {
-            this.delay = 400;
-           }
-        this.timer = this.click.defer(this.delay || this.interval, this);
-    },
 
     
-    click : function(){
-        this.fireEvent("click", this);
-        this.timer = this.click.defer(this.accelerate ?
-            this.easeOutExpo(this.mousedownTime.getElapsed(),
-                400,
-                -390,
-                12000) :
-            this.interval, this);
+    onAdded : function(container, pos) {
+        this.ownerCt = container;
+        this.initRef();
+        this.fireEvent('added', this, container, pos);
     },
 
-    easeOutExpo : function (t, b, c, d) {
-        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+    
+    onRemoved : function() {
+        this.removeRef();
+        this.fireEvent('removed', this, this.ownerCt);
+        delete this.ownerCt;
     },
 
     
-    handleMouseOut : function(){
-        clearTimeout(this.timer);
-        if(this.pressClass){
-            this.el.removeClass(this.pressClass);
+    initRef : function() {
+        
+        if(this.ref && !this.refOwner){
+            var levels = this.ref.split('/'),
+                last = levels.length,
+                i = 0,
+                t = this;
+
+            while(t && i < last){
+                t = t.ownerCt;
+                ++i;
+            }
+            if(t){
+                t[this.refName = levels[--i]] = this;
+                
+                this.refOwner = t;
+            }
         }
-        this.el.on("mouseover", this.handleMouseReturn, this);
     },
 
-    
-    handleMouseReturn : function(){
-        this.el.un("mouseover", this.handleMouseReturn, this);
-        if(this.pressClass){
-            this.el.addClass(this.pressClass);
+    removeRef : function() {
+        if (this.refOwner && this.refName) {
+            delete this.refOwner[this.refName];
+            delete this.refOwner;
         }
-        this.click();
     },
 
     
-    handleMouseUp : function(){
-        clearTimeout(this.timer);
-        this.el.un("mouseover", this.handleMouseReturn, this);
-        this.el.un("mouseout", this.handleMouseOut, this);
-        Ext.getDoc().un("mouseup", this.handleMouseUp, this);
-        this.el.removeClass(this.pressClass);
-        this.fireEvent("mouseup", this);
-    }
-});
-Ext.KeyNav = function(el, config){
-    this.el = Ext.get(el);
-    Ext.apply(this, config);
-    if(!this.disabled){
-        this.disabled = true;
-        this.enable();
-    }
-};
-
-Ext.KeyNav.prototype = {
-    
-    disabled : false,
-    
-    defaultEventAction: "stopEvent",
-    
-    forceKeyDown : false,
-
-    
-    relay : function(e){
-        var k = e.getKey();
-        var h = this.keyToHandler[k];
-        if(h && this[h]){
-            if(this.doRelay(e, this[h], h) !== true){
-                e[this.defaultEventAction]();
+    initState : function(){
+        if(Ext.state.Manager){
+            var id = this.getStateId();
+            if(id){
+                var state = Ext.state.Manager.get(id);
+                if(state){
+                    if(this.fireEvent('beforestaterestore', this, state) !== false){
+                        this.applyState(Ext.apply({}, state));
+                        this.fireEvent('staterestore', this, state);
+                    }
+                }
             }
         }
     },
 
     
-    doRelay : function(e, h, hname){
-        return h.call(this.scope || this, e);
+    getStateId : function(){
+        return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
     },
 
     
-    enter : false,
-    left : false,
-    right : false,
-    up : false,
-    down : false,
-    tab : false,
-    esc : false,
-    pageUp : false,
-    pageDown : false,
-    del : false,
-    home : false,
-    end : false,
-
-    
-    keyToHandler : {
-        37 : "left",
-        39 : "right",
-        38 : "up",
-        40 : "down",
-        33 : "pageUp",
-        34 : "pageDown",
-        46 : "del",
-        36 : "home",
-        35 : "end",
-        13 : "enter",
-        27 : "esc",
-        9  : "tab"
+    initStateEvents : function(){
+        if(this.stateEvents){
+            for(var i = 0, e; e = this.stateEvents[i]; i++){
+                this.on(e, this.saveState, this, {delay:100});
+            }
+        }
     },
-    
-    stopKeyUp: function(e) {
-        var k = e.getKey();
 
-        if (k >= 37 && k <= 40) {
-            
-            
-            e.stopEvent();
+    
+    applyState : function(state){
+        if(state){
+            Ext.apply(this, state);
         }
     },
+
     
-    
-    destroy: function(){
-        this.disable();    
+    getState : function(){
+        return null;
     },
 
-       
-       enable: function() {
-        if (this.disabled) {
-            if (Ext.isSafari2) {
-                
-                this.el.on('keyup', this.stopKeyUp, this);
+    
+    saveState : function(){
+        if(Ext.state.Manager && this.stateful !== false){
+            var id = this.getStateId();
+            if(id){
+                var state = this.getState();
+                if(this.fireEvent('beforestatesave', this, state) !== false){
+                    Ext.state.Manager.set(id, state);
+                    this.fireEvent('statesave', this, state);
+                }
             }
-
-            this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
-            this.disabled = false;
         }
     },
 
-       
-       disable: function() {
-        if (!this.disabled) {
-            if (Ext.isSafari2) {
-                
-                this.el.un('keyup', this.stopKeyUp, this);
-            }
-
-            this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
-            this.disabled = true;
-        }
-    },
-    
     
-    setDisabled : function(disabled){
-        this[disabled ? "disable" : "enable"]();
+    applyToMarkup : function(el){
+        this.allowDomMove = false;
+        this.el = Ext.get(el);
+        this.render(this.el.dom.parentNode);
     },
-    
-    
-    isKeydown: function(){
-        return this.forceKeyDown || Ext.EventManager.useKeydown;
-    }
-};
-
-Ext.KeyMap = function(el, config, eventName){
-    this.el  = Ext.get(el);
-    this.eventName = eventName || "keydown";
-    this.bindings = [];
-    if(config){
-        this.addBinding(config);
-    }
-    this.enable();
-};
 
-Ext.KeyMap.prototype = {
     
-    stopEvent : false,
+    addClass : function(cls){
+        if(this.el){
+            this.el.addClass(cls);
+        }else{
+            this.cls = this.cls ? this.cls + ' ' + cls : cls;
+        }
+        return this;
+    },
 
     
-       addBinding : function(config){
-        if(Ext.isArray(config)){
-            Ext.each(config, function(c){
-                this.addBinding(c);
-            }, this);
-            return;
+    removeClass : function(cls){
+        if(this.el){
+            this.el.removeClass(cls);
+        }else if(this.cls){
+            this.cls = this.cls.split(' ').remove(cls).join(' ');
         }
-        var keyCode = config.key,
-            fn = config.fn || config.handler,
-            scope = config.scope;
-
-       if (config.stopEvent) {
-           this.stopEvent = config.stopEvent;    
-       }       
+        return this;
+    },
 
-        if(typeof keyCode == "string"){
-            var ks = [];
-            var keyString = keyCode.toUpperCase();
-            for(var j = 0, len = keyString.length; j < len; j++){
-                ks.push(keyString.charCodeAt(j));
+    
+    
+    onRender : function(ct, position){
+        if(!this.el && this.autoEl){
+            if(Ext.isString(this.autoEl)){
+                this.el = document.createElement(this.autoEl);
+            }else{
+                var div = document.createElement('div');
+                Ext.DomHelper.overwrite(div, this.autoEl);
+                this.el = div.firstChild;
+            }
+            if (!this.el.id) {
+                this.el.id = this.getId();
             }
-            keyCode = ks;
         }
-        var keyArray = Ext.isArray(keyCode);
-        
-        var handler = function(e){
-            if(this.checkModifiers(config, e)){
-                var k = e.getKey();
-                if(keyArray){
-                    for(var i = 0, len = keyCode.length; i < len; i++){
-                        if(keyCode[i] == k){
-                          if(this.stopEvent){
-                              e.stopEvent();
-                          }
-                          fn.call(scope || window, k, e);
-                          return;
-                        }
-                    }
-                }else{
-                    if(k == keyCode){
-                        if(this.stopEvent){
-                           e.stopEvent();
-                        }
-                        fn.call(scope || window, k, e);
-                    }
+        if(this.el){
+            this.el = Ext.get(this.el);
+            if(this.allowDomMove !== false){
+                ct.dom.insertBefore(this.el.dom, position);
+                if (div) {
+                    Ext.removeNode(div);
+                    div = null;
                 }
             }
-        };
-        this.bindings.push(handler);
-       },
-    
-    
-    checkModifiers: function(config, e){
-        var val, key, keys = ['shift', 'ctrl', 'alt'];
-        for (var i = 0, len = keys.length; i < len; ++i){
-            key = keys[i];
-            val = config[key];
-            if(!(val === undefined || (val === e[key + 'Key']))){
-                return false;
-            }
         }
-        return true;
     },
 
     
-    on : function(key, fn, scope){
-        var keyCode, shift, ctrl, alt;
-        if(typeof key == "object" && !Ext.isArray(key)){
-            keyCode = key.key;
-            shift = key.shift;
-            ctrl = key.ctrl;
-            alt = key.alt;
-        }else{
-            keyCode = key;
+    getAutoCreate : function(){
+        var cfg = Ext.isObject(this.autoCreate) ?
+                      this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
+        if(this.id && !cfg.id){
+            cfg.id = this.id;
         }
-        this.addBinding({
-            key: keyCode,
-            shift: shift,
-            ctrl: ctrl,
-            alt: alt,
-            fn: fn,
-            scope: scope
-        });
+        return cfg;
     },
 
     
-    handleKeyDown : function(e){
-           if(this.enabled){ 
-           var b = this.bindings;
-           for(var i = 0, len = b.length; i < len; i++){
-               b[i].call(this, e);
-           }
-           }
-       },
-
-       
-       isEnabled : function(){
-           return this.enabled;
-       },
-
-       
-       enable: function(){
-               if(!this.enabled){
-                   this.el.on(this.eventName, this.handleKeyDown, this);
-                   this.enabled = true;
-               }
-       },
+    afterRender : Ext.emptyFn,
 
-       
-       disable: function(){
-               if(this.enabled){
-                   this.el.removeListener(this.eventName, this.handleKeyDown, this);
-                   this.enabled = false;
-               }
-       },
     
-    
-    setDisabled : function(disabled){
-        this[disabled ? "disable" : "enable"]();
-    }
-};
-Ext.util.TextMetrics = function(){
-    var shared;
-    return {
-        
-        measure : function(el, text, fixedWidth){
-            if(!shared){
-                shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
+    destroy : function(){
+        if(!this.isDestroyed){
+            if(this.fireEvent('beforedestroy', this) !== false){
+                this.destroying = true;
+                this.beforeDestroy();
+                if(this.ownerCt && this.ownerCt.remove){
+                    this.ownerCt.remove(this, false);
+                }
+                if(this.rendered){
+                    this.el.remove();
+                    if(this.actionMode == 'container' || this.removeMode == 'container'){
+                        this.container.remove();
+                    }
+                }
+                
+                if(this.focusTask && this.focusTask.cancel){
+                    this.focusTask.cancel();
+                }
+                this.onDestroy();
+                Ext.ComponentMgr.unregister(this);
+                this.fireEvent('destroy', this);
+                this.purgeListeners();
+                this.destroying = false;
+                this.isDestroyed = true;
             }
-            shared.bind(el);
-            shared.setFixedWidth(fixedWidth || 'auto');
-            return shared.getSize(text);
-        },
-
-        
-        createInstance : function(el, fixedWidth){
-            return Ext.util.TextMetrics.Instance(el, fixedWidth);
         }
-    };
-}();
-
-Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
-    var ml = new Ext.Element(document.createElement('div'));
-    document.body.appendChild(ml.dom);
-    ml.position('absolute');
-    ml.setLeftTop(-1000, -1000);
-    ml.hide();
-
-    if(fixedWidth){
-        ml.setWidth(fixedWidth);
-    }
-
-    var instance = {
-        
-        getSize : function(text){
-            ml.update(text);
-            var s = ml.getSize();
-            ml.update('');
-            return s;
-        },
-
-        
-        bind : function(el){
-            ml.setStyle(
-                Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
-            );
-        },
-
-        
-        setFixedWidth : function(width){
-            ml.setWidth(width);
-        },
-
-        
-        getWidth : function(text){
-            ml.dom.style.width = 'auto';
-            return this.getSize(text).width;
-        },
+    },
 
-        
-        getHeight : function(text){
-            return this.getSize(text).height;
+    deleteMembers : function(){
+        var args = arguments;
+        for(var i = 0, len = args.length; i < len; ++i){
+            delete this[args[i]];
         }
-    };
+    },
 
-    instance.bind(bindTo);
+    
+    beforeDestroy : Ext.emptyFn,
 
-    return instance;
-};
+    
+    onDestroy  : Ext.emptyFn,
 
-Ext.Element.addMethods({
     
-    getTextWidth : function(text, min, max){
-        return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
-    }
-});
+    getEl : function(){
+        return this.el;
+    },
 
-Ext.util.Cookies = {
     
-    set : function(name, value){
-        var argv = arguments;
-        var argc = arguments.length;
-        var expires = (argc > 2) ? argv[2] : null;
-        var path = (argc > 3) ? argv[3] : '/';
-        var domain = (argc > 4) ? argv[4] : null;
-        var secure = (argc > 5) ? argv[5] : false;
-        document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
+    getContentTarget : function(){
+        return this.el;
     },
 
     
-    get : function(name){
-        var arg = name + "=";
-        var alen = arg.length;
-        var clen = document.cookie.length;
-        var i = 0;
-        var j = 0;
-        while(i < clen){
-            j = i + alen;
-            if(document.cookie.substring(i, j) == arg){
-                return Ext.util.Cookies.getCookieVal(j);
-            }
-            i = document.cookie.indexOf(" ", i) + 1;
-            if(i === 0){
-                break;
+    getId : function(){
+        return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
+    },
+
+    
+    getItemId : function(){
+        return this.itemId || this.getId();
+    },
+
+    
+    focus : function(selectText, delay){
+        if(delay){
+            this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
+            this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
+            return this;
+        }
+        if(this.rendered && !this.isDestroyed){
+            this.el.focus();
+            if(selectText === true){
+                this.el.dom.select();
             }
         }
-        return null;
+        return this;
     },
 
     
-    clear : function(name){
-        if(Ext.util.Cookies.get(name)){
-            document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
+    blur : function(){
+        if(this.rendered){
+            this.el.blur();
         }
+        return this;
     },
+
     
-    getCookieVal : function(offset){
-        var endstr = document.cookie.indexOf(";", offset);
-        if(endstr == -1){
-            endstr = document.cookie.length;
+    disable : function( silent){
+        if(this.rendered){
+            this.onDisable();
         }
-        return unescape(document.cookie.substring(offset, endstr));
-    }
-};
-Ext.handleError = function(e) {
-    throw e;
-};
+        this.disabled = true;
+        if(silent !== true){
+            this.fireEvent('disable', this);
+        }
+        return this;
+    },
 
+    
+    onDisable : function(){
+        this.getActionEl().addClass(this.disabledClass);
+        this.el.dom.disabled = true;
+    },
 
-Ext.Error = function(message) {
     
-    this.message = (this.lang[message]) ? this.lang[message] : message;
-}
-Ext.Error.prototype = new Error();
-Ext.apply(Ext.Error.prototype, {
+    enable : function(){
+        if(this.rendered){
+            this.onEnable();
+        }
+        this.disabled = false;
+        this.fireEvent('enable', this);
+        return this;
+    },
+
     
-    lang: {},
+    onEnable : function(){
+        this.getActionEl().removeClass(this.disabledClass);
+        this.el.dom.disabled = false;
+    },
 
-    name: 'Ext.Error',
     
-    getName : function() {
-        return this.name;
+    setDisabled : function(disabled){
+        return this[disabled ? 'disable' : 'enable']();
     },
+
     
-    getMessage : function() {
-        return this.message;
+    show : function(){
+        if(this.fireEvent('beforeshow', this) !== false){
+            this.hidden = false;
+            if(this.autoRender){
+                this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
+            }
+            if(this.rendered){
+                this.onShow();
+            }
+            this.fireEvent('show', this);
+        }
+        return this;
     },
+
     
-    toJson : function() {
-        return Ext.encode(this);
-    }
-});
+    onShow : function(){
+        this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
+    },
 
+    
+    hide : function(){
+        if(this.fireEvent('beforehide', this) !== false){
+            this.doHide();
+            this.fireEvent('hide', this);
+        }
+        return this;
+    },
 
-Ext.ComponentMgr = function(){
-    var all = new Ext.util.MixedCollection();
-    var types = {};
-    var ptypes = {};
+    
+    doHide: function(){
+        this.hidden = true;
+        if(this.rendered){
+            this.onHide();
+        }
+    },
 
-    return {
-        
-        register : function(c){
-            all.add(c);
-        },
+    
+    onHide : function(){
+        this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
+    },
 
-        
-        unregister : function(c){
-            all.remove(c);
-        },
+    
+    getVisibilityEl : function(){
+        return this.hideParent ? this.container : this.getActionEl();
+    },
 
-        
-        get : function(id){
-            return all.get(id);
-        },
+    
+    setVisible : function(visible){
+        return this[visible ? 'show' : 'hide']();
+    },
 
-        
-        onAvailable : function(id, fn, scope){
-            all.on("add", function(index, o){
-                if(o.id == id){
-                    fn.call(scope || o, o);
-                    all.un("add", fn, scope);
-                }
-            });
-        },
+    
+    isVisible : function(){
+        return this.rendered && this.getVisibilityEl().isVisible();
+    },
 
-        
-        all : all,
-        
-        
-        isRegistered : function(xtype){
-            return types[xtype] !== undefined;    
-        },
+    
+    cloneConfig : function(overrides){
+        overrides = overrides || {};
+        var id = overrides.id || Ext.id();
+        var cfg = Ext.applyIf(overrides, this.initialConfig);
+        cfg.id = id; 
+        return new this.constructor(cfg);
+    },
 
-        
-        registerType : function(xtype, cls){
-            types[xtype] = cls;
-            cls.xtype = xtype;
-        },
+    
+    getXType : function(){
+        return this.constructor.xtype;
+    },
 
+    
+    isXType : function(xtype, shallow){
         
-        create : function(config, defaultType){
-            return config.render ? config : new types[config.xtype || defaultType](config);
-        },
+        if (Ext.isFunction(xtype)){
+            xtype = xtype.xtype; 
+        }else if (Ext.isObject(xtype)){
+            xtype = xtype.constructor.xtype; 
+        }
 
-        
-        registerPlugin : function(ptype, cls){
-            ptypes[ptype] = cls;
-            cls.ptype = ptype;
-        },
+        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
+    },
 
-        
-        createPlugin : function(config, defaultType){
-            var PluginCls = ptypes[config.ptype || defaultType];
-            if (PluginCls.init) {
-                return PluginCls;                
-            } else {
-                return new PluginCls(config);
-            }            
+    
+    getXTypes : function(){
+        var tc = this.constructor;
+        if(!tc.xtypes){
+            var c = [], sc = this;
+            while(sc && sc.constructor.xtype){
+                c.unshift(sc.constructor.xtype);
+                sc = sc.constructor.superclass;
+            }
+            tc.xtypeChain = c;
+            tc.xtypes = c.join('/');
         }
-    };
-}();
+        return tc.xtypes;
+    },
 
+    
+    findParentBy : function(fn) {
+        for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
+        return p || null;
+    },
 
-Ext.reg = Ext.ComponentMgr.registerType; 
+    
+    findParentByType : function(xtype, shallow){
+        return this.findParentBy(function(c){
+            return c.isXType(xtype, shallow);
+        });
+    },
+    
+    
+    bubble : function(fn, scope, args){
+        var p = this;
+        while(p){
+            if(fn.apply(scope || p, args || [p]) === false){
+                break;
+            }
+            p = p.ownerCt;
+        }
+        return this;
+    },
 
-Ext.preg = Ext.ComponentMgr.registerPlugin;
+    
+    getPositionEl : function(){
+        return this.positionEl || this.el;
+    },
 
-Ext.create = Ext.ComponentMgr.create;
-Ext.Component = function(config){
-    config = config || {};
-    if(config.initialConfig){
-        if(config.isAction){           
-            this.baseAction = config;
+    
+    purgeListeners : function(){
+        Ext.Component.superclass.purgeListeners.call(this);
+        if(this.mons){
+            this.on('beforedestroy', this.clearMons, this, {single: true});
         }
-        config = config.initialConfig; 
-    }else if(config.tagName || config.dom || Ext.isString(config)){ 
-        config = {applyTo: config, id: config.id || config};
-    }
+    },
 
     
-    this.initialConfig = config;
-
-    Ext.apply(this, config);
-    this.addEvents(
-        
-        'added',
-        
-        'disable',
-        
-        'enable',
-        
-        'beforeshow',
-        
-        'show',
-        
-        'beforehide',
-        
-        'hide',
-        
-        'removed',
-        
-        'beforerender',
-        
-        'render',
-        
-        'afterrender',
-        
-        'beforedestroy',
-        
-        'destroy',
-        
-        'beforestaterestore',
-        
-        'staterestore',
-        
-        'beforestatesave',
-        
-        'statesave'
-    );
-    this.getId();
-    Ext.ComponentMgr.register(this);
-    Ext.Component.superclass.constructor.call(this);
+    clearMons : function(){
+        Ext.each(this.mons, function(m){
+            m.item.un(m.ename, m.fn, m.scope);
+        }, this);
+        this.mons = [];
+    },
 
-    if(this.baseAction){
-        this.baseAction.addComponent(this);
-    }
+    
+    createMons: function(){
+        if(!this.mons){
+            this.mons = [];
+            this.on('beforedestroy', this.clearMons, this, {single: true});
+        }
+    },
 
-    this.initComponent();
+    
+    mon : function(item, ename, fn, scope, opt){
+        this.createMons();
+        if(Ext.isObject(ename)){
+            var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
 
-    if(this.plugins){
-        if(Ext.isArray(this.plugins)){
-            for(var i = 0, len = this.plugins.length; i < len; i++){
-                this.plugins[i] = this.initPlugin(this.plugins[i]);
+            var o = ename;
+            for(var e in o){
+                if(propRe.test(e)){
+                    continue;
+                }
+                if(Ext.isFunction(o[e])){
+                    
+                    this.mons.push({
+                        item: item, ename: e, fn: o[e], scope: o.scope
+                    });
+                    item.on(e, o[e], o.scope, o);
+                }else{
+                    
+                    this.mons.push({
+                        item: item, ename: e, fn: o[e], scope: o.scope
+                    });
+                    item.on(e, o[e]);
+                }
             }
-        }else{
-            this.plugins = this.initPlugin(this.plugins);
+            return;
         }
-    }
-
-    if(this.stateful !== false){
-        this.initState();
-    }
 
-    if(this.applyTo){
-        this.applyToMarkup(this.applyTo);
-        delete this.applyTo;
-    }else if(this.renderTo){
-        this.render(this.renderTo);
-        delete this.renderTo;
-    }
-};
-
-
-Ext.Component.AUTO_ID = 1000;
+        this.mons.push({
+            item: item, ename: ename, fn: fn, scope: scope
+        });
+        item.on(ename, fn, scope, opt);
+    },
 
-Ext.extend(Ext.Component, Ext.util.Observable, {
-    
-    
-    
-    
-    
-    
     
+    mun : function(item, ename, fn, scope){
+        var found, mon;
+        this.createMons();
+        for(var i = 0, len = this.mons.length; i < len; ++i){
+            mon = this.mons[i];
+            if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
+                this.mons.splice(i, 1);
+                item.un(ename, fn, scope);
+                found = true;
+                break;
+            }
+        }
+        return found;
+    },
 
     
-    
+    nextSibling : function(){
+        if(this.ownerCt){
+            var index = this.ownerCt.items.indexOf(this);
+            if(index != -1 && index+1 < this.ownerCt.items.getCount()){
+                return this.ownerCt.items.itemAt(index+1);
+            }
+        }
+        return null;
+    },
 
     
+    previousSibling : function(){
+        if(this.ownerCt){
+            var index = this.ownerCt.items.indexOf(this);
+            if(index > 0){
+                return this.ownerCt.items.itemAt(index-1);
+            }
+        }
+        return null;
+    },
+
     
+    getBubbleTarget : function(){
+        return this.ownerCt;
+    }
+});
+
+Ext.reg('component', Ext.Component);
+
+Ext.Action = Ext.extend(Object, {
     
     
     
@@ -9300,4394 +11362,5441 @@ Ext.extend(Ext.Component, Ext.util.Observable, {
     
     
     
-    disabled : false,
-    
-    hidden : false,
-    
-    
-    
-    
-    
-    
-    
-    autoEl : 'div',
 
+    constructor : function(config){
+        this.initialConfig = config;
+        this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
+        this.items = [];
+    },
     
-    disabledClass : 'x-item-disabled',
-    
-    allowDomMove : true,
-    
-    autoShow : false,
-    
-    hideMode : 'display',
     
-    hideParent : false,
+    isAction : true,
+
     
+    setText : function(text){
+        this.initialConfig.text = text;
+        this.callEach('setText', [text]);
+    },
+
     
+    getText : function(){
+        return this.initialConfig.text;
+    },
+
     
+    setIconClass : function(cls){
+        this.initialConfig.iconCls = cls;
+        this.callEach('setIconClass', [cls]);
+    },
+
     
+    getIconClass : function(){
+        return this.initialConfig.iconCls;
+    },
+
     
-    rendered : false,
+    setDisabled : function(v){
+        this.initialConfig.disabled = v;
+        this.callEach('setDisabled', [v]);
+    },
 
     
+    enable : function(){
+        this.setDisabled(false);
+    },
+
     
+    disable : function(){
+        this.setDisabled(true);
+    },
 
     
+    isDisabled : function(){
+        return this.initialConfig.disabled;
+    },
 
     
-    tplWriteMode : 'overwrite',
+    setHidden : function(v){
+        this.initialConfig.hidden = v;
+        this.callEach('setVisible', [!v]);
+    },
 
     
+    show : function(){
+        this.setHidden(false);
+    },
 
+    
+    hide : function(){
+        this.setHidden(true);
+    },
 
     
-    ctype : 'Ext.Component',
+    isHidden : function(){
+        return this.initialConfig.hidden;
+    },
 
     
-    actionMode : 'el',
+    setHandler : function(fn, scope){
+        this.initialConfig.handler = fn;
+        this.initialConfig.scope = scope;
+        this.callEach('setHandler', [fn, scope]);
+    },
 
     
-    getActionEl : function(){
-        return this[this.actionMode];
+    each : function(fn, scope){
+        Ext.each(this.items, fn, scope);
     },
 
-    initPlugin : function(p){
-        if(p.ptype && !Ext.isFunction(p.init)){
-            p = Ext.ComponentMgr.createPlugin(p);
-        }else if(Ext.isString(p)){
-            p = Ext.ComponentMgr.createPlugin({
-                ptype: p
-            });
+    
+    callEach : function(fnName, args){
+        var cs = this.items;
+        for(var i = 0, len = cs.length; i < len; i++){
+            cs[i][fnName].apply(cs[i], args);
         }
-        p.init(this);
-        return p;
     },
 
     
-    initComponent : Ext.emptyFn,
+    addComponent : function(comp){
+        this.items.push(comp);
+        comp.on('destroy', this.removeComponent, this);
+    },
 
     
-    render : function(container, position){
-        if(!this.rendered && this.fireEvent('beforerender', this) !== false){
-            if(!container && this.el){
-                this.el = Ext.get(this.el);
-                container = this.el.dom.parentNode;
-                this.allowDomMove = false;
-            }
-            this.container = Ext.get(container);
-            if(this.ctCls){
-                this.container.addClass(this.ctCls);
-            }
-            this.rendered = true;
-            if(position !== undefined){
-                if(Ext.isNumber(position)){
-                    position = this.container.dom.childNodes[position];
-                }else{
-                    position = Ext.getDom(position);
-                }
-            }
-            this.onRender(this.container, position || null);
-            if(this.autoShow){
-                this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
-            }
-            if(this.cls){
-                this.el.addClass(this.cls);
-                delete this.cls;
-            }
-            if(this.style){
-                this.el.applyStyles(this.style);
-                delete this.style;
-            }
-            if(this.overCls){
-                this.el.addClassOnOver(this.overCls);
-            }
-            this.fireEvent('render', this);
+    removeComponent : function(comp){
+        this.items.remove(comp);
+    },
 
+    
+    execute : function(){
+        this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
+    }
+});
 
-            
-            
-            var contentTarget = this.getContentTarget();
-            if (this.html){
-                contentTarget.update(Ext.DomHelper.markup(this.html));
-                delete this.html;
-            }
-            if (this.contentEl){
-                var ce = Ext.getDom(this.contentEl);
-                Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
-                contentTarget.appendChild(ce);
-            }
-            if (this.tpl) {
-                if (!this.tpl.compile) {
-                    this.tpl = new Ext.XTemplate(this.tpl);
-                }
-                if (this.data) {
-                    this.tpl[this.tplWriteMode](contentTarget, this.data);
-                    delete this.data;
-                }
-            }
-            this.afterRender(this.container);
+(function(){
+Ext.Layer = function(config, existingEl){
+    config = config || {};
+    var dh = Ext.DomHelper,
+        cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
+        
+    if (existingEl) {
+        this.dom = Ext.getDom(existingEl);
+    }
+    if(!this.dom){
+        var o = config.dh || {tag: 'div', cls: 'x-layer'};
+        this.dom = dh.append(pel, o);
+    }
+    if(config.cls){
+        this.addClass(config.cls);
+    }
+    this.constrain = config.constrain !== false;
+    this.setVisibilityMode(Ext.Element.VISIBILITY);
+    if(config.id){
+        this.id = this.dom.id = config.id;
+    }else{
+        this.id = Ext.id(this.dom);
+    }
+    this.zindex = config.zindex || this.getZIndex();
+    this.position('absolute', this.zindex);
+    if(config.shadow){
+        this.shadowOffset = config.shadowOffset || 4;
+        this.shadow = new Ext.Shadow({
+            offset : this.shadowOffset,
+            mode : config.shadow
+        });
+    }else{
+        this.shadowOffset = 0;
+    }
+    this.useShim = config.shim !== false && Ext.useShims;
+    this.useDisplay = config.useDisplay;
+    this.hide();
+};
 
+var supr = Ext.Element.prototype;
 
-            if(this.hidden){
-                
-                this.doHide();
-            }
-            if(this.disabled){
-                
-                this.disable(true);
-            }
 
-            if(this.stateful !== false){
-                this.initStateEvents();
-            }
-            this.fireEvent('afterrender', this);
-        }
-        return this;
-    },
+var shims = [];
 
+Ext.extend(Ext.Layer, Ext.Element, {
 
-    
-    update: function(htmlOrData, loadScripts, cb) {
-        var contentTarget = this.getContentTarget();
-        if (this.tpl && typeof htmlOrData !== "string") {
-            this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
-        } else {
-            var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
-            contentTarget.update(html, loadScripts, cb);
-        }
+    getZIndex : function(){
+        return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
     },
 
-
-    
-    onAdded : function(container, pos) {
-        this.ownerCt = container;
-        this.initRef();
-        this.fireEvent('added', this, container, pos);
+    getShim : function(){
+        if(!this.useShim){
+            return null;
+        }
+        if(this.shim){
+            return this.shim;
+        }
+        var shim = shims.shift();
+        if(!shim){
+            shim = this.createShim();
+            shim.enableDisplayMode('block');
+            shim.dom.style.display = 'none';
+            shim.dom.style.visibility = 'visible';
+        }
+        var pn = this.dom.parentNode;
+        if(shim.dom.parentNode != pn){
+            pn.insertBefore(shim.dom, this.dom);
+        }
+        shim.setStyle('z-index', this.getZIndex()-2);
+        this.shim = shim;
+        return shim;
     },
 
-    
-    onRemoved : function() {
-        this.removeRef();
-        this.fireEvent('removed', this, this.ownerCt);
-        delete this.ownerCt;
+    hideShim : function(){
+        if(this.shim){
+            this.shim.setDisplayed(false);
+            shims.push(this.shim);
+            delete this.shim;
+        }
     },
 
-    
-    initRef : function() {
-        
-        if(this.ref && !this.refOwner){
-            var levels = this.ref.split('/'),
-                last = levels.length, 
-                i = 0,
-                t = this;
-                
-            while(t && i < last){
-                t = t.ownerCt;
-                ++i;
-            }
-            if(t){
-                t[this.refName = levels[--i]] = this;
-                
-                this.refOwner = t;
-            }
+    disableShadow : function(){
+        if(this.shadow){
+            this.shadowDisabled = true;
+            this.shadow.hide();
+            this.lastShadowOffset = this.shadowOffset;
+            this.shadowOffset = 0;
         }
     },
 
-    removeRef : function() {
-        if (this.refOwner && this.refName) {
-            delete this.refOwner[this.refName];
-            delete this.refOwner;
+    enableShadow : function(show){
+        if(this.shadow){
+            this.shadowDisabled = false;
+            this.shadowOffset = this.lastShadowOffset;
+            delete this.lastShadowOffset;
+            if(show){
+                this.sync(true);
+            }
         }
     },
 
     
-    initState : function(){
-        if(Ext.state.Manager){
-            var id = this.getStateId();
-            if(id){
-                var state = Ext.state.Manager.get(id);
-                if(state){
-                    if(this.fireEvent('beforestaterestore', this, state) !== false){
-                        this.applyState(Ext.apply({}, state));
-                        this.fireEvent('staterestore', this, state);
+    
+    
+    sync : function(doShow){
+        var shadow = this.shadow;
+        if(!this.updating && this.isVisible() && (shadow || this.useShim)){
+            var shim = this.getShim(),
+                w = this.getWidth(),
+                h = this.getHeight(),
+                l = this.getLeft(true),
+                t = this.getTop(true);
+
+            if(shadow && !this.shadowDisabled){
+                if(doShow && !shadow.isVisible()){
+                    shadow.show(this);
+                }else{
+                    shadow.realign(l, t, w, h);
+                }
+                if(shim){
+                    if(doShow){
+                       shim.show();
                     }
+                    
+                    var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
+                        shadowSize = shadow.el.getSize();
+                    shimStyle.left = (shadowAdj[0])+'px';
+                    shimStyle.top = (shadowAdj[1])+'px';
+                    shimStyle.width = (shadowSize.width)+'px';
+                    shimStyle.height = (shadowSize.height)+'px';
+                }
+            }else if(shim){
+                if(doShow){
+                   shim.show();
                 }
+                shim.setSize(w, h);
+                shim.setLeftTop(l, t);
             }
         }
     },
 
     
-    getStateId : function(){
-        return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id);
+    destroy : function(){
+        this.hideShim();
+        if(this.shadow){
+            this.shadow.hide();
+        }
+        this.removeAllListeners();
+        Ext.removeNode(this.dom);
+        delete this.dom;
+    },
+
+    remove : function(){
+        this.destroy();
     },
 
     
-    initStateEvents : function(){
-        if(this.stateEvents){
-            for(var i = 0, e; e = this.stateEvents[i]; i++){
-                this.on(e, this.saveState, this, {delay:100});
-            }
-        }
+    beginUpdate : function(){
+        this.updating = true;
     },
 
     
-    applyState : function(state){
-        if(state){
-            Ext.apply(this, state);
-        }
+    endUpdate : function(){
+        this.updating = false;
+        this.sync(true);
     },
 
     
-    getState : function(){
-        return null;
+    hideUnders : function(negOffset){
+        if(this.shadow){
+            this.shadow.hide();
+        }
+        this.hideShim();
     },
 
     
-    saveState : function(){
-        if(Ext.state.Manager && this.stateful !== false){
-            var id = this.getStateId();
-            if(id){
-                var state = this.getState();
-                if(this.fireEvent('beforestatesave', this, state) !== false){
-                    Ext.state.Manager.set(id, state);
-                    this.fireEvent('statesave', this, state);
+    constrainXY : function(){
+        if(this.constrain){
+            var vw = Ext.lib.Dom.getViewWidth(),
+                vh = Ext.lib.Dom.getViewHeight();
+            var s = Ext.getDoc().getScroll();
+
+            var xy = this.getXY();
+            var x = xy[0], y = xy[1];
+            var so = this.shadowOffset;
+            var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
+            
+            var moved = false;
+            
+            if((x + w) > vw+s.left){
+                x = vw - w - so;
+                moved = true;
+            }
+            if((y + h) > vh+s.top){
+                y = vh - h - so;
+                moved = true;
+            }
+            
+            if(x < s.left){
+                x = s.left;
+                moved = true;
+            }
+            if(y < s.top){
+                y = s.top;
+                moved = true;
+            }
+            if(moved){
+                if(this.avoidY){
+                    var ay = this.avoidY;
+                    if(y <= ay && (y+h) >= ay){
+                        y = ay-h-5;
+                    }
                 }
+                xy = [x, y];
+                this.storeXY(xy);
+                supr.setXY.call(this, xy);
+                this.sync();
             }
         }
+        return this;
     },
-
     
-    applyToMarkup : function(el){
-        this.allowDomMove = false;
-        this.el = Ext.get(el);
-        this.render(this.el.dom.parentNode);
+    getConstrainOffset : function(){
+        return this.shadowOffset;    
+    },
+
+    isVisible : function(){
+        return this.visible;
     },
 
     
-    addClass : function(cls){
-        if(this.el){
-            this.el.addClass(cls);
-        }else{
-            this.cls = this.cls ? this.cls + ' ' + cls : cls;
+    showAction : function(){
+        this.visible = true; 
+        if(this.useDisplay === true){
+            this.setDisplayed('');
+        }else if(this.lastXY){
+            supr.setXY.call(this, this.lastXY);
+        }else if(this.lastLT){
+            supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
         }
-        return this;
     },
 
     
-    removeClass : function(cls){
-        if(this.el){
-            this.el.removeClass(cls);
-        }else if(this.cls){
-            this.cls = this.cls.split(' ').remove(cls).join(' ');
+    hideAction : function(){
+        this.visible = false;
+        if(this.useDisplay === true){
+            this.setDisplayed(false);
+        }else{
+            this.setLeftTop(-10000,-10000);
         }
-        return this;
     },
 
     
-    
-    onRender : function(ct, position){
-        if(!this.el && this.autoEl){
-            if(Ext.isString(this.autoEl)){
-                this.el = document.createElement(this.autoEl);
-            }else{
-                var div = document.createElement('div');
-                Ext.DomHelper.overwrite(div, this.autoEl);
-                this.el = div.firstChild;
-            }
-            if (!this.el.id) {
-                this.el.id = this.getId();
-            }
+    setVisible : function(v, a, d, c, e){
+        if(v){
+            this.showAction();
         }
-        if(this.el){
-            this.el = Ext.get(this.el);
-            if(this.allowDomMove !== false){
-                ct.dom.insertBefore(this.el.dom, position);
-                if (div) {
-                    Ext.removeNode(div);
-                    div = null;
+        if(a && v){
+            var cb = function(){
+                this.sync(true);
+                if(c){
+                    c();
                 }
+            }.createDelegate(this);
+            supr.setVisible.call(this, true, true, d, cb, e);
+        }else{
+            if(!v){
+                this.hideUnders(true);
+            }
+            var cb = c;
+            if(a){
+                cb = function(){
+                    this.hideAction();
+                    if(c){
+                        c();
+                    }
+                }.createDelegate(this);
+            }
+            supr.setVisible.call(this, v, a, d, cb, e);
+            if(v){
+                this.sync(true);
+            }else if(!a){
+                this.hideAction();
             }
         }
+        return this;
+    },
+
+    storeXY : function(xy){
+        delete this.lastLT;
+        this.lastXY = xy;
+    },
+
+    storeLeftTop : function(left, top){
+        delete this.lastXY;
+        this.lastLT = [left, top];
     },
 
     
-    getAutoCreate : function(){
-        var cfg = Ext.isObject(this.autoCreate) ?
-                      this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
-        if(this.id && !cfg.id){
-            cfg.id = this.id;
-        }
-        return cfg;
+    beforeFx : function(){
+        this.beforeAction();
+        return Ext.Layer.superclass.beforeFx.apply(this, arguments);
     },
 
     
-    afterRender : Ext.emptyFn,
+    afterFx : function(){
+        Ext.Layer.superclass.afterFx.apply(this, arguments);
+        this.sync(this.isVisible());
+    },
 
     
-    destroy : function(){
-        if(!this.isDestroyed){
-            if(this.fireEvent('beforedestroy', this) !== false){
-                this.destroying = true;
-                this.beforeDestroy();
-                if(this.ownerCt && this.ownerCt.remove){
-                    this.ownerCt.remove(this, false);
-                }
-                if(this.rendered){
-                    this.el.remove();
-                    if(this.actionMode == 'container' || this.removeMode == 'container'){
-                        this.container.remove();
-                    }
-                }
-                this.onDestroy();
-                Ext.ComponentMgr.unregister(this);
-                this.fireEvent('destroy', this);
-                this.purgeListeners();
-                this.destroying = false;
-                this.isDestroyed = true;
-            }
+    beforeAction : function(){
+        if(!this.updating && this.shadow){
+            this.shadow.hide();
         }
     },
 
-    deleteMembers : function(){
-        var args = arguments;
-        for(var i = 0, len = args.length; i < len; ++i){
-            delete this[args[i]];
+    
+    setLeft : function(left){
+        this.storeLeftTop(left, this.getTop(true));
+        supr.setLeft.apply(this, arguments);
+        this.sync();
+        return this;
+    },
+
+    setTop : function(top){
+        this.storeLeftTop(this.getLeft(true), top);
+        supr.setTop.apply(this, arguments);
+        this.sync();
+        return this;
+    },
+
+    setLeftTop : function(left, top){
+        this.storeLeftTop(left, top);
+        supr.setLeftTop.apply(this, arguments);
+        this.sync();
+        return this;
+    },
+
+    setXY : function(xy, a, d, c, e){
+        this.fixDisplay();
+        this.beforeAction();
+        this.storeXY(xy);
+        var cb = this.createCB(c);
+        supr.setXY.call(this, xy, a, d, cb, e);
+        if(!a){
+            cb();
         }
+        return this;
     },
 
     
-    beforeDestroy : Ext.emptyFn,
-
-    
-    onDestroy  : Ext.emptyFn,
+    createCB : function(c){
+        var el = this;
+        return function(){
+            el.constrainXY();
+            el.sync(true);
+            if(c){
+                c();
+            }
+        };
+    },
 
     
-    getEl : function(){
-        return this.el;
+    setX : function(x, a, d, c, e){
+        this.setXY([x, this.getY()], a, d, c, e);
+        return this;
     },
 
     
-    getContentTarget : function(){
-        return this.el;
+    setY : function(y, a, d, c, e){
+        this.setXY([this.getX(), y], a, d, c, e);
+        return this;
     },
 
     
-    getId : function(){
-        return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
+    setSize : function(w, h, a, d, c, e){
+        this.beforeAction();
+        var cb = this.createCB(c);
+        supr.setSize.call(this, w, h, a, d, cb, e);
+        if(!a){
+            cb();
+        }
+        return this;
     },
 
     
-    getItemId : function(){
-        return this.itemId || this.getId();
+    setWidth : function(w, a, d, c, e){
+        this.beforeAction();
+        var cb = this.createCB(c);
+        supr.setWidth.call(this, w, a, d, cb, e);
+        if(!a){
+            cb();
+        }
+        return this;
     },
 
     
-    focus : function(selectText, delay){
-        if(delay){
-            this.focus.defer(Ext.isNumber(delay) ? delay : 10, this, [selectText, false]);
-            return;
-        }
-        if(this.rendered){
-            this.el.focus();
-            if(selectText === true){
-                this.el.dom.select();
-            }
+    setHeight : function(h, a, d, c, e){
+        this.beforeAction();
+        var cb = this.createCB(c);
+        supr.setHeight.call(this, h, a, d, cb, e);
+        if(!a){
+            cb();
         }
         return this;
     },
 
     
-    blur : function(){
-        if(this.rendered){
-            this.el.blur();
+    setBounds : function(x, y, w, h, a, d, c, e){
+        this.beforeAction();
+        var cb = this.createCB(c);
+        if(!a){
+            this.storeXY([x, y]);
+            supr.setXY.call(this, [x, y]);
+            supr.setSize.call(this, w, h, a, d, cb, e);
+            cb();
+        }else{
+            supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
         }
         return this;
     },
 
     
-    disable : function( silent){
-        if(this.rendered){
-            this.onDisable();
+    setZIndex : function(zindex){
+        this.zindex = zindex;
+        this.setStyle('z-index', zindex + 2);
+        if(this.shadow){
+            this.shadow.setZIndex(zindex + 1);
         }
-        this.disabled = true;
-        if(silent !== true){
-            this.fireEvent('disable', this);
+        if(this.shim){
+            this.shim.setStyle('z-index', zindex);
         }
         return this;
-    },
+    }
+});
+})();
+
+Ext.Shadow = function(config) {
+    Ext.apply(this, config);
+    if (typeof this.mode != "string") {
+        this.mode = this.defaultMode;
+    }
+    var o = this.offset,
+        a = {
+            h: 0
+        },
+        rad = Math.floor(this.offset / 2);
+    switch (this.mode.toLowerCase()) {
+        
+        case "drop":
+            a.w = 0;
+            a.l = a.t = o;
+            a.t -= 1;
+            if (Ext.isIE) {
+                a.l -= this.offset + rad;
+                a.t -= this.offset + rad;
+                a.w -= rad;
+                a.h -= rad;
+                a.t += 1;
+            }
+        break;
+        case "sides":
+            a.w = (o * 2);
+            a.l = -o;
+            a.t = o - 1;
+            if (Ext.isIE) {
+                a.l -= (this.offset - rad);
+                a.t -= this.offset + rad;
+                a.l += 1;
+                a.w -= (this.offset - rad) * 2;
+                a.w -= rad + 1;
+                a.h -= 1;
+            }
+        break;
+        case "frame":
+            a.w = a.h = (o * 2);
+            a.l = a.t = -o;
+            a.t += 1;
+            a.h -= 2;
+            if (Ext.isIE) {
+                a.l -= (this.offset - rad);
+                a.t -= (this.offset - rad);
+                a.l += 1;
+                a.w -= (this.offset + rad + 1);
+                a.h -= (this.offset + rad);
+                a.h += 1;
+            }
+        break;
+    };
 
+    this.adjusts = a;
+};
+
+Ext.Shadow.prototype = {
     
-    onDisable : function(){
-        this.getActionEl().addClass(this.disabledClass);
-        this.el.dom.disabled = true;
-    },
+    
+    offset: 4,
 
     
-    enable : function(){
-        if(this.rendered){
-            this.onEnable();
-        }
-        this.disabled = false;
-        this.fireEvent('enable', this);
-        return this;
-    },
+    defaultMode: "drop",
 
     
-    onEnable : function(){
-        this.getActionEl().removeClass(this.disabledClass);
-        this.el.dom.disabled = false;
+    show: function(target) {
+        target = Ext.get(target);
+        if (!this.el) {
+            this.el = Ext.Shadow.Pool.pull();
+            if (this.el.dom.nextSibling != target.dom) {
+                this.el.insertBefore(target);
+            }
+        }
+        this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
+        if (Ext.isIE) {
+            this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
+        }
+        this.realign(
+        target.getLeft(true),
+        target.getTop(true),
+        target.getWidth(),
+        target.getHeight()
+        );
+        this.el.dom.style.display = "block";
     },
 
     
-    setDisabled : function(disabled){
-        return this[disabled ? 'disable' : 'enable']();
+    isVisible: function() {
+        return this.el ? true: false;
     },
 
     
-    show : function(){
-        if(this.fireEvent('beforeshow', this) !== false){
-            this.hidden = false;
-            if(this.autoRender){
-                this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
-            }
-            if(this.rendered){
-                this.onShow();
+    realign: function(l, t, w, h) {
+        if (!this.el) {
+            return;
+        }
+        var a = this.adjusts,
+            d = this.el.dom,
+            s = d.style,
+            iea = 0,
+            sw = (w + a.w),
+            sh = (h + a.h),
+            sws = sw + "px",
+            shs = sh + "px",
+            cn,
+            sww;
+        s.left = (l + a.l) + "px";
+        s.top = (t + a.t) + "px";
+        if (s.width != sws || s.height != shs) {
+            s.width = sws;
+            s.height = shs;
+            if (!Ext.isIE) {
+                cn = d.childNodes;
+                sww = Math.max(0, (sw - 12)) + "px";
+                cn[0].childNodes[1].style.width = sww;
+                cn[1].childNodes[1].style.width = sww;
+                cn[2].childNodes[1].style.width = sww;
+                cn[1].style.height = Math.max(0, (sh - 12)) + "px";
             }
-            this.fireEvent('show', this);
         }
-        return this;
     },
 
     
-    onShow : function(){
-        this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
+    hide: function() {
+        if (this.el) {
+            this.el.dom.style.display = "none";
+            Ext.Shadow.Pool.push(this.el);
+            delete this.el;
+        }
     },
 
     
-    hide : function(){
-        if(this.fireEvent('beforehide', this) !== false){
-            this.doHide();
-            this.fireEvent('hide', this);
+    setZIndex: function(z) {
+        this.zIndex = z;
+        if (this.el) {
+            this.el.setStyle("z-index", z);
         }
-        return this;
-    },
+    }
+};
 
-    
-    doHide: function(){
-        this.hidden = true;
-        if(this.rendered){
-            this.onHide();
+
+Ext.Shadow.Pool = function() {
+    var p = [],
+        markup = Ext.isIE ?
+            '<div class="x-ie-shadow"></div>':
+            '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
+    return {
+        pull: function() {
+            var sh = p.shift();
+            if (!sh) {
+                sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
+                sh.autoBoxAdjust = false;
+            }
+            return sh;
+        },
+
+        push: function(sh) {
+            p.push(sh);
         }
-    },
+    };
+}();
+Ext.BoxComponent = Ext.extend(Ext.Component, {
 
     
-    onHide : function(){
-        this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
-    },
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
 
     
-    getVisibilityEl : function(){
-        return this.hideParent ? this.container : this.getActionEl();
-    },
 
     
-    setVisible : function(visible){
-        return this[visible ? 'show' : 'hide']();
+    initComponent : function(){
+        Ext.BoxComponent.superclass.initComponent.call(this);
+        this.addEvents(
+            
+            'resize',
+            
+            'move'
+        );
     },
 
     
-    isVisible : function(){
-        return this.rendered && this.getVisibilityEl().isVisible();
+    boxReady : false,
+    
+    deferHeight: false,
+
+    
+    setSize : function(w, h){
+
+        
+        if(typeof w == 'object'){
+            h = w.height;
+            w = w.width;
+        }
+        if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
+            w = this.boxMinWidth;
+        }
+        if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
+            h = this.boxMinHeight;
+        }
+        if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
+            w = this.boxMaxWidth;
+        }
+        if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
+            h = this.boxMaxHeight;
+        }
+        
+        if(!this.boxReady){
+            this.width  = w;
+            this.height = h;
+            return this;
+        }
+
+        
+        if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
+            return this;
+        }
+        this.lastSize = {width: w, height: h};
+        var adj = this.adjustSize(w, h),
+            aw = adj.width,
+            ah = adj.height,
+            rz;
+        if(aw !== undefined || ah !== undefined){ 
+            rz = this.getResizeEl();
+            if(!this.deferHeight && aw !== undefined && ah !== undefined){
+                rz.setSize(aw, ah);
+            }else if(!this.deferHeight && ah !== undefined){
+                rz.setHeight(ah);
+            }else if(aw !== undefined){
+                rz.setWidth(aw);
+            }
+            this.onResize(aw, ah, w, h);
+            this.fireEvent('resize', this, aw, ah, w, h);
+        }
+        return this;
     },
 
     
-    cloneConfig : function(overrides){
-        overrides = overrides || {};
-        var id = overrides.id || Ext.id();
-        var cfg = Ext.applyIf(overrides, this.initialConfig);
-        cfg.id = id; 
-        return new this.constructor(cfg);
+    setWidth : function(width){
+        return this.setSize(width);
     },
 
     
-    getXType : function(){
-        return this.constructor.xtype;
+    setHeight : function(height){
+        return this.setSize(undefined, height);
     },
 
     
-    isXType : function(xtype, shallow){
-        
-        if (Ext.isFunction(xtype)){
-            xtype = xtype.xtype; 
-        }else if (Ext.isObject(xtype)){
-            xtype = xtype.constructor.xtype; 
-        }
+    getSize : function(){
+        return this.getResizeEl().getSize();
+    },
 
-        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
+    
+    getWidth : function(){
+        return this.getResizeEl().getWidth();
     },
 
     
-    getXTypes : function(){
-        var tc = this.constructor;
-        if(!tc.xtypes){
-            var c = [], sc = this;
-            while(sc && sc.constructor.xtype){
-                c.unshift(sc.constructor.xtype);
-                sc = sc.constructor.superclass;
-            }
-            tc.xtypeChain = c;
-            tc.xtypes = c.join('/');
-        }
-        return tc.xtypes;
+    getHeight : function(){
+        return this.getResizeEl().getHeight();
     },
 
     
-    findParentBy : function(fn) {
-        for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
-        return p || null;
+    getOuterSize : function(){
+        var el = this.getResizeEl();
+        return {width: el.getWidth() + el.getMargins('lr'),
+                height: el.getHeight() + el.getMargins('tb')};
     },
 
     
-    findParentByType : function(xtype) {
-        return Ext.isFunction(xtype) ?
-            this.findParentBy(function(p){
-                return p.constructor === xtype;
-            }) :
-            this.findParentBy(function(p){
-                return p.constructor.xtype === xtype;
-            });
+    getPosition : function(local){
+        var el = this.getPositionEl();
+        if(local === true){
+            return [el.getLeft(true), el.getTop(true)];
+        }
+        return this.xy || el.getXY();
     },
 
     
-    getPositionEl : function(){
-        return this.positionEl || this.el;
+    getBox : function(local){
+        var pos = this.getPosition(local);
+        var s = this.getSize();
+        s.x = pos[0];
+        s.y = pos[1];
+        return s;
     },
 
     
-    purgeListeners : function(){
-        Ext.Component.superclass.purgeListeners.call(this);
-        if(this.mons){
-            this.on('beforedestroy', this.clearMons, this, {single: true});
-        }
+    updateBox : function(box){
+        this.setSize(box.width, box.height);
+        this.setPagePosition(box.x, box.y);
+        return this;
     },
 
     
-    clearMons : function(){
-        Ext.each(this.mons, function(m){
-            m.item.un(m.ename, m.fn, m.scope);
-        }, this);
-        this.mons = [];
+    getResizeEl : function(){
+        return this.resizeEl || this.el;
     },
 
     
-    createMons: function(){
-        if(!this.mons){
-            this.mons = [];
-            this.on('beforedestroy', this.clearMons, this, {single: true});
+    setAutoScroll : function(scroll){
+        if(this.rendered){
+            this.getContentTarget().setOverflow(scroll ? 'auto' : '');
         }
+        this.autoScroll = scroll;
+        return this;
     },
 
     
-    mon : function(item, ename, fn, scope, opt){
-        this.createMons();
-        if(Ext.isObject(ename)){
-            var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
+    setPosition : function(x, y){
+        if(x && typeof x[1] == 'number'){
+            y = x[1];
+            x = x[0];
+        }
+        this.x = x;
+        this.y = y;
+        if(!this.boxReady){
+            return this;
+        }
+        var adj = this.adjustPosition(x, y);
+        var ax = adj.x, ay = adj.y;
 
-            var o = ename;
-            for(var e in o){
-                if(propRe.test(e)){
-                    continue;
-                }
-                if(Ext.isFunction(o[e])){
-                    
-                    this.mons.push({
-                        item: item, ename: e, fn: o[e], scope: o.scope
-                    });
-                    item.on(e, o[e], o.scope, o);
-                }else{
-                    
-                    this.mons.push({
-                        item: item, ename: e, fn: o[e], scope: o.scope
-                    });
-                    item.on(e, o[e]);
-                }
+        var el = this.getPositionEl();
+        if(ax !== undefined || ay !== undefined){
+            if(ax !== undefined && ay !== undefined){
+                el.setLeftTop(ax, ay);
+            }else if(ax !== undefined){
+                el.setLeft(ax);
+            }else if(ay !== undefined){
+                el.setTop(ay);
             }
-            return;
+            this.onPosition(ax, ay);
+            this.fireEvent('move', this, ax, ay);
         }
+        return this;
+    },
 
-        this.mons.push({
-            item: item, ename: ename, fn: fn, scope: scope
-        });
-        item.on(ename, fn, scope, opt);
+    
+    setPagePosition : function(x, y){
+        if(x && typeof x[1] == 'number'){
+            y = x[1];
+            x = x[0];
+        }
+        this.pageX = x;
+        this.pageY = y;
+        if(!this.boxReady){
+            return;
+        }
+        if(x === undefined || y === undefined){ 
+            return;
+        }
+        var p = this.getPositionEl().translatePoints(x, y);
+        this.setPosition(p.left, p.top);
+        return this;
     },
 
     
-    mun : function(item, ename, fn, scope){
-        var found, mon;
-        this.createMons();
-        for(var i = 0, len = this.mons.length; i < len; ++i){
-            mon = this.mons[i];
-            if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
-                this.mons.splice(i, 1);
-                item.un(ename, fn, scope);
-                found = true;
-                break;
-            }
+    afterRender : function(){
+        Ext.BoxComponent.superclass.afterRender.call(this);
+        if(this.resizeEl){
+            this.resizeEl = Ext.get(this.resizeEl);
         }
-        return found;
+        if(this.positionEl){
+            this.positionEl = Ext.get(this.positionEl);
+        }
+        this.boxReady = true;
+        Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
+        this.setSize(this.width, this.height);
+        if(this.x || this.y){
+            this.setPosition(this.x, this.y);
+        }else if(this.pageX || this.pageY){
+            this.setPagePosition(this.pageX, this.pageY);
+        }
+    },
+
+    
+    syncSize : function(){
+        delete this.lastSize;
+        this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
+        return this;
+    },
+
+    
+    onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
     },
 
     
-    nextSibling : function(){
-        if(this.ownerCt){
-            var index = this.ownerCt.items.indexOf(this);
-            if(index != -1 && index+1 < this.ownerCt.items.getCount()){
-                return this.ownerCt.items.itemAt(index+1);
-            }
-        }
-        return null;
+    onPosition : function(x, y){
+
     },
 
     
-    previousSibling : function(){
-        if(this.ownerCt){
-            var index = this.ownerCt.items.indexOf(this);
-            if(index > 0){
-                return this.ownerCt.items.itemAt(index-1);
-            }
+    adjustSize : function(w, h){
+        if(this.autoWidth){
+            w = 'auto';
         }
-        return null;
+        if(this.autoHeight){
+            h = 'auto';
+        }
+        return {width : w, height: h};
     },
 
     
-    getBubbleTarget : function(){
-        return this.ownerCt;
+    adjustPosition : function(x, y){
+        return {x : x, y: y};
     }
 });
+Ext.reg('box', Ext.BoxComponent);
+
+
+
+Ext.Spacer = Ext.extend(Ext.BoxComponent, {
+    autoEl:'div'
+});
+Ext.reg('spacer', Ext.Spacer);
+Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
 
-Ext.reg('component', Ext.Component);
-Ext.Action = Ext.extend(Object, {
-    
     
+    this.el = Ext.get(dragElement, true);
+    this.el.dom.unselectable = "on";
     
+    this.resizingEl = Ext.get(resizingElement, true);
+
     
+    this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
+
     
     
+    this.minSize = 0;
+
     
+    this.maxSize = 2000;
 
-    constructor : function(config){
-        this.initialConfig = config;
-        this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
-        this.items = [];
-    },
     
+    this.animate = false;
+
     
-    isAction : true,
+    this.useShim = false;
 
     
-    setText : function(text){
-        this.initialConfig.text = text;
-        this.callEach('setText', [text]);
-    },
+    this.shim = null;
 
+    if(!existingProxy){
+        
+        this.proxy = Ext.SplitBar.createProxy(this.orientation);
+    }else{
+        this.proxy = Ext.get(existingProxy).dom;
+    }
     
-    getText : function(){
-        return this.initialConfig.text;
-    },
+    this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
 
     
-    setIconClass : function(cls){
-        this.initialConfig.iconCls = cls;
-        this.callEach('setIconClass', [cls]);
-    },
+    this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
 
     
-    getIconClass : function(){
-        return this.initialConfig.iconCls;
-    },
+    this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
 
     
-    setDisabled : function(v){
-        this.initialConfig.disabled = v;
-        this.callEach('setDisabled', [v]);
-    },
+    this.dragSpecs = {};
 
     
-    enable : function(){
-        this.setDisabled(false);
+    this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
+    this.adapter.init(this);
+
+    if(this.orientation == Ext.SplitBar.HORIZONTAL){
+        
+        this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
+        this.el.addClass("x-splitbar-h");
+    }else{
+        
+        this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
+        this.el.addClass("x-splitbar-v");
+    }
+
+    this.addEvents(
+        
+        "resize",
+        
+        "moved",
+        
+        "beforeresize",
+
+        "beforeapply"
+    );
+
+    Ext.SplitBar.superclass.constructor.call(this);
+};
+
+Ext.extend(Ext.SplitBar, Ext.util.Observable, {
+    onStartProxyDrag : function(x, y){
+        this.fireEvent("beforeresize", this);
+        this.overlay =  Ext.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);
+        this.overlay.unselectable();
+        this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
+        this.overlay.show();
+        Ext.get(this.proxy).setDisplayed("block");
+        var size = this.adapter.getElementSize(this);
+        this.activeMinSize = this.getMinimumSize();
+        this.activeMaxSize = this.getMaximumSize();
+        var c1 = size - this.activeMinSize;
+        var c2 = Math.max(this.activeMaxSize - size, 0);
+        if(this.orientation == Ext.SplitBar.HORIZONTAL){
+            this.dd.resetConstraints();
+            this.dd.setXConstraint(
+                this.placement == Ext.SplitBar.LEFT ? c1 : c2,
+                this.placement == Ext.SplitBar.LEFT ? c2 : c1,
+                this.tickSize
+            );
+            this.dd.setYConstraint(0, 0);
+        }else{
+            this.dd.resetConstraints();
+            this.dd.setXConstraint(0, 0);
+            this.dd.setYConstraint(
+                this.placement == Ext.SplitBar.TOP ? c1 : c2,
+                this.placement == Ext.SplitBar.TOP ? c2 : c1,
+                this.tickSize
+            );
+         }
+        this.dragSpecs.startSize = size;
+        this.dragSpecs.startPoint = [x, y];
+        Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
     },
 
     
-    disable : function(){
-        this.setDisabled(true);
+    onEndProxyDrag : function(e){
+        Ext.get(this.proxy).setDisplayed(false);
+        var endPoint = Ext.lib.Event.getXY(e);
+        if(this.overlay){
+            Ext.destroy(this.overlay);
+            delete this.overlay;
+        }
+        var newSize;
+        if(this.orientation == Ext.SplitBar.HORIZONTAL){
+            newSize = this.dragSpecs.startSize +
+                (this.placement == Ext.SplitBar.LEFT ?
+                    endPoint[0] - this.dragSpecs.startPoint[0] :
+                    this.dragSpecs.startPoint[0] - endPoint[0]
+                );
+        }else{
+            newSize = this.dragSpecs.startSize +
+                (this.placement == Ext.SplitBar.TOP ?
+                    endPoint[1] - this.dragSpecs.startPoint[1] :
+                    this.dragSpecs.startPoint[1] - endPoint[1]
+                );
+        }
+        newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
+        if(newSize != this.dragSpecs.startSize){
+            if(this.fireEvent('beforeapply', this, newSize) !== false){
+                this.adapter.setElementSize(this, newSize);
+                this.fireEvent("moved", this, newSize);
+                this.fireEvent("resize", this, newSize);
+            }
+        }
     },
 
     
-    isDisabled : function(){
-        return this.initialConfig.disabled;
+    getAdapter : function(){
+        return this.adapter;
     },
 
     
-    setHidden : function(v){
-        this.initialConfig.hidden = v;
-        this.callEach('setVisible', [!v]);
+    setAdapter : function(adapter){
+        this.adapter = adapter;
+        this.adapter.init(this);
     },
 
     
-    show : function(){
-        this.setHidden(false);
+    getMinimumSize : function(){
+        return this.minSize;
     },
 
     
-    hide : function(){
-        this.setHidden(true);
+    setMinimumSize : function(minSize){
+        this.minSize = minSize;
     },
 
     
-    isHidden : function(){
-        return this.initialConfig.hidden;
+    getMaximumSize : function(){
+        return this.maxSize;
     },
 
     
-    setHandler : function(fn, scope){
-        this.initialConfig.handler = fn;
-        this.initialConfig.scope = scope;
-        this.callEach('setHandler', [fn, scope]);
+    setMaximumSize : function(maxSize){
+        this.maxSize = maxSize;
     },
 
     
-    each : function(fn, scope){
-        Ext.each(this.items, fn, scope);
+    setCurrentSize : function(size){
+        var oldAnimate = this.animate;
+        this.animate = false;
+        this.adapter.setElementSize(this, size);
+        this.animate = oldAnimate;
     },
 
     
-    callEach : function(fnName, args){
-        var cs = this.items;
-        for(var i = 0, len = cs.length; i < len; i++){
-            cs[i][fnName].apply(cs[i], args);
+    destroy : function(removeEl){
+        Ext.destroy(this.shim, Ext.get(this.proxy));
+        this.dd.unreg();
+        if(removeEl){
+            this.el.remove();
         }
-    },
+        this.purgeListeners();
+    }
+});
+
+
+Ext.SplitBar.createProxy = function(dir){
+    var proxy = new Ext.Element(document.createElement("div"));
+    document.body.appendChild(proxy.dom);
+    proxy.unselectable();
+    var cls = 'x-splitbar-proxy';
+    proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
+    return proxy.dom;
+};
 
+
+Ext.SplitBar.BasicLayoutAdapter = function(){
+};
+
+Ext.SplitBar.BasicLayoutAdapter.prototype = {
     
-    addComponent : function(comp){
-        this.items.push(comp);
-        comp.on('destroy', this.removeComponent, this);
-    },
+    init : function(s){
 
+    },
     
-    removeComponent : function(comp){
-        this.items.remove(comp);
+     getElementSize : function(s){
+        if(s.orientation == Ext.SplitBar.HORIZONTAL){
+            return s.resizingEl.getWidth();
+        }else{
+            return s.resizingEl.getHeight();
+        }
     },
 
     
-    execute : function(){
-        this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
-    }
-});
+    setElementSize : function(s, newSize, onComplete){
+        if(s.orientation == Ext.SplitBar.HORIZONTAL){
+            if(!s.animate){
+                s.resizingEl.setWidth(newSize);
+                if(onComplete){
+                    onComplete(s, newSize);
+                }
+            }else{
+                s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
+            }
+        }else{
 
-(function(){
-Ext.Layer = function(config, existingEl){
-    config = config || {};
-    var dh = Ext.DomHelper;
-    var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
-    if(existingEl){
-        this.dom = Ext.getDom(existingEl);
-    }
-    if(!this.dom){
-        var o = config.dh || {tag: 'div', cls: 'x-layer'};
-        this.dom = dh.append(pel, o);
-    }
-    if(config.cls){
-        this.addClass(config.cls);
-    }
-    this.constrain = config.constrain !== false;
-    this.setVisibilityMode(Ext.Element.VISIBILITY);
-    if(config.id){
-        this.id = this.dom.id = config.id;
-    }else{
-        this.id = Ext.id(this.dom);
-    }
-    this.zindex = config.zindex || this.getZIndex();
-    this.position('absolute', this.zindex);
-    if(config.shadow){
-        this.shadowOffset = config.shadowOffset || 4;
-        this.shadow = new Ext.Shadow({
-            offset : this.shadowOffset,
-            mode : config.shadow
-        });
-    }else{
-        this.shadowOffset = 0;
+            if(!s.animate){
+                s.resizingEl.setHeight(newSize);
+                if(onComplete){
+                    onComplete(s, newSize);
+                }
+            }else{
+                s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
+            }
+        }
     }
-    this.useShim = config.shim !== false && Ext.useShims;
-    this.useDisplay = config.useDisplay;
-    this.hide();
 };
 
-var supr = Ext.Element.prototype;
-
-
-var shims = [];
 
-Ext.extend(Ext.Layer, Ext.Element, {
+Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
+    this.basic = new Ext.SplitBar.BasicLayoutAdapter();
+    this.container = Ext.get(container);
+};
 
-    getZIndex : function(){
-        return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
+Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
+    init : function(s){
+        this.basic.init(s);
     },
 
-    getShim : function(){
-        if(!this.useShim){
-            return null;
-        }
-        if(this.shim){
-            return this.shim;
-        }
-        var shim = shims.shift();
-        if(!shim){
-            shim = this.createShim();
-            shim.enableDisplayMode('block');
-            shim.dom.style.display = 'none';
-            shim.dom.style.visibility = 'visible';
-        }
-        var pn = this.dom.parentNode;
-        if(shim.dom.parentNode != pn){
-            pn.insertBefore(shim.dom, this.dom);
-        }
-        shim.setStyle('z-index', this.getZIndex()-2);
-        this.shim = shim;
-        return shim;
+    getElementSize : function(s){
+        return this.basic.getElementSize(s);
     },
 
-    hideShim : function(){
-        if(this.shim){
-            this.shim.setDisplayed(false);
-            shims.push(this.shim);
-            delete this.shim;
-        }
+    setElementSize : function(s, newSize, onComplete){
+        this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
     },
 
-    disableShadow : function(){
-        if(this.shadow){
-            this.shadowDisabled = true;
-            this.shadow.hide();
-            this.lastShadowOffset = this.shadowOffset;
-            this.shadowOffset = 0;
+    moveSplitter : function(s){
+        var yes = Ext.SplitBar;
+        switch(s.placement){
+            case yes.LEFT:
+                s.el.setX(s.resizingEl.getRight());
+                break;
+            case yes.RIGHT:
+                s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
+                break;
+            case yes.TOP:
+                s.el.setY(s.resizingEl.getBottom());
+                break;
+            case yes.BOTTOM:
+                s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
+                break;
         }
-    },
+    }
+};
+
+
+Ext.SplitBar.VERTICAL = 1;
+
+
+Ext.SplitBar.HORIZONTAL = 2;
 
-    enableShadow : function(show){
-        if(this.shadow){
-            this.shadowDisabled = false;
-            this.shadowOffset = this.lastShadowOffset;
-            delete this.lastShadowOffset;
-            if(show){
-                this.sync(true);
-            }
-        }
-    },
 
+Ext.SplitBar.LEFT = 1;
+
+
+Ext.SplitBar.RIGHT = 2;
+
+
+Ext.SplitBar.TOP = 3;
+
+
+Ext.SplitBar.BOTTOM = 4;
+
+Ext.Container = Ext.extend(Ext.BoxComponent, {
     
     
     
-    sync : function(doShow){
-        var sw = this.shadow;
-        if(!this.updating && this.isVisible() && (sw || this.useShim)){
-            var sh = this.getShim();
-
-            var w = this.getWidth(),
-                h = this.getHeight();
-
-            var l = this.getLeft(true),
-                t = this.getTop(true);
+    
+    bufferResize: 50,
 
-            if(sw && !this.shadowDisabled){
-                if(doShow && !sw.isVisible()){
-                    sw.show(this);
-                }else{
-                    sw.realign(l, t, w, h);
-                }
-                if(sh){
-                    if(doShow){
-                       sh.show();
-                    }
-                    
-                    var a = sw.adjusts, s = sh.dom.style;
-                    s.left = (Math.min(l, l+a.l))+'px';
-                    s.top = (Math.min(t, t+a.t))+'px';
-                    s.width = (w+a.w)+'px';
-                    s.height = (h+a.h)+'px';
-                }
-            }else if(sh){
-                if(doShow){
-                   sh.show();
-                }
-                sh.setSize(w, h);
-                sh.setLeftTop(l, t);
-            }
+    
+    
+    
 
-        }
-    },
 
     
-    destroy : function(){
-        this.hideShim();
-        if(this.shadow){
-            this.shadow.hide();
-        }
-        this.removeAllListeners();
-        Ext.removeNode(this.dom);
-        delete this.dom;
-    },
+    autoDestroy : true,
 
-    remove : function(){
-        this.destroy();
-    },
+    
+    forceLayout: false,
 
     
-    beginUpdate : function(){
-        this.updating = true;
-    },
+    
+    defaultType : 'panel',
 
     
-    endUpdate : function(){
-        this.updating = false;
-        this.sync(true);
-    },
+    resizeEvent: 'resize',
 
     
-    hideUnders : function(negOffset){
-        if(this.shadow){
-            this.shadow.hide();
-        }
-        this.hideShim();
-    },
+    bubbleEvents: ['add', 'remove'],
 
     
-    constrainXY : function(){
-        if(this.constrain){
-            var vw = Ext.lib.Dom.getViewWidth(),
-                vh = Ext.lib.Dom.getViewHeight();
-            var s = Ext.getDoc().getScroll();
+    initComponent : function(){
+        Ext.Container.superclass.initComponent.call(this);
 
-            var xy = this.getXY();
-            var x = xy[0], y = xy[1];
-            var so = this.shadowOffset;
-            var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
+        this.addEvents(
             
-            var moved = false;
+            'afterlayout',
             
-            if((x + w) > vw+s.left){
-                x = vw - w - so;
-                moved = true;
-            }
-            if((y + h) > vh+s.top){
-                y = vh - h - so;
-                moved = true;
-            }
+            'beforeadd',
             
-            if(x < s.left){
-                x = s.left;
-                moved = true;
-            }
-            if(y < s.top){
-                y = s.top;
-                moved = true;
-            }
-            if(moved){
-                if(this.avoidY){
-                    var ay = this.avoidY;
-                    if(y <= ay && (y+h) >= ay){
-                        y = ay-h-5;
-                    }
-                }
-                xy = [x, y];
-                this.storeXY(xy);
-                supr.setXY.call(this, xy);
-                this.sync();
-            }
-        }
-        return this;
-    },
+            'beforeremove',
+            
+            'add',
+            
+            'remove'
+        );
 
-    isVisible : function(){
-        return this.visible;
+        
+        var items = this.items;
+        if(items){
+            delete this.items;
+            this.add(items);
+        }
     },
 
     
-    showAction : function(){
-        this.visible = true; 
-        if(this.useDisplay === true){
-            this.setDisplayed('');
-        }else if(this.lastXY){
-            supr.setXY.call(this, this.lastXY);
-        }else if(this.lastLT){
-            supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
+    initItems : function(){
+        if(!this.items){
+            this.items = new Ext.util.MixedCollection(false, this.getComponentId);
+            this.getLayout(); 
         }
     },
 
     
-    hideAction : function(){
-        this.visible = false;
-        if(this.useDisplay === true){
-            this.setDisplayed(false);
-        }else{
-            this.setLeftTop(-10000,-10000);
+    setLayout : function(layout){
+        if(this.layout && this.layout != layout){
+            this.layout.setContainer(null);
         }
+        this.layout = layout;
+        this.initItems();
+        layout.setContainer(this);
     },
 
-    
-    setVisible : function(v, a, d, c, e){
-        if(v){
-            this.showAction();
+    afterRender: function(){
+        
+        
+        Ext.Container.superclass.afterRender.call(this);
+        if(!this.layout){
+            this.layout = 'auto';
         }
-        if(a && v){
-            var cb = function(){
-                this.sync(true);
-                if(c){
-                    c();
-                }
-            }.createDelegate(this);
-            supr.setVisible.call(this, true, true, d, cb, e);
-        }else{
-            if(!v){
-                this.hideUnders(true);
-            }
-            var cb = c;
-            if(a){
-                cb = function(){
-                    this.hideAction();
-                    if(c){
-                        c();
-                    }
-                }.createDelegate(this);
-            }
-            supr.setVisible.call(this, v, a, d, cb, e);
-            if(v){
-                this.sync(true);
-            }else if(!a){
-                this.hideAction();
-            }
+        if(Ext.isObject(this.layout) && !this.layout.layout){
+            this.layoutConfig = this.layout;
+            this.layout = this.layoutConfig.type;
         }
-        return this;
-    },
+        if(Ext.isString(this.layout)){
+            this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
+        }
+        this.setLayout(this.layout);
 
-    storeXY : function(xy){
-        delete this.lastLT;
-        this.lastXY = xy;
-    },
+        
+        if(this.activeItem !== undefined && this.layout.setActiveItem){
+            var item = this.activeItem;
+            delete this.activeItem;
+            this.layout.setActiveItem(item);
+        }
 
-    storeLeftTop : function(left, top){
-        delete this.lastXY;
-        this.lastLT = [left, top];
-    },
+        
+        if(!this.ownerCt){
+            this.doLayout(false, true);
+        }
 
-    
-    beforeFx : function(){
-        this.beforeAction();
-        return Ext.Layer.superclass.beforeFx.apply(this, arguments);
+        
+        
+        if(this.monitorResize === true){
+            Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
+        }
     },
 
     
-    afterFx : function(){
-        Ext.Layer.superclass.afterFx.apply(this, arguments);
-        this.sync(this.isVisible());
+    getLayoutTarget : function(){
+        return this.el;
     },
 
     
-    beforeAction : function(){
-        if(!this.updating && this.shadow){
-            this.shadow.hide();
-        }
+    getComponentId : function(comp){
+        return comp.getItemId();
     },
 
     
-    setLeft : function(left){
-        this.storeLeftTop(left, this.getTop(true));
-        supr.setLeft.apply(this, arguments);
-        this.sync();
-        return this;
-    },
-
-    setTop : function(top){
-        this.storeLeftTop(this.getLeft(true), top);
-        supr.setTop.apply(this, arguments);
-        this.sync();
-        return this;
-    },
-
-    setLeftTop : function(left, top){
-        this.storeLeftTop(left, top);
-        supr.setLeftTop.apply(this, arguments);
-        this.sync();
-        return this;
-    },
-
-    setXY : function(xy, a, d, c, e){
-        this.fixDisplay();
-        this.beforeAction();
-        this.storeXY(xy);
-        var cb = this.createCB(c);
-        supr.setXY.call(this, xy, a, d, cb, e);
-        if(!a){
-            cb();
+    add : function(comp){
+        this.initItems();
+        var args = arguments.length > 1;
+        if(args || Ext.isArray(comp)){
+            var result = [];
+            Ext.each(args ? arguments : comp, function(c){
+                result.push(this.add(c));
+            }, this);
+            return result;
         }
-        return this;
+        var c = this.lookupComponent(this.applyDefaults(comp));
+        var index = this.items.length;
+        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
+            this.items.add(c);
+            
+            c.onAdded(this, index);
+            this.onAdd(c);
+            this.fireEvent('add', this, c, index);
+        }
+        return c;
     },
 
-    
-    createCB : function(c){
-        var el = this;
-        return function(){
-            el.constrainXY();
-            el.sync(true);
-            if(c){
-                c();
-            }
-        };
+    onAdd : function(c){
+        
     },
 
     
-    setX : function(x, a, d, c, e){
-        this.setXY([x, this.getY()], a, d, c, e);
-        return this;
+    onAdded : function(container, pos) {
+        
+        this.ownerCt = container;
+        this.initRef();
+        
+        this.cascade(function(c){
+            c.initRef();
+        });
+        this.fireEvent('added', this, container, pos);
     },
 
     
-    setY : function(y, a, d, c, e){
-        this.setXY([this.getX(), y], a, d, c, e);
-        return this;
+    insert : function(index, comp) {
+        var args   = arguments,
+            length = args.length,
+            result = [],
+            i, c;
+        
+        this.initItems();
+        
+        if (length > 2) {
+            for (i = length - 1; i >= 1; --i) {
+                result.push(this.insert(index, args[i]));
+            }
+            return result;
+        }
+        
+        c = this.lookupComponent(this.applyDefaults(comp));
+        index = Math.min(index, this.items.length);
+        
+        if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) {
+            if (c.ownerCt == this) {
+                this.items.remove(c);
+            }
+            this.items.insert(index, c);
+            c.onAdded(this, index);
+            this.onAdd(c);
+            this.fireEvent('add', this, c, index);
+        }
+        
+        return c;
     },
 
     
-    setSize : function(w, h, a, d, c, e){
-        this.beforeAction();
-        var cb = this.createCB(c);
-        supr.setSize.call(this, w, h, a, d, cb, e);
-        if(!a){
-            cb();
+    applyDefaults : function(c){
+        var d = this.defaults;
+        if(d){
+            if(Ext.isFunction(d)){
+                d = d.call(this, c);
+            }
+            if(Ext.isString(c)){
+                c = Ext.ComponentMgr.get(c);
+                Ext.apply(c, d);
+            }else if(!c.events){
+                Ext.applyIf(c.isAction ? c.initialConfig : c, d);
+            }else{
+                Ext.apply(c, d);
+            }
         }
-        return this;
+        return c;
     },
 
     
-    setWidth : function(w, a, d, c, e){
-        this.beforeAction();
-        var cb = this.createCB(c);
-        supr.setWidth.call(this, w, a, d, cb, e);
-        if(!a){
-            cb();
+    onBeforeAdd : function(item){
+        if(item.ownerCt){
+            item.ownerCt.remove(item, false);
+        }
+        if(this.hideBorders === true){
+            item.border = (item.border === true);
         }
-        return this;
     },
 
     
-    setHeight : function(h, a, d, c, e){
-        this.beforeAction();
-        var cb = this.createCB(c);
-        supr.setHeight.call(this, h, a, d, cb, e);
-        if(!a){
-            cb();
+    remove : function(comp, autoDestroy){
+        this.initItems();
+        var c = this.getComponent(comp);
+        if(c && this.fireEvent('beforeremove', this, c) !== false){
+            this.doRemove(c, autoDestroy);
+            this.fireEvent('remove', this, c);
         }
-        return this;
+        return c;
     },
 
-    
-    setBounds : function(x, y, w, h, a, d, c, e){
-        this.beforeAction();
-        var cb = this.createCB(c);
-        if(!a){
-            this.storeXY([x, y]);
-            supr.setXY.call(this, [x, y]);
-            supr.setSize.call(this, w, h, a, d, cb, e);
-            cb();
-        }else{
-            supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
-        }
-        return this;
+    onRemove: function(c){
+        
     },
 
     
-    setZIndex : function(zindex){
-        this.zindex = zindex;
-        this.setStyle('z-index', zindex + 2);
-        if(this.shadow){
-            this.shadow.setZIndex(zindex + 1);
+    doRemove: function(c, autoDestroy){
+        var l = this.layout,
+            hasLayout = l && this.rendered;
+
+        if(hasLayout){
+            l.onRemove(c);
         }
-        if(this.shim){
-            this.shim.setStyle('z-index', zindex);
+        this.items.remove(c);
+        c.onRemoved();
+        this.onRemove(c);
+        if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
+            c.destroy();
         }
-        return this;
-    }
-});
-})();
-
-Ext.Shadow = function(config){
-    Ext.apply(this, config);
-    if(typeof this.mode != "string"){
-        this.mode = this.defaultMode;
-    }
-    var o = this.offset, a = {h: 0};
-    var rad = Math.floor(this.offset/2);
-    switch(this.mode.toLowerCase()){ 
-        case "drop":
-            a.w = 0;
-            a.l = a.t = o;
-            a.t -= 1;
-            if(Ext.isIE){
-                a.l -= this.offset + rad;
-                a.t -= this.offset + rad;
-                a.w -= rad;
-                a.h -= rad;
-                a.t += 1;
-            }
-        break;
-        case "sides":
-            a.w = (o*2);
-            a.l = -o;
-            a.t = o-1;
-            if(Ext.isIE){
-                a.l -= (this.offset - rad);
-                a.t -= this.offset + rad;
-                a.l += 1;
-                a.w -= (this.offset - rad)*2;
-                a.w -= rad + 1;
-                a.h -= 1;
-            }
-        break;
-        case "frame":
-            a.w = a.h = (o*2);
-            a.l = a.t = -o;
-            a.t += 1;
-            a.h -= 2;
-            if(Ext.isIE){
-                a.l -= (this.offset - rad);
-                a.t -= (this.offset - rad);
-                a.l += 1;
-                a.w -= (this.offset + rad + 1);
-                a.h -= (this.offset + rad);
-                a.h += 1;
-            }
-        break;
-    };
-
-    this.adjusts = a;
-};
-
-Ext.Shadow.prototype = {
-    
-    
-    offset: 4,
-
-    
-    defaultMode: "drop",
+        if(hasLayout){
+            l.afterRemove(c);
+        }
+    },
 
     
-    show : function(target){
-        target = Ext.get(target);
-        if(!this.el){
-            this.el = Ext.Shadow.Pool.pull();
-            if(this.el.dom.nextSibling != target.dom){
-                this.el.insertBefore(target);
+    removeAll: function(autoDestroy){
+        this.initItems();
+        var item, rem = [], items = [];
+        this.items.each(function(i){
+            rem.push(i);
+        });
+        for (var i = 0, len = rem.length; i < len; ++i){
+            item = rem[i];
+            this.remove(item, autoDestroy);
+            if(item.ownerCt !== this){
+                items.push(item);
             }
         }
-        this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
-        if(Ext.isIE){
-            this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
-        }
-        this.realign(
-            target.getLeft(true),
-            target.getTop(true),
-            target.getWidth(),
-            target.getHeight()
-        );
-        this.el.dom.style.display = "block";
+        return items;
     },
 
     
-    isVisible : function(){
-        return this.el ? true : false;  
+    getComponent : function(comp){
+        if(Ext.isObject(comp)){
+            comp = comp.getItemId();
+        }
+        return this.items.get(comp);
     },
 
     
-    realign : function(l, t, w, h){
-        if(!this.el){
-            return;
-        }
-        var a = this.adjusts, d = this.el.dom, s = d.style;
-        var iea = 0;
-        s.left = (l+a.l)+"px";
-        s.top = (t+a.t)+"px";
-        var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
-        if(s.width != sws || s.height != shs){
-            s.width = sws;
-            s.height = shs;
-            if(!Ext.isIE){
-                var cn = d.childNodes;
-                var sww = Math.max(0, (sw-12))+"px";
-                cn[0].childNodes[1].style.width = sww;
-                cn[1].childNodes[1].style.width = sww;
-                cn[2].childNodes[1].style.width = sww;
-                cn[1].style.height = Math.max(0, (sh-12))+"px";
-            }
+    lookupComponent : function(comp){
+        if(Ext.isString(comp)){
+            return Ext.ComponentMgr.get(comp);
+        }else if(!comp.events){
+            return this.createComponent(comp);
         }
+        return comp;
     },
 
     
-    hide : function(){
-        if(this.el){
-            this.el.dom.style.display = "none";
-            Ext.Shadow.Pool.push(this.el);
-            delete this.el;
+    createComponent : function(config, defaultType){
+        if (config.render) {
+            return config;
         }
+        
+        
+        var c = Ext.create(Ext.apply({
+            ownerCt: this
+        }, config), defaultType || this.defaultType);
+        delete c.initialConfig.ownerCt;
+        delete c.ownerCt;
+        return c;
     },
 
     
-    setZIndex : function(z){
-        this.zIndex = z;
-        if(this.el){
-            this.el.setStyle("z-index", z);
-        }
-    }
-};
+    canLayout : function() {
+        var el = this.getVisibilityEl();
+        return el && el.dom && !el.isStyle("display", "none");
+    },
 
+    
 
-Ext.Shadow.Pool = function(){
-    var p = [];
-    var markup = Ext.isIE ?
-                 '<div class="x-ie-shadow"></div>' :
-                 '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
-    return {
-        pull : function(){
-            var sh = p.shift();
-            if(!sh){
-                sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
-                sh.autoBoxAdjust = false;
-            }
-            return sh;
-        },
+    doLayout : function(shallow, force){
+        var rendered = this.rendered,
+            forceLayout = force || this.forceLayout;
 
-        push : function(sh){
-            p.push(sh);
+        if(this.collapsed || !this.canLayout()){
+            this.deferLayout = this.deferLayout || !shallow;
+            if(!forceLayout){
+                return;
+            }
+            shallow = shallow && !this.deferLayout;
+        } else {
+            delete this.deferLayout;
         }
-    };
-}();
-Ext.BoxComponent = Ext.extend(Ext.Component, {
-
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
+        if(rendered && this.layout){
+            this.layout.layout();
+        }
+        if(shallow !== true && this.items){
+            var cs = this.items.items;
+            for(var i = 0, len = cs.length; i < len; i++){
+                var c = cs[i];
+                if(c.doLayout){
+                    c.doLayout(false, forceLayout);
+                }
+            }
+        }
+        if(rendered){
+            this.onLayout(shallow, forceLayout);
+        }
+        
+        this.hasLayout = true;
+        delete this.forceLayout;
+    },
 
-    
+    onLayout : Ext.emptyFn,
 
     
-    initComponent : function(){
-        Ext.BoxComponent.superclass.initComponent.call(this);
-        this.addEvents(
-            
-            'resize',
+    shouldBufferLayout: function(){
+        
+        var hl = this.hasLayout;
+        if(this.ownerCt){
             
-            'move'
-        );
+            return hl ? !this.hasLayoutPending() : false;
+        }
+        
+        return hl;
     },
 
     
-    boxReady : false,
-    
-    deferHeight: false,
-
-    
-    setSize : function(w, h){
+    hasLayoutPending: function(){
+        
+        var pending = false;
+        this.ownerCt.bubble(function(c){
+            if(c.layoutPending){
+                pending = true;
+                return false;
+            }
+        });
+        return pending;
+    },
 
+    onShow : function(){
         
-        if(typeof w == 'object'){
-            h = w.height, w = w.width;
-        }
-        if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
-            w = this.boxMinWidth;
-        }
-        if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
-            h = this.boxMinHeight;
-        }
-        if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
-            w = this.boxMaxWidth;
-        }
-        if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
-            h = this.boxMaxHeight;
-        }
+        Ext.Container.superclass.onShow.call(this);
         
-        if(!this.boxReady){
-            this.width = w, this.height = h;
-            return this;
+        if(Ext.isDefined(this.deferLayout)){
+            delete this.deferLayout;
+            this.doLayout(true);
+        }
+    },
+
+    
+    getLayout : function(){
+        if(!this.layout){
+            var layout = new Ext.layout.AutoLayout(this.layoutConfig);
+            this.setLayout(layout);
         }
+        return this.layout;
+    },
 
-        
-        if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
-            return this;
+    
+    beforeDestroy : function(){
+        var c;
+        if(this.items){
+            while(c = this.items.first()){
+                this.doRemove(c, true);
+            }
         }
-        this.lastSize = {width: w, height: h};
-        var adj = this.adjustSize(w, h),
-            aw = adj.width,
-            ah = adj.height,
-            rz;
-        if(aw !== undefined || ah !== undefined){ 
-            rz = this.getResizeEl();
-            if(!this.deferHeight && aw !== undefined && ah !== undefined){
-                rz.setSize(aw, ah);
-            }else if(!this.deferHeight && ah !== undefined){
-                rz.setHeight(ah);
-            }else if(aw !== undefined){
-                rz.setWidth(aw);
+        if(this.monitorResize){
+            Ext.EventManager.removeResizeListener(this.doLayout, this);
+        }
+        Ext.destroy(this.layout);
+        Ext.Container.superclass.beforeDestroy.call(this);
+    },
+
+    
+    cascade : function(fn, scope, args){
+        if(fn.apply(scope || this, args || [this]) !== false){
+            if(this.items){
+                var cs = this.items.items;
+                for(var i = 0, len = cs.length; i < len; i++){
+                    if(cs[i].cascade){
+                        cs[i].cascade(fn, scope, args);
+                    }else{
+                        fn.apply(scope || cs[i], args || [cs[i]]);
+                    }
+                }
             }
-            this.onResize(aw, ah, w, h);
         }
         return this;
     },
 
     
-    setWidth : function(width){
-        return this.setSize(width);
+    findById : function(id){
+        var m = null, 
+            ct = this;
+        this.cascade(function(c){
+            if(ct != c && c.id === id){
+                m = c;
+                return false;
+            }
+        });
+        return m;
     },
 
     
-    setHeight : function(height){
-        return this.setSize(undefined, height);
+    findByType : function(xtype, shallow){
+        return this.findBy(function(c){
+            return c.isXType(xtype, shallow);
+        });
     },
 
     
-    getSize : function(){
-        return this.getResizeEl().getSize();
+    find : function(prop, value){
+        return this.findBy(function(c){
+            return c[prop] === value;
+        });
     },
 
     
-    getWidth : function(){
-        return this.getResizeEl().getWidth();
+    findBy : function(fn, scope){
+        var m = [], ct = this;
+        this.cascade(function(c){
+            if(ct != c && fn.call(scope || c, c, ct) === true){
+                m.push(c);
+            }
+        });
+        return m;
     },
 
     
-    getHeight : function(){
-        return this.getResizeEl().getHeight();
-    },
+    get : function(key){
+        return this.getComponent(key);
+    }
+});
+
+Ext.Container.LAYOUTS = {};
+Ext.reg('container', Ext.Container);
 
+Ext.layout.ContainerLayout = Ext.extend(Object, {
     
-    getOuterSize : function(){
-        var el = this.getResizeEl();
-        return {width: el.getWidth() + el.getMargins('lr'),
-                height: el.getHeight() + el.getMargins('tb')};
+    
+
+    
+
+    
+    monitorResize:false,
+    
+    activeItem : null,
+
+    constructor : function(config){
+        this.id = Ext.id(null, 'ext-layout-');
+        Ext.apply(this, config);
     },
 
+    type: 'container',
+
     
-    getPosition : function(local){
-        var el = this.getPositionEl();
-        if(local === true){
-            return [el.getLeft(true), el.getTop(true)];
+    IEMeasureHack : function(target, viewFlag) {
+        var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
+        for (i = 0 ; i < tLen ; i++) {
+            c = tChildren[i];
+            e = Ext.get(c);
+            if (e) {
+                d[i] = e.getStyle('display');
+                e.setStyle({display: 'none'});
+            }
         }
-        return this.xy || el.getXY();
+        ret = target ? target.getViewSize(viewFlag) : {};
+        for (i = 0 ; i < tLen ; i++) {
+            c = tChildren[i];
+            e = Ext.get(c);
+            if (e) {
+                e.setStyle({display: d[i]});
+            }
+        }
+        return ret;
     },
 
     
-    getBox : function(local){
-        var pos = this.getPosition(local);
-        var s = this.getSize();
-        s.x = pos[0];
-        s.y = pos[1];
-        return s;
+    getLayoutTargetSize : Ext.EmptyFn,
+
+    
+    layout : function(){
+        var ct = this.container, target = ct.getLayoutTarget();
+        if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
+            target.addClass(this.targetCls);
+        }
+        this.onLayout(ct, target);
+        ct.fireEvent('afterlayout', ct, this);
     },
 
     
-    updateBox : function(box){
-        this.setSize(box.width, box.height);
-        this.setPagePosition(box.x, box.y);
-        return this;
+    onLayout : function(ct, target){
+        this.renderAll(ct, target);
     },
 
     
-    getResizeEl : function(){
-        return this.resizeEl || this.el;
+    isValidParent : function(c, target){
+        return target && c.getPositionEl().dom.parentNode == (target.dom || target);
     },
 
     
-    setAutoScroll : function(scroll){
-        if(this.rendered){
-            this.getContentTarget().setOverflow(scroll ? 'auto' : '');
+    renderAll : function(ct, target){
+        var items = ct.items.items, i, c, len = items.length;
+        for(i = 0; i < len; i++) {
+            c = items[i];
+            if(c && (!c.rendered || !this.isValidParent(c, target))){
+                this.renderItem(c, i, target);
+            }
         }
-        this.autoScroll = scroll;
-        return this;
     },
 
     
-    setPosition : function(x, y){
-        if(x && typeof x[1] == 'number'){
-            y = x[1];
-            x = x[0];
-        }
-        this.x = x;
-        this.y = y;
-        if(!this.boxReady){
-            return this;
+    renderItem : function(c, position, target){
+        if (c) {
+            if (!c.rendered) {
+                c.render(target, position);
+                this.configureItem(c);
+            } else if (!this.isValidParent(c, target)) {
+                if (Ext.isNumber(position)) {
+                    position = target.dom.childNodes[position];
+                }
+                
+                target.dom.insertBefore(c.getPositionEl().dom, position || null);
+                c.container = target;
+                this.configureItem(c);
+            }
         }
-        var adj = this.adjustPosition(x, y);
-        var ax = adj.x, ay = adj.y;
+    },
 
-        var el = this.getPositionEl();
-        if(ax !== undefined || ay !== undefined){
-            if(ax !== undefined && ay !== undefined){
-                el.setLeftTop(ax, ay);
-            }else if(ax !== undefined){
-                el.setLeft(ax);
-            }else if(ay !== undefined){
-                el.setTop(ay);
+    
+    
+    getRenderedItems: function(ct){
+        var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
+        for (i = 0; i < len; i++) {
+            if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){
+                items.push(c);
             }
-            this.onPosition(ax, ay);
-            this.fireEvent('move', this, ax, ay);
-        }
-        return this;
+        };
+        return items;
     },
 
     
-    setPagePosition : function(x, y){
-        if(x && typeof x[1] == 'number'){
-            y = x[1];
-            x = x[0];
+    configureItem: function(c){
+        if (this.extraCls) {
+            var t = c.getPositionEl ? c.getPositionEl() : c;
+            t.addClass(this.extraCls);
         }
-        this.pageX = x;
-        this.pageY = y;
-        if(!this.boxReady){
-            return;
+        
+        
+        if (c.doLayout && this.forceLayout) {
+            c.doLayout();
         }
-        if(x === undefined || y === undefined){ 
-            return;
+        if (this.renderHidden && c != this.activeItem) {
+            c.hide();
         }
-        var p = this.getPositionEl().translatePoints(x, y);
-        this.setPosition(p.left, p.top);
-        return this;
     },
 
-    
-    afterRender : function(){
-        Ext.BoxComponent.superclass.afterRender.call(this);
-        if(this.resizeEl){
-            this.resizeEl = Ext.get(this.resizeEl);
+    onRemove: function(c){
+        if(this.activeItem == c){
+            delete this.activeItem;
         }
-        if(this.positionEl){
-            this.positionEl = Ext.get(this.positionEl);
+        if(c.rendered && this.extraCls){
+            var t = c.getPositionEl ? c.getPositionEl() : c;
+            t.removeClass(this.extraCls);
         }
-        this.boxReady = true;
-        this.setAutoScroll(this.autoScroll);
-        this.setSize(this.width, this.height);
-        if(this.x || this.y){
-            this.setPosition(this.x, this.y);
-        }else if(this.pageX || this.pageY){
-            this.setPagePosition(this.pageX, this.pageY);
+    },
+
+    afterRemove: function(c){
+        if(c.removeRestore){
+            c.removeMode = 'container';
+            delete c.removeRestore;
         }
     },
 
     
-    syncSize : function(){
-        delete this.lastSize;
-        this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
-        return this;
+    onResize: function(){
+        var ct = this.container,
+            b;
+        if(ct.collapsed){
+            return;
+        }
+        if(b = ct.bufferResize && ct.shouldBufferLayout()){
+            if(!this.resizeTask){
+                this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
+                this.resizeBuffer = Ext.isNumber(b) ? b : 50;
+            }
+            ct.layoutPending = true;
+            this.resizeTask.delay(this.resizeBuffer);
+        }else{
+            this.runLayout();
+        }
     },
 
-    
-    onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
-        this.fireEvent('resize', this, adjWidth, adjHeight, rawWidth, rawHeight);
+    runLayout: function(){
+        var ct = this.container;
+        this.layout();
+        ct.onLayout();
+        delete ct.layoutPending;
     },
 
     
-    onPosition : function(x, y){
-
+    setContainer : function(ct){
+        
+        if(this.monitorResize && ct != this.container){
+            var old = this.container;
+            if(old){
+                old.un(old.resizeEvent, this.onResize, this);
+            }
+            if(ct){
+                ct.on(ct.resizeEvent, this.onResize, this);
+            }
+        }
+        this.container = ct;
     },
 
     
-    adjustSize : function(w, h){
-        if(this.autoWidth){
-            w = 'auto';
+    parseMargins : function(v){
+        if (Ext.isNumber(v)) {
+            v = v.toString();
         }
-        if(this.autoHeight){
-            h = 'auto';
+        var ms  = v.split(' '),
+            len = ms.length;
+            
+        if (len == 1) {
+            ms[1] = ms[2] = ms[3] = ms[0];
+        } else if(len == 2) {
+            ms[2] = ms[0];
+            ms[3] = ms[1];
+        } else if(len == 3) {
+            ms[3] = ms[1];
         }
-        return {width : w, height: h};
+        
+        return {
+            top   :parseInt(ms[0], 10) || 0,
+            right :parseInt(ms[1], 10) || 0,
+            bottom:parseInt(ms[2], 10) || 0,
+            left  :parseInt(ms[3], 10) || 0
+        };
     },
 
     
-    adjustPosition : function(x, y){
-        return {x : x, y: y};
+    fieldTpl: (function() {
+        var t = new Ext.Template(
+            '<div class="x-form-item {itemCls}" tabIndex="-1">',
+                '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
+                '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
+                '</div><div class="{clearCls}"></div>',
+            '</div>'
+        );
+        t.disableFormats = true;
+        return t.compile();
+    })(),
+
+    
+    destroy : function(){
+        
+        if(this.resizeTask && this.resizeTask.cancel){
+            this.resizeTask.cancel();
+        }
+        if(this.container) {
+            this.container.un(this.container.resizeEvent, this.onResize, this);
+        }
+        if(!Ext.isEmpty(this.targetCls)){
+            var target = this.container.getLayoutTarget();
+            if(target){
+                target.removeClass(this.targetCls);
+            }
+        }
     }
 });
-Ext.reg('box', Ext.BoxComponent);
-
+Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
+    type: 'auto',
 
+    monitorResize: true,
 
-Ext.Spacer = Ext.extend(Ext.BoxComponent, {
-    autoEl:'div'
+    onLayout : function(ct, target){
+        Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
+        var cs = this.getRenderedItems(ct), len = cs.length, i, c;
+        for(i = 0; i < len; i++){
+            c = cs[i];
+            if (c.doLayout){
+                
+                c.doLayout(true);
+            }
+        }
+    }
 });
-Ext.reg('spacer', Ext.Spacer);
-Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
 
+Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
+
+Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
     
-    this.el = Ext.get(dragElement, true);
-    this.el.dom.unselectable = "on";
-    
-    this.resizingEl = Ext.get(resizingElement, true);
+    monitorResize:true,
+
+    type: 'fit',
+
+    getLayoutTargetSize : function() {
+        var target = this.container.getLayoutTarget();
+        if (!target) {
+            return {};
+        }
+        
+        return target.getStyleSize();
+    },
 
     
-    this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
+    onLayout : function(ct, target){
+        Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
+        if(!ct.collapsed){
+            this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
+        }
+    },
 
     
+    setItemSize : function(item, size){
+        if(item && size.height > 0){ 
+            item.setSize(size);
+        }
+    }
+});
+Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
+Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
     
-    this.minSize = 0;
+    deferredRender : false,
 
     
-    this.maxSize = 2000;
+    layoutOnCardChange : false,
 
     
-    this.animate = false;
-
     
-    this.useShim = false;
+    renderHidden : true,
+
+    type: 'card',
 
     
-    this.shim = null;
+    setActiveItem : function(item){
+        var ai = this.activeItem,
+            ct = this.container;
+        item = ct.getComponent(item);
 
-    if(!existingProxy){
         
-        this.proxy = Ext.SplitBar.createProxy(this.orientation);
-    }else{
-        this.proxy = Ext.get(existingProxy).dom;
-    }
+        if(item && ai != item){
+
+            
+            if(ai){
+                ai.hide();
+                if (ai.hidden !== true) {
+                    return false;
+                }
+                ai.fireEvent('deactivate', ai);
+            }
+
+            var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
+
+            
+            this.activeItem = item;
+
+            
+            
+            delete item.deferLayout;
+
+            
+            item.show();
+
+            this.layout();
+
+            if(layout){
+                item.doLayout();
+            }
+            item.fireEvent('activate', item);
+        }
+    },
+
     
-    this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
+    renderAll : function(ct, target){
+        if(this.deferredRender){
+            this.renderItem(this.activeItem, undefined, target);
+        }else{
+            Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
+        }
+    }
+});
+Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
 
+Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
     
-    this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
 
     
-    this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
+    monitorResize : true,
+
+    type : 'anchor',
 
     
-    this.dragSpecs = {};
+    defaultAnchor : '100%',
+
+    parseAnchorRE : /^(r|right|b|bottom)$/i,
+
+
+    getLayoutTargetSize : function() {
+        var target = this.container.getLayoutTarget(), ret = {};
+        if (target) {
+            ret = target.getViewSize();
+
+            
+            
+            
+            if (Ext.isIE && Ext.isStrict && ret.width == 0){
+                ret =  target.getStyleSize();
+            }
+            ret.width -= target.getPadding('lr');
+            ret.height -= target.getPadding('tb');
+        }
+        return ret;
+    },
 
     
-    this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
-    this.adapter.init(this);
+    onLayout : function(container, target) {
+        Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target);
+
+        var size = this.getLayoutTargetSize(),
+            containerWidth = size.width,
+            containerHeight = size.height,
+            overflow = target.getStyle('overflow'),
+            components = this.getRenderedItems(container),
+            len = components.length,
+            boxes = [],
+            box,
+            anchorWidth,
+            anchorHeight,
+            component,
+            anchorSpec,
+            calcWidth,
+            calcHeight,
+            anchorsArray,
+            totalHeight = 0,
+            i,
+            el;
+
+        if(containerWidth < 20 && containerHeight < 20){
+            return;
+        }
 
-    if(this.orientation == Ext.SplitBar.HORIZONTAL){
-        
-        this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
-        this.el.addClass("x-splitbar-h");
-    }else{
         
-        this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
-        this.el.addClass("x-splitbar-v");
-    }
+        if(container.anchorSize) {
+            if(typeof container.anchorSize == 'number') {
+                anchorWidth = container.anchorSize;
+            } else {
+                anchorWidth = container.anchorSize.width;
+                anchorHeight = container.anchorSize.height;
+            }
+        } else {
+            anchorWidth = container.initialConfig.width;
+            anchorHeight = container.initialConfig.height;
+        }
 
-    this.addEvents(
-        
-        "resize",
-        
-        "moved",
-        
-        "beforeresize",
+        for(i = 0; i < len; i++) {
+            component = components[i];
+            el = component.getPositionEl();
 
-        "beforeapply"
-    );
+            
+            if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){
+                component.anchor = this.defaultAnchor;
+            }
 
-    Ext.SplitBar.superclass.constructor.call(this);
-};
+            if(component.anchor) {
+                anchorSpec = component.anchorSpec;
+                
+                if(!anchorSpec){
+                    anchorsArray = component.anchor.split(' ');
+                    component.anchorSpec = anchorSpec = {
+                        right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
+                        bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
+                    };
+                }
+                calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined;
+                calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined;
 
-Ext.extend(Ext.SplitBar, Ext.util.Observable, {
-    onStartProxyDrag : function(x, y){
-        this.fireEvent("beforeresize", this);
-        this.overlay =  Ext.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);
-        this.overlay.unselectable();
-        this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
-        this.overlay.show();
-        Ext.get(this.proxy).setDisplayed("block");
-        var size = this.adapter.getElementSize(this);
-        this.activeMinSize = this.getMinimumSize();
-        this.activeMaxSize = this.getMaximumSize();
-        var c1 = size - this.activeMinSize;
-        var c2 = Math.max(this.activeMaxSize - size, 0);
-        if(this.orientation == Ext.SplitBar.HORIZONTAL){
-            this.dd.resetConstraints();
-            this.dd.setXConstraint(
-                this.placement == Ext.SplitBar.LEFT ? c1 : c2,
-                this.placement == Ext.SplitBar.LEFT ? c2 : c1,
-                this.tickSize
-            );
-            this.dd.setYConstraint(0, 0);
-        }else{
-            this.dd.resetConstraints();
-            this.dd.setXConstraint(0, 0);
-            this.dd.setYConstraint(
-                this.placement == Ext.SplitBar.TOP ? c1 : c2,
-                this.placement == Ext.SplitBar.TOP ? c2 : c1,
-                this.tickSize
-            );
-         }
-        this.dragSpecs.startSize = size;
-        this.dragSpecs.startPoint = [x, y];
-        Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
+                if(calcWidth || calcHeight) {
+                    boxes.push({
+                        component: component,
+                        width: calcWidth || undefined,
+                        height: calcHeight || undefined
+                    });
+                }
+            }
+        }
+        for (i = 0, len = boxes.length; i < len; i++) {
+            box = boxes[i];
+            box.component.setSize(box.width, box.height);
+        }
+
+        if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
+            var newTargetSize = this.getLayoutTargetSize();
+            if (newTargetSize.width != size.width || newTargetSize.height != size.height){
+                this.adjustmentPass = true;
+                this.onLayout(container, target);
+            }
+        }
+
+        delete this.adjustmentPass;
     },
 
     
-    onEndProxyDrag : function(e){
-        Ext.get(this.proxy).setDisplayed(false);
-        var endPoint = Ext.lib.Event.getXY(e);
-        if(this.overlay){
-            Ext.destroy(this.overlay);
-            delete this.overlay;
-        }
-        var newSize;
-        if(this.orientation == Ext.SplitBar.HORIZONTAL){
-            newSize = this.dragSpecs.startSize +
-                (this.placement == Ext.SplitBar.LEFT ?
-                    endPoint[0] - this.dragSpecs.startPoint[0] :
-                    this.dragSpecs.startPoint[0] - endPoint[0]
-                );
-        }else{
-            newSize = this.dragSpecs.startSize +
-                (this.placement == Ext.SplitBar.TOP ?
-                    endPoint[1] - this.dragSpecs.startPoint[1] :
-                    this.dragSpecs.startPoint[1] - endPoint[1]
-                );
-        }
-        newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
-        if(newSize != this.dragSpecs.startSize){
-            if(this.fireEvent('beforeapply', this, newSize) !== false){
-                this.adapter.setElementSize(this, newSize);
-                this.fireEvent("moved", this, newSize);
-                this.fireEvent("resize", this, newSize);
+    parseAnchor : function(a, start, cstart) {
+        if (a && a != 'none') {
+            var last;
+            
+            if (this.parseAnchorRE.test(a)) {
+                var diff = cstart - start;
+                return function(v){
+                    if(v !== last){
+                        last = v;
+                        return v - diff;
+                    }
+                };
+            
+            } else if(a.indexOf('%') != -1) {
+                var ratio = parseFloat(a.replace('%', ''))*.01;
+                return function(v){
+                    if(v !== last){
+                        last = v;
+                        return Math.floor(v*ratio);
+                    }
+                };
+            
+            } else {
+                a = parseInt(a, 10);
+                if (!isNaN(a)) {
+                    return function(v) {
+                        if (v !== last) {
+                            last = v;
+                            return v + a;
+                        }
+                    };
+                }
             }
         }
+        return false;
     },
 
     
-    getAdapter : function(){
-        return this.adapter;
+    adjustWidthAnchor : function(value, comp){
+        return value;
     },
 
     
-    setAdapter : function(adapter){
-        this.adapter = adapter;
-        this.adapter.init(this);
-    },
+    adjustHeightAnchor : function(value, comp){
+        return value;
+    }
 
     
-    getMinimumSize : function(){
-        return this.minSize;
-    },
+});
+Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
 
+Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
     
-    setMinimumSize : function(minSize){
-        this.minSize = minSize;
-    },
+    monitorResize:true,
+
+    type: 'column',
+
+    extraCls: 'x-column',
+
+    scrollOffset : 0,
 
     
-    getMaximumSize : function(){
-        return this.maxSize;
+
+    targetCls: 'x-column-layout-ct',
+
+    isValidParent : function(c, target){
+        return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
     },
 
-    
-    setMaximumSize : function(maxSize){
-        this.maxSize = maxSize;
+    getLayoutTargetSize : function() {
+        var target = this.container.getLayoutTarget(), ret;
+        if (target) {
+            ret = target.getViewSize();
+
+            
+            
+            
+            if (Ext.isIE && Ext.isStrict && ret.width == 0){
+                ret =  target.getStyleSize();
+            }
+
+            ret.width -= target.getPadding('lr');
+            ret.height -= target.getPadding('tb');
+        }
+        return ret;
     },
 
-    
-    setCurrentSize : function(size){
-        var oldAnimate = this.animate;
-        this.animate = false;
-        this.adapter.setElementSize(this, size);
-        this.animate = oldAnimate;
+    renderAll : function(ct, target) {
+        if(!this.innerCt){
+            
+            
+            this.innerCt = target.createChild({cls:'x-column-inner'});
+            this.innerCt.createChild({cls:'x-clear'});
+        }
+        Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
     },
 
     
-    destroy : function(removeEl){
-        Ext.destroy(this.shim, Ext.get(this.proxy));
-        this.dd.unreg();
-        if(removeEl){
-            this.el.remove();
-        }
-        this.purgeListeners();
-    }
-});
+    onLayout : function(ct, target){
+        var cs = ct.items.items,
+            len = cs.length,
+            c,
+            i,
+            m,
+            margins = [];
 
+        this.renderAll(ct, target);
 
-Ext.SplitBar.createProxy = function(dir){
-    var proxy = new Ext.Element(document.createElement("div"));
-    document.body.appendChild(proxy.dom);
-    proxy.unselectable();
-    var cls = 'x-splitbar-proxy';
-    proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
-    return proxy.dom;
-};
+        var size = this.getLayoutTargetSize();
 
+        if(size.width < 1 && size.height < 1){ 
+            return;
+        }
 
-Ext.SplitBar.BasicLayoutAdapter = function(){
-};
+        var w = size.width - this.scrollOffset,
+            h = size.height,
+            pw = w;
 
-Ext.SplitBar.BasicLayoutAdapter.prototype = {
-    
-    init : function(s){
+        this.innerCt.setWidth(w);
 
-    },
-    
-     getElementSize : function(s){
-        if(s.orientation == Ext.SplitBar.HORIZONTAL){
-            return s.resizingEl.getWidth();
-        }else{
-            return s.resizingEl.getHeight();
+        
+        
+
+        for(i = 0; i < len; i++){
+            c = cs[i];
+            m = c.getPositionEl().getMargins('lr');
+            margins[i] = m;
+            if(!c.columnWidth){
+                pw -= (c.getWidth() + m);
+            }
         }
-    },
 
-    
-    setElementSize : function(s, newSize, onComplete){
-        if(s.orientation == Ext.SplitBar.HORIZONTAL){
-            if(!s.animate){
-                s.resizingEl.setWidth(newSize);
-                if(onComplete){
-                    onComplete(s, newSize);
-                }
-            }else{
-                s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
+        pw = pw < 0 ? 0 : pw;
+
+        for(i = 0; i < len; i++){
+            c = cs[i];
+            m = margins[i];
+            if(c.columnWidth){
+                c.setSize(Math.floor(c.columnWidth * pw) - m);
             }
-        }else{
+        }
 
-            if(!s.animate){
-                s.resizingEl.setHeight(newSize);
-                if(onComplete){
-                    onComplete(s, newSize);
+        
+        
+        if (Ext.isIE) {
+            if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
+                var ts = this.getLayoutTargetSize();
+                if (ts.width != size.width){
+                    this.adjustmentPass = true;
+                    this.onLayout(ct, target);
                 }
-            }else{
-                s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
             }
         }
+        delete this.adjustmentPass;
     }
-};
 
+    
+});
 
-Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
-    this.basic = new Ext.SplitBar.BasicLayoutAdapter();
-    this.container = Ext.get(container);
-};
+Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
 
-Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
-    init : function(s){
-        this.basic.init(s);
-    },
+Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
+    
+    monitorResize:true,
+    
+    rendered : false,
 
-    getElementSize : function(s){
-        return this.basic.getElementSize(s);
-    },
+    type: 'border',
 
-    setElementSize : function(s, newSize, onComplete){
-        this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
+    targetCls: 'x-border-layout-ct',
+
+    getLayoutTargetSize : function() {
+        var target = this.container.getLayoutTarget();
+        return target ? target.getViewSize() : {};
     },
 
-    moveSplitter : function(s){
-        var yes = Ext.SplitBar;
-        switch(s.placement){
-            case yes.LEFT:
-                s.el.setX(s.resizingEl.getRight());
-                break;
-            case yes.RIGHT:
-                s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
-                break;
-            case yes.TOP:
-                s.el.setY(s.resizingEl.getBottom());
-                break;
-            case yes.BOTTOM:
-                s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
-                break;
+    
+    onLayout : function(ct, target){
+        var collapsed, i, c, pos, items = ct.items.items, len = items.length;
+        if(!this.rendered){
+            collapsed = [];
+            for(i = 0; i < len; i++) {
+                c = items[i];
+                pos = c.region;
+                if(c.collapsed){
+                    collapsed.push(c);
+                }
+                c.collapsed = false;
+                if(!c.rendered){
+                    c.render(target, i);
+                    c.getPositionEl().addClass('x-border-panel');
+                }
+                this[pos] = pos != 'center' && c.split ?
+                    new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
+                    new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
+                this[pos].render(target, c);
+            }
+            this.rendered = true;
         }
-    }
-};
-
-
-Ext.SplitBar.VERTICAL = 1;
-
-
-Ext.SplitBar.HORIZONTAL = 2;
 
+        var size = this.getLayoutTargetSize();
+        if(size.width < 20 || size.height < 20){ 
+            if(collapsed){
+                this.restoreCollapsed = collapsed;
+            }
+            return;
+        }else if(this.restoreCollapsed){
+            collapsed = this.restoreCollapsed;
+            delete this.restoreCollapsed;
+        }
 
-Ext.SplitBar.LEFT = 1;
-
+        var w = size.width, h = size.height,
+            centerW = w, centerH = h, centerY = 0, centerX = 0,
+            n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
+            b, m, totalWidth, totalHeight;
+        if(!c && Ext.layout.BorderLayout.WARN !== false){
+            throw 'No center region defined in BorderLayout ' + ct.id;
+        }
 
-Ext.SplitBar.RIGHT = 2;
+        if(n && n.isVisible()){
+            b = n.getSize();
+            m = n.getMargins();
+            b.width = w - (m.left+m.right);
+            b.x = m.left;
+            b.y = m.top;
+            centerY = b.height + b.y + m.bottom;
+            centerH -= centerY;
+            n.applyLayout(b);
+        }
+        if(s && s.isVisible()){
+            b = s.getSize();
+            m = s.getMargins();
+            b.width = w - (m.left+m.right);
+            b.x = m.left;
+            totalHeight = (b.height + m.top + m.bottom);
+            b.y = h - totalHeight + m.top;
+            centerH -= totalHeight;
+            s.applyLayout(b);
+        }
+        if(west && west.isVisible()){
+            b = west.getSize();
+            m = west.getMargins();
+            b.height = centerH - (m.top+m.bottom);
+            b.x = m.left;
+            b.y = centerY + m.top;
+            totalWidth = (b.width + m.left + m.right);
+            centerX += totalWidth;
+            centerW -= totalWidth;
+            west.applyLayout(b);
+        }
+        if(e && e.isVisible()){
+            b = e.getSize();
+            m = e.getMargins();
+            b.height = centerH - (m.top+m.bottom);
+            totalWidth = (b.width + m.left + m.right);
+            b.x = w - totalWidth + m.left;
+            b.y = centerY + m.top;
+            centerW -= totalWidth;
+            e.applyLayout(b);
+        }
+        if(c){
+            m = c.getMargins();
+            var centerBox = {
+                x: centerX + m.left,
+                y: centerY + m.top,
+                width: centerW - (m.left+m.right),
+                height: centerH - (m.top+m.bottom)
+            };
+            c.applyLayout(centerBox);
+        }
+        if(collapsed){
+            for(i = 0, len = collapsed.length; i < len; i++){
+                collapsed[i].collapse(false);
+            }
+        }
+        if(Ext.isIE && Ext.isStrict){ 
+            target.repaint();
+        }
+        
+        if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
+            var ts = this.getLayoutTargetSize();
+            if (ts.width != size.width || ts.height != size.height){
+                this.adjustmentPass = true;
+                this.onLayout(ct, target);
+            }
+        }
+        delete this.adjustmentPass;
+    },
 
+    destroy: function() {
+        var r = ['north', 'south', 'east', 'west'], i, region;
+        for (i = 0; i < r.length; i++) {
+            region = this[r[i]];
+            if(region){
+                if(region.destroy){
+                    region.destroy();
+                }else if (region.split){
+                    region.split.destroy(true);
+                }
+            }
+        }
+        Ext.layout.BorderLayout.superclass.destroy.call(this);
+    }
 
-Ext.SplitBar.TOP = 3;
+    
+});
 
 
-Ext.SplitBar.BOTTOM = 4;
+Ext.layout.BorderLayout.Region = function(layout, config, pos){
+    Ext.apply(this, config);
+    this.layout = layout;
+    this.position = pos;
+    this.state = {};
+    if(typeof this.margins == 'string'){
+        this.margins = this.layout.parseMargins(this.margins);
+    }
+    this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
+    if(this.collapsible){
+        if(typeof this.cmargins == 'string'){
+            this.cmargins = this.layout.parseMargins(this.cmargins);
+        }
+        if(this.collapseMode == 'mini' && !this.cmargins){
+            this.cmargins = {left:0,top:0,right:0,bottom:0};
+        }else{
+            this.cmargins = Ext.applyIf(this.cmargins || {},
+                pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
+        }
+    }
+};
 
-Ext.Container = Ext.extend(Ext.BoxComponent, {
+Ext.layout.BorderLayout.Region.prototype = {
     
     
     
     
-    bufferResize: 50,
-
     
     
+    collapsible : false,
     
-
-
+    split:false,
     
-    autoDestroy : true,
-
+    floatable: true,
     
-    forceLayout: false,
+    minWidth:50,
+    
+    minHeight:50,
 
     
+    defaultMargins : {left:0,top:0,right:0,bottom:0},
     
-    defaultType : 'panel',
-
+    defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
     
-    resizeEvent: 'resize',
+    defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
+    floatingZIndex: 100,
 
     
-    bubbleEvents: ['add', 'remove'],
+    isCollapsed : false,
 
     
-    initComponent : function(){
-        Ext.Container.superclass.initComponent.call(this);
-
-        this.addEvents(
-            
-            'afterlayout',
-            
-            'beforeadd',
-            
-            'beforeremove',
-            
-            'add',
-            
-            'remove'
-        );
-
-        this.enableBubble(this.bubbleEvents);
-
-        
-        var items = this.items;
-        if(items){
-            delete this.items;
-            this.add(items);
-        }
-    },
-
     
-    initItems : function(){
-        if(!this.items){
-            this.items = new Ext.util.MixedCollection(false, this.getComponentId);
-            this.getLayout(); 
-        }
-    },
-
     
-    setLayout : function(layout){
-        if(this.layout && this.layout != layout){
-            this.layout.setContainer(null);
-        }
-        this.initItems();
-        this.layout = layout;
-        layout.setContainer(this);
-    },
-
-    afterRender: function(){
-        this.layoutDone = false;
-        if(!this.layout){
-            this.layout = 'auto';
-        }
-        if(Ext.isObject(this.layout) && !this.layout.layout){
-            this.layoutConfig = this.layout;
-            this.layout = this.layoutConfig.type;
-        }
-        if(Ext.isString(this.layout)){
-            this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
-        }
-        this.setLayout(this.layout);
-
-        
-        
-        Ext.Container.superclass.afterRender.call(this);
-
-        if(Ext.isDefined(this.activeItem)){
-            var item = this.activeItem;
-            delete this.activeItem;
-            this.layout.setActiveItem(item);
-        }
-
-        
-        if(!this.ownerCt && !this.layoutDone){
-            this.doLayout(false, true);
-        }
-
-        if(this.monitorResize === true){
-            Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
-        }
-    },
 
     
-    getLayoutTarget : function(){
-        return this.el;
-    },
+    render : function(ct, p){
+        this.panel = p;
+        p.el.enableDisplayMode();
+        this.targetEl = ct;
+        this.el = p.el;
 
-    
-    getComponentId : function(comp){
-        return comp.getItemId();
-    },
+        var gs = p.getState, ps = this.position;
+        p.getState = function(){
+            return Ext.apply(gs.call(p) || {}, this.state);
+        }.createDelegate(this);
 
-    
-    add : function(comp){
-        this.initItems();
-        var args = arguments.length > 1;
-        if(args || Ext.isArray(comp)){
-            var result = [];
-            Ext.each(args ? arguments : comp, function(c){
-                result.push(this.add(c));
-            }, this);
-            return result;
-        }
-        var c = this.lookupComponent(this.applyDefaults(comp));
-        var index = this.items.length;
-        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
-            this.items.add(c);
-            
-            c.onAdded(this, index);
-            this.onAdd(c);
-            this.fireEvent('add', this, c, index);
+        if(ps != 'center'){
+            p.allowQueuedExpand = false;
+            p.on({
+                beforecollapse: this.beforeCollapse,
+                collapse: this.onCollapse,
+                beforeexpand: this.beforeExpand,
+                expand: this.onExpand,
+                hide: this.onHide,
+                show: this.onShow,
+                scope: this
+            });
+            if(this.collapsible || this.floatable){
+                p.collapseEl = 'el';
+                p.slideAnchor = this.getSlideAnchor();
+            }
+            if(p.tools && p.tools.toggle){
+                p.tools.toggle.addClass('x-tool-collapse-'+ps);
+                p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
+            }
         }
-        return c;
-    },
-
-    onAdd : function(c){
-        
-    },
-    
-    
-    onAdded : function(container, pos) {
-        
-        this.ownerCt = container;
-        this.initRef();
-        
-        this.cascade(function(c){
-            c.initRef();
-        });
-        this.fireEvent('added', this, container, pos);
     },
 
     
-    insert : function(index, comp){
-        this.initItems();
-        var a = arguments, len = a.length;
-        if(len > 2){
-            var result = [];
-            for(var i = len-1; i >= 1; --i) {
-                result.push(this.insert(index, a[i]));
+    getCollapsedEl : function(){
+        if(!this.collapsedEl){
+            if(!this.toolTemplate){
+                var tt = new Ext.Template(
+                     '<div class="x-tool x-tool-{id}">&#160;</div>'
+                );
+                tt.disableFormats = true;
+                tt.compile();
+                Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
             }
-            return result;
-        }
-        var c = this.lookupComponent(this.applyDefaults(comp));
-        index = Math.min(index, this.items.length);
-        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
-            if(c.ownerCt == this){
-                this.items.remove(c);
+            this.collapsedEl = this.targetEl.createChild({
+                cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
+                id: this.panel.id + '-xcollapsed'
+            });
+            this.collapsedEl.enableDisplayMode('block');
+
+            if(this.collapseMode == 'mini'){
+                this.collapsedEl.addClass('x-layout-cmini-'+this.position);
+                this.miniCollapsedEl = this.collapsedEl.createChild({
+                    cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
+                });
+                this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
+                this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
+                this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
+            }else {
+                if(this.collapsible !== false && !this.hideCollapseTool) {
+                    var t = this.expandToolEl = this.toolTemplate.append(
+                            this.collapsedEl.dom,
+                            {id:'expand-'+this.position}, true);
+                    t.addClassOnOver('x-tool-expand-'+this.position+'-over');
+                    t.on('click', this.onExpandClick, this, {stopEvent:true});
+                }
+                if(this.floatable !== false || this.titleCollapse){
+                   this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
+                   this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
+                }
             }
-            this.items.insert(index, c);
-            c.onAdded(this, index);
-            this.onAdd(c);
-            this.fireEvent('add', this, c, index);
         }
-        return c;
+        return this.collapsedEl;
     },
 
     
-    applyDefaults : function(c){
-        var d = this.defaults;
-        if(d){
-            if(Ext.isFunction(d)){
-                d = d.call(this, c);
-            }
-            if(Ext.isString(c)){
-                c = Ext.ComponentMgr.get(c);
-                Ext.apply(c, d);
-            }else if(!c.events){
-                Ext.applyIf(c, d);
-            }else{
-                Ext.apply(c, d);
-            }
+    onExpandClick : function(e){
+        if(this.isSlid){
+            this.panel.expand(false);
+        }else{
+            this.panel.expand();
         }
-        return c;
     },
 
     
-    onBeforeAdd : function(item){
-        if(item.ownerCt){
-            item.ownerCt.remove(item, false);
-        }
-        if(this.hideBorders === true){
-            item.border = (item.border === true);
-        }
+    onCollapseClick : function(e){
+        this.panel.collapse();
     },
 
     
-    remove : function(comp, autoDestroy){
-        this.initItems();
-        var c = this.getComponent(comp);
-        if(c && this.fireEvent('beforeremove', this, c) !== false){
-            this.doRemove(c, autoDestroy);
-            this.fireEvent('remove', this, c);
+    beforeCollapse : function(p, animate){
+        this.lastAnim = animate;
+        if(this.splitEl){
+            this.splitEl.hide();
         }
-        return c;
+        this.getCollapsedEl().show();
+        var el = this.panel.getEl();
+        this.originalZIndex = el.getStyle('z-index');
+        el.setStyle('z-index', 100);
+        this.isCollapsed = true;
+        this.layout.layout();
     },
 
-    onRemove: function(c){
-        
+    
+    onCollapse : function(animate){
+        this.panel.el.setStyle('z-index', 1);
+        if(this.lastAnim === false || this.panel.animCollapse === false){
+            this.getCollapsedEl().dom.style.visibility = 'visible';
+        }else{
+            this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
+        }
+        this.state.collapsed = true;
+        this.panel.saveState();
     },
 
     
-    doRemove: function(c, autoDestroy){
-        if(this.layout && this.rendered){
-            this.layout.onRemove(c);
+    beforeExpand : function(animate){
+        if(this.isSlid){
+            this.afterSlideIn();
         }
-        this.items.remove(c);
-        c.onRemoved();
-        this.onRemove(c);
-        if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
-            c.destroy();
+        var c = this.getCollapsedEl();
+        this.el.show();
+        if(this.position == 'east' || this.position == 'west'){
+            this.panel.setSize(undefined, c.getHeight());
+        }else{
+            this.panel.setSize(c.getWidth(), undefined);
         }
+        c.hide();
+        c.dom.style.visibility = 'hidden';
+        this.panel.el.setStyle('z-index', this.floatingZIndex);
     },
 
     
-    removeAll: function(autoDestroy){
-        this.initItems();
-        var item, rem = [], items = [];
-        this.items.each(function(i){
-            rem.push(i);
-        });
-        for (var i = 0, len = rem.length; i < len; ++i){
-            item = rem[i];
-            this.remove(item, autoDestroy);
-            if(item.ownerCt !== this){
-                items.push(item);
-            }
+    onExpand : function(){
+        this.isCollapsed = false;
+        if(this.splitEl){
+            this.splitEl.show();
         }
-        return items;
+        this.layout.layout();
+        this.panel.el.setStyle('z-index', this.originalZIndex);
+        this.state.collapsed = false;
+        this.panel.saveState();
     },
 
     
-    getComponent : function(comp){
-        if(Ext.isObject(comp)){
-            comp = comp.getItemId();
+    collapseClick : function(e){
+        if(this.isSlid){
+           e.stopPropagation();
+           this.slideIn();
+        }else{
+           e.stopPropagation();
+           this.slideOut();
         }
-        return this.items.get(comp);
     },
 
     
-    lookupComponent : function(comp){
-        if(Ext.isString(comp)){
-            return Ext.ComponentMgr.get(comp);
-        }else if(!comp.events){
-            return this.createComponent(comp);
+    onHide : function(){
+        if(this.isCollapsed){
+            this.getCollapsedEl().hide();
+        }else if(this.splitEl){
+            this.splitEl.hide();
         }
-        return comp;
     },
 
     
-    createComponent : function(config, defaultType){
-        
-        
-        var c = config.render ? config : Ext.create(Ext.apply({
-            ownerCt: this
-        }, config), defaultType || this.defaultType);
-        delete c.ownerCt;
-        return c;
+    onShow : function(){
+        if(this.isCollapsed){
+            this.getCollapsedEl().show();
+        }else if(this.splitEl){
+            this.splitEl.show();
+        }
     },
 
     
-    canLayout: function() {
-        var el = this.getLayoutTarget(), vs;
-        return !!(el && (vs = el.dom.offsetWidth || el.dom.offsetHeight));
+    isVisible : function(){
+        return !this.panel.hidden;
     },
 
     
-    doLayout: function(shallow, force){
-        var rendered = this.rendered,
-            forceLayout = force || this.forceLayout,
-            cs, i, len, c;
-
-        this.layoutDone = true;
-        if(!this.canLayout() || this.collapsed){
-            this.deferLayout = this.deferLayout || !shallow;
-            if(!forceLayout){
-                return;
-            }
-            shallow = shallow && !this.deferLayout;
-        } else {
-            delete this.deferLayout;
-        }
-
-        cs = (shallow !== true && this.items) ? this.items.items : [];
-
-
-        for(i = 0, len = cs.length; i < len; i++){
-            if ((c = cs[i]).layout) {
-                c.suspendLayoutResize = true;
-            }
-        }
-
-
-
-        if(rendered && this.layout){
-            this.layout.layout();
-        }
-
-
-        for(i = 0; i < len; i++){
-            if((c = cs[i]).doLayout){
-                c.doLayout(false, forceLayout);
-            }
-        }
-        if(rendered){
-            this.onLayout(shallow, forceLayout);
-        }
-        
-        this.hasLayout = true;
-        delete this.forceLayout;
-
-
-        for(i = 0; i < len; i++){
-            if ((c = cs[i]).layout) {
-                delete c.suspendLayoutResize;
-            }
-        }
+    getMargins : function(){
+        return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
     },
 
     
-    onLayout : Ext.emptyFn,
-
-    onResize: function(adjWidth, adjHeight, rawWidth, rawHeight){
-        Ext.Container.superclass.onResize.apply(this, arguments);
-        if ((this.rendered && this.layout && this.layout.monitorResize) && !this.suspendLayoutResize) {
-            this.layout.onResize();
-        }
+    getSize : function(){
+        return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
     },
 
     
-    hasLayoutPending: function(){
-        
-        var pending = this.layoutPending;
-        this.ownerCt.bubble(function(c){
-            return !(pending = c.layoutPending);
-        });
-        return pending;
-
+    setPanel : function(panel){
+        this.panel = panel;
     },
 
-    onShow : function(){
-        Ext.Container.superclass.onShow.call(this);
-        if(Ext.isDefined(this.deferLayout)){
-            this.doLayout(true);
-        }
+    
+    getMinWidth: function(){
+        return this.minWidth;
     },
 
     
-    getLayout : function(){
-        if(!this.layout){
-            var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
-            this.setLayout(layout);
-        }
-        return this.layout;
+    getMinHeight: function(){
+        return this.minHeight;
     },
 
     
-    beforeDestroy : function(){
-        var c;
-        if(this.items){
-            while(c = this.items.first()){
-                this.doRemove(c, true);
-            }
-        }
-        if(this.monitorResize){
-            Ext.EventManager.removeResizeListener(this.doLayout, this);
-        }
-        Ext.destroy(this.layout);
-        Ext.Container.superclass.beforeDestroy.call(this);
+    applyLayoutCollapsed : function(box){
+        var ce = this.getCollapsedEl();
+        ce.setLeftTop(box.x, box.y);
+        ce.setSize(box.width, box.height);
     },
 
     
-    bubble : function(fn, scope, args){
-        var p = this;
-        while(p){
-            if(fn.apply(scope || p, args || [p]) === false){
-                break;
-            }
-            p = p.ownerCt;
+    applyLayout : function(box){
+        if(this.isCollapsed){
+            this.applyLayoutCollapsed(box);
+        }else{
+            this.panel.setPosition(box.x, box.y);
+            this.panel.setSize(box.width, box.height);
         }
-        return this;
     },
 
     
-    cascade : function(fn, scope, args){
-        if(fn.apply(scope || this, args || [this]) !== false){
-            if(this.items){
-                var cs = this.items.items;
-                for(var i = 0, len = cs.length; i < len; i++){
-                    if(cs[i].cascade){
-                        cs[i].cascade(fn, scope, args);
-                    }else{
-                        fn.apply(scope || cs[i], args || [cs[i]]);
-                    }
-                }
-            }
-        }
-        return this;
+    beforeSlide: function(){
+        this.panel.beforeEffect();
     },
 
     
-    findById : function(id){
-        var m, ct = this;
-        this.cascade(function(c){
-            if(ct != c && c.id === id){
-                m = c;
-                return false;
-            }
-        });
-        return m || null;
+    afterSlide : function(){
+        this.panel.afterEffect();
     },
 
     
-    findByType : function(xtype, shallow){
-        return this.findBy(function(c){
-            return c.isXType(xtype, shallow);
-        });
+    initAutoHide : function(){
+        if(this.autoHide !== false){
+            if(!this.autoHideHd){
+                this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
+                this.autoHideHd = {
+                    "mouseout": function(e){
+                        if(!e.within(this.el, true)){
+                            this.autoHideSlideTask.delay(500);
+                        }
+                    },
+                    "mouseover" : function(e){
+                        this.autoHideSlideTask.cancel();
+                    },
+                    scope : this
+                };
+            }
+            this.el.on(this.autoHideHd);
+            this.collapsedEl.on(this.autoHideHd);
+        }
     },
 
     
-    find : function(prop, value){
-        return this.findBy(function(c){
-            return c[prop] === value;
-        });
+    clearAutoHide : function(){
+        if(this.autoHide !== false){
+            this.el.un("mouseout", this.autoHideHd.mouseout);
+            this.el.un("mouseover", this.autoHideHd.mouseover);
+            this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
+            this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
+        }
     },
 
     
-    findBy : function(fn, scope){
-        var m = [], ct = this;
-        this.cascade(function(c){
-            if(ct != c && fn.call(scope || c, c, ct) === true){
-                m.push(c);
-            }
-        });
-        return m;
+    clearMonitor : function(){
+        Ext.getDoc().un("click", this.slideInIf, this);
     },
 
     
-    get : function(key){
-        return this.items.get(key);
-    }
-});
+    slideOut : function(){
+        if(this.isSlid || this.el.hasActiveFx()){
+            return;
+        }
+        this.isSlid = true;
+        var ts = this.panel.tools, dh, pc;
+        if(ts && ts.toggle){
+            ts.toggle.hide();
+        }
+        this.el.show();
 
-Ext.Container.LAYOUTS = {};
-Ext.reg('container', Ext.Container);
+        
+        pc = this.panel.collapsed;
+        this.panel.collapsed = false;
 
-Ext.layout.ContainerLayout = Ext.extend(Object, {
-    
-    
+        if(this.position == 'east' || this.position == 'west'){
+            
+            dh = this.panel.deferHeight;
+            this.panel.deferHeight = false;
 
-    
+            this.panel.setSize(undefined, this.collapsedEl.getHeight());
 
-    
-    monitorResize:false,
-    
-    activeItem : null,
+            
+            this.panel.deferHeight = dh;
+        }else{
+            this.panel.setSize(this.collapsedEl.getWidth(), undefined);
+        }
 
-    constructor : function(config){
-        Ext.apply(this, config);
-    },
+        
+        this.panel.collapsed = pc;
 
-    
-    layout : function(){
-        var target = this.container.getLayoutTarget();
-        if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
-            target.addClass(this.targetCls)
+        this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
+        this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
+        this.el.setStyle("z-index", this.floatingZIndex+2);
+        this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
+        if(this.animFloat !== false){
+            this.beforeSlide();
+            this.el.slideIn(this.getSlideAnchor(), {
+                callback: function(){
+                    this.afterSlide();
+                    this.initAutoHide();
+                    Ext.getDoc().on("click", this.slideInIf, this);
+                },
+                scope: this,
+                block: true
+            });
+        }else{
+            this.initAutoHide();
+             Ext.getDoc().on("click", this.slideInIf, this);
         }
-        this.onLayout(this.container, target);
-        this.container.fireEvent('afterlayout', this.container, this);
-        this.hasLayout = true;
     },
 
     
-    onLayout : function(ct, target){
-        this.renderAll(ct, target);
-    },
+    afterSlideIn : function(){
+        this.clearAutoHide();
+        this.isSlid = false;
+        this.clearMonitor();
+        this.el.setStyle("z-index", "");
+        this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
+        this.el.dom.style.left = this.restoreLT[0];
+        this.el.dom.style.top = this.restoreLT[1];
 
-    
-    isValidParent : function(c, target){
-        return target && c.getPositionEl().dom.parentNode == (target.dom || target);
+        var ts = this.panel.tools;
+        if(ts && ts.toggle){
+            ts.toggle.show();
+        }
     },
 
     
-    renderAll : function(ct, target){
-        var items = ct.items.items;
-        for(var i = 0, len = items.length; i < len; i++) {
-            var c = items[i];
-            if(c && (!c.rendered || !this.isValidParent(c, target))){
-                this.renderItem(c, i, target);
-            }
+    slideIn : function(cb){
+        if(!this.isSlid || this.el.hasActiveFx()){
+            Ext.callback(cb);
+            return;
+        }
+        this.isSlid = false;
+        if(this.animFloat !== false){
+            this.beforeSlide();
+            this.el.slideOut(this.getSlideAnchor(), {
+                callback: function(){
+                    this.el.hide();
+                    this.afterSlide();
+                    this.afterSlideIn();
+                    Ext.callback(cb);
+                },
+                scope: this,
+                block: true
+            });
+        }else{
+            this.el.hide();
+            this.afterSlideIn();
         }
     },
 
     
-    renderItem : function(c, position, target){
-        if(c && !c.rendered){
-            c.render(target, position);
-            this.configureItem(c, position);
-        }else if(c && !this.isValidParent(c, target)){
-            if(Ext.isNumber(position)){
-                position = target.dom.childNodes[position];
-            }
-            target.dom.insertBefore(c.getPositionEl().dom, position || null);
-            c.container = target;
-            this.configureItem(c, position);
+    slideInIf : function(e){
+        if(!e.within(this.el)){
+            this.slideIn();
         }
     },
 
     
-    configureItem: function(c, position){
-        if(this.extraCls){
-            var t = c.getPositionEl ? c.getPositionEl() : c;
-            t.addClass(this.extraCls);
-        }
-        
-        if(c.doLayout && this.forceLayout){
-            c.doLayout(false, true);
-        }
-        if (this.renderHidden && c != this.activeItem) {
-            c.hide();
-        }
+    anchors : {
+        "west" : "left",
+        "east" : "right",
+        "north" : "top",
+        "south" : "bottom"
     },
 
-    onRemove: function(c){
-         if(this.activeItem == c){
-            delete this.activeItem;
-         }
-         if(c.rendered && this.extraCls){
-            var t = c.getPositionEl ? c.getPositionEl() : c;
-            t.removeClass(this.extraCls);
-        }
+    
+    sanchors : {
+        "west" : "l",
+        "east" : "r",
+        "north" : "t",
+        "south" : "b"
     },
 
     
-    onResize: function(){
-        var ct = this.container,
-            b = ct.bufferResize;
-
-        if (ct.collapsed){
-            return;
-        }
+    canchors : {
+        "west" : "tl-tr",
+        "east" : "tr-tl",
+        "north" : "tl-bl",
+        "south" : "bl-tl"
+    },
 
-        
-        
-        if (b && ct.ownerCt) {
-            
-            
-            
-            if (!ct.hasLayoutPending()){
-                if(!this.resizeTask){
-                    this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
-                    this.resizeBuffer = Ext.isNumber(b) ? b : 50;
-                }
-                ct.layoutPending = true;
-                this.resizeTask.delay(this.resizeBuffer);
-            }
-        }else{
-            ct.doLayout(false, this.forceLayout);
-        }
+    
+    getAnchor : function(){
+        return this.anchors[this.position];
     },
 
     
-    runLayout: function(){
-        var ct = this.container;
-        ct.doLayout();
-        delete ct.layoutPending;
+    getCollapseAnchor : function(){
+        return this.canchors[this.position];
     },
 
     
-    setContainer : function(ct){
-        
-        
-        this.container = ct;
+    getSlideAnchor : function(){
+        return this.sanchors[this.position];
     },
 
     
-    parseMargins : function(v){
-        if(Ext.isNumber(v)){
-            v = v.toString();
-        }
-        var ms = v.split(' ');
-        var len = ms.length;
-        if(len == 1){
-            ms[1] = ms[0];
-            ms[2] = ms[0];
-            ms[3] = ms[0];
-        }
-        if(len == 2){
-            ms[2] = ms[0];
-            ms[3] = ms[1];
+    getAlignAdj : function(){
+        var cm = this.cmargins;
+        switch(this.position){
+            case "west":
+                return [0, 0];
+            break;
+            case "east":
+                return [0, 0];
+            break;
+            case "north":
+                return [0, 0];
+            break;
+            case "south":
+                return [0, 0];
+            break;
         }
-        if(len == 3){
-            ms[3] = ms[1];
+    },
+
+    
+    getExpandAdj : function(){
+        var c = this.collapsedEl, cm = this.cmargins;
+        switch(this.position){
+            case "west":
+                return [-(cm.right+c.getWidth()+cm.left), 0];
+            break;
+            case "east":
+                return [cm.right+c.getWidth()+cm.left, 0];
+            break;
+            case "north":
+                return [0, -(cm.top+cm.bottom+c.getHeight())];
+            break;
+            case "south":
+                return [0, cm.top+cm.bottom+c.getHeight()];
+            break;
         }
-        return {
-            top:parseInt(ms[0], 10) || 0,
-            right:parseInt(ms[1], 10) || 0,
-            bottom:parseInt(ms[2], 10) || 0,
-            left:parseInt(ms[3], 10) || 0
-        };
     },
 
-    
-    fieldTpl: (function() {
-        var t = new Ext.Template(
-            '<div class="x-form-item {itemCls}" tabIndex="-1">',
-                '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
-                '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
-                '</div><div class="{clearCls}"></div>',
-            '</div>'
-        );
-        t.disableFormats = true;
-        return t.compile();
-    })(),
-
-    
     destroy : function(){
-        if(!Ext.isEmpty(this.targetCls)){
-            var target = this.container.getLayoutTarget();
-            if(target){
-                target.removeClass(this.targetCls);
-            }
+        if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
+            this.autoHideSlideTask.cancel();
         }
+        Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
     }
-});
-Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
+};
 
-Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
-    
-    monitorResize:true,
 
+Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
+    Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
     
-    onLayout : function(ct, target){
-        Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
-        if(!this.container.collapsed){
-            this.setItemSize(this.activeItem || ct.items.itemAt(0), target.getViewSize(true));
-        }
-    },
+    this.applyLayout = this.applyFns[pos];
+};
 
+Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
     
-    setItemSize : function(item, size){
-        if(item && size.height > 0){ 
-            item.setSize(size);
-        }
-    }
-});
-Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
-Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
     
-    deferredRender : false,
+    splitTip : "Drag to resize.",
     
+    collapsibleSplitTip : "Drag to resize. Double click to hide.",
     
-    layoutOnCardChange : false,
+    useSplitTips : false,
 
     
-    
-    renderHidden : true,
-    
-    constructor: function(config){
-        Ext.layout.CardLayout.superclass.constructor.call(this, config);
-      
+    splitSettings : {
+        north : {
+            orientation: Ext.SplitBar.VERTICAL,
+            placement: Ext.SplitBar.TOP,
+            maxFn : 'getVMaxSize',
+            minProp: 'minHeight',
+            maxProp: 'maxHeight'
+        },
+        south : {
+            orientation: Ext.SplitBar.VERTICAL,
+            placement: Ext.SplitBar.BOTTOM,
+            maxFn : 'getVMaxSize',
+            minProp: 'minHeight',
+            maxProp: 'maxHeight'
+        },
+        east : {
+            orientation: Ext.SplitBar.HORIZONTAL,
+            placement: Ext.SplitBar.RIGHT,
+            maxFn : 'getHMaxSize',
+            minProp: 'minWidth',
+            maxProp: 'maxWidth'
+        },
+        west : {
+            orientation: Ext.SplitBar.HORIZONTAL,
+            placement: Ext.SplitBar.LEFT,
+            maxFn : 'getHMaxSize',
+            minProp: 'minWidth',
+            maxProp: 'maxWidth'
+        }
     },
 
     
-    setActiveItem : function(item){
-        var ai = this.activeItem;
-        item = this.container.getComponent(item);
-        if(ai != item){
-            if(ai){
-                ai.hide();
-                ai.fireEvent('deactivate', ai);
+    applyFns : {
+        west : function(box){
+            if(this.isCollapsed){
+                return this.applyLayoutCollapsed(box);
             }
-            var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
-            this.activeItem = item;
-            if(item){
-                item.show();
+            var sd = this.splitEl.dom, s = sd.style;
+            this.panel.setPosition(box.x, box.y);
+            var sw = sd.offsetWidth;
+            s.left = (box.x+box.width-sw)+'px';
+            s.top = (box.y)+'px';
+            s.height = Math.max(0, box.height)+'px';
+            this.panel.setSize(box.width-sw, box.height);
+        },
+        east : function(box){
+            if(this.isCollapsed){
+                return this.applyLayoutCollapsed(box);
             }
-            this.layout();
-            if(item && layout){
-                item.doLayout();
+            var sd = this.splitEl.dom, s = sd.style;
+            var sw = sd.offsetWidth;
+            this.panel.setPosition(box.x+sw, box.y);
+            s.left = (box.x)+'px';
+            s.top = (box.y)+'px';
+            s.height = Math.max(0, box.height)+'px';
+            this.panel.setSize(box.width-sw, box.height);
+        },
+        north : function(box){
+            if(this.isCollapsed){
+                return this.applyLayoutCollapsed(box);
             }
-            item.fireEvent('activate', item);
+            var sd = this.splitEl.dom, s = sd.style;
+            var sh = sd.offsetHeight;
+            this.panel.setPosition(box.x, box.y);
+            s.left = (box.x)+'px';
+            s.top = (box.y+box.height-sh)+'px';
+            s.width = Math.max(0, box.width)+'px';
+            this.panel.setSize(box.width, box.height-sh);
+        },
+        south : function(box){
+            if(this.isCollapsed){
+                return this.applyLayoutCollapsed(box);
+            }
+            var sd = this.splitEl.dom, s = sd.style;
+            var sh = sd.offsetHeight;
+            this.panel.setPosition(box.x, box.y+sh);
+            s.left = (box.x)+'px';
+            s.top = (box.y)+'px';
+            s.width = Math.max(0, box.width)+'px';
+            this.panel.setSize(box.width, box.height-sh);
         }
     },
 
     
-    renderAll : function(ct, target){
-        if(this.deferredRender){
-            this.renderItem(this.activeItem, undefined, target);
-        }else{
-            Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
-        }
-    }
-});
-Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
-Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
-    
+    render : function(ct, p){
+        Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
 
-    
-    monitorResize:true,
+        var ps = this.position;
 
-    
-    
-    getAnchorViewSize : function(ct, target){
-        return target.dom == document.body ?
-                   target.getViewSize(true) : target.getStyleSize();
-    },
+        this.splitEl = ct.createChild({
+            cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
+            id: this.panel.id + '-xsplit'
+        });
 
-    
-    onLayout : function(ct, target){
-        Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
+        if(this.collapseMode == 'mini'){
+            this.miniSplitEl = this.splitEl.createChild({
+                cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
+            });
+            this.miniSplitEl.addClassOnOver('x-layout-mini-over');
+            this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
+        }
 
-        var size = target.getViewSize(true);
+        var s = this.splitSettings[ps];
 
-        var w = size.width, h = size.height;
+        this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
+        this.split.tickSize = this.tickSize;
+        this.split.placement = s.placement;
+        this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
+        this.split.minSize = this.minSize || this[s.minProp];
+        this.split.on("beforeapply", this.onSplitMove, this);
+        this.split.useShim = this.useShim === true;
+        this.maxSize = this.maxSize || this[s.maxProp];
 
-        if(w < 20 && h < 20){
-            return;
+        if(p.hidden){
+            this.splitEl.hide();
         }
 
-        
-        var aw, ah;
-        if(ct.anchorSize){
-            if(typeof ct.anchorSize == 'number'){
-                aw = ct.anchorSize;
-            }else{
-                aw = ct.anchorSize.width;
-                ah = ct.anchorSize.height;
-            }
+        if(this.useSplitTips){
+            this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
+        }
+        if(this.collapsible){
+            this.splitEl.on("dblclick", this.onCollapseClick,  this);
+        }
+    },
+
+    
+    getSize : function(){
+        if(this.isCollapsed){
+            return this.collapsedEl.getSize();
+        }
+        var s = this.panel.getSize();
+        if(this.position == 'north' || this.position == 'south'){
+            s.height += this.splitEl.dom.offsetHeight;
         }else{
-            aw = ct.initialConfig.width;
-            ah = ct.initialConfig.height;
+            s.width += this.splitEl.dom.offsetWidth;
         }
+        return s;
+    },
 
-        var cs = ct.items.items, len = cs.length, i, c, a, cw, ch, el, vs;
-        for(i = 0; i < len; i++){
-            c = cs[i];
-            el = c.getPositionEl();
-            if(c.anchor){
-                a = c.anchorSpec;
-                if(!a){ 
-                    vs = c.anchor.split(' ');
-                    c.anchorSpec = a = {
-                        right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
-                        bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
-                    };
-                }
-                cw = a.right ? this.adjustWidthAnchor(a.right(w) - el.getMargins('lr'), c) : undefined;
-                ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h) - el.getMargins('tb'), c) : undefined;
+    
+    getHMaxSize : function(){
+         var cmax = this.maxSize || 10000;
+         var center = this.layout.center;
+         return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
+    },
 
-                if(cw || ch){
-                    c.setSize(cw || undefined, ch || undefined);
-                }
-            }
-        }
+    
+    getVMaxSize : function(){
+        var cmax = this.maxSize || 10000;
+        var center = this.layout.center;
+        return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
     },
 
     
-    parseAnchor : function(a, start, cstart){
-        if(a && a != 'none'){
-            var last;
-            if(/^(r|right|b|bottom)$/i.test(a)){   
-                var diff = cstart - start;
-                return function(v){
-                    if(v !== last){
-                        last = v;
-                        return v - diff;
-                    }
-                }
-            }else if(a.indexOf('%') != -1){
-                var ratio = parseFloat(a.replace('%', ''))*.01;   
-                return function(v){
-                    if(v !== last){
-                        last = v;
-                        return Math.floor(v*ratio);
-                    }
-                }
-            }else{
-                a = parseInt(a, 10);
-                if(!isNaN(a)){                            
-                    return function(v){
-                        if(v !== last){
-                            last = v;
-                            return v + a;
-                        }
-                    }
-                }
-            }
+    onSplitMove : function(split, newSize){
+        var s = this.panel.getSize();
+        this.lastSplitSize = newSize;
+        if(this.position == 'north' || this.position == 'south'){
+            this.panel.setSize(s.width, newSize);
+            this.state.height = newSize;
+        }else{
+            this.panel.setSize(newSize, s.height);
+            this.state.width = newSize;
         }
+        this.layout.layout();
+        this.panel.saveState();
         return false;
     },
 
     
-    adjustWidthAnchor : function(value, comp){
-        return value;
+    getSplitBar : function(){
+        return this.split;
     },
 
     
-    adjustHeightAnchor : function(value, comp){
-        return value;
+    destroy : function() {
+        Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
+        Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
     }
-
-    
 });
-Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
 
-Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
-    
-    monitorResize:true,
+Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
 
-    extraCls: 'x-column',
+Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
 
-    scrollOffset : 0,
+    
+    labelSeparator : ':',
 
     
 
-    targetCls: 'x-column-layout-ct',
+    
+    trackLabels: true,
 
-    isValidParent : function(c, target){
-        return c.getPositionEl().dom.parentNode == this.innerCt.dom;
+    type: 'form',
+
+    onRemove: function(c){
+        Ext.layout.FormLayout.superclass.onRemove.call(this, c);
+        if(this.trackLabels){
+            c.un('show', this.onFieldShow, this);
+            c.un('hide', this.onFieldHide, this);
+        }
+        
+        var el = c.getPositionEl(),
+            ct = c.getItemCt && c.getItemCt();
+        if (c.rendered && ct) {
+            if (el && el.dom) {
+                el.insertAfter(ct);
+            }
+            Ext.destroy(ct);
+            Ext.destroyMembers(c, 'label', 'itemCt');
+            if (c.customItemCt) {
+                Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
+            }
+        }
     },
 
     
-    onLayout : function(ct, target){
-        var cs = ct.items.items, len = cs.length, c, i;
-
-        if(!this.innerCt){
-            
-            
-            this.innerCt = target.createChild({cls:'x-column-inner'});
-            this.innerCt.createChild({cls:'x-clear'});
+    setContainer : function(ct){
+        Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
+        if(ct.labelAlign){
+            ct.addClass('x-form-label-'+ct.labelAlign);
         }
-        this.renderAll(ct, this.innerCt);
-
-        var size = target.getViewSize(true);
 
-        if(size.width < 1 && size.height < 1){ 
-            return;
+        if(ct.hideLabels){
+            Ext.apply(this, {
+                labelStyle: 'display:none',
+                elementStyle: 'padding-left:0;',
+                labelAdjust: 0
+            });
+        }else{
+            this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
+            ct.labelWidth = ct.labelWidth || 100;
+            if(Ext.isNumber(ct.labelWidth)){
+                var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
+                Ext.apply(this, {
+                    labelAdjust: ct.labelWidth + pad,
+                    labelStyle: 'width:' + ct.labelWidth + 'px;',
+                    elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
+                });
+            }
+            if(ct.labelAlign == 'top'){
+                Ext.apply(this, {
+                    labelStyle: 'width:auto;',
+                    labelAdjust: 0,
+                    elementStyle: 'padding-left:0;'
+                });
+            }
         }
+    },
 
-        var w = size.width - this.scrollOffset,
-            h = size.height,
-            pw = w;
+    
+    isHide: function(c){
+        return c.hideLabel || this.container.hideLabels;
+    },
 
-        this.innerCt.setWidth(w);
+    onFieldShow: function(c){
+        c.getItemCt().removeClass('x-hide-' + c.hideMode);
 
         
-        
-
-        for(i = 0; i < len; i++){
-            c = cs[i];
-            if(!c.columnWidth){
-                pw -= (c.getSize().width + c.getPositionEl().getMargins('lr'));
-            }
+        if (c.isComposite) {
+            c.doLayout();
         }
+    },
 
-        pw = pw < 0 ? 0 : pw;
+    onFieldHide: function(c){
+        c.getItemCt().addClass('x-hide-' + c.hideMode);
+    },
 
-        for(i = 0; i < len; i++){
-            c = cs[i];
-            if(c.columnWidth){
-                c.setSize(Math.floor(c.columnWidth * pw) - c.getPositionEl().getMargins('lr'));
+    
+    getLabelStyle: function(s){
+        var ls = '', items = [this.labelStyle, s];
+        for (var i = 0, len = items.length; i < len; ++i){
+            if (items[i]){
+                ls += items[i];
+                if (ls.substr(-1, 1) != ';'){
+                    ls += ';';
+                }
             }
         }
-    }
-
-    
-});
+        return ls;
+    },
 
-Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
-Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
     
-    monitorResize:true,
-    
-    rendered : false,
-
-    targetCls: 'x-border-layout-ct',
 
     
-    onLayout : function(ct, target){
-        var collapsed;
-        if(!this.rendered){
-            var items = ct.items.items;
-            collapsed = [];
-            for(var i = 0, len = items.length; i < len; i++) {
-                var c = items[i];
-                var pos = c.region;
-                if(c.collapsed){
-                    collapsed.push(c);
-                }
-                c.collapsed = false;
-                if(!c.rendered){
-                    c.render(target, i);
-                    c.getPositionEl().addClass('x-border-panel');
+    renderItem : function(c, position, target){
+        if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
+            var args = this.getTemplateArgs(c);
+            if(Ext.isNumber(position)){
+                position = target.dom.childNodes[position] || null;
+            }
+            if(position){
+                c.itemCt = this.fieldTpl.insertBefore(position, args, true);
+            }else{
+                c.itemCt = this.fieldTpl.append(target, args, true);
+            }
+            if(!c.getItemCt){
+                
+                
+                Ext.apply(c, {
+                    getItemCt: function(){
+                        return c.itemCt;
+                    },
+                    customItemCt: true
+                });
+            }
+            c.label = c.getItemCt().child('label.x-form-item-label');
+            if(!c.rendered){
+                c.render('x-form-el-' + c.id);
+            }else if(!this.isValidParent(c, target)){
+                Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
+            }
+            if(this.trackLabels){
+                if(c.hidden){
+                    this.onFieldHide(c);
                 }
-                this[pos] = pos != 'center' && c.split ?
-                    new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
-                    new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
-                this[pos].render(target, c);
+                c.on({
+                    scope: this,
+                    show: this.onFieldShow,
+                    hide: this.onFieldHide
+                });
             }
-            this.rendered = true;
+            this.configureItem(c);
+        }else {
+            Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
         }
+    },
 
-        var size = target.getViewSize(false);
-        if(size.width < 20 || size.height < 20){ 
-            if(collapsed){
-                this.restoreCollapsed = collapsed;
-            }
-            return;
-        }else if(this.restoreCollapsed){
-            collapsed = this.restoreCollapsed;
-            delete this.restoreCollapsed;
-        }
+    
+    getTemplateArgs: function(field) {
+        var noLabelSep = !field.fieldLabel || field.hideLabel;
 
-        var w = size.width, h = size.height;
-        var centerW = w, centerH = h, centerY = 0, centerX = 0;
+        return {
+            id            : field.id,
+            label         : field.fieldLabel,
+            itemCls       : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
+            clearCls      : field.clearCls || 'x-form-clear-left',
+            labelStyle    : this.getLabelStyle(field.labelStyle),
+            elementStyle  : this.elementStyle || '',
+            labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
+        };
+    },
 
-        var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
-        if(!c && Ext.layout.BorderLayout.WARN !== false){
-            throw 'No center region defined in BorderLayout ' + ct.id;
+    
+    adjustWidthAnchor: function(value, c){
+        if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
+            var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
+            return value - this.labelAdjust + (adjust ? -3 : 0);
         }
+        return value;
+    },
 
-        if(n && n.isVisible()){
-            var b = n.getSize();
-            var m = n.getMargins();
-            b.width = w - (m.left+m.right);
-            b.x = m.left;
-            b.y = m.top;
-            centerY = b.height + b.y + m.bottom;
-            centerH -= centerY;
-            n.applyLayout(b);
-        }
-        if(s && s.isVisible()){
-            var b = s.getSize();
-            var m = s.getMargins();
-            b.width = w - (m.left+m.right);
-            b.x = m.left;
-            var totalHeight = (b.height + m.top + m.bottom);
-            b.y = h - totalHeight + m.top;
-            centerH -= totalHeight;
-            s.applyLayout(b);
-        }
-        if(west && west.isVisible()){
-            var b = west.getSize();
-            var m = west.getMargins();
-            b.height = centerH - (m.top+m.bottom);
-            b.x = m.left;
-            b.y = centerY + m.top;
-            var totalWidth = (b.width + m.left + m.right);
-            centerX += totalWidth;
-            centerW -= totalWidth;
-            west.applyLayout(b);
-        }
-        if(e && e.isVisible()){
-            var b = e.getSize();
-            var m = e.getMargins();
-            b.height = centerH - (m.top+m.bottom);
-            var totalWidth = (b.width + m.left + m.right);
-            b.x = w - totalWidth + m.left;
-            b.y = centerY + m.top;
-            centerW -= totalWidth;
-            e.applyLayout(b);
-        }
-        if(c){
-            var m = c.getMargins();
-            var centerBox = {
-                x: centerX + m.left,
-                y: centerY + m.top,
-                width: centerW - (m.left+m.right),
-                height: centerH - (m.top+m.bottom)
-            };
-            c.applyLayout(centerBox);
-        }
-        if(collapsed){
-            for(var i = 0, len = collapsed.length; i < len; i++){
-                collapsed[i].collapse(false);
-            }
-        }
-        if(Ext.isIE && Ext.isStrict){ 
-            target.repaint();
+    adjustHeightAnchor : function(value, c){
+        if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
+            return value - c.label.getHeight();
         }
+        return value;
     },
 
-    destroy: function() {
-        var r = ['north', 'south', 'east', 'west'];
-        for (var i = 0; i < r.length; i++) {
-            var region = this[r[i]];
-            if(region){
-                if(region.destroy){
-                    region.destroy();
-                }else if (region.split){
-                    region.split.destroy(true);
-                }
-            }
-        }
-        Ext.layout.BorderLayout.superclass.destroy.call(this);
+    
+    isValidParent : function(c, target){
+        return target && this.container.getEl().contains(c.getPositionEl());
     }
 
     
 });
 
+Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
 
-Ext.layout.BorderLayout.Region = function(layout, config, pos){
-    Ext.apply(this, config);
-    this.layout = layout;
-    this.position = pos;
-    this.state = {};
-    if(typeof this.margins == 'string'){
-        this.margins = this.layout.parseMargins(this.margins);
-    }
-    this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
-    if(this.collapsible){
-        if(typeof this.cmargins == 'string'){
-            this.cmargins = this.layout.parseMargins(this.cmargins);
-        }
-        if(this.collapseMode == 'mini' && !this.cmargins){
-            this.cmargins = {left:0,top:0,right:0,bottom:0};
-        }else{
-            this.cmargins = Ext.applyIf(this.cmargins || {},
-                pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
-        }
-    }
-};
-
-Ext.layout.BorderLayout.Region.prototype = {
-    
-    
-    
-    
-    
-    
-    collapsible : false,
-    
-    split:false,
-    
-    floatable: true,
-    
-    minWidth:50,
+Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
     
-    minHeight:50,
-
+    fill : true,
     
-    defaultMargins : {left:0,top:0,right:0,bottom:0},
+    autoWidth : true,
     
-    defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
+    titleCollapse : true,
     
-    defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
-    floatingZIndex: 100,
-
+    hideCollapseTool : false,
     
-    isCollapsed : false,
-
+    collapseFirst : false,
     
+    animate : false,
     
+    sequence : false,
     
+    activeOnTop : false,
 
-    
-    render : function(ct, p){
-        this.panel = p;
-        p.el.enableDisplayMode();
-        this.targetEl = ct;
-        this.el = p.el;
+    type: 'accordion',
 
-        var gs = p.getState, ps = this.position;
-        p.getState = function(){
-            return Ext.apply(gs.call(p) || {}, this.state);
-        }.createDelegate(this);
+    renderItem : function(c){
+        if(this.animate === false){
+            c.animCollapse = false;
+        }
+        c.collapsible = true;
+        if(this.autoWidth){
+            c.autoWidth = true;
+        }
+        if(this.titleCollapse){
+            c.titleCollapse = true;
+        }
+        if(this.hideCollapseTool){
+            c.hideCollapseTool = true;
+        }
+        if(this.collapseFirst !== undefined){
+            c.collapseFirst = this.collapseFirst;
+        }
+        if(!this.activeItem && !c.collapsed){
+            this.setActiveItem(c, true);
+        }else if(this.activeItem && this.activeItem != c){
+            c.collapsed = true;
+        }
+        Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
+        c.header.addClass('x-accordion-hd');
+        c.on('beforeexpand', this.beforeExpand, this);
+    },
 
-        if(ps != 'center'){
-            p.allowQueuedExpand = false;
-            p.on({
-                beforecollapse: this.beforeCollapse,
-                collapse: this.onCollapse,
-                beforeexpand: this.beforeExpand,
-                expand: this.onExpand,
-                hide: this.onHide,
-                show: this.onShow,
-                scope: this
-            });
-            if(this.collapsible || this.floatable){
-                p.collapseEl = 'el';
-                p.slideAnchor = this.getSlideAnchor();
-            }
-            if(p.tools && p.tools.toggle){
-                p.tools.toggle.addClass('x-tool-collapse-'+ps);
-                p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
-            }
+    onRemove: function(c){
+        Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
+        if(c.rendered){
+            c.header.removeClass('x-accordion-hd');
         }
+        c.un('beforeexpand', this.beforeExpand, this);
     },
 
     
-    getCollapsedEl : function(){
-        if(!this.collapsedEl){
-            if(!this.toolTemplate){
-                var tt = new Ext.Template(
-                     '<div class="x-tool x-tool-{id}">&#160;</div>'
-                );
-                tt.disableFormats = true;
-                tt.compile();
-                Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
-            }
-            this.collapsedEl = this.targetEl.createChild({
-                cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
-                id: this.panel.id + '-xcollapsed'
-            });
-            this.collapsedEl.enableDisplayMode('block');
-
-            if(this.collapseMode == 'mini'){
-                this.collapsedEl.addClass('x-layout-cmini-'+this.position);
-                this.miniCollapsedEl = this.collapsedEl.createChild({
-                    cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
-                });
-                this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
-                this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
-                this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
-            }else {
-                if(this.collapsible !== false && !this.hideCollapseTool) {
-                    var t = this.toolTemplate.append(
-                            this.collapsedEl.dom,
-                            {id:'expand-'+this.position}, true);
-                    t.addClassOnOver('x-tool-expand-'+this.position+'-over');
-                    t.on('click', this.onExpandClick, this, {stopEvent:true});
-                }
-                if(this.floatable !== false || this.titleCollapse){
-                   this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
-                   this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
+    beforeExpand : function(p, anim){
+        var ai = this.activeItem;
+        if(ai){
+            if(this.sequence){
+                delete this.activeItem;
+                if (!ai.collapsed){
+                    ai.collapse({callback:function(){
+                        p.expand(anim || true);
+                    }, scope: this});
+                    return false;
                 }
+            }else{
+                ai.collapse(this.animate);
             }
         }
-        return this.collapsedEl;
+        this.setActive(p);
+        if(this.activeOnTop){
+            p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
+        }
+        
+        this.layout();
     },
 
     
-    onExpandClick : function(e){
-        if(this.isSlid){
-            this.panel.expand(false);
-        }else{
-            this.panel.expand();
+    setItemSize : function(item, size){
+        if(this.fill && item){
+            var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
+            
+            for (i = 0; i < len; i++) {
+                if((p = ct[i]) != item && !p.hidden){
+                    hh += p.header.getHeight();
+                }
+            };
+            
+            size.height -= hh;
+            
+            
+            item.setSize(size);
         }
     },
 
     
-    onCollapseClick : function(e){
-        this.panel.collapse();
+    setActiveItem : function(item){
+        this.setActive(item, true);
     },
 
     
-    beforeCollapse : function(p, animate){
-        this.lastAnim = animate;
-        if(this.splitEl){
-            this.splitEl.hide();
+    setActive : function(item, expand){
+        var ai = this.activeItem;
+        item = this.container.getComponent(item);
+        if(ai != item){
+            if(item.rendered && item.collapsed && expand){
+                item.expand();
+            }else{
+                if(ai){
+                   ai.fireEvent('deactivate', ai);
+                }
+                this.activeItem = item;
+                item.fireEvent('activate', item);
+            }
         }
-        this.getCollapsedEl().show();
-        var el = this.panel.getEl();
-        this.originalZIndex = el.getStyle('z-index');
-        el.setStyle('z-index', 100);
-        this.isCollapsed = true;
-        this.layout.layout();
-    },
+    }
+});
+Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
+
 
+Ext.layout.Accordion = Ext.layout.AccordionLayout;
+Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
     
-    onCollapse : function(animate){
-        this.panel.el.setStyle('z-index', 1);
-        if(this.lastAnim === false || this.panel.animCollapse === false){
-            this.getCollapsedEl().dom.style.visibility = 'visible';
-        }else{
-            this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
-        }
-        this.state.collapsed = true;
-        this.panel.saveState();
-    },
 
     
-    beforeExpand : function(animate){
-        if(this.isSlid){
-            this.afterSlideIn();
-        }
-        var c = this.getCollapsedEl();
-        this.el.show();
-        if(this.position == 'east' || this.position == 'west'){
-            this.panel.setSize(undefined, c.getHeight());
-        }else{
-            this.panel.setSize(c.getWidth(), undefined);
-        }
-        c.hide();
-        c.dom.style.visibility = 'hidden';
-        this.panel.el.setStyle('z-index', this.floatingZIndex);
-    },
+    monitorResize:false,
+
+    type: 'table',
+
+    targetCls: 'x-table-layout-ct',
 
     
-    onExpand : function(){
-        this.isCollapsed = false;
-        if(this.splitEl){
-            this.splitEl.show();
-        }
-        this.layout.layout();
-        this.panel.el.setStyle('z-index', this.originalZIndex);
-        this.state.collapsed = false;
-        this.panel.saveState();
-    },
+    tableAttrs:null,
 
     
-    collapseClick : function(e){
-        if(this.isSlid){
-           e.stopPropagation();
-           this.slideIn();
-        }else{
-           e.stopPropagation();
-           this.slideOut();
-        }
-    },
+    setContainer : function(ct){
+        Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
 
+        this.currentRow = 0;
+        this.currentColumn = 0;
+        this.cells = [];
+    },
     
-    onHide : function(){
-        if(this.isCollapsed){
-            this.getCollapsedEl().hide();
-        }else if(this.splitEl){
-            this.splitEl.hide();
+    
+    onLayout : function(ct, target){
+        var cs = ct.items.items, len = cs.length, c, i;
+
+        if(!this.table){
+            target.addClass('x-table-layout-ct');
+
+            this.table = target.createChild(
+                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
         }
+        this.renderAll(ct, target);
     },
 
     
-    onShow : function(){
-        if(this.isCollapsed){
-            this.getCollapsedEl().show();
-        }else if(this.splitEl){
-            this.splitEl.show();
+    getRow : function(index){
+        var row = this.table.tBodies[0].childNodes[index];
+        if(!row){
+            row = document.createElement('tr');
+            this.table.tBodies[0].appendChild(row);
         }
+        return row;
     },
 
     
-    isVisible : function(){
-        return !this.panel.hidden;
+    getNextCell : function(c){
+        var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
+        var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
+        for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
+            if(!this.cells[rowIndex]){
+                this.cells[rowIndex] = [];
+            }
+            for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
+                this.cells[rowIndex][colIndex] = true;
+            }
+        }
+        var td = document.createElement('td');
+        if(c.cellId){
+            td.id = c.cellId;
+        }
+        var cls = 'x-table-layout-cell';
+        if(c.cellCls){
+            cls += ' ' + c.cellCls;
+        }
+        td.className = cls;
+        if(c.colspan){
+            td.colSpan = c.colspan;
+        }
+        if(c.rowspan){
+            td.rowSpan = c.rowspan;
+        }
+        this.getRow(curRow).appendChild(td);
+        return td;
     },
 
     
-    getMargins : function(){
-        return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
+    getNextNonSpan: function(colIndex, rowIndex){
+        var cols = this.columns;
+        while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
+            if(cols && colIndex >= cols){
+                rowIndex++;
+                colIndex = 0;
+            }else{
+                colIndex++;
+            }
+        }
+        return [colIndex, rowIndex];
     },
 
     
-    getSize : function(){
-        return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
+    renderItem : function(c, position, target){
+        
+        if(!this.table){
+            this.table = target.createChild(
+                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
+        }
+        if(c && !c.rendered){
+            c.render(this.getNextCell(c));
+            this.configureItem(c);
+        }else if(c && !this.isValidParent(c, target)){
+            var container = this.getNextCell(c);
+            container.insertBefore(c.getPositionEl().dom, null);
+            c.container = Ext.get(container);
+            this.configureItem(c);
+        }
     },
 
     
-    setPanel : function(panel){
-        this.panel = panel;
+    isValidParent : function(c, target){
+        return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
     },
-
     
-    getMinWidth: function(){
-        return this.minWidth;
-    },
+    destroy: function(){
+        delete this.table;
+        Ext.layout.TableLayout.superclass.destroy.call(this);
+    }
 
     
-    getMinHeight: function(){
-        return this.minHeight;
-    },
+});
 
-    
-    applyLayoutCollapsed : function(box){
-        var ce = this.getCollapsedEl();
-        ce.setLeftTop(box.x, box.y);
-        ce.setSize(box.width, box.height);
-    },
+Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
+Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
 
-    
-    applyLayout : function(box){
-        if(this.isCollapsed){
-            this.applyLayoutCollapsed(box);
-        }else{
-            this.panel.setPosition(box.x, box.y);
-            this.panel.setSize(box.width, box.height);
-        }
-    },
+    extraCls: 'x-abs-layout-item',
 
-    
-    beforeSlide: function(){
-        this.panel.beforeEffect();
-    },
+    type: 'absolute',
 
-    
-    afterSlide : function(){
-        this.panel.afterEffect();
+    onLayout : function(ct, target){
+        target.position();
+        this.paddingLeft = target.getPadding('l');
+        this.paddingTop = target.getPadding('t');
+        Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
     },
 
     
-    initAutoHide : function(){
-        if(this.autoHide !== false){
-            if(!this.autoHideHd){
-                var st = new Ext.util.DelayedTask(this.slideIn, this);
-                this.autoHideHd = {
-                    "mouseout": function(e){
-                        if(!e.within(this.el, true)){
-                            st.delay(500);
-                        }
-                    },
-                    "mouseover" : function(e){
-                        st.cancel();
-                    },
-                    scope : this
-                };
-            }
-            this.el.on(this.autoHideHd);
-            this.collapsedEl.on(this.autoHideHd);
-        }
+    adjustWidthAnchor : function(value, comp){
+        return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
     },
 
     
-    clearAutoHide : function(){
-        if(this.autoHide !== false){
-            this.el.un("mouseout", this.autoHideHd.mouseout);
-            this.el.un("mouseover", this.autoHideHd.mouseover);
-            this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
-            this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
-        }
-    },
-
+    adjustHeightAnchor : function(value, comp){
+        return  value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
+    }
     
-    clearMonitor : function(){
-        Ext.getDoc().un("click", this.slideInIf, this);
-    },
+});
+Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
 
+Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
     
-    slideOut : function(){
-        if(this.isSlid || this.el.hasActiveFx()){
-            return;
-        }
-        this.isSlid = true;
-        var ts = this.panel.tools;
-        if(ts && ts.toggle){
-            ts.toggle.hide();
-        }
-        this.el.show();
-        if(this.position == 'east' || this.position == 'west'){
-            this.panel.setSize(undefined, this.collapsedEl.getHeight());
-        }else{
-            this.panel.setSize(this.collapsedEl.getWidth(), undefined);
-        }
-        this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
-        this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
-        this.el.setStyle("z-index", this.floatingZIndex+2);
-        this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
-        if(this.animFloat !== false){
-            this.beforeSlide();
-            this.el.slideIn(this.getSlideAnchor(), {
-                callback: function(){
-                    this.afterSlide();
-                    this.initAutoHide();
-                    Ext.getDoc().on("click", this.slideInIf, this);
-                },
-                scope: this,
-                block: true
-            });
-        }else{
-            this.initAutoHide();
-             Ext.getDoc().on("click", this.slideInIf, this);
-        }
-    },
+    defaultMargins : {left:0,top:0,right:0,bottom:0},
+    
+    padding : '0',
+    
+    pack : 'start',
 
     
-    afterSlideIn : function(){
-        this.clearAutoHide();
-        this.isSlid = false;
-        this.clearMonitor();
-        this.el.setStyle("z-index", "");
-        this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
-        this.el.dom.style.left = this.restoreLT[0];
-        this.el.dom.style.top = this.restoreLT[1];
+    monitorResize : true,
+    type: 'box',
+    scrollOffset : 0,
+    extraCls : 'x-box-item',
+    targetCls : 'x-box-layout-ct',
+    innerCls : 'x-box-inner',
 
-        var ts = this.panel.tools;
-        if(ts && ts.toggle){
-            ts.toggle.show();
-        }
-    },
+    constructor : function(config){
+        Ext.layout.BoxLayout.superclass.constructor.call(this, config);
 
-    
-    slideIn : function(cb){
-        if(!this.isSlid || this.el.hasActiveFx()){
-            Ext.callback(cb);
-            return;
+        if (Ext.isString(this.defaultMargins)) {
+            this.defaultMargins = this.parseMargins(this.defaultMargins);
         }
-        this.isSlid = false;
-        if(this.animFloat !== false){
-            this.beforeSlide();
-            this.el.slideOut(this.getSlideAnchor(), {
-                callback: function(){
-                    this.el.hide();
-                    this.afterSlide();
-                    this.afterSlideIn();
-                    Ext.callback(cb);
-                },
-                scope: this,
-                block: true
-            });
-        }else{
-            this.el.hide();
-            this.afterSlideIn();
+        
+        var handler = this.overflowHandler;
+        
+        if (typeof handler == 'string') {
+            handler = {
+                type: handler
+            };
+        }
+        
+        var handlerType = 'none';
+        if (handler && handler.type != undefined) {
+            handlerType = handler.type;
+        }
+        
+        var constructor = Ext.layout.boxOverflow[handlerType];
+        if (constructor[this.type]) {
+            constructor = constructor[this.type];
         }
+        
+        this.overflowHandler = new constructor(this, handler);
     },
 
     
-    slideInIf : function(e){
-        if(!e.within(this.el)){
-            this.slideIn();
+    onLayout: function(container, target) {
+        Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
+
+        var tSize = this.getLayoutTargetSize(),
+            items = this.getVisibleItems(container),
+            calcs = this.calculateChildBoxes(items, tSize),
+            boxes = calcs.boxes,
+            meta  = calcs.meta;
+        
+        
+        if (tSize.width > 0) {
+            var handler = this.overflowHandler,
+                method  = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow';
+            
+            var results = handler[method](calcs, tSize);
+            
+            if (results) {
+                if (results.targetSize) {
+                    tSize = results.targetSize;
+                }
+                
+                if (results.recalculate) {
+                    items = this.getVisibleItems(container);
+                    calcs = this.calculateChildBoxes(items, tSize);
+                    boxes = calcs.boxes;
+                }
+            }
         }
+        
+        
+        this.layoutTargetLastSize = tSize;
+        
+        
+        this.childBoxCache = calcs;
+        
+        this.updateInnerCtSize(tSize, calcs);
+        this.updateChildBoxes(boxes);
+
+        
+        this.handleTargetOverflow(tSize, container, target);
     },
 
     
-    anchors : {
-        "west" : "left",
-        "east" : "right",
-        "north" : "top",
-        "south" : "bottom"
+    updateChildBoxes: function(boxes) {
+        for (var i = 0, length = boxes.length; i < length; i++) {
+            var box  = boxes[i],
+                comp = box.component;
+            
+            if (box.dirtySize) {
+                comp.setSize(box.width, box.height);
+            }
+            
+            if (isNaN(box.left) || isNaN(box.top)) {
+                continue;
+            }
+            
+            comp.setPosition(box.left, box.top);
+        }
     },
 
     
-    sanchors : {
-        "west" : "l",
-        "east" : "r",
-        "north" : "t",
-        "south" : "b"
+    updateInnerCtSize: function(tSize, calcs) {
+        var align   = this.align,
+            padding = this.padding,
+            width   = tSize.width,
+            height  = tSize.height;
+        
+        if (this.type == 'hbox') {
+            var innerCtWidth  = width,
+                innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom;
+
+            if (align == 'stretch') {
+                innerCtHeight = height;
+            } else if (align == 'middle') {
+                innerCtHeight = Math.max(height, innerCtHeight);
+            }
+        } else {
+            var innerCtHeight = height,
+                innerCtWidth  = calcs.meta.maxWidth + padding.left + padding.right;
+
+            if (align == 'stretch') {
+                innerCtWidth = width;
+            } else if (align == 'center') {
+                innerCtWidth = Math.max(width, innerCtWidth);
+            }
+        }
+
+        this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
     },
 
     
-    canchors : {
-        "west" : "tl-tr",
-        "east" : "tr-tl",
-        "north" : "tl-bl",
-        "south" : "bl-tl"
+    handleTargetOverflow: function(previousTargetSize, container, target) {
+        var overflow = target.getStyle('overflow');
+
+        if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
+            var newTargetSize = this.getLayoutTargetSize();
+            if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
+                this.adjustmentPass = true;
+                this.onLayout(container, target);
+            }
+        }
+
+        delete this.adjustmentPass;
     },
 
     
-    getAnchor : function(){
-        return this.anchors[this.position];
+    isValidParent : function(c, target) {
+        return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
     },
 
     
-    getCollapseAnchor : function(){
-        return this.canchors[this.position];
+    getVisibleItems: function(ct) {
+        var ct  = ct || this.container,
+            t   = ct.getLayoutTarget(),
+            cti = ct.items.items,
+            len = cti.length,
+
+            i, c, items = [];
+
+        for (i = 0; i < len; i++) {
+            if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true  && c.collapsed !== true && c.shouldLayout !== false){
+                items.push(c);
+            }
+        }
+
+        return items;
     },
 
     
-    getSlideAnchor : function(){
-        return this.sanchors[this.position];
+    renderAll : function(ct, target) {
+        if (!this.innerCt) {
+            
+            this.innerCt = target.createChild({cls:this.innerCls});
+            this.padding = this.parseMargins(this.padding);
+        }
+        Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
     },
 
-    
-    getAlignAdj : function(){
-        var cm = this.cmargins;
-        switch(this.position){
-            case "west":
-                return [0, 0];
-            break;
-            case "east":
-                return [0, 0];
-            break;
-            case "north":
-                return [0, 0];
-            break;
-            case "south":
-                return [0, 0];
-            break;
+    getLayoutTargetSize : function() {
+        var target = this.container.getLayoutTarget(), ret;
+        
+        if (target) {
+            ret = target.getViewSize();
+
+            
+            
+            
+            if (Ext.isIE && Ext.isStrict && ret.width == 0){
+                ret =  target.getStyleSize();
+            }
+
+            ret.width  -= target.getPadding('lr');
+            ret.height -= target.getPadding('tb');
         }
+        
+        return ret;
     },
 
     
-    getExpandAdj : function(){
-        var c = this.collapsedEl, cm = this.cmargins;
-        switch(this.position){
-            case "west":
-                return [-(cm.right+c.getWidth()+cm.left), 0];
-            break;
-            case "east":
-                return [cm.right+c.getWidth()+cm.left, 0];
-            break;
-            case "north":
-                return [0, -(cm.top+cm.bottom+c.getHeight())];
-            break;
-            case "south":
-                return [0, cm.top+cm.bottom+c.getHeight()];
-            break;
+    renderItem : function(c) {
+        if(Ext.isString(c.margins)){
+            c.margins = this.parseMargins(c.margins);
+        }else if(!c.margins){
+            c.margins = this.defaultMargins;
         }
+        Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
     },
-
-    destroy : function(){
-        Ext.destroy(this.miniCollapsedEl, this.collapsedEl);
+    
+    
+    destroy: function() {
+        Ext.destroy(this.overflowHandler);
+        
+        Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments);
     }
-};
+});
 
 
-Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
-    Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
+
+Ext.ns('Ext.layout.boxOverflow');
+
+
+
+Ext.layout.boxOverflow.None = Ext.extend(Object, {
+    constructor: function(layout, config) {
+        this.layout = layout;
+        
+        Ext.apply(this, config || {});
+    },
     
-    this.applyLayout = this.applyFns[pos];
-};
+    handleOverflow: Ext.emptyFn,
+    
+    clearOverflow: Ext.emptyFn
+});
 
-Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
+
+Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None;
+
+Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, {
     
+    afterCls: 'x-strip-right',
     
-    splitTip : "Drag to resize.",
     
-    collapsibleSplitTip : "Drag to resize. Double click to hide.",
+    noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
     
-    useSplitTips : false,
-
+    constructor: function(layout) {
+        Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments);
+        
+        
+        this.menuItems = [];
+    },
     
-    splitSettings : {
-        north : {
-            orientation: Ext.SplitBar.VERTICAL,
-            placement: Ext.SplitBar.TOP,
-            maxFn : 'getVMaxSize',
-            minProp: 'minHeight',
-            maxProp: 'maxHeight'
-        },
-        south : {
-            orientation: Ext.SplitBar.VERTICAL,
-            placement: Ext.SplitBar.BOTTOM,
-            maxFn : 'getVMaxSize',
-            minProp: 'minHeight',
-            maxProp: 'maxHeight'
-        },
-        east : {
-            orientation: Ext.SplitBar.HORIZONTAL,
-            placement: Ext.SplitBar.RIGHT,
-            maxFn : 'getHMaxSize',
-            minProp: 'minWidth',
-            maxProp: 'maxWidth'
-        },
-        west : {
-            orientation: Ext.SplitBar.HORIZONTAL,
-            placement: Ext.SplitBar.LEFT,
-            maxFn : 'getHMaxSize',
-            minProp: 'minWidth',
-            maxProp: 'maxWidth'
+    
+    createInnerElements: function() {
+        if (!this.afterCt) {
+            this.afterCt  = this.layout.innerCt.insertSibling({cls: this.afterCls},  'before');
         }
     },
-
     
-    applyFns : {
-        west : function(box){
-            if(this.isCollapsed){
-                return this.applyLayoutCollapsed(box);
-            }
-            var sd = this.splitEl.dom, s = sd.style;
-            this.panel.setPosition(box.x, box.y);
-            var sw = sd.offsetWidth;
-            s.left = (box.x+box.width-sw)+'px';
-            s.top = (box.y)+'px';
-            s.height = Math.max(0, box.height)+'px';
-            this.panel.setSize(box.width-sw, box.height);
-        },
-        east : function(box){
-            if(this.isCollapsed){
-                return this.applyLayoutCollapsed(box);
-            }
-            var sd = this.splitEl.dom, s = sd.style;
-            var sw = sd.offsetWidth;
-            this.panel.setPosition(box.x+sw, box.y);
-            s.left = (box.x)+'px';
-            s.top = (box.y)+'px';
-            s.height = Math.max(0, box.height)+'px';
-            this.panel.setSize(box.width-sw, box.height);
-        },
-        north : function(box){
-            if(this.isCollapsed){
-                return this.applyLayoutCollapsed(box);
-            }
-            var sd = this.splitEl.dom, s = sd.style;
-            var sh = sd.offsetHeight;
-            this.panel.setPosition(box.x, box.y);
-            s.left = (box.x)+'px';
-            s.top = (box.y+box.height-sh)+'px';
-            s.width = Math.max(0, box.width)+'px';
-            this.panel.setSize(box.width, box.height-sh);
-        },
-        south : function(box){
-            if(this.isCollapsed){
-                return this.applyLayoutCollapsed(box);
+    
+    clearOverflow: function(calculations, targetSize) {
+        var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0),
+            items    = this.menuItems;
+        
+        this.hideTrigger();
+        
+        for (var index = 0, length = items.length; index < length; index++) {
+            items.pop().component.show();
+        }
+        
+        return {
+            targetSize: {
+                height: targetSize.height,
+                width : newWidth
             }
-            var sd = this.splitEl.dom, s = sd.style;
-            var sh = sd.offsetHeight;
-            this.panel.setPosition(box.x, box.y+sh);
-            s.left = (box.x)+'px';
-            s.top = (box.y)+'px';
-            s.width = Math.max(0, box.width)+'px';
-            this.panel.setSize(box.width, box.height-sh);
+        };
+    },
+    
+    
+    showTrigger: function() {
+        this.createMenu();
+        this.menuTrigger.show();
+    },
+    
+    
+    hideTrigger: function() {
+        if (this.menuTrigger != undefined) {
+            this.menuTrigger.hide();
         }
     },
+    
+    
+    beforeMenuShow: function(menu) {
+        var items = this.menuItems,
+            len   = items.length,
+            item,
+            prev;
+
+        var needsSep = function(group, item){
+            return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
+        };
+        
+        this.clearMenu();
+        menu.removeAll();
+        
+        for (var i = 0; i < len; i++) {
+            item = items[i].component;
+            
+            if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
+                menu.add('-');
+            }
+            
+            this.addComponentToMenu(menu, item);
+            prev = item;
+        }
 
+        
+        if (menu.items.length < 1) {
+            menu.add(this.noItemsMenuText);
+        }
+    },
     
-    render : function(ct, p){
-        Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
+    
+    createMenuConfig : function(component, hideOnClick){
+        var config = Ext.apply({}, component.initialConfig),
+            group  = component.toggleGroup;
 
-        var ps = this.position;
+        Ext.copyTo(config, component, [
+            'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
+        ]);
 
-        this.splitEl = ct.createChild({
-            cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
-            id: this.panel.id + '-xsplit'
+        Ext.apply(config, {
+            text       : component.overflowText || component.text,
+            hideOnClick: hideOnClick
         });
 
-        if(this.collapseMode == 'mini'){
-            this.miniSplitEl = this.splitEl.createChild({
-                cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
+        if (group || component.enableToggle) {
+            Ext.apply(config, {
+                group  : group,
+                checked: component.pressed,
+                listeners: {
+                    checkchange: function(item, checked){
+                        component.toggle(checked);
+                    }
+                }
             });
-            this.miniSplitEl.addClassOnOver('x-layout-mini-over');
-            this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
         }
 
-        var s = this.splitSettings[ps];
+        delete config.ownerCt;
+        delete config.xtype;
+        delete config.id;
 
-        this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
-        this.split.tickSize = this.tickSize;
-        this.split.placement = s.placement;
-        this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
-        this.split.minSize = this.minSize || this[s.minProp];
-        this.split.on("beforeapply", this.onSplitMove, this);
-        this.split.useShim = this.useShim === true;
-        this.maxSize = this.maxSize || this[s.maxProp];
+        return config;
+    },
 
-        if(p.hidden){
-            this.splitEl.hide();
-        }
+    
+    addComponentToMenu : function(menu, component) {
+        if (component instanceof Ext.Toolbar.Separator) {
+            menu.add('-');
 
-        if(this.useSplitTips){
-            this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
-        }
-        if(this.collapsible){
-            this.splitEl.on("dblclick", this.onCollapseClick,  this);
+        } else if (Ext.isFunction(component.isXType)) {
+            if (component.isXType('splitbutton')) {
+                menu.add(this.createMenuConfig(component, true));
+
+            } else if (component.isXType('button')) {
+                menu.add(this.createMenuConfig(component, !component.menu));
+
+            } else if (component.isXType('buttongroup')) {
+                component.items.each(function(item){
+                     this.addComponentToMenu(menu, item);
+                }, this);
+            }
         }
     },
-
     
-    getSize : function(){
-        if(this.isCollapsed){
-            return this.collapsedEl.getSize();
+    
+    clearMenu : function(){
+        var menu = this.moreMenu;
+        if (menu && menu.items) {
+            menu.items.each(function(item){
+                delete item.menu;
+            });
         }
-        var s = this.panel.getSize();
-        if(this.position == 'north' || this.position == 'south'){
-            s.height += this.splitEl.dom.offsetHeight;
-        }else{
-            s.width += this.splitEl.dom.offsetWidth;
+    },
+    
+    
+    createMenu: function() {
+        if (!this.menuTrigger) {
+            this.createInnerElements();
+            
+            
+            this.menu = new Ext.menu.Menu({
+                ownerCt : this.layout.container,
+                listeners: {
+                    scope: this,
+                    beforeshow: this.beforeMenuShow
+                }
+            });
+
+            
+            this.menuTrigger = new Ext.Button({
+                iconCls : 'x-toolbar-more-icon',
+                cls     : 'x-toolbar-more',
+                menu    : this.menu,
+                renderTo: this.afterCt
+            });
         }
-        return s;
     },
+    
+    
+    destroy: function() {
+        Ext.destroy(this.menu, this.menuTrigger);
+    }
+});
+
+Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu;
+
 
+
+Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, {
     
-    getHMaxSize : function(){
-         var cmax = this.maxSize || 10000;
-         var center = this.layout.center;
-         return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
+    constructor: function() {
+        Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments);
+        
+        var me = this,
+            layout = me.layout,
+            origFunction = layout.calculateChildBoxes;
+        
+        layout.calculateChildBoxes = function(visibleItems, targetSize) {
+            var calcs = origFunction.apply(layout, arguments),
+                meta  = calcs.meta,
+                items = me.menuItems;
+            
+            
+            
+            var hiddenWidth = 0;
+            for (var index = 0, length = items.length; index < length; index++) {
+                hiddenWidth += items[index].width;
+            }
+            
+            meta.minimumWidth += hiddenWidth;
+            meta.tooNarrow = meta.minimumWidth > targetSize.width;
+            
+            return calcs;
+        };        
     },
+    
+    handleOverflow: function(calculations, targetSize) {
+        this.showTrigger();
+        
+        var newWidth    = targetSize.width - this.afterCt.getWidth(),
+            boxes       = calculations.boxes,
+            usedWidth   = 0,
+            recalculate = false;
+        
+        
+        for (var index = 0, length = boxes.length; index < length; index++) {
+            usedWidth += boxes[index].width;
+        }
+        
+        var spareWidth = newWidth - usedWidth,
+            showCount  = 0;
+        
+        
+        for (var index = 0, length = this.menuItems.length; index < length; index++) {
+            var hidden = this.menuItems[index],
+                comp   = hidden.component,
+                width  = hidden.width;
+            
+            if (width < spareWidth) {
+                comp.show();
+                
+                spareWidth -= width;
+                showCount ++;
+                recalculate = true;
+            } else {
+                break;
+            }
+        }
+                
+        if (recalculate) {
+            this.menuItems = this.menuItems.slice(showCount);
+        } else {
+            for (var i = boxes.length - 1; i >= 0; i--) {
+                var item  = boxes[i].component,
+                    right = boxes[i].left + boxes[i].width;
+
+                if (right >= newWidth) {
+                    this.menuItems.unshift({
+                        component: item,
+                        width    : boxes[i].width
+                    });
+
+                    item.hide();
+                } else {
+                    break;
+                }
+            }
+        }
+        
+        if (this.menuItems.length == 0) {
+            this.hideTrigger();
+        }
+        
+        return {
+            targetSize: {
+                height: targetSize.height,
+                width : newWidth
+            },
+            recalculate: recalculate
+        };
+    }
+});
 
+Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;
+Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {
     
-    getVMaxSize : function(){
-        var cmax = this.maxSize || 10000;
-        var center = this.layout.center;
-        return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
-    },
+    animateScroll: true,
+    
+    
+    scrollIncrement: 100,
+    
+    
+    wheelIncrement: 3,
+    
+    
+    scrollRepeatInterval: 400,
+    
+    
+    scrollDuration: 0.4,
+    
+    
+    beforeCls: 'x-strip-left',
+    
+    
+    afterCls: 'x-strip-right',
+    
+    
+    scrollerCls: 'x-strip-scroller',
+    
+    
+    beforeScrollerCls: 'x-strip-scroller-left',
+    
+    
+    afterScrollerCls: 'x-strip-scroller-right',
+    
+    
+    createWheelListener: function() {
+        this.layout.innerCt.on({
+            scope     : this,
+            mousewheel: function(e) {
+                e.stopEvent();
 
+                this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
+            }
+        });
+    },
     
-    onSplitMove : function(split, newSize){
-        var s = this.panel.getSize();
-        this.lastSplitSize = newSize;
-        if(this.position == 'north' || this.position == 'south'){
-            this.panel.setSize(s.width, newSize);
-            this.state.height = newSize;
-        }else{
-            this.panel.setSize(newSize, s.height);
-            this.state.width = newSize;
+    
+    handleOverflow: function(calculations, targetSize) {
+        this.createInnerElements();
+        this.showScrollers();
+    },
+    
+    
+    clearOverflow: function() {
+        this.hideScrollers();
+    },
+    
+    
+    showScrollers: function() {
+        this.createScrollers();
+        
+        this.beforeScroller.show();
+        this.afterScroller.show();
+        
+        this.updateScrollButtons();
+    },
+    
+    
+    hideScrollers: function() {
+        if (this.beforeScroller != undefined) {
+            this.beforeScroller.hide();
+            this.afterScroller.hide();          
+        }
+    },
+    
+    
+    createScrollers: function() {
+        if (!this.beforeScroller && !this.afterScroller) {
+            var before = this.beforeCt.createChild({
+                cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
+            });
+            
+            var after = this.afterCt.createChild({
+                cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
+            });
+            
+            before.addClassOnOver(this.beforeScrollerCls + '-hover');
+            after.addClassOnOver(this.afterScrollerCls + '-hover');
+            
+            before.setVisibilityMode(Ext.Element.DISPLAY);
+            after.setVisibilityMode(Ext.Element.DISPLAY);
+            
+            this.beforeRepeater = new Ext.util.ClickRepeater(before, {
+                interval: this.scrollRepeatInterval,
+                handler : this.scrollLeft,
+                scope   : this
+            });
+            
+            this.afterRepeater = new Ext.util.ClickRepeater(after, {
+                interval: this.scrollRepeatInterval,
+                handler : this.scrollRight,
+                scope   : this
+            });
+            
+            
+            this.beforeScroller = before;
+            
+            
+            this.afterScroller = after;
+        }
+    },
+    
+    
+    destroy: function() {
+        Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
+    },
+    
+    
+    scrollBy: function(delta, animate) {
+        this.scrollTo(this.getScrollPosition() + delta, animate);
+    },
+    
+    
+    getItem: function(item) {
+        if (Ext.isString(item)) {
+            item = Ext.getCmp(item);
+        } else if (Ext.isNumber(item)) {
+            item = this.items[item];
+        }
+        
+        return item;
+    },
+    
+    
+    getScrollAnim: function() {
+        return {
+            duration: this.scrollDuration, 
+            callback: this.updateScrollButtons, 
+            scope   : this
+        };
+    },
+    
+    
+    updateScrollButtons: function() {
+        if (this.beforeScroller == undefined || this.afterScroller == undefined) {
+            return;
+        }
+        
+        var beforeMeth = this.atExtremeBefore()  ? 'addClass' : 'removeClass',
+            afterMeth  = this.atExtremeAfter() ? 'addClass' : 'removeClass',
+            beforeCls  = this.beforeScrollerCls + '-disabled',
+            afterCls   = this.afterScrollerCls  + '-disabled';
+        
+        this.beforeScroller[beforeMeth](beforeCls);
+        this.afterScroller[afterMeth](afterCls);
+        this.scrolling = false;
+    },
+    
+    
+    atExtremeBefore: function() {
+        return this.getScrollPosition() === 0;
+    },
+    
+    
+    scrollLeft: function(animate) {
+        this.scrollBy(-this.scrollIncrement, animate);
+    },
+    
+    
+    scrollRight: function(animate) {
+        this.scrollBy(this.scrollIncrement, animate);
+    },
+    
+    
+    scrollToItem: function(item, animate) {
+        item = this.getItem(item);
+        
+        if (item != undefined) {
+            var visibility = this.getItemVisibility(item);
+            
+            if (!visibility.fullyVisible) {
+                var box  = item.getBox(true, true),
+                    newX = box.x;
+                    
+                if (visibility.hiddenRight) {
+                    newX -= (this.layout.innerCt.getWidth() - box.width);
+                }
+                
+                this.scrollTo(newX, animate);
+            }
         }
-        this.layout.layout();
-        this.panel.saveState();
-        return false;
     },
-
     
-    getSplitBar : function(){
-        return this.split;
-    },
-
     
-    destroy : function() {
-        Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
-        Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
+    getItemVisibility: function(item) {
+        var box         = this.getItem(item).getBox(true, true),
+            itemLeft    = box.x,
+            itemRight   = box.x + box.width,
+            scrollLeft  = this.getScrollPosition(),
+            scrollRight = this.layout.innerCt.getWidth() + scrollLeft;
+        
+        return {
+            hiddenLeft  : itemLeft < scrollLeft,
+            hiddenRight : itemRight > scrollRight,
+            fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
+        };
     }
 });
 
-Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
-Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
+Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;
 
-    
-    labelSeparator : ':',
 
+\r
+Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
+    scrollIncrement: 75,
+    wheelIncrement : 2,
     
-
+    handleOverflow: function(calculations, targetSize) {
+        Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);
+        
+        return {
+            targetSize: {
+                height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
+                width : targetSize.width
+            }
+        };
+    },
     
-    trackLabels: false,
-
+    
+    createInnerElements: function() {
+        var target = this.layout.innerCt;
+        
+        
+        
+        if (!this.beforeCt) {
+            this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
+            this.afterCt  = target.insertSibling({cls: this.afterCls},  'after');
 
-    onRemove: function(c){
-        Ext.layout.FormLayout.superclass.onRemove.call(this, c);
-        if(this.trackLabels){
-            c.un('show', this.onFieldShow, this);
-            c.un('hide', this.onFieldHide, this);
+            this.createWheelListener();
         }
+    },
+    
+    
+    scrollTo: function(position, animate) {
+        var oldPosition = this.getScrollPosition(),
+            newPosition = position.constrain(0, this.getMaxScrollBottom());
         
-        var el = c.getPositionEl(),
-                ct = c.getItemCt && c.getItemCt();
-        if(c.rendered && ct){
-            if (el && el.dom) {
-                el.insertAfter(ct);
+        if (newPosition != oldPosition && !this.scrolling) {
+            if (animate == undefined) {
+                animate = this.animateScroll;
             }
-            Ext.destroy(ct);
-            Ext.destroyMembers(c, 'label', 'itemCt');
-            if(c.customItemCt){
-                Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
+            
+            this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false);
+            
+            if (animate) {
+                this.scrolling = true;
+            } else {
+                this.scrolling = false;
+                this.updateScrollButtons();
             }
         }
     },
-
     
-    setContainer : function(ct){
-        Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
-        if(ct.labelAlign){
-            ct.addClass('x-form-label-'+ct.labelAlign);
-        }
-
-        if(ct.hideLabels){
-            Ext.apply(this, {
-                labelStyle: 'display:none',
-                elementStyle: 'padding-left:0;',
-                labelAdjust: 0
-            });
-        }else{
-            this.labelSeparator = ct.labelSeparator || this.labelSeparator;
-            ct.labelWidth = ct.labelWidth || 100;
-            if(Ext.isNumber(ct.labelWidth)){
-                var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
-                Ext.apply(this, {
-                    labelAdjust: ct.labelWidth + pad,
-                    labelStyle: 'width:' + ct.labelWidth + 'px;',
-                    elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
-                });
-            }
-            if(ct.labelAlign == 'top'){
-                Ext.apply(this, {
-                    labelStyle: 'width:auto;',
-                    labelAdjust: 0,
-                    elementStyle: 'padding-left:0;'
-                });
-            }
-        }
+    
+    getScrollPosition: function(){
+        return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
     },
-
     
-    isHide: function(c){
-        return c.hideLabel || this.container.hideLabels;
+    
+    getMaxScrollBottom: function() {
+        return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
     },
+    
+    
+    atExtremeAfter: function() {
+        return this.getScrollPosition() >= this.getMaxScrollBottom();
+    }
+});
 
-    onFieldShow: function(c){
-        c.getItemCt().removeClass('x-hide-' + c.hideMode);
-    },
+Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;
 
-    onFieldHide: function(c){
-        c.getItemCt().addClass('x-hide-' + c.hideMode);
-    },
 
-    
-    getLabelStyle: function(s){
-        var ls = '', items = [this.labelStyle, s];
-        for (var i = 0, len = items.length; i < len; ++i){
-            if (items[i]){
-                ls += items[i];
-                if (ls.substr(-1, 1) != ';'){
-                    ls += ';'
-                }
+
+Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
+    handleOverflow: function(calculations, targetSize) {
+        Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);
+        
+        return {
+            targetSize: {
+                height: targetSize.height,
+                width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
             }
+        };
+    },
+    
+    
+    createInnerElements: function() {
+        var target = this.layout.innerCt;
+        
+        
+        
+        if (!this.beforeCt) {
+            this.afterCt  = target.insertSibling({cls: this.afterCls},  'before');
+            this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
+            
+            this.createWheelListener();
         }
-        return ls;
     },
-
     
-
     
-    renderItem : function(c, position, target){
-        if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
-            var args = this.getTemplateArgs(c);
-            if(Ext.isNumber(position)){
-                position = target.dom.childNodes[position] || null;
-            }
-            if(position){
-                c.itemCt = this.fieldTpl.insertBefore(position, args, true);
-            }else{
-                c.itemCt = this.fieldTpl.append(target, args, true);
-            }
-            if(!c.getItemCt){
-                
-                
-                Ext.apply(c, {
-                    getItemCt: function(){
-                        return c.itemCt;
-                    },
-                    customItemCt: true
-                });
-            }
-            c.label = c.getItemCt().child('label.x-form-item-label');
-            if(!c.rendered){
-                c.render('x-form-el-' + c.id);
-            }else if(!this.isValidParent(c, target)){
-                Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
+    scrollTo: function(position, animate) {
+        var oldPosition = this.getScrollPosition(),
+            newPosition = position.constrain(0, this.getMaxScrollRight());
+        
+        if (newPosition != oldPosition && !this.scrolling) {
+            if (animate == undefined) {
+                animate = this.animateScroll;
             }
-            if(this.trackLabels){
-                if(c.hidden){
-                    this.onFieldHide(c);
-                }
-                c.on({
-                    scope: this,
-                    show: this.onFieldShow,
-                    hide: this.onFieldHide
-                });
+            
+            this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false);
+            
+            if (animate) {
+                this.scrolling = true;
+            } else {
+                this.scrolling = false;
+                this.updateScrollButtons();
             }
-            this.configureItem(c);
-        }else {
-            Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
         }
     },
-
     
-    getTemplateArgs: function(field) {
-        var noLabelSep = !field.fieldLabel || field.hideLabel;
-        return {
-            id: field.id,
-            label: field.fieldLabel,
-            labelStyle: this.getLabelStyle(field.labelStyle),
-            elementStyle: this.elementStyle||'',
-            labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator),
-            itemCls: (field.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''),
-            clearCls: field.clearCls || 'x-form-clear-left'
-        };
-    },
-
     
-    adjustWidthAnchor: function(value, c){
-        if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
-            var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
-            return value - this.labelAdjust + (adjust ? -3 : 0);
-        }
-        return value;
+    getScrollPosition: function(){
+        return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
     },
-
-    adjustHeightAnchor : function(value, c){
-        if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
-            return value - c.label.getHeight();
-        }
-        return value;
+    
+    
+    getMaxScrollRight: function() {
+        return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
     },
-
     
-    isValidParent : function(c, target){
-        return target && this.container.getEl().contains(c.getPositionEl());
+    
+    atExtremeAfter: function() {
+        return this.getScrollPosition() >= this.getMaxScrollRight();
     }
+});
 
+Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;
+Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
     
-});
+    align: 'top', 
 
-Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
+    type : 'hbox',
 
-Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
-    
-    fill : true,
-    
-    autoWidth : true,
-    
-    titleCollapse : true,
-    
-    hideCollapseTool : false,
-    
-    collapseFirst : false,
-    
-    animate : false,
     
-    sequence : false,
     
-    activeOnTop : false,
 
-    renderItem : function(c){
-        if(this.animate === false){
-            c.animCollapse = false;
-        }
-        c.collapsible = true;
-        if(this.autoWidth){
-            c.autoWidth = true;
-        }
-        if(this.titleCollapse){
-            c.titleCollapse = true;
-        }
-        if(this.hideCollapseTool){
-            c.hideCollapseTool = true;
-        }
-        if(this.collapseFirst !== undefined){
-            c.collapseFirst = this.collapseFirst;
-        }
-        if(!this.activeItem && !c.collapsed){
-            this.setActiveItem(c, true);
-        }else if(this.activeItem && this.activeItem != c){
-            c.collapsed = true;
-        }
-        Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
-        c.header.addClass('x-accordion-hd');
-        c.on('beforeexpand', this.beforeExpand, this);
-    },
     
-    onRemove: function(c){
-        Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
-        if(c.rendered){
-            c.header.removeClass('x-accordion-hd');
-        }
-        c.un('beforeexpand', this.beforeExpand, this);
-    },
+    calculateChildBoxes: function(visibleItems, targetSize) {
+        var visibleCount = visibleItems.length,
 
-    
-    beforeExpand : function(p, anim){
-        var ai = this.activeItem;
-        if(ai){
-            if(this.sequence){
-                delete this.activeItem;
-                if (!ai.collapsed){
-                    ai.collapse({callback:function(){
-                        p.expand(anim || true);
-                    }, scope: this});
-                    return false;
+            padding      = this.padding,
+            topOffset    = padding.top,
+            leftOffset   = padding.left,
+            paddingVert  = topOffset  + padding.bottom,
+            paddingHoriz = leftOffset + padding.right,
+
+            width        = targetSize.width - this.scrollOffset,
+            height       = targetSize.height,
+            availHeight  = Math.max(0, height - paddingVert),
+
+            isStart      = this.pack == 'start',
+            isCenter     = this.pack == 'center',
+            isEnd        = this.pack == 'end',
+
+            nonFlexWidth = 0,
+            maxHeight    = 0,
+            totalFlex    = 0,
+            desiredWidth = 0,
+            minimumWidth = 0,
+
+            
+            boxes        = [],
+
+            
+            child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, 
+            horizMargins, vertMargins, stretchHeight;
+
+        
+        for (i = 0; i < visibleCount; i++) {
+            child       = visibleItems[i];
+            childHeight = child.height;
+            childWidth  = child.width;
+            canLayout   = !child.hasLayout && typeof child.doLayout == 'function';
+
+            
+            if (typeof childWidth != 'number') {
+
+                
+                if (child.flex && !childWidth) {
+                    totalFlex += child.flex;
+
+                
+                } else {
+                    
+                    
+                    if (!childWidth && canLayout) {
+                        child.doLayout();
+                    }
+
+                    childSize   = child.getSize();
+                    childWidth  = childSize.width;
+                    childHeight = childSize.height;
                 }
-            }else{
-                ai.collapse(this.animate);
             }
-        }
-        this.setActive(p);
-        if(this.activeOnTop){
-            p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
-        }
-        this.layout();
-    },
 
-    
-    setItemSize : function(item, size){
-        if(this.fill && item){
-            var hh = 0;
-            this.container.items.each(function(p){
-                if(p != item){
-                    hh += p.header.getHeight();
-                }    
+            childMargins = child.margins;
+            horizMargins = childMargins.left + childMargins.right;
+
+            nonFlexWidth += horizMargins + (childWidth || 0);
+            desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
+            minimumWidth += horizMargins + (child.minWidth || childWidth || 0);
+
+            
+            if (typeof childHeight != 'number') {
+                if (canLayout) {
+                    child.doLayout();
+                }
+                childHeight = child.getHeight();
+            }
+
+            maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
+
+            
+            boxes.push({
+                component: child,
+                height   : childHeight || undefined,
+                width    : childWidth  || undefined
             });
-            size.height -= hh;
-            item.setSize(size);
         }
-    },
+                
+        var shortfall = desiredWidth - width,
+            tooNarrow = minimumWidth > width;
+            
+        
+        var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
+        
+        if (tooNarrow) {
+            for (i = 0; i < visibleCount; i++) {
+                boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
+            }
+        } else {
+            
+            
+            if (shortfall > 0) {
+                var minWidths = [];
+                
+                
+                for (var index = 0, length = visibleCount; index < length; index++) {
+                    var item     = visibleItems[index],
+                        minWidth = item.minWidth || 0;
 
-    
-    setActiveItem : function(item){
-        this.setActive(item, true);
-    },
-    
-    
-    setActive : function(item, expand){
-        var ai = this.activeItem;
-        item = this.container.getComponent(item);
-        if(ai != item){
-            if(item.rendered && item.collapsed && expand){
-                item.expand();
-            }else{
-                if(ai){
-                   ai.fireEvent('deactivate', ai);
+                    
+                    
+                    if (item.flex) {
+                        boxes[index].width = minWidth;
+                    } else {
+                        minWidths.push({
+                            minWidth : minWidth,
+                            available: boxes[index].width - minWidth,
+                            index    : index
+                        });
+                    }
                 }
-                this.activeItem = item;
-                item.fireEvent('activate', item);
+                
+                
+                minWidths.sort(function(a, b) {
+                    return a.available > b.available ? 1 : -1;
+                });
+                
+                
+                for (var i = 0, length = minWidths.length; i < length; i++) {
+                    var itemIndex = minWidths[i].index;
+                    
+                    if (itemIndex == undefined) {
+                        continue;
+                    }
+                        
+                    var item      = visibleItems[itemIndex],
+                        box       = boxes[itemIndex],
+                        oldWidth  = box.width,
+                        minWidth  = item.minWidth,
+                        newWidth  = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
+                        reduction = oldWidth - newWidth;
+                    
+                    boxes[itemIndex].width = newWidth;
+                    shortfall -= reduction;                    
+                }
+            } else {
+                
+                var remainingWidth = availableWidth,
+                    remainingFlex  = totalFlex;
+
+                
+                for (i = 0; i < visibleCount; i++) {
+                    child = visibleItems[i];
+                    calcs = boxes[i];
+
+                    childMargins = child.margins;
+                    vertMargins  = childMargins.top + childMargins.bottom;
+
+                    if (isStart && child.flex && !child.width) {
+                        flexedWidth     = Math.ceil((child.flex / remainingFlex) * remainingWidth);
+                        remainingWidth -= flexedWidth;
+                        remainingFlex  -= child.flex;
+
+                        calcs.width = flexedWidth;
+                        calcs.dirtySize = true;
+                    }
+                }
+            }
+        }
+        
+        if (isCenter) {
+            leftOffset += availableWidth / 2;
+        } else if (isEnd) {
+            leftOffset += availableWidth;
+        }
+        
+        
+        for (i = 0; i < visibleCount; i++) {
+            child = visibleItems[i];
+            calcs = boxes[i];
+            
+            childMargins = child.margins;
+            leftOffset  += childMargins.left;
+            vertMargins  = childMargins.top + childMargins.bottom;
+            
+            calcs.left = leftOffset;
+            calcs.top  = topOffset + childMargins.top;
+
+            switch (this.align) {
+                case 'stretch':
+                    stretchHeight = availHeight - vertMargins;
+                    calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
+                    calcs.dirtySize = true;
+                    break;
+                case 'stretchmax':
+                    stretchHeight = maxHeight - vertMargins;
+                    calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
+                    calcs.dirtySize = true;
+                    break;
+                case 'middle':
+                    var diff = availHeight - calcs.height - vertMargins;
+                    if (diff > 0) {
+                        calcs.top = topOffset + vertMargins + (diff / 2);
+                    }
             }
+            
+            leftOffset += calcs.width + childMargins.right;
         }
+
+        return {
+            boxes: boxes,
+            meta : {
+                maxHeight   : maxHeight,
+                nonFlexWidth: nonFlexWidth,
+                desiredWidth: desiredWidth,
+                minimumWidth: minimumWidth,
+                shortfall   : desiredWidth - width,
+                tooNarrow   : tooNarrow
+            }
+        };
     }
 });
-Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
-
 
-Ext.layout.Accordion = Ext.layout.AccordionLayout;
-Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
+Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
+Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
     
+    align : 'left', 
+    type: 'vbox',
 
     
-    monitorResize:false,
-    
-    targetCls: 'x-table-layout-ct',
 
     
-    tableAttrs:null,
-    
+
     
-    setContainer : function(ct){
-        Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
+    calculateChildBoxes: function(visibleItems, targetSize) {
+        var visibleCount = visibleItems.length,
 
-        this.currentRow = 0;
-        this.currentColumn = 0;
-        this.cells = [];
-    },
+            padding      = this.padding,
+            topOffset    = padding.top,
+            leftOffset   = padding.left,
+            paddingVert  = topOffset  + padding.bottom,
+            paddingHoriz = leftOffset + padding.right,
 
-    
-    onLayout : function(ct, target){
-        var cs = ct.items.items, len = cs.length, c, i;
+            width        = targetSize.width - this.scrollOffset,
+            height       = targetSize.height,
+            availWidth   = Math.max(0, width - paddingHoriz),
 
-        if(!this.table){
-            this.table = target.createChild(
-                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
-        }
-        this.renderAll(ct, target);
-    },
+            isStart      = this.pack == 'start',
+            isCenter     = this.pack == 'center',
+            isEnd        = this.pack == 'end',
 
-    
-    getRow : function(index){
-        var row = this.table.tBodies[0].childNodes[index];
-        if(!row){
-            row = document.createElement('tr');
-            this.table.tBodies[0].appendChild(row);
-        }
-        return row;
-    },
+            nonFlexHeight= 0,
+            maxWidth     = 0,
+            totalFlex    = 0,
+            desiredHeight= 0,
+            minimumHeight= 0,
 
-    
-    getNextCell : function(c){
-        var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
-        var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
-        for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
-            if(!this.cells[rowIndex]){
-                this.cells[rowIndex] = [];
+            
+            boxes        = [],
+            
+            
+            child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, 
+            horizMargins, vertMargins, stretchWidth;
+
+        
+        for (i = 0; i < visibleCount; i++) {
+            child = visibleItems[i];
+            childHeight = child.height;
+            childWidth  = child.width;
+            canLayout   = !child.hasLayout && typeof child.doLayout == 'function';
+
+            
+            if (typeof childHeight != 'number') {
+
+                
+                if (child.flex && !childHeight) {
+                    totalFlex += child.flex;
+
+                
+                } else {
+                    
+                    
+                    if (!childHeight && canLayout) {
+                        child.doLayout();
+                    }
+
+                    childSize = child.getSize();
+                    childWidth = childSize.width;
+                    childHeight = childSize.height;
+                }
             }
-            for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
-                this.cells[rowIndex][colIndex] = true;
+            
+            childMargins = child.margins;
+            vertMargins  = childMargins.top + childMargins.bottom;
+
+            nonFlexHeight += vertMargins + (childHeight || 0);
+            desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
+            minimumHeight += vertMargins + (child.minHeight || childHeight || 0);
+
+            
+            if (typeof childWidth != 'number') {
+                if (canLayout) {
+                    child.doLayout();
+                }
+                childWidth = child.getWidth();
             }
+
+            maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
+
+            
+            boxes.push({
+                component: child,
+                height   : childHeight || undefined,
+                width    : childWidth || undefined
+            });
         }
-        var td = document.createElement('td');
-        if(c.cellId){
-            td.id = c.cellId;
-        }
-        var cls = 'x-table-layout-cell';
-        if(c.cellCls){
-            cls += ' ' + c.cellCls;
+                
+        var shortfall = desiredHeight - height,
+            tooNarrow = minimumHeight > height;
+
+        
+        var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
+        
+        if (tooNarrow) {
+            for (i = 0, length = visibleCount; i < length; i++) {
+                boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
+            }
+        } else {
+            
+            
+            if (shortfall > 0) {
+                var minHeights = [];
+
+                
+                for (var index = 0, length = visibleCount; index < length; index++) {
+                    var item      = visibleItems[index],
+                        minHeight = item.minHeight || 0;
+
+                    
+                    
+                    if (item.flex) {
+                        boxes[index].height = minHeight;
+                    } else {
+                        minHeights.push({
+                            minHeight: minHeight, 
+                            available: boxes[index].height - minHeight,
+                            index    : index
+                        });
+                    }
+                }
+
+                
+                minHeights.sort(function(a, b) {
+                    return a.available > b.available ? 1 : -1;
+                });
+
+                
+                for (var i = 0, length = minHeights.length; i < length; i++) {
+                    var itemIndex = minHeights[i].index;
+
+                    if (itemIndex == undefined) {
+                        continue;
+                    }
+
+                    var item      = visibleItems[itemIndex],
+                        box       = boxes[itemIndex],
+                        oldHeight  = box.height,
+                        minHeight  = item.minHeight,
+                        newHeight  = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
+                        reduction = oldHeight - newHeight;
+
+                    boxes[itemIndex].height = newHeight;
+                    shortfall -= reduction;
+                }
+            } else {
+                
+                var remainingHeight = availableHeight,
+                    remainingFlex   = totalFlex;
+                
+                
+                for (i = 0; i < visibleCount; i++) {
+                    child = visibleItems[i];
+                    calcs = boxes[i];
+
+                    childMargins = child.margins;
+                    horizMargins = childMargins.left + childMargins.right;
+
+                    if (isStart && child.flex && !child.height) {
+                        flexedHeight     = Math.ceil((child.flex / remainingFlex) * remainingHeight);
+                        remainingHeight -= flexedHeight;
+                        remainingFlex   -= child.flex;
+
+                        calcs.height = flexedHeight;
+                        calcs.dirtySize = true;
+                    }
+                }
+            }
         }
-        td.className = cls;
-        if(c.colspan){
-            td.colSpan = c.colspan;
+
+        if (isCenter) {
+            topOffset += availableHeight / 2;
+        } else if (isEnd) {
+            topOffset += availableHeight;
         }
-        if(c.rowspan){
-            td.rowSpan = c.rowspan;
+
+        
+        for (i = 0; i < visibleCount; i++) {
+            child = visibleItems[i];
+            calcs = boxes[i];
+
+            childMargins = child.margins;
+            topOffset   += childMargins.top;
+            horizMargins = childMargins.left + childMargins.right;
+            
+
+            calcs.left = leftOffset + childMargins.left;
+            calcs.top  = topOffset;
+            
+            switch (this.align) {
+                case 'stretch':
+                    stretchWidth = availWidth - horizMargins;
+                    calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
+                    calcs.dirtySize = true;
+                    break;
+                case 'stretchmax':
+                    stretchWidth = maxWidth - horizMargins;
+                    calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
+                    calcs.dirtySize = true;
+                    break;
+                case 'center':
+                    var diff = availWidth - calcs.width - horizMargins;
+                    if (diff > 0) {
+                        calcs.left = leftOffset + horizMargins + (diff / 2);
+                    }
+            }
+
+            topOffset += calcs.height + childMargins.bottom;
         }
-        this.getRow(curRow).appendChild(td);
-        return td;
-    },
+        
+        return {
+            boxes: boxes,
+            meta : {
+                maxWidth     : maxWidth,
+                nonFlexHeight: nonFlexHeight,
+                desiredHeight: desiredHeight,
+                minimumHeight: minimumHeight,
+                shortfall    : desiredHeight - height,
+                tooNarrow    : tooNarrow
+            }
+        };
+    }
+});
+
+Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
+
+Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
+    monitorResize : true,
+
+    type: 'toolbar',
+
     
+    triggerWidth: 18,
+
+    
+    noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
+
     
-    getNextNonSpan: function(colIndex, rowIndex){
-        var cols = this.columns;
-        while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
-            if(cols && colIndex >= cols){
-                rowIndex++;
-                colIndex = 0;
-            }else{
-                colIndex++;
+    lastOverflow: false,
+
+    
+    tableHTML: [
+        '<table cellspacing="0" class="x-toolbar-ct">',
+            '<tbody>',
+                '<tr>',
+                    '<td class="x-toolbar-left" align="{0}">',
+                        '<table cellspacing="0">',
+                            '<tbody>',
+                                '<tr class="x-toolbar-left-row"></tr>',
+                            '</tbody>',
+                        '</table>',
+                    '</td>',
+                    '<td class="x-toolbar-right" align="right">',
+                        '<table cellspacing="0" class="x-toolbar-right-ct">',
+                            '<tbody>',
+                                '<tr>',
+                                    '<td>',
+                                        '<table cellspacing="0">',
+                                            '<tbody>',
+                                                '<tr class="x-toolbar-right-row"></tr>',
+                                            '</tbody>',
+                                        '</table>',
+                                    '</td>',
+                                    '<td>',
+                                        '<table cellspacing="0">',
+                                            '<tbody>',
+                                                '<tr class="x-toolbar-extras-row"></tr>',
+                                            '</tbody>',
+                                        '</table>',
+                                    '</td>',
+                                '</tr>',
+                            '</tbody>',
+                        '</table>',
+                    '</td>',
+                '</tr>',
+            '</tbody>',
+        '</table>'
+    ].join(""),
+
+    
+    onLayout : function(ct, target) {
+        
+        if (!this.leftTr) {
+            var align = ct.buttonAlign == 'center' ? 'center' : 'left';
+
+            target.addClass('x-toolbar-layout-ct');
+            target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
+
+            this.leftTr   = target.child('tr.x-toolbar-left-row', true);
+            this.rightTr  = target.child('tr.x-toolbar-right-row', true);
+            this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
+
+            if (this.hiddenItem == undefined) {
+                
+                this.hiddenItems = [];
             }
         }
-        return [colIndex, rowIndex];
-    },
 
-    
-    renderItem : function(c, position, target){
-        if(c && !c.rendered){
-            c.render(this.getNextCell(c));
-            this.configureItem(c, position);
-        }else if(c && !this.isValidParent(c, target)){
-            var container = this.getNextCell(c);
-            container.insertBefore(c.getPositionEl().dom, null);
-            c.container = Ext.get(container);
-            this.configureItem(c, position);
+        var side     = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
+            items    = ct.items.items,
+            position = 0;
+
+        
+        for (var i = 0, len = items.length, c; i < len; i++, position++) {
+            c = items[i];
+
+            if (c.isFill) {
+                side   = this.rightTr;
+                position = -1;
+            } else if (!c.rendered) {
+                c.render(this.insertCell(c, side, position));
+                this.configureItem(c);
+            } else {
+                if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
+                    var td = this.insertCell(c, side, position);
+                    td.appendChild(c.getPositionEl().dom);
+                    c.container = Ext.get(td);
+                }
+            }
         }
+
+        
+        this.cleanup(this.leftTr);
+        this.cleanup(this.rightTr);
+        this.cleanup(this.extrasTr);
+        this.fitToSize(target);
     },
 
     
-    isValidParent : function(c, target){
-        return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
-    }
+    cleanup : function(el) {
+        var cn = el.childNodes, i, c;
+
+        for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
+            if (!c.firstChild) {
+                el.removeChild(c);
+            }
+        }
+    },
 
     
-});
+    insertCell : function(c, target, position) {
+        var td = document.createElement('td');
+        td.className = 'x-toolbar-cell';
 
-Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
-Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
+        target.insertBefore(td, target.childNodes[position] || null);
 
-    extraCls: 'x-abs-layout-item',
+        return td;
+    },
 
-    onLayout : function(ct, target){
-        target.position();
-        this.paddingLeft = target.getPadding('l');
-        this.paddingTop = target.getPadding('t');
+    
+    hideItem : function(item) {
+        this.hiddenItems.push(item);
 
-        Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
+        item.xtbHidden = true;
+        item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
+        item.hide();
     },
 
     
-    adjustWidthAnchor : function(value, comp){
-        return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
+    unhideItem : function(item) {
+        item.show();
+        item.xtbHidden = false;
+        this.hiddenItems.remove(item);
     },
 
     
-    adjustHeightAnchor : function(value, comp){
-        return  value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
-    }
-    
-});
-Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
+    getItemWidth : function(c) {
+        return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
+    },
 
-Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
-    
-    defaultMargins : {left:0,top:0,right:0,bottom:0},
-    
-    padding : '0',
     
-    pack : 'start',
+    fitToSize : function(target) {
+        if (this.container.enableOverflow === false) {
+            return;
+        }
 
-    
-    monitorResize : true,
-    scrollOffset : 0,
-    extraCls : 'x-box-item',
-    targetCls : 'x-box-layout-ct',
-    innerCls : 'x-box-inner',
+        var width       = target.dom.clientWidth,
+            tableWidth  = target.dom.firstChild.offsetWidth,
+            clipWidth   = width - this.triggerWidth,
+            lastWidth   = this.lastWidth || 0,
 
-    constructor : function(config){
-        Ext.layout.BoxLayout.superclass.constructor.call(this, config);
-        if(Ext.isString(this.defaultMargins)){
-            this.defaultMargins = this.parseMargins(this.defaultMargins);
+            hiddenItems = this.hiddenItems,
+            hasHiddens  = hiddenItems.length != 0,
+            isLarger    = width >= lastWidth;
+
+        this.lastWidth  = width;
+
+        if (tableWidth > width || (hasHiddens && isLarger)) {
+            var items     = this.container.items.items,
+                len       = items.length,
+                loopWidth = 0,
+                item;
+
+            for (var i = 0; i < len; i++) {
+                item = items[i];
+
+                if (!item.isFill) {
+                    loopWidth += this.getItemWidth(item);
+                    if (loopWidth > clipWidth) {
+                        if (!(item.hidden || item.xtbHidden)) {
+                            this.hideItem(item);
+                        }
+                    } else if (item.xtbHidden) {
+                        this.unhideItem(item);
+                    }
+                }
+            }
+        }
+
+        
+        hasHiddens = hiddenItems.length != 0;
+
+        if (hasHiddens) {
+            this.initMore();
+
+            if (!this.lastOverflow) {
+                this.container.fireEvent('overflowchange', this.container, true);
+                this.lastOverflow = true;
+            }
+        } else if (this.more) {
+            this.clearMenu();
+            this.more.destroy();
+            delete this.more;
+
+            if (this.lastOverflow) {
+                this.container.fireEvent('overflowchange', this.container, false);
+                this.lastOverflow = false;
+            }
         }
     },
 
     
-    isValidParent : function(c, target){
-        return c.getPositionEl().dom.parentNode == this.innerCt.dom;
+    createMenuConfig : function(component, hideOnClick){
+        var config = Ext.apply({}, component.initialConfig),
+            group  = component.toggleGroup;
+
+        Ext.copyTo(config, component, [
+            'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
+        ]);
+
+        Ext.apply(config, {
+            text       : component.overflowText || component.text,
+            hideOnClick: hideOnClick
+        });
+
+        if (group || component.enableToggle) {
+            Ext.apply(config, {
+                group  : group,
+                checked: component.pressed,
+                listeners: {
+                    checkchange: function(item, checked){
+                        component.toggle(checked);
+                    }
+                }
+            });
+        }
+
+        delete config.ownerCt;
+        delete config.xtype;
+        delete config.id;
+
+        return config;
     },
 
     
-    onLayout : function(ct, target){
-        var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;
+    addComponentToMenu : function(menu, component) {
+        if (component instanceof Ext.Toolbar.Separator) {
+            menu.add('-');
 
-        if(!this.innerCt){
-            
-            
-            this.innerCt = target.createChild({cls:this.innerCls});
-            this.padding = this.parseMargins(this.padding);
+        } else if (Ext.isFunction(component.isXType)) {
+            if (component.isXType('splitbutton')) {
+                menu.add(this.createMenuConfig(component, true));
+
+            } else if (component.isXType('button')) {
+                menu.add(this.createMenuConfig(component, !component.menu));
+
+            } else if (component.isXType('buttongroup')) {
+                component.items.each(function(item){
+                     this.addComponentToMenu(menu, item);
+                }, this);
+            }
         }
-        this.renderAll(ct, this.innerCt);
     },
 
     
-    renderItem : function(c){
-        if(Ext.isString(c.margins)){
-            c.margins = this.parseMargins(c.margins);
-        }else if(!c.margins){
-            c.margins = this.defaultMargins;
+    clearMenu : function(){
+        var menu = this.moreMenu;
+        if (menu && menu.items) {
+            menu.items.each(function(item){
+                delete item.menu;
+            });
         }
-        Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
     },
 
     
-    getTargetSize : function(target){
-        return (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize(true);
-    },
+    beforeMoreShow : function(menu) {
+        var items = this.container.items.items,
+            len   = items.length,
+            item,
+            prev;
 
-    getItems: function(ct){
-        var items = [];
-        ct.items.each(function(c){
-            if(c.isVisible()){
-                items.push(c);
+        var needsSep = function(group, item){
+            return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
+        };
+
+        this.clearMenu();
+        menu.removeAll();
+        for (var i = 0; i < len; i++) {
+            item = items[i];
+            if (item.xtbHidden) {
+                if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
+                    menu.add('-');
+                }
+                this.addComponentToMenu(menu, item);
+                prev = item;
             }
-        });
-        return items;
-    }
-});
+        }
 
+        
+        if (menu.items.length < 1) {
+            menu.add(this.noItemsMenuText);
+        }
+    },
 
-Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
-    
-    align : 'left', 
-    
     
+    initMore : function(){
+        if (!this.more) {
+            
+            this.moreMenu = new Ext.menu.Menu({
+                ownerCt : this.container,
+                listeners: {
+                    beforeshow: this.beforeMoreShow,
+                    scope: this
+                }
+            });
 
-    
-    onLayout : function(ct, target){
-        Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);
-
-        var cs = this.getItems(ct), cm, ch, margin, cl, diff, aw,
-            size = target.getViewSize(true),
-            w = size.width,
-            h = size.height - this.scrollOffset,
-            l = this.padding.left, t = this.padding.top,
-            isStart = this.pack == 'start',
-            stretchWidth = w - (this.padding.left + this.padding.right),
-            extraHeight = 0,
-            maxWidth = 0,
-            totalFlex = 0,
-            flexHeight = 0,
-            usedHeight = 0,
-            idx = 0,
-            heights = [],
-            restore = [],
-            c,
-            csLen = cs.length;
+            
+            this.more = new Ext.Button({
+                iconCls: 'x-toolbar-more-icon',
+                cls    : 'x-toolbar-more',
+                menu   : this.moreMenu,
+                ownerCt: this.container
+            });
 
-        
-        for (i = 0 ; i < csLen; i++) {
-            c = cs[i];
-            cm = c.margins;
-            margin = cm.top + cm.bottom;
-            maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
+            var td = this.insertCell(this.more, this.extrasTr, 100);
+            this.more.render(td);
         }
+    },
 
-        var innerCtWidth = maxWidth + this.padding.left + this.padding.right;
-        switch(this.align){
-            case 'stretch':
-                this.innerCt.setSize(w, h);
-                break;
-            case 'stretchmax':
-            case 'left':
-                this.innerCt.setSize(innerCtWidth, h);
-                break;
-            case 'center':
-                this.innerCt.setSize(w = Math.max(w, innerCtWidth), h);
-                break;
-        }
+    destroy : function(){
+        Ext.destroy(this.more, this.moreMenu);
+        delete this.leftTr;
+        delete this.rightTr;
+        delete this.extrasTr;
+        Ext.layout.ToolbarLayout.superclass.destroy.call(this);
+    }
+});
 
-        var availableWidth = Math.max(0, w - this.padding.left - this.padding.right);
-        
-        for (i = 0 ; i < csLen; i++) {
-            c = cs[i];
-            cm = c.margins;
-            if(this.align == 'stretch'){
-                c.setWidth((stretchWidth - (cm.left + cm.right)).constrain(
-                    c.minWidth || 0, c.maxWidth || 1000000));
-            }else if(this.align == 'stretchmax'){
-                c.setWidth((maxWidth - (cm.left + cm.right)).constrain(
-                    c.minWidth || 0, c.maxWidth || 1000000));
-            }else if(isStart && c.flex){
-                c.setWidth();
-            }
+Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
 
-        }
+ Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
+    monitorResize : true,
 
+    type: 'menu',
+
+    setContainer : function(ct){
+        this.monitorResize = !ct.floating;
         
-        for (i = 0 ; i < csLen; i++) {
-            c = cs[i];
-            cm = c.margins;
-            totalFlex += c.flex || 0;
-            ch = c.getHeight();
-            margin = cm.top + cm.bottom;
-            extraHeight += ch + margin;
-            flexHeight += margin + (c.flex ? 0 : ch);
-        }
-        extraHeight = h - extraHeight - this.padding.top - this.padding.bottom;
-
-        var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight),
-            leftOver = availHeight;
-        for (i = 0 ; i < csLen; i++) {
-            c = cs[i];
-            if(isStart && c.flex){
-                ch = Math.floor(availHeight * (c.flex / totalFlex));
-                leftOver -= ch;
-                heights.push(ch);
-            }
-        }
-        if(this.pack == 'center'){
-            t += extraHeight ? extraHeight / 2 : 0;
-        }else if(this.pack == 'end'){
-            t += extraHeight;
-        }
-        idx = 0;
         
-        for (i = 0 ; i < csLen; i++) {
-            c = cs[i];
-            cm = c.margins;
-            t += cm.top;
-            aw = availableWidth;
-            cl = l + cm.left 
+        ct.on('autosize', this.doAutoSize, this);
+        Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
+    },
 
+    renderItem : function(c, position, target){
+        if (!this.itemTpl) {
+            this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
+                '<li id="{itemId}" class="{itemCls}">',
+                    '<tpl if="needsIcon">',
+                        '<img alt="{altText}" src="{icon}" class="{iconCls}"/>',
+                    '</tpl>',
+                '</li>'
+            );
+        }
 
-            if(this.align == 'center'){
-                if((diff = availableWidth - (c.getWidth() + cm.left + cm.right)) > 0){
-                    cl += (diff/2);
-                    aw -= diff;
-                }
+        if(c && !c.rendered){
+            if(Ext.isNumber(position)){
+                position = target.dom.childNodes[position];
             }
+            var a = this.getItemArgs(c);
 
-            c.setPosition(cl, t);
-            if(isStart && c.flex){
-                ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0));
-                c.setSize(aw, ch);
-            }else{
-                ch = c.getHeight();
-            }
-            t += ch + cm.bottom;
-        }
-    }
-});
 
-Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
+            c.render(c.positionEl = position ?
+                this.itemTpl.insertBefore(position, a, true) :
+                this.itemTpl.append(target, a, true));
 
 
-Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
-    
-    align : 'top', 
-    
-    
+            c.positionEl.menuItemId = c.getItemId();
 
-    
-    onLayout : function(ct, target){
-        Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
 
-        var cs = this.getItems(ct), cm, cw, margin, ch, diff,
-            size = target.getViewSize(true),
-            w = size.width - this.scrollOffset,
-            h = size.height,
-            l = this.padding.left, t = this.padding.top,
-            isStart = this.pack == 'start',
-            isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
-            stretchHeight = h - (this.padding.top + this.padding.bottom),
-            extraWidth = 0,
-            maxHeight = 0,
-            totalFlex = 0,
-            flexWidth = 0,
-            usedWidth = 0;
-
-        Ext.each(cs, function(c){
-            cm = c.margins;
-            totalFlex += c.flex || 0;
-            cw = c.getWidth();
-            margin = cm.left + cm.right;
-            extraWidth += cw + margin;
-            flexWidth += margin + (c.flex ? 0 : cw);
-            maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
-        });
-        extraWidth = w - extraWidth - this.padding.left - this.padding.right;
 
-        var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
-        switch(this.align){
-            case 'stretch':
-                this.innerCt.setSize(w, h);
-                break;
-            case 'stretchmax':
-            case 'top':
-                this.innerCt.setSize(w, innerCtHeight);
-                break;
-            case 'middle':
-                this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
-                break;
+            if (!a.isMenuItem && a.needsIcon) {
+                c.positionEl.addClass('x-menu-list-item-indent');
+            }
+            this.configureItem(c);
+        }else if(c && !this.isValidParent(c, target)){
+            if(Ext.isNumber(position)){
+                position = target.dom.childNodes[position];
+            }
+            target.dom.insertBefore(c.getActionEl().dom, position || null);
         }
+    },
 
+    getItemArgs : function(c) {
+        var isMenuItem = c instanceof Ext.menu.Item,
+            canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator);
 
-        var availWidth = Math.max(0, w - this.padding.left - this.padding.right - flexWidth),
-            leftOver = availWidth,
-            widths = [],
-            restore = [],
-            idx = 0,
-            availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom);
-
+        return {
+            isMenuItem: isMenuItem,
+            needsIcon: canHaveIcon && (c.icon || c.iconCls),
+            icon: c.icon || Ext.BLANK_IMAGE_URL,
+            iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
+            itemId: 'x-menu-el-' + c.id,
+            itemCls: 'x-menu-list-item ',
+            altText: c.altText || ''
+        };
+    },
 
-        Ext.each(cs, function(c){
-            if(isStart && c.flex){
-                cw = Math.floor(availWidth * (c.flex / totalFlex));
-                leftOver -= cw;
-                widths.push(cw);
-            }
-        });
+    
+    isValidParent : function(c, target) {
+        return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
+    },
 
-        if(this.pack == 'center'){
-            l += extraWidth ? extraWidth / 2 : 0;
-        }else if(this.pack == 'end'){
-            l += extraWidth;
-        }
-        Ext.each(cs, function(c){
-            cm = c.margins;
-            l += cm.left;
-            c.setPosition(l, t + cm.top);
-            if(isStart && c.flex){
-                cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0));
-                if(isRestore){
-                    restore.push(c.getHeight());
-                }
-                c.setSize(cw, availableHeight);
-            }else{
-                cw = c.getWidth();
-            }
-            l += cw + cm.right;
-        });
+    onLayout : function(ct, target){
+        Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
+        this.doAutoSize();
+    },
 
-        idx = 0;
-        Ext.each(cs, function(c){
-            cm = c.margins;
-            ch = c.getHeight();
-            if(isStart && c.flex){
-                ch = restore[idx++];
-            }
-            if(this.align == 'stretch'){
-                c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain(
-                    c.minHeight || 0, c.maxHeight || 1000000));
-            }else if(this.align == 'stretchmax'){
-                c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
-                    c.minHeight || 0, c.maxHeight || 1000000));
-            }else{
-                if(this.align == 'middle'){
-                    diff = availableHeight - (ch + cm.top + cm.bottom);
-                    ch = t + cm.top + (diff/2);
-                    if(diff > 0){
-                        c.setPosition(c.x, ch);
-                    }
-                }
-                if(isStart && c.flex){
-                    c.setHeight(ch);
-                }
+    doAutoSize : function(){
+        var ct = this.container, w = ct.width;
+        if(ct.floating){
+            if(w){
+                ct.setWidth(w);
+            }else if(Ext.isIE){
+                ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
+                var el = ct.getEl(), t = el.dom.offsetWidth; 
+                ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
             }
-        }, this);
+        }
     }
 });
-
-Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
+Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
 
 Ext.Viewport = Ext.extend(Ext.Container, {
     
@@ -13719,7 +16828,7 @@ Ext.Viewport = Ext.extend(Ext.Container, {
     },
 
     fireResize : function(w, h){
-        this.onResize(w, h, w, h);
+        this.fireEvent('resize', this, w, h, w, h);
     }
 });
 Ext.reg('viewport', Ext.Viewport);
@@ -13856,30 +16965,30 @@ Ext.Panel = Ext.extend(Ext.Container, {
         if(this.tbar){
             this.elements += ',tbar';
             this.topToolbar = this.createToolbar(this.tbar);
-            delete this.tbar;
+            this.tbar = null;
 
         }
         if(this.bbar){
             this.elements += ',bbar';
             this.bottomToolbar = this.createToolbar(this.bbar);
-            delete this.bbar;
+            this.bbar = null;
         }
 
         if(this.header === true){
             this.elements += ',header';
-            delete this.header;
+            this.header = null;
         }else if(this.headerCfg || (this.title && this.header !== false)){
             this.elements += ',header';
         }
 
         if(this.footerCfg || this.footer === true){
             this.elements += ',footer';
-            delete this.footer;
+            this.footer = null;
         }
 
         if(this.buttons){
             this.fbar = this.buttons;
-            delete this.buttons;
+            this.buttons = null;
         }
         if(this.fbar){
             this.createFbar(this.fbar);
@@ -13903,10 +17012,8 @@ Ext.Panel = Ext.extend(Ext.Container, {
                 };
             }
         });
-        //@compat addButton and buttons could possibly be removed
-
-        //@target 4.0
-
+        
+        
         
         this.fbar.items.each(function(c){
             c.minWidth = c.minWidth || this.minButtonWidth;
@@ -13924,8 +17031,6 @@ Ext.Panel = Ext.extend(Ext.Container, {
             };
         }
         result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
-        result.ownerCt = this;
-        result.bufferResize = false;
         this.toolbars.push(result);
         return result;
     },
@@ -14100,18 +17205,21 @@ Ext.Panel = Ext.extend(Ext.Container, {
         if(ts){
             this.addTool.apply(this, ts);
         }
+
+        
         if(this.fbar){
             this.footer.addClass('x-panel-btns');
+            this.fbar.ownerCt = this;
             this.fbar.render(this.footer);
             this.footer.createChild({cls:'x-clear'});
         }
-
         if(this.tbar && this.topToolbar){
+            this.topToolbar.ownerCt = this;
             this.topToolbar.render(this.tbar);
         }
         if(this.bbar && this.bottomToolbar){
+            this.bottomToolbar.ownerCt = this;
             this.bottomToolbar.render(this.bbar);
-
         }
     },
 
@@ -14129,9 +17237,12 @@ Ext.Panel = Ext.extend(Ext.Container, {
                 if(img){
                     Ext.fly(img).replaceClass(old, this.iconCls);
                 }else{
-                    Ext.DomHelper.insertBefore(hd.dom.firstChild, {
-                        tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
-                    });
+                    var hdspan = hd.child('span.' + this.headerTextCls);
+                    if (hdspan) {
+                        Ext.DomHelper.insertBefore(hdspan.dom, {
+                            tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
+                        });
+                    }
                  }
             }
         }
@@ -14160,6 +17271,11 @@ Ext.Panel = Ext.extend(Ext.Container, {
     },
 
     
+    getFooterToolbar : function() {
+        return this.fbar;
+    },
+
+    
     addButton : function(config, handler, scope){
         if(!this.fbar){
             this.createFbar([]);
@@ -14171,7 +17287,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
             config = Ext.apply({
                 handler: handler,
                 scope: scope
-            }, config)
+            }, config);
         }
         return this.fbar.add(config);
     },
@@ -14183,7 +17299,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
                 this.tools = [];
             }
             Ext.each(arguments, function(arg){
-                this.tools.push(arg)
+                this.tools.push(arg);
             }, this);
             return;
         }
@@ -14204,7 +17320,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
             var tc = a[i];
             if(!this.tools[tc.id]){
                 var overCls = 'x-tool-'+tc.id+'-over';
-                var t = this.toolTemplate.insertFirst((tc.align !== 'left') ? this[this.toolTarget] : this[this.toolTarget].child('span'), tc, true);
+                var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
                 this.tools[tc.id] = t;
                 t.enableDisplayMode('block');
                 this.mon(t, 'click',  this.createToolHandler(t, tc, overCls, this));
@@ -14229,6 +17345,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
     },
 
     onLayout : function(shallow, force){
+        Ext.Panel.superclass.onLayout.apply(this, arguments);
         if(this.hasLayout && this.toolbars.length > 0){
             Ext.each(this.toolbars, function(tb){
                 tb.doLayout(undefined, force);
@@ -14249,7 +17366,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
 
 
         if(h != this.getToolbarHeight()){
-            h = Math.max(0, this.adjustBodyHeight(lsh - this.getFrameHeight()));
+            h = Math.max(0, lsh - this.getFrameHeight());
             bd.setHeight(h);
             sz = bd.getSize();
             this.toolbarHeight = this.getToolbarHeight();
@@ -14294,13 +17411,13 @@ Ext.Panel = Ext.extend(Ext.Container, {
         if(this.title){
             this.setTitle(this.title);
         }
-        if(this.collapsed){
+        Ext.Panel.superclass.afterRender.call(this); 
+        if (this.collapsed) {
             this.collapsed = false;
             this.collapse(false);
         }
-        Ext.Panel.superclass.afterRender.call(this); 
         this.initEvents();
-    },    
+    },
 
     
     getKeyMap : function(){
@@ -14327,9 +17444,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
                     remove: this.syncHeight
                 });
             }, this);
-            if(!this.ownerCt){
-                this.syncHeight();
-            }
+            this.syncHeight();
         }
 
     },
@@ -14353,9 +17468,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
     
     afterEffect : function(anim){
         this.syncShadow();
-        if(anim !== false){
-            this.el.removeClass('x-panel-animated');
-        }
+        this.el.removeClass('x-panel-animated');
     },
 
     
@@ -14396,7 +17509,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
                     Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
                         this.collapseDefaults));
         }else{
-            this[this.collapseEl].hide();
+            this[this.collapseEl].hide(this.hideMode);
             this.afterCollapse(false);
         }
     },
@@ -14405,7 +17518,17 @@ Ext.Panel = Ext.extend(Ext.Container, {
     afterCollapse : function(anim){
         this.collapsed = true;
         this.el.addClass(this.collapsedCls);
+        if(anim !== false){
+            this[this.collapseEl].hide(this.hideMode);
+        }
         this.afterEffect(anim);
+
+        
+        this.cascade(function(c) {
+            if (c.lastSize) {
+                c.lastSize = { width: undefined, height: undefined };
+            }
+        });
         this.fireEvent('collapse', this);
     },
 
@@ -14428,7 +17551,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
                     Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
                         this.expandDefaults));
         }else{
-            this[this.collapseEl].show();
+            this[this.collapseEl].show(this.hideMode);
             this.afterExpand(false);
         }
     },
@@ -14436,8 +17559,12 @@ Ext.Panel = Ext.extend(Ext.Container, {
     
     afterExpand : function(anim){
         this.collapsed = false;
+        if(anim !== false){
+            this[this.collapseEl].show(this.hideMode);
+        }
         this.afterEffect(anim);
-        if(Ext.isDefined(this.deferLayout)){
+        if (this.deferLayout) {
+            delete this.deferLayout;
             this.doLayout(true);
         }
         this.fireEvent('expand', this);
@@ -14466,7 +17593,10 @@ Ext.Panel = Ext.extend(Ext.Container, {
     },
 
     
-    onResize : function(w, h){
+    onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
+        var w = adjWidth,
+            h = adjHeight;
+
         if(Ext.isDefined(w) || Ext.isDefined(h)){
             if(!this.collapsed){
                 
@@ -14507,7 +17637,8 @@ Ext.Panel = Ext.extend(Ext.Container, {
 
                 
                 if(Ext.isNumber(h)){
-                    h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight()));
+                    h = Math.max(0, h - this.getFrameHeight());
+                    
                     this.body.setHeight(h);
                 }else if(h == 'auto'){
                     this.body.setHeight(h);
@@ -14517,6 +17648,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
                     this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
                 }
             }else{
+                
                 this.queuedBodySize = {width: w, height: h};
                 if(!this.queuedExpand && this.allowQueuedExpand !== false){
                     this.queuedExpand = true;
@@ -14529,7 +17661,8 @@ Ext.Panel = Ext.extend(Ext.Container, {
             this.onBodyResize(w, h);
         }
         this.syncShadow();
-        Ext.Panel.superclass.onResize.call(this);
+        Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
+
     },
 
     
@@ -14576,7 +17709,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
     },
 
     
-    getFrameHeight : function(){
+    getFrameHeight : function() {
         var h  = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
         h += (this.tbar ? this.tbar.getHeight() : 0) +
              (this.bbar ? this.bbar.getHeight() : 0);
@@ -14597,7 +17730,8 @@ Ext.Panel = Ext.extend(Ext.Container, {
 
     
     getInnerHeight : function(){
-        return this.getSize().height - this.getFrameHeight();
+        return this.body.getHeight();
+        
     },
 
     
@@ -14653,6 +17787,12 @@ Ext.Panel = Ext.extend(Ext.Container, {
                 Ext.destroy(this.tools[k]);
             }
         }
+        if(this.toolbars.length > 0){
+            Ext.each(this.toolbars, function(tb){
+                tb.un('afterlayout', this.syncHeight, this);
+                tb.un('remove', this.syncHeight, this);
+            }, this);
+        }
         if(Ext.isArray(this.buttons)){
             while(this.buttons.length) {
                 Ext.destroy(this.buttons[0]);
@@ -14663,12 +17803,12 @@ Ext.Panel = Ext.extend(Ext.Container, {
                 this.ft,
                 this.header,
                 this.footer,
-                this.toolbars,
                 this.tbar,
                 this.bbar,
                 this.body,
                 this.mc,
-                this.bwrap
+                this.bwrap,
+                this.dd
             );
             if (this.fbar) {
                 Ext.destroy(
@@ -14676,12 +17816,8 @@ Ext.Panel = Ext.extend(Ext.Container, {
                     this.fbar.el
                 );
             }
-        }else{
-            Ext.destroy(
-                this.topToolbar,
-                this.bottomToolbar
-            );
         }
+        Ext.destroy(this.toolbars);
     },
 
     
@@ -14750,6 +17886,7 @@ Ext.Editor = function(field, config){
 Ext.extend(Ext.Editor, Ext.Component, {
     
     
+    allowBlur: true,
     
     
     
@@ -14841,7 +17978,7 @@ Ext.extend(Ext.Editor, Ext.Component, {
                 this.cancelEdit();
             }
             if(field.triggerBlur){
-                field.triggerBlur(); 
+                field.triggerBlur();
             }
         }
         this.fireEvent('specialkey', field, e);
@@ -14894,7 +18031,8 @@ Ext.extend(Ext.Editor, Ext.Component, {
         delete this.field.lastSize;
         this.field.setSize(w, h);
         if(this.el){
-            if(Ext.isGecko2 || Ext.isOpera){
+            
+            if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){
                 
                 this.el.setSize(w, h);
             }
@@ -14915,6 +18053,10 @@ Ext.extend(Ext.Editor, Ext.Component, {
         if(!this.editing){
             return;
         }
+        
+        if (this.field.assertValue) {
+            this.field.assertValue();
+        }
         var v = this.getValue();
         if(!this.field.isValid()){
             if(this.revertInvalid !== false){
@@ -14955,7 +18097,7 @@ Ext.extend(Ext.Editor, Ext.Component, {
             this.fireEvent("canceledit", this, v, this.startValue);
         }
     },
-    
+
     
     hideEdit: function(remainVisible){
         if(remainVisible !== true){
@@ -14966,7 +18108,8 @@ Ext.extend(Ext.Editor, Ext.Component, {
 
     
     onBlur : function(){
-        if(this.allowBlur !== true && this.editing){
+        
+        if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
             this.completeEdit();
         }
     },
@@ -14999,7 +18142,7 @@ Ext.extend(Ext.Editor, Ext.Component, {
 
     beforeDestroy : function(){
         Ext.destroyMembers(this, 'field');
-        
+
         delete this.parentEl;
         delete this.boundEl;
     }
@@ -15068,7 +18211,7 @@ Ext.ColorPalette = Ext.extend(Ext.Component, {
         if(this.value){
             var s = this.value;
             this.value = null;
-            this.select(s);
+            this.select(s, true);
         }
     },
 
@@ -15082,7 +18225,7 @@ Ext.ColorPalette = Ext.extend(Ext.Component, {
     },
 
     
-    select : function(color){
+    select : function(color, suppressEvent){
         color = color.replace('#', '');
         if(color != this.value || this.allowReselect){
             var el = this.el;
@@ -15091,14 +18234,15 @@ Ext.ColorPalette = Ext.extend(Ext.Component, {
             }
             el.child('a.color-'+color).addClass('x-color-palette-sel');
             this.value = color;
-            this.fireEvent('select', this, color);
+            if(suppressEvent !== true){
+                this.fireEvent('select', this, color);
+            }
         }
     }
 
     
 });
 Ext.reg('colorpalette', Ext.ColorPalette);
-
 Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     
     todayText : 'Today',
@@ -15107,7 +18251,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     
     cancelText : 'Cancel',
     
-     
+    
     
     todayTip : '{0} (Spacebar)',
     
@@ -15139,12 +18283,16 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     
     
     
-    
+
     
     
     focusOnSelect: true,
 
     
+    
+    initHour: 12, 
+
+    
     initComponent : function(){
         Ext.DatePicker.superclass.initComponent.call(this);
 
@@ -15169,7 +18317,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
             var dd = this.disabledDates,
                 len = dd.length - 1,
                 re = '(?:';
-                
+
             Ext.each(dd, function(d, i){
                 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
                 if(i != len){
@@ -15225,21 +18373,21 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     focus : function(){
         this.update(this.activeDate);
     },
-    
+
     
     onEnable: function(initial){
-        Ext.DatePicker.superclass.onEnable.call(this);    
+        Ext.DatePicker.superclass.onEnable.call(this);
         this.doDisabled(false);
         this.update(initial ? this.value : this.activeDate);
         if(Ext.isIE){
             this.el.repaint();
         }
-        
+
     },
-    
+
     
     onDisable : function(){
-        Ext.DatePicker.superclass.onDisable.call(this);   
+        Ext.DatePicker.superclass.onDisable.call(this);
         this.doDisabled(true);
         if(Ext.isIE && !Ext.isIE8){
             
@@ -15248,7 +18396,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
              });
         }
     },
-    
+
     
     doDisabled : function(disabled){
         this.keyNav.setDisabled(disabled);
@@ -15317,7 +18465,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
                 if(e.ctrlKey){
                     this.showPrevMonth();
                 }else{
-                    this.update(this.activeDate.add('d', -1));    
+                    this.update(this.activeDate.add('d', -1));
                 }
             },
 
@@ -15325,7 +18473,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
                 if(e.ctrlKey){
                     this.showNextMonth();
                 }else{
-                    this.update(this.activeDate.add('d', 1));    
+                    this.update(this.activeDate.add('d', 1));
                 }
             },
 
@@ -15592,141 +18740,140 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     
     update : function(date, forceRefresh){
         if(this.rendered){
-               var vd = this.activeDate, vis = this.isVisible();
-               this.activeDate = date;
-               if(!forceRefresh && vd && this.el){
-                   var t = date.getTime();
-                   if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
-                       this.cells.removeClass('x-date-selected');
-                       this.cells.each(function(c){
-                          if(c.dom.firstChild.dateValue == t){
-                              c.addClass('x-date-selected');
-                              if(vis && !this.cancelFocus){
-                                  Ext.fly(c.dom.firstChild).focus(50);
-                              }
-                              return false;
-                          }
-                       }, this);
-                       return;
-                   }
-               }
-               var days = date.getDaysInMonth(),
-                   firstOfMonth = date.getFirstDateOfMonth(),
-                   startingPos = firstOfMonth.getDay()-this.startDay;
-       
-               if(startingPos < 0){
-                   startingPos += 7;
-               }
-               days += startingPos;
-       
-               var pm = date.add('mo', -1),
-                   prevStart = pm.getDaysInMonth()-startingPos,
-                   cells = this.cells.elements,
-                   textEls = this.textNodes,
-                   
-                   day = 86400000,
-                   d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime(),
-                   today = new Date().clearTime().getTime(),
-                   sel = date.clearTime(true).getTime(),
-                   min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
-                   max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
-                   ddMatch = this.disabledDatesRE,
-                   ddText = this.disabledDatesText,
-                   ddays = this.disabledDays ? this.disabledDays.join('') : false,
-                   ddaysText = this.disabledDaysText,
-                   format = this.format;
-       
-               if(this.showToday){
-                   var td = new Date().clearTime(),
-                       disable = (td < min || td > max ||
-                       (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
-                       (ddays && ddays.indexOf(td.getDay()) != -1));
-       
-                   if(!this.disabled){
-                       this.todayBtn.setDisabled(disable);
-                       this.todayKeyListener[disable ? 'disable' : 'enable']();
-                   }
-               }
-       
-               var setCellClass = function(cal, cell){
-                   cell.title = '';
-                   var t = d.getTime();
-                   cell.firstChild.dateValue = t;
-                   if(t == today){
-                       cell.className += ' x-date-today';
-                       cell.title = cal.todayText;
-                   }
-                   if(t == sel){
-                       cell.className += ' x-date-selected';
-                       if(vis){
-                           Ext.fly(cell.firstChild).focus(50);
-                       }
-                   }
-                   
-                   if(t < min) {
-                       cell.className = ' x-date-disabled';
-                       cell.title = cal.minText;
-                       return;
-                   }
-                   if(t > max) {
-                       cell.className = ' x-date-disabled';
-                       cell.title = cal.maxText;
-                       return;
-                   }
-                   if(ddays){
-                       if(ddays.indexOf(d.getDay()) != -1){
-                           cell.title = ddaysText;
-                           cell.className = ' x-date-disabled';
-                       }
-                   }
-                   if(ddMatch && format){
-                       var fvalue = d.dateFormat(format);
-                       if(ddMatch.test(fvalue)){
-                           cell.title = ddText.replace('%0', fvalue);
-                           cell.className = ' x-date-disabled';
-                       }
-                   }
-               };
-       
-               var i = 0;
-               for(; i < startingPos; i++) {
-                   textEls[i].innerHTML = (++prevStart);
-                   d.setDate(d.getDate()+1);
-                   cells[i].className = 'x-date-prevday';
-                   setCellClass(this, cells[i]);
-               }
-               for(; i < days; i++){
-                   var intDay = i - startingPos + 1;
-                   textEls[i].innerHTML = (intDay);
-                   d.setDate(d.getDate()+1);
-                   cells[i].className = 'x-date-active';
-                   setCellClass(this, cells[i]);
-               }
-               var extraDays = 0;
-               for(; i < 42; i++) {
-                    textEls[i].innerHTML = (++extraDays);
-                    d.setDate(d.getDate()+1);
-                    cells[i].className = 'x-date-nextday';
-                    setCellClass(this, cells[i]);
-               }
-       
-               this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
-       
-               if(!this.internalRender){
-                   var main = this.el.dom.firstChild,
-                       w = main.offsetWidth;
-                   this.el.setWidth(w + this.el.getBorderWidth('lr'));
-                   Ext.fly(main).setWidth(w);
-                   this.internalRender = true;
-                   
-                   
-                   
-                   if(Ext.isOpera && !this.secondPass){
-                       main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
-                       this.secondPass = true;
-                       this.update.defer(10, this, [date]);
-                   }
-               }
+            var vd = this.activeDate, vis = this.isVisible();
+            this.activeDate = date;
+            if(!forceRefresh && vd && this.el){
+                var t = date.getTime();
+                if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
+                    this.cells.removeClass('x-date-selected');
+                    this.cells.each(function(c){
+                       if(c.dom.firstChild.dateValue == t){
+                           c.addClass('x-date-selected');
+                           if(vis && !this.cancelFocus){
+                               Ext.fly(c.dom.firstChild).focus(50);
+                           }
+                           return false;
+                       }
+                    }, this);
+                    return;
+                }
+            }
+            var days = date.getDaysInMonth(),
+                firstOfMonth = date.getFirstDateOfMonth(),
+                startingPos = firstOfMonth.getDay()-this.startDay;
+
+            if(startingPos < 0){
+                startingPos += 7;
+            }
+            days += startingPos;
+
+            var pm = date.add('mo', -1),
+                prevStart = pm.getDaysInMonth()-startingPos,
+                cells = this.cells.elements,
+                textEls = this.textNodes,
+                
+                d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
+                today = new Date().clearTime().getTime(),
+                sel = date.clearTime(true).getTime(),
+                min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
+                max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
+                ddMatch = this.disabledDatesRE,
+                ddText = this.disabledDatesText,
+                ddays = this.disabledDays ? this.disabledDays.join('') : false,
+                ddaysText = this.disabledDaysText,
+                format = this.format;
+
+            if(this.showToday){
+                var td = new Date().clearTime(),
+                    disable = (td < min || td > max ||
+                    (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
+                    (ddays && ddays.indexOf(td.getDay()) != -1));
+
+                if(!this.disabled){
+                    this.todayBtn.setDisabled(disable);
+                    this.todayKeyListener[disable ? 'disable' : 'enable']();
+                }
+            }
+
+            var setCellClass = function(cal, cell){
+                cell.title = '';
+                var t = d.clearTime(true).getTime();
+                cell.firstChild.dateValue = t;
+                if(t == today){
+                    cell.className += ' x-date-today';
+                    cell.title = cal.todayText;
+                }
+                if(t == sel){
+                    cell.className += ' x-date-selected';
+                    if(vis){
+                        Ext.fly(cell.firstChild).focus(50);
+                    }
+                }
+                
+                if(t < min) {
+                    cell.className = ' x-date-disabled';
+                    cell.title = cal.minText;
+                    return;
+                }
+                if(t > max) {
+                    cell.className = ' x-date-disabled';
+                    cell.title = cal.maxText;
+                    return;
+                }
+                if(ddays){
+                    if(ddays.indexOf(d.getDay()) != -1){
+                        cell.title = ddaysText;
+                        cell.className = ' x-date-disabled';
+                    }
+                }
+                if(ddMatch && format){
+                    var fvalue = d.dateFormat(format);
+                    if(ddMatch.test(fvalue)){
+                        cell.title = ddText.replace('%0', fvalue);
+                        cell.className = ' x-date-disabled';
+                    }
+                }
+            };
+
+            var i = 0;
+            for(; i < startingPos; i++) {
+                textEls[i].innerHTML = (++prevStart);
+                d.setDate(d.getDate()+1);
+                cells[i].className = 'x-date-prevday';
+                setCellClass(this, cells[i]);
+            }
+            for(; i < days; i++){
+                var intDay = i - startingPos + 1;
+                textEls[i].innerHTML = (intDay);
+                d.setDate(d.getDate()+1);
+                cells[i].className = 'x-date-active';
+                setCellClass(this, cells[i]);
+            }
+            var extraDays = 0;
+            for(; i < 42; i++) {
+                 textEls[i].innerHTML = (++extraDays);
+                 d.setDate(d.getDate()+1);
+                 cells[i].className = 'x-date-nextday';
+                 setCellClass(this, cells[i]);
+            }
+
+            this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
+
+            if(!this.internalRender){
+                var main = this.el.dom.firstChild,
+                    w = main.offsetWidth;
+                this.el.setWidth(w + this.el.getBorderWidth('lr'));
+                Ext.fly(main).setWidth(w);
+                this.internalRender = true;
+                
+                
+                
+                if(Ext.isOpera && !this.secondPass){
+                    main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
+                    this.secondPass = true;
+                    this.update.defer(10, this, [date]);
+                }
+            }
         }
     },
 
@@ -15833,183 +18980,408 @@ Ext.LoadMask.prototype = {
             um.un('failure', this.onLoad, this);
         }
     }
-};
-Ext.Slider = Ext.extend(Ext.BoxComponent, {
-       
-       
+};Ext.ns('Ext.slider');
+
+
+Ext.slider.Thumb = Ext.extend(Object, {
+    
+    
+    dragging: false,
+
+    
+    constructor: function(config) {
+        
+        Ext.apply(this, config || {}, {
+            cls: 'x-slider-thumb',
+
+            
+            constrain: false
+        });
+
+        Ext.slider.Thumb.superclass.constructor.call(this, config);
+
+        if (this.slider.vertical) {
+            Ext.apply(this, Ext.slider.Thumb.Vertical);
+        }
+    },
+
+    
+    render: function() {
+        this.el = this.slider.innerEl.insertFirst({cls: this.cls});
+
+        this.initEvents();
+    },
+
+    
+    enable: function() {
+        this.disabled = false;
+        this.el.removeClass(this.slider.disabledClass);
+    },
+
+    
+    disable: function() {
+        this.disabled = true;
+        this.el.addClass(this.slider.disabledClass);
+    },
+
+    
+    initEvents: function() {
+        var el = this.el;
+
+        el.addClassOnOver('x-slider-thumb-over');
+
+        this.tracker = new Ext.dd.DragTracker({
+            onBeforeStart: this.onBeforeDragStart.createDelegate(this),
+            onStart      : this.onDragStart.createDelegate(this),
+            onDrag       : this.onDrag.createDelegate(this),
+            onEnd        : this.onDragEnd.createDelegate(this),
+            tolerance    : 3,
+            autoStart    : 300
+        });
+
+        this.tracker.initEl(el);
+    },
+
+    
+    onBeforeDragStart : function(e) {
+        if (this.disabled) {
+            return false;
+        } else {
+            this.slider.promoteThumb(this);
+            return true;
+        }
+    },
+
+    
+    onDragStart: function(e){
+        this.el.addClass('x-slider-thumb-drag');
+        this.dragging = true;
+        this.dragStartValue = this.value;
+
+        this.slider.fireEvent('dragstart', this.slider, e, this);
+    },
+
+    
+    onDrag: function(e) {
+        var slider   = this.slider,
+            index    = this.index,
+            newValue = this.getNewValue();
+
+        if (this.constrain) {
+            var above = slider.thumbs[index + 1],
+                below = slider.thumbs[index - 1];
+
+            if (below != undefined && newValue <= below.value) newValue = below.value;
+            if (above != undefined && newValue >= above.value) newValue = above.value;
+        }
+
+        slider.setValue(index, newValue, false);
+        slider.fireEvent('drag', slider, e, this);
+    },
+
+    getNewValue: function() {
+        var slider   = this.slider,
+            pos      = slider.innerEl.translatePoints(this.tracker.getXY());
+
+        return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
+    },
+
+    
+    onDragEnd: function(e) {
+        var slider = this.slider,
+            value  = this.value;
+
+        this.el.removeClass('x-slider-thumb-drag');
+
+        this.dragging = false;
+        slider.fireEvent('dragend', slider, e);
+
+        if (this.dragStartValue != value) {
+            slider.fireEvent('changecomplete', slider, value, this);
+        }
+    },
+    
+    
+    destroy: function(){
+        Ext.destroyMembers(this, 'tracker', 'el');
+    }
+});
+
+
+Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
+    
+    
     vertical: false,
-       
+    
     minValue: 0,
-       
+    
     maxValue: 100,
     
     decimalPrecision: 0,
-       
+    
     keyIncrement: 1,
-       
+    
     increment: 0,
-       
+
+    
     clickRange: [5,15],
-       
+
+    
     clickToChange : true,
-       
+    
     animate: true,
+    
+    constrainThumbs: true,
 
     
-    dragging: false,
+    topThumbZIndex: 10000,
 
     
     initComponent : function(){
         if(!Ext.isDefined(this.value)){
             this.value = this.minValue;
         }
-        Ext.Slider.superclass.initComponent.call(this);
+
+        
+        this.thumbs = [];
+
+        Ext.slider.MultiSlider.superclass.initComponent.call(this);
+
         this.keyIncrement = Math.max(this.increment, this.keyIncrement);
         this.addEvents(
             
-                       'beforechange',
-                       
-                       'change',
-                       
-                       'changecomplete',
-                       
-                       'dragstart',
-                       
-                       'drag',
-                       
-                       'dragend'
-               );
+            'beforechange',
+
+            
+            'change',
+
+            
+            'changecomplete',
+
+            
+            'dragstart',
+
+            
+            'drag',
+
+            
+            'dragend'
+        );
+
+        
+        if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
+
+        var values = this.values;
+
+        for (var i=0; i < values.length; i++) {
+            this.addThumb(values[i]);
+        }
 
         if(this.vertical){
-            Ext.apply(this, Ext.Slider.Vertical);
+            Ext.apply(this, Ext.slider.Vertical);
         }
     },
 
-       
-    onRender : function(){
+    
+    addThumb: function(value) {
+        var thumb = new Ext.slider.Thumb({
+            value    : value,
+            slider   : this,
+            index    : this.thumbs.length,
+            constrain: this.constrainThumbs
+        });
+        this.thumbs.push(thumb);
+
+        
+        if (this.rendered) thumb.render();
+    },
+
+    
+    promoteThumb: function(topThumb) {
+        var thumbs = this.thumbs,
+            zIndex, thumb;
+
+        for (var i = 0, j = thumbs.length; i < j; i++) {
+            thumb = thumbs[i];
+
+            if (thumb == topThumb) {
+                zIndex = this.topThumbZIndex;
+            } else {
+                zIndex = '';
+            }
+
+            thumb.el.setStyle('zIndex', zIndex);
+        }
+    },
+
+    
+    onRender : function() {
         this.autoEl = {
             cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
-            cn:{cls:'x-slider-end',cn:{cls:'x-slider-inner',cn:[{cls:'x-slider-thumb'},{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]}}
+            cn : {
+                cls: 'x-slider-end',
+                cn : {
+                    cls:'x-slider-inner',
+                    cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
+                }
+            }
         };
-        Ext.Slider.superclass.onRender.apply(this, arguments);
-        this.endEl = this.el.first();
+
+        Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
+
+        this.endEl   = this.el.first();
         this.innerEl = this.endEl.first();
-        this.thumb = this.innerEl.first();
-        this.halfThumb = (this.vertical ? this.thumb.getHeight() : this.thumb.getWidth())/2;
-        this.focusEl = this.thumb.next();
+        this.focusEl = this.innerEl.child('.x-slider-focus');
+
+        
+        for (var i=0; i < this.thumbs.length; i++) {
+            this.thumbs[i].render();
+        }
+
+        
+        var thumb      = this.innerEl.child('.x-slider-thumb');
+        this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
+
         this.initEvents();
     },
 
-       
+    
     initEvents : function(){
-        this.thumb.addClassOnOver('x-slider-thumb-over');
         this.mon(this.el, {
-            scope: this,
+            scope    : this,
             mousedown: this.onMouseDown,
-            keydown: this.onKeyDown
+            keydown  : this.onKeyDown
         });
 
         this.focusEl.swallowEvent("click", true);
-
-        this.tracker = new Ext.dd.DragTracker({
-            onBeforeStart: this.onBeforeDragStart.createDelegate(this),
-            onStart: this.onDragStart.createDelegate(this),
-            onDrag: this.onDrag.createDelegate(this),
-            onEnd: this.onDragEnd.createDelegate(this),
-            tolerance: 3,
-            autoStart: 300
-        });
-        this.tracker.initEl(this.thumb);
     },
 
-       
+    
     onMouseDown : function(e){
         if(this.disabled){
             return;
         }
-        if(this.clickToChange && e.target != this.thumb.dom){
+
+        
+        var thumbClicked = false;
+        for (var i=0; i < this.thumbs.length; i++) {
+            thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
+        }
+
+        if (this.clickToChange && !thumbClicked) {
             var local = this.innerEl.translatePoints(e.getXY());
             this.onClickChange(local);
         }
         this.focus();
     },
 
-       
-    onClickChange : function(local){
-        if(local.top > this.clickRange[0] && local.top < this.clickRange[1]){
-            this.setValue(Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
+    
+    onClickChange : function(local) {
+        if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
+            
+            var thumb = this.getNearest(local, 'left'),
+                index = thumb.index;
+
+            this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
         }
     },
 
-       
+    
+    getNearest: function(local, prop) {
+        var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
+            clickValue = this.reverseValue(localValue),
+            nearestDistance = (this.maxValue - this.minValue) + 5, 
+            index = 0,
+            nearest = null;
+
+        for (var i=0; i < this.thumbs.length; i++) {
+            var thumb = this.thumbs[i],
+                value = thumb.value,
+                dist  = Math.abs(value - clickValue);
+
+            if (Math.abs(dist <= nearestDistance)) {
+                nearest = thumb;
+                index = i;
+                nearestDistance = dist;
+            }
+        }
+        return nearest;
+    },
+
+    
     onKeyDown : function(e){
-        if(this.disabled){e.preventDefault();return;}
-        var k = e.getKey();
+        
+        if(this.disabled || this.thumbs.length !== 1){
+            e.preventDefault();
+            return;
+        }
+        var k = e.getKey(),
+            val;
         switch(k){
             case e.UP:
             case e.RIGHT:
                 e.stopEvent();
-                if(e.ctrlKey){
-                    this.setValue(this.maxValue, undefined, true);
-                }else{
-                    this.setValue(this.value+this.keyIncrement, undefined, true);
-                }
+                val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
+                this.setValue(0, val, undefined, true);
             break;
             case e.DOWN:
             case e.LEFT:
                 e.stopEvent();
-                if(e.ctrlKey){
-                    this.setValue(this.minValue, undefined, true);
-                }else{
-                    this.setValue(this.value-this.keyIncrement, undefined, true);
-                }
+                val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
+                this.setValue(0, val, undefined, true);
             break;
             default:
                 e.preventDefault();
         }
     },
 
-       
+    
     doSnap : function(value){
-        if(!(this.increment && value)){
+        if (!(this.increment && value)) {
             return value;
         }
-        var newValue = value, 
+        var newValue = value,
             inc = this.increment,
             m = value % inc;
-        if(m != 0){
+        if (m != 0) {
             newValue -= m;
-            if(m * 2 > inc){
+            if (m * 2 >= inc) {
                 newValue += inc;
-            }else if(m * 2 < -inc){
+            } else if (m * 2 < -inc) {
                 newValue -= inc;
             }
         }
         return newValue.constrain(this.minValue,  this.maxValue);
     },
 
-       
+    
     afterRender : function(){
-        Ext.Slider.superclass.afterRender.apply(this, arguments);
-        if(this.value !== undefined){
-            var v = this.normalizeValue(this.value);
-            if(v !== this.value){
-                delete this.value;
-                this.setValue(v, false);
-            }else{
-                this.moveThumb(this.translateValue(v), false);
+        Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
+
+        for (var i=0; i < this.thumbs.length; i++) {
+            var thumb = this.thumbs[i];
+
+            if (thumb.value !== undefined) {
+                var v = this.normalizeValue(thumb.value);
+
+                if (v !== thumb.value) {
+                    
+                    this.setValue(i, v, false);
+                } else {
+                    this.moveThumb(i, this.translateValue(v), false);
+                }
             }
-        }
+        };
     },
 
-       
+    
     getRatio : function(){
         var w = this.innerEl.getWidth(),
             v = this.maxValue - this.minValue;
         return v == 0 ? w : (w/v);
     },
 
-       
+    
     normalizeValue : function(v){
         v = this.doSnap(v);
         v = Ext.util.Format.round(v, this.decimalPrecision);
@@ -16017,133 +19389,240 @@ Ext.Slider = Ext.extend(Ext.BoxComponent, {
         return v;
     },
 
-       
-    setValue : function(v, animate, changeComplete){
+    
+    setMinValue : function(val){
+        this.minValue = val;
+        var i = 0,
+            thumbs = this.thumbs,
+            len = thumbs.length,
+            t;
+            
+        for(; i < len; ++i){
+            t = thumbs[i];
+            t.value = t.value < val ? val : t.value;
+        }
+        this.syncThumb();
+    },
+
+    
+    setMaxValue : function(val){
+        this.maxValue = val;
+        var i = 0,
+            thumbs = this.thumbs,
+            len = thumbs.length,
+            t;
+            
+        for(; i < len; ++i){
+            t = thumbs[i];
+            t.value = t.value > val ? val : t.value;
+        }
+        this.syncThumb();
+    },
+
+    
+    setValue : function(index, v, animate, changeComplete) {
+        var thumb = this.thumbs[index],
+            el    = thumb.el;
+
         v = this.normalizeValue(v);
-        if(v !== this.value && this.fireEvent('beforechange', this, v, this.value) !== false){
-            this.value = v;
-            this.moveThumb(this.translateValue(v), animate !== false);
-            this.fireEvent('change', this, v);
-            if(changeComplete){
-                this.fireEvent('changecomplete', this, v);
+
+        if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
+            thumb.value = v;
+            if(this.rendered){
+                this.moveThumb(index, this.translateValue(v), animate !== false);
+                this.fireEvent('change', this, v, thumb);
+                if(changeComplete){
+                    this.fireEvent('changecomplete', this, v, thumb);
+                }
             }
         }
     },
 
-       
-    translateValue : function(v){
+    
+    translateValue : function(v) {
         var ratio = this.getRatio();
         return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
     },
 
-       reverseValue : function(pos){
+    
+    reverseValue : function(pos){
         var ratio = this.getRatio();
-        return (pos + this.halfThumb + (this.minValue * ratio)) / ratio;
+        return (pos + (this.minValue * ratio)) / ratio;
     },
 
-       
-    moveThumb: function(v, animate){
+    
+    moveThumb: function(index, v, animate){
+        var thumb = this.thumbs[index].el;
+
         if(!animate || this.animate === false){
-            this.thumb.setLeft(v);
+            thumb.setLeft(v);
         }else{
-            this.thumb.shift({left: v, stopFx: true, duration:.35});
+            thumb.shift({left: v, stopFx: true, duration:.35});
         }
     },
 
-       
+    
     focus : function(){
         this.focusEl.focus(10);
     },
 
-       
-    onBeforeDragStart : function(e){
-        return !this.disabled;
+    
+    onResize : function(w, h){
+        var thumbs = this.thumbs,
+            len = thumbs.length,
+            i = 0;
+            
+        
+        for(; i < len; ++i){
+            thumbs[i].el.stopFx();    
+        }
+        
+        if(Ext.isNumber(w)){
+            this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
+        }
+        this.syncThumb();
+        Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
     },
 
-       
-    onDragStart: function(e){
-        this.thumb.addClass('x-slider-thumb-drag');
-        this.dragging = true;
-        this.dragStartValue = this.value;
-        this.fireEvent('dragstart', this, e);
-    },
+    
+    onDisable: function(){
+        Ext.slider.MultiSlider.superclass.onDisable.call(this);
 
-       
-    onDrag: function(e){
-        var pos = this.innerEl.translatePoints(this.tracker.getXY());
-        this.setValue(Ext.util.Format.round(this.reverseValue(pos.left), this.decimalPrecision), false);
-        this.fireEvent('drag', this, e);
-    },
+        for (var i=0; i < this.thumbs.length; i++) {
+            var thumb = this.thumbs[i],
+                el    = thumb.el;
 
-       
-    onDragEnd: function(e){
-        this.thumb.removeClass('x-slider-thumb-drag');
-        this.dragging = false;
-        this.fireEvent('dragend', this, e);
-        if(this.dragStartValue != this.value){
-            this.fireEvent('changecomplete', this, this.value);
+            thumb.disable();
+
+            if(Ext.isIE){
+                
+                
+                var xy = el.getXY();
+                el.hide();
+
+                this.innerEl.addClass(this.disabledClass).dom.disabled = true;
+
+                if (!this.thumbHolder) {
+                    this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
+                }
+
+                this.thumbHolder.show().setXY(xy);
+            }
         }
     },
 
-       
-    onResize : function(w, h){
-        this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
-        this.syncThumb();
-    },
     
+    onEnable: function(){
+        Ext.slider.MultiSlider.superclass.onEnable.call(this);
+
+        for (var i=0; i < this.thumbs.length; i++) {
+            var thumb = this.thumbs[i],
+                el    = thumb.el;
+
+            thumb.enable();
+
+            if (Ext.isIE) {
+                this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
+
+                if (this.thumbHolder) this.thumbHolder.hide();
+
+                el.show();
+                this.syncThumb();
+            }
+        }
+    },
+
     
-    onDisable: function(){
-        Ext.Slider.superclass.onDisable.call(this);
-        this.thumb.addClass(this.disabledClass);
-        if(Ext.isIE){
-            
-            
-            var xy = this.thumb.getXY();
-            this.thumb.hide();
-            this.innerEl.addClass(this.disabledClass).dom.disabled = true;
-            if (!this.thumbHolder){
-                this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});    
+    syncThumb : function() {
+        if (this.rendered) {
+            for (var i=0; i < this.thumbs.length; i++) {
+                this.moveThumb(i, this.translateValue(this.thumbs[i].value));
             }
-            this.thumbHolder.show().setXY(xy);
         }
     },
+
     
+    getValue : function(index) {
+        return this.thumbs[index].value;
+    },
+
     
-    onEnable: function(){
-        Ext.Slider.superclass.onEnable.call(this);
-        this.thumb.removeClass(this.disabledClass);
-        if(Ext.isIE){
-            this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
-            if(this.thumbHolder){
-                this.thumbHolder.hide();
-            }
-            this.thumb.show();
-            this.syncThumb();
+    getValues: function() {
+        var values = [];
+
+        for (var i=0; i < this.thumbs.length; i++) {
+            values.push(this.thumbs[i].value);
+        }
+
+        return values;
+    },
+
+    
+    beforeDestroy : function(){
+        var thumbs = this.thumbs;
+        for(var i = 0, len = thumbs.length; i < len; ++i){
+            thumbs[i].destroy();
+            thumbs[i] = null;
         }
+        Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
+        Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
+    }
+});
+
+Ext.reg('multislider', Ext.slider.MultiSlider);
+
+
+Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
+    constructor: function(config) {
+      config = config || {};
+
+      Ext.applyIf(config, {
+          values: [config.value || 0]
+      });
+
+      Ext.slider.SingleSlider.superclass.constructor.call(this, config);
     },
+
     
+    getValue: function() {
+        
+        return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
+    },
+
     
-    syncThumb : function(){
-        if(this.rendered){
-            this.moveThumb(this.translateValue(this.value));
+    setValue: function(value, animate) {
+        var args = Ext.toArray(arguments),
+            len  = args.length;
+
+        
+        
+        
+        if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
+            args.unshift(0);
         }
+
+        return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
     },
 
-       
-    getValue : function(){
-        return this.value;
+    
+    syncThumb : function() {
+        return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
     },
     
     
-    beforeDestroy : function(){
-        Ext.destroyMembers(this, 'endEl', 'innerEl', 'thumb', 'halfThumb', 'focusEl', 'tracker', 'thumbHolder');
-        Ext.Slider.superclass.beforeDestroy.call(this);
+    getNearest : function(){
+        
+        return this.thumbs[0];    
     }
 });
-Ext.reg('slider', Ext.Slider);
 
 
-Ext.Slider.Vertical = {
+Ext.Slider = Ext.slider.SingleSlider;
+
+Ext.reg('slider', Ext.slider.SingleSlider);
+
+
+Ext.slider.Vertical = {
     onResize : function(w, h){
         this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
         this.syncThumb();
@@ -16155,28 +19634,40 @@ Ext.Slider.Vertical = {
         return h/v;
     },
 
-    moveThumb: function(v, animate){
-        if(!animate || this.animate === false){
-            this.thumb.setBottom(v);
-        }else{
-            this.thumb.shift({bottom: v, stopFx: true, duration:.35});
+    moveThumb: function(index, v, animate) {
+        var thumb = this.thumbs[index],
+            el    = thumb.el;
+
+        if (!animate || this.animate === false) {
+            el.setBottom(v);
+        } else {
+            el.shift({bottom: v, stopFx: true, duration:.35});
         }
     },
 
-    onDrag: function(e){
-        var pos = this.innerEl.translatePoints(this.tracker.getXY()),
-            bottom = this.innerEl.getHeight()-pos.top;
-        this.setValue(this.minValue + Ext.util.Format.round(bottom/this.getRatio(), this.decimalPrecision), false);
-        this.fireEvent('drag', this, e);
-    },
+    onClickChange : function(local) {
+        if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
+            var thumb = this.getNearest(local, 'top'),
+                index = thumb.index,
+                value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
 
-    onClickChange : function(local){
-        if(local.left > this.clickRange[0] && local.left < this.clickRange[1]){
-            var bottom = this.innerEl.getHeight() - local.top;
-            this.setValue(this.minValue + Ext.util.Format.round(bottom/this.getRatio(), this.decimalPrecision), undefined, true);
+            this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
         }
     }
 };
+
+
+Ext.slider.Thumb.Vertical = {
+    getNewValue: function() {
+        var slider   = this.slider,
+            innerEl  = slider.innerEl,
+            pos      = innerEl.translatePoints(this.tracker.getXY()),
+            bottom   = innerEl.getHeight() - pos.top;
+
+        return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
+    }
+};
+
 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
    
     baseCls : 'x-progress',
@@ -16214,8 +19705,8 @@ Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
         );
 
         this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
-               : tpl.append(ct, {cls: this.baseCls}, true);
-                       
+            : tpl.append(ct, {cls: this.baseCls}, true);
+                
         if(this.id){
             this.el.dom.id = this.id;
         }
@@ -16253,7 +19744,7 @@ Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
         if(text){
             this.updateText(text);
         }
-        if(this.rendered){
+        if(this.rendered && !this.isDestroyed){
             var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
             this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
             if(this.textTopEl){
@@ -16330,18 +19821,24 @@ Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
         if(this.textTopEl){
             this.textTopEl.addClass('x-hidden');
         }
+        this.clearTimer();
+        if(hide === true){
+            this.hide();
+        }
+        return this;
+    },
+    
+    
+    clearTimer : function(){
         if(this.waitTimer){
             this.waitTimer.onStop = null; 
             Ext.TaskMgr.stop(this.waitTimer);
             this.waitTimer = null;
         }
-        if(hide === true){
-            this.hide();
-        }
-        return this;
     },
     
     onDestroy: function(){
+        this.clearTimer();
         if(this.rendered){
             if(this.textEl.isComposite){
                 this.textEl.clear();
@@ -16403,13 +19900,17 @@ Ext.dd.DragDrop.prototype = {
     locked: false,
 
     
-    lock: function() { this.locked = true; },
+    lock: function() {
+        this.locked = true;
+    },
 
     
     moveOnly: false,
 
     
-    unlock: function() { this.locked = false; },
+    unlock: function() {
+        this.locked = false;
+    },
 
     
     isTarget: true,
@@ -16661,7 +20162,6 @@ Ext.dd.DragDrop.prototype = {
         this.lastPageX = p[0];
         this.lastPageY = p[1];
 
-
         this.setStartPosition(p);
     },
 
@@ -16752,7 +20252,6 @@ Ext.dd.DragDrop.prototype = {
                 
                 this.setStartPosition();
 
-
                 this.b4MouseDown(e);
                 this.onMouseDown(e);
 
@@ -16929,8 +20428,6 @@ Ext.dd.DragDrop.prototype = {
 
     
     resetConstraints: function() {
-
-
         
         if (this.initPageX || this.initPageX === 0) {
             
@@ -16959,7 +20456,6 @@ Ext.dd.DragDrop.prototype = {
 
     
     getTick: function(val, tickArray) {
-
         if (!tickArray) {
             
             
@@ -17213,7 +20709,7 @@ Ext.dd.DragDropMgr = function() {
         
         handleMouseDown: function(e, oDD) {
             if(Ext.QuickTips){
-                Ext.QuickTips.disable();
+                Ext.QuickTips.ddDisable();
             }
             if(this.dragCurrent){
                 
@@ -17257,7 +20753,7 @@ Ext.dd.DragDropMgr = function() {
         handleMouseUp: function(e) {
 
             if(Ext.QuickTips){
-                Ext.QuickTips.enable();
+                Ext.QuickTips.ddEnable();
             }
             if (! this.dragCurrent) {
                 return;
@@ -17732,10 +21228,14 @@ Ext.dd.DragDropMgr = function() {
         },
 
         
-        getScrollTop: function () { return this.getScroll().top; },
+        getScrollTop: function () {
+            return this.getScroll().top;
+        },
 
         
-        getScrollLeft: function () { return this.getScroll().left; },
+        getScrollLeft: function () {
+            return this.getScroll().left;
+        },
 
         
         moveToEl: function (moveEl, targetEl) {
@@ -17744,7 +21244,9 @@ Ext.dd.DragDropMgr = function() {
         },
 
         
-        numericSort: function(a, b) { return (a - b); },
+        numericSort: function(a, b) {
+            return (a - b);
+        },
 
         
         _timeoutCount: 0,
@@ -17928,8 +21430,6 @@ Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
 
     
     getTargetCoord: function(iPageX, iPageY) {
-
-
         var x = iPageX - this.deltaX;
         var y = iPageY - this.deltaY;
 
@@ -18189,7 +21689,7 @@ Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
         return ("DDTarget " + this.id);
     }
 });
-Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
+Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {    
        
     active: false,
        
@@ -18230,6 +21730,7 @@ Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
 
     destroy : function(){
         this.el.un('mousedown', this.onMouseDown, this);
+        delete this.el;
     },
 
     onMouseDown: function(e, target){
@@ -18239,12 +21740,14 @@ Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
             if(this.preventDefault !== false){
                 e.preventDefault();
             }
-            var doc = Ext.getDoc();
-            doc.on('mouseup', this.onMouseUp, this);
-            doc.on('mousemove', this.onMouseMove, this);
-            doc.on('selectstart', this.stopSelect, this);
+            Ext.getDoc().on({
+                scope: this,
+                mouseup: this.onMouseUp,
+                mousemove: this.onMouseMove,
+                selectstart: this.stopSelect
+            });
             if(this.autoStart){
-                this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
+                this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
             }
         }
     },
@@ -18262,7 +21765,7 @@ Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
         this.lastXY = xy;
         if(!this.active){
             if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
-                this.triggerStart();
+                this.triggerStart(e);
             }else{
                 return;
             }
@@ -18272,14 +21775,15 @@ Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
         this.fireEvent('drag', this, e);
     },
 
-    onMouseUp: function(e){
-        var doc = Ext.getDoc();
+    onMouseUp: function(e) {
+        var doc = Ext.getDoc(),
+            wasActive = this.active;
+            
         doc.un('mousemove', this.onMouseMove, this);
         doc.un('mouseup', this.onMouseUp, this);
         doc.un('selectstart', this.stopSelect, this);
         e.preventDefault();
         this.clearStart();
-        var wasActive = this.active;
         this.active = false;
         delete this.elRegion;
         this.fireEvent('mouseup', this, e);
@@ -18289,41 +21793,46 @@ Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
         }
     },
 
-    triggerStart: function(isTimer){
+    triggerStart: function(e) {
         this.clearStart();
         this.active = true;
-        this.onStart(this.startXY);
-        this.fireEvent('dragstart', this, this.startXY);
+        this.onStart(e);
+        this.fireEvent('dragstart', this, e);
     },
 
-    clearStart : function(){
+    clearStart : function() {
         if(this.timer){
             clearTimeout(this.timer);
             delete this.timer;
         }
     },
 
-    stopSelect : function(e){
+    stopSelect : function(e) {
         e.stopEvent();
         return false;
     },
-
-    onBeforeStart : function(e){
+    
+    
+    onBeforeStart : function(e) {
 
     },
 
-    onStart : function(xy){
+    
+    onStart : function(xy) {
 
     },
 
-    onDrag : function(e){
+    
+    onDrag : function(e) {
 
     },
 
-    onEnd : function(e){
+    
+    onEnd : function(e) {
 
     },
 
+    
     getDragTarget : function(){
         return this.dragTarget;
     },
@@ -18338,8 +21847,8 @@ Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {
     },
 
     getOffset : function(constrain){
-        var xy = this.getXY(constrain);
-        var s = this.startXY;
+        var xy = this.getXY(constrain),
+            s = this.startXY;
         return [s[0]-xy[0], s[1]-xy[1]];
     },
 
@@ -18403,14 +21912,19 @@ Ext.dd.ScrollManager = function(){
         proc.el = null;
         proc.dir = "";
     };
-    
+
     var startProc = function(el, dir){
         clearProc();
         proc.el = el;
         proc.dir = dir;
-        var freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ? 
-                el.ddScrollConfig.frequency : Ext.dd.ScrollManager.frequency;
-        proc.id = setInterval(doScroll, freq);
+        var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined,
+            freq  = (el.ddScrollConfig && el.ddScrollConfig.frequency)
+                  ? el.ddScrollConfig.frequency
+                  : Ext.dd.ScrollManager.frequency;
+
+        if (group === undefined || ddm.dragCurrent.ddGroup == group) {
+            proc.id = setInterval(doScroll, freq);
+        }
     };
     
     var onFire = function(e, isDrop){
@@ -18500,6 +22014,9 @@ Ext.dd.ScrollManager = function(){
         animDuration: .4,
         
         
+        ddGroup: undefined,
+        
+        
         refreshCache : function(){
             for(var id in els){
                 if(typeof els[id] == 'object'){ 
@@ -18965,21 +22482,21 @@ Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
         Ext.destroy(this.proxy);
     }
 });
-Ext.dd.DropTarget = function(el, config){
-    this.el = Ext.get(el);
+Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {
     
-    Ext.apply(this, config);
+    constructor : function(el, config){
+        this.el = Ext.get(el);
     
-    if(this.containerScroll){
-        Ext.dd.ScrollManager.register(this.el);
-    }
+        Ext.apply(this, config);
+    
+        if(this.containerScroll){
+            Ext.dd.ScrollManager.register(this.el);
+        }
+    
+        Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, 
+              {isTarget: true});        
+    },
     
-    Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, 
-          {isTarget: true});
-
-};
-
-Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
     
     
     
@@ -19016,16 +22533,24 @@ Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
     
     notifyDrop : function(dd, e, data){
         return false;
+    },
+    
+    destroy : function(){
+        Ext.dd.DropTarget.superclass.destroy.call(this);
+        if(this.containerScroll){
+            Ext.dd.ScrollManager.unregister(this.el);
+        }
     }
 });
-Ext.dd.DragZone = function(el, config){
-    Ext.dd.DragZone.superclass.constructor.call(this, el, config);
-    if(this.containerScroll){
-        Ext.dd.ScrollManager.register(this.el);
-    }
-};
-
-Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
+Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {
+    
+    constructor : function(el, config){
+        Ext.dd.DragZone.superclass.constructor.call(this, el, config);
+        if(this.containerScroll){
+            Ext.dd.ScrollManager.register(this.el);
+        }
+    },
+    
     
     
     
@@ -19053,6 +22578,13 @@ Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
     
     getRepairXY : function(e){
         return Ext.Element.fly(this.dragData.ddel).getXY();  
+    },
+    
+    destroy : function(){
+        Ext.dd.DragZone.superclass.destroy.call(this);
+        if(this.containerScroll){
+            Ext.dd.ScrollManager.unregister(this.el);
+        }
     }
 });
 Ext.dd.DropZone = function(el, config){
@@ -19254,7 +22786,8 @@ Ext.data.Api = (function() {
         restify : function(proxy) {
             proxy.restful = true;
             for (var verb in this.restActions) {
-                proxy.api[this.actions[verb]].method = this.restActions[verb];
+                proxy.api[this.actions[verb]].method ||
+                    (proxy.api[this.actions[verb]].method = this.restActions[verb]);
             }
             
             
@@ -19270,7 +22803,12 @@ Ext.data.Api = (function() {
                         return true;
                         break;
                     case 201:   
-                        res.success = true;
+                        if (Ext.isEmpty(res.raw.responseText)) {
+                          res.success = true;
+                        } else {
+                          
+                          return true;
+                        }
                         break;
                     case 204:  
                         res.success = true;
@@ -19313,7 +22851,7 @@ Ext.data.Response.prototype = {
         return this.success;
     },
     getStatus : function() {
-        return this.status
+        return this.status;
     },
     getRoot : function() {
         return this.root;
@@ -19467,7 +23005,7 @@ Ext.data.Record.prototype = {
 
     
     afterEdit : function(){
-        if(this.store){
+        if (this.store != undefined && typeof this.store.afterEdit == "function") {
             this.store.afterEdit(this);
         }
     },
@@ -19673,16 +23211,22 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
         dir : 'dir'
     },
 
+    isDestroyed: false,    
+    hasMultiSort: false,
+
     
     batchKey : '_ext_batch_',
 
     constructor : function(config){
+        
+        
+        
+        
         this.data = new Ext.util.MixedCollection(false);
         this.data.getKey = function(o){
             return o.id;
         };
         
-        this.baseParams = {};
 
         
         this.removed = [];
@@ -19694,6 +23238,9 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
 
         Ext.apply(this, config);
 
+        
+        this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
+
         this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
 
         if((this.url || this.api) && !this.proxy){
@@ -19809,8 +23356,8 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
 
     
     buildWriter : function(config) {
-        var klass = undefined;
-        type = (config.format || 'json').toLowerCase();
+        var klass = undefined,
+            type = (config.format || 'json').toLowerCase();
         switch (type) {
             case 'json':
                 klass = Ext.data.JsonWriter;
@@ -19840,19 +23387,31 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     },
 
     
-    add : function(records){
+    add : function(records) {
+        var i, len, record, index;
+        
         records = [].concat(records);
-        if(records.length < 1){
+        if (records.length < 1) {
             return;
         }
-        for(var i = 0, len = records.length; i < len; i++){
-            records[i].join(this);
+        
+        for (i = 0, len = records.length; i < len; i++) {
+            record = records[i];
+            
+            record.join(this);
+            
+            if (record.dirty || record.phantom) {
+                this.modified.push(record);
+            }
         }
-        var index = this.data.length;
+        
+        index = this.data.length;
         this.data.addAll(records);
-        if(this.snapshot){
+        
+        if (this.snapshot) {
             this.snapshot.addAll(records);
         }
+        
         this.fireEvent('add', this, records, index);
     },
 
@@ -19861,6 +23420,15 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
         var index = this.findInsertIndex(record);
         this.insert(index, record);
     },
+    
+    
+    doUpdate : function(rec){
+        this.data.replace(rec.id, rec);
+        if(this.snapshot){
+            this.snapshot.replace(rec.id, rec);
+        }
+        this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
+    },
 
     
     remove : function(record){
@@ -19868,6 +23436,7 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
             Ext.each(record, function(r){
                 this.remove(r);
             }, this);
+            return;
         }
         var index = this.data.indexOf(record);
         if(index > -1){
@@ -19916,15 +23485,25 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     },
 
     
-    insert : function(index, records){
+    insert : function(index, records) {
+        var i, len, record;
+        
         records = [].concat(records);
-        for(var i = 0, len = records.length; i < len; i++){
-            this.data.insert(index, records[i]);
-            records[i].join(this);
+        for (i = 0, len = records.length; i < len; i++) {
+            record = records[i];
+            
+            this.data.insert(index + i, record);
+            record.join(this);
+            
+            if (record.dirty || record.phantom) {
+                this.modified.push(record);
+            }
         }
-        if(this.snapshot){
+        
+        if (this.snapshot) {
             this.snapshot.addAll(records);
         }
+        
         this.fireEvent('add', this, records, index);
     },
 
@@ -19971,11 +23550,11 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
 
     
     load : function(options) {
-        options = options || {};
+        options = Ext.apply({}, options);
         this.storeOptions(options);
         if(this.sortInfo && this.remoteSort){
             var pn = this.paramNames;
-            options.params = options.params || {};
+            options.params = Ext.apply({}, options.params);
             options.params[pn.sort] = this.sortInfo.field;
             options.params[pn.dir] = this.sortInfo.direction;
         }
@@ -19995,11 +23574,20 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     },
 
     
-    createRecords : function(store, rs, index) {
-        for (var i = 0, len = rs.length; i < len; i++) {
-            if (rs[i].phantom && rs[i].isValid()) {
-                rs[i].markDirty();  
-                this.modified.push(rs[i]);  
+    createRecords : function(store, records, index) {
+        var modified = this.modified,
+            length   = records.length,
+            record, i;
+        
+        for (i = 0; i < length; i++) {
+            record = records[i];
+            
+            if (record.phantom && record.isValid()) {
+                record.markDirty();  
+                
+                if (modified.indexOf(record) == -1) {
+                    modified.push(record);
+                }
             }
         }
         if (this.autoSave === true) {
@@ -20044,8 +23632,8 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
         var doRequest = true;
 
         if (action === 'read') {
-            Ext.applyIf(options.params, this.baseParams);
             doRequest = this.fireEvent('beforeload', this, options);
+            Ext.applyIf(options.params, this.baseParams);
         }
         else {
             
@@ -20087,7 +23675,8 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
             len,
             trans,
             batch,
-            data = {};
+            data = {},
+            i;
         
         if(this.removed.length){
             queue.push(['destroy', this.removed]);
@@ -20098,7 +23687,7 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
         if(rs.length){
             
             var phantoms = [];
-            for(var i = rs.length-1; i >= 0; i--){
+            for(i = rs.length-1; i >= 0; i--){
                 if(rs[i].phantom === true){
                     var rec = rs.splice(i, 1).shift();
                     if(rec.isValid()){
@@ -20121,12 +23710,12 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
         len = queue.length;
         if(len){
             batch = ++this.batchCounter;
-            for(var i = 0; i < len; ++i){
+            for(i = 0; i < len; ++i){
                 trans = queue[i];
                 data[trans[0]] = trans[1];
             }
             if(this.fireEvent('beforesave', this, data) !== false){
-                for(var i = 0; i < len; ++i){
+                for(i = 0; i < len; ++i){
                     trans = queue[i];
                     this.doTransaction(trans[0], trans[1], batch);
                 }
@@ -20165,7 +23754,7 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
                 id: batch,
                 count: 0,
                 data: {}
-            }
+            };
         }
         ++o.count;
     },
@@ -20174,7 +23763,6 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
         var b = this.batches,
             key = this.batchKey + batch,
             o = b[key],
-            data,
             arr;
 
 
@@ -20296,6 +23884,8 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     
     
     loadRecords : function(o, options, success){
+        var i, len;
+        
         if (this.isDestroyed === true) {
             return;
         }
@@ -20313,7 +23903,7 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
             if(this.pruneModifiedRecords){
                 this.modified = [];
             }
-            for(var i = 0, len = r.length; i < len; i++){
+            for(i = 0, len = r.length; i < len; i++){
                 r[i].join(this);
             }
             if(this.snapshot){
@@ -20326,8 +23916,20 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
             this.applySort();
             this.fireEvent('datachanged', this);
         }else{
-            this.totalLength = Math.max(t, this.data.length+r.length);
-            this.add(r);
+            var toAdd = [],
+                rec,
+                cnt = 0;
+            for(i = 0, len = r.length; i < len; ++i){
+                rec = r[i];
+                if(this.indexOfId(rec.id) > -1){
+                    this.doUpdate(rec);
+                }else{
+                    toAdd.push(rec);
+                    ++cnt;
+                }
+            }
+            this.totalLength = Math.max(t, this.data.length + cnt);
+            this.add(toAdd);
         }
         this.fireEvent('load', this, r, options);
         if(options.callback){
@@ -20358,63 +23960,151 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
 
     
     applySort : function(){
-        if(this.sortInfo && !this.remoteSort){
-            var s = this.sortInfo, f = s.field;
-            this.sortData(f, s.direction);
+        if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
+            this.sortData();
         }
     },
 
     
-    sortData : function(f, direction){
-        direction = direction || 'ASC';
-        var st = this.fields.get(f).sortType;
-        var fn = function(r1, r2){
-            var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
-            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+    sortData : function() {
+        var sortInfo  = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
+            direction = sortInfo.direction || "ASC",
+            sorters   = sortInfo.sorters,
+            sortFns   = [];
+
+        
+        if (!this.hasMultiSort) {
+            sorters = [{direction: direction, field: sortInfo.field}];
+        }
+
+        
+        for (var i=0, j = sorters.length; i < j; i++) {
+            sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
+        }
+        
+        if (sortFns.length == 0) {
+            return;
+        }
+
+        
+        
+        var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
+
+        
+        var fn = function(r1, r2) {
+          var result = sortFns[0].call(this, r1, r2);
+
+          
+          if (sortFns.length > 1) {
+              for (var i=1, j = sortFns.length; i < j; i++) {
+                  result = result || sortFns[i].call(this, r1, r2);
+              }
+          }
+
+          return directionModifier * result;
         };
+
+        
         this.data.sort(direction, fn);
-        if(this.snapshot && this.snapshot != this.data){
+        if (this.snapshot && this.snapshot != this.data) {
             this.snapshot.sort(direction, fn);
         }
     },
 
     
-    setDefaultSort : function(field, dir){
+    createSortFunction: function(field, direction) {
+        direction = direction || "ASC";
+        var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
+
+        var sortType = this.fields.get(field).sortType;
+
+        
+        
+        return function(r1, r2) {
+            var v1 = sortType(r1.data[field]),
+                v2 = sortType(r2.data[field]);
+
+            return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
+        };
+    },
+
+    
+    setDefaultSort : function(field, dir) {
         dir = dir ? dir.toUpperCase() : 'ASC';
         this.sortInfo = {field: field, direction: dir};
         this.sortToggle[field] = dir;
     },
 
     
-    sort : function(fieldName, dir){
-        var f = this.fields.get(fieldName);
-        if(!f){
+    sort : function(fieldName, dir) {
+        if (Ext.isArray(arguments[0])) {
+            return this.multiSort.call(this, fieldName, dir);
+        } else {
+            return this.singleSort(fieldName, dir);
+        }
+    },
+
+    
+    singleSort: function(fieldName, dir) {
+        var field = this.fields.get(fieldName);
+        if (!field) {
             return false;
         }
-        if(!dir){
-            if(this.sortInfo && this.sortInfo.field == f.name){ 
-                dir = (this.sortToggle[f.name] || 'ASC').toggle('ASC', 'DESC');
-            }else{
-                dir = f.sortDir;
+
+        var name       = field.name,
+            sortInfo   = this.sortInfo || null,
+            sortToggle = this.sortToggle ? this.sortToggle[name] : null;
+
+        if (!dir) {
+            if (sortInfo && sortInfo.field == name) { 
+                dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
+            } else {
+                dir = field.sortDir;
             }
         }
-        var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
-        var si = (this.sortInfo) ? this.sortInfo : null;
 
-        this.sortToggle[f.name] = dir;
-        this.sortInfo = {field: f.name, direction: dir};
-        if(!this.remoteSort){
-            this.applySort();
-            this.fireEvent('datachanged', this);
-        }else{
+        this.sortToggle[name] = dir;
+        this.sortInfo = {field: name, direction: dir};
+        this.hasMultiSort = false;
+
+        if (this.remoteSort) {
             if (!this.load(this.lastOptions)) {
-                if (st) {
-                    this.sortToggle[f.name] = st;
+                if (sortToggle) {
+                    this.sortToggle[name] = sortToggle;
                 }
-                if (si) {
-                    this.sortInfo = si;
+                if (sortInfo) {
+                    this.sortInfo = sortInfo;
                 }
             }
+        } else {
+            this.applySort();
+            this.fireEvent('datachanged', this);
+        }
+        return true;
+    },
+
+    
+    multiSort: function(sorters, direction) {
+        this.hasMultiSort = true;
+        direction = direction || "ASC";
+
+        
+        if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
+            direction = direction.toggle("ASC", "DESC");
+        }
+
+        
+        this.multiSortInfo = {
+            sorters  : sorters,
+            direction: direction
+        };
+        
+        if (this.remoteSort) {
+            this.singleSort(sorters[0].field, sorters[0].direction);
+
+        } else {
+            this.applySort();
+            this.fireEvent('datachanged', this);
         }
     },
 
@@ -20429,17 +24119,6 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     },
 
     
-    createFilterFn : function(property, value, anyMatch, caseSensitive){
-        if(Ext.isEmpty(value, false)){
-            return false;
-        }
-        value = this.data.createValueMatcher(value, anyMatch, caseSensitive);
-        return function(r){
-            return value.test(r.data[property]);
-        };
-    },
-
-    
     sum : function(property, start, end){
         var rs = this.data.items, v = 0;
         start = start || 0;
@@ -20452,19 +24131,91 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     },
 
     
-    filter : function(property, value, anyMatch, caseSensitive){
-        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
+    createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
+        if(Ext.isEmpty(value, false)){
+            return false;
+        }
+        value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
+        return function(r) {
+            return value.test(r.data[property]);
+        };
+    },
+
+    
+    createMultipleFilterFn: function(filters) {
+        return function(record) {
+            var isMatch = true;
+
+            for (var i=0, j = filters.length; i < j; i++) {
+                var filter = filters[i],
+                    fn     = filter.fn,
+                    scope  = filter.scope;
+
+                isMatch = isMatch && fn.call(scope, record);
+            }
+
+            return isMatch;
+        };
+    },
+
+    
+    filter : function(property, value, anyMatch, caseSensitive, exactMatch){
+        var fn;
+        
+        if (Ext.isObject(property)) {
+            property = [property];
+        }
+
+        if (Ext.isArray(property)) {
+            var filters = [];
+
+            
+            for (var i=0, j = property.length; i < j; i++) {
+                var filter = property[i],
+                    func   = filter.fn,
+                    scope  = filter.scope || this;
+
+                
+                if (!Ext.isFunction(func)) {
+                    func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
+                }
+
+                filters.push({fn: func, scope: scope});
+            }
+
+            fn = this.createMultipleFilterFn(filters);
+        } else {
+            
+            fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
+        }
+
         return fn ? this.filterBy(fn) : this.clearFilter();
     },
 
     
     filterBy : function(fn, scope){
         this.snapshot = this.snapshot || this.data;
-        this.data = this.queryBy(fn, scope||this);
+        this.data = this.queryBy(fn, scope || this);
         this.fireEvent('datachanged', this);
     },
 
     
+    clearFilter : function(suppressEvent){
+        if(this.isFiltered()){
+            this.data = this.snapshot;
+            delete this.snapshot;
+            if(suppressEvent !== true){
+                this.fireEvent('datachanged', this);
+            }
+        }
+    },
+
+    
+    isFiltered : function(){
+        return !!this.snapshot && this.snapshot != this.data;
+    },
+
+    
     query : function(property, value, anyMatch, caseSensitive){
         var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
         return fn ? this.queryBy(fn) : this.data.clone();
@@ -20511,22 +24262,6 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
     },
 
     
-    clearFilter : function(suppressEvent){
-        if(this.isFiltered()){
-            this.data = this.snapshot;
-            delete this.snapshot;
-            if(suppressEvent !== true){
-                this.fireEvent('datachanged', this);
-            }
-        }
-    },
-
-    
-    isFiltered : function(){
-        return this.snapshot && this.snapshot != this.data;
-    },
-
-    
     afterEdit : function(record){
         if(this.modified.indexOf(record) == -1){
             this.modified.push(record);
@@ -20548,26 +24283,37 @@ Ext.data.Store = Ext.extend(Ext.util.Observable, {
 
     
     commitChanges : function(){
-        var m = this.modified.slice(0);
-        this.modified = [];
-        for(var i = 0, len = m.length; i < len; i++){
-            m[i].commit();
+        var modified = this.modified.slice(0),
+            length   = modified.length,
+            i;
+            
+        for (i = 0; i < length; i++){
+            modified[i].commit();
         }
+        
+        this.modified = [];
+        this.removed  = [];
     },
 
     
-    rejectChanges : function(){
-        var m = this.modified.slice(0);
-        this.modified = [];
-        for(var i = 0, len = m.length; i < len; i++){
-            m[i].reject();
+    rejectChanges : function() {
+        var modified = this.modified.slice(0),
+            removed  = this.removed.slice(0).reverse(),
+            mLength  = modified.length,
+            rLength  = removed.length,
+            i;
+        
+        for (i = 0; i < mLength; i++) {
+            modified[i].reject();
         }
-        var m = this.removed.slice(0).reverse();
-        this.removed = [];
-        for(var i = 0, len = m.length; i < len; i++){
-            this.insert(m[i].lastIndex||0, m[i]);
-            m[i].reject();
+        
+        for (i = 0; i < rLength; i++) {
+            this.insert(removed[i].lastIndex || 0, removed[i]);
+            removed[i].reject();
         }
+        
+        this.modified = [];
+        this.removed  = [];
     },
 
     
@@ -20618,104 +24364,48 @@ Ext.apply(Ext.data.Store.Error.prototype, {
     }
 });
 
-Ext.data.Field = function(config){
-    if(typeof config == "string"){
-        config = {name: config};
-    }
-    Ext.apply(this, config);
-
-    if(!this.type){
-        this.type = "auto";
-    }
-
-    var st = Ext.data.SortTypes;
-    
-    if(typeof this.sortType == "string"){
-        this.sortType = st[this.sortType];
-    }
-
+Ext.data.Field = Ext.extend(Object, {
     
-    if(!this.sortType){
-        switch(this.type){
-            case "string":
-                this.sortType = st.asUCString;
-                break;
-            case "date":
-                this.sortType = st.asDate;
-                break;
-            default:
-                this.sortType = st.none;
+    constructor : function(config){
+        if(Ext.isString(config)){
+            config = {name: config};
         }
-    }
-
-    
-    var stripRe = /[\$,%]/g;
+        Ext.apply(this, config);
+        
+        var types = Ext.data.Types,
+            st = this.sortType,
+            t;
 
-    
-    
-    if(!this.convert){
-        var cv, dateFormat = this.dateFormat;
-        switch(this.type){
-            case "":
-            case "auto":
-            case undefined:
-                cv = function(v){ return v; };
-                break;
-            case "string":
-                cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };
-                break;
-            case "int":
-                cv = function(v){
-                    return v !== undefined && v !== null && v !== '' ?
-                        parseInt(String(v).replace(stripRe, ""), 10) : '';
-                    };
-                break;
-            case "float":
-                cv = function(v){
-                    return v !== undefined && v !== null && v !== '' ?
-                        parseFloat(String(v).replace(stripRe, ""), 10) : '';
-                    };
-                break;
-            case "bool":
-                cv = function(v){ return v === true || v === "true" || v == 1; };
-                break;
-            case "date":
-                cv = function(v){
-                    if(!v){
-                        return '';
-                    }
-                    if(Ext.isDate(v)){
-                        return v;
-                    }
-                    if(dateFormat){
-                        if(dateFormat == "timestamp"){
-                            return new Date(v*1000);
-                        }
-                        if(dateFormat == "time"){
-                            return new Date(parseInt(v, 10));
-                        }
-                        return Date.parseDate(v, dateFormat);
-                    }
-                    var parsed = Date.parse(v);
-                    return parsed ? new Date(parsed) : null;
-                };
-                break;
-            default:
-                cv = function(v){ return v; };
-                break;
+        if(this.type){
+            if(Ext.isString(this.type)){
+                this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
+            }
+        }else{
+            this.type = types.AUTO;
+        }
 
+        
+        if(Ext.isString(st)){
+            this.sortType = Ext.data.SortTypes[st];
+        }else if(Ext.isEmpty(st)){
+            this.sortType = this.type.sortType;
         }
-        this.convert = cv;
-    }
-};
 
-Ext.data.Field.prototype = {
+        if(!this.convert){
+            this.convert = this.type.convert;
+        }
+    },
+    
     
     
     
     
     dateFormat: null,
     
+    
+    useNull: false,
+    
+    
     defaultValue: "",
     
     mapping: null,
@@ -20725,7 +24415,8 @@ Ext.data.Field.prototype = {
     sortDir : "ASC",
     
     allowBlank : true
-};
+});
+
 Ext.data.DataReader = function(meta, recordType){
     
     this.meta = meta;
@@ -20754,8 +24445,6 @@ Ext.data.DataReader.prototype = {
     
     buildExtractors : Ext.emptyFn,
     
-    extractData : Ext.emptyFn,
-    
     extractValues : Ext.emptyFn,
 
     
@@ -20786,12 +24475,8 @@ Ext.data.DataReader.prototype = {
             rs.phantom = false; 
             rs._phid = rs.id;  
             rs.id = this.getId(data);
+            rs.data = data;
 
-            rs.fields.each(function(f) {
-                if (data[f.name] !== f.defaultValue) {
-                    rs.data[f.name] = data[f.name];
-                }
-            });
             rs.commit();
         }
     },
@@ -20816,11 +24501,7 @@ Ext.data.DataReader.prototype = {
                 data = data.shift();
             }
             if (this.isData(data)) {
-                rs.fields.each(function(f) {
-                    if (data[f.name] !== f.defaultValue) {
-                        rs.data[f.name] = data[f.name];
-                    }
-                });
+                rs.data = Ext.apply(rs.data, data);
             }
             rs.commit();
         }
@@ -20948,7 +24629,7 @@ Ext.data.DataWriter.prototype = {
                 delete data[this.meta.idProperty];
             }
         } else {
-            data[this.meta.idProperty] = rec.id
+            data[this.meta.idProperty] = rec.id;
         }
         return data;
     },
@@ -21440,7 +25121,7 @@ Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
             } else {
                 this.onWrite(action, o, response, rs);
             }
-        }
+        };
     },
 
     
@@ -21485,10 +25166,10 @@ Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
             o.request.callback.call(o.request.scope, null, o.request.arg, false);
             return;
         }
-        if (res.success === false) {
-            this.fireEvent('exception', this, 'remote', action, o, res, rs);
-        } else {
+        if (res.success === true) {
             this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
+        } else {
+            this.fireEvent('exception', this, 'remote', action, o, res, rs);
         }
         
         
@@ -21542,20 +25223,98 @@ Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
         callback.call(scope, result, arg, true);
     }
 });
-Ext.data.JsonWriter = function(config) {
-    Ext.data.JsonWriter.superclass.constructor.call(this, config);
+Ext.data.Types = new function(){
+    var st = Ext.data.SortTypes;
+    Ext.apply(this, {
+        
+        stripRe: /[\$,%]/g,
+        
+        
+        AUTO: {
+            convert: function(v){ return v; },
+            sortType: st.none,
+            type: 'auto'
+        },
 
+        
+        STRING: {
+            convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
+            sortType: st.asUCString,
+            type: 'string'
+        },
+
+        
+        INT: {
+            convert: function(v){
+                return v !== undefined && v !== null && v !== '' ?
+                    parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
+            },
+            sortType: st.none,
+            type: 'int'
+        },
+        
+        
+        FLOAT: {
+            convert: function(v){
+                return v !== undefined && v !== null && v !== '' ?
+                    parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
+            },
+            sortType: st.none,
+            type: 'float'
+        },
+        
+        
+        BOOL: {
+            convert: function(v){ return v === true || v === 'true' || v == 1; },
+            sortType: st.none,
+            type: 'bool'
+        },
+        
+        
+        DATE: {
+            convert: function(v){
+                var df = this.dateFormat;
+                if(!v){
+                    return null;
+                }
+                if(Ext.isDate(v)){
+                    return v;
+                }
+                if(df){
+                    if(df == 'timestamp'){
+                        return new Date(v*1000);
+                    }
+                    if(df == 'time'){
+                        return new Date(parseInt(v, 10));
+                    }
+                    return Date.parseDate(v, df);
+                }
+                var parsed = Date.parse(v);
+                return parsed ? new Date(parsed) : null;
+            },
+            sortType: st.asDate,
+            type: 'date'
+        }
+    });
     
+    Ext.apply(this, {
+        
+        BOOLEAN: this.BOOL,
+        
+        INTEGER: this.INT,
+        
+        NUMBER: this.FLOAT    
+    });
+};
+Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
     
-    if (this.returnJson != undefined) {
-        this.encode = this.returnJson;
-    }
-}
-Ext.extend(Ext.data.JsonWriter, Ext.data.DataWriter, {
+    encode : true,
     
-    returnJson : undefined,
+    encodeDelete: false,
     
-    encode : true,
+    constructor : function(config){
+        Ext.data.JsonWriter.superclass.constructor.call(this, config);    
+    },
 
     
     render : function(params, baseParams, data) {
@@ -21580,8 +25339,14 @@ Ext.extend(Ext.data.JsonWriter, Ext.data.DataWriter, {
 
     },
     
-    destroyRecord : function(rec) {
-        return rec.id;
+    destroyRecord : function(rec){
+        if(this.encodeDelete){
+            var data = {};
+            data[this.meta.idProperty] = rec.id;
+            return data;
+        }else{
+            return rec.id;
+        }
     }
 });
 Ext.data.JsonReader = function(meta, recordType){
@@ -21611,6 +25376,7 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
     },
 
     
+    
     readResponse : function(action, response) {
         var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
         if(!o) {
@@ -21721,14 +25487,20 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
     createAccessor : function(){
         var re = /[\[\.]/;
         return function(expr) {
-            try {
-                return(re.test(expr)) ?
-                new Function('obj', 'return obj.' + expr) :
-                function(obj){
-                    return obj[expr];
-                };
-            } catch(e){}
-            return Ext.emptyFn;
+            if(Ext.isEmpty(expr)){
+                return Ext.emptyFn;
+            }
+            if(Ext.isFunction(expr)){
+                return expr;
+            }
+            var i = String(expr).search(re);
+            if(i >= 0){
+                return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
+            }
+            return function(obj){
+                return obj[expr];
+            };
+
         };
     }(),
 
@@ -21774,6 +25546,7 @@ Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
             recordType = this.recordType,
             fields = recordType.prototype.fields,
             records = [],
+            success = true,
             v;
 
         var root = this.getRoot(o);
@@ -21802,8 +25575,15 @@ Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
                 totalRecords = v;
             }
         }
+        if(s.successProperty){
+            v = this.getSuccess(o);
+            if(v === false || v === 'false'){
+                success = false;
+            }
+        }
 
         return {
+            success : success,
             records : records,
             totalRecords : totalRecords
         };
@@ -21860,7 +25640,8 @@ Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
     xmlEncoding: 'ISO-8859-15',
     
     
-    tpl: '<tpl for="."><' + '?xml version="{version}" encoding="{encoding}"?' + '><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}</tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
+    tpl: '<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}></tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
+
 
     
     render : function(params, baseParams, data) {
@@ -21894,7 +25675,6 @@ Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
     }
 });
 
-
 Ext.data.XmlReader = function(meta, recordType){
     meta = meta || {};
 
@@ -21945,15 +25725,16 @@ Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
 
     
     readResponse : function(action, response) {
-        var q   = Ext.DomQuery,
-        doc     = response.responseXML;
+        var q = Ext.DomQuery,
+            doc = response.responseXML,
+            root = doc.documentElement || doc;
 
         
         var res = new Ext.data.Response({
             action: action,
-            success : this.getSuccess(doc),
-            message: this.getMessage(doc),
-            data: this.extractData(q.select(this.meta.record, doc) || q.select(this.meta.root, doc), false),
+            success : this.getSuccess(root),
+            message: this.getMessage(root),
+            data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
             raw: doc
         });
 
@@ -22000,7 +25781,7 @@ Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
         }
         this.getRoot = function(res) {
             return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
-        }
+        };
         if (s.idPath || s.idProperty) {
             var g = this.createAccessor(s.idPath || s.idProperty);
             this.getId = function(rec) {
@@ -22023,23 +25804,26 @@ Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
     createAccessor : function(){
         var q = Ext.DomQuery;
         return function(key) {
+            if (Ext.isFunction(key)) {
+                return key;
+            }
             switch(key) {
                 case this.meta.totalProperty:
                     return function(root, def){
                         return q.selectNumber(key, root, def);
-                    }
+                    };
                     break;
                 case this.meta.successProperty:
                     return function(root, def) {
                         var sv = q.selectValue(key, root, true);
                         var success = sv !== false && sv !== 'false';
                         return success;
-                    }
+                    };
                     break;
                 default:
                     return function(root, def) {
                         return q.selectValue(key, root, def);
-                    }
+                    };
                     break;
             }
         };
@@ -22066,83 +25850,181 @@ Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
 });
 Ext.reg('xmlstore', Ext.data.XmlStore);
 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
+
     
-    
-    constructor: function(config){
+    constructor: function(config) {
+        config = config || {};
+
+        
+        
+        
+        
+        this.hasMultiSort  = true;
+        this.multiSortInfo = this.multiSortInfo || {sorters: []};
+
+        var sorters    = this.multiSortInfo.sorters,
+            groupField = config.groupField || this.groupField,
+            sortInfo   = config.sortInfo || this.sortInfo,
+            groupDir   = config.groupDir || this.groupDir;
+
+        
+        if(groupField){
+            sorters.push({
+                field    : groupField,
+                direction: groupDir
+            });
+        }
+
+        
+        if (sortInfo) {
+            sorters.push(sortInfo);
+        }
+
         Ext.data.GroupingStore.superclass.constructor.call(this, config);
+
+        this.addEvents(
+          
+          'groupchange'
+        );
+
         this.applyGroupField();
     },
-    
+
     
     
     remoteGroup : false,
     
     groupOnSort:false,
 
-       groupDir : 'ASC',
-       
+    
+    groupDir : 'ASC',
+
     
     clearGrouping : function(){
         this.groupField = false;
+
         if(this.remoteGroup){
             if(this.baseParams){
                 delete this.baseParams.groupBy;
+                delete this.baseParams.groupDir;
             }
             var lo = this.lastOptions;
             if(lo && lo.params){
                 delete lo.params.groupBy;
+                delete lo.params.groupDir;
             }
+
             this.reload();
         }else{
-            this.applySort();
+            this.sort();
             this.fireEvent('datachanged', this);
         }
     },
 
     
-    groupBy : function(field, forceRegroup, direction){
-               direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
-        if(this.groupField == field && this.groupDir == direction && !forceRegroup){
+    groupBy : function(field, forceRegroup, direction) {
+        direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
+
+        if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
             return; 
         }
+
+        
+        
+        var sorters = this.multiSortInfo.sorters;
+        if (sorters.length > 0 && sorters[0].field == this.groupField) {
+            sorters.shift();
+        }
+
         this.groupField = field;
-               this.groupDir = direction;
+        this.groupDir = direction;
         this.applyGroupField();
-        if(this.groupOnSort){
+
+        var fireGroupEvent = function() {
+            this.fireEvent('groupchange', this, this.getGroupState());
+        };
+
+        if (this.groupOnSort) {
             this.sort(field, direction);
+            fireGroupEvent.call(this);
             return;
         }
-        if(this.remoteGroup){
+
+        if (this.remoteGroup) {
+            this.on('load', fireGroupEvent, this, {single: true});
             this.reload();
-        }else{
-            var si = this.sortInfo || {};
-            if(si.field != field || si.direction != direction){
-                this.applySort();
-            }else{
-                this.sortData(field, direction);
-            }
-            this.fireEvent('datachanged', this);
+        } else {
+            this.sort(sorters);
+            fireGroupEvent.call(this);
         }
     },
+
     
     
-    applyGroupField: function(){
-        if(this.remoteGroup){
-            if(!this.baseParams){
-                this.baseParams = {};
+    sort : function(fieldName, dir) {
+        if (this.remoteSort) {
+            return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
+        }
+
+        var sorters = [];
+
+        
+        if (Ext.isArray(arguments[0])) {
+            sorters = arguments[0];
+        } else if (fieldName == undefined) {
+            
+            
+            sorters = this.sortInfo ? [this.sortInfo] : [];
+        } else {
+            
+            
+            var field = this.fields.get(fieldName);
+            if (!field) return false;
+
+            var name       = field.name,
+                sortInfo   = this.sortInfo || null,
+                sortToggle = this.sortToggle ? this.sortToggle[name] : null;
+
+            if (!dir) {
+                if (sortInfo && sortInfo.field == name) { 
+                    dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
+                } else {
+                    dir = field.sortDir;
+                }
             }
-            this.baseParams.groupBy = this.groupField;
-            this.baseParams.groupDir = this.groupDir;
+
+            this.sortToggle[name] = dir;
+            this.sortInfo = {field: name, direction: dir};
+
+            sorters = [this.sortInfo];
+        }
+
+        
+        if (this.groupField) {
+            sorters.unshift({direction: this.groupDir, field: this.groupField});
         }
+
+        return this.multiSort.call(this, sorters, dir);
     },
 
     
-    applySort : function(){
-        Ext.data.GroupingStore.superclass.applySort.call(this);
-        if(!this.groupOnSort && !this.remoteGroup){
-            var gs = this.getGroupState();
-            if(gs && (gs != this.sortInfo.field || this.groupDir != this.sortInfo.direction)){
-                this.sortData(this.groupField, this.groupDir);
+    applyGroupField: function(){
+        if (this.remoteGroup) {
+            if(!this.baseParams){
+                this.baseParams = {};
+            }
+
+            Ext.apply(this.baseParams, {
+                groupBy : this.groupField,
+                groupDir: this.groupDir
+            });
+
+            var lo = this.lastOptions;
+            if (lo && lo.params) {
+                lo.params.groupDir = this.groupDir;
+
+                
+                delete lo.params.groupBy;
             }
         }
     },
@@ -22167,6 +26049,7 @@ Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
     }
 });
 Ext.reg('groupingstore', Ext.data.GroupingStore);
+
 Ext.data.DirectProxy = function(config){
     Ext.apply(this, config);
     if(typeof this.paramOrder == 'string'){
@@ -22230,23 +26113,25 @@ Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
 
     
     createCallback : function(action, rs, trans) {
+        var me = this;
         return function(result, res) {
             if (!res.status) {
                 
                 if (action === Ext.data.Api.actions.read) {
-                    this.fireEvent("loadexception", this, trans, res, null);
+                    me.fireEvent("loadexception", me, trans, res, null);
                 }
-                this.fireEvent('exception', this, 'remote', action, trans, res, null);
+                me.fireEvent('exception', me, 'remote', action, trans, res, null);
                 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
                 return;
             }
             if (action === Ext.data.Api.actions.read) {
-                this.onRead(action, trans, result, res);
+                me.onRead(action, trans, result, res);
             } else {
-                this.onWrite(action, trans, result, res, rs);
+                me.onWrite(action, trans, result, res, rs);
             }
         };
     },
+
     
     onRead : function(action, trans, result, res) {
         var records;
@@ -22266,23 +26151,30 @@ Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
     },
     
     onWrite : function(action, trans, result, res, rs) {
-        var data = trans.reader.extractData(result, false);
-        this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
-        trans.request.callback.call(trans.request.scope, data, res, true);
+        var data = trans.reader.extractData(trans.reader.getRoot(result), false);
+        var success = trans.reader.getSuccess(result);
+        success = (success !== false);
+        if (success){
+            this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
+        }else{
+            this.fireEvent('exception', this, 'remote', action, trans, result, rs);
+        }
+        trans.request.callback.call(trans.request.scope, data, res, success);
     }
 });
 
-
-Ext.data.DirectStore = function(c){
-    
-    c.batchTransactions = false;
-
-    Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
-        proxy: (typeof(c.proxy) == 'undefined') ? new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')) : c.proxy,
-        reader: (typeof(c.reader) == 'undefined' && typeof(c.fields) == 'object') ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
-    }));
-};
-Ext.extend(Ext.data.DirectStore, Ext.data.Store, {});
+Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
+    constructor : function(config){
+        
+        var c = Ext.apply({}, {
+            batchTransactions: false
+        }, config);
+        Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
+            proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
+            reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
+        }));
+    }
+});
 Ext.reg('directstore', Ext.data.DirectStore);
 
 Ext.Direct = Ext.extend(Ext.util.Observable, {
@@ -22295,7 +26187,7 @@ Ext.Direct = Ext.extend(Ext.util.Observable, {
         LOGIN: 'login',
         SERVER: 'exception'
     },
-    
+
     
     constructor: function(){
         this.addEvents(
@@ -22309,7 +26201,7 @@ Ext.Direct = Ext.extend(Ext.util.Observable, {
     },
 
     
-    addProvider : function(provider){        
+    addProvider : function(provider){
         var a = arguments;
         if(a.length > 1){
             for(var i = 0, len = a.length; i < len; i++){
@@ -22317,7 +26209,7 @@ Ext.Direct = Ext.extend(Ext.util.Observable, {
             }
             return;
         }
-        
+
         
         if(!provider.events){
             provider = new Ext.Direct.PROVIDERS[provider.type](provider);
@@ -22342,7 +26234,7 @@ Ext.Direct = Ext.extend(Ext.util.Observable, {
     },
 
     removeProvider : function(id){
-        var provider = id.id ? id : this.providers[id.id];
+        var provider = id.id ? id : this.providers[id];
         provider.un('data', this.onProviderData, this);
         provider.un('exception', this.onProviderException, this);
         delete this.providers[provider.id];
@@ -22407,7 +26299,8 @@ Ext.Direct.Transaction.prototype = {
     }
 };Ext.Direct.Event = function(config){
     Ext.apply(this, config);
-}
+};
+
 Ext.Direct.Event.prototype = {
     status: true,
     getData: function(){
@@ -22433,7 +26326,6 @@ Ext.Direct.eventTypes = {
     'exception':  Ext.Direct.ExceptionEvent
 };
 
-
 Ext.direct.Provider = Ext.extend(Ext.util.Observable, {    
     
         
@@ -22491,7 +26383,7 @@ Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
                 xhr: xhr,
                 code: Ext.Direct.exceptions.PARSE,
                 message: 'Error parsing json response: \n\n ' + data
-            })
+            });
             return [event];
         }
         var events = [];
@@ -22770,10 +26662,10 @@ Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
             cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
         });
 
-        if(this.fireEvent('beforecall', this, t) !== false){
+        if(this.fireEvent('beforecall', this, t, m) !== false){
             Ext.Direct.addTransaction(t);
             this.queueTransaction(t);
-            this.fireEvent('call', this, t);
+            this.fireEvent('call', this, t, m);
         }
     },
 
@@ -22787,7 +26679,7 @@ Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
             isForm: true
         });
 
-        if(this.fireEvent('beforecall', this, t) !== false){
+        if(this.fireEvent('beforecall', this, t, m) !== false){
             Ext.Direct.addTransaction(t);
             var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
                 params = {
@@ -22805,7 +26697,7 @@ Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
                 isUpload: isUpload,
                 params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
             });
-            this.fireEvent('call', this, t);
+            this.fireEvent('call', this, t, m);
             this.processForm(t);
         }
     },
@@ -22859,117 +26751,116 @@ Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
     }
 });
 Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
-Ext.Resizable = function(el, config){
-    this.el = Ext.get(el);
-    
-    if(config && config.wrap){
-        config.resizeChild = this.el;
-        this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
-        this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
-        this.el.setStyle('overflow', 'hidden');
-        this.el.setPositioning(config.resizeChild.getPositioning());
-        config.resizeChild.clearPositioning();
-        if(!config.width || !config.height){
-            var csize = config.resizeChild.getSize();
-            this.el.setSize(csize.width, csize.height);
-        }
-        if(config.pinned && !config.adjustments){
-            config.adjustments = 'auto';
+Ext.Resizable = Ext.extend(Ext.util.Observable, {
+
+    constructor: function(el, config){
+        this.el = Ext.get(el);
+        if(config && config.wrap){
+            config.resizeChild = this.el;
+            this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
+            this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
+            this.el.setStyle('overflow', 'hidden');
+            this.el.setPositioning(config.resizeChild.getPositioning());
+            config.resizeChild.clearPositioning();
+            if(!config.width || !config.height){
+                var csize = config.resizeChild.getSize();
+                this.el.setSize(csize.width, csize.height);
+            }
+            if(config.pinned && !config.adjustments){
+                config.adjustments = 'auto';
+            }
         }
-    }
 
-    
-    this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
-    this.proxy.unselectable();
-    this.proxy.enableDisplayMode('block');
+        
+        this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
+        this.proxy.unselectable();
+        this.proxy.enableDisplayMode('block');
 
-    Ext.apply(this, config);
-    
-    if(this.pinned){
-        this.disableTrackOver = true;
-        this.el.addClass('x-resizable-pinned');
-    }
-    
-    var position = this.el.getStyle('position');
-    if(position != 'absolute' && position != 'fixed'){
-        this.el.setStyle('position', 'relative');
-    }
-    if(!this.handles){ 
-        this.handles = 's,e,se';
-        if(this.multiDirectional){
-            this.handles += ',n,w';
+        Ext.apply(this, config);
+
+        if(this.pinned){
+            this.disableTrackOver = true;
+            this.el.addClass('x-resizable-pinned');
         }
-    }
-    if(this.handles == 'all'){
-        this.handles = 'n s e w ne nw se sw';
-    }
-    var hs = this.handles.split(/\s*?[,;]\s*?| /);
-    var ps = Ext.Resizable.positions;
-    for(var i = 0, len = hs.length; i < len; i++){
-        if(hs[i] && ps[hs[i]]){
-            var pos = ps[hs[i]];
-            this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);
+        
+        var position = this.el.getStyle('position');
+        if(position != 'absolute' && position != 'fixed'){
+            this.el.setStyle('position', 'relative');
         }
-    }
-    
-    this.corner = this.southeast;
-    
-    if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
-        this.updateBox = true;
-    }   
-   
-    this.activeHandle = null;
-    
-    if(this.resizeChild){
-        if(typeof this.resizeChild == 'boolean'){
-            this.resizeChild = Ext.get(this.el.dom.firstChild, true);
-        }else{
-            this.resizeChild = Ext.get(this.resizeChild, true);
+        if(!this.handles){ 
+            this.handles = 's,e,se';
+            if(this.multiDirectional){
+                this.handles += ',n,w';
+            }
         }
-    }
-    
-    if(this.adjustments == 'auto'){
-        var rc = this.resizeChild;
-        var hw = this.west, he = this.east, hn = this.north, hs = this.south;
-        if(rc && (hw || hn)){
-            rc.position('relative');
-            rc.setLeft(hw ? hw.el.getWidth() : 0);
-            rc.setTop(hn ? hn.el.getHeight() : 0);
+        if(this.handles == 'all'){
+            this.handles = 'n s e w ne nw se sw';
         }
-        this.adjustments = [
-            (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
-            (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1 
-        ];
-    }
-    
-    if(this.draggable){
-        this.dd = this.dynamic ? 
-            this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
-        this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
-        if(this.constrainTo){
-            this.dd.constrainTo(this.constrainTo);
+        var hs = this.handles.split(/\s*?[,;]\s*?| /);
+        var ps = Ext.Resizable.positions;
+        for(var i = 0, len = hs.length; i < len; i++){
+            if(hs[i] && ps[hs[i]]){
+                var pos = ps[hs[i]];
+                this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
+            }
         }
-    }
-    
-    this.addEvents(
-        
-        'beforeresize',
         
-        'resize'
-    );
-    
-    if(this.width !== null && this.height !== null){
-        this.resizeTo(this.width, this.height);
-    }else{
-        this.updateChildSize();
-    }
-    if(Ext.isIE){
-        this.el.dom.style.zoom = 1;
-    }
-    Ext.Resizable.superclass.constructor.call(this);
-};
+        this.corner = this.southeast;
 
-Ext.extend(Ext.Resizable, Ext.util.Observable, {
+        if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
+            this.updateBox = true;
+        }
+
+        this.activeHandle = null;
+
+        if(this.resizeChild){
+            if(typeof this.resizeChild == 'boolean'){
+                this.resizeChild = Ext.get(this.el.dom.firstChild, true);
+            }else{
+                this.resizeChild = Ext.get(this.resizeChild, true);
+            }
+        }
+
+        if(this.adjustments == 'auto'){
+            var rc = this.resizeChild;
+            var hw = this.west, he = this.east, hn = this.north, hs = this.south;
+            if(rc && (hw || hn)){
+                rc.position('relative');
+                rc.setLeft(hw ? hw.el.getWidth() : 0);
+                rc.setTop(hn ? hn.el.getHeight() : 0);
+            }
+            this.adjustments = [
+                (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
+                (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
+            ];
+        }
+
+        if(this.draggable){
+            this.dd = this.dynamic ?
+                this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
+            this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
+            if(this.constrainTo){
+                this.dd.constrainTo(this.constrainTo);
+            }
+        }
+
+        this.addEvents(
+            
+            'beforeresize',
+            
+            'resize'
+        );
+
+        if(this.width !== null && this.height !== null){
+            this.resizeTo(this.width, this.height);
+        }else{
+            this.updateChildSize();
+        }
+        if(Ext.isIE){
+            this.el.dom.style.zoom = 1;
+        }
+        Ext.Resizable.superclass.constructor.call(this);
+    },
 
     
     adjustments : [0, 0],
@@ -23017,14 +26908,15 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
     pinned : false,
     
     preserveRatio : false,
-     
+    
     resizeChild : false,
     
     transparent: false,
     
     
-
     
+
+
     
     resizeTo : function(width, height){
         this.el.setSize(width, height);
@@ -23083,7 +26975,7 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
             e.stopEvent();
             this.activeHandle = handle;
             this.startSizing(e, handle);
-        }          
+        }
     },
 
     
@@ -23161,11 +27053,11 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
     
     constrain : function(v, diff, m, mx){
         if(v - diff < m){
-            diff = v - m;    
+            diff = v - m;
         }else if(v - diff > mx){
-            diff = v - mx; 
+            diff = v - mx;
         }
-        return diff;                
+        return diff;
     },
 
     
@@ -23180,15 +27072,15 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
             
             var curSize = this.curSize || this.startBox,
                 x = this.startBox.x, y = this.startBox.y,
-                ox = x, 
+                ox = x,
                 oy = y,
-                w = curSize.width, 
+                w = curSize.width,
                 h = curSize.height,
-                ow = w, 
+                ow = w,
                 oh = h,
-                mw = this.minWidth, 
+                mw = this.minWidth,
                 mh = this.minHeight,
-                mxw = this.maxWidth, 
+                mxw = this.maxWidth,
                 mxh = this.maxHeight,
                 wi = this.widthIncrement,
                 hi = this.heightIncrement,
@@ -23198,10 +27090,10 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
                 pos = this.activeHandle.position,
                 tw,
                 th;
-            
+
             switch(pos){
                 case 'east':
-                    w += diffX; 
+                    w += diffX;
                     w = Math.min(Math.max(mw, w), mxw);
                     break;
                 case 'south':
@@ -23209,7 +27101,7 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
                     h = Math.min(Math.max(mh, h), mxh);
                     break;
                 case 'southeast':
-                    w += diffX; 
+                    w += diffX;
                     h += diffY;
                     w = Math.min(Math.max(mw, w), mxw);
                     h = Math.min(Math.max(mh, h), mxh);
@@ -23225,7 +27117,7 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
                     w -= diffX;
                     break;
                 case 'northeast':
-                    w += diffX; 
+                    w += diffX;
                     w = Math.min(Math.max(mw, w), mxw);
                     diffY = this.constrain(h, diffY, mh, mxh);
                     y += diffY;
@@ -23247,7 +27139,7 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
                     w -= diffX;
                     break;
             }
-            
+
             var sw = this.snap(w, wi, mw);
             var sh = this.snap(h, hi, mh);
             if(sw != w || sh != h){
@@ -23272,7 +27164,7 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
                 w = sw;
                 h = sh;
             }
-            
+
             if(this.preserveRatio){
                 switch(pos){
                     case 'southeast':
@@ -23323,7 +27215,7 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
                         y += th - h;
                         x += tw - w;
                         break;
-                        
+
                 }
             }
             this.proxy.setBounds(x, y, w, h);
@@ -23347,23 +27239,23 @@ Ext.extend(Ext.Resizable, Ext.util.Observable, {
             this.el.removeClass('x-resizable-over');
         }
     },
-    
+
     
     getEl : function(){
         return this.el;
     },
-    
+
     
     getResizeChild : function(){
         return this.resizeChild;
     },
-    
+
     
     destroy : function(removeEl){
         Ext.destroy(this.dd, this.overlay, this.proxy);
         this.overlay = null;
         this.proxy = null;
-        
+
         var ps = Ext.Resizable.positions;
         for(var k in ps){
             if(typeof ps[k] != 'function' && this[ps[k]]){
@@ -23395,35 +27287,36 @@ Ext.Resizable.positions = {
     n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
 };
 
+Ext.Resizable.Handle = Ext.extend(Object, {
+    constructor : function(rz, pos, disableTrackOver, transparent, cls){
+       if(!this.tpl){
+            
+            var tpl = Ext.DomHelper.createTemplate(
+                {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
+            );
+            tpl.compile();
+            Ext.Resizable.Handle.prototype.tpl = tpl;
+        }
+        this.position = pos;
+        this.rz = rz;
+        this.el = this.tpl.append(rz.el.dom, [this.position], true);
+        this.el.unselectable();
+        if(transparent){
+            this.el.setOpacity(0);
+        }
+        if(!Ext.isEmpty(cls)){
+            this.el.addClass(cls);
+        }
+        this.el.on('mousedown', this.onMouseDown, this);
+        if(!disableTrackOver){
+            this.el.on({
+                scope: this,
+                mouseover: this.onMouseOver,
+                mouseout: this.onMouseOut
+            });
+        }
+    },
 
-Ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){
-    if(!this.tpl){
-        
-        var tpl = Ext.DomHelper.createTemplate(
-            {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
-        );
-        tpl.compile();
-        Ext.Resizable.Handle.prototype.tpl = tpl;
-    }
-    this.position = pos;
-    this.rz = rz;
-    this.el = this.tpl.append(rz.el.dom, [this.position], true);
-    this.el.unselectable();
-    if(transparent){
-        this.el.setOpacity(0);
-    }
-    this.el.on('mousedown', this.onMouseDown, this);
-    if(!disableTrackOver){
-        this.el.on({
-            scope: this,
-            mouseover: this.onMouseOver,
-            mouseout: this.onMouseOut
-        });
-    }
-};
-
-
-Ext.Resizable.Handle.prototype = {
     
     afterResize : function(rz){
         
@@ -23445,7 +27338,7 @@ Ext.Resizable.Handle.prototype = {
         Ext.destroy(this.el);
         this.el = null;
     }
-};
+});
 
 Ext.Window = Ext.extend(Ext.Panel, {
     
@@ -23485,6 +27378,12 @@ Ext.Window = Ext.extend(Ext.Panel, {
     minWidth : 200,
     
     expandOnShow : true,
+    
+    
+    showAnimDuration: 0.25,
+    
+    
+    hideAnimDuration: 0.25,
 
     
     collapsible : false,
@@ -23496,9 +27395,6 @@ Ext.Window = Ext.extend(Ext.Panel, {
     hidden : true,
 
     
-    monitorResize : true,
-
-    
     
     
     
@@ -23581,7 +27477,8 @@ Ext.Window = Ext.extend(Ext.Panel, {
                 minHeight:this.minHeight,
                 handles: this.resizeHandles || 'all',
                 pinned: true,
-                resizeElement : this.resizerAction
+                resizeElement : this.resizerAction,
+                handleCls: 'x-window-handle'
             });
             this.resizer.window = this;
             this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
@@ -23610,18 +27507,16 @@ Ext.Window = Ext.extend(Ext.Panel, {
     },
 
    
-    onEsc : function(){
+    onEsc : function(k, e){
+        e.stopEvent();
         this[this.closeAction]();
     },
 
     
     beforeDestroy : function(){
-        if (this.rendered){
+        if(this.rendered){
             this.hide();
-          if(this.doAnchor){
-                Ext.EventManager.removeResizeListener(this.doAnchor, this);
-              Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
-            }
+            this.clearAnchor();
             Ext.destroy(
                 this.focusEl,
                 this.resizer,
@@ -23698,6 +27593,9 @@ Ext.Window = Ext.extend(Ext.Panel, {
             this.updateBox(box);
         }else{
             this.setSize(box);
+            if (Ext.isIE6 && Ext.isStrict) {
+                this.doLayout();
+            }
         }
         this.focus();
         this.updateHandles();
@@ -23706,7 +27604,11 @@ Ext.Window = Ext.extend(Ext.Panel, {
 
     
     focus : function(){
-        var f = this.focusEl, db = this.defaultButton, t = typeof db;
+        var f = this.focusEl,
+            db = this.defaultButton,
+            t = typeof db,
+            el,
+            ct;
         if(Ext.isDefined(db)){
             if(Ext.isNumber(db) && this.fbar){
                 f = this.fbar.items.get(db);
@@ -23715,6 +27617,13 @@ Ext.Window = Ext.extend(Ext.Panel, {
             }else{
                 f = db;
             }
+            el = f.getEl();
+            ct = Ext.getDom(this.container);
+            if (el && ct) {
+                if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
+                    return;
+                }
+            }
         }
         f = f || this.focusEl;
         f.focus.defer(10, f);
@@ -23779,6 +27688,9 @@ Ext.Window = Ext.extend(Ext.Panel, {
 
     
     afterShow : function(isAnim){
+        if (this.isDestroyed){
+            return false;
+        }
         this.proxy.hide();
         this.el.setStyle('display', 'block');
         this.el.show();
@@ -23818,7 +27730,7 @@ Ext.Window = Ext.extend(Ext.Panel, {
             callback: this.afterShow.createDelegate(this, [true], false),
             scope: this,
             easing: 'easeNone',
-            duration: 0.25,
+            duration: this.showAnimDuration,
             opacity: 0.5
         }));
     },
@@ -23871,7 +27783,7 @@ Ext.Window = Ext.extend(Ext.Panel, {
         this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
             callback: this.afterHide,
             scope: this,
-            duration: 0.25,
+            duration: this.hideAnimDuration,
             easing: 'easeNone',
             opacity: 0
         }));
@@ -23939,7 +27851,7 @@ Ext.Window = Ext.extend(Ext.Panel, {
         }
         if(show !== false){
             this.el.show();
-            this.focus();
+            this.focus.defer(10, this);
             if(Ext.isMac && Ext.isGecko2){ 
                 this.cascade(this.setAutoScroll);
             }
@@ -24072,22 +27984,37 @@ Ext.Window = Ext.extend(Ext.Panel, {
 
     
     anchorTo : function(el, alignment, offsets, monitorScroll){
-      if(this.doAnchor){
-          Ext.EventManager.removeResizeListener(this.doAnchor, this);
-          Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
-      }
-      this.doAnchor = function(){
-          this.alignTo(el, alignment, offsets);
-      };
-      Ext.EventManager.onWindowResize(this.doAnchor, this);
-
-      var tm = typeof monitorScroll;
-      if(tm != 'undefined'){
-          Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
-              {buffer: tm == 'number' ? monitorScroll : 50});
-      }
-      this.doAnchor();
-      return this;
+        this.clearAnchor();
+        this.anchorTarget = {
+            el: el,
+            alignment: alignment,
+            offsets: offsets
+        };
+
+        Ext.EventManager.onWindowResize(this.doAnchor, this);
+        var tm = typeof monitorScroll;
+        if(tm != 'undefined'){
+            Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
+                {buffer: tm == 'number' ? monitorScroll : 50});
+        }
+        return this.doAnchor();
+    },
+
+    
+    doAnchor : function(){
+        var o = this.anchorTarget;
+        this.alignTo(o.el, o.alignment, o.offsets);
+        return this;
+    },
+
+    
+    clearAnchor : function(){
+        if(this.anchorTarget){
+            Ext.EventManager.removeResizeListener(this.doAnchor, this);
+            Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
+            delete this.anchorTarget;
+        }
+        return this;
     },
 
     
@@ -24131,19 +28058,20 @@ Ext.Window = Ext.extend(Ext.Panel, {
 Ext.reg('window', Ext.Window);
 
 
-Ext.Window.DD = function(win){
-    this.win = win;
-    Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
-    this.setHandleElId(win.header.id);
-    this.scroll = false;
-};
-
-Ext.extend(Ext.Window.DD, Ext.dd.DD, {
+Ext.Window.DD = Ext.extend(Ext.dd.DD, {
+    
+    constructor : function(win){
+        this.win = win;
+        Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
+        this.setHandleElId(win.header.id);
+        this.scroll = false;        
+    },
+    
     moveOnly:true,
     headerOffsets:[100, 25],
     startDrag : function(){
         var w = this.win;
-        this.proxy = w.ghost();
+        this.proxy = w.ghost(w.initialConfig.cls);
         if(w.constrain !== false){
             var so = w.el.shadowOffset;
             this.constrainTo(w.container, {right: so, left: so, bottom: so});
@@ -24443,19 +28371,17 @@ Ext.MessageBox = function(){
             if(!dlg.isVisible() && !opt.width){
                 dlg.setSize(this.maxWidth, 100); 
             }
-            msgEl.update(text || '&#160;');
+            
+            msgEl.update(text ? text + ' ' : '&#160;');
 
-            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
-            var mw = msgEl.getWidth() + msgEl.getMargins('lr');
-            var fw = dlg.getFrameWidth('lr');
-            var bw = dlg.body.getFrameWidth('lr');
-            if (Ext.isIE && iw > 0){
-                
+            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
+                mw = msgEl.getWidth() + msgEl.getMargins('lr'),
+                fw = dlg.getFrameWidth('lr'),
+                bw = dlg.body.getFrameWidth('lr'),
+                w;
                 
-                iw += 3;
-            }
-            var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
-                        Math.max(opt.minWidth || this.minWidth, bwidth || 0));
+            w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
+                    Math.max(opt.minWidth || this.minWidth, bwidth || 0));
 
             if(opt.prompt === true){
                 activeTextEl.setWidth(w-iw-fw-bw);
@@ -24466,6 +28392,7 @@ Ext.MessageBox = function(){
             if(Ext.isIE && w == bwidth){
                 w += 4; 
             }
+            msgEl.update(text || '&#160;');
             dlg.setSize(w, 'auto').center();
             return this;
         },
@@ -24541,7 +28468,7 @@ Ext.MessageBox = function(){
                     d.focusEl = db;
                 }
             }
-            if(opt.iconCls){
+            if(Ext.isDefined(opt.iconCls)){
               d.setIconClass(opt.iconCls);
             }
             this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
@@ -24631,7 +28558,8 @@ Ext.MessageBox = function(){
                 msg : msg,
                 buttons: this.OK,
                 fn: fn,
-                scope : scope
+                scope : scope,
+                minWidth: this.minWidth
             });
             return this;
         },
@@ -24644,7 +28572,8 @@ Ext.MessageBox = function(){
                 buttons: this.YESNO,
                 fn: fn,
                 scope : scope,
-                icon: this.QUESTION
+                icon: this.QUESTION,
+                minWidth: this.minWidth
             });
             return this;
         },
@@ -24656,7 +28585,7 @@ Ext.MessageBox = function(){
                 msg : msg,
                 buttons: this.OKCANCEL,
                 fn: fn,
-                minWidth:250,
+                minWidth: this.minPromptWidth,
                 scope : scope,
                 prompt:true,
                 multiline: multiline,
@@ -24693,6 +28622,8 @@ Ext.MessageBox = function(){
         
         minProgressWidth : 250,
         
+        minPromptWidth: 250,
+        
         buttonText : {
             ok : "OK",
             cancel : "Cancel",
@@ -24704,13 +28635,14 @@ Ext.MessageBox = function(){
 
 
 Ext.Msg = Ext.MessageBox;
-Ext.dd.PanelProxy = function(panel, config){
-    this.panel = panel;
-    this.id = this.panel.id +'-ddproxy';
-    Ext.apply(this, config);
-};
-
-Ext.dd.PanelProxy.prototype = {
+Ext.dd.PanelProxy  = Ext.extend(Object, {
+    
+    constructor : function(panel, config){
+        this.panel = panel;
+        this.id = this.panel.id +'-ddproxy';
+        Ext.apply(this, config);        
+    },
+    
     
     insertProxy : true,
 
@@ -24752,8 +28684,8 @@ Ext.dd.PanelProxy.prototype = {
     
     show : function(){
         if(!this.ghost){
-            this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
-            this.ghost.setXY(this.panel.el.getXY())
+            this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
+            this.ghost.setXY(this.panel.el.getXY());
             if(this.insertProxy){
                 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
                 this.proxy.setSize(this.panel.getSize());
@@ -24776,31 +28708,34 @@ Ext.dd.PanelProxy.prototype = {
             parentNode.insertBefore(this.proxy.dom, before);
         }
     }
-};
+});
 
 
-Ext.Panel.DD = function(panel, cfg){
-    this.panel = panel;
-    this.dragData = {panel: panel};
-    this.proxy = new Ext.dd.PanelProxy(panel, cfg);
-    Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
-    var h = panel.header;
-    if(h){
-        this.setHandleElId(h.id);
-    }
-    (h ? h : this.panel.body).setStyle('cursor', 'move');
-    this.scroll = false;
-};
-
-Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
+Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {
+    
+    constructor : function(panel, cfg){
+        this.panel = panel;
+        this.dragData = {panel: panel};
+        this.proxy = new Ext.dd.PanelProxy(panel, cfg);
+        Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
+        var h = panel.header,
+            el = panel.body;
+        if(h){
+            this.setHandleElId(h.id);
+            el = panel.header;
+        }
+        el.setStyle('cursor', 'move');
+        this.scroll = false;        
+    },
+    
     showFrame: Ext.emptyFn,
     startDrag: Ext.emptyFn,
     b4StartDrag: function(x, y) {
         this.proxy.show();
     },
     b4MouseDown: function(e) {
-        var x = e.getPageX();
-        var y = e.getPageY();
+        var x = e.getPageX(),
+            y = e.getPageY();
         this.autoOffset(x, y);
     },
     onInitDrag : function(x, y){
@@ -24822,13 +28757,15 @@ Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
         this.setDelta(x, y);
     }
 });
-Ext.state.Provider = function(){
+Ext.state.Provider = Ext.extend(Ext.util.Observable, {
+    
+    constructor : function(){
+        
+        this.addEvents("statechange");
+        this.state = {};
+        Ext.state.Provider.superclass.constructor.call(this);
+    },
     
-    this.addEvents("statechange");
-    this.state = {};
-    Ext.state.Provider.superclass.constructor.call(this);
-};
-Ext.extend(Ext.state.Provider, Ext.util.Observable, {
     
     get : function(name, defaultValue){
         return typeof this.state[name] == "undefined" ?
@@ -24849,31 +28786,40 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
 
     
     decodeValue : function(cookie){
-        var re = /^(a|n|d|b|s|o)\:(.*)$/;
-        var matches = re.exec(unescape(cookie));
-        if(!matches || !matches[1]) return; 
-        var type = matches[1];
-        var v = matches[2];
+        
+        var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
+            matches = re.exec(unescape(cookie)),
+            all,
+            type,
+            v,
+            kv;
+        if(!matches || !matches[1]){
+            return; 
+        }
+        type = matches[1];
+        v = matches[2];
         switch(type){
-            case "n":
+            case 'e':
+                return null;
+            case 'n':
                 return parseFloat(v);
-            case "d":
+            case 'd':
                 return new Date(Date.parse(v));
-            case "b":
-                return (v == "1");
-            case "a":
-                var all = [];
+            case 'b':
+                return (v == '1');
+            case 'a':
+                all = [];
                 if(v != ''){
                     Ext.each(v.split('^'), function(val){
                         all.push(this.decodeValue(val));
                     }, this);
                 }
                 return all;
-           case "o":
-                var all = {};
+           case 'o':
+                all = {};
                 if(v != ''){
                     Ext.each(v.split('^'), function(val){
-                        var kv = val.split('=');
+                        kv = val.split('=');
                         all[kv[0]] = this.decodeValue(kv[1]);
                     }, this);
                 }
@@ -24885,30 +28831,36 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
 
     
     encodeValue : function(v){
-        var enc;
-        if(typeof v == "number"){
-            enc = "n:" + v;
-        }else if(typeof v == "boolean"){
-            enc = "b:" + (v ? "1" : "0");
+        var enc,
+            flat = '',
+            i = 0,
+            len,
+            key;
+        if(v == null){
+            return 'e:1';    
+        }else if(typeof v == 'number'){
+            enc = 'n:' + v;
+        }else if(typeof v == 'boolean'){
+            enc = 'b:' + (v ? '1' : '0');
         }else if(Ext.isDate(v)){
-            enc = "d:" + v.toGMTString();
+            enc = 'd:' + v.toGMTString();
         }else if(Ext.isArray(v)){
-            var flat = "";
-            for(var i = 0, len = v.length; i < len; i++){
+            for(len = v.length; i < len; i++){
                 flat += this.encodeValue(v[i]);
-                if(i != len-1) flat += "^";
+                if(i != len - 1){
+                    flat += '^';
+                }
             }
-            enc = "a:" + flat;
-        }else if(typeof v == "object"){
-            var flat = "";
-            for(var key in v){
-                if(typeof v[key] != "function" && v[key] !== undefined){
-                    flat += key + "=" + this.encodeValue(v[key]) + "^";
+            enc = 'a:' + flat;
+        }else if(typeof v == 'object'){
+            for(key in v){
+                if(typeof v[key] != 'function' && v[key] !== undefined){
+                    flat += key + '=' + this.encodeValue(v[key]) + '^';
                 }
             }
-            enc = "o:" + flat.substring(0, flat.length-1);
+            enc = 'o:' + flat.substring(0, flat.length-1);
         }else{
-            enc = "s:" + v;
+            enc = 's:' + v;
         }
         return escape(enc);
     }
@@ -24945,17 +28897,18 @@ Ext.state.Manager = function(){
     };
 }();
 
-Ext.state.CookieProvider = function(config){
-    Ext.state.CookieProvider.superclass.constructor.call(this);
-    this.path = "/";
-    this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); 
-    this.domain = null;
-    this.secure = false;
-    Ext.apply(this, config);
-    this.state = this.readCookies();
-};
-
-Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
+Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {
+    
+    constructor : function(config){
+        Ext.state.CookieProvider.superclass.constructor.call(this);
+        this.path = "/";
+        this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); 
+        this.domain = null;
+        this.secure = false;
+        Ext.apply(this, config);
+        this.state = this.readCookies();
+    },
+    
     
     set : function(name, value){
         if(typeof value == "undefined" || value === null){
@@ -24974,13 +28927,15 @@ Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
 
     
     readCookies : function(){
-        var cookies = {};
-        var c = document.cookie + ";";
-        var re = /\s?(.*?)=(.*?);/g;
-       var matches;
+        var cookies = {},
+            c = document.cookie + ";",
+            re = /\s?(.*?)=(.*?);/g,
+           matches,
+            name,
+            value;
        while((matches = re.exec(c)) != null){
-            var name = matches[1];
-            var value = matches[2];
+            name = matches[1];
+            value = matches[2];
             if(name && name.substring(0,3) == "ys-"){
                 cookies[name.substr(3)] = this.decodeValue(value);
             }
@@ -25023,6 +28978,9 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
     deferEmptyText: true,
     
     trackOver: false,
+    
+    
+    blockRefresh: false,
 
     
     last: false,
@@ -25088,11 +29046,12 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
     },
 
     
-    refresh : function(){
+    refresh : function() {
         this.clearSelections(false, true);
-        var el = this.getTemplateTarget();
-        el.update("");
-        var records = this.store.getRange();
+        var el = this.getTemplateTarget(),
+            records = this.store.getRange();
+            
+        el.update('');
         if(records.length < 1){
             if(!this.deferEmptyText || this.hasSkippedEmptyText){
                 el.update(this.emptyText);
@@ -25117,17 +29076,19 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
 
     
     collectData : function(records, startIndex){
-        var r = [];
-        for(var i = 0, len = records.length; i < len; i++){
-            r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
+        var r = [],
+            i = 0,
+            len = records.length;
+        for(; i < len; i++){
+            r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
         }
         return r;
     },
 
     
-    bufferRender : function(records){
+    bufferRender : function(records, index){
         var div = document.createElement('div');
-        this.tpl.overwrite(div, this.collectData(records));
+        this.tpl.overwrite(div, this.collectData(records, index));
         return Ext.query(this.itemSelector, div);
     },
 
@@ -25135,9 +29096,9 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
     onUpdate : function(ds, record){
         var index = this.store.indexOf(record);
         if(index > -1){
-            var sel = this.isSelected(index);
-            var original = this.all.elements[index];
-            var node = this.bufferRender([record], index)[0];
+            var sel = this.isSelected(index),
+                original = this.all.elements[index],
+                node = this.bufferRender([record], index)[0];
 
             this.all.replaceElement(index, node, true);
             if(sel){
@@ -25202,7 +29163,7 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
                 this.store.destroy();
             }else{
                 this.store.un("beforeload", this.onBeforeLoad, this);
-                this.store.un("datachanged", this.refresh, this);
+                this.store.un("datachanged", this.onDataChanged, this);
                 this.store.un("add", this.onAdd, this);
                 this.store.un("remove", this.onRemove, this);
                 this.store.un("update", this.onUpdate, this);
@@ -25217,7 +29178,7 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
             store.on({
                 scope: this,
                 beforeload: this.onBeforeLoad,
-                datachanged: this.refresh,
+                datachanged: this.onDataChanged,
                 add: this.onAdd,
                 remove: this.onRemove,
                 update: this.onUpdate,
@@ -25229,6 +29190,13 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
             this.refresh();
         }
     },
+    
+    
+    onDataChanged: function() {
+        if (this.blockRefresh !== true) {
+            this.refresh.apply(this, arguments);
+        }
+    },
 
     
     findItemFromChild : function(node){
@@ -25237,9 +29205,10 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
 
     
     onClick : function(e){
-        var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
+        var item = e.getTarget(this.itemSelector, this.getTemplateTarget()),
+            index;
         if(item){
-            var index = this.indexOf(item);
+            index = this.indexOf(item);
             if(this.onItemClick(item, index, e) !== false){
                 this.fireEvent("click", this, index, item, e);
             }
@@ -25344,29 +29313,32 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
 
     
     getSelectedIndexes : function(){
-        var indexes = [], s = this.selected.elements;
-        for(var i = 0, len = s.length; i < len; i++){
-            indexes.push(s[i].viewIndex);
+        var indexes = [], 
+            selected = this.selected.elements,
+            i = 0,
+            len = selected.length;
+            
+        for(; i < len; i++){
+            indexes.push(selected[i].viewIndex);
         }
         return indexes;
     },
 
     
     getSelectedRecords : function(){
-        var r = [], s = this.selected.elements;
-        for(var i = 0, len = s.length; i < len; i++){
-            r[r.length] = this.store.getAt(s[i].viewIndex);
-        }
-        return r;
+        return this.getRecords(this.selected.elements);
     },
 
     
     getRecords : function(nodes){
-        var r = [], s = nodes;
-        for(var i = 0, len = s.length; i < len; i++){
-            r[r.length] = this.store.getAt(s[i].viewIndex);
+        var records = [], 
+            i = 0,
+            len = nodes.length;
+            
+        for(; i < len; i++){
+            records[records.length] = this.store.getAt(nodes[i].viewIndex);
         }
-        return r;
+        return records;
     },
 
     
@@ -25450,16 +29422,21 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
             return document.getElementById(nodeInfo);
         }else if(Ext.isNumber(nodeInfo)){
             return this.all.elements[nodeInfo];
+        }else if(nodeInfo instanceof Ext.data.Record){
+            var idx = this.store.indexOf(nodeInfo);
+            return this.all.elements[idx];
         }
         return nodeInfo;
     },
 
     
     getNodes : function(start, end){
-        var ns = this.all.elements;
+        var ns = this.all.elements,
+            nodes = [],
+            i;
+            
         start = start || 0;
         end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
-        var nodes = [], i;
         if(start <= end){
             for(i = start; i <= end && ns[i]; i++){
                 nodes.push(ns[i]);
@@ -25523,8 +29500,8 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
     
 
     
-    maxWidth: Ext.isIE ? 99 : 100,
-    
+    maxColumnWidth: Ext.isIE ? 99 : 100,
+
     initComponent : function(){
         if(this.columnResize){
             this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
@@ -25563,13 +29540,13 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
                 '</tpl>'
             );
         };
-        
-        var cs = this.columns, 
-            allocatedWidth = 0, 
-            colsWithWidth = 0, 
-            len = cs.length, 
+
+        var cs = this.columns,
+            allocatedWidth = 0,
+            colsWithWidth = 0,
+            len = cs.length,
             columns = [];
-            
+
         for(var i = 0; i < len; i++){
             var c = cs[i];
             if(!c.isColumn) {
@@ -25578,18 +29555,21 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
             }
             if(c.width) {
                 allocatedWidth += c.width*100;
+                if(allocatedWidth > this.maxColumnWidth){
+                    c.width -= (allocatedWidth - this.maxColumnWidth) / 100;
+                }
                 colsWithWidth++;
             }
             columns.push(c);
         }
-        
+
         cs = this.columns = columns;
-        
+
         
         if(colsWithWidth < len){
             var remaining = len - colsWithWidth;
-            if(allocatedWidth < this.maxWidth){
-                var perCol = ((this.maxWidth-allocatedWidth) / remaining)/100;
+            if(allocatedWidth < this.maxColumnWidth){
+                var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
                 for(var j = 0; j < len; j++){
                     var c = cs[j];
                     if(!c.width){
@@ -25603,12 +29583,12 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
 
     onRender : function(){
         this.autoEl = {
-            cls: 'x-list-wrap'  
+            cls: 'x-list-wrap'
         };
         Ext.list.ListView.superclass.onRender.apply(this, arguments);
 
         this.internalTpl.overwrite(this.el, {columns: this.columns});
-        
+
         this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
         this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
 
@@ -25627,7 +29607,7 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
         return {
             columns: this.columns,
             rows: rs
-        }
+        };
     },
 
     verifyInternalSize : function(){
@@ -25638,30 +29618,32 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
 
     
     onResize : function(w, h){
-        var bd = this.innerBody.dom;
-        var hd = this.innerHd.dom
-        if(!bd){
+        var body = this.innerBody.dom,
+            header = this.innerHd.dom,
+            scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px',
+            parentNode;
+            
+        if(!body){
             return;
         }
-        var bdp = bd.parentNode;
+        parentNode = body.parentNode;
         if(Ext.isNumber(w)){
-            var sw = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
-            if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){
-                bd.style.width = sw + 'px';
-                hd.style.width = sw + 'px';
+            if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){
+                body.style.width = scrollWidth;
+                header.style.width = scrollWidth;
             }else{
-                bd.style.width = w + 'px';
-                hd.style.width = w + 'px';
+                body.style.width = w + 'px';
+                header.style.width = w + 'px';
                 setTimeout(function(){
-                    if((bdp.offsetWidth - bdp.clientWidth) > 10){
-                        bd.style.width = sw + 'px';
-                        hd.style.width = sw + 'px';
+                    if((parentNode.offsetWidth - parentNode.clientWidth) > 10){
+                        body.style.width = scrollWidth;
+                        header.style.width = scrollWidth;
                     }
                 }, 10);
             }
         }
         if(Ext.isNumber(h)){
-            bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px';
+            parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px';
         }
     },
 
@@ -25670,11 +29652,14 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
         this.verifyInternalSize();
     },
 
-    findHeaderIndex : function(hd){
-        hd = hd.dom || hd;
-        var pn = hd.parentNode, cs = pn.parentNode.childNodes;
-        for(var i = 0, c; c = cs[i]; i++){
-            if(c == pn){
+    findHeaderIndex : function(header){
+        header = header.dom || header;
+        var parentNode = header.parentNode, 
+            children = parentNode.parentNode.childNodes,
+            i = 0,
+            c;
+        for(; c = children[i]; i++){
+            if(c == parentNode){
                 return i;
             }
         }
@@ -25682,9 +29667,13 @@ Ext.list.ListView = Ext.extend(Ext.DataView, {
     },
 
     setHdWidths : function(){
-        var els = this.innerHd.dom.getElementsByTagName('div');
-        for(var i = 0, cs = this.columns, len = cs.length; i < len; i++){
-            els[i].style.width = (cs[i].width*100) + '%';
+        var els = this.innerHd.dom.getElementsByTagName('div'),
+            i = 0,
+            columns = this.columns,
+            len = columns.length;
+            
+        for(; i < len; i++){
+            els[i].style.width = (columns[i].width*100) + '%';
         }
     }
 });
@@ -25805,23 +29794,23 @@ Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
     },
 
     handleHdMove : function(e, t){
-        var hw = 5,
+        var handleWidth = 5,
             x = e.getPageX(),
-            hd = e.getTarget('em', 3, true);
-        if(hd){
-            var r = hd.getRegion(),
-                ss = hd.dom.style,
-                pn = hd.dom.parentNode;
-
-            if(x - r.left <= hw && pn != pn.parentNode.firstChild){
-                this.activeHd = Ext.get(pn.previousSibling.firstChild);
-                ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
-            } else if(r.right - x <= hw && pn != pn.parentNode.lastChild.previousSibling){
-                this.activeHd = hd;
-                ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
+            header = e.getTarget('em', 3, true);
+        if(header){
+            var region = header.getRegion(),
+                style = header.dom.style,
+                parentNode = header.dom.parentNode;
+
+            if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){
+                this.activeHd = Ext.get(parentNode.previousSibling.firstChild);
+                style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
+            } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){
+                this.activeHd = header;
+                style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
             } else{
                 delete this.activeHd;
-                ss.cursor = '';
+                style.cursor = '';
             }
         }
     },
@@ -25832,59 +29821,89 @@ Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
     },
 
     onStart: function(e){
-        this.view.disableHeaders = true;
-        this.proxy = this.view.el.createChild({cls:'x-list-resizer'});
-        this.proxy.setHeight(this.view.el.getHeight());
-
-        var x = this.tracker.getXY()[0],
-            w = this.view.innerHd.getWidth();
-
-        this.hdX = this.dragHd.getX();
-        this.hdIndex = this.view.findHeaderIndex(this.dragHd);
-
-        this.proxy.setX(this.hdX);
-        this.proxy.setWidth(x-this.hdX);
-
-        this.minWidth = w*this.minPct;
-        this.maxWidth = w - (this.minWidth*(this.view.columns.length-1-this.hdIndex));
+        
+        var me = this,
+            view = me.view,
+            dragHeader = me.dragHd,
+            x = me.tracker.getXY()[0];            
+        
+        me.proxy = view.el.createChild({cls:'x-list-resizer'});
+        me.dragX = dragHeader.getX();
+        me.headerIndex = view.findHeaderIndex(dragHeader);
+        
+        me.headersDisabled = view.disableHeaders;
+        view.disableHeaders = true;
+        
+        me.proxy.setHeight(view.el.getHeight());
+        me.proxy.setX(me.dragX);
+        me.proxy.setWidth(x - me.dragX);
+        
+        this.setBoundaries();
+        
+    },
+    
+    
+    setBoundaries: function(relativeX){
+        var view = this.view,
+            headerIndex = this.headerIndex,
+            width = view.innerHd.getWidth(),
+            relativeX = view.innerHd.getX(),
+            minWidth = Math.ceil(width * this.minPct),
+            maxWidth = width - minWidth,
+            numColumns = view.columns.length,
+            headers = view.innerHd.select('em', true),
+            minX = minWidth + relativeX,
+            maxX = maxWidth + relativeX,
+            header;
+          
+        if (numColumns == 2) {
+            this.minX = minX;
+            this.maxX = maxX;
+        }else{
+            header = headers.item(headerIndex + 2);
+            this.minX = headers.item(headerIndex).getX() + minWidth;
+            this.maxX = header ? header.getX() - minWidth : maxX;
+            if (headerIndex == 0) {
+                
+                this.minX = minX;
+            } else if (headerIndex == numColumns - 2) {
+                
+                this.maxX = maxX;
+            }
+        }
     },
 
     onDrag: function(e){
-        var cursorX = this.tracker.getXY()[0];
-        this.proxy.setWidth((cursorX-this.hdX).constrain(this.minWidth, this.maxWidth));
+        var me = this,
+            cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX);
+            
+        me.proxy.setWidth(cursorX - this.dragX);
     },
 
     onEnd: function(e){
         
-        var nw = this.proxy.getWidth();
+        var newWidth = this.proxy.getWidth(),
+            index = this.headerIndex,
+            view = this.view,
+            columns = view.columns,
+            width = view.innerHd.getWidth(),
+            newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100,
+            disabled = this.headersDisabled,
+            headerCol = columns[index],
+            otherCol = columns[index + 1],
+            totalPercent = headerCol.width + otherCol.width;
+
         this.proxy.remove();
 
-        var index = this.hdIndex,
-            vw = this.view,
-            cs = vw.columns,
-            len = cs.length,
-            w = this.view.innerHd.getWidth(),
-            minPct = this.minPct * 100,
-            pct = Math.ceil((nw * vw.maxWidth) / w),
-            diff = (cs[index].width * 100) - pct,
-            each = Math.floor(diff / (len-1-index)),
-            mod = diff - (each * (len-1-index));
-
-        for(var i = index+1; i < len; i++){
-            var cw = (cs[i].width * 100) + each,
-                ncw = Math.max(minPct, cw);
-            if(cw != ncw){
-                mod += cw - ncw;
-            }
-            cs[i].width = ncw / 100;
-        }
-        cs[index].width = pct / 100;
-        cs[index+1].width += (mod / 100);
+        headerCol.width = newPercent;
+        otherCol.width = totalPercent - newPercent;
+      
         delete this.dragHd;
-        vw.setHdWidths();
-        vw.refresh();
+        view.setHdWidths();
+        view.refresh();
+        
         setTimeout(function(){
-            vw.disableHeaders = false;
+            view.disableHeaders = disabled;
         }, 100);
     }
 });
@@ -25952,8 +29971,6 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
     
     
     
-    monitorResize : true,
-    
     deferredRender : true,
     
     tabWidth : 120,
@@ -26099,8 +30116,9 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
 
     
     findTargets : function(e){
-        var item = null;
-        var itemEl = e.getTarget('li', this.strip);
+        var item = null,
+            itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
+
         if(itemEl){
             item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
             if(item.disabled){
@@ -26204,8 +30222,8 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
             beforeshow: this.onBeforeShowItem
         });
     },
-    
-    
+
+
 
     
     getTemplateArgs : function(item) {
@@ -26234,9 +30252,6 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
         if(this.rendered){
             var items = this.items;
             this.initTab(c, items.indexOf(c));
-            if(items.getCount() == 1){
-                this.syncSize();
-            }
             this.delegateUpdates();
         }
     },
@@ -26374,13 +30389,14 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
 
     
     delegateUpdates : function(){
+        var rendered = this.rendered;
         if(this.suspendUpdates){
             return;
         }
-        if(this.resizeTabs && this.rendered){
+        if(this.resizeTabs && rendered){
             this.autoSizeTabs();
         }
-        if(this.enableTabScroll && this.rendered){
+        if(this.enableTabScroll && rendered){
             this.autoScrollTabs();
         }
     },
@@ -26398,7 +30414,7 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
 
         var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); 
         this.lastTabWidth = each;
-        var lis = this.strip.query("li:not([className^=x-tab-edge])");
+        var lis = this.strip.query('li:not(.x-tab-edge)');
         for(var i = 0, len = lis.length; i < len; i++) {
             var li = lis[i],
                 inner = Ext.fly(li).child('.x-tab-strip-inner', true),
@@ -26436,13 +30452,15 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
                     Ext.fly(oldEl).removeClass('x-tab-strip-active');
                 }
             }
+            this.activeTab = item;
             if(item){
                 var el = this.getTabEl(item);
                 Ext.fly(el).addClass('x-tab-strip-active');
-                this.activeTab = item;
                 this.stack.add(item);
 
                 this.layout.setActiveItem(item);
+                
+                this.delegateUpdates();
                 if(this.scrolling){
                     this.scrollToTab(item, this.animScroll);
                 }
@@ -26473,10 +30491,11 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
             pos = this.getScrollPos(),
             l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
 
-        if(!this.enableTabScroll || count < 1 || cw < 20){ 
+        if(!this.enableTabScroll || cw < 20){ 
             return;
         }
-        if(l <= tw){
+        if(count == 0 || l <= tw){
+            
             wd.scrollLeft = 0;
             wrap.setWidth(tw);
             if(this.scrolling){
@@ -26579,11 +30598,11 @@ Ext.TabPanel = Ext.extend(Ext.Panel,  {
     
 
     scrollToTab : function(item, animate){
-        if(!item){ 
-            return; 
+        if(!item){
+            return;
         }
         var el = this.getTabEl(item),
-            pos = this.getScrollPos(), 
+            pos = this.getScrollPos(),
             area = this.getScrollArea(),
             left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
             right = left + el.offsetWidth;
@@ -26748,8 +30767,14 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     
     
     
+    
 
     initComponent : function(){
+        if(this.menu){
+            this.menu = Ext.menu.MenuMgr.get(this.menu);
+            this.menu.ownerCt = this;
+        }
+        
         Ext.Button.superclass.initComponent.call(this);
 
         this.addEvents(
@@ -26770,8 +30795,9 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             
             'menutriggerout'
         );
-        if(this.menu){
-            this.menu = Ext.menu.MenuMgr.get(this.menu);
+        
+        if (this.menu){
+            this.menu.ownerCt = undefined;
         }
         if(Ext.isString(this.toggleGroup)){
             this.enableToggle = true;
@@ -26789,7 +30815,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             if(!Ext.isEmpty(this.oldCls)){
                 this.el.removeClass([this.oldCls, 'x-btn-pressed']);
             }
-            this.oldCls = (this.iconCls || this.icon) ? (this.text ? ' x-btn-text-icon' : ' x-btn-icon') : ' x-btn-noicon';
+            this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
             this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
         }
     },
@@ -26869,9 +30895,10 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
 
         if(this.repeat){
             var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
-            this.mon(repeater, 'click', this.onClick, this);
+            this.mon(repeater, 'click', this.onRepeatClick, this);
+        }else{
+            this.mon(btn, this.clickEvent, this.onClick, this);
         }
-        this.mon(btn, this.clickEvent, this.onClick, this);
     },
 
     
@@ -26926,8 +30953,8 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
         if(this.rendered){
             this.clearTip();
         }
-        if(this.menu && this.menu.autoDestroy) {
-            Ext.destroy(this.menu);
+        if(this.menu && this.destroyMenu !== false) {
+            Ext.destroy(this.btnEl, this.menu);
         }
         Ext.destroy(this.repeater);
     },
@@ -26941,11 +30968,12 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             delete this.btnEl;
             Ext.ButtonToggleMgr.unregister(this);
         }
+        Ext.Button.superclass.onDestroy.call(this);
     },
 
     
     doAutoWidth : function(){
-        if(this.el && this.text && this.width === undefined){
+        if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
             this.el.setWidth('auto');
             if(Ext.isIE7 && Ext.isStrict){
                 var ib = this.btnEl;
@@ -27014,11 +31042,6 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     },
 
     
-    focus : function(){
-        this.btnEl.focus();
-    },
-
-    
     onDisable : function(){
         this.onDisableChange(true);
     },
@@ -27044,6 +31067,10 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             if(this.tooltip){
                 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
             }
+            if(this.menu.isVisible()){
+                this.menu.hide();
+            }
+            this.menu.ownerCt = this;
             this.menu.show(this.el, this.menuAlign);
         }
         return this;
@@ -27051,7 +31078,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
 
     
     hideMenu : function(){
-        if(this.menu){
+        if(this.hasVisibleMenu()){
             this.menu.hide();
         }
         return this;
@@ -27059,7 +31086,12 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
 
     
     hasVisibleMenu : function(){
-        return this.menu && this.menu.isVisible();
+        return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
+    },
+    
+    
+    onRepeatClick : function(repeat, e){
+        this.onClick(e);
     },
 
     
@@ -27071,10 +31103,8 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             return;
         }
         if(!this.disabled){
-            if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
-                this.toggle();
-            }
-            if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
+            this.doToggle();
+            if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
                 this.showMenu();
             }
             this.fireEvent('click', this, e);
@@ -27084,6 +31114,13 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             }
         }
     },
+    
+    
+    doToggle: function(){
+        if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) {
+            this.toggle();
+        }
+    },
 
     
     isMenuTriggerOver : function(e, internal){
@@ -27174,17 +31211,21 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     },
     
     onMenuShow : function(e){
-        this.menu.ownerCt = this;
-        this.ignoreNextClick = 0;
-        this.el.addClass('x-btn-menu-active');
-        this.fireEvent('menushow', this, this.menu);
+        if(this.menu.ownerCt == this){
+            this.menu.ownerCt = this;
+            this.ignoreNextClick = 0;
+            this.el.addClass('x-btn-menu-active');
+            this.fireEvent('menushow', this, this.menu);
+        }
     },
     
     onMenuHide : function(e){
-        this.el.removeClass('x-btn-menu-active');
-        this.ignoreNextClick = this.restoreClick.defer(250, this);
-        this.fireEvent('menuhide', this, this.menu);
-        delete this.menu.ownerCt;
+        if(this.menu.ownerCt == this){
+            this.el.removeClass('x-btn-menu-active');
+            this.ignoreNextClick = this.restoreClick.defer(250, this);
+            this.fireEvent('menuhide', this, this.menu);
+            delete this.menu.ownerCt;
+        }
     },
 
     
@@ -27193,6 +31234,11 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     }
 
     
+    
+    
+    
+    
+    
 });
 Ext.reg('button', Ext.Button);
 
@@ -27303,9 +31349,7 @@ Ext.SplitButton = Ext.extend(Ext.Button, {
                     this.arrowHandler.call(this.scope || this, this, e);
                 }
             }else{
-                if(this.enableToggle){
-                    this.toggle();
-                }
+                this.doToggle();
                 this.fireEvent("click", this, e);
                 if(this.handler){
                     this.handler.call(this.scope || this, this, e);
@@ -27365,7 +31409,7 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
             }
             this.activeItem = item;
             if(!item.checked){
-                item.setChecked(true, true);
+                item.setChecked(true, false);
             }
             if(this.forceIcon){
                 this.setIconClass(this.forceIcon);
@@ -27396,7 +31440,7 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
         this.itemCount = this.items.length;
 
         this.menu = {cls:'x-cycle-menu', items:[]};
-        var checked;
+        var checked = 0;
         Ext.each(this.items, function(item, i){
             Ext.apply(item, {
                 group: item.group || this.id,
@@ -27407,13 +31451,12 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
             });
             this.menu.items.push(item);
             if(item.checked){
-                checked = item;
+                checked = i;
             }
         }, this);
-        this.setActiveItem(checked, true);
         Ext.CycleButton.superclass.initComponent.call(this);
-
         this.on('click', this.toggleSelected, this);
+        this.setActiveItem(checked, true);
     },
 
     
@@ -27446,261 +31489,6 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
     }
 });
 Ext.reg('cycle', Ext.CycleButton);
-Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
-    monitorResize : true,
-    triggerWidth : 18,
-    lastOverflow : false,
-    forceLayout: true,
-
-    noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
-    
-    onLayout : function(ct, target){
-        if(!this.leftTr){
-            var align = ct.buttonAlign == 'center' ? 'center' : 'left';
-            target.addClass('x-toolbar-layout-ct');
-            target.insertHtml('beforeEnd',
-                 '<table cellspacing="0" class="x-toolbar-ct"><tbody><tr><td class="x-toolbar-left" align="' + align + '"><table cellspacing="0"><tbody><tr class="x-toolbar-left-row"></tr></tbody></table></td><td class="x-toolbar-right" align="right"><table cellspacing="0" class="x-toolbar-right-ct"><tbody><tr><td><table cellspacing="0"><tbody><tr class="x-toolbar-right-row"></tr></tbody></table></td><td><table cellspacing="0"><tbody><tr class="x-toolbar-extras-row"></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>');
-            this.leftTr = target.child('tr.x-toolbar-left-row', true);
-            this.rightTr = target.child('tr.x-toolbar-right-row', true);
-            this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
-        }
-        var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
-            pos = 0,
-            items = ct.items.items;
-
-        for(var i = 0, len = items.length, c; i < len; i++, pos++) {
-            c = items[i];
-            if(c.isFill){
-                side = this.rightTr;
-                pos = -1;
-            }else if(!c.rendered){
-                c.render(this.insertCell(c, side, pos));
-            }else{
-                if(!c.xtbHidden && !this.isValidParent(c, side.childNodes[pos])){
-                    var td = this.insertCell(c, side, pos);
-                    td.appendChild(c.getPositionEl().dom);
-                    c.container = Ext.get(td);
-                }
-            }
-        }
-        
-        this.cleanup(this.leftTr);
-        this.cleanup(this.rightTr);
-        this.cleanup(this.extrasTr);
-        this.fitToSize(target);
-    },
-
-    cleanup : function(row){
-        var cn = row.childNodes;
-        for(var i = cn.length-1, c; i >= 0 && (c = cn[i]); i--){
-            if(!c.firstChild){
-                row.removeChild(c);
-            }
-        }
-    },
-
-    insertCell : function(c, side, pos){
-        var td = document.createElement('td');
-        td.className='x-toolbar-cell';
-        side.insertBefore(td, side.childNodes[pos]||null);
-        return td;
-    },
-
-    hideItem : function(item){
-        var h = (this.hiddens = this.hiddens || []);
-        h.push(item);
-        item.xtbHidden = true;
-        item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
-        item.hide();
-    },
-
-    unhideItem : function(item){
-        item.show();
-        item.xtbHidden = false;
-        this.hiddens.remove(item);
-        if(this.hiddens.length < 1){
-            delete this.hiddens;
-        }
-    },
-
-    getItemWidth : function(c){
-        return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
-    },
-
-    fitToSize : function(t){
-        if(this.container.enableOverflow === false){
-            return;
-        }
-        var w = t.dom.clientWidth,
-            lw = this.lastWidth || 0,
-            iw = t.dom.firstChild.offsetWidth,
-            clipWidth = w - this.triggerWidth,
-            hideIndex = -1;
-
-        this.lastWidth = w;
-
-        if(iw > w || (this.hiddens && w >= lw)){
-            var i, items = this.container.items.items,
-                len = items.length, c,
-                loopWidth = 0;
-
-            for(i = 0; i < len; i++) {
-                c = items[i];
-                if(!c.isFill){
-                    loopWidth += this.getItemWidth(c);
-                    if(loopWidth > clipWidth){
-                        if(!(c.hidden || c.xtbHidden)){
-                            this.hideItem(c);
-                        }
-                    }else if(c.xtbHidden){
-                        this.unhideItem(c);
-                    }
-                }
-            }
-        }
-        if(this.hiddens){
-            this.initMore();
-            if(!this.lastOverflow){
-                this.container.fireEvent('overflowchange', this.container, true);
-                this.lastOverflow = true;
-            }
-        }else if(this.more){
-            this.clearMenu();
-            this.more.destroy();
-            delete this.more;
-            if(this.lastOverflow){
-                this.container.fireEvent('overflowchange', this.container, false);
-                this.lastOverflow = false;
-            }
-        }
-    },
-
-    createMenuConfig : function(c, hideOnClick){
-        var cfg = Ext.apply({}, c.initialConfig),
-            group = c.toggleGroup;
-
-        Ext.apply(cfg, {
-            text: c.overflowText || c.text,
-            iconCls: c.iconCls,
-            icon: c.icon,
-            itemId: c.itemId,
-            disabled: c.disabled,
-            handler: c.handler,
-            scope: c.scope,
-            menu: c.menu,
-            hideOnClick: hideOnClick
-        });
-        if(group || c.enableToggle){
-            Ext.apply(cfg, {
-                group: group,
-                checked: c.pressed,
-                listeners: {
-                    checkchange: function(item, checked){
-                        c.toggle(checked);
-                    }
-                }
-            });
-        }
-        delete cfg.ownerCt;
-        delete cfg.xtype;
-        delete cfg.id;
-        return cfg;
-    },
-
-    
-    addComponentToMenu : function(m, c){
-        if(c instanceof Ext.Toolbar.Separator){
-            m.add('-');
-        }else if(Ext.isFunction(c.isXType)){
-            if(c.isXType('splitbutton')){
-                m.add(this.createMenuConfig(c, true));
-            }else if(c.isXType('button')){
-                m.add(this.createMenuConfig(c, !c.menu));
-            }else if(c.isXType('buttongroup')){
-                c.items.each(function(item){
-                     this.addComponentToMenu(m, item);
-                }, this);
-            }
-        }
-    },
-
-    clearMenu : function(){
-        var m = this.moreMenu;
-        if(m && m.items){
-            m.items.each(function(item){
-                delete item.menu;
-            });
-        }
-    },
-
-    
-    beforeMoreShow : function(m){
-        var h = this.container.items.items,
-            len = h.length,
-            c,
-            prev,
-            needsSep = function(group, item){
-                return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
-            };
-
-        this.clearMenu();
-        m.removeAll();
-        for(var i = 0; i < len; i++){
-            c = h[i];
-            if(c.xtbHidden){
-                if(prev && (needsSep(c, prev) || needsSep(prev, c))){
-                    m.add('-');
-                }
-                this.addComponentToMenu(m, c);
-                prev = c;
-            }
-        }
-        
-        
-        if(m.items.length < 1){
-            m.add(this.noItemsMenuText);
-        }
-    },
-
-    initMore : function(){
-        if(!this.more){
-            this.moreMenu = new Ext.menu.Menu({
-                listeners: {
-                    beforeshow: this.beforeMoreShow,
-                    scope: this
-                }
-            });
-            this.moreMenu.ownerCt = this.container;
-            this.more = new Ext.Button({
-                iconCls: 'x-toolbar-more-icon',
-                cls: 'x-toolbar-more',
-                menu: this.moreMenu
-            });
-            var td = this.insertCell(this.more, this.extrasTr, 100);
-            this.more.render(td);
-        }
-    },
-
-    onRemove : function(c){
-        delete this.leftTr;
-        delete this.rightTr;
-        delete this.extrasTr;
-        Ext.layout.ToolbarLayout.superclass.onRemove.call(this, c);
-    },
-
-    destroy : function(){
-        Ext.destroy(this.more, this.moreMenu);
-        delete this.leftTr;
-        delete this.rightTr;
-        delete this.extrasTr;
-        Ext.layout.ToolbarLayout.superclass.destroy.call(this);
-    }
-    
-});
-
-Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
-
-
 Ext.Toolbar = function(config){
     if(Ext.isArray(config)){
         config = {items: config, layout: 'toolbar'};
@@ -27724,6 +31512,10 @@ Ext.extend(T, Ext.Container, {
     defaultType: 'button',
 
     
+
+    enableOverflow : false,
+
+    
     
 
     trackMenus : true,
@@ -27878,11 +31670,17 @@ Ext.extend(T, Ext.Container, {
     onAdd : function(c){
         Ext.Toolbar.superclass.onAdd.call(this);
         this.trackMenu(c);
+        if(this.disabled){
+            c.disable();
+        }
     },
 
     
     onRemove : function(c){
         Ext.Toolbar.superclass.onRemove.call(this);
+        if (c == this.activeMenuBtn) {
+            delete this.activeMenuBtn;
+        }
         this.trackMenu(c, true);
     },
 
@@ -28370,7 +32168,7 @@ Ext.History = (function () {
     var currentToken;
 
     function getHash() {
-        var href = top.location.href, i = href.indexOf("#");
+        var href = location.href, i = href.indexOf("#");
         return i >= 0 ? href.substr(i + 1) : null;
     }
 
@@ -28675,7 +32473,7 @@ Ext.ToolTip = Ext.extend(Ext.Tip, {
     
     afterRender : function(){
         Ext.ToolTip.superclass.afterRender.call(this);
-        this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1);
+        this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
     },
 
     
@@ -28735,7 +32533,7 @@ Ext.ToolTip = Ext.extend(Ext.Tip, {
                 bd = document.body,
                 scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
                 scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
-                axy = [xy[0] + offsets[0], xy[1] + offsets[1]]
+                axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
                 sz = this.getSize();
                 
             this.anchorEl.removeClass(this.anchorCls);
@@ -28935,8 +32733,8 @@ Ext.ToolTip = Ext.extend(Ext.Tip, {
         this.showAt(this.getTargetXY());
 
         if(this.anchor){
-            this.syncAnchor();
             this.anchorEl.show();
+            this.syncAnchor();
             this.constrainPosition = this.origConstrainPosition;
         }else{
             this.anchorEl.hide();
@@ -28954,6 +32752,8 @@ Ext.ToolTip = Ext.extend(Ext.Tip, {
         if(this.anchor && !this.anchorEl.isVisible()){
             this.syncAnchor();
             this.anchorEl.show();
+        }else{
+            this.anchorEl.hide();
         }
     },
 
@@ -29023,7 +32823,14 @@ Ext.ToolTip = Ext.extend(Ext.Tip, {
     onDocMouseDown : function(e){
         if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
             this.disable();
-            this.enable.defer(100, this);
+            this.doEnable.defer(100, this);
+        }
+    },
+    
+    
+    doEnable : function(){
+        if(!this.isDestroyed){
+            this.enable();
         }
     },
 
@@ -29246,7 +33053,9 @@ Ext.QuickTip = Ext.extend(Ext.ToolTip, {
 });
 Ext.reg('quicktip', Ext.QuickTip);
 Ext.QuickTips = function(){
-    var tip, locks = [];
+    var tip,
+        disabled = false;
+        
     return {
         
         init : function(autoRender){
@@ -29257,21 +33066,38 @@ Ext.QuickTips = function(){
                     });
                     return;
                 }
-                tip = new Ext.QuickTip({elements:'header,body'});
+                tip = new Ext.QuickTip({
+                    elements:'header,body', 
+                    disabled: disabled
+                });
                 if(autoRender !== false){
                     tip.render(Ext.getBody());
                 }
             }
         },
+        
+        
+        ddDisable : function(){
+            
+            if(tip && !disabled){
+                tip.disable();
+            }    
+        },
+        
+        
+        ddEnable : function(){
+            
+            if(tip && !disabled){
+                tip.enable();
+            }
+        },
 
         
         enable : function(){
             if(tip){
-                locks.pop();
-                if(locks.length < 1){
-                    tip.enable();
-                }
+                tip.enable();
             }
+            disabled = false;
         },
 
         
@@ -29279,7 +33105,7 @@ Ext.QuickTips = function(){
             if(tip){
                 tip.disable();
             }
-            locks.push(1);
+            disabled = true;
         },
 
         
@@ -29303,11 +33129,41 @@ Ext.QuickTips = function(){
         },
 
         
-        tips :function(){
+        tips : function(){
             tip.register.apply(tip, arguments);
         }
-    }
+    };
 }();
+Ext.slider.Tip = Ext.extend(Ext.Tip, {
+    minWidth: 10,
+    offsets : [0, -10],
+    
+    init: function(slider) {
+        slider.on({
+            scope    : this,
+            dragstart: this.onSlide,
+            drag     : this.onSlide,
+            dragend  : this.hide,
+            destroy  : this.destroy
+        });
+    },
+    
+    
+    onSlide : function(slider, e, thumb) {
+        this.show();
+        this.body.update(this.getText(thumb));
+        this.doAutoWidth();
+        this.el.alignTo(thumb.el, 'b-t?', this.offsets);
+    },
+
+    
+    getText : function(thumb) {
+        return String(thumb.value);
+    }
+});
+
+
+Ext.ux.SliderTip = Ext.slider.Tip;
 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
     rootVisible : true,
     animate : Ext.enableFx,
@@ -29438,7 +33294,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
 
     
     setRootNode : function(node){
-        Ext.destroy(this.root);
+        this.destroyRoot();
         if(!node.render){ 
             node = this.loader.createNode(node);
         }
@@ -29450,12 +33306,24 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
             var uiP = node.attributes.uiProvider;
             node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
         }
-        if (this.innerCt) {
-            this.innerCt.update('');
-            this.afterRender();
+        if(this.innerCt){
+            this.clearInnerCt();
+            this.renderRoot();
         }
         return node;
     },
+    
+    clearInnerCt : function(){
+        this.innerCt.update('');    
+    },
+    
+    
+    renderRoot : function(){
+        this.root.render();
+        if(!this.rootVisible){
+            this.root.renderChildren();
+        }
+    },
 
     
     getNodeById : function(id){
@@ -29526,6 +33394,12 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
 
     
     expandPath : function(path, attr, callback){
+        if(Ext.isEmpty(path)){
+            if(callback){
+                callback(false, undefined);
+            }
+            return;
+        }
         attr = attr || 'id';
         var keys = path.split(this.pathSeparator);
         var curNode = this.root;
@@ -29558,6 +33432,12 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
 
     
     selectPath : function(path, attr, callback){
+        if(Ext.isEmpty(path)){
+            if(callback){
+                callback(false, undefined);
+            }
+            return;
+        }
         attr = attr || 'id';
         var keys = path.split(this.pathSeparator),
             v = keys.pop();
@@ -29628,10 +33508,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
     
     afterRender : function(){
         Ext.tree.TreePanel.superclass.afterRender.call(this);
-        this.root.render();
-        if(!this.rootVisible){
-            this.root.renderChildren();
-        }
+        this.renderRoot();
     },
 
     beforeDestroy : function(){
@@ -29639,9 +33516,17 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
             Ext.dd.ScrollManager.unregister(this.body);
             Ext.destroy(this.dropZone, this.dragZone);
         }
-        Ext.destroy(this.root, this.loader);
+        this.destroyRoot();
+        Ext.destroy(this.loader);
         this.nodeHash = this.root = this.loader = null;
         Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
+    },
+    
+    
+    destroyRoot : function(){
+        if(this.root && this.root.destroy){
+            this.root.destroy(true);
+        }
     }
 
     
@@ -29687,6 +33572,9 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
     
     
     
+    
+    
+    
     
     
     
@@ -29698,12 +33586,12 @@ Ext.tree.TreePanel.nodeTypes = {};
 Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
     this.tree = tree;
     this.tree.on('render', this.initEvents, this);
-}
+};
 
 Ext.tree.TreeEventModel.prototype = {
     initEvents : function(){
         var t = this.tree;
-            
+
         if(t.trackMouseOver !== false){
             t.mon(t.innerCt, {
                 scope: this,
@@ -29776,12 +33664,15 @@ Ext.tree.TreeEventModel.prototype = {
     },
 
     trackExit : function(e){
-        if(this.lastOverNode && !e.within(this.lastOverNode.ui.getEl())){
-            this.onNodeOut(e, this.lastOverNode);
+        if(this.lastOverNode){
+            if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
+                this.onNodeOut(e, this.lastOverNode);
+            }
             delete this.lastOverNode;
             Ext.getBody().un('mouseover', this.trackExit, this);
             this.trackingDoc = false;
         }
+
     },
 
     delegateClick : function(e, t){
@@ -29792,9 +33683,9 @@ Ext.tree.TreeEventModel.prototype = {
                 this.onIconClick(e, this.getNode(e));
             }else if(this.getNodeTarget(e)){
                 this.onNodeClick(e, this.getNode(e));
-            }else{
-                this.onContainerEvent(e, 'click');
             }
+        }else{
+            this.checkContainerEvent(e, 'click');
         }
     },
 
@@ -29802,9 +33693,9 @@ Ext.tree.TreeEventModel.prototype = {
         if(this.beforeEvent(e)){
             if(this.getNodeTarget(e)){
                 this.onNodeDblClick(e, this.getNode(e));
-            }else{
-                this.onContainerEvent(e, 'dblclick');    
             }
+        }else{
+            this.checkContainerEvent(e, 'dblclick');
         }
     },
 
@@ -29812,14 +33703,22 @@ Ext.tree.TreeEventModel.prototype = {
         if(this.beforeEvent(e)){
             if(this.getNodeTarget(e)){
                 this.onNodeContextMenu(e, this.getNode(e));
-            }else{
-                this.onContainerEvent(e, 'contextmenu');    
             }
+        }else{
+            this.checkContainerEvent(e, 'contextmenu');
         }
     },
     
+    checkContainerEvent: function(e, type){
+        if(this.disabled){
+            e.stopEvent();
+            return false;
+        }
+        this.onContainerEvent(e, type);    
+    },
+
     onContainerEvent: function(e, type){
-        this.tree.fireEvent('container' + type, this.tree, e); 
+        this.tree.fireEvent('container' + type, this.tree, e);
     },
 
     onNodeClick : function(e, node){
@@ -29860,7 +33759,8 @@ Ext.tree.TreeEventModel.prototype = {
     },
 
     beforeEvent : function(e){
-        if(this.disabled){
+        var node = this.getNode(e);
+        if(this.disabled || !node || !node.ui){
             e.stopEvent();
             return false;
         }
@@ -29875,22 +33775,23 @@ Ext.tree.TreeEventModel.prototype = {
         this.disabled = false;
     }
 };
-Ext.tree.DefaultSelectionModel = function(config){
-   this.selNode = null;
+Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
+    
+    constructor : function(config){
+        this.selNode = null;
    
-   this.addEvents(
-       
-       'selectionchange',
-
-       
-       'beforeselect'
-   );
+        this.addEvents(
+            
+            'selectionchange',
 
-    Ext.apply(this, config);
-    Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
-};
+            
+            'beforeselect'
+        );
 
-Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
+        Ext.apply(this, config);
+        Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);    
+    },
+    
     init : function(tree){
         this.tree = tree;
         tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
@@ -30037,18 +33938,19 @@ Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
 });
 
 
-Ext.tree.MultiSelectionModel = function(config){
-   this.selNodes = [];
-   this.selMap = {};
-   this.addEvents(
-       
-       'selectionchange'
-   );
-    Ext.apply(this, config);
-    Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
-};
-
-Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
+Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {
+    
+    constructor : function(config){
+        this.selNodes = [];
+        this.selMap = {};
+        this.addEvents(
+            
+            'selectionchange'
+        );
+        Ext.apply(this, config);
+        Ext.tree.MultiSelectionModel.superclass.constructor.call(this);    
+    },
+    
     init : function(tree){
         this.tree = tree;
         tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
@@ -30116,7 +34018,7 @@ Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
     
     
     getSelectedNodes : function(){
-        return this.selNodes;    
+        return this.selNodes.concat([]);
     },
 
     onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
@@ -30125,36 +34027,36 @@ Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
 
     selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
 });
-Ext.data.Tree = function(root){
-   this.nodeHash = {};
-   
-   this.root = null;
-   if(root){
-       this.setRootNode(root);
-   }
-   this.addEvents(
-       
-       "append",
-       
-       "remove",
-       
-       "move",
-       
-       "insert",
-       
-       "beforeappend",
-       
-       "beforeremove",
-       
-       "beforemove",
-       
-       "beforeinsert"
-   );
-
-    Ext.data.Tree.superclass.constructor.call(this);
-};
-
-Ext.extend(Ext.data.Tree, Ext.util.Observable, {
+Ext.data.Tree = Ext.extend(Ext.util.Observable, {
+    
+    constructor: function(root){
+        this.nodeHash = {};
+        
+        this.root = null;
+        if(root){
+            this.setRootNode(root);
+        }
+        this.addEvents(
+            
+            "append",
+            
+            "remove",
+            
+            "move",
+            
+            "insert",
+            
+            "beforeappend",
+            
+            "beforeremove",
+            
+            "beforemove",
+            
+            "beforeinsert"
+        );
+        Ext.data.Tree.superclass.constructor.call(this);        
+    },
+    
     
     pathSeparator: "/",
 
@@ -30198,62 +34100,53 @@ Ext.extend(Ext.data.Tree, Ext.util.Observable, {
 });
 
 
-Ext.data.Node = function(attributes){
+Ext.data.Node = Ext.extend(Ext.util.Observable, {
     
-    this.attributes = attributes || {};
-    this.leaf = this.attributes.leaf;
-    
-    this.id = this.attributes.id;
-    if(!this.id){
-        this.id = Ext.id(null, "xnode-");
-        this.attributes.id = this.id;
-    }
-    
-    this.childNodes = [];
-    if(!this.childNodes.indexOf){ 
-        this.childNodes.indexOf = function(o){
-            for(var i = 0, len = this.length; i < len; i++){
-                if(this[i] == o){
-                    return i;
-                }
-            }
-            return -1;
-        };
-    }
-    
-    this.parentNode = null;
-    
-    this.firstChild = null;
-    
-    this.lastChild = null;
-    
-    this.previousSibling = null;
-    
-    this.nextSibling = null;
-
-    this.addEvents({
-       
-       "append" : true,
-       
-       "remove" : true,
-       
-       "move" : true,
-       
-       "insert" : true,
-       
-       "beforeappend" : true,
-       
-       "beforeremove" : true,
-       
-       "beforemove" : true,
-       
-       "beforeinsert" : true
-   });
-    this.listeners = this.attributes.listeners;
-    Ext.data.Node.superclass.constructor.call(this);
-};
+    constructor: function(attributes){
+        
+        this.attributes = attributes || {};
+        this.leaf = this.attributes.leaf;
+        
+        this.id = this.attributes.id;
+        if(!this.id){
+            this.id = Ext.id(null, "xnode-");
+            this.attributes.id = this.id;
+        }
+        
+        this.childNodes = [];
+        
+        this.parentNode = null;
+        
+        this.firstChild = null;
+        
+        this.lastChild = null;
+        
+        this.previousSibling = null;
+        
+        this.nextSibling = null;
 
-Ext.extend(Ext.data.Node, Ext.util.Observable, {
+        this.addEvents({
+            
+            "append" : true,
+            
+            "remove" : true,
+            
+            "move" : true,
+            
+            "insert" : true,
+            
+            "beforeappend" : true,
+            
+            "beforeremove" : true,
+            
+            "beforemove" : true,
+             
+            "beforeinsert" : true
+        });
+        this.listeners = this.attributes.listeners;
+        Ext.data.Node.superclass.constructor.call(this);    
+    },
+    
     
     fireEvent : function(evtName){
         
@@ -30300,7 +34193,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
     hasChildNodes : function(){
         return !this.isLeaf() && this.childNodes.length > 0;
     },
-    
+
     
     isExpandable : function(){
         return this.attributes.expandable || this.hasChildNodes();
@@ -30317,7 +34210,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
         
         if(multi){
             for(var i = 0, len = multi.length; i < len; i++) {
-               this.appendChild(multi[i]);
+                this.appendChild(multi[i]);
             }
         }else{
             if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
@@ -30385,32 +34278,38 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
             this.setLastChild(node.previousSibling);
         }
 
-        node.clear();
         this.fireEvent("remove", this.ownerTree, this, node);
         if(destroy){
-            node.destroy();
+            node.destroy(true);
+        }else{
+            node.clear();
         }
         return node;
     },
-    
+
     
     clear : function(destroy){
         
         this.setOwnerTree(null, destroy);
-        this.parentNode = this.previousSibling = this.nextSibling = null
+        this.parentNode = this.previousSibling = this.nextSibling = null;
         if(destroy){
-            this.firstChild = this.lastChild = null; 
+            this.firstChild = this.lastChild = null;
         }
     },
+
     
-    
-    destroy : function(){
-        this.purgeListeners();
-        this.clear(true);  
-        Ext.each(this.childNodes, function(n){
-            n.destroy();
-        });
-        this.childNodes = null;
+    destroy : function( silent){
+        
+        if(silent === true){
+            this.purgeListeners();
+            this.clear(true);
+            Ext.each(this.childNodes, function(n){
+                n.destroy(true);
+            });
+            this.childNodes = null;
+        }else{
+            this.remove(true);
+        }
     },
 
     
@@ -30466,7 +34365,19 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
 
     
     remove : function(destroy){
-        this.parentNode.removeChild(this, destroy);
+        if (this.parentNode) {
+            this.parentNode.removeChild(this, destroy);
+        }
+        return this;
+    },
+
+    
+    removeAll : function(destroy){
+        var cn = this.childNodes,
+            n;
+        while((n = cn[0])){
+            this.removeChild(n, destroy);
+        }
         return this;
     },
 
@@ -30534,7 +34445,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
             }
         }
     },
-    
+
     
     setId: function(id){
         if(id !== this.id){
@@ -30549,7 +34460,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
             this.onIdChange(id);
         }
     },
-    
+
     
     onIdChange: Ext.emptyFn,
 
@@ -30582,7 +34493,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
         if(fn.apply(scope || this, args || [this]) !== false){
             var cs = this.childNodes;
             for(var i = 0, len = cs.length; i < len; i++) {
-               cs[i].cascade(fn, scope, args);
+                cs[i].cascade(fn, scope, args);
             }
         }
     },
@@ -30591,30 +34502,37 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
     eachChild : function(fn, scope, args){
         var cs = this.childNodes;
         for(var i = 0, len = cs.length; i < len; i++) {
-               if(fn.apply(scope || this, args || [cs[i]]) === false){
-                   break;
-               }
+            if(fn.apply(scope || cs[i], args || [cs[i]]) === false){
+                break;
+            }
         }
     },
 
     
-    findChild : function(attribute, value){
-        var cs = this.childNodes;
-        for(var i = 0, len = cs.length; i < len; i++) {
-               if(cs[i].attributes[attribute] == value){
-                   return cs[i];
-               }
-        }
-        return null;
+    findChild : function(attribute, value, deep){
+        return this.findChildBy(function(){
+            return this.attributes[attribute] == value;
+        }, null, deep);
     },
 
     
-    findChildBy : function(fn, scope){
-        var cs = this.childNodes;
-        for(var i = 0, len = cs.length; i < len; i++) {
-               if(fn.call(scope||cs[i], cs[i]) === true){
-                   return cs[i];
-               }
+    findChildBy : function(fn, scope, deep){
+        var cs = this.childNodes,
+            len = cs.length,
+            i = 0,
+            n,
+            res;
+        for(; i < len; i++){
+            n = cs[i];
+            if(fn.call(scope || n, n) === true){
+                return n;
+            }else if (deep){
+                res = n.findChildBy(fn, scope, deep);
+                if(res != null){
+                    return res;
+                }
+            }
+            
         }
         return null;
     },
@@ -30661,61 +34579,63 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
         return "[Node"+(this.id?" "+this.id:"")+"]";
     }
 });
-Ext.tree.TreeNode = function(attributes){
-    attributes = attributes || {};
-    if(Ext.isString(attributes)){
-        attributes = {text: attributes};
-    }
-    this.childrenRendered = false;
-    this.rendered = false;
-    Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
-    this.expanded = attributes.expanded === true;
-    this.isTarget = attributes.isTarget !== false;
-    this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
-    this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
-
+Ext.tree.TreeNode = Ext.extend(Ext.data.Node, {
     
-    this.text = attributes.text;
-    
-    this.disabled = attributes.disabled === true;
-    
-    this.hidden = attributes.hidden === true;
+    constructor : function(attributes){
+        attributes = attributes || {};
+        if(Ext.isString(attributes)){
+            attributes = {text: attributes};
+        }
+        this.childrenRendered = false;
+        this.rendered = false;
+        Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
+        this.expanded = attributes.expanded === true;
+        this.isTarget = attributes.isTarget !== false;
+        this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
+        this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
 
-    this.addEvents(
-        
-        'textchange',
-        
-        'beforeexpand',
-        
-        'beforecollapse',
-        
-        'expand',
-        
-        'disabledchange',
-        
-        'collapse',
-        
-        'beforeclick',
         
-        'click',
+        this.text = attributes.text;
         
-        'checkchange',
+        this.disabled = attributes.disabled === true;
         
-        'beforedblclick',
-        
-        'dblclick',
-        
-        'contextmenu',
+        this.hidden = attributes.hidden === true;
+    
+        this.addEvents(
+            
+            'textchange',
+            
+            'beforeexpand',
+            
+            'beforecollapse',
+            
+            'expand',
+            
+            'disabledchange',
+            
+            'collapse',
+            
+            'beforeclick',
+            
+            'click',
+            
+            'checkchange',
+            
+            'beforedblclick',
+            
+            'dblclick',
+            
+            'contextmenu',
+            
+            'beforechildrenrendered'
+        );
+    
+        var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
+    
         
-        'beforechildrenrendered'
-    );
-
-    var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
-
+        this.ui = new uiClass(this);    
+    },
     
-    this.ui = new uiClass(this);
-};
-Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
     preventHScroll : true,
     
     isExpanded : function(){
@@ -30775,16 +34695,20 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
         this.ownerTree.getSelectionModel().unselect(node);
         Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
         
-        if(node.ui.rendered){
-            node.ui.remove();
-        }
-        if(this.childNodes.length < 1){
-            this.collapse(false, false);
-        }else{
-            this.ui.updateExpandIcon();
-        }
-        if(!this.firstChild && !this.isHiddenRoot()) {
-            this.childrenRendered = false;
+        if(!destroy){
+            var rendered = node.ui.rendered;
+            
+            if(rendered){
+                node.ui.remove();
+            }
+            if(rendered && this.childNodes.length < 1){
+                this.collapse(false, false);
+            }else{
+                this.ui.updateExpandIcon();
+            }
+            if(!this.firstChild && !this.isHiddenRoot()){
+                this.childrenRendered = false;
+            }
         }
         return node;
     },
@@ -30811,6 +34735,50 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
         }
         this.fireEvent('textchange', this, text, oldText);
     },
+    
+    
+    setIconCls : function(cls){
+        var old = this.attributes.iconCls;
+        this.attributes.iconCls = cls;
+        if(this.rendered){
+            this.ui.onIconClsChange(this, cls, old);
+        }
+    },
+    
+    
+    setTooltip : function(tip, title){
+        this.attributes.qtip = tip;
+        this.attributes.qtipTitle = title;
+        if(this.rendered){
+            this.ui.onTipChange(this, tip, title);
+        }
+    },
+    
+    
+    setIcon : function(icon){
+        this.attributes.icon = icon;
+        if(this.rendered){
+            this.ui.onIconChange(this, icon);
+        }
+    },
+    
+    
+    setHref : function(href, target){
+        this.attributes.href = href;
+        this.attributes.hrefTarget = target;
+        if(this.rendered){
+            this.ui.onHrefChange(this, href, target);
+        }
+    },
+    
+    
+    setCls : function(cls){
+        var old = this.attributes.cls;
+        this.attributes.cls = cls;
+        if(this.rendered){
+            this.ui.onClsChange(this, cls, old);
+        }
+    },
 
     
     select : function(){
@@ -30849,7 +34817,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
                     this.fireEvent('expand', this);
                     this.runCallback(callback, scope || this, [this]);
                     if(deep === true){
-                        this.expandChildNodes(true);
+                        this.expandChildNodes(true, true);
                     }
                 }.createDelegate(this));
                 return;
@@ -30943,10 +34911,12 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
     },
 
     
-    expandChildNodes : function(deep){
-        var cs = this.childNodes;
-        for(var i = 0, len = cs.length; i < len; i++) {
-               cs[i].expand(deep);
+    expandChildNodes : function(deep, anim) {
+        var cs = this.childNodes,
+            i,
+            len = cs.length;
+        for (i = 0; i < len; i++) {
+               cs[i].expand(deep, anim);
         }
     },
 
@@ -31038,9 +35008,12 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
         }
     },
 
-    destroy : function(){
-        this.unselect(true);
-        Ext.tree.TreeNode.superclass.destroy.call(this);
+    
+    destroy : function(silent){
+        if(silent === true){
+            this.unselect(true);
+        }
+        Ext.tree.TreeNode.superclass.destroy.call(this, silent);
         Ext.destroy(this.ui, this.loader);
         this.ui = this.loader = null;
     },
@@ -31131,21 +35104,24 @@ Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
 });
 
 Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
-Ext.tree.TreeNodeUI = function(node){
-    this.node = node;
-    this.rendered = false;
-    this.animating = false;
-    this.wasLeaf = true;
-    this.ecc = 'x-tree-ec-icon x-tree-elbow';
-    this.emptyIcon = Ext.BLANK_IMAGE_URL;
-};
-
-Ext.tree.TreeNodeUI.prototype = {
+Ext.tree.TreeNodeUI = Ext.extend(Object, {
+    
+    constructor : function(node){
+        Ext.apply(this, {
+            node: node,
+            rendered: false,
+            animating: false,
+            wasLeaf: true,
+            ecc: 'x-tree-ec-icon x-tree-elbow',
+            emptyIcon: Ext.BLANK_IMAGE_URL    
+        });
+    },
+    
     
     removeChild : function(node){
         if(this.rendered){
             this.ctNode.removeChild(node.ui.getEl());
-        } 
+        }
     },
 
     
@@ -31164,18 +35140,66 @@ Ext.tree.TreeNodeUI.prototype = {
             this.textNode.innerHTML = text;
         }
     },
+    
+    
+    onIconClsChange : function(node, cls, oldCls){
+        if(this.rendered){
+            Ext.fly(this.iconNode).replaceClass(oldCls, cls);
+        }
+    },
+    
+    
+    onIconChange : function(node, icon){
+        if(this.rendered){
+            
+            var empty = Ext.isEmpty(icon);
+            this.iconNode.src = empty ? this.emptyIcon : icon;
+            Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon');
+        }
+    },
+    
+    
+    onTipChange : function(node, tip, title){
+        if(this.rendered){
+            var hasTitle = Ext.isDefined(title);
+            if(this.textNode.setAttributeNS){
+                this.textNode.setAttributeNS("ext", "qtip", tip);
+                if(hasTitle){
+                    this.textNode.setAttributeNS("ext", "qtitle", title);
+                }
+            }else{
+                this.textNode.setAttribute("ext:qtip", tip);
+                if(hasTitle){
+                    this.textNode.setAttribute("ext:qtitle", title);
+                }
+            }
+        }
+    },
+    
+    
+    onHrefChange : function(node, href, target){
+        if(this.rendered){
+            this.anchor.href = this.getHref(href);
+            if(Ext.isDefined(target)){
+                this.anchor.target = target;
+            }
+        }
+    },
+    
+    
+    onClsChange : function(node, cls, oldCls){
+        if(this.rendered){
+            Ext.fly(this.elNode).replaceClass(oldCls, cls);
+        }    
+    },
 
     
     onDisableChange : function(node, state){
         this.disabled = state;
         if (this.checkbox) {
             this.checkbox.disabled = state;
-        }        
-        if(state){
-            this.addClass("x-tree-node-disabled");
-        }else{
-            this.removeClass("x-tree-node-disabled");
-        } 
+        }
+        this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled');
     },
 
     
@@ -31219,7 +35243,7 @@ Ext.tree.TreeNodeUI.prototype = {
 
     removeClass : function(cls){
         if(this.elNode){
-            Ext.fly(this.elNode).removeClass(cls);  
+            Ext.fly(this.elNode).removeClass(cls);
         }
     },
 
@@ -31228,12 +35252,12 @@ Ext.tree.TreeNodeUI.prototype = {
         if(this.rendered){
             this.holder = document.createElement("div");
             this.holder.appendChild(this.wrap);
-        }  
+        }
     },
 
     
     fireEvent : function(){
-        return this.node.fireEvent.apply(this.node, arguments);  
+        return this.node.fireEvent.apply(this.node, arguments);
     },
 
     
@@ -31241,7 +35265,7 @@ Ext.tree.TreeNodeUI.prototype = {
         this.node.on("move", this.onMove, this);
 
         if(this.node.disabled){
-            this.onDisableChange(this.node, true);            
+            this.onDisableChange(this.node, true);
         }
         if(this.node.hidden){
             this.hide();
@@ -31275,7 +35299,7 @@ Ext.tree.TreeNodeUI.prototype = {
         this.node.hidden = false;
         if(this.wrap){
             this.wrap.style.display = "";
-        } 
+        }
     },
 
     
@@ -31345,7 +35369,7 @@ Ext.tree.TreeNodeUI.prototype = {
     onCheckChange : function(){
         var checked = this.checkbox.checked;
         
-        this.checkbox.defaultChecked = checked;        
+        this.checkbox.defaultChecked = checked;
         this.node.attributes.checked = checked;
         this.fireEvent('checkchange', this.node, checked);
     },
@@ -31361,12 +35385,12 @@ Ext.tree.TreeNodeUI.prototype = {
     startDrop : function(){
         this.dropping = true;
     },
+
     
-    
-    endDrop : function(){ 
+    endDrop : function(){
        setTimeout(function(){
            this.dropping = false;
-       }.createDelegate(this), 50); 
+       }.createDelegate(this), 50);
     },
 
     
@@ -31403,7 +35427,7 @@ Ext.tree.TreeNodeUI.prototype = {
     blur : function(){
         try{
             this.anchor.blur();
-        }catch(e){} 
+        }catch(e){}
     },
 
     
@@ -31418,7 +35442,7 @@ Ext.tree.TreeNodeUI.prototype = {
         }
         this.animating = true;
         this.updateExpandIcon();
-        
+
         ct.slideIn('t', {
            callback : function(){
                this.animating = false;
@@ -31465,12 +35489,12 @@ Ext.tree.TreeNodeUI.prototype = {
 
     
     getContainer : function(){
-        return this.ctNode;  
+        return this.ctNode;
     },
 
 
     getEl : function(){
-        return this.wrap;  
+        return this.wrap;
     },
 
     
@@ -31485,32 +35509,22 @@ Ext.tree.TreeNodeUI.prototype = {
 
     
     onRender : function(){
-        this.render();    
+        this.render();
     },
 
     
     render : function(bulkRender){
         var n = this.node, a = n.attributes;
-        var targetNode = n.parentNode ? 
+        var targetNode = n.parentNode ?
               n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
-        
+
         if(!this.rendered){
             this.rendered = true;
 
             this.renderElements(n, a, targetNode, bulkRender);
 
             if(a.qtip){
-               if(this.textNode.setAttributeNS){
-                   this.textNode.setAttributeNS("ext", "qtip", a.qtip);
-                   if(a.qtipTitle){
-                       this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
-                   }
-               }else{
-                   this.textNode.setAttribute("ext:qtip", a.qtip);
-                   if(a.qtipTitle){
-                       this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
-                   }
-               } 
+                this.onTipChange(n, a.qtip, a.qtipTitle);
             }else if(a.qtipCfg){
                 a.qtipCfg.target = Ext.id(this.textNode);
                 Ext.QuickTips.register(a.qtipCfg);
@@ -31533,11 +35547,11 @@ Ext.tree.TreeNodeUI.prototype = {
 
         var cb = Ext.isBoolean(a.checked),
             nel,
-            href = a.href ? a.href : Ext.isGecko ? "" : "#",
+            href = this.getHref(a.href),
             buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
             '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
-            '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
-            '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
+            '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
+            '<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
             cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
             '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
              a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
@@ -31549,7 +35563,7 @@ Ext.tree.TreeNodeUI.prototype = {
         }else{
             this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
         }
-        
+
         this.elNode = this.wrap.childNodes[0];
         this.ctNode = this.wrap.childNodes[1];
         var cs = this.elNode.childNodes;
@@ -31566,17 +35580,22 @@ Ext.tree.TreeNodeUI.prototype = {
         this.anchor = cs[index];
         this.textNode = cs[index].firstChild;
     },
+    
+    
+    getHref : function(href){
+        return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href;
+    },
 
 
     getAnchor : function(){
         return this.anchor;
     },
-    
+
 
     getTextEl : function(){
         return this.textNode;
     },
-    
+
 
     getIconEl : function(){
         return this.iconNode;
@@ -31584,14 +35603,14 @@ Ext.tree.TreeNodeUI.prototype = {
 
 
     isChecked : function(){
-        return this.checkbox ? this.checkbox.checked : false; 
+        return this.checkbox ? this.checkbox.checked : false;
     },
 
     
     updateExpandIcon : function(){
         if(this.rendered){
-            var n = this.node, 
-                c1, 
+            var n = this.node,
+                c1,
                 c2,
                 cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
                 hasChild = n.hasChildNodes();
@@ -31615,7 +35634,7 @@ Ext.tree.TreeNodeUI.prototype = {
                 }
             }else{
                 if(!this.wasLeaf){
-                    Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
+                    Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
                     delete this.c1;
                     delete this.c2;
                     this.wasLeaf = true;
@@ -31628,7 +35647,7 @@ Ext.tree.TreeNodeUI.prototype = {
             }
         }
     },
-    
+
     
     onIdChange: function(id){
         if(this.rendered){
@@ -31644,9 +35663,9 @@ Ext.tree.TreeNodeUI.prototype = {
             while(p){
                 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
                     if(!p.isLast()) {
-                        buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
+                        buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
                     } else {
-                        buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
+                        buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />');
                     }
                 }
                 p = p.parentNode;
@@ -31676,7 +35695,7 @@ Ext.tree.TreeNodeUI.prototype = {
         if(this.elNode){
             Ext.dd.Registry.unregister(this.elNode.id);
         }
-        
+
         Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
             if(this[el]){
                 Ext.fly(this[el]).remove();
@@ -31685,7 +35704,7 @@ Ext.tree.TreeNodeUI.prototype = {
         }, this);
         delete this.node;
     }
-};
+});
 
 
 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
@@ -31737,7 +35756,7 @@ Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
 
     
     paramsAsHash: false,
-    
+
     
     nodeParameter: 'node',
 
@@ -31777,23 +35796,29 @@ Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
     },
 
     getParams: function(node){
-        var buf = [], bp = this.baseParams;
+        var bp = Ext.apply({}, this.baseParams),
+            np = this.nodeParameter,
+            po = this.paramOrder;
+
+        np && (bp[ np ] = node.id);
+
         if(this.directFn){
-            buf.push(node.id);
-            if(bp){
-                if(this.paramOrder){
-                    for(var i = 0, len = this.paramOrder.length; i < len; i++){
-                        buf.push(bp[this.paramOrder[i]]);
-                    }
-                }else if(this.paramsAsHash){
-                    buf.push(bp);
+            var buf = [node.id];
+            if(po){
+                
+                if(np && po.indexOf(np) > -1){
+                    buf = [];
                 }
+
+                for(var i = 0, len = po.length; i < len; i++){
+                    buf.push(bp[ po[i] ]);
+                }
+            }else if(this.paramsAsHash){
+                buf = [bp];
             }
             return buf;
         }else{
-            var o = Ext.apply({}, bp);
-            o[this.nodeParameter] = node.id;
-            return o;
+            return bp;
         }
     },
 
@@ -31904,8 +35929,9 @@ Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
         this.fireEvent("loadexception", this, a.node, response);
         this.runCallback(a.callback, a.scope || a.node, [a.node]);
     },
-    
+
     destroy : function(){
+        this.abort();
         this.purgeListeners();
     }
 });
@@ -31997,70 +36023,78 @@ Ext.tree.TreeFilter.prototype = {
     }
 };
 
-Ext.tree.TreeSorter = function(tree, config){
-    
+Ext.tree.TreeSorter = Ext.extend(Object, {
     
+    constructor: function(tree, config){
+        
     
     
     
     
     
+
     Ext.apply(this, config);
-    tree.on("beforechildrenrendered", this.doSort, this);
-    tree.on("append", this.updateSort, this);
-    tree.on("insert", this.updateSort, this);
-    tree.on("textchange", this.updateSortParent, this);
-    
-    var dsc = this.dir && this.dir.toLowerCase() == "desc";
-    var p = this.property || "text";
-    var sortType = this.sortType;
-    var fs = this.folderSort;
-    var cs = this.caseSensitive === true;
-    var leafAttr = this.leafAttr || 'leaf';
+    tree.on({
+        scope: this,
+        beforechildrenrendered: this.doSort,
+        append: this.updateSort,
+        insert: this.updateSort,
+        textchange: this.updateSortParent
+    });
 
+    var desc = this.dir && this.dir.toLowerCase() == 'desc',
+        prop = this.property || 'text';
+        sortType = this.sortType;
+        folderSort = this.folderSort;
+        caseSensitive = this.caseSensitive === true;
+        leafAttr = this.leafAttr || 'leaf';
+
+    if(Ext.isString(sortType)){
+        sortType = Ext.data.SortTypes[sortType];
+    }
     this.sortFn = function(n1, n2){
-        if(fs){
-            if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
+        var attr1 = n1.attributes,
+            attr2 = n2.attributes;
+            
+        if(folderSort){
+            if(attr1[leafAttr] && !attr2[leafAttr]){
                 return 1;
             }
-            if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
+            if(!attr1[leafAttr] && attr2[leafAttr]){
                 return -1;
             }
         }
-       var v1 = sortType ? sortType(n1.attributes[p]) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
-       var v2 = sortType ? sortType(n2.attributes[p]) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
-       if(v1 < v2){
-                       return dsc ? +1 : -1;
-               }else if(v1 > v2){
-                       return dsc ? -1 : +1;
-        }else{
-               return 0;
+        var prop1 = attr1[prop],
+            prop2 = attr2[prop],
+            v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase());
+            v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());
+            
+        if(v1 < v2){
+            return desc ? 1 : -1;
+        }else if(v1 > v2){
+            return desc ? -1 : 1;
         }
+        return 0;
     };
-};
-
-Ext.tree.TreeSorter.prototype = {
-    doSort : function(node){
-        node.sort(this.sortFn);
     },
     
-    compareNodes : function(n1, n2){
-        return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
+    doSort : function(node){
+        node.sort(this.sortFn);
     },
-    
+
     updateSort : function(tree, node){
         if(node.childrenRendered){
             this.doSort.defer(1, this, [node]);
         }
     },
-    
+
     updateSortParent : function(node){
-               var p = node.parentNode;
-               if(p && p.childrenRendered){
+        var p = node.parentNode;
+        if(p && p.childrenRendered){
             this.doSort.defer(1, this, [p]);
         }
-    }
-};
+    }    
+});
 if(Ext.dd.DropZone){
     
 Ext.tree.TreeDropZone = function(tree, config){
@@ -32406,6 +36440,7 @@ Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
 Ext.tree.TreeEditor = function(tree, fc, config){
     fc = fc || {};
     var field = fc.events ? fc : new Ext.form.TextField(fc);
+    
     Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
 
     this.tree = tree;
@@ -32437,16 +36472,18 @@ Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
 
     initEditor : function(tree){
         tree.on({
-            scope: this,
+            scope      : this,
             beforeclick: this.beforeNodeClick,
-            dblclick: this.onNodeDblClick
+            dblclick   : this.onNodeDblClick
         });
+        
         this.on({
-            scope: this,
-            complete: this.updateNode,
+            scope          : this,
+            complete       : this.updateNode,
             beforestartedit: this.fitToTree,
-            specialkey: this.onSpecialKey
+            specialkey     : this.onSpecialKey
         });
+        
         this.on('startedit', this.bindScroll, this, {delay:10});
     },
 
@@ -32567,8 +36604,8 @@ var swfobject = function() {
         var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
             u = nav.userAgent.toLowerCase(),
             p = nav.platform.toLowerCase(),
-            windows = p ? /win/.test(p) : /win/.test(u),
-            mac = p ? /mac/.test(p) : /mac/.test(u),
+            windows = p ? (/win/).test(p) : /win/.test(u),
+            mac = p ? (/mac/).test(p) : /mac/.test(u),
             webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, 
             ie = !+"\v1", 
             playerVersion = [0,0,0],
@@ -32635,7 +36672,7 @@ var swfobject = function() {
             if (ua.wk) {
                 (function(){
                     if (isDomLoaded) { return; }
-                    if (!/loaded|complete/.test(doc.readyState)) {
+                    if (!(/loaded|complete/).test(doc.readyState)) {
                         setTimeout(arguments.callee, 0);
                         return;
                     }
@@ -32829,8 +36866,13 @@ var swfobject = function() {
                 storedAltContentId = replaceElemIdStr;
             }
             att.id = EXPRESS_INSTALL_ID;
-            if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
-            if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
+            if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) {
+                att.width = "310";
+            }
+            
+            if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
+                att.height = "137";
+            }
             doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
             var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
                 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
@@ -33276,10 +37318,10 @@ Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
 
     
     wmode: 'opaque',
-    
+
     
     flashVars: undefined,
-    
+
     
     flashParams: undefined,
 
@@ -33310,8 +37352,8 @@ Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
             wmode: this.wmode
         }, this.flashParams), vars = Ext.apply({
             allowedDomain: document.location.hostname,
-            elementID: this.getId(),
-            eventHandler: 'Ext.FlashEventProxy.onEvent'
+            YUISwfId: this.getId(),
+            YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
         }, this.flashVars);
 
         new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
@@ -33370,11 +37412,11 @@ Ext.FlashEventProxy = {
             arguments.callee.defer(10, this, [id, e]);
         }
     }
-}
+};
+
  Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
     refreshBuffer: 100,
-    
+
     
 
     
@@ -33404,15 +37446,15 @@ Ext.FlashEventProxy = {
             }
         }
     },
+
     
-    
-    
+
     
     extraStyle: null,
-    
+
     
     seriesStyles: null,
-    
+
     
     disableCaching: Ext.isIE || Ext.isOpera,
     disableCacheParam: '_dc',
@@ -33465,13 +37507,25 @@ Ext.FlashEventProxy = {
         this.swf.setCategoryNames(names);
     },
 
-    setTipRenderer : function(fn){
+    setLegendRenderer : function(fn, scope){
+        var chart = this;
+        scope = scope || chart;
+        chart.removeFnProxy(chart.legendFnName);
+        chart.legendFnName = chart.createFnProxy(function(name){
+            return fn.call(scope, name);
+        });
+        chart.swf.setLegendLabelFunction(chart.legendFnName);
+    },
+
+    setTipRenderer : function(fn, scope){
         var chart = this;
-        this.tipFnName = this.createFnProxy(function(item, index, series){
+        scope = scope || chart;
+        chart.removeFnProxy(chart.tipFnName);
+        chart.tipFnName = chart.createFnProxy(function(item, index, series){
             var record = chart.store.getAt(index);
-            return fn(chart, record, index, series);
-        }, this.tipFnName);
-        this.swf.setDataTipFunction(this.tipFnName);
+            return fn.call(scope, chart, record, index, series);
+        });
+        chart.swf.setDataTipFunction(chart.tipFnName);
     },
 
     setSeries : function(series){
@@ -33511,6 +37565,7 @@ Ext.FlashEventProxy = {
 
     onSwfReady : function(isReset){
         Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
+        var ref;
         this.swf.setType(this.type);
 
         if(this.chartStyle){
@@ -33522,7 +37577,12 @@ Ext.FlashEventProxy = {
         }
 
         if(this.tipRenderer){
-            this.setTipRenderer(this.tipRenderer);
+            ref = this.getFunctionRef(this.tipRenderer);
+            this.setTipRenderer(ref.fn, ref.scope);
+        }
+        if(this.legendRenderer){
+            ref = this.getFunctionRef(this.legendRenderer);
+            this.setLegendRenderer(ref.fn, ref.scope);
         }
         if(!isReset){
             this.bindStore(this.store, true);
@@ -33539,81 +37599,105 @@ Ext.FlashEventProxy = {
 
     refresh : function(){
         if(this.fireEvent('beforerefresh', this) !== false){
-               var styleChanged = false;
-               
-               var data = [], rs = this.store.data.items;
-               for(var j = 0, len = rs.length; j < len; j++){
-                   data[j] = rs[j].data;
-               }
-               
-               
-               var dataProvider = [];
-               var seriesCount = 0;
-               var currentSeries = null;
-               var i = 0;
-               if(this.series){
-                   seriesCount = this.series.length;
-                   for(i = 0; i < seriesCount; i++){
-                       currentSeries = this.series[i];
-                       var clonedSeries = {};
-                       for(var prop in currentSeries){
-                           if(prop == "style" && currentSeries.style !== null){
-                               clonedSeries.style = Ext.encode(currentSeries.style);
-                               styleChanged = true;
-                               
-                               
-                               
-                               
-                           } else{
-                               clonedSeries[prop] = currentSeries[prop];
-                           }
-                       }
-                       dataProvider.push(clonedSeries);
-                   }
-               }
-       
-               if(seriesCount > 0){
-                   for(i = 0; i < seriesCount; i++){
-                       currentSeries = dataProvider[i];
-                       if(!currentSeries.type){
-                           currentSeries.type = this.type;
-                       }
-                       currentSeries.dataProvider = data;
-                   }
-               } else{
-                   dataProvider.push({type: this.type, dataProvider: data});
-               }
-               this.swf.setDataProvider(dataProvider);
-               if(this.seriesStyles){
-                   this.setSeriesStyles(this.seriesStyles);
-               }
+            var styleChanged = false;
+            
+            var data = [], rs = this.store.data.items;
+            for(var j = 0, len = rs.length; j < len; j++){
+                data[j] = rs[j].data;
+            }
+            
+            
+            var dataProvider = [];
+            var seriesCount = 0;
+            var currentSeries = null;
+            var i = 0;
+            if(this.series){
+                seriesCount = this.series.length;
+                for(i = 0; i < seriesCount; i++){
+                    currentSeries = this.series[i];
+                    var clonedSeries = {};
+                    for(var prop in currentSeries){
+                        if(prop == "style" && currentSeries.style !== null){
+                            clonedSeries.style = Ext.encode(currentSeries.style);
+                            styleChanged = true;
+                            
+                            
+                            
+                            
+                        } else{
+                            clonedSeries[prop] = currentSeries[prop];
+                        }
+                    }
+                    dataProvider.push(clonedSeries);
+                }
+            }
+
+            if(seriesCount > 0){
+                for(i = 0; i < seriesCount; i++){
+                    currentSeries = dataProvider[i];
+                    if(!currentSeries.type){
+                        currentSeries.type = this.type;
+                    }
+                    currentSeries.dataProvider = data;
+                }
+            } else{
+                dataProvider.push({type: this.type, dataProvider: data});
+            }
+            this.swf.setDataProvider(dataProvider);
+            if(this.seriesStyles){
+                this.setSeriesStyles(this.seriesStyles);
+            }
             this.fireEvent('refresh', this);
         }
     },
 
-    createFnProxy : function(fn, old){
-        if(old){
-            delete window[old];
+    
+    createFnProxy : function(fn){
+        var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
+        Ext.chart.Chart.proxyFunction[fnName] = fn;
+        return 'Ext.chart.Chart.proxyFunction.' + fnName;
+    },
+
+    
+    removeFnProxy : function(fn){
+        if(!Ext.isEmpty(fn)){
+            fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
+            delete Ext.chart.Chart.proxyFunction[fn];
+        }
+    },
+
+    
+    getFunctionRef : function(val){
+        if(Ext.isFunction(val)){
+            return {
+                fn: val,
+                scope: this
+            };
+        }else{
+            return {
+                fn: val.fn,
+                scope: val.scope || this
+            };
         }
-        var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);
-        window[fnName] = fn;
-        return fnName;
     },
+
     
     onDestroy: function(){
+        if (this.refreshTask && this.refreshTask.cancel){
+            this.refreshTask.cancel();
+        }
         Ext.chart.Chart.superclass.onDestroy.call(this);
         this.bindStore(null);
-        var tip = this.tipFnName;
-        if(!Ext.isEmpty(tip)){
-            delete window[tip];
-        }
+        this.removeFnProxy(this.tipFnName);
+        this.removeFnProxy(this.legendFnName);
     }
 });
 Ext.reg('chart', Ext.chart.Chart);
 Ext.chart.Chart.PROXY_FN_ID = 0;
+Ext.chart.Chart.proxyFunction = {};
 
 
-Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf';
+Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';
 
 
 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
@@ -33642,7 +37726,7 @@ Ext.reg('piechart', Ext.chart.PieChart);
 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
     onSwfReady : function(isReset){
         Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
-
+        this.labelFn = [];
         if(this.xField){
             this.setXField(this.xField);
         }
@@ -33652,9 +37736,18 @@ Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
         if(this.xAxis){
             this.setXAxis(this.xAxis);
         }
+        if(this.xAxes){
+            this.setXAxes(this.xAxes);
+        }
         if(this.yAxis){
             this.setYAxis(this.yAxis);
         }
+        if(this.yAxes){
+            this.setYAxes(this.yAxes);
+        }
+        if(Ext.isDefined(this.constrainViewport)){
+            this.swf.setConstrainViewport(this.constrainViewport);
+        }
     },
 
     setXField : function(value){
@@ -33672,24 +37765,56 @@ Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
         this.swf.setHorizontalAxis(this.xAxis);
     },
 
+    setXAxes : function(value){
+        var axis;
+        for(var i = 0; i < value.length; i++) {
+            axis = this.createAxis('xAxis' + i, value[i]);
+            this.swf.setHorizontalAxis(axis);
+        }
+    },
+
     setYAxis : function(value){
         this.yAxis = this.createAxis('yAxis', value);
         this.swf.setVerticalAxis(this.yAxis);
     },
 
+    setYAxes : function(value){
+        var axis;
+        for(var i = 0; i < value.length; i++) {
+            axis = this.createAxis('yAxis' + i, value[i]);
+            this.swf.setVerticalAxis(axis);
+        }
+    },
+
     createAxis : function(axis, value){
-        var o = Ext.apply({}, value), oldFn = null;
+        var o = Ext.apply({}, value),
+            ref,
+            old;
+
         if(this[axis]){
-            oldFn = this[axis].labelFunction;
+            old = this[axis].labelFunction;
+            this.removeFnProxy(old);
+            this.labelFn.remove(old);
         }
         if(o.labelRenderer){
-            var fn = o.labelRenderer;
+            ref = this.getFunctionRef(o.labelRenderer);
             o.labelFunction = this.createFnProxy(function(v){
-                return fn(v);
-            }, oldFn);
+                return ref.fn.call(ref.scope, v);
+            });
             delete o.labelRenderer;
+            this.labelFn.push(o.labelFunction);
+        }
+        if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
+            o.position = 'bottom';
         }
         return o;
+    },
+
+    onDestroy : function(){
+        Ext.chart.CartesianChart.superclass.onDestroy.call(this);
+        Ext.each(this.labelFn, function(fn){
+            this.removeFnProxy(fn);
+        }, this);
     }
 });
 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
@@ -33746,7 +37871,10 @@ Ext.chart.Axis.prototype =
     labelFunction: null,
 
     
-    hideOverlappingLabels: true
+    hideOverlappingLabels: true,
+
+    
+    labelSpacing: 2
 };
 
 
@@ -33772,7 +37900,23 @@ Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
     alwaysShowZero: true,
 
     
-    scale: "linear"
+    scale: "linear",
+
+    
+    roundMajorUnit: true,
+
+    
+    calculateByLabelSize: true,
+
+    
+    position: 'left',
+
+    
+    adjustMaximumByMajorUnit: true,
+
+    
+    adjustMinimumByMajorUnit: true
+
 });
 
 
@@ -33798,7 +37942,14 @@ Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
     minorTimeUnit: null,
 
     
-    snapToUnits: true
+    snapToUnits: true,
+
+    
+    stackingEnabled: false,
+
+    
+    calculateByLabelSize: true
+
 });
 
 
@@ -33806,7 +37957,11 @@ Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
     type: "category",
 
     
-    categoryNames: null
+    categoryNames: null,
+
+    
+    calculateCategoryCount: false
+
 });
 
 
@@ -33827,7 +37982,13 @@ Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
     xField: null,
 
     
-    yField: null
+    yField: null,
+
+    
+    showInLegend: true,
+
+    
+    axis: 'primary'
 });
 
 
@@ -33852,94 +38013,6 @@ Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
     dataField: null,
     categoryField: null
 });
- Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
-    monitorResize : true,
-
-    setContainer : function(ct){
-        this.monitorResize = !ct.floating;
-        
-        
-        ct.on('autosize', this.doAutoSize, this);
-        Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
-    },
-
-    renderItem : function(c, position, target){
-        if (!this.itemTpl) {
-            this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
-                '<li id="{itemId}" class="{itemCls}">',
-                    '<tpl if="needsIcon">',
-                        '<img src="{icon}" class="{iconCls}"/>',
-                    '</tpl>',
-                '</li>'
-            );
-        }
-
-        if(c && !c.rendered){
-            if(Ext.isNumber(position)){
-                position = target.dom.childNodes[position];
-            }
-            var a = this.getItemArgs(c);
-
-
-            c.render(c.positionEl = position ?
-                this.itemTpl.insertBefore(position, a, true) :
-                this.itemTpl.append(target, a, true));
-
-
-            c.positionEl.menuItemId = c.getItemId();
-
-
-
-            if (!a.isMenuItem && a.needsIcon) {
-                c.positionEl.addClass('x-menu-list-item-indent');
-            }
-            this.configureItem(c, position);
-        }else if(c && !this.isValidParent(c, target)){
-            if(Ext.isNumber(position)){
-                position = target.dom.childNodes[position];
-            }
-            target.dom.insertBefore(c.getActionEl().dom, position || null);
-        }
-    },
-
-    getItemArgs : function(c) {
-        var isMenuItem = c instanceof Ext.menu.Item;
-        return {
-            isMenuItem: isMenuItem,
-            needsIcon: !isMenuItem && (c.icon || c.iconCls),
-            icon: c.icon || Ext.BLANK_IMAGE_URL,
-            iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
-            itemId: 'x-menu-el-' + c.id,
-            itemCls: 'x-menu-list-item '
-        };
-    },
-
-
-    isValidParent : function(c, target) {
-        return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
-    },
-
-    onLayout : function(ct, target){
-        this.renderAll(ct, target);
-        this.doAutoSize();
-    },
-
-    doAutoSize : function(){
-        var ct = this.container, w = ct.width;
-        if(ct.floating){
-            if(w){
-                ct.setWidth(w);
-            }else if(Ext.isIE){
-                ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
-                var el = ct.getEl(), t = el.dom.offsetWidth; 
-                ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
-            }
-        }
-    }
-});
-Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
-
-
 Ext.menu.Menu = Ext.extend(Ext.Container, {
     
     
@@ -33972,6 +38045,10 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     
     floating : true,
 
+
+    
+    zIndex: 15000,
+
     
     hidden : true,
 
@@ -34008,10 +38085,10 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         }
         Ext.menu.Menu.superclass.initComponent.call(this);
         if(this.autoLayout){
+            var fn = this.doLayout.createDelegate(this, []);
             this.on({
-                add: this.doLayout,
-                remove: this.doLayout,
-                scope: this
+                add: fn,
+                remove: fn
             });
         }
     },
@@ -34042,7 +38119,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
                 dh: dh,
                 constrain: false,
                 parentEl: ct,
-                zindex:15000
+                zindex: this.zIndex
             });
         }else{
             this.el = ct.createChild(dh);
@@ -34131,7 +38208,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         var items = this.items;
         for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
             var item = items.get(i);
-            if(!item.disabled && (item.canActivate || item.isFormField)){
+            if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){
                 this.setActiveItem(item, false);
                 return item;
             }
@@ -34214,7 +38291,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
                 
                 this.el.setXY(xy);
                 
-                this.constrainScroll(xy[1]);
+                xy[1] = this.constrainScroll(xy[1]);
                 xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
             }else{
                 
@@ -34237,12 +38314,31 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },
 
     constrainScroll : function(y){
-        var max, full = this.ul.setHeight('auto').getHeight();
+        var max, full = this.ul.setHeight('auto').getHeight(),
+            returnY = y, normalY, parentEl, scrollTop, viewHeight;
         if(this.floating){
-            max = this.maxHeight ? this.maxHeight : Ext.fly(this.el.dom.parentNode).getViewSize(false).height - y;
+            parentEl = Ext.fly(this.el.dom.parentNode);
+            scrollTop = parentEl.getScroll().top;
+            viewHeight = parentEl.getViewSize().height;
+            
+            
+            normalY = y - scrollTop;
+            max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
+            if(full > viewHeight) {
+                max = viewHeight;
+                
+                returnY = y - normalY;
+            } else if(max < full) {
+                returnY = y - (full - max);
+                max = full;
+            }
         }else{
             max = this.getHeight();
         }
+        
+        if (this.maxHeight){
+            max = Math.min(this.maxHeight, max);
+        }
         if(full > max && max > 0){
             this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
             this.ul.setHeight(this.activeMax);
@@ -34253,6 +38349,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
             this.el.select('.x-menu-scroller').setDisplayed('none');
         }
         this.ul.dom.scrollTop = 0;
+        return returnY;
     },
 
     createScrollers : function(){
@@ -34310,9 +38407,11 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
 
     
     hide : function(deep){
-        this.deepHide = deep;
-        Ext.menu.Menu.superclass.hide.call(this);
-        delete this.deepHide;
+        if (!this.isDestroyed) {
+            this.deepHide = deep;
+            Ext.menu.Menu.superclass.hide.call(this);
+            delete this.deepHide;
+        }
     },
 
     
@@ -34349,8 +38448,8 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
          return c;
     },
 
-    applyDefaults : function(c){
-        if(!Ext.isString(c)){
+    applyDefaults : function(c) {
+        if (!Ext.isString(c)) {
             c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
             var d = this.internalDefaults;
             if(d){
@@ -34366,10 +38465,10 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },
 
     
-    getMenuItem : function(config){
-       if(!config.isXType){
-            if(!config.xtype && Ext.isBoolean(config.checked)){
-                return new Ext.menu.CheckItem(config)
+    getMenuItem : function(config) {
+        if (!config.isXType) {
+            if (!config.xtype && Ext.isBoolean(config.checked)) {
+                return new Ext.menu.CheckItem(config);
             }
             return Ext.create(config, this.defaultType);
         }
@@ -34377,22 +38476,24 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },
 
     
-    addSeparator : function(){
+    addSeparator : function() {
         return this.add(new Ext.menu.Separator());
     },
 
     
-    addElement : function(el){
-        return this.add(new Ext.menu.BaseItem(el));
+    addElement : function(el) {
+        return this.add(new Ext.menu.BaseItem({
+            el: el
+        }));
     },
 
     
-    addItem : function(item){
+    addItem : function(item) {
         return this.add(item);
     },
 
     
-    addMenuItem : function(config){
+    addMenuItem : function(config) {
         return this.add(this.getMenuItem(config));
     },
 
@@ -34403,6 +38504,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
 
     
     onDestroy : function(){
+        Ext.EventManager.removeResizeListener(this.hide, this);
         var pm = this.parentMenu;
         if(pm && pm.activeChild == this){
             delete pm.activeChild;
@@ -34410,7 +38512,6 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         delete this.parentMenu;
         Ext.menu.Menu.superclass.onDestroy.call(this);
         Ext.menu.MenuMgr.unregister(this);
-        Ext.EventManager.removeResizeListener(this.hide, this);
         if(this.keyNav) {
             this.keyNav.disable();
         }
@@ -34543,7 +38644,7 @@ Ext.menu.MenuMgr = function(){
        if(m.parentMenu){
           m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
           m.parentMenu.activeChild = m;
-       }else if(last && last.isVisible()){
+       }else if(last && !last.isDestroyed && last.isVisible()){
           m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
        }
    }
@@ -34576,23 +38677,11 @@ Ext.menu.MenuMgr = function(){
        }
    }
 
-   
-   function onBeforeCheck(mi, state){
-       if(state){
-           var g = groups[mi.group];
-           for(var i = 0, l = g.length; i < l; i++){
-               if(g[i] != mi){
-                   g[i].setChecked(false);
-               }
-           }
-       }
-   }
-
    return {
 
        
        hideAll : function(){
-            return hideAll();  
+            return hideAll();
        },
 
        
@@ -34642,7 +38731,6 @@ Ext.menu.MenuMgr = function(){
                    groups[g] = [];
                }
                groups[g].push(menuItem);
-               menuItem.on("beforecheckchange", onBeforeCheck);
            }
        },
 
@@ -34651,7 +38739,23 @@ Ext.menu.MenuMgr = function(){
            var g = menuItem.group;
            if(g){
                groups[g].remove(menuItem);
-               menuItem.un("beforecheckchange", onBeforeCheck);
+           }
+       },
+       
+       
+       onCheckChange: function(item, state){
+           if(item.group && state){
+               var group = groups[item.group],
+                   i = 0,
+                   len = group.length,
+                   current;
+                   
+               for(; i < len; i++){
+                   current = group[i];
+                   if(current != item){
+                       current.setChecked(false);
+                   }
+               }
            }
        },
 
@@ -34699,20 +38803,20 @@ Ext.menu.BaseItem = Ext.extend(Ext.Component, {
 
     
     actionMode : "container",
-    
+
     initComponent : function(){
         Ext.menu.BaseItem.superclass.initComponent.call(this);
         this.addEvents(
-               
-               'click',
-               
-               'activate',
-               
-               'deactivate'
-           );
-           if(this.handler){
-               this.on("click", this.handler, this.scope);
-           }
+            
+            'click',
+            
+            'activate',
+            
+            'deactivate'
+        );
+        if(this.handler){
+            this.on("click", this.handler, this.scope);
+        }
     },
 
     
@@ -34798,15 +38902,17 @@ Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
     
     itemCls : "x-menu-text",
     
-    constructor : function(config){
-        if(typeof config == 'string'){
-            config = {text: config}
+    constructor : function(config) {
+        if (typeof config == 'string') {
+            config = {
+                text: config
+            };
         }
         Ext.menu.TextItem.superclass.constructor.call(this, config);
     },
 
     
-    onRender : function(){
+    onRender : function() {
         var s = document.createElement("span");
         s.className = this.itemCls;
         s.innerHTML = this.text;
@@ -34850,6 +38956,10 @@ Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
     
     showDelay: 200,
     
+    
+    altText: '',
+    
+    
     hideDelay: 200,
 
     
@@ -34872,7 +38982,7 @@ Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
                         ' target="{hrefTarget}"',
                     '</tpl>',
                  '>',
-                     '<img src="{icon}" class="x-menu-item-icon {iconCls}"/>',
+                     '<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
                      '<span class="x-menu-item-text">{text}</span>',
                  '</a>'
              );
@@ -34895,7 +39005,8 @@ Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
             hrefTarget: this.hrefTarget,
             icon: this.icon || Ext.BLANK_IMAGE_URL,
             iconCls: this.iconCls || '',
-            text: this.itemText||this.text||'&#160;'
+            text: this.itemText||this.text||'&#160;',
+            altText: this.altText || ''
         };
     },
 
@@ -35052,12 +39163,14 @@ Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
 
     
     setChecked : function(state, suppressEvent){
-        if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
+        var suppress = suppressEvent === true;
+        if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
+            Ext.menu.MenuMgr.onCheckChange(this, state);
             if(this.container){
                 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
             }
             this.checked = state;
-            if(suppressEvent !== true){
+            if(!suppress){
                 this.fireEvent("checkchange", this, state);
             }
         }
@@ -35311,7 +39424,7 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
         }
         return String(this.getValue()) !== String(this.originalValue);
     },
-    
+
     
     setReadOnly : function(readOnly){
         if(this.rendered){
@@ -35342,7 +39455,7 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
 
     
     initEvents : function(){
-        this.mon(this.el, Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.fireKey,  this);
+        this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey,  this);
         this.mon(this.el, 'focus', this.onFocus, this);
 
         
@@ -35418,56 +39531,81 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
     },
 
     
-    validateValue : function(value){
-        return true;
-    },
+     validateValue : function(value) {
+         
+         var error = this.getErrors(value)[0];
+
+         if (error == undefined) {
+             return true;
+         } else {
+             this.markInvalid(error);
+             return false;
+         }
+     },
     
     
+    getErrors: function() {
+        return [];
+    },
+
+    
     getActiveError : function(){
-        return this.activeError || '';    
+        return this.activeError || '';
     },
 
     
     markInvalid : function(msg){
-        if(!this.rendered || this.preventMark){ 
-            return;
-        }
-        msg = msg || this.invalidText;
+        
+        if (this.rendered && !this.preventMark) {
+            msg = msg || this.invalidText;
 
-        var mt = this.getMessageHandler();
-        if(mt){
-            mt.mark(this, msg);
-        }else if(this.msgTarget){
-            this.el.addClass(this.invalidClass);
-            var t = Ext.getDom(this.msgTarget);
-            if(t){
-                t.innerHTML = msg;
-                t.style.display = this.msgDisplay;
+            var mt = this.getMessageHandler();
+            if(mt){
+                mt.mark(this, msg);
+            }else if(this.msgTarget){
+                this.el.addClass(this.invalidClass);
+                var t = Ext.getDom(this.msgTarget);
+                if(t){
+                    t.innerHTML = msg;
+                    t.style.display = this.msgDisplay;
+                }
             }
         }
-        this.activeError = msg;
-        this.fireEvent('invalid', this, msg);
+        
+        this.setActiveError(msg);
     },
-
+    
     
     clearInvalid : function(){
-        if(!this.rendered || this.preventMark){ 
-            return;
-        }
-        this.el.removeClass(this.invalidClass);
-        var mt = this.getMessageHandler();
-        if(mt){
-            mt.clear(this);
-        }else if(this.msgTarget){
+        
+        if (this.rendered && !this.preventMark) {
             this.el.removeClass(this.invalidClass);
-            var t = Ext.getDom(this.msgTarget);
-            if(t){
-                t.innerHTML = '';
-                t.style.display = 'none';
+            var mt = this.getMessageHandler();
+            if(mt){
+                mt.clear(this);
+            }else if(this.msgTarget){
+                this.el.removeClass(this.invalidClass);
+                var t = Ext.getDom(this.msgTarget);
+                if(t){
+                    t.innerHTML = '';
+                    t.style.display = 'none';
+                }
             }
         }
+        
+        this.unsetActiveError();
+    },
+
+    
+    setActiveError: function(msg, suppressEvent) {
+        this.activeError = msg;
+        if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
+    },
+    
+    
+    unsetActiveError: function(suppressEvent) {
         delete this.activeError;
-        this.fireEvent('valid', this);
+        if (suppressEvent !== true) this.fireEvent('valid', this);
     },
 
     
@@ -35482,6 +39620,11 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
     },
 
     
+    alignErrorEl : function(){
+        this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
+    },
+
+    
     alignErrorIcon : function(){
         this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
     },
@@ -35568,8 +39711,12 @@ Ext.form.MessageTargets = {
                     return;
                 }
                 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
-                field.errorEl.setWidth(elp.getWidth(true)-20);
+                field.on('resize', field.alignErrorEl, field);
+                field.on('destroy', function(){
+                    Ext.destroy(this.errorEl);
+                }, field);
             }
+            field.alignErrorEl();
             field.errorEl.update(msg);
             Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
         },
@@ -35587,24 +39734,31 @@ Ext.form.MessageTargets = {
             field.el.addClass(field.invalidClass);
             if(!field.errorIcon){
                 var elp = field.getErrorCt();
-                if(!elp){ 
+                
+                if(!elp){
                     field.el.dom.title = msg;
                     return;
                 }
                 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
+                if (field.ownerCt) {
+                    field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
+                    field.ownerCt.on('expand', field.alignErrorIcon, field);
+                }
+                field.on('resize', field.alignErrorIcon, field);
+                field.on('destroy', function(){
+                    Ext.destroy(this.errorIcon);
+                }, field);
             }
             field.alignErrorIcon();
             field.errorIcon.dom.qtip = msg;
             field.errorIcon.dom.qclass = 'x-form-invalid-tip';
             field.errorIcon.show();
-            field.on('resize', field.alignErrorIcon, field);
         },
         clear: function(field){
             field.el.removeClass(field.invalidClass);
             if(field.errorIcon){
                 field.errorIcon.dom.qtip = '';
                 field.errorIcon.hide();
-                field.un('resize', field.alignErrorIcon, field);
             }else{
                 field.el.dom.title = '';
             }
@@ -35820,14 +39974,16 @@ Ext.form.TextField = Ext.extend(Ext.form.Field,  {
 
     
     preFocus : function(){
-        var el = this.el;
+        var el = this.el,
+            isEmpty;
         if(this.emptyText){
             if(el.dom.value == this.emptyText){
                 this.setRawValue('');
+                isEmpty = true;
             }
             el.removeClass(this.emptyClass);
         }
-        if(this.selectOnFocus){
+        if(this.selectOnFocus || isEmpty){
             el.dom.select();
         }
     },
@@ -35866,43 +40022,51 @@ Ext.form.TextField = Ext.extend(Ext.form.Field,  {
     },
 
     
-    validateValue : function(value){
-        if(Ext.isFunction(this.validator)){
+    getErrors: function(value) {
+        var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
+        
+        value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());        
+        
+        if (Ext.isFunction(this.validator)) {
             var msg = this.validator(value);
-            if(msg !== true){
-                this.markInvalid(msg);
-                return false;
+            if (msg !== true) {
+                errors.push(msg);
             }
         }
-        if(value.length < 1 || value === this.emptyText){ 
-             if(this.allowBlank){
-                 this.clearInvalid();
-                 return true;
-             }else{
-                 this.markInvalid(this.blankText);
-                 return false;
-             }
+        
+        if (value.length < 1 || value === this.emptyText) {
+            if (this.allowBlank) {
+                
+                return errors;
+            } else {
+                errors.push(this.blankText);
+            }
         }
-        if(value.length < this.minLength){
-            this.markInvalid(String.format(this.minLengthText, this.minLength));
-            return false;
+        
+        if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) { 
+            errors.push(this.blankText);
         }
-        if(value.length > this.maxLength){
-            this.markInvalid(String.format(this.maxLengthText, this.maxLength));
-            return false;
-        }      
-        if(this.vtype){
+        
+        if (value.length < this.minLength) {
+            errors.push(String.format(this.minLengthText, this.minLength));
+        }
+        
+        if (value.length > this.maxLength) {
+            errors.push(String.format(this.maxLengthText, this.maxLength));
+        }
+        
+        if (this.vtype) {
             var vt = Ext.form.VTypes;
             if(!vt[this.vtype](value, this)){
-                this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
-                return false;
+                errors.push(this.vtypeText || vt[this.vtype +'Text']);
             }
         }
-        if(this.regex && !this.regex.test(value)){
-            this.markInvalid(this.regexText);
-            return false;
+        
+        if (this.regex && !this.regex.test(value)) {
+            errors.push(this.regexText);
         }
-        return true;
+        
+        return errors;
     },
 
     
@@ -35985,8 +40149,6 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
 
     actionMode: 'wrap',
 
-    removeMode: 'container',
-
     defaultTriggerWidth: 17,
 
     
@@ -36001,7 +40163,7 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
 
     getTriggerWidth: function(){
         var tw = this.trigger.getWidth();
-        if(!this.hideTrigger && tw === 0){
+        if(!this.hideTrigger && !this.readOnly && tw === 0){
             tw = this.defaultTriggerWidth;
         }
         return tw;
@@ -36021,13 +40183,16 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
 
         this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
         this.trigger = this.wrap.createChild(this.triggerConfig ||
-                {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
+                {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass});
         this.initTrigger();
         if(!this.width){
             this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
         }
         this.resizeEl = this.positionEl = this.wrap;
-        this.updateEditState();
+    },
+
+    getWidth: function() {
+        return(this.el.getWidth() + this.trigger.getWidth());
     },
 
     updateEditState: function(){
@@ -36053,6 +40218,7 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
         }
     },
 
+    
     setHideTrigger: function(hideTrigger){
         if(hideTrigger != this.hideTrigger){
             this.hideTrigger = hideTrigger;
@@ -36078,6 +40244,7 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
 
     afterRender : function(){
         Ext.form.TriggerField.superclass.afterRender.call(this);
+        this.updateEditState();
     },
 
     
@@ -36167,37 +40334,47 @@ Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
 
         this.triggerConfig = {
             tag:'span', cls:'x-form-twin-triggers', cn:[
-            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
-            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
+            {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class},
+            {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class}
         ]};
     },
 
     getTrigger : function(index){
         return this.triggers[index];
     },
+    
+    afterRender: function(){
+        Ext.form.TwinTriggerField.superclass.afterRender.call(this);
+        var triggers = this.triggers,
+            i = 0,
+            len = triggers.length;
+            
+        for(; i < len; ++i){
+            if(this['hideTrigger' + (i + 1)]){
+                    triggers[i].hide();
+                }
+
+        }    
+    },
 
     initTrigger : function(){
-        var ts = this.trigger.select('.x-form-trigger', true);
-        var triggerField = this;
+        var ts = this.trigger.select('.x-form-trigger', true),
+            triggerField = this;
+            
         ts.each(function(t, all, index){
             var triggerIndex = 'Trigger'+(index+1);
             t.hide = function(){
                 var w = triggerField.wrap.getWidth();
                 this.dom.style.display = 'none';
                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
-                this['hidden' + triggerIndex] = true;
+                triggerField['hidden' + triggerIndex] = true;
             };
             t.show = function(){
                 var w = triggerField.wrap.getWidth();
                 this.dom.style.display = '';
                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
-                this['hidden' + triggerIndex] = false;
+                triggerField['hidden' + triggerIndex] = false;
             };
-
-            if(this['hide'+triggerIndex]){
-                t.dom.style.display = 'none';
-                this['hidden' + triggerIndex] = true;
-            }
             this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
             t.addClassOnOver('x-form-trigger-over');
             t.addClassOnClick('x-form-trigger-click');
@@ -36281,6 +40458,13 @@ Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {
     doAutoSize : function(e){
         return !e.isNavKeyPress() || e.getKey() == e.ENTER;
     },
+    
+    
+    filterValidation: function(e) {            
+        if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){
+            this.validationTask.delay(this.validationDelay);
+        }
+    },
 
     
     autoSize: function(){
@@ -36317,28 +40501,41 @@ Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {
     
     fieldClass: "x-form-field x-form-num-field",
     
+    
     allowDecimals : true,
     
+    
     decimalSeparator : ".",
     
+    
     decimalPrecision : 2,
     
+    
     allowNegative : true,
     
+    
     minValue : Number.NEGATIVE_INFINITY,
     
+    
     maxValue : Number.MAX_VALUE,
     
+    
     minText : "The minimum value for this field is {0}",
     
+    
     maxText : "The maximum value for this field is {0}",
     
+    
     nanText : "{0} is not a valid number",
     
+    
     baseChars : "0123456789",
+    
+    
+    autoStripChars: false,
 
     
-    initEvents : function(){
+    initEvents : function() {
         var allowed = this.baseChars + '';
         if (this.allowDecimals) {
             allowed += this.decimalSeparator;
@@ -36346,83 +40543,98 @@ Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {
         if (this.allowNegative) {
             allowed += '-';
         }
-        this.maskRe = new RegExp('[' + Ext.escapeRe(allowed) + ']');
+        allowed = Ext.escapeRe(allowed);
+        this.maskRe = new RegExp('[' + allowed + ']');
+        if (this.autoStripChars) {
+            this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
+        }
+        
         Ext.form.NumberField.superclass.initEvents.call(this);
     },
-
     
-    validateValue : function(value){
-        if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
-            return false;
-        }
-        if(value.length < 1){ 
-             return true;
+    
+    getErrors: function(value) {
+        var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
+        
+        value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
+        
+        if (value.length < 1) { 
+             return errors;
         }
+        
         value = String(value).replace(this.decimalSeparator, ".");
+        
         if(isNaN(value)){
-            this.markInvalid(String.format(this.nanText, value));
-            return false;
+            errors.push(String.format(this.nanText, value));
         }
+        
         var num = this.parseValue(value);
-        if(num < this.minValue){
-            this.markInvalid(String.format(this.minText, this.minValue));
-            return false;
+        
+        if (num < this.minValue) {
+            errors.push(String.format(this.minText, this.minValue));
         }
-        if(num > this.maxValue){
-            this.markInvalid(String.format(this.maxText, this.maxValue));
-            return false;
+        
+        if (num > this.maxValue) {
+            errors.push(String.format(this.maxText, this.maxValue));
         }
-        return true;
+        
+        return errors;
     },
 
-    getValue : function(){
+    getValue : function() {
         return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
     },
 
-    setValue : function(v){
+    setValue : function(v) {
+        v = this.fixPrecision(v);
        v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
         v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
         return Ext.form.NumberField.superclass.setValue.call(this, v);
     },
     
     
-    setMinValue : function(value){
+    setMinValue : function(value) {
         this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
     },
     
     
-    setMaxValue : function(value){
+    setMaxValue : function(value) {
         this.maxValue = Ext.num(value, Number.MAX_VALUE);    
     },
 
     
-    parseValue : function(value){
+    parseValue : function(value) {
         value = parseFloat(String(value).replace(this.decimalSeparator, "."));
         return isNaN(value) ? '' : value;
     },
 
     
-    fixPrecision : function(value){
+    fixPrecision : function(value) {
         var nan = isNaN(value);
-        if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
-           return nan ? '' : value;
+        
+        if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) {
+            return nan ? '' : value;
         }
+        
         return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
     },
 
-    beforeBlur : function(){
+    beforeBlur : function() {
         var v = this.parseValue(this.getRawValue());
-        if(!Ext.isEmpty(v)){
-            this.setValue(this.fixPrecision(v));
+        
+        if (!Ext.isEmpty(v)) {
+            this.setValue(v);
         }
     }
 });
+
 Ext.reg('numberfield', Ext.form.NumberField);
+
 Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     
     format : "m/d/Y",
     
-    altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
+    altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",
     
     disabledDaysText : "Disabled",
     
@@ -36439,6 +40651,10 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     showToday : true,
     
     
+    startDay : 0,
+    
+    
+    
     
     
     
@@ -36446,6 +40662,27 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     
     defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
 
+    
+    
+    initTime: '12', 
+
+    initTimeFormat: 'H',
+
+    
+    safeParse : function(value, format) {
+        if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) {
+            
+            return Date.parseDate(value, format);
+        } else {
+            
+            var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
+
+            if (parsedDate) {
+                return parsedDate.clearTime();
+            }
+        }
+    },
+
     initComponent : function(){
         Ext.form.DateField.superclass.initComponent.call(this);
 
@@ -36463,7 +40700,7 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
         this.disabledDatesRE = null;
         this.initDisabledDays();
     },
-    
+
     initEvents: function() {
         Ext.form.DateField.superclass.initEvents.call(this);
         this.keyNav = new Ext.KeyNav(this.el, {
@@ -36480,9 +40717,9 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     initDisabledDays : function(){
         if(this.disabledDates){
             var dd = this.disabledDates,
-                len = dd.length - 1, 
+                len = dd.length - 1,
                 re = "(?:";
-                
+
             Ext.each(dd, function(d, i){
                 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
                 if(i != len){
@@ -36527,44 +40764,48 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     },
 
     
-    validateValue : function(value){
-        value = this.formatDate(value);
-        if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
-            return false;
-        }
-        if(value.length < 1)
-             return true;
+    getErrors: function(value) {
+        var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
+
+        value = this.formatDate(value || this.processValue(this.getRawValue()));
+
+        if (value.length < 1) 
+             return errors;
         }
+
         var svalue = value;
         value = this.parseDate(value);
-        if(!value){
-            this.markInvalid(String.format(this.invalidText, svalue, this.format));
-            return false;
+        if (!value) {
+            errors.push(String.format(this.invalidText, svalue, this.format));
+            return errors;
         }
+
         var time = value.getTime();
-        if(this.minValue && time < this.minValue.getTime()){
-            this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
-            return false;
+        if (this.minValue && time < this.minValue.clearTime().getTime()) {
+            errors.push(String.format(this.minText, this.formatDate(this.minValue)));
         }
-        if(this.maxValue && time > this.maxValue.getTime()){
-            this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
-            return false;
+
+        if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
+            errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
         }
-        if(this.disabledDays){
+
+        if (this.disabledDays) {
             var day = value.getDay();
+
             for(var i = 0; i < this.disabledDays.length; i++) {
-                if(day === this.disabledDays[i]){
-                    this.markInvalid(this.disabledDaysText);
-                    return false;
+                if (day === this.disabledDays[i]) {
+                    errors.push(this.disabledDaysText);
+                    break;
                 }
             }
         }
+
         var fvalue = this.formatDate(value);
-        if(this.disabledDatesRE && this.disabledDatesRE.test(fvalue)){
-            this.markInvalid(String.format(this.disabledDatesText, fvalue));
-            return false;
+        if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
+            errors.push(String.format(this.disabledDatesText, fvalue));
         }
-        return true;
+
+        return errors;
     },
 
     
@@ -36584,17 +40825,20 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     },
 
     
-    parseDate : function(value){
+    parseDate : function(value) {
         if(!value || Ext.isDate(value)){
             return value;
         }
-        var v = Date.parseDate(value, this.format);
-        if(!v && this.altFormats){
-            if(!this.altFormatsArray){
-                this.altFormatsArray = this.altFormats.split("|");
-            }
-            for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
-                v = Date.parseDate(value, this.altFormatsArray[i]);
+
+        var v = this.safeParse(value, this.format),
+            af = this.altFormats,
+            afa = this.altFormatsArray;
+
+        if (!v && af) {
+            afa = afa || af.split("|");
+
+            for (var i = 0, len = afa.length; i < len && !v; i++) {
+                v = this.safeParse(value, afa[i]);
             }
         }
         return v;
@@ -36602,7 +40846,7 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
 
     
     onDestroy : function(){
-               Ext.destroy(this.menu, this.keyNav);
+        Ext.destroy(this.menu, this.keyNav);
         Ext.form.DateField.superclass.onDestroy.call(this);
     },
 
@@ -36634,6 +40878,7 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
             disabledDaysText : this.disabledDaysText,
             format : this.format,
             showToday : this.showToday,
+            startDay: this.startDay,
             minText : String.format(this.minText, this.formatDate(this.minValue)),
             maxText : String.format(this.maxText, this.formatDate(this.maxValue))
         });
@@ -36641,20 +40886,20 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
         this.menu.show(this.el, "tl-bl?");
         this.menuEvents('on');
     },
-    
+
     
     menuEvents: function(method){
         this.menu[method]('select', this.onSelect, this);
         this.menu[method]('hide', this.onMenuHide, this);
         this.menu[method]('show', this.onFocus, this);
     },
-    
+
     onSelect: function(m, d){
         this.setValue(d);
         this.fireEvent('select', this, d);
         this.menu.hide();
     },
-    
+
     onMenuHide: function(){
         this.focus(false, 60);
         this.menuEvents('un');
@@ -36674,6 +40919,7 @@ Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
     
 });
 Ext.reg('datefield', Ext.form.DateField);
+
 Ext.form.DisplayField = Ext.extend(Ext.form.Field,  {
     validationEvent : false,
     validateOnBlur : false,
@@ -36770,6 +41016,8 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
     
     minChars : 4,
     
+    autoSelect : true,
+    
     typeAhead : false,
     
     queryDelay : 500,
@@ -36816,6 +41064,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
             'expand',
             
             'collapse',
+
             
             'beforeselect',
             
@@ -36840,7 +41089,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
                     d.push([value, o.text]);
                 }
                 this.store = new Ext.data.ArrayStore({
-                    'id': 0,
+                    idIndex: 0,
                     fields: ['value', 'text'],
                     data : d,
                     autoDestroy: true
@@ -36887,7 +41136,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
         Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
         if(this.hiddenName){
             this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
-                    id: (this.hiddenId||this.hiddenName)}, 'before', true);
+                    id: (this.hiddenId || Ext.id())}, 'before', true);
 
         }
         if(Ext.isGecko){
@@ -36906,22 +41155,42 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
         Ext.form.ComboBox.superclass.initValue.call(this);
         if(this.hiddenField){
             this.hiddenField.value =
-                Ext.isDefined(this.hiddenValue) ? this.hiddenValue :
-                Ext.isDefined(this.value) ? this.value : '';
+                Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
+        }
+    },
+
+    getParentZIndex : function(){
+        var zindex;
+        if (this.ownerCt){
+            this.findParentBy(function(ct){
+                zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
+                return !!zindex;
+            });
+        }
+        return zindex;
+    },
+    
+    getZIndex : function(listParent){
+        listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
+        var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
+        if(!zindex){
+            zindex = this.getParentZIndex();
         }
+        return (zindex || 12000) + 5;
     },
 
     
     initList : function(){
         if(!this.list){
-            var cls = 'x-combo-list';
+            var cls = 'x-combo-list',
+                listParent = Ext.getDom(this.getListParent() || Ext.getBody());
 
             this.list = new Ext.Layer({
-                parentEl: this.getListParent(),
+                parentEl: listParent,
                 shadow: this.shadow,
                 cls: [cls, this.listClass].join(' '),
                 constrain:false,
-                zindex: 12000
+                zindex: this.getZIndex(listParent)
             });
 
             var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
@@ -36964,10 +41233,15 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
                 singleSelect: true,
                 selectedClass: this.selectedClass,
                 itemSelector: this.itemSelector || '.' + cls + '-item',
-                emptyText: this.listEmptyText
+                emptyText: this.listEmptyText,
+                deferEmptyText: false
             });
 
-            this.mon(this.view, 'click', this.onViewClick, this);
+            this.mon(this.view, {
+                containerclick : this.onViewClick,
+                click : this.onViewClick,
+                scope :this
+            });
 
             this.bindStore(this.store, true);
 
@@ -37040,16 +41314,17 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
     },
 
     reset : function(){
-        Ext.form.ComboBox.superclass.reset.call(this);
         if(this.clearFilterOnReset && this.mode == 'local'){
             this.store.clearFilter();
         }
+        Ext.form.ComboBox.superclass.reset.call(this);
     },
 
     
     initEvents : function(){
         Ext.form.ComboBox.superclass.initEvents.call(this);
 
+        
         this.keyNav = new Ext.KeyNav(this.el, {
             "up" : function(e){
                 this.inKeyMode = true;
@@ -37074,7 +41349,11 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
             },
 
             "tab" : function(e){
-                this.onViewClick(false);
+                if (this.forceSelection === true) {
+                    this.collapse();
+                } else {
+                    this.onViewClick(false);
+                }
                 return true;
             },
 
@@ -37107,6 +41386,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
         }
     },
 
+
     
     onDestroy : function(){
         if (this.dqTask){
@@ -37134,7 +41414,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
     
     onResize : function(w, h){
         Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
-        if(this.isVisible() && this.list){
+        if(!isNaN(w) && this.isVisible() && this.list){
             this.doResize(w);
         }else{
             this.bufferSize = w;
@@ -37188,19 +41468,22 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
                 if(this.editable){
                     this.el.dom.select();
                 }
-                if(!this.selectByValue(this.value, true)){
+
+                if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
                     this.select(0, true);
                 }
             }else{
-                this.selectNext();
+                if(this.autoSelect !== false){
+                    this.selectNext();
+                }
                 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
                     this.taTask.delay(this.typeAheadDelay);
                 }
             }
         }else{
-            this.onEmptyResults();
+            this.collapse();
         }
-        
+
     },
 
     
@@ -37218,6 +41501,38 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
     },
 
     
+    assertValue : function(){
+        var val = this.getRawValue(),
+            rec;
+
+        if(this.valueField && Ext.isDefined(this.value)){
+            rec = this.findRecord(this.valueField, this.value);
+        }
+        if(!rec || rec.get(this.displayField) != val){
+            rec = this.findRecord(this.displayField, val);
+        }
+        if(!rec && this.forceSelection){
+            if(val.length > 0 && val != this.emptyText){
+                this.el.dom.value = Ext.value(this.lastSelectionText, '');
+                this.applyEmptyText();
+            }else{
+                this.clearValue();
+            }
+        }else{
+            if(rec && this.valueField){
+                
+                
+                
+                if (this.value == val){
+                    return;
+                }
+                val = rec.get(this.valueField || this.displayField);
+            }
+            this.setValue(val);
+        }
+    },
+
+    
     onSelect : function(record, index){
         if(this.fireEvent('beforeselect', this, record, index) !== false){
             this.setValue(record.data[this.valueField || this.displayField]);
@@ -37265,7 +41580,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
         }
         this.lastSelectionText = text;
         if(this.hiddenField){
-            this.hiddenField.value = v;
+            this.hiddenField.value = Ext.value(v, '');
         }
         Ext.form.ComboBox.superclass.setValue.call(this, text);
         this.value = v;
@@ -37310,14 +41625,15 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
             r = s.getAt(index);
         if(r){
             this.onSelect(r, index);
-        }else if(s.getCount() === 0){
-            this.onEmptyResults();
+        }else {
+            this.collapse();
         }
         if(doFocus !== false){
             this.el.focus();
         }
     },
 
+
     
     restrictHeight : function(){
         this.innerList.dom.style.height = '';
@@ -37333,16 +41649,11 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
         this.innerList.setHeight(h);
         this.list.beginUpdate();
         this.list.setHeight(h+pad);
-        this.list.alignTo(this.wrap, this.listAlign);
+        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
         this.list.endUpdate();
     },
 
     
-    onEmptyResults : function(){
-        this.collapse();
-    },
-
-    
     isExpanded : function(){
         return this.list && this.list.isVisible();
     },
@@ -37369,6 +41680,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
                 this.innerList.scrollChildIntoView(el, false);
             }
         }
+
     },
 
     
@@ -37399,6 +41711,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
     onKeyUp : function(e){
         var k = e.getKey();
         if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
+
             this.lastKey = k;
             this.dqTask.delay(this.queryDelay);
         }
@@ -37417,21 +41730,14 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
 
     
     beforeBlur : function(){
-        var val = this.getRawValue(),
-            rec = this.findRecord(this.displayField, val);
-        if(!rec && this.forceSelection){
-            if(val.length > 0 && val != this.emptyText){
-                this.el.dom.value = Ext.isEmpty(this.lastSelectionText) ? '' : this.lastSelectionText;
-                this.applyEmptyText();
-            }else{
-                this.clearValue();
-            }
-        }else{
-            if(rec){
-                val = rec.get(this.valueField || this.displayField);
-            }
-            this.setValue(val);
-        }
+        this.assertValue();
+    },
+
+    
+    postBlur  : function(){
+        Ext.form.ComboBox.superclass.postBlur.call(this);
+        this.collapse();
+        this.inKeyMode = false;
     },
 
     
@@ -37475,13 +41781,13 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
 
     
     getParams : function(q){
-        var p = {};
-        
+        var params = {},
+            paramNames = this.store.paramNames;
         if(this.pageSize){
-            p.start = 0;
-            p.limit = this.pageSize;
+            params[paramNames.start] = 0;
+            params[paramNames.limit] = this.pageSize;
         }
-        return p;
+        return params;
     },
 
     
@@ -37497,7 +41803,7 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
 
     
     collapseIf : function(e){
-        if(!e.within(this.wrap) && !e.within(this.list)){
+        if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
             this.collapse();
         }
     },
@@ -37507,11 +41813,25 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
         if(this.isExpanded() || !this.hasFocus){
             return;
         }
+
+        if(this.title || this.pageSize){
+            this.assetHeight = 0;
+            if(this.title){
+                this.assetHeight += this.header.getHeight();
+            }
+            if(this.pageSize){
+                this.assetHeight += this.footer.getHeight();
+            }
+        }
+
         if(this.bufferSize){
             this.doResize(this.bufferSize);
             delete this.bufferSize;
         }
-        this.list.alignTo(this.wrap, this.listAlign);
+        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
+
+        
+        this.list.setZIndex(this.getZIndex());
         this.list.show();
         if(Ext.isGecko2){
             this.innerList.setOverflow('auto'); 
@@ -37561,15 +41881,16 @@ Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
     
     checked : false,
     
-    defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
+    boxLabel: '&#160;',
     
+    defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
     
     
     
 
     
     actionMode : 'wrap',
-    
+
        
     initComponent : function(){
         Ext.form.Checkbox.superclass.initComponent.call(this);
@@ -37618,7 +41939,7 @@ Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
             this.checked = this.el.dom.checked;
         }
         
-        if(Ext.isIE){
+        if (Ext.isIE && !Ext.isStrict) {
             this.wrap.repaint();
         }
         this.resizeEl = this.positionEl = this.wrap;
@@ -37652,8 +41973,10 @@ Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
 
     
     setValue : function(v){
-        var checked = this.checked ;
-        this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
+        var checked = this.checked,
+            inputVal = this.inputValue;
+            
+        this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
         if(this.rendered){
             this.el.dom.checked = this.checked;
             this.el.dom.defaultChecked = this.checked;
@@ -37756,7 +42079,7 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
                     var cc = Ext.apply({items:[]}, colCfg);
                     cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
                     if(this.defaults){
-                        cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)
+                        cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
                     }
                     cols.push(cc);
                 };
@@ -37845,22 +42168,24 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
         });
         this.fireEvent('change', this, arr);
     },
-
     
-    validateValue : function(value){
-        if(!this.allowBlank){
+    
+    getErrors: function() {
+        var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
+        
+        if (!this.allowBlank) {
             var blank = true;
+            
             this.eachItem(function(f){
-                if(f.checked){
+                if (f.checked) {
                     return (blank = false);
                 }
             });
-            if(blank){
-                this.markInvalid(this.blankText);
-                return false;
-            }
+            
+            if (blank) errors.push(this.blankText);
         }
-        return true;
+        
+        return errors;
     },
 
     
@@ -37871,16 +42196,28 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
         }
 
         var dirty = false;
+        
         this.eachItem(function(item){
             if(item.isDirty()){
                 dirty = true;
                 return false;
             }
         });
+        
         return dirty;
     },
 
     
+    setReadOnly : function(readOnly){
+        if(this.rendered){
+            this.eachItem(function(item){
+                item.setReadOnly(readOnly);
+            });
+        }
+        this.readOnly = readOnly;
+    },
+
+    
     onDisable : function(){
         this.eachItem(function(item){
             item.disable();
@@ -37895,14 +42232,6 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
     },
 
     
-    doLayout: function(){
-        if(this.rendered){
-            this.panel.forceLayout = this.ownerCt.forceLayout;
-            this.panel.doLayout();
-        }
-    },
-
-    
     onResize : function(w, h){
         this.panel.setSize(w, h);
         this.panel.doLayout();
@@ -37910,11 +42239,26 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
 
     
     reset : function(){
-        this.eachItem(function(c){
-            if(c.reset){
-                c.reset();
-            }
-        });
+        if (this.originalValue) {
+            
+            this.eachItem(function(c){
+                if(c.setValue){
+                    c.setValue(false);
+                    c.originalValue = c.getValue();
+                }
+            });
+            
+            
+            this.resetOriginal = true;
+            this.setValue(this.originalValue);
+            delete this.resetOriginal;
+        } else {
+            this.eachItem(function(c){
+                if(c.reset){
+                    c.reset();
+                }
+            });
+        }
         
         
         (function() {
@@ -37933,14 +42277,21 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
         return this;
     },
 
+    
     onSetValue: function(id, value){
         if(arguments.length == 1){
             if(Ext.isArray(id)){
-                
                 Ext.each(id, function(val, idx){
-                    var item = this.items.itemAt(idx);
-                    if(item){
-                        item.setValue(val);
+                    if (Ext.isObject(val) && val.setValue){ 
+                        val.setValue(true);
+                        if (this.resetOriginal === true) {
+                            val.originalValue = val.getValue();
+                        }
+                    } else { 
+                        var item = this.items.itemAt(idx);
+                        if(item){
+                            item.setValue(val);
+                        }
                     }
                 }, this);
             }else if(Ext.isObject(id)){
@@ -37965,6 +42316,9 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
     
     beforeDestroy: function(){
         Ext.destroy(this.panel);
+        if (!this.rendered) {
+            Ext.destroy(this.items);
+        }
         Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
 
     },
@@ -38002,9 +42356,9 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
     },
 
     
-    eachItem: function(fn){
+    eachItem: function(fn, scope) {
         if(this.items && this.items.each){
-            this.items.each(fn, this);
+            this.items.each(fn, scope || this);
         }
     },
 
@@ -38020,6 +42374,316 @@ Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
 
 Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
 
+Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
+
+    
+    defaultMargins: '0 5 0 0',
+
+    
+    skipLastItemMargin: true,
+
+    
+    isComposite: true,
+
+    
+    combineErrors: true,
+    
+    
+    labelConnector: ', ',
+    
+    
+
+    
+    
+    initComponent: function() {
+        var labels = [],
+            items  = this.items,
+            item;
+
+        for (var i=0, j = items.length; i < j; i++) {
+            item = items[i];
+            
+            if (!Ext.isEmpty(item.ref)){
+                item.ref = '../' + item.ref;
+            }
+
+            labels.push(item.fieldLabel);
+
+            
+            Ext.applyIf(item, this.defaults);
+
+            
+            if (!(i == j - 1 && this.skipLastItemMargin)) {
+                Ext.applyIf(item, {margins: this.defaultMargins});
+            }
+        }
+
+        this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
+
+        
+        this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
+            return item.field;
+        });
+
+        this.fieldErrors.on({
+            scope  : this,
+            add    : this.updateInvalidMark,
+            remove : this.updateInvalidMark,
+            replace: this.updateInvalidMark
+        });
+
+        Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
+        
+        this.innerCt = new Ext.Container({
+            layout  : 'hbox',
+            items   : this.items,
+            cls     : 'x-form-composite',
+            defaultMargins: '0 3 0 0',
+            ownerCt: this
+        });
+        this.innerCt.ownerCt = undefined;
+        
+        var fields = this.innerCt.findBy(function(c) {
+            return c.isFormField;
+        }, this);
+
+        
+        this.items = new Ext.util.MixedCollection();
+        this.items.addAll(fields);
+        
+    },
+
+    
+    onRender: function(ct, position) {
+        if (!this.el) {
+            
+            var innerCt = this.innerCt;
+            innerCt.render(ct);
+
+            this.el = innerCt.getEl();
+
+            
+            
+            if (this.combineErrors) {
+                this.eachItem(function(field) {
+                    Ext.apply(field, {
+                        markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
+                        clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
+                    });
+                });
+            }
+
+            
+            var l = this.el.parent().parent().child('label', true);
+            if (l) {
+                l.setAttribute('for', this.items.items[0].id);
+            }
+        }
+
+        Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
+    },
+
+    
+    onFieldMarkInvalid: function(field, message) {
+        var name  = field.getName(),
+            error = {
+                field: name, 
+                errorName: field.fieldLabel || name,
+                error: message
+            };
+
+        this.fieldErrors.replace(name, error);
+
+        field.el.addClass(field.invalidClass);
+    },
+
+    
+    onFieldClearInvalid: function(field) {
+        this.fieldErrors.removeKey(field.getName());
+
+        field.el.removeClass(field.invalidClass);
+    },
+
+    
+    updateInvalidMark: function() {
+        var ieStrict = Ext.isIE6 && Ext.isStrict;
+
+        if (this.fieldErrors.length == 0) {
+            this.clearInvalid();
+
+            
+            if (ieStrict) {
+                this.clearInvalid.defer(50, this);
+            }
+        } else {
+            var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
+
+            this.sortErrors();
+            this.markInvalid(message);
+
+            
+            if (ieStrict) {
+                this.markInvalid(message);
+            }
+        }
+    },
+
+    
+    validateValue: function() {
+        var valid = true;
+
+        this.eachItem(function(field) {
+            if (!field.isValid()) valid = false;
+        });
+
+        return valid;
+    },
+
+    
+    buildCombinedErrorMessage: function(errors) {
+        var combined = [],
+            error;
+
+        for (var i = 0, j = errors.length; i < j; i++) {
+            error = errors[i];
+
+            combined.push(String.format("{0}: {1}", error.errorName, error.error));
+        }
+
+        return combined.join("<br />");
+    },
+
+    
+    sortErrors: function() {
+        var fields = this.items;
+
+        this.fieldErrors.sort("ASC", function(a, b) {
+            var findByName = function(key) {
+                return function(field) {
+                    return field.getName() == key;
+                };
+            };
+
+            var aIndex = fields.findIndexBy(findByName(a.field)),
+                bIndex = fields.findIndexBy(findByName(b.field));
+
+            return aIndex < bIndex ? -1 : 1;
+        });
+    },
+
+    
+    reset: function() {
+        this.eachItem(function(item) {
+            item.reset();
+        });
+
+        
+        
+        (function() {
+            this.clearInvalid();
+        }).defer(50, this);
+    },
+    
+    
+    clearInvalidChildren: function() {
+        this.eachItem(function(item) {
+            item.clearInvalid();
+        });
+    },
+
+    
+    buildLabel: function(segments) {
+        return Ext.clean(segments).join(this.labelConnector);
+    },
+
+    
+    isDirty: function(){
+        
+        if (this.disabled || !this.rendered) {
+            return false;
+        }
+
+        var dirty = false;
+        this.eachItem(function(item){
+            if(item.isDirty()){
+                dirty = true;
+                return false;
+            }
+        });
+        return dirty;
+    },
+
+    
+    eachItem: function(fn, scope) {
+        if(this.items && this.items.each){
+            this.items.each(fn, scope || this);
+        }
+    },
+
+    
+    onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
+        var innerCt = this.innerCt;
+
+        if (this.rendered && innerCt.rendered) {
+            innerCt.setSize(adjWidth, adjHeight);
+        }
+
+        Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
+    },
+
+    
+    doLayout: function(shallow, force) {
+        if (this.rendered) {
+            var innerCt = this.innerCt;
+
+            innerCt.forceLayout = this.ownerCt.forceLayout;
+            innerCt.doLayout(shallow, force);
+        }
+    },
+
+    
+    beforeDestroy: function(){
+        Ext.destroy(this.innerCt);
+
+        Ext.form.CompositeField.superclass.beforeDestroy.call(this);
+    },
+
+    
+    setReadOnly : function(readOnly) {
+        if (readOnly == undefined) {
+            readOnly = true;
+        }
+        readOnly = !!readOnly;
+
+        if(this.rendered){
+            this.eachItem(function(item){
+                item.setReadOnly(readOnly);
+            });
+        }
+        this.readOnly = readOnly;
+    },
+
+    onShow : function() {
+        Ext.form.CompositeField.superclass.onShow.call(this);
+        this.doLayout();
+    },
+
+    
+    onDisable : function(){
+        this.eachItem(function(item){
+            item.disable();
+        });
+    },
+
+    
+    onEnable : function(){
+        this.eachItem(function(item){
+            item.enable();
+        });
+    }
+});
+
+Ext.reg('compositefield', Ext.form.CompositeField);
 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
     inputType: 'radio',
 
@@ -38036,36 +42700,35 @@ Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
     },
 
     
-    onClick : function(){
-       if(this.el.dom.checked != this.checked){
-                       var els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
-                       els.each(function(el){
-                               if(el.dom.id == this.id){
-                                       this.setValue(true);
-                               }else{
-                                       Ext.getCmp(el.dom.id).setValue(false);
-                               }
-                       }, this);
-               }
-    },
-
-    
     setValue : function(v){
+       var checkEl,
+            els,
+            radio;
        if (typeof v == 'boolean') {
             Ext.form.Radio.superclass.setValue.call(this, v);
-        } else {
-            var r = this.getCheckEl().child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
-            if(r){
-                Ext.getCmp(r.id).setValue(true);
+        } else if (this.rendered) {
+            checkEl = this.getCheckEl();
+            radio = checkEl.child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
+            if(radio){
+                Ext.getCmp(radio.id).setValue(true);
             }
         }
+        if(this.rendered && this.checked){
+            checkEl = checkEl || this.getCheckEl();
+            els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
+                       els.each(function(el){
+                               if(el.dom.id != this.id){
+                                       Ext.getCmp(el.dom.id).setValue(false);
+                               }
+                       }, this);
+        }
         return this;
     },
-    
+
     
     getCheckEl: function(){
         if(this.inGroup){
-            return this.el.up('.x-form-radio-group')
+            return this.el.up('.x-form-radio-group');
         }
         return this.el.up('form') || Ext.getBody();
     }
@@ -38160,6 +42823,8 @@ Ext.reg('radiogroup', Ext.form.RadioGroup);
 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
     
     inputType : 'hidden',
+    
+    shouldLayout: false,
 
     
     onRender : function(){
@@ -38181,31 +42846,32 @@ Ext.form.Hidden = Ext.extend(Ext.form.Field, {
     clearInvalid : Ext.emptyFn
 });
 Ext.reg('hidden', Ext.form.Hidden);
-Ext.form.BasicForm = function(el, config){
-    Ext.apply(this, config);
-    if(Ext.isString(this.paramOrder)){
-        this.paramOrder = this.paramOrder.split(/[\s,|]/);
-    }
-    
-    this.items = new Ext.util.MixedCollection(false, function(o){
-        return o.getItemId();
-    });
-    this.addEvents(
-        
-        'beforeaction',
-        
-        'actionfailed',
+Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
+
+    constructor: function(el, config){
+        Ext.apply(this, config);
+        if(Ext.isString(this.paramOrder)){
+            this.paramOrder = this.paramOrder.split(/[\s,|]/);
+        }
         
-        'actioncomplete'
-    );
+        this.items = new Ext.util.MixedCollection(false, function(o){
+            return o.getItemId();
+        });
+        this.addEvents(
+            
+            'beforeaction',
+            
+            'actionfailed',
+            
+            'actioncomplete'
+        );
 
-    if(el){
-        this.initEl(el);
-    }
-    Ext.form.BasicForm.superclass.constructor.call(this);
-};
+        if(el){
+            this.initEl(el);
+        }
+        Ext.form.BasicForm.superclass.constructor.call(this);
+    },
 
-Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
     
     
     
@@ -38222,7 +42888,7 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
 
     
     paramsAsHash: false,
-    
+
     
     waitTitle: 'Please Wait...',
 
@@ -38256,14 +42922,14 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
     },
 
     
-    destroy: function() {
-        this.items.each(function(f){
-            Ext.destroy(f);
-        });
-        if(this.el){
-            this.el.removeAllListeners();
-            this.el.remove();
+    destroy: function(bound){
+        if(bound !== true){
+            this.items.each(function(f){
+                Ext.destroy(f);
+            });
+            Ext.destroy(this.el);
         }
+        this.items.clear();
         this.purgeListeners();
     },
 
@@ -38304,8 +42970,9 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
 
     
     submit : function(options){
+        options = options || {};
         if(this.standardSubmit){
-            var v = this.isValid();
+            var v = options.clientValidation === false || this.isValid();
             if(v){
                 var el = this.el.dom;
                 if(this.url && Ext.isEmpty(el.action)){
@@ -38330,11 +42997,22 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
     
     updateRecord : function(record){
         record.beginEdit();
-        var fs = record.fields;
+        var fs = record.fields,
+            field,
+            value;
         fs.each(function(f){
-            var field = this.findField(f.name);
+            field = this.findField(f.name);
             if(field){
-                record.set(f.name, field.getValue());
+                value = field.getValue();
+                if (typeof value != undefined && value.getGroupValue) {
+                    value = value.getGroupValue();
+                } else if ( field.eachItem ) {
+                    value = [];
+                    field.eachItem(function(item){
+                        value.push(item.getValue());
+                    });
+                }
+                record.set(f.name, value);
             }
         }, this);
         record.endEdit();
@@ -38349,6 +43027,12 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
 
     
     beforeAction : function(action){
+        
+        this.items.each(function(f){
+            if(f.isFormField && f.syncValue){
+                f.syncValue();
+            }
+        });
         var o = action.options;
         if(o.waitMsg){
             if(this.waitMsgTarget === true){
@@ -38389,15 +43073,25 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
     },
 
     
-    findField : function(id){
+    findField : function(id) {
         var field = this.items.get(id);
-        if(!Ext.isObject(field)){
-            this.items.each(function(f){
-                if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
-                    field = f;
-                    return false;
+
+        if (!Ext.isObject(field)) {
+            
+            var findMatchingField = function(f) {
+                if (f.isFormField) {
+                    if (f.dataIndex == id || f.id == id || f.getName() == id) {
+                        field = f;
+                        return false;
+                    } else if (f.isComposite) {
+                        return f.items.each(findMatchingField);
+                    } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) {
+                        return f.eachItem(findMatchingField);
+                    }
                 }
-            });
+            };
+
+            this.items.each(findMatchingField);
         }
         return field || null;
     },
@@ -38405,7 +43099,7 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
 
     
     markInvalid : function(errors){
-        if(Ext.isArray(errors)){
+        if (Ext.isArray(errors)) {
             for(var i = 0, len = errors.length; i < len; i++){
                 var fieldError = errors[i];
                 var f = this.findField(fieldError.id);
@@ -38413,7 +43107,7 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
                     f.markInvalid(fieldError.msg);
                 }
             }
-        }else{
+        } else {
             var field, id;
             for(id in errors){
                 if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
@@ -38421,6 +43115,7 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
                 }
             }
         }
+
         return this;
     },
 
@@ -38466,12 +43161,12 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
             n,
             key,
             val;
-        this.items.each(function(f){
-            if(dirtyOnly !== true || f.isDirty()){
+        this.items.each(function(f) {
+            if (!f.disabled && (dirtyOnly !== true || f.isDirty())) {
                 n = f.getName();
                 key = o[n];
                 val = f.getValue();
-                
+
                 if(Ext.isDefined(key)){
                     if(Ext.isArray(key)){
                         o[n].push(val);
@@ -38508,7 +43203,6 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
         return this;
     },
 
-
     
     remove : function(field){
         this.items.remove(field);
@@ -38516,6 +43210,11 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
     },
 
     
+    cleanDestroyed : function() {
+        this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
+    },
+
+    
     render : function(){
         this.items.each(function(f){
             if(f.isFormField && !f.rendered && document.getElementById(f.id)){ 
@@ -38554,6 +43253,7 @@ Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
 
 
 Ext.BasicForm = Ext.form.BasicForm;
+
 Ext.FormPanel = Ext.extend(Ext.Panel, {
     
     
@@ -38657,9 +43357,7 @@ Ext.FormPanel = Ext.extend(Ext.Panel, {
     
     beforeDestroy : function(){
         this.stopMonitoring();
-        
-        Ext.destroy(this.form);
-        this.form.items.clear();
+        this.form.destroy(true);
         Ext.FormPanel.superclass.beforeDestroy.call(this);
     },
 
@@ -38720,16 +43418,17 @@ Ext.FormPanel = Ext.extend(Ext.Panel, {
     },
 
     
-    processRemove : function(c){
-        
-        if(this.isField(c)){
-            this.form.remove(c);
-        
-        }else if(c.findBy){
-            var isDestroyed = function(o) {
-                return !!o.isDestroyed;
+    processRemove: function(c){
+        if(!this.destroying){
+            
+            if(this.isField(c)){
+                this.form.remove(c);
+            
+            }else if (c.findBy){
+                Ext.each(c.findBy(this.isField), this.form.remove, this.form);
+                
+                this.form.cleanDestroyed();
             }
-            this.form.items.filterBy(isDestroyed, this.form).each(this.form.remove, this.form);
         }
     },
 
@@ -38822,7 +43521,7 @@ Ext.form.FieldSet = Ext.extend(Ext.Panel, {
             this.el = document.createElement('fieldset');
             this.el.id = this.id;
             if (this.title || this.header || this.checkboxToggle) {
-                this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
+                this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
             }
         }
 
@@ -38897,7 +43596,6 @@ Ext.form.FieldSet = Ext.extend(Ext.Panel, {
 });
 Ext.reg('fieldset', Ext.form.FieldSet);
 
-
 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     
     enableFormat : true,
@@ -38964,7 +43662,8 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             'push',
              
             'editmodechange'
-        )
+        );
+        Ext.form.HtmlEditor.superclass.initComponent.call(this);
     },
 
     
@@ -38987,7 +43686,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     createToolbar : function(editor){
         var items = [];
         var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
-        
+
 
         function btn(id, toggle, handler){
             return {
@@ -39013,7 +43712,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                     html: this.createFontOptions()
                }
             });
-            
+
             items.push(
                 fontSelectItem,
                 '-'
@@ -39124,16 +43823,16 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 );
             }
         }
+
         
         var tb = new Ext.Toolbar({
             renderTo: this.wrap.dom.firstChild,
             items: items
         });
-        
+
         if (fontSelectItem) {
             this.fontSelect = fontSelectItem.el;
-            
+
             this.mon(this.fontSelect, 'change', function(){
                 var font = this.fontSelect.dom.value;
                 this.relayCmd('fontname', font);
@@ -39141,15 +43840,13 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             }, this);
         }
 
-
         
         this.mon(tb.el, 'click', function(e){
             e.preventDefault();
         });
-       
-        
-        
+
         this.tb = tb;
+        this.tb.doLayout();
     },
 
     onDisable: function(){
@@ -39163,20 +43860,26 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     },
 
     setReadOnly: function(readOnly){
+
+        Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
         if(this.initialized){
-            var newDM = readOnly ? 'off' : 'on',
-                doc = this.getDoc();
-            if(String(doc.designMode).toLowerCase() != newDM){
-                doc.designMode = newDM;
+            if(Ext.isIE){
+                this.getEditorBody().contentEditable = !readOnly;
+            }else{
+                this.setDesignMode(!readOnly);
+            }
+            var bd = this.getEditorBody();
+            if(bd){
+                bd.style.cursor = this.readOnly ? 'default' : 'text';
             }
-            this.disableItems(!readOnly);
+            this.disableItems(readOnly);
         }
-        Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
     },
 
     
     getDocMarkup : function(){
-        return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
+        var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
+        return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
     },
 
     
@@ -39202,7 +43905,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         this.el.dom.setAttribute('tabIndex', -1);
         this.el.addClass('x-hidden');
         if(Ext.isIE){ 
-            this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
+            this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
         }
         this.wrap = this.el.wrap({
             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
@@ -39211,8 +43914,8 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         this.createToolbar(this);
 
         this.disableItems(true);
-        
-        
+
+        this.tb.doLayout();
 
         this.createIFrame();
 
@@ -39227,9 +43930,10 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         var iframe = document.createElement('iframe');
         iframe.name = Ext.id();
         iframe.frameBorder = '0';
+        iframe.style.overflow = 'auto';
         iframe.src = Ext.SSL_SECURE_URL;
-        this.wrap.dom.appendChild(iframe);
 
+        this.wrap.dom.appendChild(iframe);
         this.iframe = iframe;
 
         this.monitorTask = Ext.TaskMgr.start({
@@ -39253,7 +43957,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 var doc = this.getDoc();
                 if(doc.body || doc.readyState == 'complete'){
                     Ext.TaskMgr.stop(task);
-                    doc.designMode="on";
+                    this.setDesignMode(true);
                     this.initEditor.defer(10, this);
                 }
             },
@@ -39271,12 +43975,32 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             if(!doc){
                 return;
             }
-            if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){
+            if(!doc.editorInitialized || this.getDesignMode() != 'on'){
                 this.initFrame();
             }
         }
     },
 
+    
+    setDesignMode : function(mode){
+        var doc = this.getDoc();
+        if (doc) {
+            if(this.readOnly){
+                mode = false;
+            }
+            doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
+        }
+
+    },
+
+    
+    getDesignMode : function(){
+        var doc = this.getDoc();
+        if(!doc){ return ''; }
+        return String(doc.designMode).toLowerCase();
+
+    },
+
     disableItems: function(disabled){
         if(this.fontSelect){
             this.fontSelect.dom.disabled = disabled;
@@ -39312,45 +44036,55 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
 
     
     toggleSourceEdit : function(sourceEditMode){
-        if(sourceEditMode === undefined){
+        var iframeHeight,
+            elHeight;
+
+        if (sourceEditMode === undefined) {
             sourceEditMode = !this.sourceEditMode;
         }
         this.sourceEditMode = sourceEditMode === true;
         var btn = this.tb.getComponent('sourceedit');
-        
-        if(btn.pressed !== this.sourceEditMode){
+
+        if (btn.pressed !== this.sourceEditMode) {
             btn.toggle(this.sourceEditMode);
-            if(!btn.xtbHidden){
+            if (!btn.xtbHidden) {
                 return;
             }
         }
-        if(this.sourceEditMode){
+        if (this.sourceEditMode) {
+            
+            this.previousSize = this.getSize();
+
+            iframeHeight = Ext.get(this.iframe).getHeight();
+
             this.disableItems(true);
             this.syncValue();
             this.iframe.className = 'x-hidden';
             this.el.removeClass('x-hidden');
             this.el.dom.removeAttribute('tabIndex');
             this.el.focus();
-        }else{
-            if(this.initialized && !this.readOnly){
-                this.disableItems(false);
+            this.el.dom.style.height = iframeHeight + 'px';
+        }
+        else {
+            elHeight = parseInt(this.el.dom.style.height, 10);
+            if (this.initialized) {
+                this.disableItems(this.readOnly);
             }
             this.pushValue();
             this.iframe.className = '';
             this.el.addClass('x-hidden');
             this.el.dom.setAttribute('tabIndex', -1);
             this.deferFocus();
-        }
-        var lastSize = this.lastSize;
-        if(lastSize){
-            delete this.lastSize;
-            this.setSize(lastSize);
+
+            this.setSize(this.previousSize);
+            delete this.previousSize;
+            this.iframe.style.height = elHeight + 'px';
         }
         this.fireEvent('editmodechange', this, this.sourceEditMode);
     },
 
     
-    createLink : function(){
+    createLink : function() {
         var url = prompt(this.createLinkText, this.defaultLinkValue);
         if(url && url != 'http:/'+'/'){
             this.relayCmd('createlink', url);
@@ -39426,14 +44160,12 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 this.getEditorBody().innerHTML = v;
                 if(Ext.isGecko){
                     
-                    var d = this.getDoc(),
-                        mode = d.designMode.toLowerCase();
-
-                    d.designMode = mode.toggle('on', 'off');
-                    d.designMode = mode;
+                    this.setDesignMode(false);  
+                    this.setDesignMode(true);
                 }
                 this.fireEvent('push', this, v);
             }
+
         }
     },
 
@@ -39456,15 +44188,15 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         
         try{
             var dbody = this.getEditorBody(),
-                ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat'),
+                ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
                 doc,
                 fn;
-                
+
             ss['background-attachment'] = 'fixed'; 
             dbody.bgProperties = 'fixed'; 
 
             Ext.DomHelper.applyStyles(dbody, ss);
-            
+
             doc = this.getDoc();
 
             if(doc){
@@ -39498,7 +44230,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     },
 
     
-    onDestroy : function(){
+    beforeDestroy : function(){
         if(this.monitorTask){
             Ext.TaskMgr.stop(this.monitorTask);
         }
@@ -39518,18 +44250,13 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 this.wrap.remove();
             }
         }
-        
-        if(this.el){
-            this.el.removeAllListeners();
-            this.el.remove();
-        }
-        this.purgeListeners();
+        Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
     },
 
     
     onFirstFocus : function(){
         this.activated = true;
-        this.disableItems(false);
+        this.disableItems(this.readOnly);
         if(Ext.isGecko){ 
             this.win.focus();
             var s = this.win.getSelection();
@@ -39596,7 +44323,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             return;
         }
 
-        var btns = this.tb.items.map, 
+        var btns = this.tb.items.map,
             doc = this.getDoc();
 
         if(this.enableFont && !Ext.isSafari2){
@@ -39698,7 +44425,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     fixKeys : function(){ 
         if(Ext.isIE){
             return function(e){
-                var k = e.getKey(), 
+                var k = e.getKey(),
                     doc = this.getDoc(),
                         r;
                 if(k == e.TAB){
@@ -39863,6 +44590,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     
 });
 Ext.reg('htmleditor', Ext.form.HtmlEditor);
+
 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
     
     minValue : undefined,
@@ -39877,7 +44605,7 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
     
     format : "g:i A",
     
-    altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H",
+    altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",
     
     increment: 15,
 
@@ -39887,12 +44615,14 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
     triggerAction: 'all',
     
     typeAhead: false,
-    
+
     
     
     
     initDate: '1/1/2008',
 
+    initDateFormat: 'j/n/Y',
+
     
     initComponent : function(){
         if(Ext.isDefined(this.minValue)){
@@ -39906,7 +44636,7 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
         }
         Ext.form.TimeField.superclass.initComponent.call(this);
     },
-    
+
     
     setMinValue: function(value,  initial){
         this.setLimit(value, true, initial);
@@ -39918,13 +44648,13 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
         this.setLimit(value, false, initial);
         return this;
     },
-    
+
     
     generateStore: function(initial){
         var min = this.minValue || new Date(this.initDate).clearTime(),
             max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
             times = [];
-            
+
         while(min <= max){
             times.push(min.dateFormat(this.format));
             min = min.add('mi', this.increment);
@@ -39942,14 +44672,14 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
         }
         if(d){
             var val = new Date(this.initDate).clearTime();
-            val.setHours(d.getHours(), d.getMinutes(), isMin ? 0 : 59, 0);
+            val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
             this[isMin ? 'minValue' : 'maxValue'] = val;
             if(!initial){
                 this.generateStore();
             }
         }
     },
-    
+
     
     getValue : function(){
         var v = Ext.form.TimeField.superclass.getValue.call(this);
@@ -39963,24 +44693,141 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
 
     
     validateValue : Ext.form.DateField.prototype.validateValue,
-    parseDate : Ext.form.DateField.prototype.parseDate,
+
     formatDate : Ext.form.DateField.prototype.formatDate,
 
-    
-    beforeBlur : function(){
-        var v = this.parseDate(this.getRawValue());
-        if(v){
-            this.setValue(v.dateFormat(this.format));
+    parseDate: function(value) {
+        if (!value || Ext.isDate(value)) {
+            return value;
         }
-        Ext.form.TimeField.superclass.beforeBlur.call(this);
-    }
 
+        var id = this.initDate + ' ',
+            idf = this.initDateFormat + ' ',
+            v = Date.parseDate(id + value, idf + this.format), 
+            af = this.altFormats;
+
+        if (!v && af) {
+            if (!this.altFormatsArray) {
+                this.altFormatsArray = af.split("|");
+            }
+            for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
+                v = Date.parseDate(id + value, idf + afa[i]);
+            }
+        }
+
+        return v;
+    }
+});
+Ext.reg('timefield', Ext.form.TimeField);
+Ext.form.SliderField = Ext.extend(Ext.form.Field, {
+    
+    
+    useTips : true,
+    
+    
+    tipText : null,
+    
+    
+    actionMode: 'wrap',
+    
+    
+    initComponent : function() {
+        var cfg = Ext.copyTo({
+            id: this.id + '-slider'
+        }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
+        
+        
+        if (this.useTips) {
+            var plug = this.tipText ? {getText: this.tipText} : {};
+            cfg.plugins = [new Ext.slider.Tip(plug)];
+        }
+        this.slider = new Ext.Slider(cfg);
+        Ext.form.SliderField.superclass.initComponent.call(this);
+    },    
+    
+    
+    onRender : function(ct, position){
+        this.autoCreate = {
+            id: this.id,
+            name: this.name,
+            type: 'hidden',
+            tag: 'input'    
+        };
+        Ext.form.SliderField.superclass.onRender.call(this, ct, position);
+        this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
+        this.resizeEl = this.positionEl = this.wrap;
+        this.slider.render(this.wrap);
+    },
+    
+    
+    onResize : function(w, h, aw, ah){
+        Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
+        this.slider.setSize(w, h);    
+    },
+    
+    
+    initEvents : function(){
+        Ext.form.SliderField.superclass.initEvents.call(this);
+        this.slider.on('change', this.onChange, this);   
+    },
+    
+    
+    onChange : function(slider, v){
+        this.setValue(v, undefined, true);
+    },
+    
+    
+    onEnable : function(){
+        Ext.form.SliderField.superclass.onEnable.call(this);
+        this.slider.enable();
+    },
+    
+    
+    onDisable : function(){
+        Ext.form.SliderField.superclass.onDisable.call(this);
+        this.slider.disable();    
+    },
+    
+    
+    beforeDestroy : function(){
+        Ext.destroy(this.slider);
+        Ext.form.SliderField.superclass.beforeDestroy.call(this);
+    },
+    
+    
+    alignErrorIcon : function(){
+        this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
+    },
+    
     
+    setMinValue : function(v){
+        this.slider.setMinValue(v);
+        return this;    
+    },
+    
+    
+    setMaxValue : function(v){
+        this.slider.setMaxValue(v);
+        return this;    
+    },
     
     
+    setValue : function(v, animate,  silent){
+        
+        
+        if(!silent){
+            this.slider.setValue(v, animate);
+        }
+        return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
+    },
+    
     
+    getValue : function(){
+        return this.slider.getValue();    
+    }
 });
-Ext.reg('timefield', Ext.form.TimeField);
+
+Ext.reg('sliderfield', Ext.form.SliderField);
 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
     
     
@@ -40039,6 +44886,8 @@ Ext.form.Action.prototype = {
 
 
 
+
+
     type : 'default',
 
  
@@ -40136,10 +44985,25 @@ Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
 
     
     run : function(){
-        var o = this.options;
-        var method = this.getMethod();
-        var isGet = method == 'GET';
+        var o = this.options,
+            method = this.getMethod(),
+            isGet = method == 'GET';
         if(o.clientValidation === false || this.form.isValid()){
+            if (o.submitEmptyText === false) {
+                var fields = this.form.items,
+                    emptyFields = [],
+                    setupEmptyFields = function(f){
+                        if (f.el.getValue() == f.emptyText) {
+                            emptyFields.push(f);
+                            f.el.dom.value = "";
+                        }
+                        if(f.isComposite && f.rendered){
+                            f.items.each(setupEmptyFields);
+                        }
+                    };
+                    
+                fields.each(setupEmptyFields);
+            }
             Ext.Ajax.request(Ext.apply(this.createCallback(o), {
                 form:this.form.el.dom,
                 url:this.getUrl(isGet),
@@ -40148,6 +45012,13 @@ Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
                 params:!isGet ? this.getParams() : null,
                 isUpload: this.form.fileUpload
             }));
+            if (o.submitEmptyText === false) {
+                Ext.each(emptyFields, function(f) {
+                    if (f.applyEmptyText) {
+                        f.applyEmptyText();
+                    }
+                });
+            }
         }else if (o.clientValidation !== false){ 
             this.failureType = Ext.form.Action.CLIENT_INVALID;
             this.form.afterAction(this, false);
@@ -40277,7 +45148,7 @@ Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
         this.result = result;
         return result;
     },
-    
+
     success : function(response, trans){
         if(trans.type == Ext.Direct.exceptions.SERVER){
             response = {};
@@ -40320,7 +45191,7 @@ Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
         this.result = result;
         return result;
     },
-    
+
     success : function(response, trans){
         if(trans.type == Ext.Direct.exceptions.SERVER){
             response = {};
@@ -40352,7 +45223,7 @@ Ext.form.VTypes = function(){
         
         'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
         
-        'emailMask' : /[a-z0-9_\.\-@]/i,
+        'emailMask' : /[a-z0-9_\.\-@\+]/i,
 
         
         'url' : function(v){
@@ -40360,7 +45231,7 @@ Ext.form.VTypes = function(){
         },
         
         'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
-        
+
         
         'alpha' : function(v){
             return alpha.test(v);
@@ -40380,66 +45251,83 @@ Ext.form.VTypes = function(){
         'alphanumMask' : /[a-z0-9_]/i
     };
 }();
+
 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
     
     autoExpandColumn : false,
     
+    
     autoExpandMax : 1000,
     
+    
     autoExpandMin : 50,
     
+    
     columnLines : false,
     
     
     
     
     
+    
     ddText : '{0} selected row{1}',
     
+    
     deferRowRender : true,
     
     
     
+    
     enableColumnHide : true,
     
+    
     enableColumnMove : true,
     
+    
     enableDragDrop : false,
     
+    
     enableHdMenu : true,
     
     
+    
     loadMask : false,
     
     
+    
     minColumnWidth : 25,
     
     
     
     
+    
     stripeRows : false,
     
+    
     trackMouseOver : true,
     
-    stateEvents : ['columnmove', 'columnresize', 'sortchange'],
     
-    view : null,
+    stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
     
     
-    bubbleEvents: [],
+    view : null,
+
     
+    bubbleEvents: [],
+
     
 
     
     rendered : false,
     
+    
     viewReady : false,
 
     
-    initComponent : function(){
+    initComponent : function() {
         Ext.grid.GridPanel.superclass.initComponent.call(this);
 
-        if(this.columnLines){
+        if (this.columnLines) {
             this.cls = (this.cls || '') + ' x-grid-with-col-lines';
         }
         
@@ -40495,13 +45383,13 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
             'rowmousedown',
             
             'headermousedown',
-            
+
             
             'groupmousedown',
-            
+
             
             'rowbodymousedown',
-            
+
             
             'containermousedown',
 
@@ -40525,12 +45413,12 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
             'containerclick',
             
             'containerdblclick',
-            
+
             
             'rowbodyclick',
             
             'rowbodydblclick',
-            
+
             
             'rowcontextmenu',
             
@@ -40552,6 +45440,8 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
             
             'sortchange',
             
+            'groupchange',
+            
             'reconfigure',
             
             'viewready'
@@ -40599,23 +45489,43 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
 
     applyState : function(state){
         var cm = this.colModel,
-            cs = state.columns;
+            cs = state.columns,
+            store = this.store,
+            s,
+            c,
+            colIndex;
+
         if(cs){
             for(var i = 0, len = cs.length; i < len; i++){
-                var s = cs[i],
-                    c = cm.getColumnById(s.id);
+                s = cs[i];
+                c = cm.getColumnById(s.id);
                 if(c){
-                    c.hidden = s.hidden;
-                    c.width = s.width;
-                    var oldIndex = cm.getIndexById(s.id);
-                    if(oldIndex != i){
-                        cm.moveColumn(oldIndex, i);
+                    colIndex = cm.getIndexById(s.id);
+                    cm.setState(colIndex, {
+                        hidden: s.hidden,
+                        width: s.width,
+                        sortable: s.sortable
+                    });
+                    if(colIndex != i){
+                        cm.moveColumn(colIndex, i);
                     }
                 }
             }
         }
-        if(state.sort && this.store){
-            this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
+        if(store){
+            s = state.sort;
+            if(s){
+                store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
+            }
+            s = state.group;
+            if(store.groupBy){
+                if(s){
+                    store.groupBy(s);
+                }else{
+                    store.clearGrouping();
+                }
+            }
+
         }
         var o = Ext.apply({}, state);
         delete o.columns;
@@ -40624,7 +45534,11 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
     },
 
     getState : function(){
-        var o = {columns: []};
+        var o = {columns: []},
+            store = this.store,
+            ss,
+            gs;
+
         for(var i = 0, c; (c = this.colModel.config[i]); i++){
             o.columns[i] = {
                 id: c.id,
@@ -40633,12 +45547,21 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
             if(c.hidden){
                 o.columns[i].hidden = true;
             }
+            if(c.sortable){
+                o.columns[i].sortable = true;
+            }
         }
-        if(this.store){
-            var ss = this.store.getSortState();
+        if(store){
+            ss = store.getSortState();
             if(ss){
                 o.sort = ss;
             }
+            if(store.getGroupState){
+                gs = store.getGroupState();
+                if(gs){
+                    o.group = gs;
+                }
+            }
         }
         return o;
     },
@@ -40648,9 +45571,12 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
         Ext.grid.GridPanel.superclass.afterRender.call(this);
         var v = this.view;
         this.on('bodyresize', v.layout, v);
-        v.layout();
+        v.layout(true);
         if(this.deferRowRender){
-            v.afterRender.defer(10, this.view);
+            if (!this.deferRowRenderTask){
+                this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
+            }
+            this.deferRowRenderTask.delay(10);
         }else{
             v.afterRender();
         }
@@ -40680,6 +45606,9 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
 
     
     onDestroy : function(){
+        if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
+            this.deferRowRenderTask.cancel();
+        }
         if(this.rendered){
             Ext.destroy(this.view, this.loadMask);
         }else if(this.store && this.store.autoDestroy){
@@ -40692,31 +45621,6 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
 
     
     processEvent : function(name, e){
-        this.fireEvent(name, e);
-        var t = e.getTarget(),
-            v = this.view,
-            header = v.findHeaderIndex(t);
-            
-        if(header !== false){
-            this.fireEvent('header' + name, this, header, e);
-        }else{
-            var row = v.findRowIndex(t),
-                cell,
-                body;
-            if(row !== false){
-                this.fireEvent('row' + name, this, row, e);
-                cell = v.findCellIndex(t);
-                body = v.findRowBody(t);
-                if(cell !== false){
-                    this.fireEvent('cell' + name, this, row, cell, e);
-                }
-                if(body){
-                    this.fireEvent('rowbody' + name, this, row, e);
-                }
-            }else{
-                this.fireEvent('container' + name, this, e);
-            }
-        }
         this.view.processEvent(name, e);
     },
 
@@ -40742,11 +45646,12 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
 
     
     walkCells : function(row, col, step, fn, scope){
-        var cm = this.colModel, 
-            clen = cm.getColumnCount(),
-            ds = this.store, 
-            rlen = ds.getCount(), 
+        var cm    = this.colModel,
+            clen  = cm.getColumnCount(),
+            ds    = this.store,
+            rlen  = ds.getCount(),
             first = true;
+
         if(step < 0){
             if(col < 0){
                 row--;
@@ -40788,14 +45693,6 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
     },
 
     
-    onResize : function(){
-        Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);
-        if(this.viewReady){
-            this.view.layout();
-        }
-    },
-
-    
     getGridEl : function(){
         return this.body;
     },
@@ -40823,10 +45720,11 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
     },
 
     
-    getView : function(){
-        if(!this.view){
+    getView : function() {
+        if (!this.view) {
             this.view = new Ext.grid.GridView(this.viewConfig);
         }
+        
         return this.view;
     },
     
@@ -40887,26 +45785,246 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
     
 });
 Ext.reg('grid', Ext.grid.GridPanel);
+Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, {
+    
+    
+    aggregator: 'sum',
+    
+    
+    renderer: undefined,
+    
+    
+    
+    
+    
+    
+    
+    
+    initComponent: function() {
+        Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments);
+        
+        this.initAxes();
+        
+        
+        this.enableColumnResize = false;
+        
+        this.viewConfig = Ext.apply(this.viewConfig || {}, {
+            forceFit: true
+        });
+        
+        
+        
+        this.colModel = new Ext.grid.ColumnModel({});
+    },
+    
+    
+    getAggregator: function() {
+        if (typeof this.aggregator == 'string') {
+            return Ext.grid.PivotAggregatorMgr.types[this.aggregator];
+        } else {
+            return this.aggregator;
+        }
+    },
+    
+    
+    setAggregator: function(aggregator) {
+        this.aggregator = aggregator;
+    },
+    
+    
+    setMeasure: function(measure) {
+        this.measure = measure;
+    },
+    
+    
+    setLeftAxis: function(axis, refresh) {
+        
+        this.leftAxis = axis;
+        
+        if (refresh) {
+            this.view.refresh();
+        }
+    },
+    
+    
+    setTopAxis: function(axis, refresh) {
+        
+        this.topAxis = axis;
+        
+        if (refresh) {
+            this.view.refresh();
+        }
+    },
+    
+    
+    initAxes: function() {
+        var PivotAxis = Ext.grid.PivotAxis;
+        
+        if (!(this.leftAxis instanceof PivotAxis)) {
+            this.setLeftAxis(new PivotAxis({
+                orientation: 'vertical',
+                dimensions : this.leftAxis || [],
+                store      : this.store
+            }));
+        };
+        
+        if (!(this.topAxis instanceof PivotAxis)) {
+            this.setTopAxis(new PivotAxis({
+                orientation: 'horizontal',
+                dimensions : this.topAxis || [],
+                store      : this.store
+            }));
+        };
+    },
+    
+    
+    extractData: function() {
+        var records  = this.store.data.items,
+            recCount = records.length,
+            cells    = [],
+            record, i, j, k;
+        
+        if (recCount == 0) {
+            return [];
+        }
+        
+        var leftTuples = this.leftAxis.getTuples(),
+            leftCount  = leftTuples.length,
+            topTuples  = this.topAxis.getTuples(),
+            topCount   = topTuples.length,
+            aggregator = this.getAggregator();
+        
+        for (i = 0; i < recCount; i++) {
+            record = records[i];
+            
+            for (j = 0; j < leftCount; j++) {
+                cells[j] = cells[j] || [];
+                
+                if (leftTuples[j].matcher(record) === true) {
+                    for (k = 0; k < topCount; k++) {
+                        cells[j][k] = cells[j][k] || [];
+                        
+                        if (topTuples[k].matcher(record)) {
+                            cells[j][k].push(record);
+                        }
+                    }
+                }
+            }
+        }
+        
+        var rowCount = cells.length,
+            colCount, row;
+        
+        for (i = 0; i < rowCount; i++) {
+            row = cells[i];
+            colCount = row.length;
+            
+            for (j = 0; j < colCount; j++) {
+                cells[i][j] = aggregator(cells[i][j], this.measure);
+            }
+        }
+        
+        return cells;
+    },
+    
+    
+    getView: function() {
+        if (!this.view) {
+            this.view = new Ext.grid.PivotGridView(this.viewConfig);
+        }
+        
+        return this.view;
+    }
+});
+
+Ext.reg('pivotgrid', Ext.grid.PivotGrid);
+
+
+Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager();
+
+Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) {
+    var length = records.length,
+        total  = 0,
+        i;
+    
+    for (i = 0; i < length; i++) {
+        total += records[i].get(measure);
+    }
+    
+    return total;
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) {
+    var length = records.length,
+        total  = 0,
+        i;
+    
+    for (i = 0; i < length; i++) {
+        total += records[i].get(measure);
+    }
+    
+    return (total / length) || 'n/a';
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) {
+    var data   = [],
+        length = records.length,
+        i;
+    
+    for (i = 0; i < length; i++) {
+        data.push(records[i].get(measure));
+    }
+    
+    return Math.min.apply(this, data) || 'n/a';
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) {
+    var data   = [],
+        length = records.length,
+        i;
+    
+    for (i = 0; i < length; i++) {
+        data.push(records[i].get(measure));
+    }
+    
+    return Math.max.apply(this, data) || 'n/a';
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) {
+    return records.length;
+});
 Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     
+
     
+
     
+
     
+
     
+
     
     deferEmptyText : true,
+
     
     scrollOffset : undefined,
+
     
     autoFill : false,
+
     
     forceFit : false,
+
     
     sortClasses : ['sort-asc', 'sort-desc'],
+
     
     sortAscText : 'Sort Ascending',
+
     
     sortDescText : 'Sort Descending',
+
     
     columnsText : 'Columns',
 
@@ -40917,121 +46035,169 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     borderWidth : 2,
     tdClass : 'x-grid3-cell',
     hdCls : 'x-grid3-hd',
+    
+    
+    
     markDirty : true,
 
     
     cellSelectorDepth : 4,
     
-    rowSelectorDepth : 10,
     
+    rowSelectorDepth : 10,
+
     
     rowBodySelectorDepth : 10,
 
     
     cellSelector : 'td.x-grid3-cell',
     
-    rowSelector : 'div.x-grid3-row',
     
+    rowSelector : 'div.x-grid3-row',
+
     
     rowBodySelector : 'div.x-grid3-row-body',
-    
+
     
     firstRowCls: 'x-grid3-row-first',
     lastRowCls: 'x-grid3-row-last',
     rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
     
-    constructor : function(config){
+    
+    headerMenuOpenCls: 'x-grid3-hd-menu-open',
+    
+    
+    rowOverCls: 'x-grid3-row-over',
+
+    constructor : function(config) {
         Ext.apply(this, config);
-           
-           this.addEvents(
-               
-               'beforerowremoved',
-               
-               'beforerowsinserted',
-               
-               'beforerefresh',
-               
-               'rowremoved',
-               
-               'rowsinserted',
-               
-               'rowupdated',
-               
-               'refresh'
-           );
-           Ext.grid.GridView.superclass.constructor.call(this);    
+        
+        
+        this.addEvents(
+            
+            'beforerowremoved',
+            
+            
+            'beforerowsinserted',
+            
+            
+            'beforerefresh',
+            
+            
+            'rowremoved',
+            
+            
+            'rowsinserted',
+            
+            
+            'rowupdated',
+            
+            
+            'refresh'
+        );
+        
+        Ext.grid.GridView.superclass.constructor.call(this);
     },
 
     
-
     
-    initTemplates : function(){
-        var ts = this.templates || {};
-        if(!ts.master){
-            ts.master = new Ext.Template(
-                    '<div class="x-grid3" hidefocus="true">',
-                        '<div class="x-grid3-viewport">',
-                            '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
-                            '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
-                        '</div>',
-                        '<div class="x-grid3-resize-marker">&#160;</div>',
-                        '<div class="x-grid3-resize-proxy">&#160;</div>',
-                    '</div>'
-                    );
-        }
-
-        if(!ts.header){
-            ts.header = new Ext.Template(
-                    '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
-                    '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
-                    '</table>'
-                    );
-        }
-
-        if(!ts.hcell){
-            ts.hcell = new Ext.Template(
-                    '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
-                    '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
-                    '</div></td>'
-                    );
-        }
-
-        if(!ts.body){
-            ts.body = new Ext.Template('{rows}');
-        }
-
-        if(!ts.row){
-            ts.row = new Ext.Template(
-                    '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
-                    '<tbody><tr>{cells}</tr>',
-                    (this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
-                    '</tbody></table></div>'
-                    );
-        }
-
-        if(!ts.cell){
-            ts.cell = new Ext.Template(
-                    '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
-                    '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
-                    '</td>'
-                    );
-        }
+    
+    masterTpl: new Ext.Template(
+        '<div class="x-grid3" hidefocus="true">',
+            '<div class="x-grid3-viewport">',
+                '<div class="x-grid3-header">',
+                    '<div class="x-grid3-header-inner">',
+                        '<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',
+                    '</div>',
+                    '<div class="x-clear"></div>',
+                '</div>',
+                '<div class="x-grid3-scroller">',
+                    '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
+                    '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
+                '</div>',
+            '</div>',
+            '<div class="x-grid3-resize-marker">&#160;</div>',
+            '<div class="x-grid3-resize-proxy">&#160;</div>',
+        '</div>'
+    ),
+    
+    
+    headerTpl: new Ext.Template(
+        '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
+            '<thead>',
+                '<tr class="x-grid3-hd-row">{cells}</tr>',
+            '</thead>',
+        '</table>'
+    ),
+    
+    
+    bodyTpl: new Ext.Template('{rows}'),
+    
+    
+    cellTpl: new Ext.Template(
+        '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
+            '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
+        '</td>'
+    ),
+    
+    
+    initTemplates : function() {
+        var templates = this.templates || {},
+            template, name,
+            
+            headerCellTpl = new Ext.Template(
+                '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
+                    '<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', 
+                        this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
+                        '{value}',
+                        '<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
+                    '</div>',
+                '</td>'
+            ),
+        
+            rowBodyText = [
+                '<tr class="x-grid3-row-body-tr" style="{bodyStyle}">',
+                    '<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">',
+                        '<div class="x-grid3-row-body">{body}</div>',
+                    '</td>',
+                '</tr>'
+            ].join(""),
+        
+            innerText = [
+                '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
+                     '<tbody>',
+                        '<tr>{cells}</tr>',
+                        this.enableRowBody ? rowBodyText : '',
+                     '</tbody>',
+                '</table>'
+            ].join("");
+        
+        Ext.applyIf(templates, {
+            hcell   : headerCellTpl,
+            cell    : this.cellTpl,
+            body    : this.bodyTpl,
+            header  : this.headerTpl,
+            master  : this.masterTpl,
+            row     : new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">' + innerText + '</div>'),
+            rowInner: new Ext.Template(innerText)
+        });
 
-        for(var k in ts){
-            var t = ts[k];
-            if(t && Ext.isFunction(t.compile) && !t.compiled){
-                t.disableFormats = true;
-                t.compile();
+        for (name in templates) {
+            template = templates[name];
+            
+            if (template && Ext.isFunction(template.compile) && !template.compiled) {
+                template.disableFormats = true;
+                template.compile();
             }
         }
 
-        this.templates = ts;
+        this.templates = templates;
         this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
     },
 
     
-    fly : function(el){
-        if(!this._flyweight){
+    fly : function(el) {
+        if (!this._flyweight) {
             this._flyweight = new Ext.Element.Flyweight(document.body);
         }
         this._flyweight.dom = el;
@@ -41039,78 +46205,87 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    getEditorParent : function(){
+    getEditorParent : function() {
         return this.scroller.dom;
     },
 
     
-    initElements : function(){
-        var E = Ext.Element;
-
-        var el = this.grid.getGridEl().dom.firstChild;
-        var cs = el.childNodes;
-
-        this.el = new E(el);
-
-        this.mainWrap = new E(cs[0]);
-        this.mainHd = new E(this.mainWrap.dom.firstChild);
-
-        if(this.grid.hideHeaders){
-            this.mainHd.setDisplayed(false);
+    initElements : function() {
+        var Element  = Ext.Element,
+            el       = Ext.get(this.grid.getGridEl().dom.firstChild),
+            mainWrap = new Element(el.child('div.x-grid3-viewport')),
+            mainHd   = new Element(mainWrap.child('div.x-grid3-header')),
+            scroller = new Element(mainWrap.child('div.x-grid3-scroller'));
+        
+        if (this.grid.hideHeaders) {
+            mainHd.setDisplayed(false);
         }
-
-        this.innerHd = this.mainHd.dom.firstChild;
-        this.scroller = new E(this.mainWrap.dom.childNodes[1]);
-        if(this.forceFit){
-            this.scroller.setStyle('overflow-x', 'hidden');
+        
+        if (this.forceFit) {
+            scroller.setStyle('overflow-x', 'hidden');
         }
         
-        this.mainBody = new E(this.scroller.dom.firstChild);
-
-        this.focusEl = new E(this.scroller.dom.childNodes[1]);
+        
+        
+        Ext.apply(this, {
+            el      : el,
+            mainWrap: mainWrap,
+            scroller: scroller,
+            mainHd  : mainHd,
+            innerHd : mainHd.child('div.x-grid3-header-inner').dom,
+            mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')),
+            focusEl : new Element(Element.fly(scroller).child('a')),
+            
+            resizeMarker: new Element(el.child('div.x-grid3-resize-marker')),
+            resizeProxy : new Element(el.child('div.x-grid3-resize-proxy'))
+        });
+        
         this.focusEl.swallowEvent('click', true);
-
-        this.resizeMarker = new E(cs[1]);
-        this.resizeProxy = new E(cs[2]);
     },
 
     
-    getRows : function(){
+    getRows : function() {
         return this.hasRows() ? this.mainBody.dom.childNodes : [];
     },
 
     
 
     
-    findCell : function(el){
-        if(!el){
+    findCell : function(el) {
+        if (!el) {
             return false;
         }
         return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
     },
 
     
-    findCellIndex : function(el, requiredCls){
-        var cell = this.findCell(el);
-        if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
-            return this.getCellIndex(cell);
+    findCellIndex : function(el, requiredCls) {
+        var cell = this.findCell(el),
+            hasCls;
+        
+        if (cell) {
+            hasCls = this.fly(cell).hasClass(requiredCls);
+            if (!requiredCls || hasCls) {
+                return this.getCellIndex(cell);
+            }
         }
         return false;
     },
 
     
-    getCellIndex : function(el){
-        if(el){
-            var m = el.className.match(this.colRe);
-            if(m && m[1]){
-                return this.cm.getIndexById(m[1]);
+    getCellIndex : function(el) {
+        if (el) {
+            var match = el.className.match(this.colRe);
+            
+            if (match && match[1]) {
+                return this.cm.getIndexById(match[1]);
             }
         }
         return false;
     },
 
     
-    findHeaderCell : function(el){
+    findHeaderCell : function(el) {
         var cell = this.findCell(el);
         return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
     },
@@ -41121,56 +46296,57 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    findRow : function(el){
-        if(!el){
+    findRow : function(el) {
+        if (!el) {
             return false;
         }
         return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
     },
 
     
-    findRowIndex : function(el){
-        var r = this.findRow(el);
-        return r ? r.rowIndex : false;
+    findRowIndex : function(el) {
+        var row = this.findRow(el);
+        return row ? row.rowIndex : false;
     },
+
     
-    
-    findRowBody : function(el){
-        if(!el){
+    findRowBody : function(el) {
+        if (!el) {
             return false;
         }
+        
         return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
     },
 
     
 
     
-    getRow : function(row){
+    getRow : function(row) {
         return this.getRows()[row];
     },
 
     
-    getCell : function(row, col){
-        return this.getRow(row).getElementsByTagName('td')[col];
+    getCell : function(row, col) {
+        return Ext.fly(this.getRow(row)).query(this.cellSelector)[col]; 
     },
 
     
-    getHeaderCell : function(index){
-      return this.mainHd.dom.getElementsByTagName('td')[index];
+    getHeaderCell : function(index) {
+        return this.mainHd.dom.getElementsByTagName('td')[index];
     },
 
     
 
     
-    addRowClass : function(row, cls){
-        var r = this.getRow(row);
-        if(r){
-            this.fly(r).addClass(cls);
+    addRowClass : function(rowId, cls) {
+        var row = this.getRow(rowId);
+        if (row) {
+            this.fly(row).addClass(cls);
         }
     },
 
     
-    removeRowClass : function(row, cls){
+    removeRowClass : function(row, cls) {
         var r = this.getRow(row);
         if(r){
             this.fly(r).removeClass(cls);
@@ -41178,281 +46354,323 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    removeRow : function(row){
+    removeRow : function(row) {
         Ext.removeNode(this.getRow(row));
         this.syncFocusEl(row);
     },
+
     
-    
-    removeRows : function(firstRow, lastRow){
-        var bd = this.mainBody.dom;
-        for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
+    removeRows : function(firstRow, lastRow) {
+        var bd = this.mainBody.dom,
+            rowIndex;
+            
+        for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
             Ext.removeNode(bd.childNodes[firstRow]);
         }
+        
         this.syncFocusEl(firstRow);
     },
 
     
-
     
-    getScrollState : function(){
+    
+    getScrollState : function() {
         var sb = this.scroller.dom;
-        return {left: sb.scrollLeft, top: sb.scrollTop};
+        
+        return {
+            left: sb.scrollLeft, 
+            top : sb.scrollTop
+        };
     },
 
     
-    restoreScroll : function(state){
+    restoreScroll : function(state) {
         var sb = this.scroller.dom;
         sb.scrollLeft = state.left;
-        sb.scrollTop = state.top;
+        sb.scrollTop  = state.top;
     },
 
     
-    scrollToTop : function(){
-        this.scroller.dom.scrollTop = 0;
-        this.scroller.dom.scrollLeft = 0;
+    scrollToTop : function() {
+        var dom = this.scroller.dom;
+        
+        dom.scrollTop  = 0;
+        dom.scrollLeft = 0;
     },
 
     
-    syncScroll : function(){
-      this.syncHeaderScroll();
-      var mb = this.scroller.dom;
+    syncScroll : function() {
+        this.syncHeaderScroll();
+        var mb = this.scroller.dom;
         this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
     },
 
     
-    syncHeaderScroll : function(){
-        var mb = this.scroller.dom;
-        this.innerHd.scrollLeft = mb.scrollLeft;
-        this.innerHd.scrollLeft = mb.scrollLeft; 
+    syncHeaderScroll : function() {
+        var innerHd    = this.innerHd,
+            scrollLeft = this.scroller.dom.scrollLeft;
+        
+        innerHd.scrollLeft = scrollLeft;
+        innerHd.scrollLeft = scrollLeft; 
     },
-
     
-    updateSortIcon : function(col, dir){
-        var sc = this.sortClasses;
-        var hds = this.mainHd.select('td').removeClass(sc);
-        hds.item(col).addClass(sc[dir == 'DESC' ? 1 : 0]);
+    
+    updateSortIcon : function(col, dir) {
+        var sortClasses = this.sortClasses,
+            sortClass   = sortClasses[dir == "DESC" ? 1 : 0],
+            headers     = this.mainHd.select('td').removeClass(sortClasses);
+        
+        headers.item(col).addClass(sortClass);
     },
 
     
-    updateAllColumnWidths : function(){
-        var tw = this.getTotalWidth(),
-            clen = this.cm.getColumnCount(),
-            ws = [],
-            len,
-            i;
-        for(i = 0; i < clen; i++){
-            ws[i] = this.getColumnWidth(i);
-        }
-        this.innerHd.firstChild.style.width = this.getOffsetWidth();
-        this.innerHd.firstChild.firstChild.style.width = tw;
-        this.mainBody.dom.style.width = tw;
-        for(i = 0; i < clen; i++){
-            var hd = this.getHeaderCell(i);
-            hd.style.width = ws[i];
+    updateAllColumnWidths : function() {
+        var totalWidth = this.getTotalWidth(),
+            colCount   = this.cm.getColumnCount(),
+            rows       = this.getRows(),
+            rowCount   = rows.length,
+            widths     = [],
+            row, rowFirstChild, trow, i, j;
+        
+        for (i = 0; i < colCount; i++) {
+            widths[i] = this.getColumnWidth(i);
+            this.getHeaderCell(i).style.width = widths[i];
         }
-
-        var ns = this.getRows(), row, trow;
-        for(i = 0, len = ns.length; i < len; i++){
-            row = ns[i];
-            row.style.width = tw;
-            if(row.firstChild){
-                row.firstChild.style.width = tw;
-                trow = row.firstChild.rows[0];
-                for (var j = 0; j < clen; j++) {
-                   trow.childNodes[j].style.width = ws[j];
+        
+        this.updateHeaderWidth();
+        
+        for (i = 0; i < rowCount; i++) {
+            row = rows[i];
+            row.style.width = totalWidth;
+            rowFirstChild = row.firstChild;
+            
+            if (rowFirstChild) {
+                rowFirstChild.style.width = totalWidth;
+                trow = rowFirstChild.rows[0];
+                
+                for (j = 0; j < colCount; j++) {
+                    trow.childNodes[j].style.width = widths[j];
                 }
             }
         }
-
-        this.onAllColumnWidthsUpdated(ws, tw);
+        
+        this.onAllColumnWidthsUpdated(widths, totalWidth);
     },
 
     
-    updateColumnWidth : function(col, width){
-        var w = this.getColumnWidth(col);
-        var tw = this.getTotalWidth();
-        this.innerHd.firstChild.style.width = this.getOffsetWidth();
-        this.innerHd.firstChild.firstChild.style.width = tw;
-        this.mainBody.dom.style.width = tw;
-        var hd = this.getHeaderCell(col);
-        hd.style.width = w;
-
-        var ns = this.getRows(), row;
-        for(var i = 0, len = ns.length; i < len; i++){
-            row = ns[i];
-            row.style.width = tw;
-            if(row.firstChild){
-                row.firstChild.style.width = tw;
-                row.firstChild.rows[0].childNodes[col].style.width = w;
+    updateColumnWidth : function(column, width) {
+        var columnWidth = this.getColumnWidth(column),
+            totalWidth  = this.getTotalWidth(),
+            headerCell  = this.getHeaderCell(column),
+            nodes       = this.getRows(),
+            nodeCount   = nodes.length,
+            row, i, firstChild;
+        
+        this.updateHeaderWidth();
+        headerCell.style.width = columnWidth;
+        
+        for (i = 0; i < nodeCount; i++) {
+            row = nodes[i];
+            firstChild = row.firstChild;
+            
+            row.style.width = totalWidth;
+            if (firstChild) {
+                firstChild.style.width = totalWidth;
+                firstChild.rows[0].childNodes[column].style.width = columnWidth;
             }
         }
-
-        this.onColumnWidthUpdated(col, w, tw);
+        
+        this.onColumnWidthUpdated(column, columnWidth, totalWidth);
     },
-
     
-    updateColumnHidden : function(col, hidden){
-        var tw = this.getTotalWidth();
-        this.innerHd.firstChild.style.width = this.getOffsetWidth();
-        this.innerHd.firstChild.firstChild.style.width = tw;
-        this.mainBody.dom.style.width = tw;
-        var display = hidden ? 'none' : '';
-
-        var hd = this.getHeaderCell(col);
-        hd.style.display = display;
-
-        var ns = this.getRows(), row;
-        for(var i = 0, len = ns.length; i < len; i++){
-            row = ns[i];
-            row.style.width = tw;
-            if(row.firstChild){
-                row.firstChild.style.width = tw;
-                row.firstChild.rows[0].childNodes[col].style.display = display;
+    
+    updateColumnHidden : function(col, hidden) {
+        var totalWidth = this.getTotalWidth(),
+            display    = hidden ? 'none' : '',
+            headerCell = this.getHeaderCell(col),
+            nodes      = this.getRows(),
+            nodeCount  = nodes.length,
+            row, rowFirstChild, i;
+        
+        this.updateHeaderWidth();
+        headerCell.style.display = display;
+        
+        for (i = 0; i < nodeCount; i++) {
+            row = nodes[i];
+            row.style.width = totalWidth;
+            rowFirstChild = row.firstChild;
+            
+            if (rowFirstChild) {
+                rowFirstChild.style.width = totalWidth;
+                rowFirstChild.rows[0].childNodes[col].style.display = display;
             }
         }
-
-        this.onColumnHiddenUpdated(col, hidden, tw);
+        
+        this.onColumnHiddenUpdated(col, hidden, totalWidth);
         delete this.lastViewWidth; 
         this.layout();
     },
 
     
-    doRender : function(cs, rs, ds, startRow, colCount, stripe){
-        var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
-        var tstyle = 'width:'+this.getTotalWidth()+';';
-        
-        var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
-        for(var j = 0, len = rs.length; j < len; j++){
-            r = rs[j]; cb = [];
-            var rowIndex = (j+startRow);
-            for(var i = 0; i < colCount; i++){
-                c = cs[i];
-                p.id = c.id;
-                p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
-                p.attr = p.cellAttr = '';
-                p.value = c.renderer.call(c.scope, r.data[c.name], p, r, rowIndex, i, ds);
-                p.style = c.style;
-                if(Ext.isEmpty(p.value)){
-                    p.value = '&#160;';
-                }
-                if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){
-                    p.css += ' x-grid3-dirty-cell';
-                }
-                cb[cb.length] = ct.apply(p);
-            }
-            var alt = [];
-            if(stripe && ((rowIndex+1) % 2 === 0)){
+    doRender : function(columns, records, store, startRow, colCount, stripe) {
+        var templates = this.templates,
+            cellTemplate = templates.cell,
+            rowTemplate = templates.row,
+            last = colCount - 1,
+            tstyle = 'width:' + this.getTotalWidth() + ';',
+            
+            rowBuffer = [],
+            colBuffer = [],
+            rowParams = {tstyle: tstyle},
+            meta = {},
+            len  = records.length,
+            alt,
+            column,
+            record, i, j, rowIndex;
+
+        
+        for (j = 0; j < len; j++) {
+            record    = records[j];
+            colBuffer = [];
+
+            rowIndex = j + startRow;
+
+            
+            for (i = 0; i < colCount; i++) {
+                column = columns[i];
+                
+                meta.id    = column.id;
+                meta.css   = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
+                meta.attr  = meta.cellAttr = '';
+                meta.style = column.style;
+                meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
+
+                if (Ext.isEmpty(meta.value)) {
+                    meta.value = '&#160;';
+                }
+
+                if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
+                    meta.css += ' x-grid3-dirty-cell';
+                }
+
+                colBuffer[colBuffer.length] = cellTemplate.apply(meta);
+            }
+
+            alt = [];
+            
+            if (stripe && ((rowIndex + 1) % 2 === 0)) {
                 alt[0] = 'x-grid3-row-alt';
             }
-            if(r.dirty){
+
+            if (record.dirty) {
                 alt[1] = ' x-grid3-dirty-row';
             }
-            rp.cols = colCount;
-            if(this.getRowClass){
-                alt[2] = this.getRowClass(r, rowIndex, rp, ds);
+
+            rowParams.cols = colCount;
+
+            if (this.getRowClass) {
+                alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
             }
-            rp.alt = alt.join(' ');
-            rp.cells = cb.join('');
-            buf[buf.length] =  rt.apply(rp);
+
+            rowParams.alt   = alt.join(' ');
+            rowParams.cells = colBuffer.join('');
+
+            rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
         }
-        return buf.join('');
+
+        return rowBuffer.join('');
     },
 
     
-    processRows : function(startRow, skipStripe){
-        if(!this.ds || this.ds.getCount() < 1){
+    processRows : function(startRow, skipStripe) {
+        if (!this.ds || this.ds.getCount() < 1) {
             return;
         }
-        var rows = this.getRows(),
-            len = rows.length,
-            i, r;
-            
+
+        var rows   = this.getRows(),
+            length = rows.length,
+            row, i;
+
         skipStripe = skipStripe || !this.grid.stripeRows;
-        startRow = startRow || 0;
-        for(i = 0; i<len; i++) {
-            r = rows[i];
-            if(r) {
-                r.rowIndex = i;
-                if(!skipStripe){
-                    r.className = r.className.replace(this.rowClsRe, ' ');
+        startRow   = startRow   || 0;
+
+        for (i = 0; i < length; i++) {
+            row = rows[i];
+            if (row) {
+                row.rowIndex = i;
+                if (!skipStripe) {
+                    row.className = row.className.replace(this.rowClsRe, ' ');
                     if ((i + 1) % 2 === 0){
-                        r.className += ' x-grid3-row-alt';
+                        row.className += ' x-grid3-row-alt';
                     }
-                }   
-            }          
+                }
+            }
         }
+
         
-        if(startRow === 0){
+        if (startRow === 0) {
             Ext.fly(rows[0]).addClass(this.firstRowCls);
         }
-        Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
-    },
 
-    afterRender : function(){
-        if(!this.ds || !this.cm){
+        Ext.fly(rows[length - 1]).addClass(this.lastRowCls);
+    },
+    
+    
+    afterRender : function() {
+        if (!this.ds || !this.cm) {
             return;
         }
-        this.mainBody.dom.innerHTML = this.renderRows() || '&#160;';
+        
+        this.mainBody.dom.innerHTML = this.renderBody() || '&#160;';
         this.processRows(0, true);
 
-        if(this.deferEmptyText !== true){
+        if (this.deferEmptyText !== true) {
             this.applyEmptyText();
         }
+        
         this.grid.fireEvent('viewready', this.grid);
     },
-
     
-    renderUI : function(){
-
-        var header = this.renderHeaders();
-        var body = this.templates.body.apply({rows:'&#160;'});
-
-
-        var html = this.templates.master.apply({
-            body: body,
-            header: header,
-            ostyle: 'width:'+this.getOffsetWidth()+';',
-            bstyle: 'width:'+this.getTotalWidth()+';'
-        });
-
-        var g = this.grid;
-
-        g.getGridEl().dom.innerHTML = html;
-
+    
+    afterRenderUI: function() {
+        var grid = this.grid;
+        
         this.initElements();
 
         
         Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
+
         this.mainHd.on({
-            scope: this,
+            scope    : this,
             mouseover: this.handleHdOver,
-            mouseout: this.handleHdOut,
+            mouseout : this.handleHdOut,
             mousemove: this.handleHdMove
         });
 
         this.scroller.on('scroll', this.syncScroll,  this);
-        if(g.enableColumnResize !== false){
-            this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
+        
+        if (grid.enableColumnResize !== false) {
+            this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
         }
 
-        if(g.enableColumnMove){
-            this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
-            this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
+        if (grid.enableColumnMove) {
+            this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
+            this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
         }
 
-        if(g.enableHdMenu !== false){
-            this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});
+        if (grid.enableHdMenu !== false) {
+            this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'});
             this.hmenu.add(
-                {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
+                {itemId:'asc',  text: this.sortAscText,  cls: 'xg-hmenu-sort-asc'},
                 {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
             );
-            if(g.enableColumnHide !== false){
-                this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});
+
+            if (grid.enableColumnHide !== false) {
+                this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'});
                 this.colMenu.on({
-                    scope: this,
+                    scope     : this,
                     beforeshow: this.beforeColMenuShow,
-                    itemclick: this.handleHdMenuClick
+                    itemclick : this.handleHdMenuClick
                 });
                 this.hmenu.add('-', {
                     itemId:'columns',
@@ -41462,101 +46680,156 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
                     iconCls: 'x-cols-icon'
                 });
             }
+
             this.hmenu.on('itemclick', this.handleHdMenuClick, this);
         }
 
-        if(g.trackMouseOver){
+        if (grid.trackMouseOver) {
             this.mainBody.on({
-                scope: this,
+                scope    : this,
                 mouseover: this.onRowOver,
-                mouseout: this.onRowOut
+                mouseout : this.onRowOut
             });
         }
 
-        if(g.enableDragDrop || g.enableDrag){
-            this.dragZone = new Ext.grid.GridDragZone(g, {
-                ddGroup : g.ddGroup || 'GridDD'
+        if (grid.enableDragDrop || grid.enableDrag) {
+            this.dragZone = new Ext.grid.GridDragZone(grid, {
+                ddGroup : grid.ddGroup || 'GridDD'
             });
         }
 
         this.updateHeaderSortState();
-
     },
+
     
+    renderUI : function() {
+        var templates = this.templates;
+
+        return templates.master.apply({
+            body  : templates.body.apply({rows:'&#160;'}),
+            header: this.renderHeaders(),
+            ostyle: 'width:' + this.getOffsetWidth() + ';',
+            bstyle: 'width:' + this.getTotalWidth()  + ';'
+        });
+    },
+
     
-    processEvent: Ext.emptyFn,
+    processEvent : function(name, e) {
+        var target = e.getTarget(),
+            grid   = this.grid,
+            header = this.findHeaderIndex(target),
+            row, cell, col, body;
+
+        grid.fireEvent(name, e);
+
+        if (header !== false) {
+            grid.fireEvent('header' + name, grid, header, e);
+        } else {
+            row = this.findRowIndex(target);
+
+
+
+
+            if (row !== false) {
+                cell = this.findCellIndex(target);
+                if (cell !== false) {
+                    col = grid.colModel.getColumnAt(cell);
+                    if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) {
+                        if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) {
+                            grid.fireEvent('row' + name, grid, row, e);
+                        }
+                    }
+                } else {
+                    if (grid.fireEvent('row' + name, grid, row, e) !== false) {
+                        (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e);
+                    }
+                }
+            } else {
+                grid.fireEvent('container' + name, grid, e);
+            }
+        }
+    },
 
     
-    layout : function(){
-        if(!this.mainBody){
+    layout : function(initial) {
+        if (!this.mainBody) {
             return; 
         }
-        var g = this.grid;
-        var c = g.getGridEl();
-        var csize = c.getSize(true);
-        var vw = csize.width;
 
-        if(!g.hideHeaders && (vw < 20 || csize.height < 20)){ 
+        var grid       = this.grid,
+            gridEl     = grid.getGridEl(),
+            gridSize   = gridEl.getSize(true),
+            gridWidth  = gridSize.width,
+            gridHeight = gridSize.height,
+            scroller   = this.scroller,
+            scrollStyle, headerHeight, scrollHeight;
+        
+        if (gridWidth < 20 || gridHeight < 20) {
             return;
         }
         
-        if(g.autoHeight){
-            this.scroller.dom.style.overflow = 'visible';
-            if(Ext.isWebKit){
-                this.scroller.dom.style.position = 'static';
+        if (grid.autoHeight) {
+            scrollStyle = scroller.dom.style;
+            scrollStyle.overflow = 'visible';
+            
+            if (Ext.isWebKit) {
+                scrollStyle.position = 'static';
             }
-        }else{
-            this.el.setSize(csize.width, csize.height);
-
-            var hdHeight = this.mainHd.getHeight();
-            var vh = csize.height - (hdHeight);
-
-            this.scroller.setSize(vw, vh);
-            if(this.innerHd){
-                this.innerHd.style.width = (vw)+'px';
+        } else {
+            this.el.setSize(gridWidth, gridHeight);
+            
+            headerHeight = this.mainHd.getHeight();
+            scrollHeight = gridHeight - headerHeight;
+            
+            scroller.setSize(gridWidth, scrollHeight);
+            
+            if (this.innerHd) {
+                this.innerHd.style.width = (gridWidth) + "px";
             }
         }
-        if(this.forceFit){
-            if(this.lastViewWidth != vw){
+        
+        if (this.forceFit || (initial === true && this.autoFill)) {
+            if (this.lastViewWidth != gridWidth) {
                 this.fitColumns(false, false);
-                this.lastViewWidth = vw;
+                this.lastViewWidth = gridWidth;
             }
-        }else {
+        } else {
             this.autoExpand();
             this.syncHeaderScroll();
         }
-        this.onLayout(vw, vh);
+        
+        this.onLayout(gridWidth, scrollHeight);
     },
 
     
     
-    onLayout : function(vw, vh){
+    onLayout : function(vw, vh) {
         
     },
 
-    onColumnWidthUpdated : function(col, w, tw){
+    onColumnWidthUpdated : function(col, w, tw) {
         
     },
 
-    onAllColumnWidthsUpdated : function(ws, tw){
+    onAllColumnWidthsUpdated : function(ws, tw) {
         
     },
 
-    onColumnHiddenUpdated : function(col, hidden, tw){
+    onColumnHiddenUpdated : function(col, hidden, tw) {
         
     },
 
-    updateColumnText : function(col, text){
+    updateColumnText : function(col, text) {
         
     },
 
-    afterMove : function(colIndex){
+    afterMove : function(colIndex) {
         
     },
 
     
     
-    init : function(grid){
+    init : function(grid) {
         this.grid = grid;
 
         this.initTemplates();
@@ -41566,203 +46839,260 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
 
     
     getColumnId : function(index){
-      return this.cm.getColumnId(index);
+        return this.cm.getColumnId(index);
     },
-    
+
     
     getOffsetWidth : function() {
         return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
     },
+
     
-    getScrollOffset: function(){
+    getScrollOffset: function() {
         return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
     },
 
     
-    renderHeaders : function(){
-        var cm = this.cm, 
-            ts = this.templates,
-            ct = ts.hcell,
-            cb = [], 
-            p = {},
-            len = cm.getColumnCount(),
-            last = len - 1;
+    renderHeaders : function() {
+        var colModel   = this.cm,
+            templates  = this.templates,
+            headerTpl  = templates.hcell,
+            properties = {},
+            colCount   = colModel.getColumnCount(),
+            last       = colCount - 1,
+            cells      = [],
+            i, cssCls;
+        
+        for (i = 0; i < colCount; i++) {
+            if (i == 0) {
+                cssCls = 'x-grid3-cell-first ';
+            } else {
+                cssCls = i == last ? 'x-grid3-cell-last ' : '';
+            }
             
-        for(var i = 0; i < len; i++){
-            p.id = cm.getColumnId(i);
-            p.value = cm.getColumnHeader(i) || '';
-            p.style = this.getColumnStyle(i, true);
-            p.tooltip = this.getColumnTooltip(i);
-            p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
-            if(cm.config[i].align == 'right'){
-                p.istyle = 'padding-right:16px';
+            properties = {
+                id     : colModel.getColumnId(i),
+                value  : colModel.getColumnHeader(i) || '',
+                style  : this.getColumnStyle(i, true),
+                css    : cssCls,
+                tooltip: this.getColumnTooltip(i)
+            };
+            
+            if (colModel.config[i].align == 'right') {
+                properties.istyle = 'padding-right: 16px;';
             } else {
-                delete p.istyle;
+                delete properties.istyle;
             }
-            cb[cb.length] = ct.apply(p);
+            
+            cells[i] = headerTpl.apply(properties);
         }
-        return ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'});
+        
+        return templates.header.apply({
+            cells : cells.join(""),
+            tstyle: String.format("width: {0};", this.getTotalWidth())
+        });
     },
 
     
-    getColumnTooltip : function(i){
-        var tt = this.cm.getColumnTooltip(i);
-        if(tt){
-            if(Ext.QuickTips.isEnabled()){
-                return 'ext:qtip="'+tt+'"';
-            }else{
-                return 'title="'+tt+'"';
+    getColumnTooltip : function(i) {
+        var tooltip = this.cm.getColumnTooltip(i);
+        if (tooltip) {
+            if (Ext.QuickTips.isEnabled()) {
+                return 'ext:qtip="' + tooltip + '"';
+            } else {
+                return 'title="' + tooltip + '"';
             }
         }
+        
         return '';
     },
 
     
-    beforeUpdate : function(){
+    beforeUpdate : function() {
         this.grid.stopEditing(true);
     },
 
     
-    updateHeaders : function(){
+    updateHeaders : function() {
         this.innerHd.firstChild.innerHTML = this.renderHeaders();
-        this.innerHd.firstChild.style.width = this.getOffsetWidth();
-        this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
+        
+        this.updateHeaderWidth(false);
+    },
+    
+    
+    updateHeaderWidth: function(updateMain) {
+        var innerHdChild = this.innerHd.firstChild,
+            totalWidth   = this.getTotalWidth();
+        
+        innerHdChild.style.width = this.getOffsetWidth();
+        innerHdChild.firstChild.style.width = totalWidth;
+        
+        if (updateMain !== false) {
+            this.mainBody.dom.style.width = totalWidth;
+        }
     },
 
     
-    focusRow : function(row){
+    focusRow : function(row) {
         this.focusCell(row, 0, false);
     },
 
     
-    focusCell : function(row, col, hscroll){
+    focusCell : function(row, col, hscroll) {
         this.syncFocusEl(this.ensureVisible(row, col, hscroll));
-        if(Ext.isGecko){
-            this.focusEl.focus();
-        }else{
-            this.focusEl.focus.defer(1, this.focusEl);
+        
+        var focusEl = this.focusEl;
+        
+        if (Ext.isGecko) {
+            focusEl.focus();
+        } else {
+            focusEl.focus.defer(1, focusEl);
         }
     },
 
-    resolveCell : function(row, col, hscroll){
-        if(!Ext.isNumber(row)){
+    
+    resolveCell : function(row, col, hscroll) {
+        if (!Ext.isNumber(row)) {
             row = row.rowIndex;
         }
-        if(!this.ds){
+        
+        if (!this.ds) {
             return null;
         }
-        if(row < 0 || row >= this.ds.getCount()){
+        
+        if (row < 0 || row >= this.ds.getCount()) {
             return null;
         }
         col = (col !== undefined ? col : 0);
 
-        var rowEl = this.getRow(row),
-            cm = this.cm,
-            colCount = cm.getColumnCount(),
+        var rowEl    = this.getRow(row),
+            colModel = this.cm,
+            colCount = colModel.getColumnCount(),
             cellEl;
-        if(!(hscroll === false && col === 0)){
-            while(col < colCount && cm.isHidden(col)){
+            
+        if (!(hscroll === false && col === 0)) {
+            while (col < colCount && colModel.isHidden(col)) {
                 col++;
             }
+            
             cellEl = this.getCell(row, col);
         }
 
         return {row: rowEl, cell: cellEl};
     },
 
-    getResolvedXY : function(resolved){
-        if(!resolved){
+    
+    getResolvedXY : function(resolved) {
+        if (!resolved) {
             return null;
         }
-        var s = this.scroller.dom, c = resolved.cell, r = resolved.row;
-        return c ? Ext.fly(c).getXY() : [this.el.getX(), Ext.fly(r).getY()];
+        
+        var cell = resolved.cell,
+            row  = resolved.row;
+        
+        if (cell) {
+            return Ext.fly(cell).getXY();
+        } else {
+            return [this.el.getX(), Ext.fly(row).getY()];
+        }
     },
 
-    syncFocusEl : function(row, col, hscroll){
+    
+    syncFocusEl : function(row, col, hscroll) {
         var xy = row;
-        if(!Ext.isArray(xy)){
+        
+        if (!Ext.isArray(xy)) {
             row = Math.min(row, Math.max(0, this.getRows().length-1));
+            
+            if (isNaN(row)) {
+                return;
+            }
+            
             xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
         }
-        this.focusEl.setXY(xy||this.scroller.getXY());
+        
+        this.focusEl.setXY(xy || this.scroller.getXY());
     },
 
-    ensureVisible : function(row, col, hscroll){
+    
+    ensureVisible : function(row, col, hscroll) {
         var resolved = this.resolveCell(row, col, hscroll);
-        if(!resolved || !resolved.row){
-            return;
+        
+        if (!resolved || !resolved.row) {
+            return null;
         }
 
-        var rowEl = resolved.row, 
+        var rowEl  = resolved.row,
             cellEl = resolved.cell,
             c = this.scroller.dom,
+            p = rowEl,
             ctop = 0,
-            p = rowEl, 
             stop = this.el.dom;
-            
-        while(p && p != stop){
+
+        while (p && p != stop) {
             ctop += p.offsetTop;
             p = p.offsetParent;
         }
-        
+
         ctop -= this.mainHd.dom.offsetHeight;
         stop = parseInt(c.scrollTop, 10);
-        
+
         var cbot = ctop + rowEl.offsetHeight,
             ch = c.clientHeight,
             sbot = stop + ch;
-        
 
-        if(ctop < stop){
+
+        if (ctop < stop) {
           c.scrollTop = ctop;
-        }else if(cbot > sbot){
+        } else if(cbot > sbot) {
             c.scrollTop = cbot-ch;
         }
 
-        if(hscroll !== false){
-            var cleft = parseInt(cellEl.offsetLeft, 10);
-            var cright = cleft + cellEl.offsetWidth;
-
-            var sleft = parseInt(c.scrollLeft, 10);
-            var sright = sleft + c.clientWidth;
-            if(cleft < sleft){
+        if (hscroll !== false) {
+            var cleft  = parseInt(cellEl.offsetLeft, 10),
+                cright = cleft + cellEl.offsetWidth,
+                sleft  = parseInt(c.scrollLeft, 10),
+                sright = sleft + c.clientWidth;
+                
+            if (cleft < sleft) {
                 c.scrollLeft = cleft;
-            }else if(cright > sright){
+            } else if(cright > sright) {
                 c.scrollLeft = cright-c.clientWidth;
             }
         }
+        
         return this.getResolvedXY(resolved);
     },
 
     
-    insertRows : function(dm, firstRow, lastRow, isUpdate){
+    insertRows : function(dm, firstRow, lastRow, isUpdate) {
         var last = dm.getCount() - 1;
-        if(!isUpdate && firstRow === 0 && lastRow >= last){
-           this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
-            this.refresh();
-           this.fireEvent('rowsinserted', this, firstRow, lastRow);
-        }else{
-            if(!isUpdate){
+        if( !isUpdate && firstRow === 0 && lastRow >= last) {
+            this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
+                this.refresh();
+            this.fireEvent('rowsinserted', this, firstRow, lastRow);
+        } else {
+            if (!isUpdate) {
                 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
             }
             var html = this.renderRows(firstRow, lastRow),
                 before = this.getRow(firstRow);
-            if(before){
+            if (before) {
                 if(firstRow === 0){
                     Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
                 }
                 Ext.DomHelper.insertHtml('beforeBegin', before, html);
-            }else{
+            } else {
                 var r = this.getRow(last - 1);
                 if(r){
                     Ext.fly(r).removeClass(this.lastRowCls);
                 }
                 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
             }
-            if(!isUpdate){
-                this.fireEvent('rowsinserted', this, firstRow, lastRow);
+            if (!isUpdate) {
                 this.processRows(firstRow);
-            }else if(firstRow === 0 || firstRow >= last){
+                this.fireEvent('rowsinserted', this, firstRow, lastRow);
+            } else if (firstRow === 0 || firstRow >= last) {
                 
                 Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
             }
@@ -41771,10 +47101,10 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    deleteRows : function(dm, firstRow, lastRow){
-        if(dm.getRowCount()<1){
+    deleteRows : function(dm, firstRow, lastRow) {
+        if (dm.getRowCount() < 1) {
             this.refresh();
-        }else{
+        } else {
             this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
 
             this.removeRows(firstRow, lastRow);
@@ -41785,145 +47115,185 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    getColumnStyle : function(col, isHeader){
-        var style = !isHeader ? (this.cm.config[col].css || '') : '';
-        style += 'width:'+this.getColumnWidth(col)+';';
-        if(this.cm.isHidden(col)){
-            style += 'display:none;';
+    getColumnStyle : function(colIndex, isHeader) {
+        var colModel  = this.cm,
+            colConfig = colModel.config,
+            style     = isHeader ? '' : colConfig[colIndex].css || '',
+            align     = colConfig[colIndex].align;
+        
+        style += String.format("width: {0};", this.getColumnWidth(colIndex));
+        
+        if (colModel.isHidden(colIndex)) {
+            style += 'display: none; ';
         }
-        var align = this.cm.config[col].align;
-        if(align){
-            style += 'text-align:'+align+';';
+        
+        if (align) {
+            style += String.format("text-align: {0};", align);
         }
+        
         return style;
     },
 
     
-    getColumnWidth : function(col){
-        var w = this.cm.getColumnWidth(col);
-        if(Ext.isNumber(w)){
-            return (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2) ? w : (w - this.borderWidth > 0 ? w - this.borderWidth : 0)) + 'px';
+    getColumnWidth : function(column) {
+        var columnWidth = this.cm.getColumnWidth(column),
+            borderWidth = this.borderWidth;
+        
+        if (Ext.isNumber(columnWidth)) {
+            if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) {
+                return columnWidth + "px";
+            } else {
+                return Math.max(columnWidth - borderWidth, 0) + "px";
+            }
+        } else {
+            return columnWidth;
         }
-        return w;
     },
 
     
-    getTotalWidth : function(){
-        return this.cm.getTotalWidth()+'px';
+    getTotalWidth : function() {
+        return this.cm.getTotalWidth() + 'px';
     },
 
     
-    fitColumns : function(preventRefresh, onlyExpand, omitColumn){
-        var cm = this.cm, i;
-        var tw = cm.getTotalWidth(false);
-        var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
-
-        if(aw < 20){ 
-            return;
-        }
-        var extra = aw - tw;
-
-        if(extra === 0){
+    fitColumns : function(preventRefresh, onlyExpand, omitColumn) {
+        var grid          = this.grid,
+            colModel      = this.cm,
+            totalColWidth = colModel.getTotalWidth(false),
+            gridWidth     = this.getGridInnerWidth(),
+            extraWidth    = gridWidth - totalColWidth,
+            columns       = [],
+            extraCol      = 0,
+            width         = 0,
+            colWidth, fraction, i;
+        
+        
+        if (gridWidth < 20 || extraWidth === 0) {
             return false;
         }
-
-        var vc = cm.getColumnCount(true);
-        var ac = vc-(Ext.isNumber(omitColumn) ? 1 : 0);
-        if(ac === 0){
-            ac = 1;
+        
+        var visibleColCount = colModel.getColumnCount(true),
+            totalColCount   = colModel.getColumnCount(false),
+            adjCount        = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0);
+        
+        if (adjCount === 0) {
+            adjCount = 1;
             omitColumn = undefined;
         }
-        var colCount = cm.getColumnCount();
-        var cols = [];
-        var extraCol = 0;
-        var width = 0;
-        var w;
-        for (i = 0; i < colCount; i++){
-            if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
-                w = cm.getColumnWidth(i);
-                cols.push(i);
-                extraCol = i;
-                cols.push(w);
-                width += w;
+        
+        
+        for (i = 0; i < totalColCount; i++) {
+            if (!colModel.isFixed(i) && i !== omitColumn) {
+                colWidth = colModel.getColumnWidth(i);
+                columns.push(i, colWidth);
+                
+                if (!colModel.isHidden(i)) {
+                    extraCol = i;
+                    width += colWidth;
+                }
             }
         }
-        var frac = (aw - cm.getTotalWidth())/width;
-        while (cols.length){
-            w = cols.pop();
-            i = cols.pop();
-            cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
+        
+        fraction = (gridWidth - colModel.getTotalWidth()) / width;
+        
+        while (columns.length) {
+            colWidth = columns.pop();
+            i        = columns.pop();
+            
+            colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true);
         }
-
-        if((tw = cm.getTotalWidth(false)) > aw){
-            var adjustCol = ac != vc ? omitColumn : extraCol;
-             cm.setColumnWidth(adjustCol, Math.max(1,
-                     cm.getColumnWidth(adjustCol)- (tw-aw)), true);
+        
+        
+        totalColWidth = colModel.getTotalWidth(false);
+        
+        if (totalColWidth > gridWidth) {
+            var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn,
+                newWidth  = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth));
+            
+            colModel.setColumnWidth(adjustCol, newWidth, true);
         }
-
-        if(preventRefresh !== true){
+        
+        if (preventRefresh !== true) {
             this.updateAllColumnWidths();
         }
-
-
+        
         return true;
     },
 
     
-    autoExpand : function(preventUpdate){
-        var g = this.grid, cm = this.cm;
-        if(!this.userResized && g.autoExpandColumn){
-            var tw = cm.getTotalWidth(false);
-            var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
-            if(tw != aw){
-                var ci = cm.getIndexById(g.autoExpandColumn);
-                var currentWidth = cm.getColumnWidth(ci);
-                var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
-                if(cw != currentWidth){
-                    cm.setColumnWidth(ci, cw, true);
-                    if(preventUpdate !== true){
-                        this.updateColumnWidth(ci, cw);
+    autoExpand : function(preventUpdate) {
+        var grid             = this.grid,
+            colModel         = this.cm,
+            gridWidth        = this.getGridInnerWidth(),
+            totalColumnWidth = colModel.getTotalWidth(false),
+            autoExpandColumn = grid.autoExpandColumn;
+        
+        if (!this.userResized && autoExpandColumn) {
+            if (gridWidth != totalColumnWidth) {
+                
+                var colIndex     = colModel.getIndexById(autoExpandColumn),
+                    currentWidth = colModel.getColumnWidth(colIndex),
+                    desiredWidth = gridWidth - totalColumnWidth + currentWidth,
+                    newWidth     = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax);
+                
+                if (currentWidth != newWidth) {
+                    colModel.setColumnWidth(colIndex, newWidth, true);
+                    
+                    if (preventUpdate !== true) {
+                        this.updateColumnWidth(colIndex, newWidth);
                     }
                 }
             }
         }
     },
+    
+    
+    getGridInnerWidth: function() {
+        return this.grid.getGridEl().getWidth(true) - this.getScrollOffset();
+    },
 
     
-    getColumnData : function(){
+    getColumnData : function() {
+        var columns  = [],
+            colModel = this.cm,
+            colCount = colModel.getColumnCount(),
+            fields   = this.ds.fields,
+            i, name;
         
-        var cs = [], cm = this.cm, colCount = cm.getColumnCount();
-        for(var i = 0; i < colCount; i++){
-            var name = cm.getDataIndex(i);
-            cs[i] = {
-                name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),
-                renderer : cm.getRenderer(i),
-                scope: cm.getRendererScope(i),
-                id : cm.getColumnId(i),
-                style : this.getColumnStyle(i)
+        for (i = 0; i < colCount; i++) {
+            name = colModel.getDataIndex(i);
+            
+            columns[i] = {
+                name    : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
+                renderer: colModel.getRenderer(i),
+                scope   : colModel.getRendererScope(i),
+                id      : colModel.getColumnId(i),
+                style   : this.getColumnStyle(i)
             };
         }
-        return cs;
+        
+        return columns;
     },
 
     
-    renderRows : function(startRow, endRow){
+    renderRows : function(startRow, endRow) {
+        var grid     = this.grid,
+            store    = grid.store,
+            stripe   = grid.stripeRows,
+            colModel = grid.colModel,
+            colCount = colModel.getColumnCount(),
+            rowCount = store.getCount(),
+            records;
         
-        var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
-        var colCount = cm.getColumnCount();
-
-        if(ds.getCount() < 1){
+        if (rowCount < 1) {
             return '';
         }
-
-        var cs = this.getColumnData();
-
+        
         startRow = startRow || 0;
-        endRow = !Ext.isDefined(endRow) ? ds.getCount()-1 : endRow;
-
+        endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;
+        records  = store.getRange(startRow, endRow);
         
-        var rs = ds.getRange(startRow, endRow);
-
-        return this.doRender(cs, rs, ds, startRow, colCount, stripe);
+        return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe);
     },
 
     
@@ -41933,34 +47303,89 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    refreshRow : function(record){
-        var ds = this.ds, index;
-        if(Ext.isNumber(record)){
-            index = record;
-            record = ds.getAt(index);
-            if(!record){
-                return;
+    refreshRow: function(record) {
+        var store     = this.ds,
+            colCount  = this.cm.getColumnCount(),
+            columns   = this.getColumnData(),
+            last      = colCount - 1,
+            cls       = ['x-grid3-row'],
+            rowParams = {
+                tstyle: String.format("width: {0};", this.getTotalWidth())
+            },
+            colBuffer = [],
+            cellTpl   = this.templates.cell,
+            rowIndex, row, column, meta, css, i;
+        
+        if (Ext.isNumber(record)) {
+            rowIndex = record;
+            record   = store.getAt(rowIndex);
+        } else {
+            rowIndex = store.indexOf(record);
+        }
+        
+        
+        if (!record || rowIndex < 0) {
+            return;
+        }
+        
+        
+        for (i = 0; i < colCount; i++) {
+            column = columns[i];
+            
+            if (i == 0) {
+                css = 'x-grid3-cell-first';
+            } else {
+                css = (i == last) ? 'x-grid3-cell-last ' : '';
             }
-        }else{
-            index = ds.indexOf(record);
-            if(index < 0){
-                return;
+            
+            meta = {
+                id      : column.id,
+                style   : column.style,
+                css     : css,
+                attr    : "",
+                cellAttr: ""
+            };
+            
+            meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
+            
+            if (Ext.isEmpty(meta.value)) {
+                meta.value = '&#160;';
+            }
+            
+            if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
+                meta.css += ' x-grid3-dirty-cell';
             }
+            
+            colBuffer[i] = cellTpl.apply(meta);
+        }
+        
+        row = this.getRow(rowIndex);
+        row.className = '';
+        
+        if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
+            cls.push('x-grid3-row-alt');
         }
-        this.insertRows(ds, index, index, true);
-        this.getRow(index).rowIndex = index;
-        this.onRemove(ds, record, index+1, true);
-        this.fireEvent('rowupdated', this, index, record);
+        
+        if (this.getRowClass) {
+            rowParams.cols = colCount;
+            cls.push(this.getRowClass(record, rowIndex, rowParams, store));
+        }
+        
+        this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
+        rowParams.cells = colBuffer.join("");
+        row.innerHTML = this.templates.rowInner.apply(rowParams);
+        
+        this.fireEvent('rowupdated', this, rowIndex, record);
     },
 
     
-    refresh : function(headersToo){
+    refresh : function(headersToo) {
         this.fireEvent('beforerefresh', this);
         this.grid.stopEditing(true);
 
         var result = this.renderBody();
         this.mainBody.update(result).setWidth(this.getTotalWidth());
-        if(headersToo === true){
+        if (headersToo === true) {
             this.updateHeaders();
             this.updateHeaderSortState();
         }
@@ -41971,32 +47396,35 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    applyEmptyText : function(){
-        if(this.emptyText && !this.hasRows()){
+    applyEmptyText : function() {
+        if (this.emptyText && !this.hasRows()) {
             this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
         }
     },
 
     
-    updateHeaderSortState : function(){
+    updateHeaderSortState : function() {
         var state = this.ds.getSortState();
-        if(!state){
+        if (!state) {
             return;
         }
-        if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
+
+        if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
             this.grid.fireEvent('sortchange', this.grid, state);
         }
+
         this.sortState = state;
+
         var sortColumn = this.cm.findColumnIndex(state.field);
-        if(sortColumn != -1){
+        if (sortColumn != -1) {
             var sortDir = state.direction;
             this.updateSortIcon(sortColumn, sortDir);
         }
     },
 
     
-    clearHeaderSortState : function(){
-        if(!this.sortState){
+    clearHeaderSortState : function() {
+        if (!this.sortState) {
             return;
         }
         this.grid.fireEvent('sortchange', this.grid, null);
@@ -42005,193 +47433,220 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    destroy : function(){
-        if(this.colMenu){
-            Ext.menu.MenuMgr.unregister(this.colMenu);
-            this.colMenu.destroy();
-            delete this.colMenu;
-        }
-        if(this.hmenu){
-            Ext.menu.MenuMgr.unregister(this.hmenu);
-            this.hmenu.destroy();
-            delete this.hmenu;
+    destroy : function() {
+        var me              = this,
+            grid            = me.grid,
+            gridEl          = grid.getGridEl(),
+            dragZone        = me.dragZone,
+            splitZone       = me.splitZone,
+            columnDrag      = me.columnDrag,
+            columnDrop      = me.columnDrop,
+            scrollToTopTask = me.scrollToTopTask,
+            columnDragData,
+            columnDragProxy;
+        
+        if (scrollToTopTask && scrollToTopTask.cancel) {
+            scrollToTopTask.cancel();
         }
+        
+        Ext.destroyMembers(me, 'colMenu', 'hmenu');
 
-        this.initData(null, null);
-        this.purgeListeners();
-        Ext.fly(this.innerHd).un("click", this.handleHdDown, this);
+        me.initData(null, null);
+        me.purgeListeners();
+        
+        Ext.fly(me.innerHd).un("click", me.handleHdDown, me);
 
-        if(this.grid.enableColumnMove){
+        if (grid.enableColumnMove) {
+            columnDragData = columnDrag.dragData;
+            columnDragProxy = columnDrag.proxy;
             Ext.destroy(
-                this.columnDrag.el,
-                this.columnDrag.proxy.ghost,
-                this.columnDrag.proxy.el,
-                this.columnDrop.el,
-                this.columnDrop.proxyTop,
-                this.columnDrop.proxyBottom,
-                this.columnDrag.dragData.ddel,
-                this.columnDrag.dragData.header
+                columnDrag.el,
+                columnDragProxy.ghost,
+                columnDragProxy.el,
+                columnDrop.el,
+                columnDrop.proxyTop,
+                columnDrop.proxyBottom,
+                columnDragData.ddel,
+                columnDragData.header
             );
-            if (this.columnDrag.proxy.anim) {
-                Ext.destroy(this.columnDrag.proxy.anim);
+            
+            if (columnDragProxy.anim) {
+                Ext.destroy(columnDragProxy.anim);
             }
-            delete this.columnDrag.proxy.ghost;
-            delete this.columnDrag.dragData.ddel;
-            delete this.columnDrag.dragData.header;
-            this.columnDrag.destroy();
-            delete Ext.dd.DDM.locationCache[this.columnDrag.id];
-            delete this.columnDrag._domRef;
+            
+            delete columnDragProxy.ghost;
+            delete columnDragData.ddel;
+            delete columnDragData.header;
+            columnDrag.destroy();
+            
+            delete Ext.dd.DDM.locationCache[columnDrag.id];
+            delete columnDrag._domRef;
 
-            delete this.columnDrop.proxyTop;
-            delete this.columnDrop.proxyBottom;
-            this.columnDrop.destroy();
-            delete Ext.dd.DDM.locationCache["gridHeader" + this.grid.getGridEl().id];
-            delete this.columnDrop._domRef;
-            delete Ext.dd.DDM.ids[this.columnDrop.ddGroup];
+            delete columnDrop.proxyTop;
+            delete columnDrop.proxyBottom;
+            columnDrop.destroy();
+            delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id];
+            delete columnDrop._domRef;
+            delete Ext.dd.DDM.ids[columnDrop.ddGroup];
         }
 
-        if (this.splitZone)
-            this.splitZone.destroy();
-            delete this.splitZone._domRef;
-            delete Ext.dd.DDM.ids["gridSplitters" + this.grid.getGridEl().id];
+        if (splitZone) 
+            splitZone.destroy();
+            delete splitZone._domRef;
+            delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id];
         }
 
-        Ext.fly(this.innerHd).removeAllListeners();
-        Ext.removeNode(this.innerHd);
-        delete this.innerHd;
+        Ext.fly(me.innerHd).removeAllListeners();
+        Ext.removeNode(me.innerHd);
+        delete me.innerHd;
 
         Ext.destroy(
-            this.el,
-            this.mainWrap,
-            this.mainHd,
-            this.scroller,
-            this.mainBody,
-            this.focusEl,
-            this.resizeMarker,
-            this.resizeProxy,
-            this.activeHdBtn,
-            this.dragZone,
-            this.splitZone,
-            this._flyweight
+            me.el,
+            me.mainWrap,
+            me.mainHd,
+            me.scroller,
+            me.mainBody,
+            me.focusEl,
+            me.resizeMarker,
+            me.resizeProxy,
+            me.activeHdBtn,
+            me._flyweight,
+            dragZone,
+            splitZone
         );
 
-        delete this.grid.container;
+        delete grid.container;
 
-        if(this.dragZone){
-            this.dragZone.destroy();
+        if (dragZone) {
+            dragZone.destroy();
         }
 
         Ext.dd.DDM.currentTarget = null;
-        delete Ext.dd.DDM.locationCache[this.grid.getGridEl().id];
+        delete Ext.dd.DDM.locationCache[gridEl.id];
 
-        Ext.EventManager.removeResizeListener(this.onWindowResize, this);
+        Ext.EventManager.removeResizeListener(me.onWindowResize, me);
     },
 
     
-    onDenyColumnHide : function(){
+    onDenyColumnHide : function() {
 
     },
 
     
-    render : function(){
-        if(this.autoFill){
+    render : function() {
+        if (this.autoFill) {
             var ct = this.grid.ownerCt;
-            if (ct && ct.getLayout()){
-                ct.on('afterlayout', function(){ 
+            
+            if (ct && ct.getLayout()) {
+                ct.on('afterlayout', function() {
                     this.fitColumns(true, true);
-                    this.updateHeaders(); 
-                }, this, {single: true}); 
-            }else{ 
-                this.fitColumns(true, true); 
+                    this.updateHeaders();
+                    this.updateHeaderSortState();
+                }, this, {single: true});
             }
-        }else if(this.forceFit){
+        } else if (this.forceFit) {
             this.fitColumns(true, false);
-        }else if(this.grid.autoExpandColumn){
+        } else if (this.grid.autoExpandColumn) {
             this.autoExpand(true);
         }
-
-        this.renderUI();
+        
+        this.grid.getGridEl().dom.innerHTML = this.renderUI();
+        
+        this.afterRenderUI();
     },
 
     
     
-    initData : function(ds, cm){
-        if(this.ds){
-            this.ds.un('load', this.onLoad, this);
-            this.ds.un('datachanged', this.onDataChange, this);
-            this.ds.un('add', this.onAdd, this);
-            this.ds.un('remove', this.onRemove, this);
-            this.ds.un('update', this.onUpdate, this);
-            this.ds.un('clear', this.onClear, this);
-            if(this.ds !== ds && this.ds.autoDestroy){
-                this.ds.destroy();
-            }
-        }
-        if(ds){
-            ds.on({
-                scope: this,
-                load: this.onLoad,
-                datachanged: this.onDataChange,
-                add: this.onAdd,
-                remove: this.onRemove,
-                update: this.onUpdate,
-                clear: this.onClear
+    
+    initData : function(newStore, newColModel) {
+        var me = this;
+        
+        if (me.ds) {
+            var oldStore = me.ds;
+            
+            oldStore.un('add', me.onAdd, me);
+            oldStore.un('load', me.onLoad, me);
+            oldStore.un('clear', me.onClear, me);
+            oldStore.un('remove', me.onRemove, me);
+            oldStore.un('update', me.onUpdate, me);
+            oldStore.un('datachanged', me.onDataChange, me);
+            
+            if (oldStore !== newStore && oldStore.autoDestroy) {
+                oldStore.destroy();
+            }
+        }
+        
+        if (newStore) {
+            newStore.on({
+                scope      : me,
+                load       : me.onLoad,
+                add        : me.onAdd,
+                remove     : me.onRemove,
+                update     : me.onUpdate,
+                clear      : me.onClear,
+                datachanged: me.onDataChange
             });
         }
-        this.ds = ds;
-
-        if(this.cm){
-            this.cm.un('configchange', this.onColConfigChange, this);
-            this.cm.un('widthchange', this.onColWidthChange, this);
-            this.cm.un('headerchange', this.onHeaderChange, this);
-            this.cm.un('hiddenchange', this.onHiddenChange, this);
-            this.cm.un('columnmoved', this.onColumnMove, this);
-        }
-        if(cm){
-            delete this.lastViewWidth;
-            cm.on({
-                scope: this,
-                configchange: this.onColConfigChange,
-                widthchange: this.onColWidthChange,
-                headerchange: this.onHeaderChange,
-                hiddenchange: this.onHiddenChange,
-                columnmoved: this.onColumnMove
+        
+        if (me.cm) {
+            var oldColModel = me.cm;
+            
+            oldColModel.un('configchange', me.onColConfigChange, me);
+            oldColModel.un('widthchange',  me.onColWidthChange, me);
+            oldColModel.un('headerchange', me.onHeaderChange, me);
+            oldColModel.un('hiddenchange', me.onHiddenChange, me);
+            oldColModel.un('columnmoved',  me.onColumnMove, me);
+        }
+        
+        if (newColModel) {
+            delete me.lastViewWidth;
+            
+            newColModel.on({
+                scope       : me,
+                configchange: me.onColConfigChange,
+                widthchange : me.onColWidthChange,
+                headerchange: me.onHeaderChange,
+                hiddenchange: me.onHiddenChange,
+                columnmoved : me.onColumnMove
             });
         }
-        this.cm = cm;
+        
+        me.ds = newStore;
+        me.cm = newColModel;
     },
 
     
     onDataChange : function(){
-        this.refresh();
+        this.refresh(true);
         this.updateHeaderSortState();
         this.syncFocusEl(0);
     },
 
     
-    onClear : function(){
+    onClear : function() {
         this.refresh();
         this.syncFocusEl(0);
     },
 
     
-    onUpdate : function(ds, record){
+    onUpdate : function(store, record) {
         this.refreshRow(record);
     },
 
     
-    onAdd : function(ds, records, index){
-       
-        this.insertRows(ds, index, index + (records.length-1));
+    onAdd : function(store, records, index) {
+        this.insertRows(store, index, index + (records.length-1));
     },
 
     
-    onRemove : function(ds, record, index, isUpdate){
-        if(isUpdate !== true){
+    onRemove : function(store, record, index, isUpdate) {
+        if (isUpdate !== true) {
             this.fireEvent('beforerowremoved', this, index, record);
         }
+        
         this.removeRow(index);
-        if(isUpdate !== true){
+        
+        if (isUpdate !== true) {
             this.processRows(index);
             this.applyEmptyText();
             this.fireEvent('rowremoved', this, index, record);
@@ -42199,37 +47654,44 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    onLoad : function(){
-        this.scrollToTop.defer(Ext.isGecko ? 1 : 0, this);
+    onLoad : function() {
+        if (Ext.isGecko) {
+            if (!this.scrollToTopTask) {
+                this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
+            }
+            this.scrollToTopTask.delay(1);
+        } else {
+            this.scrollToTop();
+        }
     },
 
     
-    onColWidthChange : function(cm, col, width){
+    onColWidthChange : function(cm, col, width) {
         this.updateColumnWidth(col, width);
     },
 
     
-    onHeaderChange : function(cm, col, text){
+    onHeaderChange : function(cm, col, text) {
         this.updateHeaders();
     },
 
     
-    onHiddenChange : function(cm, col, hidden){
+    onHiddenChange : function(cm, col, hidden) {
         this.updateColumnHidden(col, hidden);
     },
 
     
-    onColumnMove : function(cm, oldIndex, newIndex){
+    onColumnMove : function(cm, oldIndex, newIndex) {
         this.indexMap = null;
-        var s = this.getScrollState();
         this.refresh(true);
-        this.restoreScroll(s);
+        this.restoreScroll(this.getScrollState());
+        
         this.afterMove(newIndex);
         this.grid.fireEvent('columnmove', oldIndex, newIndex);
     },
 
     
-    onColConfigChange : function(){
+    onColConfigChange : function() {
         delete this.lastViewWidth;
         this.indexMap = null;
         this.refresh(true);
@@ -42237,17 +47699,16 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
 
     
     
-    initUI : function(grid){
+    initUI : function(grid) {
         grid.on('headerclick', this.onHeaderClick, this);
     },
 
     
-    initEvents : function(){
-    },
+    initEvents : Ext.emptyFn,
 
     
-    onHeaderClick : function(g, index){
-        if(this.headersDisabled || !this.cm.isSortable(index)){
+    onHeaderClick : function(g, index) {
+        if (this.headersDisabled || !this.cm.isSortable(index)) {
             return;
         }
         g.stopEditing(true);
@@ -42255,191 +47716,245 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
     },
 
     
-    onRowOver : function(e, t){
-        var row;
-        if((row = this.findRowIndex(t)) !== false){
-            this.addRowClass(row, 'x-grid3-row-over');
+    onRowOver : function(e, target) {
+        var row = this.findRowIndex(target);
+        
+        if (row !== false) {
+            this.addRowClass(row, this.rowOverCls);
         }
     },
 
     
-    onRowOut : function(e, t){
-        var row;
-        if((row = this.findRowIndex(t)) !== false && !e.within(this.getRow(row), true)){
-            this.removeRowClass(row, 'x-grid3-row-over');
+    onRowOut : function(e, target) {
+        var row = this.findRowIndex(target);
+        
+        if (row !== false && !e.within(this.getRow(row), true)) {
+            this.removeRowClass(row, this.rowOverCls);
         }
     },
 
     
-    handleWheel : function(e){
-        e.stopPropagation();
-    },
-
-    
-    onRowSelect : function(row){
+    onRowSelect : function(row) {
         this.addRowClass(row, this.selectedRowClass);
     },
 
     
-    onRowDeselect : function(row){
+    onRowDeselect : function(row) {
         this.removeRowClass(row, this.selectedRowClass);
     },
 
     
-    onCellSelect : function(row, col){
+    onCellSelect : function(row, col) {
         var cell = this.getCell(row, col);
-        if(cell){
+        if (cell) {
             this.fly(cell).addClass('x-grid3-cell-selected');
         }
     },
 
     
-    onCellDeselect : function(row, col){
+    onCellDeselect : function(row, col) {
         var cell = this.getCell(row, col);
-        if(cell){
+        if (cell) {
             this.fly(cell).removeClass('x-grid3-cell-selected');
         }
     },
 
     
-    onColumnSplitterMoved : function(i, w){
+    handleWheel : function(e) {
+        e.stopPropagation();
+    },
+
+    
+    onColumnSplitterMoved : function(cellIndex, width) {
         this.userResized = true;
-        var cm = this.grid.colModel;
-        cm.setColumnWidth(i, w, true);
+        this.grid.colModel.setColumnWidth(cellIndex, width, true);
 
-        if(this.forceFit){
-            this.fitColumns(true, false, i);
+        if (this.forceFit) {
+            this.fitColumns(true, false, cellIndex);
             this.updateAllColumnWidths();
-        }else{
-            this.updateColumnWidth(i, w);
+        } else {
+            this.updateColumnWidth(cellIndex, width);
             this.syncHeaderScroll();
         }
 
-        this.grid.fireEvent('columnresize', i, w);
+        this.grid.fireEvent('columnresize', cellIndex, width);
     },
 
     
-    handleHdMenuClick : function(item){
-        var index = this.hdCtxIndex,
-            cm = this.cm, 
-            ds = this.ds,
-            id = item.getItemId();
-        switch(id){
+    beforeColMenuShow : function() {
+        var colModel = this.cm,
+            colCount = colModel.getColumnCount(),
+            colMenu  = this.colMenu,
+            i;
+
+        colMenu.removeAll();
+
+        for (i = 0; i < colCount; i++) {
+            if (colModel.config[i].hideable !== false) {
+                colMenu.add(new Ext.menu.CheckItem({
+                    text       : colModel.getColumnHeader(i),
+                    itemId     : 'col-' + colModel.getColumnId(i),
+                    checked    : !colModel.isHidden(i),
+                    disabled   : colModel.config[i].hideable === false,
+                    hideOnClick: false
+                }));
+            }
+        }
+    },
+    
+    
+    handleHdMenuClick : function(item) {
+        var store     = this.ds,
+            dataIndex = this.cm.getDataIndex(this.hdCtxIndex);
+
+        switch (item.getItemId()) {
             case 'asc':
-                ds.sort(cm.getDataIndex(index), 'ASC');
+                store.sort(dataIndex, 'ASC');
                 break;
             case 'desc':
-                ds.sort(cm.getDataIndex(index), 'DESC');
+                store.sort(dataIndex, 'DESC');
                 break;
             default:
-                index = cm.getIndexById(id.substr(4));
-                if(index != -1){
-                    if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
-                        this.onDenyColumnHide();
-                        return false;
-                    }
-                    cm.setHidden(index, item.checked);
-                }
+                this.handleHdMenuClickDefault(item);
         }
         return true;
     },
-
     
-    isHideableColumn : function(c){
-        return !c.hidden && !c.fixed;
-    },
-
     
-    beforeColMenuShow : function(){
-        var cm = this.cm,  colCount = cm.getColumnCount();
-        this.colMenu.removeAll();
-        for(var i = 0; i < colCount; i++){
-            if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
-                this.colMenu.add(new Ext.menu.CheckItem({
-                    itemId: 'col-'+cm.getColumnId(i),
-                    text: cm.getColumnHeader(i),
-                    checked: !cm.isHidden(i),
-                    hideOnClick:false,
-                    disabled: cm.config[i].hideable === false
-                }));
+    handleHdMenuClickDefault: function(item) {
+        var colModel = this.cm,
+            itemId   = item.getItemId(),
+            index    = colModel.getIndexById(itemId.substr(4));
+
+        if (index != -1) {
+            if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
+                this.onDenyColumnHide();
+                return;
             }
+            colModel.setHidden(index, item.checked);
         }
     },
 
     
-    handleHdDown : function(e, t){
-        if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
+    handleHdDown : function(e, target) {
+        if (Ext.fly(target).hasClass('x-grid3-hd-btn')) {
             e.stopEvent();
-            var hd = this.findHeaderCell(t);
-            Ext.fly(hd).addClass('x-grid3-hd-menu-open');
-            var index = this.getCellIndex(hd);
+            
+            var colModel  = this.cm,
+                header    = this.findHeaderCell(target),
+                index     = this.getCellIndex(header),
+                sortable  = colModel.isSortable(index),
+                menu      = this.hmenu,
+                menuItems = menu.items,
+                menuCls   = this.headerMenuOpenCls;
+            
             this.hdCtxIndex = index;
-            var ms = this.hmenu.items, cm = this.cm;
-            ms.get('asc').setDisabled(!cm.isSortable(index));
-            ms.get('desc').setDisabled(!cm.isSortable(index));
-            this.hmenu.on('hide', function(){
-                Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
+            
+            Ext.fly(header).addClass(menuCls);
+            menuItems.get('asc').setDisabled(!sortable);
+            menuItems.get('desc').setDisabled(!sortable);
+            
+            menu.on('hide', function() {
+                Ext.fly(header).removeClass(menuCls);
             }, this, {single:true});
-            this.hmenu.show(t, 'tl-bl?');
+            
+            menu.show(target, 'tl-bl?');
         }
     },
 
     
-    handleHdOver : function(e, t){
-        var hd = this.findHeaderCell(t);
-        if(hd && !this.headersDisabled){
-            this.activeHdRef = t;
-            this.activeHdIndex = this.getCellIndex(hd);
-            var fly = this.fly(hd);
-            this.activeHdRegion = fly.getRegion();
-            if(!this.cm.isMenuDisabled(this.activeHdIndex)){
-                fly.addClass('x-grid3-hd-over');
-                this.activeHdBtn = fly.child('.x-grid3-hd-btn');
-                if(this.activeHdBtn){
-                    this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
+    handleHdMove : function(e) {
+        var header = this.findHeaderCell(this.activeHdRef);
+        
+        if (header && !this.headersDisabled) {
+            var handleWidth  = this.splitHandleWidth || 5,
+                activeRegion = this.activeHdRegion,
+                headerStyle  = header.style,
+                colModel     = this.cm,
+                cursor       = '',
+                pageX        = e.getPageX();
+                
+            if (this.grid.enableColumnResize !== false) {
+                var activeHeaderIndex = this.activeHdIndex,
+                    previousVisible   = this.getPreviousVisible(activeHeaderIndex),
+                    currentResizable  = colModel.isResizable(activeHeaderIndex),
+                    previousResizable = previousVisible && colModel.isResizable(previousVisible),
+                    inLeftResizer     = pageX - activeRegion.left <= handleWidth,
+                    inRightResizer    = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);
+                
+                if (inLeftResizer && previousResizable) {
+                    cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; 
+                } else if (inRightResizer && currentResizable) {
+                    cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
                 }
             }
+            
+            headerStyle.cursor = cursor;
+        }
+    },
+    
+    
+    getPreviousVisible: function(index) {
+        while (index > 0) {
+            if (!this.cm.isHidden(index - 1)) {
+                return index;
+            }
+            index--;
         }
+        return undefined;
     },
 
     
-    handleHdMove : function(e, t){
-        var hd = this.findHeaderCell(this.activeHdRef);
-        if(hd && !this.headersDisabled){
-            var hw = this.splitHandleWidth || 5,
-                r = this.activeHdRegion,
-                x = e.getPageX(),
-                ss = hd.style,
-                cur = '';
-            if(this.grid.enableColumnResize !== false){
-                if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
-                    cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; 
-                }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
-                    cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
+    handleHdOver : function(e, target) {
+        var header = this.findHeaderCell(target);
+        
+        if (header && !this.headersDisabled) {
+            var fly = this.fly(header);
+            
+            this.activeHdRef = target;
+            this.activeHdIndex = this.getCellIndex(header);
+            this.activeHdRegion = fly.getRegion();
+            
+            if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
+                fly.addClass('x-grid3-hd-over');
+                this.activeHdBtn = fly.child('.x-grid3-hd-btn');
+                
+                if (this.activeHdBtn) {
+                    this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
                 }
             }
-            ss.cursor = cur;
         }
     },
 
     
-    handleHdOut : function(e, t){
-        var hd = this.findHeaderCell(t);
-        if(hd && (!Ext.isIE || !e.within(hd, true))){
+    handleHdOut : function(e, target) {
+        var header = this.findHeaderCell(target);
+        
+        if (header && (!Ext.isIE || !e.within(header, true))) {
             this.activeHdRef = null;
-            this.fly(hd).removeClass('x-grid3-hd-over');
-            hd.style.cursor = '';
+            this.fly(header).removeClass('x-grid3-hd-over');
+            header.style.cursor = '';
         }
     },
+    
+    
+    isMenuDisabled: function(cellIndex, el) {
+        return this.cm.isMenuDisabled(cellIndex);
+    },
 
     
-    hasRows : function(){
+    hasRows : function() {
         var fc = this.mainBody.dom.firstChild;
         return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
     },
+    
+    
+    isHideableColumn : function(c) {
+        return !c.hidden;
+    },
 
     
-    bind : function(d, c){
+    bind : function(d, c) {
         this.initData(d, c);
     }
 });
@@ -42447,29 +47962,31 @@ Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
 
 
 
-Ext.grid.GridView.SplitDragZone = function(grid, hd){
-    this.grid = grid;
-    this.view = grid.getView();
-    this.marker = this.view.resizeMarker;
-    this.proxy = this.view.resizeProxy;
-    Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
-        'gridSplitters' + this.grid.getGridEl().id, {
-        dragElId : Ext.id(this.proxy.dom), resizeFrame:false
-    });
-    this.scroll = false;
-    this.hw = this.view.splitHandleWidth || 5;
-};
-Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
+Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
+
+    constructor: function(grid, hd){
+        this.grid = grid;
+        this.view = grid.getView();
+        this.marker = this.view.resizeMarker;
+        this.proxy = this.view.resizeProxy;
+        Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
+            'gridSplitters' + this.grid.getGridEl().id, {
+            dragElId : Ext.id(this.proxy.dom), resizeFrame:false
+        });
+        this.scroll = false;
+        this.hw = this.view.splitHandleWidth || 5;
+    },
 
     b4StartDrag : function(x, y){
+        this.dragHeadersDisabled = this.view.headersDisabled;
         this.view.headersDisabled = true;
         var h = this.view.mainWrap.getHeight();
         this.marker.setHeight(h);
         this.marker.show();
         this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
         this.proxy.setHeight(h);
-        var w = this.cm.getColumnWidth(this.cellIndex);
-        var minw = Math.max(w-this.grid.minColumnWidth, 0);
+        var w = this.cm.getColumnWidth(this.cellIndex),
+            minw = Math.max(w-this.grid.minColumnWidth, 0);
         this.resetConstraints();
         this.setXConstraint(minw, 1000);
         this.setYConstraint(0, 0);
@@ -42478,18 +47995,21 @@ Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
         this.startPos = x;
         Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
     },
-    
+
     allowHeaderDrag : function(e){
         return true;
     },
 
-
     handleMouseDown : function(e){
         var t = this.view.findHeaderCell(e.getTarget());
         if(t && this.allowHeaderDrag(e)){
-            var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
-            var exy = e.getXY(), ex = exy[0];
-            var w = t.offsetWidth, adjust = false;
+            var xy = this.view.fly(t).getXY(), 
+                x = xy[0],
+                exy = e.getXY(), 
+                ex = exy[0],
+                w = t.offsetWidth, 
+                adjust = false;
+                
             if((ex - x) <= this.hw){
                 adjust = -1;
             }else if((x+w) - ex <= this.hw){
@@ -42522,12 +48042,14 @@ Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
 
     endDrag : function(e){
         this.marker.hide();
-        var v = this.view;
-        var endX = Math.max(this.minX, e.getPageX());
-        var diff = endX - this.startPos;
+        var v = this.view,
+            endX = Math.max(this.minX, e.getPageX()),
+            diff = endX - this.startPos,
+            disabled = this.dragHeadersDisabled;
+            
         v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
         setTimeout(function(){
-            v.headersDisabled = false;
+            v.headersDisabled = disabled;
         }, 50);
     },
 
@@ -42536,6 +48058,516 @@ Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
     }
 });
 
+Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {
+    
+    
+    colHeaderCellCls: 'grid-hd-group-cell',
+    
+    
+    title: '',
+    
+    
+    
+    
+    getColumnHeaders: function() {
+        return this.grid.topAxis.buildHeaders();;
+    },
+    
+    
+    getRowHeaders: function() {
+        return this.grid.leftAxis.buildHeaders();
+    },
+    
+    
+    renderRows : function(startRow, endRow) {
+        var grid          = this.grid,
+            rows          = grid.extractData(),
+            rowCount      = rows.length,
+            templates     = this.templates,
+            renderer      = grid.renderer,
+            hasRenderer   = typeof renderer == 'function',
+            getCellCls    = this.getCellCls,
+            hasGetCellCls = typeof getCellCls == 'function',
+            cellTemplate  = templates.cell,
+            rowTemplate   = templates.row,
+            rowBuffer     = [],
+            meta          = {},
+            tstyle        = 'width:' + this.getGridInnerWidth() + 'px;',
+            colBuffer, column, i;
+        
+        startRow = startRow || 0;
+        endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;
+        
+        for (i = 0; i < rowCount; i++) {
+            row = rows[i];
+            colCount  = row.length;
+            colBuffer = [];
+            
+            rowIndex = startRow + i;
+
+            
+            for (j = 0; j < colCount; j++) {
+                cell = row[j];
+
+                meta.css   = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
+                meta.attr  = meta.cellAttr = '';
+                meta.value = cell;
+
+                if (Ext.isEmpty(meta.value)) {
+                    meta.value = '&#160;';
+                }
+                
+                if (hasRenderer) {
+                    meta.value = renderer(meta.value);
+                }
+                
+                if (hasGetCellCls) {
+                    meta.css += getCellCls(meta.value) + ' ';
+                }
+
+                colBuffer[colBuffer.length] = cellTemplate.apply(meta);
+            }
+            
+            rowBuffer[rowBuffer.length] = rowTemplate.apply({
+                tstyle: tstyle,
+                cols  : colCount,
+                cells : colBuffer.join(""),
+                alt   : ''
+            });
+        }
+        
+        return rowBuffer.join("");
+    },
+    
+    
+    masterTpl: new Ext.Template(
+        '<div class="x-grid3 x-pivotgrid" hidefocus="true">',
+            '<div class="x-grid3-viewport">',
+                '<div class="x-grid3-header">',
+                    '<div class="x-grid3-header-title"><span>{title}</span></div>',
+                    '<div class="x-grid3-header-inner">',
+                        '<div class="x-grid3-header-offset" style="{ostyle}"></div>',
+                    '</div>',
+                    '<div class="x-clear"></div>',
+                '</div>',
+                '<div class="x-grid3-scroller">',
+                    '<div class="x-grid3-row-headers"></div>',
+                    '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
+                    '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
+                '</div>',
+            '</div>',
+            '<div class="x-grid3-resize-marker">&#160;</div>',
+            '<div class="x-grid3-resize-proxy">&#160;</div>',
+        '</div>'
+    ),
+    
+    
+    initTemplates: function() {
+        Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);
+        
+        var templates = this.templates || {};
+        if (!templates.gcell) {
+            templates.gcell = new Ext.XTemplate(
+                '<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
+                    '<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', 
+                        this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
+                    '</div>',
+                '</td>'
+            );
+        }
+        
+        this.templates = templates;
+        this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
+    },
+    
+    
+    initElements: function() {
+        Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);
+        
+        
+        this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));
+        
+        
+        this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
+    },
+    
+    
+    getGridInnerWidth: function() {
+        var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);
+        
+        return previousWidth - this.getTotalRowHeaderWidth();
+    },
+    
+    
+    getTotalRowHeaderWidth: function() {
+        var headers = this.getRowHeaders(),
+            length  = headers.length,
+            total   = 0,
+            i;
+        
+        for (i = 0; i< length; i++) {
+            total += headers[i].width;
+        }
+        
+        return total;
+    },
+    
+    
+    getTotalColumnHeaderHeight: function() {
+        return this.getColumnHeaders().length * 21;
+    },
+    
+    
+    renderUI : function() {
+        var templates  = this.templates,
+            innerWidth = this.getGridInnerWidth();
+            
+        return templates.master.apply({
+            body  : templates.body.apply({rows:'&#160;'}),
+            ostyle: 'width:' + innerWidth + 'px',
+            bstyle: 'width:' + innerWidth + 'px'
+        });
+    },
+    
+    
+    onLayout: function(width, height) {
+        Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);
+        
+        var width = this.getGridInnerWidth();
+        
+        this.resizeColumnHeaders(width);
+        this.resizeAllRows(width);
+    },
+    
+    
+    refresh : function(headersToo) {
+        this.fireEvent('beforerefresh', this);
+        this.grid.stopEditing(true);
+        
+        var result = this.renderBody();
+        this.mainBody.update(result).setWidth(this.getGridInnerWidth());
+        if (headersToo === true) {
+            this.updateHeaders();
+            this.updateHeaderSortState();
+        }
+        this.processRows(0, true);
+        this.layout();
+        this.applyEmptyText();
+        this.fireEvent('refresh', this);
+    },
+    
+    
+    renderHeaders: Ext.emptyFn,
+    
+    
+    fitColumns: Ext.emptyFn,
+    
+    
+    resizeColumnHeaders: function(width) {
+        var topAxis = this.grid.topAxis;
+        
+        if (topAxis.rendered) {
+            topAxis.el.setWidth(width);
+        }
+    },
+    
+    
+    resizeRowHeaders: function() {
+        var rowHeaderWidth = this.getTotalRowHeaderWidth(),
+            marginStyle    = String.format("margin-left: {0}px;", rowHeaderWidth);
+        
+        this.rowHeadersEl.setWidth(rowHeaderWidth);
+        this.mainBody.applyStyles(marginStyle);
+        Ext.fly(this.innerHd).applyStyles(marginStyle);
+        
+        this.headerTitleEl.setWidth(rowHeaderWidth);
+        this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
+    },
+    
+    
+    resizeAllRows: function(width) {
+        var rows   = this.getRows(),
+            length = rows.length,
+            i;
+        
+        for (i = 0; i < length; i++) {
+            Ext.fly(rows[i]).setWidth(width);
+            Ext.fly(rows[i]).child('table').setWidth(width);
+        }
+    },
+    
+    
+    updateHeaders: function() {
+        this.renderGroupRowHeaders();
+        this.renderGroupColumnHeaders();
+    },
+    
+    
+    renderGroupRowHeaders: function() {
+        var leftAxis = this.grid.leftAxis;
+        
+        this.resizeRowHeaders();
+        leftAxis.rendered = false;
+        leftAxis.render(this.rowHeadersEl);
+        
+        this.setTitle(this.title);
+    },
+    
+    
+    setTitle: function(title) {
+        this.headerTitleEl.child('span').dom.innerHTML = title;
+    },
+    
+    
+    renderGroupColumnHeaders: function() {
+        var topAxis = this.grid.topAxis;
+        
+        topAxis.rendered = false;
+        topAxis.render(this.innerHd.firstChild);
+    },
+    
+    
+    isMenuDisabled: function(cellIndex, el) {
+        return true;
+    }
+});
+Ext.grid.PivotAxis = Ext.extend(Ext.Component, {
+    
+    orientation: 'horizontal',
+    
+    
+    defaultHeaderWidth: 80,
+    
+    
+    paddingWidth: 7,
+    
+    
+    setDimensions: function(dimensions) {
+        this.dimensions = dimensions;
+    },
+    
+    
+    onRender: function(ct, position) {
+        var rows = this.orientation == 'horizontal'
+                 ? this.renderHorizontalRows()
+                 : this.renderVerticalRows();
+        
+        this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true);
+    },
+    
+    
+    renderHorizontalRows: function() {
+        var headers  = this.buildHeaders(),
+            rowCount = headers.length,
+            rows     = [],
+            cells, cols, colCount, i, j;
+        
+        for (i = 0; i < rowCount; i++) {
+            cells = [];
+            cols  = headers[i].items;
+            colCount = cols.length;
+
+            for (j = 0; j < colCount; j++) {
+                cells.push({
+                    tag: 'td',
+                    html: cols[j].header,
+                    colspan: cols[j].span
+                });
+            }
+
+            rows[i] = {
+                tag: 'tr',
+                cn: cells
+            };
+        }
+        
+        return rows;
+    },
+    
+    
+    renderVerticalRows: function() {
+        var headers  = this.buildHeaders(),
+            colCount = headers.length,
+            rowCells = [],
+            rows     = [],
+            rowCount, col, row, colWidth, i, j;
+        
+        for (i = 0; i < colCount; i++) {
+            col = headers[i];
+            colWidth = col.width || 80;
+            rowCount = col.items.length;
+            
+            for (j = 0; j < rowCount; j++) {
+                row = col.items[j];
+                
+                rowCells[row.start] = rowCells[row.start] || [];
+                rowCells[row.start].push({
+                    tag    : 'td',
+                    html   : row.header,
+                    rowspan: row.span,
+                    width  : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth
+                });
+            }
+        }
+        
+        rowCount = rowCells.length;
+        for (i = 0; i < rowCount; i++) {
+            rows[i] = {
+                tag: 'tr',
+                cn : rowCells[i]
+            };
+        }
+        
+        return rows;
+    },
+    
+    
+    getTuples: function() {
+        var newStore = new Ext.data.Store({});
+        
+        newStore.data = this.store.data.clone();
+        newStore.fields = this.store.fields;
+        
+        var sorters    = [],
+            dimensions = this.dimensions,
+            length     = dimensions.length,
+            i;
+        
+        for (i = 0; i < length; i++) {
+            sorters.push({
+                field    : dimensions[i].dataIndex,
+                direction: dimensions[i].direction || 'ASC'
+            });
+        }
+        
+        newStore.sort(sorters);
+        
+        var records = newStore.data.items,
+            hashes  = [],
+            tuples  = [],
+            recData, hash, info, data, key;
+        
+        length = records.length;
+        
+        for (i = 0; i < length; i++) {
+            info = this.getRecordInfo(records[i]);
+            data = info.data;
+            hash = "";
+            
+            for (key in data) {
+                hash += data[key] + '---';
+            }
+            
+            if (hashes.indexOf(hash) == -1) {
+                hashes.push(hash);
+                tuples.push(info);
+            }
+        }
+        
+        newStore.destroy();
+        
+        return tuples;
+    },
+    
+    
+    getRecordInfo: function(record) {
+        var dimensions = this.dimensions,
+            length  = dimensions.length,
+            data    = {},
+            dimension, dataIndex, i;
+        
+        
+        for (i = 0; i < length; i++) {
+            dimension = dimensions[i];
+            dataIndex = dimension.dataIndex;
+            
+            data[dataIndex] = record.get(dataIndex);
+        }
+        
+        
+        
+        var createMatcherFunction = function(data) {
+            return function(record) {
+                for (var dataIndex in data) {
+                    if (record.get(dataIndex) != data[dataIndex]) {
+                        return false;
+                    }
+                }
+                
+                return true;
+            };
+        };
+        
+        return {
+            data: data,
+            matcher: createMatcherFunction(data)
+        };
+    },
+    
+    
+    buildHeaders: function() {
+        var tuples     = this.getTuples(),
+            rowCount   = tuples.length,
+            dimensions = this.dimensions,
+            colCount   = dimensions.length,
+            headers    = [],
+            tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
+        
+        for (i = 0; i < colCount; i++) {
+            dimension = dimensions[i];
+            rows  = [];
+            span  = 0;
+            start = 0;
+            
+            for (j = 0; j < rowCount; j++) {
+                tuple  = tuples[j];
+                isLast = j == (rowCount - 1);
+                currentHeader = tuple.data[dimension.dataIndex];
+                
+                
+                changed = previousHeader != undefined && previousHeader != currentHeader;
+                if (i > 0 && j > 0) {
+                    changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
+                }
+                
+                if (changed) {                    
+                    rows.push({
+                        header: previousHeader,
+                        span  : span,
+                        start : start
+                    });
+                    
+                    start += span;
+                    span = 0;
+                }
+                
+                if (isLast) {
+                    rows.push({
+                        header: currentHeader,
+                        span  : span + 1,
+                        start : start
+                    });
+                    
+                    start += span;
+                    span = 0;
+                }
+                
+                previousHeader = currentHeader;
+                span++;
+            }
+            
+            headers.push({
+                items: rows,
+                width: dimension.width || this.defaultHeaderWidth
+            });
+            
+            previousHeader = undefined;
+        }
+        
+        return headers;
+    }
+});
+
 
 Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
     maxDragWidth: 120,
@@ -42553,8 +48585,8 @@ Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
     },
     
     getDragData : function(e){
-        var t = Ext.lib.Event.getTarget(e);
-        var h = this.view.findHeaderCell(t);
+        var t = Ext.lib.Event.getTarget(e),
+            h = this.view.findHeaderCell(t);
         if(h){
             return {ddel: h.firstChild, header:h};
         }
@@ -42562,6 +48594,8 @@ Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
     },
 
     onInitDrag : function(e){
+        
+        this.dragHeadersDisabled = this.view.headersDisabled;
         this.view.headersDisabled = true;
         var clone = this.dragData.ddel.cloneNode(true);
         clone.id = Ext.id();
@@ -42571,16 +48605,18 @@ Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
     },
 
     afterValidDrop : function(){
-        var v = this.view;
-        setTimeout(function(){
-            v.headersDisabled = false;
-        }, 50);
+        this.completeDrop();
     },
 
     afterInvalidDrop : function(){
-        var v = this.view;
+        this.completeDrop();
+    },
+    
+    completeDrop: function(){
+        var v = this.view,
+            disabled = this.dragHeadersDisabled;
         setTimeout(function(){
-            v.headersDisabled = false;
+            v.headersDisabled = disabled;
         }, 50);
     }
 });
@@ -42612,8 +48648,8 @@ Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
     },
 
     getTargetFromEvent : function(e){
-        var t = Ext.lib.Event.getTarget(e);
-        var cindex = this.view.findCellIndex(t);
+        var t = Ext.lib.Event.getTarget(e),
+            cindex = this.view.findCellIndex(t);
         if(cindex !== false){
             return this.view.getHeaderCell(cindex);
         }
@@ -42644,9 +48680,11 @@ Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
     },
 
     positionIndicator : function(h, n, e){
-        var x = Ext.lib.Event.getPageX(e);
-        var r = Ext.lib.Dom.getRegion(n.firstChild);
-        var px, pt, py = r.top + this.proxyOffsets[1];
+        var x = Ext.lib.Event.getPageX(e),
+            r = Ext.lib.Dom.getRegion(n.firstChild),
+            px, 
+            pt, 
+            py = r.top + this.proxyOffsets[1];
         if((r.right - x) <= (r.right-r.left)/2){
             px = r.right+this.view.borderWidth;
             pt = "after";
@@ -42696,12 +48734,12 @@ Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
     onNodeDrop : function(n, dd, e, data){
         var h = data.header;
         if(h != n){
-            var cm = this.grid.colModel;
-            var x = Ext.lib.Event.getPageX(e);
-            var r = Ext.lib.Dom.getRegion(n.firstChild);
-            var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";
-            var oldIndex = this.view.getCellIndex(h);
-            var newIndex = this.view.getCellIndex(n);
+            var cm = this.grid.colModel,
+                x = Ext.lib.Event.getPageX(e),
+                r = Ext.lib.Dom.getRegion(n.firstChild),
+                pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
+                oldIndex = this.view.getCellIndex(h),
+                newIndex = this.view.getCellIndex(n);
             if(pt == "after"){
                 newIndex++;
             }
@@ -42846,52 +48884,65 @@ Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
 Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
     
     defaultWidth: 100,
+
     
     defaultSortable: false,
+
     
+
     
-    
-    constructor : function(config){
+
+    constructor : function(config) {
         
-           if(config.columns){
+           if (config.columns) {
                Ext.apply(this, config);
                this.setConfig(config.columns, true);
-           }else{
+           } else {
                this.setConfig(config, true);
            }
+           
            this.addEvents(
                
                "widthchange",
                
+               
                "headerchange",
                
+               
                "hiddenchange",
                
+               
                "columnmoved",
                
+               
                "configchange"
            );
+           
            Ext.grid.ColumnModel.superclass.constructor.call(this);
     },
 
     
-    getColumnId : function(index){
+    getColumnId : function(index) {
         return this.config[index].id;
     },
 
-    getColumnAt : function(index){
+    getColumnAt : function(index) {
         return this.config[index];
     },
 
     
-    setConfig : function(config, initial){
+    setConfig : function(config, initial) {
         var i, c, len;
-        if(!initial){ 
+        
+        if (!initial) { 
             delete this.totalWidth;
-            for(i = 0, len = this.config.length; i < len; i++){
+            
+            for (i = 0, len = this.config.length; i < len; i++) {
                 c = this.config[i];
-                if(c.editor){
-                    c.editor.destroy();
+                
+                if (c.setEditor) {
+                    
+                    c.setEditor(null);
                 }
             }
         }
@@ -42905,33 +48956,37 @@ Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
         this.config = config;
         this.lookup = {};
 
-        for(i = 0, len = config.length; i < len; i++){
+        for (i = 0, len = config.length; i < len; i++) {
             c = Ext.applyIf(config[i], this.defaults);
             
-            if(typeof c.id == 'undefined'){
+            
+            if (Ext.isEmpty(c.id)) {
                 c.id = i;
             }
-            if(!c.isColumn){
+            
+            if (!c.isColumn) {
                 var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
                 c = new Cls(c);
                 config[i] = c;
             }
+            
             this.lookup[c.id] = c;
         }
-        if(!initial){
+        
+        if (!initial) {
             this.fireEvent('configchange', this);
         }
     },
 
     
-    getColumnById : function(id){
+    getColumnById : function(id) {
         return this.lookup[id];
     },
 
     
-    getIndexById : function(id){
-        for(var i = 0, len = this.config.length; i < len; i++){
-            if(this.config[i].id == id){
+    getIndexById : function(id) {
+        for (var i = 0, len = this.config.length; i < len; i++) {
+            if (this.config[i].id == id) {
                 return i;
             }
         }
@@ -42939,87 +48994,102 @@ Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
     },
 
     
-    moveColumn : function(oldIndex, newIndex){
-        var c = this.config[oldIndex];
-        this.config.splice(oldIndex, 1);
-        this.config.splice(newIndex, 0, c);
+    moveColumn : function(oldIndex, newIndex) {
+        var config = this.config,
+            c      = config[oldIndex];
+            
+        config.splice(oldIndex, 1);
+        config.splice(newIndex, 0, c);
         this.dataMap = null;
         this.fireEvent("columnmoved", this, oldIndex, newIndex);
     },
 
     
-    getColumnCount : function(visibleOnly){
-        if(visibleOnly === true){
-            var c = 0;
-            for(var i = 0, len = this.config.length; i < len; i++){
-                if(!this.isHidden(i)){
+    getColumnCount : function(visibleOnly) {
+        var length = this.config.length,
+            c = 0,
+            i;
+        
+        if (visibleOnly === true) {
+            for (i = 0; i < length; i++) {
+                if (!this.isHidden(i)) {
                     c++;
                 }
             }
+            
             return c;
         }
-        return this.config.length;
+        
+        return length;
     },
 
     
-    getColumnsBy : function(fn, scope){
-        var r = [];
-        for(var i = 0, len = this.config.length; i < len; i++){
-            var c = this.config[i];
-            if(fn.call(scope||this, c, i) === true){
-                r[r.length] = c;
+    getColumnsBy : function(fn, scope) {
+        var config = this.config,
+            length = config.length,
+            result = [],
+            i, c;
+            
+        for (i = 0; i < length; i++){
+            c = config[i];
+            
+            if (fn.call(scope || this, c, i) === true) {
+                result[result.length] = c;
             }
         }
-        return r;
+        
+        return result;
     },
 
     
-    isSortable : function(col){
+    isSortable : function(col) {
         return !!this.config[col].sortable;
     },
 
     
-    isMenuDisabled : function(col){
+    isMenuDisabled : function(col) {
         return !!this.config[col].menuDisabled;
     },
 
     
-    getRenderer : function(col){
-        if(!this.config[col].renderer){
-            return Ext.grid.ColumnModel.defaultRenderer;
-        }
-        return this.config[col].renderer;
+    getRenderer : function(col) {
+        return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer;
     },
-    
-    getRendererScope : function(col){
+
+    getRendererScope : function(col) {
         return this.config[col].scope;
     },
 
     
-    setRenderer : function(col, fn){
+    setRenderer : function(col, fn) {
         this.config[col].renderer = fn;
     },
 
     
-    getColumnWidth : function(col){
-        return this.config[col].width;
+    getColumnWidth : function(col) {
+        var width = this.config[col].width;
+        if(typeof width != 'number'){
+            width = this.defaultWidth;
+        }
+        return width;
     },
 
     
-    setColumnWidth : function(col, width, suppressEvent){
+    setColumnWidth : function(col, width, suppressEvent) {
         this.config[col].width = width;
         this.totalWidth = null;
-        if(!suppressEvent){
+        
+        if (!suppressEvent) {
              this.fireEvent("widthchange", this, col, width);
         }
     },
 
     
-    getTotalWidth : function(includeHidden){
-        if(!this.totalWidth){
+    getTotalWidth : function(includeHidden) {
+        if (!this.totalWidth) {
             this.totalWidth = 0;
-            for(var i = 0, len = this.config.length; i < len; i++){
-                if(includeHidden || !this.isHidden(i)){
+            for (var i = 0, len = this.config.length; i < len; i++) {
+                if (includeHidden || !this.isHidden(i)) {
                     this.totalWidth += this.getColumnWidth(i);
                 }
             }
@@ -43028,37 +49098,37 @@ Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
     },
 
     
-    getColumnHeader : function(col){
+    getColumnHeader : function(col) {
         return this.config[col].header;
     },
 
     
-    setColumnHeader : function(col, header){
+    setColumnHeader : function(col, header) {
         this.config[col].header = header;
         this.fireEvent("headerchange", this, col, header);
     },
 
     
-    getColumnTooltip : function(col){
+    getColumnTooltip : function(col) {
             return this.config[col].tooltip;
     },
     
-    setColumnTooltip : function(col, tooltip){
+    setColumnTooltip : function(col, tooltip) {
             this.config[col].tooltip = tooltip;
     },
 
     
-    getDataIndex : function(col){
+    getDataIndex : function(col) {
         return this.config[col].dataIndex;
     },
 
     
-    setDataIndex : function(col, dataIndex){
+    setDataIndex : function(col, dataIndex) {
         this.config[col].dataIndex = dataIndex;
     },
 
     
-    findColumnIndex : function(dataIndex){
+    findColumnIndex : function(dataIndex) {
         var c = this.config;
         for(var i = 0, len = c.length; i < len; i++){
             if(c[i].dataIndex == dataIndex){
@@ -43069,36 +49139,41 @@ Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
     },
 
     
-    isCellEditable : function(colIndex, rowIndex){
-        return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
+    isCellEditable : function(colIndex, rowIndex) {
+        var c = this.config[colIndex],
+            ed = c.editable;
+
+        
+        return !!(ed || (!Ext.isDefined(ed) && c.editor));
     },
 
     
-    getCellEditor : function(colIndex, rowIndex){
+    getCellEditor : function(colIndex, rowIndex) {
         return this.config[colIndex].getCellEditor(rowIndex);
     },
 
     
-    setEditable : function(col, editable){
+    setEditable : function(col, editable) {
         this.config[col].editable = editable;
     },
 
     
-    isHidden : function(colIndex){
+    isHidden : function(colIndex) {
         return !!this.config[colIndex].hidden; 
     },
 
     
-    isFixed : function(colIndex){
+    isFixed : function(colIndex) {
         return !!this.config[colIndex].fixed;
     },
 
     
-    isResizable : function(colIndex){
+    isResizable : function(colIndex) {
         return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
     },
     
-    setHidden : function(colIndex, hidden){
+    
+    setHidden : function(colIndex, hidden) {
         var c = this.config[colIndex];
         if(c.hidden !== hidden){
             c.hidden = hidden;
@@ -43108,30 +49183,40 @@ Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
     },
 
     
-    setEditor : function(col, editor){
-        Ext.destroy(this.config[col].editor);
-        this.config[col].editor = editor;
+    setEditor : function(col, editor) {
+        this.config[col].setEditor(editor);
     },
 
     
-    destroy : function(){
-        for(var i = 0, c = this.config, len = c.length; i < len; i++){
-            Ext.destroy(c[i].editor);
+    destroy : function() {
+        var length = this.config.length,
+            i = 0;
+
+        for (; i < length; i++){
+            this.config[i].destroy(); 
         }
+        delete this.config;
+        delete this.lookup;
         this.purgeListeners();
+    },
+
+    
+    setState : function(col, state) {
+        state = Ext.applyIf(state, this.defaults);
+        Ext.apply(this.config[col], state);
     }
 });
 
 
-Ext.grid.ColumnModel.defaultRenderer = function(value){
-    if(typeof value == "string" && value.length < 1){
+Ext.grid.ColumnModel.defaultRenderer = function(value) {
+    if (typeof value == "string" && value.length < 1) {
         return "&#160;";
     }
     return value;
 };
 Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable,  {
     
-    
+
     constructor : function(){
         this.locked = false;
         Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
@@ -43140,25 +49225,67 @@ Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable,  {
     
     init : function(grid){
         this.grid = grid;
+        if(this.lockOnInit){
+            delete this.lockOnInit;
+            this.locked = false;
+            this.lock();
+        }
         this.initEvents();
     },
 
     
     lock : function(){
+        if(!this.locked){
+            this.locked = true;
+            
+            var g = this.grid;
+            if(g){
+                g.getView().on({
+                    scope: this,
+                    beforerefresh: this.sortUnLock,
+                    refresh: this.sortLock
+                });
+            }else{
+                this.lockOnInit = true;
+            }
+        }
+    },
+
+    
+    sortLock : function() {
         this.locked = true;
     },
 
     
-    unlock : function(){
+    sortUnLock : function() {
         this.locked = false;
     },
 
     
+    unlock : function(){
+        if(this.locked){
+            this.locked = false;
+            var g = this.grid,
+                gv;
+                
+            
+            if(g){
+                gv = g.getView();
+                gv.un('beforerefresh', this.sortUnLock, this);
+                gv.un('refresh', this.sortLock, this);    
+            }else{
+                delete this.lockOnInit;
+            }
+        }
+    },
+
+    
     isLocked : function(){
         return this.locked;
     },
-    
+
     destroy: function(){
+        this.unlock();
         this.purgeListeners();
     }
 });
@@ -43197,34 +49324,8 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
         }
 
         this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
-            'up' : function(e){
-                if(!e.shiftKey || this.singleSelect){
-                    this.selectPrevious(false);
-                }else if(this.last !== false && this.lastActive !== false){
-                    var last = this.last;
-                    this.selectRange(this.last,  this.lastActive-1);
-                    this.grid.getView().focusRow(this.lastActive);
-                    if(last !== false){
-                        this.last = last;
-                    }
-                }else{
-                    this.selectFirstRow();
-                }
-            },
-            'down' : function(e){
-                if(!e.shiftKey || this.singleSelect){
-                    this.selectNext(false);
-                }else if(this.last !== false && this.lastActive !== false){
-                    var last = this.last;
-                    this.selectRange(this.last,  this.lastActive+1);
-                    this.grid.getView().focusRow(this.lastActive);
-                    if(last !== false){
-                        this.last = last;
-                    }
-                }else{
-                    this.selectFirstRow();
-                }
-            },
+            up: this.onKeyPress, 
+            down: this.onKeyPress,
             scope: this
         });
 
@@ -43235,14 +49336,38 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
             rowremoved: this.onRemove
         });
     },
+    
+    onKeyPress : function(e, name){
+        var up = name == 'up',
+            method = up ? 'selectPrevious' : 'selectNext',
+            add = up ? -1 : 1,
+            last;
+        if(!e.shiftKey || this.singleSelect){
+            this[method](false);
+        }else if(this.last !== false && this.lastActive !== false){
+            last = this.last;
+            this.selectRange(this.last,  this.lastActive + add);
+            this.grid.getView().focusRow(this.lastActive);
+            if(last !== false){
+                this.last = last;
+            }
+        }else{
+           this.selectFirstRow();
+        }
+    },
 
     
     onRefresh : function(){
-        var ds = this.grid.store, index;
-        var s = this.getSelections();
+        var ds = this.grid.store,
+            s = this.getSelections(),
+            i = 0,
+            len = s.length, 
+            index, r;
+            
+        this.silent = true;
         this.clearSelections(true);
-        for(var i = 0, len = s.length; i < len; i++){
-            var r = s[i];
+        for(; i < len; i++){
+            r = s[i];
             if((index = ds.indexOfId(r.id)) != -1){
                 this.selectRow(index, true);
             }
@@ -43250,6 +49375,7 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
         if(s.length != this.selections.getCount()){
             this.fireEvent('selectionchange', this);
         }
+        this.silent = false;
     },
 
     
@@ -43271,8 +49397,10 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
         if(!keepExisting){
             this.clearSelections();
         }
-        var ds = this.grid.store;
-        for(var i = 0, len = records.length; i < len; i++){
+        var ds = this.grid.store,
+            i = 0,
+            len = records.length;
+        for(; i < len; i++){
             this.selectRow(ds.indexOf(records[i]), true);
         }
     },
@@ -43335,8 +49463,11 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
 
     
     each : function(fn, scope){
-        var s = this.getSelections();
-        for(var i = 0, len = s.length; i < len; i++){
+        var s = this.getSelections(),
+            i = 0,
+            len = s.length;
+            
+        for(; i < len; i++){
             if(fn.call(scope || this, s[i], i) === false){
                 return false;
             }
@@ -43350,8 +49481,8 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
             return;
         }
         if(fast !== true){
-            var ds = this.grid.store;
-            var s = this.selections;
+            var ds = this.grid.store,
+                s = this.selections;
             s.each(function(r){
                 this.deselectRow(ds.indexOfId(r.id));
             }, this);
@@ -43467,8 +49598,10 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
             if(!preventViewNotify){
                 this.grid.getView().onRowSelect(index);
             }
-            this.fireEvent('rowselect', this, index, r);
-            this.fireEvent('selectionchange', this);
+            if(!this.silent){
+                this.fireEvent('rowselect', this, index, r);
+                this.fireEvent('selectionchange', this);
+            }
         }
     },
 
@@ -43495,13 +49628,6 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
     },
 
     
-    restoreLast : function(){
-        if(this._last){
-            this.last = this._last;
-        }
-    },
-
-    
     acceptsNav : function(row, col, cm){
         return !cm.isHidden(col) && cm.isCellEditable(col, row);
     },
@@ -43513,8 +49639,9 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
             g = this.grid, 
             last = g.lastEdit,
             ed = g.activeEditor,
+            shift = e.shiftKey,
             ae, last, r, c;
-        var shift = e.shiftKey;
+            
         if(k == e.TAB){
             e.stopEvent();
             ed.completeEdit();
@@ -43536,9 +49663,7 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
             r = newCell[0];
             c = newCell[1];
 
-            if(last.row != r){
-                this.selectRow(r); 
-            }
+            this.onEditorSelect(r, last.row);
 
             if(g.isEditor && g.editing){ 
                 ae = g.activeEditor;
@@ -43551,15 +49676,20 @@ Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
         }
     },
     
-    destroy : function(){
-        if(this.rowNav){
-            this.rowNav.disable();
-            this.rowNav = null;
+    onEditorSelect: function(row, lastRow){
+        if(lastRow != row){
+            this.selectRow(row); 
         }
+    },
+    
+    destroy : function(){
+        Ext.destroy(this.rowNav);
+        this.rowNav = null;
         Ext.grid.RowSelectionModel.superclass.destroy.call(this);
     }
 });
-Ext.grid.Column = Ext.extend(Object, {
+
+Ext.grid.Column = Ext.extend(Ext.util.Observable, {
     
     
     
@@ -43585,7 +49715,7 @@ Ext.grid.Column = Ext.extend(Object, {
 
     
     isColumn : true,
-    
+
     constructor : function(config){
         Ext.apply(this, config);
 
@@ -43599,16 +49729,37 @@ Ext.grid.Column = Ext.extend(Object, {
             this.scope = this;
         }
 
-        if(this.editor){
-            this.editor = Ext.create(this.editor, 'textfield');
+        var ed = this.editor;
+        delete this.editor;
+        this.setEditor(ed);
+        this.addEvents(
+            
+            'click',
+            
+            'contextmenu',
+            
+            'dblclick',
+            
+            'mousedown'
+        );
+        Ext.grid.Column.superclass.constructor.call(this);
+    },
+
+    
+    processEvent : function(name, e, grid, rowIndex, colIndex){
+        return this.fireEvent(name, this, grid, rowIndex, e);
+    },
+
+    
+    destroy: function() {
+        if(this.setEditor){
+            this.setEditor(null);
         }
+        this.purgeListeners();
     },
 
     
     renderer : function(value){
-        if(Ext.isString(value) && value.length < 1){
-            return '&#160;';
-        }
         return value;
     },
 
@@ -43618,19 +49769,38 @@ Ext.grid.Column = Ext.extend(Object, {
     },
 
     
-    getCellEditor: function(rowIndex){
-        var editor = this.getEditor(rowIndex);
+    setEditor : function(editor){
+        var ed = this.editor;
+        if(ed){
+            if(ed.gridEditor){
+                ed.gridEditor.destroy();
+                delete ed.gridEditor;
+            }else{
+                ed.destroy();
+            }
+        }
+        this.editor = null;
         if(editor){
-            if(!editor.startEdit){
-                if(!editor.gridEditor){
-                    editor.gridEditor = new Ext.grid.GridEditor(editor);
+            
+            if(!editor.isXType){
+                editor = Ext.create(editor, 'textfield');
+            }
+            this.editor = editor;
+        }
+    },
+
+    
+    getCellEditor: function(rowIndex){
+        var ed = this.getEditor(rowIndex);
+        if(ed){
+            if(!ed.startEdit){
+                if(!ed.gridEditor){
+                    ed.gridEditor = new Ext.grid.GridEditor(ed);
                 }
-                return editor.gridEditor;
-            }else if(editor.startEdit){
-                return editor;
+                ed = ed.gridEditor;
             }
         }
-        return null;
+        return ed;
     }
 });
 
@@ -43692,12 +49862,78 @@ Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
 });
 
 
+Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
+    
+    
+    
+    
+    
+    
+    
+    
+    header: '&#160;',
+
+    actionIdRe: /x-action-col-(\d+)/,
+    
+    
+    altText: '',
+
+    constructor: function(cfg) {
+        var me = this,
+            items = cfg.items || (me.items = [me]),
+            l = items.length,
+            i,
+            item;
+
+        Ext.grid.ActionColumn.superclass.constructor.call(me, cfg);
+
+
+
+        me.renderer = function(v, meta) {
+
+            v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
+
+            meta.css += ' x-action-col-cell';
+            for (i = 0; i < l; i++) {
+                item = items[i];
+                v += '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
+                    '" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
+                    ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
+                    ((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
+            }
+            return v;
+        };
+    },
+
+    destroy: function() {
+        delete this.items;
+        delete this.renderer;
+        return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
+    },
+
+    
+    processEvent : function(name, e, grid, rowIndex, colIndex){
+        var m = e.getTarget().className.match(this.actionIdRe),
+            item, fn;
+        if (m && (item = this.items[parseInt(m[1], 10)])) {
+            if (name == 'click') {
+                (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
+            } else if ((name == 'mousedown') && (item.stopSelection !== false)) {
+                return false;
+            }
+        }
+        return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
+    }
+});
+
+
 Ext.grid.Column.types = {
     gridcolumn : Ext.grid.Column,
     booleancolumn: Ext.grid.BooleanColumn,
     numbercolumn: Ext.grid.NumberColumn,
     datecolumn: Ext.grid.DateColumn,
-    templatecolumn: Ext.grid.TemplateColumn
+    templatecolumn: Ext.grid.TemplateColumn,
+    actioncolumn: Ext.grid.ActionColumn
 };
 Ext.grid.RowNumberer = Ext.extend(Object, {
     
@@ -43716,6 +49952,7 @@ Ext.grid.RowNumberer = Ext.extend(Object, {
 
     
     fixed:true,
+    hideable: false,
     menuDisabled:true,
     dataIndex: '',
     id: 'numberer',
@@ -43742,12 +49979,13 @@ Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
     
     menuDisabled : true,
     fixed : true,
+    hideable: false,
     dataIndex : '',
     id : 'checker',
+    isColumn: true, 
 
     constructor : function(){
         Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
-
         if(this.checkOnly){
             this.handleMouseDown = Ext.emptyFn;
         }
@@ -43757,14 +49995,21 @@ Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
     initEvents : function(){
         Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
         this.grid.on('render', function(){
-            var view = this.grid.getView();
-            view.mainBody.on('mousedown', this.onMouseDown, this);
-            Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
-
+            Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this);
         }, this);
     },
 
     
+    processEvent : function(name, e, grid, rowIndex, colIndex){
+        if (name == 'mousedown') {
+            this.onMouseDown(e, e.getTarget());
+            return false;
+        } else {
+            return Ext.grid.Column.prototype.processEvent.apply(this, arguments);
+        }
+    },
+
+    
     onMouseDown : function(e, t){
         if(e.button === 0 && t.className == 'x-grid3-row-checker'){ 
             e.stopEvent();
@@ -43775,13 +50020,14 @@ Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
                     this.deselectRow(index);
                 }else{
                     this.selectRow(index, true);
+                    this.grid.getView().focusRow(index);
                 }
             }
         }
     },
 
     
-    onHdMouseDown : function(e, t){
+    onHdMouseDown : function(e, t) {
         if(t.className == 'x-grid3-hd-checker'){
             e.stopEvent();
             var hd = Ext.fly(t.parentNode);
@@ -43799,6 +50045,12 @@ Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
     
     renderer : function(v, p, record){
         return '<div class="x-grid3-row-checker">&#160;</div>';
+    },
+    
+    onEditorSelect: function(row, lastRow){
+        if(lastRow != row && !this.checkOnly){
+            this.selectRow(row); 
+        }
     }
 });
 Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
@@ -43823,7 +50075,7 @@ Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
     
     initEvents : function(){
         this.grid.on('cellmousedown', this.handleMouseDown, this);
-        this.grid.on(Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.handleKeyDown, this);
+        this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
         this.grid.getView().on({
             scope: this,
             refresh: this.onViewChange,
@@ -44014,7 +50266,7 @@ Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
     
     clicksToEdit: 2,
-    
+
     
     forceValidation: false,
 
@@ -44023,10 +50275,10 @@ Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
     
     detectEdit: false,
 
-       
-       autoEncode : false,
+    
+    autoEncode : false,
 
-       
+    
     
     trackMouseOver: false, 
 
@@ -44041,7 +50293,7 @@ Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
 
         this.activeEditor = null;
 
-           this.addEvents(
+        this.addEvents(
             
             "beforeedit",
             
@@ -44068,7 +50320,7 @@ Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
             this.on('celldblclick', this.onCellDblClick, this);
         }
     },
-    
+
     onResize : function(){
         Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
         var ae = this.activeEditor;
@@ -44107,9 +50359,10 @@ Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
     
     onEditComplete : function(ed, value, startValue){
         this.editing = false;
+        this.lastActiveEditor = this.activeEditor;
         this.activeEditor = null;
-        
-               var r = ed.record,
+
+        var r = ed.record,
             field = this.colModel.getDataIndex(ed.col);
         value = this.postEditValue(value, startValue, r, field);
         if(this.forceValidation === true || String(value) !== String(startValue)){
@@ -44182,8 +50435,16 @@ Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
                     col: col
                 };
                 this.activeEditor = ed;
+                
+                
+                ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
                 var v = this.preEditValue(r, field);
                 ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
+
+                
+                (function(){
+                    delete ed.selectSameEditor;
+                }).defer(50);
             }
         }
     },
@@ -44195,14 +50456,15 @@ Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
     },
 
     
-       postEditValue : function(value, originalValue, r, field){
-               return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
-       },
+    postEditValue : function(value, originalValue, r, field){
+        return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
+    },
 
     
     stopEditing : function(cancel){
         if(this.editing){
-            var ae = this.activeEditor;
+            
+            var ae = this.lastActiveEditor = this.activeEditor;
             if(ae){
                 ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
                 this.view.focusCell(ae.row, ae.col);
@@ -44285,9 +50547,32 @@ Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
     },
 
     
-    setValue : function(prop, value){
-        this.source[prop] = value;
-        this.store.getById(prop).set('value', value);
+    setValue : function(prop, value, create){
+        var r = this.getRec(prop);
+        if(r){
+            r.set('value', value);
+            this.source[prop] = value;
+        }else if(create){
+            
+            this.source[prop] = value;
+            r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
+            this.store.add(r);
+
+        }
+    },
+    
+    
+    remove : function(prop){
+        var r = this.getRec(prop);
+        if(r){
+            this.store.remove(r);
+            delete this.source[prop];
+        }
+    },
+    
+    
+    getRec : function(prop){
+        return this.store.getById(prop);
     },
 
     
@@ -44302,6 +50587,8 @@ Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
     nameText : 'Name',
     valueText : 'Value',
     dateFormat : 'm/j/Y',
+    trueText: 'true',
+    falseText: 'false',
     
     constructor : function(grid, store){
         var g = Ext.grid,
@@ -44316,8 +50603,8 @@ Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
        
            var bfield = new f.Field({
                autoCreate: {tag: 'select', children: [
-                   {tag: 'option', value: 'true', html: 'true'},
-                   {tag: 'option', value: 'false', html: 'false'}
+                   {tag: 'option', value: 'true', html: this.trueText},
+                   {tag: 'option', value: 'false', html: this.falseText}
                ]},
                getValue : function(){
                    return this.el.dom.value == 'true';
@@ -44342,7 +50629,7 @@ Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
 
     
     renderBool : function(bVal){
-        return bVal ? 'true' : 'false';
+        return this[bVal ? 'trueText' : 'falseText'];
     },
 
     
@@ -44362,7 +50649,11 @@ Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
     },
 
     
-    renderCell : function(val){
+    renderCell : function(val, meta, rec){
+        var renderer = this.grid.customRenderers[rec.get('name')];
+        if(renderer){
+            return renderer.apply(this, arguments);
+        }
         var rv = val;
         if(Ext.isDate(val)){
             rv = this.renderDate(val);
@@ -44400,8 +50691,13 @@ Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
     
     destroy : function(){
         Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
-        for(var ed in this.editors){
-            Ext.destroy(this.editors[ed]);
+        this.destroyEditors(this.editors);
+        this.destroyEditors(this.grid.customEditors);
+    },
+    
+    destroyEditors: function(editors){
+        for(var ed in editors){
+            Ext.destroy(editors[ed]);
         }
     }
 });
@@ -44411,6 +50707,8 @@ Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
     
     
     
+    
+    
 
     
     enableColumnMove:false,
@@ -44424,6 +50722,7 @@ Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
 
     
     initComponent : function(){
+        this.customRenderers = this.customRenderers || {};
         this.customEditors = this.customEditors || {};
         this.lastEditRow = null;
         var store = new Ext.grid.PropertyStore(this);
@@ -44471,6 +50770,16 @@ Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
     
     getSource : function(){
         return this.propStore.getSource();
+    },
+    
+    
+    setProperty : function(prop, value, create){
+        this.propStore.setValue(prop, value, create);    
+    },
+    
+    
+    removeProperty : function(prop){
+        this.propStore.remove(prop);
     }
 
     
@@ -44509,9 +50818,9 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
     groupMode: 'value',
 
     
-
     
-    gidSeed : 1000,
+    
+    cancelEditOnToggle: true,
 
     
     initTemplates : function(){
@@ -44530,11 +50839,10 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
             );
         }
         this.startGroup.compile();
-        if(!this.endGroup){
+
+        if (!this.endGroup) {
             this.endGroup = '</div></div>';
         }
-
-        this.endGroup = '</div></div>';
     },
 
     
@@ -44548,12 +50856,14 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
     },
 
     
-    onAdd : function(){
-        if(this.enableGrouping && !this.ignoreAdd){
+    onAdd : function(ds, records, index) {
+        if (this.canGroup() && !this.ignoreAdd) {
             var ss = this.getScrollState();
+            this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
             this.refresh();
             this.restoreScroll(ss);
-        }else if(!this.enableGrouping){
+            this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
+        } else if (!this.canGroup()) {
             Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
         }
     },
@@ -44587,14 +50897,13 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
         }
         if((item = items.get('showGroups'))){
             item.setDisabled(disabled);
-        item.setChecked(this.enableGrouping, true);
+            item.setChecked(this.canGroup(), true);
         }
     },
 
     
     renderUI : function(){
-        Ext.grid.GroupingView.superclass.renderUI.call(this);
-        this.mainBody.on('mousedown', this.interceptMouse, this);
+        var markup = Ext.grid.GroupingView.superclass.renderUI.call(this);
 
         if(this.enableGroupingMenu && this.hmenu){
             this.hmenu.add('-',{
@@ -44608,53 +50917,64 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
                 this.hmenu.add({
                     itemId:'showGroups',
                     text: this.showGroupsText,
-            checked: true,
+                    checked: true,
                     checkHandler: this.onShowGroupsClick,
                     scope: this
                 });
             }
             this.hmenu.on('beforeshow', this.beforeMenuShow, this);
         }
+        return markup;
     },
 
     processEvent: function(name, e){
+        Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
         var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
         if(hd){
             
             var field = this.getGroupField(),
                 prefix = this.getPrefix(field),
-                groupValue = hd.id.substring(prefix.length);
+                groupValue = hd.id.substring(prefix.length),
+                emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');
 
             
             groupValue = groupValue.substr(0, groupValue.length - 3);
-            if(groupValue){
+            
+            
+            if(groupValue || emptyRe.test(hd.id)){
                 this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
             }
+            if(name == 'mousedown' && e.button == 0){
+                this.toggleGroup(hd.parentNode);
+            }
         }
 
     },
 
     
     onGroupByClick : function(){
-    this.enableGrouping = true;
-        this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
+        var grid = this.grid;
+        this.enableGrouping = true;
+        grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
+        grid.fireEvent('groupchange', grid, grid.store.getGroupState());
         this.beforeMenuShow(); 
-    this.refresh();
+        this.refresh();
     },
 
     
     onShowGroupsClick : function(mi, checked){
-    this.enableGrouping = checked;
+        this.enableGrouping = checked;
         if(checked){
             this.onGroupByClick();
         }else{
             this.grid.store.clearGrouping();
+            this.grid.fireEvent('groupchange', this, null);
         }
     },
 
     
     toggleRowIndex : function(rowIndex, expanded){
-        if(!this.enableGrouping){
+        if(!this.canGroup()){
             return;
         }
         var row = this.getRow(rowIndex);
@@ -44668,7 +50988,9 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
         var gel = Ext.get(group);
         expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
         if(this.state[gel.id] !== expanded){
-            this.grid.stopEditing(true);
+            if (this.cancelEditOnToggle !== false) {
+                this.grid.stopEditing(true);
+            }
             this.state[gel.id] = expanded;
             gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
         }
@@ -44693,19 +51015,11 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
     },
 
     
-    interceptMouse : function(e){
-        var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
-        if(hd){
-            e.stopEvent();
-            this.toggleGroup(hd.parentNode);
-        }
-    },
-
-    
     getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
-        var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
+        var column = this.cm.config[colIndex],
+            g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v);
         if(g === '' || g === '&#160;'){
-            g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
+            g = column.emptyGroupText || this.emptyGroupText;
         }
         return g;
     },
@@ -44717,11 +51031,40 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
 
     
     afterRender : function(){
+        if(!this.ds || !this.cm){
+            return;
+        }
         Ext.grid.GroupingView.superclass.afterRender.call(this);
         if(this.grid.deferRowRender){
             this.updateGroupWidths();
         }
     },
+    
+    afterRenderUI: function () {
+        Ext.grid.GroupingView.superclass.afterRenderUI.call(this);
+
+        if (this.enableGroupingMenu && this.hmenu) {
+            this.hmenu.add('-',{
+                itemId:'groupBy',
+                text: this.groupByText,
+                handler: this.onGroupByClick,
+                scope: this,
+                iconCls:'x-group-by-icon'
+            });
+            
+            if (this.enableNoGroups) {
+                this.hmenu.add({
+                    itemId:'showGroups',
+                    text: this.showGroupsText,
+                    checked: true,
+                    checkHandler: this.onShowGroupsClick,
+                    scope: this
+                });
+            }
+            
+            this.hmenu.on('beforeshow', this.beforeMenuShow, this);
+        }
+    },
 
     
     renderRows : function(){
@@ -44755,17 +51098,15 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
         if(rs.length < 1){
             return '';
         }
-        var groupField = this.getGroupField(),
-            colIndex = this.cm.findColumnIndex(groupField),
-            g;
 
-        this.enableGrouping = (this.enableGrouping === false) ? false : !!groupField;
-
-        if(!this.enableGrouping || this.isUpdating){
-            return Ext.grid.GroupingView.superclass.doRender.apply(
-                    this, arguments);
+        if(!this.canGroup() || this.isUpdating){
+            return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
         }
-        var gstyle = 'width:' + this.getTotalWidth() + ';',
+
+        var groupField = this.getGroupField(),
+            colIndex = this.cm.findColumnIndex(groupField),
+            g,
+            gstyle = 'width:' + this.getTotalWidth() + ';',
             cfg = this.cm.config[colIndex],
             groupRenderer = cfg.groupRenderer || cfg.renderer,
             prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
@@ -44828,6 +51169,11 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
     },
 
     
+    canGroup  : function(){
+        return this.enableGrouping && !!this.getGroupField();
+    },
+
+    
     getPrefix: function(field){
         return this.grid.getGridEl().id + '-gp-' + field + '-';
     },
@@ -44844,15 +51190,23 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
 
     
     getRows : function(){
-        if(!this.enableGrouping){
+        if(!this.canGroup()){
             return Ext.grid.GroupingView.superclass.getRows.call(this);
         }
-        var r = [];
-        var g, gs = this.getGroups();
-        for(var i = 0, len = gs.length; i < len; i++){
-            g = gs[i].childNodes[1].childNodes;
-            for(var j = 0, jlen = g.length; j < jlen; j++){
-                r[r.length] = g[j];
+        var r = [],
+            gs = this.getGroups(),
+            g,
+            i = 0,
+            len = gs.length,
+            j,
+            jlen;
+        for(; i < len; ++i){
+            g = gs[i].childNodes[1];
+            if(g){
+                g = g.childNodes;
+                for(j = 0, jlen = g.length; j < jlen; ++j){
+                    r[r.length] = g[j];
+                }
             }
         }
         return r;
@@ -44860,7 +51214,7 @@ Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
 
     
     updateGroupWidths : function(){
-        if(!this.enableGrouping || !this.hasRows()){
+        if(!this.canGroup() || !this.hasRows()){
             return;
         }
         var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';