/*
 * Ext JS Library 3.0.0
 * Copyright(c) 2006-2009, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * http://extjs.com/license
 */

pExt.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,
    	pub,
    	afterbegin = "afterbegin",
    	afterend = "afterend",
    	beforebegin = "beforebegin",
    	beforeend = "beforeend",
    	ts = '<table>',
        te = '</table>',
        tbs = ts+'<tbody>',
        tbe = '</tbody>'+te,
        trs = tbs + '<tr>',
        tre = '</tr>'+tbe;
    function doInsert(el, o, returnElement, pos, sibling, append){
        var newNode = pub.insertHtml(pos, pExt.getDom(el), createHtml(o));
        return returnElement ? pExt.get(newNode, true) : newNode;
    }
    function createHtml(o){
	    var b = "",
	    	attr,
	    	val,
	    	key,
	    	keyVal,
	    	cn;
        if(typeof o == 'string'){
            b = o;
        } else if (pExt.isArray(o)) {
	        pExt.each(o, function(v) {
                b += createHtml(v);
            });
        } else {
	        b += "<" + (o.tag = o.tag || "div");
            pExt.iterate(o, function(attr, val){
                if(!/tag|children|cn|html$/i.test(attr)){
                    if (pExt.isObject(val)) {
                        b += " " + attr + "='";
                        pExt.iterate(val, function(key, keyVal){
                            b += key + ":" + keyVal + ";";
                        });
                        b += "'";
                    }else{
                        b += " " + ({cls : "class", htmlFor : "for"}[attr] || attr) + "='" + val + "'";
                    }
                }
            });
	        if (emptyTags.test(o.tag)) {
	            b += "/>";
	        } else {
	            b += ">";
	            if ((cn = o.children || o.cn)) {
	                b += createHtml(cn);
	            } else if(o.html){
	                b += o.html;
	            }
	            b += "</" + o.tag + ">";
        	}
        }
        return b;
    }
    function ieTable(depth, s, h, e){
        tempTableEl.innerHTML = [s, h, e].join('');
        var i = -1,
        	el = tempTableEl;
        while(++i < depth){
            el = el.firstChild;
        }
        return el;
    }
    function insertIntoTable(tag, where, el, html) {
	    var node,
        	before;
        tempTableEl = tempTableEl || document.createElement('div');
  	    if(tag == 'td' && (where == afterbegin || where == beforeend) ||
  	       !/td|tr|tbody/i.test(tag) && (where == beforebegin || where == afterend)) {
            return;
        }
        before = where == beforebegin ? el :
		 		 where == afterend ? el.nextSibling :
				 where == afterbegin ? el.firstChild : null;
        if (where == beforebegin || where == afterend) {
        	el = el.parentNode;
    	}
        if (tag == 'td' || (tag == "tr" && (where == beforeend || where == afterbegin))) {
	        node = ieTable(4, trs, html, tre);
        } else if ((tag == "tbody" && (where == beforeend || where == afterbegin)) ||
        		   (tag == "tr" && (where == beforebegin || where == afterend))) {
	        node = ieTable(3, tbs, html, tbe);
        } else {
	     	node = ieTable(2, ts, html, te);
        }
        el.insertBefore(node, before);
        return node;
    }
    pub = {
	    markup : function(o){
	        return createHtml(o);
	    },
	    insertHtml : function(where, el, html){
	        var hash = {},
	        	hashVal,
 	        	setStart,
	        	range,
	        	frag,
	        	rangeEl,
	        	rs;
	        where = where.toLowerCase();
	        hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
	        hash[afterend] = ['AfterEnd', 'nextSibling'];
	        if (el.insertAdjacentHTML) {
	            if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
	            	return rs;
	            }
	            hash[afterbegin] = ['AfterBegin', 'firstChild'];
	            hash[beforeend] = ['BeforeEnd', 'lastChild'];
	            if ((hashVal = hash[where])) {
		        	el.insertAdjacentHTML(hashVal[0], html);
	            	return el[hashVal[1]];
	            }
	        } else {
		        range = el.ownerDocument.createRange();
		        setStart = "setStart" + (/end/i.test(where) ? "After" : "Before");
		        if (hash[where]) {
			     	range[setStart](el);
			     	frag = range.createContextualFragment(html);
			     	el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
			     	return el[(where == beforebegin ? "previous" : "next") + "Sibling"];
		        } else {
			        rangeEl = (where == afterbegin ? "first" : "last") + "Child";
			        if (el.firstChild) {
				        range[setStart](el[rangeEl]);
				        frag = range.createContextualFragment(html);
                        if(where == afterbegin){
                            el.insertBefore(frag, el.firstChild);
                        }else{
                            el.appendChild(frag);
                        }
			        } else {
		 	            el.innerHTML = html;
	 	            }
	 	            return el[rangeEl];
		        }
	        }
	        throw 'Illegal insertion point -> "' + where + '"';
	    },
	    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);
	    },
	    overwrite : function(el, o, returnElement){
	        el = pExt.getDom(el);
	        el.innerHTML = createHtml(o);
	        return returnElement ? pExt.get(el.firstChild) : el.firstChild;
	    },
	    createHtml : createHtml
    };
    return pub;
}();
pExt.apply(pExt.DomHelper,
function(){
	var pub,
		afterbegin = 'afterbegin',
    	afterend = 'afterend',
    	beforebegin = 'beforebegin',
    	beforeend = 'beforeend';
    function doInsert(el, o, returnElement, pos, sibling, append){
        el = pExt.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 = pExt.DomHelper.insertHtml(pos, el, pExt.DomHelper.createHtml(o));
        }
        return returnElement ? pExt.get(newNode, true) : newNode;
    }
    function createDom(o, parentNode){
        var el,
        	doc = document,
        	useSet,
        	attr,
        	val,
        	cn;
        if (pExt.isArray(o)) {                       
            el = doc.createDocumentFragment(); 
	        pExt.each(o, function(v) {
                createDom(v, el);
            });
        } else if (pExt.isString(o)) {         
            el = doc.createTextNode(o);
        } else {
            el = doc.createElement( o.tag || 'div' );
            useSet = !!el.setAttribute; 
            pExt.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;
                        }
	                }
                }
            });
            pub.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 = pExt.DomHelper.createHtml(o);
	        return new pExt.Template(html);
	    },
	    useDom : false,
	    applyStyles : function(el, styles){
		    if(styles){
				var i = 0,
	    			len,
	    			style;
	    		el = pExt.fly(el);
				if(pExt.isFunction(styles)){
   					styles = styles.call();
				}
				if(pExt.isString(styles)){
					styles = styles.trim().split(/\s*(?::|;)\s*/);
					for(len = styles.length; i < len;){
						el.setStyle(styles[i++], styles[i++]);
					}
				}else if (pExt.isObject(styles)){
					el.setStyle(styles);
				}
			}
	    },
	    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;
}());
pExt.Template = function(html){
    var me = this,
    	a = arguments,
    	buf = [];
    if (pExt.isArray(html)) {
        html = html.join("");
    } else if (a.length > 1) {
	    pExt.each(a, function(v) {
            if (pExt.isObject(v)) {
                pExt.apply(me, v);
            } else {
                buf.push(v);
            }
        });
        html = buf.join('');
    }
    me.html = html;
    if (me.compiled) {
        me.compile();
    }
};
pExt.Template.prototype = {
    applyTemplate : function(values){
		var me = this;
        return me.compiled ?
        		me.compiled(values) :
				me.html.replace(me.re, function(m, name){
		        	return values[name] !== undefined ? values[name] : "";
		        });
	},
    set : function(html, compile){
	    var me = this;
        me.html = html;
        me.compiled = null;
        return compile ? me.compile() : me;
    },
    re : /\{([\w-]+)\}/g,
    compile : function(){
        var me = this,
        	sep = pExt.isGecko ? "+" : ",";
        function fn(m, name){                        
	        name = "values['" + name + "']";
	        return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
        }
        eval("this.compiled = function(values){ return " + (pExt.isGecko ? "'" : "['") +
             me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
             (pExt.isGecko ?  "';};" : "'].join('');};"));
        return me;
    },
    insertFirst: function(el, values, returnElement){
        return this.doInsert('afterBegin', el, values, returnElement);
    },
    insertBefore: function(el, values, returnElement){
        return this.doInsert('beforeBegin', el, values, returnElement);
    },
    insertAfter : function(el, values, returnElement){
        return this.doInsert('afterEnd', el, values, returnElement);
    },
    append : function(el, values, returnElement){
        return this.doInsert('beforeEnd', el, values, returnElement);
    },
    doInsert : function(where, el, values, returnEl){
        el = pExt.getDom(el);
        var newNode = pExt.DomHelper.insertHtml(where, el, this.applyTemplate(values));
        return returnEl ? pExt.get(newNode, true) : newNode;
    },
    overwrite : function(el, values, returnElement){
        el = pExt.getDom(el);
        el.innerHTML = this.applyTemplate(values);
        return returnElement ? pExt.get(el.firstChild, true) : el.firstChild;
    }
};
pExt.Template.prototype.apply = pExt.Template.prototype.applyTemplate;
pExt.Template.from = function(el, config){
    el = pExt.getDom(el);
    return new pExt.Template(el.value || el.innerHTML, config || '');
};
pExt.apply(pExt.Template.prototype, {
    applyTemplate : function(values){
		var me = this,
			useF = me.disableFormats !== true,
        	fm = pExt.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);
    },
    disableFormats : false,				
    re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
    compile : function(){
        var me = this,
        	fm = pExt.util.Format,
        	useF = me.disableFormats !== true,
        	sep = pExt.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(pExt.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);
    }
});
pExt.Template.prototype.apply = pExt.Template.prototype.applyTemplate; 
pExt.DomQuery = function(){
    var cache = {}, 
    	simpleCache = {}, 
    	valueCache = {},
    	nonSpace = /\S/,
    	trimRe = /^\s+|\s+$/g,
    	tplRe = /\{(\d+)\}/g,
    	modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
    	tagTokenRe = /^(#)?([\w-\*]+)/,
    	nthRe = /(\d*)n\+?(\d*)/, 
    	nthRe2 = /\D/,
	    isIE = window.ActiveXObject ? true : false,
        isOpera = pExt.isOpera,
	    key = 30803;
	eval("var batch = 30803;");    	
    function child(p, index){
        var i = 0,
        	n = p.firstChild;
        while(n){
            if(n.nodeType == 1){
               if(++i == index){
                   return n;
               }
            }
            n = n.nextSibling;
        }
        return null;
    };
    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;
        }
        var r = [], ri = -1, cn;
        for(var i = 0, ci; ci = c[i]; i++){
            if((' '+ci.className+' ').indexOf(v) != -1){
                r[++ri] = ci;
            }
        }
        return r;
    };
    function attrValue(n, attr){
        if(!n.tagName && typeof n.length != "undefined"){
            n = n[0];
        }
        if(!n){
            return null;
        }
        if(attr == "for"){
            return n.htmlFor;
        }
        if(attr == "class" || attr == "className"){
            return n.className;
        }
        return n.getAttribute(attr) || n[attr];
    };
    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);
                for(var j = 0, ci; ci = cs[j]; j++){
                    result[++ri] = ci;
                }
            }
        }else if(mode == "/" || mode == ">"){
            var utag = tagName.toUpperCase();
            for(var i = 0, ni, cn; ni = ns[i]; i++){
                cn = isOpera ? ni.childNodes : (ni.children || ni.childNodes);
                for(var j = 0, cj; cj = cn[j]; j++){
                    if(cj.nodeName == utag || cj.nodeName == tagName  || tagName == '*'){
                        result[++ri] = cj;
                    }
                }
            }
        }else if(mode == "+"){
            var utag = tagName.toUpperCase();
            for(var i = 0, n; n = ns[i]; i++){
                while((n = n.nextSibling) && n.nodeType != 1);
                if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
                    result[++ri] = n;
                }
            }
        }else if(mode == "~"){
            var utag = tagName.toUpperCase();
            for(var i = 0, n; n = ns[i]; i++){
                while((n = n.nextSibling)){
                    if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
                        result[++ri] = n;
                    }
                }
            }
        }
        return result;
    };
    function concat(a, b){
        if(b.slice){
            return a.concat(b);
        }
        for(var i = 0, l = b.length; i < l; i++){
            a[a.length] = b[i];
        }
        return a;
    }
    function byTag(cs, tagName){
        if(cs.tagName || cs == document){
            cs = [cs];
        }
        if(!tagName){
            return cs;
        }
        var r = [], 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;
            }
        }
        return r;
    };
    function byId(cs, attr, 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++){
            if(ci && ci.id == id){
                r[++ri] = ci;
                return r;
            }
        }
        return r;
    };
    function byAttribute(cs, attr, value, op, custom){
        var r = [], 
        	ri = -1, 
        	st = custom=="{",
        	f = pExt.DomQuery.operators[op];
        for(var i = 0, ci; ci = cs[i]; i++){
            if(ci.nodeType != 1){
                continue;
            }
            var a;
            if(st){
                a = pExt.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);
            }
            if((f && f(a, value)) || (!f && a)){
                r[++ri] = ci;
            }
        }
        return r;
    };
    function byPseudo(cs, name, value){
        return pExt.DomQuery.pseudos[name](cs, value);
    };
    function nodupIEXml(cs){
        var d = ++key, 
        	r;
        cs[0].setAttribute("_nodup", d);
        r = [cs[0]];
        for(var i = 1, len = cs.length; i < len; i++){
            var c = cs[i];
            if(!c.getAttribute("_nodup") != d){
                c.setAttribute("_nodup", d);
                r[r.length] = c;
            }
        }
        for(var i = 0, len = cs.length; i < len; i++){
            cs[i].removeAttribute("_nodup");
        }
        return r;
    }
    function nodup(cs){
        if(!cs){
            return [];
        }
        var len = cs.length, c, i, r = cs, cj, ri = -1;
        if(!len || typeof cs.nodeType != "undefined" || len == 1){
            return cs;
        }
        if(isIE && typeof cs[0].selectSingleNode != "undefined"){
            return nodupIEXml(cs);
        }
        var d = ++key;
        cs[0]._nodup = d;
        for(i = 1; c = cs[i]; i++){
            if(c._nodup != d){
                c._nodup = d;
            }else{
                r = [];
                for(var j = 0; j < i; j++){
                    r[++ri] = cs[j];
                }
                for(j = i+1; cj = cs[j]; j++){
                    if(cj._nodup != d){
                        cj._nodup = d;
                        r[++ri] = cj;
                    }
                }
                return r;
            }
        }
        return r;
    }
    function quickDiffIEXml(c1, c2){
        var d = ++key,
        	r = [];
        for(var i = 0, len = c1.length; i < len; i++){
            c1[i].setAttribute("_qdiff", d);
        }        
        for(var i = 0, len = c2.length; i < len; i++){
            if(c2[i].getAttribute("_qdiff") != d){
                r[r.length] = c2[i];
            }
        }
        for(var i = 0, len = c1.length; i < len; i++){
           c1[i].removeAttribute("_qdiff");
        }
        return r;
    }
    function quickDiff(c1, c2){
        var len1 = c1.length,
        	d = ++key,
        	r = [];
        if(!len1){
            return c2;
        }
        if(isIE && c1[0].selectSingleNode){
            return quickDiffIEXml(c1, c2);
        }        
        for(var i = 0; i < len1; i++){
            c1[i]._qdiff = d;
        }        
        for(var i = 0, len = c2.length; i < len; i++){
            if(c2[i]._qdiff != d){
                r[r.length] = c2[i];
            }
        }
        return r;
    }
    function quickId(ns, mode, root, id){
        if(ns == root){
           var d = root.ownerDocument || root;
           return d.getElementById(id);
        }
        ns = getNodes(ns, mode, "*");
        return byId(ns, null, id);
    }
    return {
        getStyle : function(el, name){
            return pExt.fly(el).getStyle(name);
        },
        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 = pExt.DomQuery.matchers,
            	tklen = tk.length,
            	mm,
            	lmode = q.match(modeRe);
            if(lmode && lmode[1]){
                fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
                q = q.replace(lmode[1], "");
            }
            while(path.substr(0, 1)=="/"){
                path = path.substr(1);
            }
            while(q && lq != q){
                lq = q;
                var tm = q.match(tagTokenRe);
                if(type == "select"){
                    if(tm){
                        if(tm[1] == "#"){
                            fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
                        }else{
                            fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
                        }
                        q = q.replace(tm[0], "");
                    }else if(q.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]+'");';
                        }else{
                            fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
                        }
                        q = q.replace(tm[0], "");
                    }
                }
                while(!(mm = q.match(modeRe))){
                    var matched = false;
                    for(var j = 0; j < tklen; j++){
                        var t = tk[j];
                        var m = q.match(t.re);
                        if(m){
                            fn[fn.length] = t.select.replace(tplRe, function(x, i){
                                                    return m[i];
                                                });
                            q = q.replace(m[0], "");
                            matched = true;
                            break;
                        }
                    }
                    if(!matched){
                        throw 'Error parsing selector, parsing failed at "' + q + '"';
                    }
                }
                if(mm[1]){
                    fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
                    q = q.replace(mm[1], "");
                }
            }
            fn[fn.length] = "return nodup(n);\n}";
            eval(fn.join(""));
            return f;
        },
        select : function(path, root, type){
            if(!root || root == document){
                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] = pExt.DomQuery.compile(p);
                    if(!cache[p]){
                        throw p + " is not a valid selector";
                    }
                }
                var result = cache[p](root);
                if(result && result != document){
                    results = results.concat(result);
                }
            }
            if(paths.length > 1){
                return nodup(results);
            }
            return results;
        },
        selectNode : function(path, root){
            return pExt.DomQuery.select(path, root)[0];
        },
        selectValue : function(path, root, defaultValue){
            path = path.replace(trimRe, "");
            if(!valueCache[path]){
                valueCache[path] = pExt.DomQuery.compile(path, "select");
            }
            var n = valueCache[path](root),
            	v;
            n = n[0] ? n[0] : n;
            v = (n && n.firstChild ? n.firstChild.nodeValue : null);
            return ((v === null||v === undefined||v==='') ? defaultValue : v);
        },
        selectNumber : function(path, root, defaultValue){
            var v = pExt.DomQuery.selectValue(path, root, defaultValue || 0);
            return parseFloat(v);
        },
        is : function(el, ss){
            if(typeof el == "string"){
                el = document.getElementById(el);
            }
            var isArray = pExt.isArray(el),
            	result = pExt.DomQuery.filter(isArray ? el : [el], ss);
            return isArray ? (result.length == el.length) : (result.length > 0);
        },
        filter : function(els, ss, nonMatches){
            ss = ss.replace(trimRe, "");
            if(!simpleCache[ss]){
                simpleCache[ss] = pExt.DomQuery.compile(ss, "simple");
            }
            var result = simpleCache[ss](els);
            return nonMatches ? quickDiff(result, els) : result;
        },
        matchers : [{
                re: /^\.([\w-]+)/,
                select: 'n = byClassName(n, null, " {1} ");'
            }, {
                re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
                select: 'n = byPseudo(n, "{1}", "{2}");'
            },{
                re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
                select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
            }, {
                re: /^#([\w-]+)/,
                select: 'n = byId(n, null, "{1}");'
            },{
                re: /^@([\w-]+)/,
                select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
            }
        ],
        operators : {
            "=" : function(a, v){
                return a == v;
            },
            "!=" : function(a, v){
                return a != v;
            },
            "^=" : function(a, v){
                return a && a.substr(0, v.length) == v;
            },
            "$=" : function(a, v){
                return a && a.substr(a.length-v.length) == v;
            },
            "*=" : function(a, v){
                return a && a.indexOf(v) !== -1;
            },
            "%=" : function(a, v){
                return (a % v) == 0;
            },
            "|=" : function(a, v){
                return a && (a == v || a.substr(0, v.length+1) == v+'-');
            },
            "~=" : function(a, v){
                return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
            }
        },
        pseudos : {
            "first-child" : function(c){
                var r = [], ri = -1, n;
                for(var i = 0, ci; ci = n = c[i]; i++){
                    while((n = n.previousSibling) && n.nodeType != 1);
                    if(!n){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "last-child" : function(c){
                var r = [], ri = -1, n;
                for(var i = 0, ci; ci = n = c[i]; i++){
                    while((n = n.nextSibling) && n.nodeType != 1);
                    if(!n){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "nth-child" : function(c, a) {
                var r = [], ri = -1,
                	m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
                	f = (m[1] || 1) - 0, l = m[2] - 0;
                for(var i = 0, n; n = c[i]; i++){
                    var pn = n.parentNode;
                    if (batch != pn._batch) {
                        var j = 0;
                        for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
                            if(cn.nodeType == 1){
                               cn.nodeIndex = ++j;
                            }
                        }
                        pn._batch = batch;
                    }
                    if (f == 1) {
                        if (l == 0 || n.nodeIndex == l){
                            r[++ri] = n;
                        }
                    } else if ((n.nodeIndex + l) % f == 0){
                        r[++ri] = n;
                    }
                }
                return r;
            },
            "only-child" : function(c){
                var r = [], ri = -1;;
                for(var i = 0, ci; ci = c[i]; i++){
                    if(!prev(ci) && !next(ci)){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "empty" : function(c){
                var r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    var cns = ci.childNodes, j = 0, cn, empty = true;
                    while(cn = cns[j]){
                        ++j;
                        if(cn.nodeType == 1 || cn.nodeType == 3){
                            empty = false;
                            break;
                        }
                    }
                    if(empty){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "contains" : function(c, v){
                var r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "nodeValue" : function(c, v){
                var r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    if(ci.firstChild && ci.firstChild.nodeValue == v){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "checked" : function(c){
                var r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    if(ci.checked == true){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "not" : function(c, ss){
                return pExt.DomQuery.filter(c, ss, true);
            },
            "any" : function(c, selectors){
                var ss = selectors.split('|'),
                	r = [], ri = -1, s;
                for(var i = 0, ci; ci = c[i]; i++){
                    for(var j = 0; s = ss[j]; j++){
                        if(pExt.DomQuery.is(ci, s)){
                            r[++ri] = ci;
                            break;
                        }
                    }
                }
                return r;
            },
            "odd" : function(c){
                return this["nth-child"](c, "odd");
            },
            "even" : function(c){
                return this["nth-child"](c, "even");
            },
            "nth" : function(c, a){
                return c[a-1] || [];
            },
            "first" : function(c){
                return c[0] || [];
            },
            "last" : function(c){
                return c[c.length-1] || [];
            },
            "has" : function(c, ss){
                var s = pExt.DomQuery.select,
                	r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    if(s(ss, ci).length > 0){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "next" : function(c, ss){
                var is = pExt.DomQuery.is,
                	r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    var n = next(ci);
                    if(n && is(n, ss)){
                        r[++ri] = ci;
                    }
                }
                return r;
            },
            "prev" : function(c, ss){
                var is = pExt.DomQuery.is,
                	r = [], ri = -1;
                for(var i = 0, ci; ci = c[i]; i++){
                    var n = prev(ci);
                    if(n && is(n, ss)){
                        r[++ri] = ci;
                    }
                }
                return r;
            }
        }
    };
}();
pExt.query = pExt.DomQuery.select;
(function(){
var EXTUTIL = pExt.util,
    TOARRAY = pExt.toArray,
    EACH = pExt.each,
    ISOBJECT = pExt.isObject,
    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 = function(){
    var filterOptRe = /^(?:scope|delay|buffer|single)$/, toLower = function(s){
        return s.toLowerCase();
    };
    return {
        fireEvent : function(){
            var a = TOARRAY(arguments),
                ename = toLower(a[0]),
                me = this,
                ret = TRUE,
                ce = me.events[ename],
                q,
                c;
            if (me.eventsSuspended === TRUE) {
                if (q = me.suspendedEventsQueue) {
                    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) {
                    c.enableBubble(ename);
                    return c.fireEvent.apply(c, a);
                }
            }
            else {
                if (ISOBJECT(ce)) {
                    a.shift();
                    ret = ce.fire.apply(ce, a);
                }
            }
            return ret;
        },
        addListener : function(eventName, fn, scope, o){
            var me = this,
                e,
                oe,
                isF,
            ce;
            if (ISOBJECT(eventName)) {
                o = eventName;
                for (e in o){
                    oe = o[e];
                    if (!filterOptRe.test(e)) {
                        me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
                    }
                }
            } else {
                eventName = toLower(eventName);
                ce = me.events[eventName] || TRUE;
                if (typeof ce == "boolean") {
                    me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
                }
                ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
            }
        },
        removeListener : function(eventName, fn, scope){
            var ce = this.events[toLower(eventName)];
            if (ISOBJECT(ce)) {
                ce.removeListener(fn, scope);
            }
        },
        purgeListeners : function(){
            var events = this.events,
                evt,
                key;
            for(key in events){
                evt = events[key];
                if(ISOBJECT(evt)){
                    evt.clearListeners();
                }
            }
        },
        addEvents : function(o){
            var me = this;
            me.events = me.events || {};
            if (typeof o == 'string') {
                EACH(arguments, function(a) {
                    me.events[a] = me.events[a] || TRUE;
                });
            } else {
                pExt.applyIf(me.events, o);
            }
        },
        hasListener : function(eventName){
            var e = this.events[eventName];
            return ISOBJECT(e) && e.listeners.length > 0;
        },
        suspendEvents : function(queueSuspended){
            this.eventsSuspended = TRUE;
            if (queueSuspended){
                this.suspendedEventsQueue = [];
            }
        },
        resumeEvents : function(){
            var me = this;
            me.eventsSuspended = !delete me.suspendedEventQueue;
            EACH(me.suspendedEventsQueue, 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, TOARRAY(arguments));
        }
    };
};
function createBuffered(h, o, scope){
    var task = new EXTUTIL.DelayedTask();
    return function(){
        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);
    };
}
function createDelayed(h, o, scope){
    return function(){
        var args = TOARRAY(arguments);
        (function(){
            h.apply(scope, args);
        }).defer(o.delay || 10);
    };
};
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, scope);
        }
        if(o.single){
            h = createSingle(h, this, fn, scope);
        }
        if(o.buffer){
            h = createBuffered(h, o, scope);
        }
        l.fireFn = h;
        return l;
    },
    findListener : function(fn, scope){
        var s, ret = -1;
        EACH(this.listeners, function(l, i) {
            s = l.scope;
            if(l.fn == fn && (s == scope || s == this.obj)){
                ret = i;
                return FALSE;
            }
        },
        this);
        return ret;
    },
    isListening : function(fn, scope){
        return this.findListener(fn, scope) != -1;
    },
    removeListener : function(fn, scope){
        var index,
            me = this,
            ret = FALSE;
        if((index = me.findListener(fn, scope)) != -1){
            if (me.firing) {
                me.listeners = me.listeners.slice(0);
            }
            me.listeners.splice(index, 1);
            ret = TRUE;
        }
        return ret;
    },
    clearListeners : function(){
        this.listeners = [];
    },
    fire : function(){
        var me = this,
            args = TOARRAY(arguments),
            ret = TRUE;
        EACH(me.listeners, function(l) {
            me.firing = TRUE;
            if (l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
                return ret = me.firing = FALSE;
            }
        });
        me.firing = FALSE;
        return ret;
    }
};
})();
pExt.apply(pExt.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 (!pExt.isEmpty(v = fn.apply(scope || obj, args))) {
                    if (pExt.isObject(v)) {
                        returnValue = !pExt.isEmpty(v.returnValue) ? v.returnValue : v;
                        cancel = !!v.cancel;
                    }
                    else 
                        if (v === false) {
                            cancel = true;
                        }
                        else {
                            returnValue = v;
                        }
                }
            };
            this[method] = function(){
                var args = pExt.toArray(arguments);
                returnValue = v = undefined;
                cancel = false;
                pExt.each(e.before, function(b){
                    makeCall(b.fn, b.scope, args);
                    if (cancel) {
                        return returnValue;
                    }
                });
                if (!pExt.isEmpty(v = e.originalFn.apply(obj, args))) {
                    returnValue = v;
                }
                pExt.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
            });
        },
        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;
            pExt.each(e.before, function(b, i, arr){
                if (b.fn == fn && b.scope == scope) {
                    arr.splice(i, 1);
                    found = true;
                    return false;
                }
            });
            if (!found) {
                pExt.each(e.after, function(a, i, arr){
                    if (a.fn == fn && a.scope == scope) {
                        arr.splice(i, 1);
                        return false;
                    }
                });
            }
        },
        relayEvents: function(o, events){
            var me = this;
            function createHandler(ename){
                return function(){
                    return me.fireEvent.apply(me, [ename].concat(pExt.toArray(arguments)));
                };
            }
            pExt.each(events, function(ename){
                me.events[ename] = me.events[ename] || true;
                o.on(ename, createHandler(ename), me);
            });
        },
        enableBubble: function(events){
            var me = this;
            events = pExt.isArray(events) ? events : pExt.toArray(arguments);
            pExt.each(events, function(ename){
                ename = ename.toLowerCase();
                var ce = me.events[ename] || true;
                if (typeof ce == "boolean") {
                    ce = new pExt.util.Event(me, ename);
                    me.events[ename] = ce;
                }
                ce.bubble = true;
            });
        }
    };
}());
pExt.util.Observable.capture = function(o, fn, scope){
    o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
};
pExt.util.Observable.observeClass = function(c){
    pExt.apply(c, new pExt.util.Observable());
    c.prototype.fireEvent = function(){
        return (c.fireEvent.apply(c, arguments) !== false) &&
        (pExt.util.Observable.prototype.fireEvent.apply(this, arguments) !== false);
    };
};
pExt.EventManager = function(){
    var docReadyEvent, 
    	docReadyProcId, 
    	docReadyState = false,    	
    	E = pExt.lib.Event,
    	D = pExt.lib.Dom,
    	DOC = document,
    	WINDOW = window,
    	IEDEFERED = "ie-deferred-loader",
    	DOMCONTENTLOADED = "DOMContentLoaded",
    	elHash = {},
    	propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
    function addListener(el, ename, fn, wrap, scope){	    
        var id = pExt.id(el),
        	es = elHash[id] = elHash[id] || {};     	
        (es[ename] = es[ename] || []).push([fn, wrap, scope]);
        E.on(el, ename, wrap);
        if(ename == "mousewheel" && el.addEventListener){ 
        	var args = ["DOMMouseScroll", wrap, false];
        	el.addEventListener.apply(el, args);
            E.on(window, 'unload', function(){
	            el.removeEventListener.apply(el, args);                
            });
        }
        if(ename == "mousedown" && el == document){ 
            pExt.EventManager.stoppedMouseDownEvent.addListener(wrap);
        }
    };
    function fireDocReady(){
        if(!docReadyState){            
            pExt.isReady = docReadyState = true;
            if(docReadyProcId){
                clearInterval(docReadyProcId);
            }
            if(pExt.isGecko || pExt.isOpera) {
                DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
            }
            if(pExt.isIE){
                var defer = DOC.getElementById(IEDEFERED);
                if(defer){
                    defer.onreadystatechange = null;
                    defer.parentNode.removeChild(defer);
                }
            }
            if(docReadyEvent){
                docReadyEvent.fire();
                docReadyEvent.clearListeners();
            }
        }
    };
    function initDocReady(){
	    var COMPLETE = "complete";
        docReadyEvent = new pExt.util.Event();
        if (pExt.isGecko || pExt.isOpera) {
            DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
        } else if (pExt.isIE){
            DOC.write("<s"+'cript id=' + IEDEFERED + ' defer="defer" src="/'+'/:"></s'+"cript>");            
            DOC.getElementById(IEDEFERED).onreadystatechange = function(){
                if(this.readyState == COMPLETE){
                    fireDocReady();
                }
            };
        } else if (pExt.isWebKit){
            docReadyProcId = setInterval(function(){                
                if(DOC.readyState == COMPLETE) {
                    fireDocReady();
                 }
            }, 10);
        }
        E.on(WINDOW, "load", fireDocReady);
    };
    function createTargeted(h, o){
        return function(){
	        var args = pExt.toArray(arguments);
            if(o.target == pExt.EventObject.setEvent(args[0]).target){
                h.apply(this, args);
            }
        };
    };    
    function createBuffered(h, o){
        var task = new pExt.util.DelayedTask(h);
        return function(e){
            task.delay(o.buffer, h, null, [new pExt.EventObjectImpl(e)]);
        };
    };
    function createSingle(h, el, ename, fn, scope){
        return function(e){
            pExt.EventManager.removeListener(el, ename, fn, scope);
            h(e);
        };
    };
    function createDelayed(h, o){
        return function(e){
            e = new pExt.EventObjectImpl(e);
            setTimeout(function(){
                h(e);
            }, o.delay || 10);
        };
    };
    function listen(element, ename, opt, fn, scope){
        var o = !pExt.isObject(opt) ? {} : opt,
        	el = pExt.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(!pExt){
                return;
            }
            e = pExt.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;
            }
            fn.call(scope || el, e, t, o);
        };
        if(o.target){
            h = createTargeted(h, o);
        }
        if(o.delay){
            h = createDelayed(h, o);
        }
        if(o.single){
            h = createSingle(h, el, ename, fn, scope);
        }
        if(o.buffer){
            h = createBuffered(h, o);
        }
        addListener(el, ename, fn, h, scope);
        return h;
    };
    var pub = {
		addListener : function(element, eventName, fn, scope, options){		     		     		     
            if(pExt.isObject(eventName)){                
	            var o = eventName, e, val;
                for(e in o){
	                val = o[e];
                    if(!propRe.test(e)){                            		         
	                    if(pExt.isFunction(val)){
	                        listen(element, e, o, val, o.scope);
	                    }else{
	                        listen(element, e, val);
	                    }
                    }
                }
            } else {
            	listen(element, eventName, options, fn, scope);
        	}
        },
        removeListener : function(element, eventName, fn, scope){            
            var el = pExt.getDom(element),
                id = pExt.id(el),
        	    wrap;      
	        pExt.each((elHash[id] || {})[eventName], function (v,i,a) {
			    if (pExt.isArray(v) && v[0] == fn && (!scope || v[2] == scope)) {		        			        
			        E.un(el, eventName, wrap = v[1]);
			        a.splice(i,1);
			        return false;			        
		        }
	        });	
	        if(eventName == "mousewheel" && el.addEventListener && wrap){
	            el.removeEventListener("DOMMouseScroll", wrap, false);
	        }
	        if(eventName == "mousedown" && el == DOC && wrap){ 
	            pExt.EventManager.stoppedMouseDownEvent.removeListener(wrap);
	        }
        },
        removeAll : function(el){
	        var id = pExt.id(el = pExt.getDom(el)), 
				es = elHash[id], 				
				ename;
	        for(ename in es){
	            if(es.hasOwnProperty(ename)){	                    
	                pExt.each(es[ename], function(v) {
	                    E.un(el, ename, v.wrap);                    
	                });
	            }            
	        }
	        elHash[id] = null;       
        },
        onDocumentReady : function(fn, scope, options){
            if(docReadyState){ 
                docReadyEvent.addListener(fn, scope, options);
                docReadyEvent.fire();
                docReadyEvent.clearListeners();               
            } else {
                if(!docReadyEvent) initDocReady();
                options = options || {};
	            options.delay = options.delay || 1;	            
	            docReadyEvent.addListener(fn, scope, options);
            }
        },
        elHash : elHash   
    };
    pub.on = pub.addListener;
    pub.un = pub.removeListener;
    pub.stoppedMouseDownEvent = new pExt.util.Event();
    return pub;
}();
pExt.onReady = pExt.EventManager.onDocumentReady;
(function(){
    var initpExtCss = function(){
        var bd = document.body || document.getElementsByTagName('body')[0];
        if(!bd){ return false; }
        var cls = [' ',
                pExt.isIE ? "pext-ie " + (pExt.isIE6 ? 'pext-ie6' : (pExt.isIE7 ? 'pext-ie7' : 'pext-ie8'))
                : pExt.isGecko ? "pext-gecko " + (pExt.isGecko2 ? 'pext-gecko2' : 'pext-gecko3')
                : pExt.isOpera ? "pext-opera"
                : pExt.isWebKit ? "pext-webkit" : ""];
        if(pExt.isSafari){
            cls.push("pext-safari " + (pExt.isSafari2 ? 'pext-safari2' : (pExt.isSafari3 ? 'pext-safari3' : 'pext-safari4')));
        }else if(pExt.isChrome){
            cls.push("pext-chrome");
        }
        if(pExt.isMac){
            cls.push("pext-mac");
        }
        if(pExt.isLinux){
            cls.push("pext-linux");
        }
        if(pExt.isStrict || pExt.isBorderBox){ 
            var p = bd.parentNode;
            if(p){
                p.className += pExt.isStrict ? ' pext-strict' : ' pext-border-box';
            }
        }
        bd.className += cls.join(' ');
        return true;
    }
    if(!initpExtCss()){
        pExt.onReady(initpExtCss);
    }
})();
pExt.EventObject = function(){
    var E = pExt.lib.Event,
    	safariKeys = {
	        3 : 13, 
	        63234 : 37, 
	        63235 : 39, 
	        63232 : 38, 
	        63233 : 40, 
	        63276 : 33, 
	        63277 : 34, 
	        63272 : 46, 
	        63273 : 36, 
	        63275 : 35  
    	},
    	btnMap = pExt.isIE ? {1:0,4:1,2:2} :
                (pExt.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
    pExt.EventObjectImpl = function(e){
        if(e){
            this.setEvent(e.browserEvent || e);
        }
    };
    pExt.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;
                }
                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;
        },
        stopEvent : function(){
	        var me = this;
            if(me.browserEvent){
                if(me.browserEvent.type == 'mousedown'){
                    pExt.EventManager.stoppedMouseDownEvent.fire(me);
                }
                E.stopEvent(me.browserEvent);
            }
        },
        preventDefault : function(){
            if(this.browserEvent){
                E.preventDefault(this.browserEvent);
            }
        },        
        stopPropagation : function(){
	        var me = this;
            if(me.browserEvent){
                if(me.browserEvent.type == 'mousedown'){
                    pExt.EventManager.stoppedMouseDownEvent.fire(me);
                }
                E.stopPropagation(me.browserEvent);
            }
        },
        getCharCode : function(){
            return this.charCode || this.keyCode;
        },
        getKey : function(){
            return this.normalizeKey(this.keyCode || this.charCode)
        },
		normalizeKey: function(k){
			return pExt.isSafari ? (safariKeys[k] || k) : k; 
		},
        getPageX : function(){
            return this.xy[0];
        },
        getPageY : function(){
            return this.xy[1];
        },
        getXY : function(){
            return this.xy;
        },
        getTarget : function(selector, maxDepth, returnEl){
            return selector ? pExt.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? pExt.get(this.target) : this.target);
        },
        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;
            }
            return delta;
        },
		within : function(el, related, allowEl){
            if(el){
			    var t = this[related ? "getRelatedTarget" : "getTarget"]();
			    return t && ((allowEl ? (t == pExt.getDom(el)) : false) || pExt.fly(el).contains(t));
            }
            return false;
		}
	 };
    return new pExt.EventObjectImpl();
}();
pExt.apply(pExt.EventManager, function(){
	var resizeEvent, 
    	resizeTask, 
    	textEvent, 
    	textSize,
    	D = pExt.lib.Dom,
    	E = pExt.lib.Event,
    	propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
        curWidth = 0,
        curHeight = 0,
        useKeydown = pExt.isSafari ? 
                    pExt.num(navigator.userAgent.toLowerCase().match(/version\/(\d+\.\d)/)[1] || 2) >= 3.1 :
                    !((pExt.isGecko && !pExt.isWindows) || pExt.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 pExt.util.Event();
	            resizeTask = new pExt.util.DelayedTask(this.doResizeEvent);
	            E.on(window, "resize", this.fireWindowResize, this);
	        }
	        resizeEvent.addListener(fn, scope, options);
	    },
	    fireWindowResize : function(){
	        if(resizeEvent){
	            if((pExt.isIE||pExt.isAir) && resizeTask){
	                resizeTask.delay(50);
	            }else{
	                resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
	            }
	        }
	    },
	    onTextResize : function(fn, scope, options){
	        if(!textEvent){
	            textEvent = new pExt.util.Event();
	            var textEl = new pExt.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
    };
}());
pExt.EventManager.on = pExt.EventManager.addListener;
pExt.apply(pExt.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 pExt.lib.Point(this.xy[0], this.xy[1]);
	},
    hasModifier : function(){
        return ((this.ctrlKey || this.altKey) || this.shiftKey);
    }
});
(function(){
var DOC = document;
pExt.Element = function(element, forceNew){
    var dom = typeof element == "string" ?
              DOC.getElementById(element) : element,
        id;
    if(!dom) return null;
    id = dom.id;
    if(!forceNew && id && pExt.Element.cache[id]){ 
        return pExt.Element.cache[id];
    }
    this.dom = dom;
    this.id = id || pExt.id(dom);
};
var D = pExt.lib.Dom,
    DH = pExt.DomHelper,
    E = pExt.lib.Event,
    A = pExt.lib.Anim,
    El = pExt.Element;
El.prototype = {
    set : function(o, useSet){
        var el = this.dom,
            attr,
            val;        
        for(attr in o){
            val = o[attr];
            if (attr != "style" && !pExt.isFunction(val)) {
                if (attr == "cls" ) {
                    el.className = val;
                } else if (o.hasOwnProperty(attr)) {
                    if (useSet || !!el.setAttribute) el.setAttribute(attr, val);
                    else el[attr] = val;
                }
            }
        }
        if(o.style){
            pExt.DomHelper.applyStyles(el, o.style);
        }
        return this;
    },
    defaultUnit : "px",
    is : function(simpleSelector){
        return pExt.DomQuery.is(this.dom, simpleSelector);
    },
    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;
    },
    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){
        pExt.EventManager.on(this.dom,  eventName, fn, scope || this, options);
        return this;
    },
    removeListener : function(eventName, fn, scope){
        pExt.EventManager.removeListener(this.dom,  eventName, fn, scope || this);
        return this;
    },
    removeAllListeners : function(){
        pExt.EventManager.removeAll(this.dom);
        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;
    },
    load : function(url, params, cb){
        pExt.Ajax.request(pExt.apply({
            params: params,
            url: url.url || url,
            callback: cb,
            el: this.dom,
            indicatorText: url.indicatorText || ''
        }, pExt.isObject(url) ? url : {}));
        return this;
    },
    isBorderBox : function(){
        return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || pExt.isBorderBox;
    },
    remove : function(){
        var me = this,
            dom = me.dom;
        me.removeAllListeners();
        delete El.cache[dom.id];
        delete El.dataCache[dom.id]
        pExt.removeNode(dom);
    },
    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;
    },
    contains : function(el){
        return !el ? false : pExt.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
    },
    getAttributeNS : function(ns, name){
        return this.getAttribute(name, ns); 
    },
    getAttribute : pExt.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];
    },
    update : function(html) {
        this.dom.innerHTML = html;
        return this;
    }
};
var ep = El.prototype;
El.addMethods = function(o){
   pExt.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.cache = {};
El.dataCache = {};
El.get = function(el){
    var ex,
        elm,
        id;
    if(!el){ return null; }
    if (typeof el == "string") { 
        if (!(elm = DOC.getElementById(el))) {
            return null;
        }
        if (ex = El.cache[el]) {
            ex.dom = elm;
        } else {
            ex = El.cache[el] = new El(elm);
        }
        return ex;
    } else if (el.tagName) { 
        if(!(id = el.id)){
            id = pExt.id(el);
        }
        if(ex = El.cache[id]){
            ex.dom = el;
        }else{
            ex = El.cache[id] = new El(el);
        }
        return ex;
    } else if (el instanceof El) {
        if(el != docEl){
            el.dom = DOC.getElementById(el.id) || el.dom; 
            El.cache[el.id] = el; 
        }
        return el;
    } else if(el.isComposite) {
        return el;
    } else if(pExt.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.data = function(el, key, value){
    var c = El.dataCache[el.id];
    if(!c){
        c = El.dataCache[el.id] = {};
    }
    if(arguments.length == 2){
        return c[key];    
    }else{
        c[key] = value;
    }
};
function garbageCollect(){
    if(!pExt.enableGarbageCollector){
        clearInterval(El.collectorThread);
    } else {
        var eid,
            el,
            d;
        for(eid in El.cache){
            el = El.cache[eid];
            d = el.dom;
            if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
                delete El.cache[eid];
                if(d && pExt.enableListenerCollection){
                    pExt.EventManager.removeAll(d);
                }
            }
        }
    }
}
El.collectorThreadId = setInterval(garbageCollect, 30000);
var flyFn = function(){};
flyFn.prototype = El.prototype;
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 = pExt.getDom(el)) {
        (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
        ret = El._flyweights[named];
    }
    return ret;
};
pExt.get = El.get;
pExt.fly = El.fly;
var noBoxAdjust = pExt.isStrict ? {
    select:1
} : {
    input:1, select:1, textarea:1
};
if(pExt.isIE || pExt.isGecko){
    noBoxAdjust['button'] = 1;
}
pExt.EventManager.on(window, 'unload', function(){
    delete El.cache;
    delete El.dataCache;
    delete El._flyweights;
});
})();
pExt.Element.addMethods({    
    swallowEvent : function(eventName, preventDefault){
	    var me = this;
        function fn(e){
            e.stopPropagation();
            if(preventDefault){
                e.preventDefault();
            }
        }
        if(pExt.isArray(eventName)){            
	        pExt.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(pExt.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;
 	    }
        pExt.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 pExt.Updater(this));
    },
    update : function(html, loadScripts, callback){
        html = html || "";
        if(loadScripts !== true){
            this.dom.innerHTML = html;
            if(pExt.isFunction(callback)){
                callback();
            }
            return this;
        }
        var id = pExt.id(),
        	dom = this.dom;
        html += '<span id="' + id + '"></span>';
        pExt.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){pExt.removeNode(el);}
            if(pExt.isFunction(callback)){
                callback();
            }
        });
        dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
        return this;
    },
    createProxy : function(config, renderTo, matchBox){
        config = pExt.isObject(config) ? config : {tag : "div", cls: config};
        var me = this,
        	proxy = renderTo ? pExt.DomHelper.append(renderTo, config, true) :
        					   pExt.DomHelper.insertBefore(me.dom, config, true);        
        if(matchBox && me.setBox && me.getBox){ 
           proxy.setBox(me.getBox());
        }
        return proxy;
    }
});
pExt.Element.prototype.getUpdateManager = pExt.Element.prototype.getUpdater;
pExt.Element.uncache = function(el){
    for(var i = 0, a = arguments, len = a.length; i < len; i++) {
        if(a[i]){
            delete pExt.Element.cache[a[i].id || a[i]];
        }
    }
};
pExt.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 ? pExt.lib.Dom.getViewWidth() : me.getWidth(),
        	h = s.height || vp ? pExt.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;
	    function action(){
            pExt.fly(dom).alignTo(el, alignment, offsets, animate);
            pExt.callback(callback, pExt.fly(dom));
        }
        pExt.EventManager.onWindowResize(action, me);
        if(!pExt.isEmpty(monitorScroll)){
            pExt.EventManager.on(window, 'scroll', action, me,
                {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
        }
        action.call(me); 
        return me;
    },
    getAlignToXY : function(el, p, o){	    
        el = pExt.get(el);
        if(!el || !el.dom){
            throw "Element.alignToXY with an element that doesn't exist";
        }
        o = o || [0,0];
        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 = pExt.lib.Dom.getViewWidth() -10, 
        	dh = pExt.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 = pExt.get(el);
            offsets = offsets ? pExt.applyIf(offsets, os) : os;
            var vw, vh, vx = 0, vy = 0;
            if(el.dom == document.body || el.dom == document){
                vw =pExt.lib.Dom.getViewWidth();
                vh = pExt.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;
            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;
        };
    }(),
    getCenterXY : function(){
        return this.getAlignToXY(document, 'c-c');
    },
    center : function(centerIn){
        return this.alignTo(centerIn || document, 'c-c');        
    }    
});
pExt.Element.addMethods(function(){
	var PARENTNODE = 'parentNode',
		NEXTSIBLING = 'nextSibling',
		PREVIOUSSIBLING = 'previousSibling',
		DQ = pExt.DomQuery,
		GET = pExt.get;
	return {
	    findParent : function(simpleSelector, maxDepth, returnEl){
	        var p = this.dom,
	        	b = document.body, 
	        	depth = 0, 	        	
	        	stopEl;	        
            if(pExt.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
                return null;
            }
	        maxDepth = maxDepth || 50;
	        if (isNaN(maxDepth)) {
	            stopEl = pExt.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 = pExt.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, unique){
	        return pExt.Element.select(selector, unique, this.dom);
	    },
	    query : function(selector, unique){
	        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;
	    }	
    }
}());
pExt.Element.addMethods(
function() {
	var GETDOM = pExt.getDom,
		GET = pExt.get,
		DH = pExt.DomHelper,
        isEl = function(el){
            return  (el.nodeType || el.dom || typeof el == 'string');  
        };
	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(isEl(el)){ 
                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,
		    	Element = pExt.Element;
            if(isEl(el)){
                el = GETDOM(el);
                me.dom.parentNode.insertBefore(el, me.dom);
            }else{
                el = DH.insertBefore(me.dom, el);
            }
	        delete Element.cache[me.id];
	        pExt.removeNode(me.dom);      
	        me.id = pExt.id(me.dom = el);
	        return Element.cache[me.id] = 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 ? pExt.get(el) : el;
		}
	}
}());
pExt.apply(pExt.Element.prototype, function() {
	var GETDOM = pExt.getDom,
		GET = pExt.get,
		DH = pExt.DomHelper;
	return {	
	    insertSibling: function(el, where, returnDom){
	        var me = this,
	        	rt;
	        if(pExt.isArray(el)){            
	            pExt.each(el, function(e) {
		            rt = me.insertSibling(e, where, returnDom);
	            });
	            return rt;
	        }
	        where = (where || 'before').toLowerCase();
	        el = el || {};
            if(el.nodeType || el.dom){
                rt = me.dom.parentNode.insertBefore(GETDOM(el), where == 'before' ? me.dom : me.dom.nextSibling);
                if (!returnDom) {
                    rt = GET(rt);
                }
            }else{
                if (where == 'after' && !me.dom.nextSibling) {
                    rt = DH.append(me.dom.parentNode, el, !returnDom);
                } else {                    
                    rt = DH[where == 'after' ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
                }
            }
	        return rt;
	    }
    };
}());
pExt.Element.addMethods(function(){  
    var propCache = {},
        camelRe = /(-[a-z])/gi,
        classReCache = {},
        view = document.defaultView,
        propFloat = pExt.isIE ? 'styleFloat' : 'cssFloat',
        opacityRe = /alpha\(opacity=(.*)\)/i,
        trimRe = /^\s+|\s+$/g,
        EL = pExt.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',
        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 = pExt.Element.data;
    function camelFn(m, a) {
        return a.charAt(1).toUpperCase();
    }
    function addStyles(sides, styles){
        var val = 0;    
        pExt.each(sides.match(/\w/g), function(s) {
            if (s = parseInt(this.getStyle(styles[s]), 10)) {
                val += MATH.abs(s);      
            }
        },
        this);
        return val;
    }
    function chkCache(prop) {
        return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
    }
    return {    
        adjustWidth : function(width) {
            var me = this;
            var isNum = (typeof width == "number");
            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
               width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
            }
            return (isNum && width < 0) ? 0 : width;
        },
        adjustHeight : function(height) {
            var me = this;
            var isNum = (typeof height == "number");
            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
               height -= (me.getBorderWidth("tb") + me.getPadding("tb"));               
            }
            return (isNum && height < 0) ? 0 : height;
        },
        addClass : function(className){
            var me = this;
            pExt.each(className, function(v) {
                me.dom.className += (!me.hasClass(v) && v ? " " + v : "");  
            });
            return me;
        },
        radioClass : function(className){
            pExt.each(this.dom.parentNode.childNodes, function(v) {
                if(v.nodeType == 1) {
                    pExt.fly(v, '_internal').removeClass(className);          
                }
            });
            return this.addClass(className);
        },
        removeClass : function(className){
            var me = this;
            if (me.dom.className) {
                pExt.each(className, function(v) {               
                    me.dom.className = me.dom.className.replace(
                        classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"), 
                        " ");               
                });    
            }
            return me;
        },
        toggleClass : function(className){
            return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
        },
        hasClass : function(className){
            return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
        },
        replaceClass : function(oldClassName, newClassName){
            return this.removeClass(oldClassName).addClass(newClassName);
        },
        isStyle : function(style, val) {
            return this.getStyle(style) == val;  
        },
        getStyle : function(){         
            return view && view.getComputedStyle ?
                function(prop){
                    var el = this.dom,
                        v,                  
                        cs;
                    if(el == document) return null;
                    prop = chkCache(prop);
                    return (v = el.style[prop]) ? v : 
                           (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
                } :
                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);
                };
        }(),
        getColor : function(attr, defaultValue, prefix){
            var v = this.getStyle(attr),
                color = prefix || '#',
                h;
            if(!v || /transparent|inherit/.test(v)){
                return defaultValue;
            }
            if(/^r/.test(v)){
                pExt.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);
        },
        setStyle : function(prop, value){
            var tmp, 
                style,
                camel;
            if (!pExt.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;
        },
         setOpacity : function(opacity, animate){
            var me = this,
                s = me.dom.style;
            if(!animate || !me.anim){            
                if(pExt.isIE){
                    var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', 
                    val = s.filter.replace(opacityRe, '').replace(trimRe, '');
                    s.zoom = 1;
                    s.filter = val + (val.length > 0 ? ' ' : '') + opac;
                }else{
                    s.opacity = opacity;
                }
            }else{
                me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
            }
            return me;
        },
        clearOpacity : function(){
            var style = this.dom.style;
            if(pExt.isIE){
                if(!pExt.isEmpty(style.filter)){
                    style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
                }
            }else{
                style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
            }
            return this;
        },
        getHeight : function(contentHeight){
            var me = this,
                dom = me.dom,
                h = MATH.max(dom.offsetHeight, dom.clientHeight) || 0;
            h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
            return h < 0 ? 0 : h;
        },
        getWidth : function(contentWidth){
            var me = this,
                dom = me.dom,
                w = MATH.max(dom.offsetWidth, dom.clientWidth) || 0;
            w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
            return w < 0 ? 0 : w;
        },
        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;
        },
        getBorderWidth : function(side){
            return addStyles.call(this, side, borders);
        },
        getPadding : function(side){
            return addStyles.call(this, side, paddings);
        },
        clip : function(){
            var me = this,
                dom = me.dom;
            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;
        },
        unclip : function(){
            var me = this,
                dom = me.dom;
            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 me;
        },
        addStyles : addStyles,
        margins : margins
    }
}()         
);
pExt.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>';
pExt.Element.addMethods(function(){
	var INTERNAL = "_internal";
	return {
	    applyStyles : function(style){
	        pExt.DomHelper.applyStyles(this.dom, style);
	        return this;
	    },
	    getStyles : function(){
		    var ret = {};
		    pExt.each(arguments, function(v) {
			   ret[v] = this.getStyle(v);
		    },
		    this);
		    return ret;
	    },
		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');
	            }
	        }
	        if(s.height && s.height != 'auto'){
	            h = parseInt(s.height, 10);
	            if(me.isBorderBox()){
	               h -= me.getFrameWidth('tb');
	            }
	        }
	        return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
	    },
		setOverflow : function(v){
			var dom = this.dom;
	    	if(v=='auto' && pExt.isMac && pExt.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 = pExt.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(pExt.Element.boxMarkup, cls) + "</div>"));        
	        pExt.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
	        return el;
	    },
	    setSize : function(width, height, animate){
			var me = this;
			if(pExt.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;
	    },
	    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;
	    },
	    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;
	    },
	    getFrameWidth : function(sides, onlyContentBox){
	        return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
	    },
	    addClassOnOver : function(className){
	        this.hover(
	            function(){
	                pExt.fly(this, INTERNAL).addClass(className);
	            },
	            function(){
	                pExt.fly(this, INTERNAL).removeClass(className);
	            }
	        );
	        return this;
	    },
	    addClassOnFocus : function(className){
		    this.on("focus", function(){
		        pExt.fly(this, INTERNAL).addClass(className);
		    }, this.dom);
		    this.on("blur", function(){
		        pExt.fly(this, INTERNAL).removeClass(className);
		    }, this.dom);
		    return this;
	    },
	    addClassOnClick : function(className){
	        var dom = this.dom;
	        this.on("mousedown", function(){
	            pExt.fly(dom, INTERNAL).addClass(className);
	            var d = pExt.getDoc(),
	            	fn = function(){
		                pExt.fly(dom, INTERNAL).removeClass(className);
		                d.removeListener("mouseup", fn);
		            };
	            d.on("mouseup", fn);
	        });
	        return this;
	    },
	    getViewSize : function(){
	        var doc = document,
	        	d = this.dom,
	        	extdom = pExt.lib.Dom,
	        	isDoc = (d == doc || d == doc.body);
	        return { width : (isDoc ? extdom.getViewWidth() : d.clientWidth),
	        		 height : (isDoc ? extdom.getViewHeight() : d.clientHeight) };
	    },
	    getSize : function(contentSize){
	        return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
	    },
	    repaint : function(){
	        var dom = this.dom;
	        this.addClass("x-repaint");
	        setTimeout(function(){
	            pExt.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]] = parseInt(me.getStyle(me.margins[key]), 10) || 0;
                }
		        return o;
	        } else {
	            return me.addStyles.call(me, side, me.margins);
	        }
	    }
    };
}());
(function(){
var D = pExt.lib.Dom,
        LEFT = "left",
        RIGHT = "right",
        TOP = "top",
        BOTTOM = "bottom",
        POSITION = "position",
        STATIC = "static",
        RELATIVE = "relative",
        AUTO = "auto",
        ZINDEX = "z-index";
function animTest(args, animate, i) {
	return this.preanim && !!animate ? this.preanim(args, i) : false	
}
pExt.Element.addMethods({
    getX : function(){
        return D.getX(this.dom);
    },
    getY : function(){
        return D.getY(this.dom);
    },
    getXY : function(){
        return D.getXY(this.dom);
    },
    getOffsetsTo : function(el){
        var o = this.getXY(),
        	e = pExt.fly(el, '_internal').getXY();
        return [o[0]-e[0],o[1]-e[1]];
    },
    setX : function(x, animate){	    
	    return this.setXY([x, this.getY()], animTest.call(this, arguments, animate, 1));
    },
    setY : function(y, animate){	    
	    return this.setXY([this.getX(), y], animTest.call(this, arguments, animate, 1));
    },
    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;
    },
    setBottom : function(bottom){
        this.setStyle(BOTTOM, this.addUnits(bottom));
        return this;
    },
    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 me;
    },
    setLocation : function(x, y, animate){
        return this.setXY([x, y], animTest.call(this, arguments, animate, 2));
    },
    moveTo : function(x, y, animate){
        return this.setXY([x, y], animTest.call(this, arguments, animate, 2));        
    },    
    getLeft : function(local){
	    return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
    },
    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;
    },
    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);
        }
        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;
    },
    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 = "";
        }
        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);        
        return {left: (x - o[0] + l), top: (y - o[1] + t)}; 
    },
    animTest : animTest
});
})();
pExt.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 pExt.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));
    }
});
pExt.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;
    },
    getScroll : function(){
        var d = this.dom, 
            doc = document,
            body = doc.body,
            docElement = doc.documentElement,
            l,
            t,
            ret;
        if(d == doc || d == body){
            if(pExt.isIE && pExt.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;
    }
});
pExt.Element.addMethods({
    scrollTo : function(side, value, animate){
        var tester = /top/i,
        	prop = "scroll" + (tester.test(side) ? "Top" : "Left"),
        	me = this,
        	dom = me.dom;
        if (!animate || !me.anim) {
            dom[prop] = value;
        } else {
            me.anim({scroll: {to: tester.test(prop) ? [dom[prop], value] : [value, dom[prop]]}},
            		 me.preanim(arguments, 2), 'scroll');
        }
        return me;
    },
    scrollIntoView : function(container, hscroll){
        var c = pExt.getDom(container) || pExt.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){
        pExt.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
    },
     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)
            };
            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;
    }
});
pExt.Element.VISIBILITY = 1;
pExt.Element.DISPLAY = 2;
pExt.Element.addMethods(function(){
    var VISIBILITY = "visibility",
        DISPLAY = "display",
        HIDDEN = "hidden",
        NONE = "none",      
        ORIGINALDISPLAY = 'originalDisplay',
        VISMODE = 'visibilityMode',
        ELDISPLAY = pExt.Element.DISPLAY,
        data = pExt.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;
        };
    return {
        originalDisplay : "",
        visibilityMode : 1,
        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;
        },
        anim : function(args, opt, animType, defaultDur, defaultEase, cb){
            animType = animType || 'run';
            opt = opt || {};
            var me = this,              
                anim = pExt.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 : (pExt.isObject(a[i]) ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
        },
        isVisible : function() {
            return !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE);
        },
         setVisible : function(visible, animate){
            var me = this,
                dom = me.dom,
                isDisplay = getVisMode(this.dom) == ELDISPLAY;
            if (!animate || !me.anim) {
                if(isDisplay){
                    me.setDisplayed(visible);
                }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(){
                             if(!visible){
                                 dom.style[isDisplay ? DISPLAY : VISIBILITY] = (isDisplay) ? NONE : HIDDEN;                     
                                 pExt.fly(dom).setOpacity(1);
                             }
                        });
            }
            return me;
        },
        toggle : function(animate){
            var me = this;
            me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
            return me;
        },
        setDisplayed : function(value) {            
            if(typeof value == "boolean"){
               value = value ? getDisplay(this.dom) : NONE;
            }
            this.setStyle(DISPLAY, value);
            return this;
        },
        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");
                }
            }
        },
        hide : function(animate){
            this.setVisible(false, this.preanim(arguments, 0));
            return this;
        },
        show : function(animate){
            this.setVisible(true, this.preanim(arguments, 0));
            return this;
        }
    }
}());
pExt.Element.addMethods(
function(){
    var VISIBILITY = "visibility",
        DISPLAY = "display",
        HIDDEN = "hidden",
        NONE = "none",
	    XMASKED = "x-masked",
		XMASKEDRELATIVE = "x-masked-relative",
        data = pExt.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(!pExt.fly(p, '_isVisible').isVisible()){
	                return false;
	            }
	            p = p.parentNode;
	        }
	        return true;
	    },
	    isDisplayed : function() {
	        return !this.isStyle(DISPLAY, NONE);
	    },
	    enableDisplayMode : function(display){	    
	        this.setVisibilityMode(pExt.Element.DISPLAY);
	        if(!pExt.isEmpty(display)){
                data(this.dom, 'originalDisplay', display);
            }
	        return this;
	    },
	    mask : function(msg, msgCls){
		    var me = this,
		    	dom = me.dom,
		    	dh = pExt.DomHelper,
		    	EXTELMASKMSG = "pext-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 : "pext-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(pExt.isIE && !(pExt.isIE7 && pExt.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 = 'pext-shim';
	        if(pExt.isIE && pExt.isSecure){
	            el.src = pExt.SSL_SECURE_URL;
	        }
	        shim = pExt.get(this.dom.parentNode.insertBefore(el, this.dom));
	        shim.autoBoxAdjust = false;
	        return shim;
	    }
    };
}());
pExt.Element.addMethods({
    initDD : function(group, config, overrides){
        var dd = new pExt.dd.DD(pExt.id(this.dom), group, config);
        return pExt.apply(dd, overrides);
    },
    initDDProxy : function(group, config, overrides){
        var dd = new pExt.dd.DDProxy(pExt.id(this.dom), group, config);
        return pExt.apply(dd, overrides);
    },
    initDDTarget : function(group, config, overrides){
        var dd = new pExt.dd.DDTarget(pExt.id(this.dom), group, config);
        return pExt.apply(dd, overrides);
    }
});
pExt.Element.addMethods({
    autoHeight : function(animate, duration, onComplete, easing){
        var oldHeight = this.getHeight();
        this.clip();
        this.setHeight(1); 
        setTimeout(function(){
            var height = parseInt(this.dom.scrollHeight, 10); 
            if(!animate){
                this.setHeight(height);
                this.unclip();
                if(typeof onComplete == "function"){
                    onComplete();
                }
            }else{
                this.setHeight(oldHeight); 
                this.setHeight(height, animate, duration, function(){
                    this.unclip();
                    if(typeof onComplete == "function") onComplete();
                }.createDelegate(this), easing);
            }
        }.createDelegate(this), 0);
        return this;
    }
});
pExt.Element.addMethods({
    addKeyListener : function(key, fn, scope){
        var config;
        if(!pExt.isObject(key) || pExt.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 pExt.KeyMap(this, config);
    },
    addKeyMap : function(config){
        return new pExt.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 pExt.Element.Flyweight(),
        queues = {},
        getObject = function(o){
            return o || {};
        },
        fly = function(dom){
            flyEl.dom = dom;
            flyEl.id = pExt.id(dom);
            return flyEl;
        },
        getQueue = function(id){
            if(!queues[id]){
                queues[id] = [];
            }
            return queues[id];
        },
        setQueue = function(id, value){
            queues[id] = value;
        };
pExt.enableFx = TRUE;
pExt.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";
        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);
            }
            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:{
                            visbility: HIDDEN,
                            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 = pExt.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){
                        pExt.Element.data(dom, 'visibilityMode') == pExt.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(pExt.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 = pExt.apply(me.fxDefaults || {}, {
            block : FALSE,
            concurrent : TRUE,
            stopFx : FALSE
        });
        return me;
    },
    sequenceFx : function(){
        var me = this;
        me.fxDefaults = pExt.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 = this;
        if(!me.hasFxBlock()){
            pExt.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 = pExt.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){
            wrap.parentNode.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,
            notConcurrent = !o.concurrent;
        if(o.afterStyle){
            fly(dom).setStyle(o.afterStyle);            
        }
        if(o.afterCls){
            fly(dom).addClass(o.afterCls);
        }
        if(o.remove == TRUE){
            fly(dom).remove();
        }
        if(notConcurrent){
            getQueue(id).shift();
        }
        if(o.callback){
            o.callback.call(o.scope, fly(dom));
        }
        if(notConcurrent){
            fly(dom).nextFx();
        }
    },
    fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
        animType = animType || 'run';
        opt = opt || {};
        var anim = pExt.lib.Anim[animType](
                this.dom, 
                args,
                (opt.duration || defaultDur) || .35,
                (opt.easing || defaultEase) || EASEOUT,
                cb,            
                this
            );
        opt.anim = anim;
        return anim;
    }
};
pExt.Fx.resize = pExt.Fx.scale;
pExt.Element.addMethods(pExt.Fx);
})();
pExt.CompositeElementLite = function(els, root){
    this.elements = [];
    this.add(els, root);
    this.el = new pExt.Element.Flyweight();
};
pExt.CompositeElementLite.prototype = {
	isComposite: true,	
    getCount : function(){
        return this.elements.length;
    },    
	add : function(els){
        if(els){
            if (pExt.isArray(els)) {
                this.elements = this.elements.concat(els);
            } else {
                var yels = this.elements;                	                
	            pExt.each(els, function(e) {
                    yels.push(e);
                });
            }
        }
        return this;
    },
    invoke : function(fn, args){
        var els = this.elements,
        	el = this.el;        
	    pExt.each(els, function(e) {    
            el.dom = e;
        	pExt.Element.prototype[fn].apply(el, args);
        });
        return this;
    },
    item : function(index){
	    var me = this;
        if(!me.elements[index]){
            return null;
        }
        me.el.dom = me.elements[index];
        return me.el;
    },
    addListener : function(eventName, handler, scope, opt){
        pExt.each(this.elements, function(e) {
	        pExt.EventManager.on(e, eventName, handler, scope || e, opt);
        });
        return this;
    },
    each : function(fn, scope){       
        var me = this,
        	el = me.el;
	    pExt.each(me.elements, function(e,i) {    
            el.dom = e;
        	return fn.call(scope || el, el, me, i);
        });
        return me;
    },
    indexOf : function(el){
        return this.elements.indexOf(pExt.getDom(el));
    },
    replaceElement : function(el, replacement, domReplace){
        var index = !isNaN(el) ? el : this.indexOf(el),
        	d;
        if(index > -1){
            replacement = pExt.getDom(replacement);
            if(domReplace){
                d = this.elements[index];
                d.parentNode.insertBefore(replacement, d);
                pExt.removeNode(d);
            }
            this.elements.splice(index, 1, replacement);
        }
        return this;
    },
    clear : function(){
        this.elements = [];
    }
};
pExt.CompositeElementLite.prototype.on = pExt.CompositeElementLite.prototype.addListener;
(function(){
var fnName,
	ElProto = pExt.Element.prototype,
	CelProto = pExt.CompositeElementLite.prototype;
for(fnName in ElProto){
    if(pExt.isFunction(ElProto[fnName])){
	    (function(fnName){ 
		    CelProto[fnName] = CelProto[fnName] || function(){
		    	return this.invoke(fnName, arguments);
	    	};
    	}).call(CelProto, fnName);
    }
}
})();
if(pExt.DomQuery){
    pExt.Element.selectorFunction = pExt.DomQuery.select;
} 
pExt.Element.select = function(selector, unique, root){
    var els;
    if(typeof selector == "string"){
        els = pExt.Element.selectorFunction(selector, root);
    }else if(selector.length !== undefined){
        els = selector;
    }else{
        throw "Invalid selector";
    }
    return new pExt.CompositeElementLite(els);
};
pExt.select = pExt.Element.select;
pExt.apply(pExt.CompositeElementLite.prototype, {	
	addElements : function(els, root){
        if(!els){
            return this;
        }
        if(typeof els == "string"){
            els = pExt.Element.selectorFunction(els, root);
        }
        var yels = this.elements;        
	    pExt.each(els, function(e) {
        	yels.push(pExt.get(e));
        });
        return this;
    },
    fill : function(els){
        this.elements = [];
        this.add(els);
        return this;
    },
    first : function(){
        return this.item(0);
    },   
    last : function(){
        return this.item(this.getCount()-1);
    },
    contains : function(el){
        return this.indexOf(el) != -1;
    },
    filter : function(selector){
        var els = [];
        this.each(function(el){
            if(el.is(selector)){
                els[els.length] = el.dom;
            }
        });
        this.fill(els);
        return this;
    },
    removeElement : function(keys, removeDom){
        var me = this,
	        els = this.elements,	    
	    	el;	    	
	    pExt.each(keys, function(val){
		    if ((el = (els[val] || els[val = me.indexOf(val)]))) {
		    	if(removeDom){
                    if(el.dom){
                        el.remove();
                    }else{
                        pExt.removeNode(el);
                    }
                }
		    	els.splice(val, 1);		    	
			}
	    });
        return this;
    }    
});
pExt.CompositeElement = function(els, root){
    this.elements = [];
    this.add(els, root);
};
pExt.extend(pExt.CompositeElement, pExt.CompositeElementLite, {
    invoke : function(fn, args){
	    pExt.each(this.elements, function(e) {
        	pExt.Element.prototype[fn].apply(e, args);
        });
        return this;
    },
    add : function(els, root){
	    if(!els){
            return this;
        }
        if(typeof els == "string"){
            els = pExt.Element.selectorFunction(els, root);
        }
        var yels = this.elements;        
	    pExt.each(els, function(e) {
        	yels.push(pExt.get(e));
        });
        return this;
    },    
    item : function(index){
        return this.elements[index] || null;
    },
    indexOf : function(el){
        return this.elements.indexOf(pExt.get(el));
    },
    filter : function(selector){
		var me = this,
			out = [];
		pExt.each(me.elements, function(el) {	
			if(el.is(selector)){
				out.push(pExt.get(el));
			}
		});
		me.elements = out;
		return me;
	},
    each : function(fn, scope){        
        pExt.each(this.elements, function(e,i) {
	        return fn.call(scope || e, e, this, i);
        }, this);
        return this;
    }
});
pExt.Element.select = function(selector, unique, root){
    var els;
    if(typeof selector == "string"){
        els = pExt.Element.selectorFunction(selector, root);
    }else if(selector.length !== undefined){
        els = selector;
    }else{
        throw "Invalid selector";
    }
    return (unique === true) ? new pExt.CompositeElement(els) : new pExt.CompositeElementLite(els);
};
pExt.select = pExt.Element.select;
pExt.handleError = function(e) {
    throw e;
};
pExt.Error = function(message) {
    this.message = (this.lang[message]) ? this.lang[message] : message;
}
pExt.Error.prototype = new Error();
pExt.apply(pExt.Error.prototype, {
    lang: {},
    name: 'pExt.Error',
    getName : function() {
        return this.name;
    },
    getMessage : function() {
        return this.message;
    },
    toJson : function() {
        return pExt.encode(this);
    }
});
(function(){
    var BEFOREREQUEST = "beforerequest",
        REQUESTCOMPLETE = "requestcomplete",
        REQUESTEXCEPTION = "requestexception",
        UNDEFINED = undefined,
        LOAD = 'load',
        POST = 'POST',
        GET = 'GET',
        WINDOW = window;
    pExt.data.Connection = function(config){    
        pExt.apply(this, config);
        this.addEvents(
            BEFOREREQUEST,
            REQUESTCOMPLETE,
            REQUESTEXCEPTION
        );
        pExt.data.Connection.superclass.constructor.call(this);
    };
    function handleResponse(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);
        }
    }
    function handleFailure(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);
        }
    }
    function doFormUpload(o, ps, url){
        var id = pExt.id(),
            doc = document,
            frame = doc.createElement('iframe'),
            form = pExt.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
            };
        pExt.apply(frame, {
            id: id,
            name: id,
            className: 'x-hidden',
            src: pExt.SSL_SECURE_URL 
        });     
        doc.body.appendChild(frame);
        if(pExt.isIE){
           document.frames[id].name = id;
        }
        pExt.apply(form, {
            target: id,
            method: POST,
            enctype: encoding,
            encoding: encoding,
            action: url || buf.action
        });
        ps = pExt.urlDecode(ps, false);
        for(var k in ps){
            if(ps.hasOwnProperty(k)){
                hd = doc.createElement('input');
                hd.type = 'hidden';                    
                hd.value = ps[hd.name = k];
                form.appendChild(hd);
                hiddens.push(hd);
            }
        }        
        function cb(){
            var me = this,
                r = {responseText : '',
                     responseXML : null,
                     argument : o.argument},
                doc,
                firstChild;
            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) {}
            pExt.EventManager.removeListener(frame, LOAD, cb, me);
            me.fireEvent(REQUESTCOMPLETE, me, r, o);
            function runCallback(fn, scope, args){
                if(pExt.isFunction(fn)){
                    fn.apply(scope, args);
                }
            }
            runCallback(o.success, o.scope, [r, o]);
            runCallback(o.callback, o.scope, [o, true, r]);
            if(!me.debugUploads){
                setTimeout(function(){pExt.removeNode(frame);}, 100);
            }
        }
        pExt.EventManager.on(frame, LOAD, cb, this);
        form.submit();
        pExt.apply(form, buf);
        pExt.each(hiddens, function(h) {
            pExt.removeNode(h);
        });
    }
    pExt.extend(pExt.data.Connection, pExt.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(!pExt.isEmpty(o.indicatorText)){
                        me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
                    }
                    if(me.indicatorText) {
                        pExt.getDom(o.el).innerHTML = me.indicatorText;                        
                    }
                    o.success = (pExt.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
                        pExt.getDom(o.el).innerHTML = response.responseText;
                    });
                }
                var p = o.params,
                    url = o.url || me.url,                
                    method,
                    cb = {success: handleResponse,
                          failure: handleFailure,
                          scope: me,
                          argument: {options: o},
                          timeout : o.timeout || me.timeout
                    },
                    form,                    
                    serForm;                    
                if (pExt.isFunction(p)) {
                    p = p.call(o.scope||WINDOW, o);
                }
                p = pExt.urlEncode(me.extraParams, pExt.isObject(p) ? pExt.urlEncode(p) : p);    
                if (pExt.isFunction(url)) {
                    url = url.call(o.scope || WINDOW, o);
                }
                if((form = pExt.getDom(o.form))){
                    url = url || form.action;
                     if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) { 
                         return doFormUpload.call(me, o, p, url);
                     }
                    serForm = pExt.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 = pExt.urlAppend(url, dcp + '=' + (new Date().getTime()));
                }
                o.headers = pExt.apply(o.headers || {}, me.defaultHeaders || {});
                if(o.autoAbort === true || me.autoAbort) {
                    me.abort();
                }
                if((method == GET || o.xmlData || o.jsonData) && p){
                    url = pExt.urlAppend(url, p);  
                    p = '';
                }
                return (me.transId = pExt.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 ? pExt.lib.Ajax.isCallInProgress(transId) : !! this.transId;            
        },
        abort : function(transId){
            if(transId || this.isLoading()){
                pExt.lib.Ajax.abort(transId || this.transId);
            }
        }
    });
})();
pExt.Ajax = new pExt.data.Connection({
    autoAbort : false,
    serializeForm : function(form){
        return pExt.lib.Ajax.serializeForm(form);
    }
});
pExt.UpdateManager = pExt.Updater = pExt.extend(pExt.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(pExt.isFunction(response.argument.callback)){
            response.argument.callback.call(response.argument.scope, this.el, pExt.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 = pExt.get(el);
	        if(!forceNew && el.updateManager){
	            return el.updateManager;
	        }
	        me.el = el;
	        me.defaultUrl = null;
	        me.addEvents(
	            BEFOREUPDATE,
	            UPDATE,
	            FAILURE
	        );
	        pExt.apply(me, pExt.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();
	        pExt.Updater.superclass.constructor.call(me);
	    },
	    setRenderer : function(renderer){
	        this.renderer = renderer;
	    },	
	    getRenderer : function(){
	       return this.renderer;
	    },
	    getDefaultRenderer: function() {
	        return new pExt.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(pExt.isObject(url)){ 
	                cfg = url;
	                url = cfg.url;
	                params = params || cfg.params;
	                callback = callback || cfg.callback;
	                discardUrl = discardUrl || cfg.discardUrl;
	                callerScope = cfg.scope;	                
	                if(!pExt.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
	                if(!pExt.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
	                if(!pExt.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
	                if(!pExt.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
	            }
	            me.showLoading();
	            if(!discardUrl){
	                me.defaultUrl = url;
	            }
	            if(pExt.isFunction(url)){
	                url = url.call(me);
	            }
	            var o = pExt.apply({}, {
	                url : url,
	                params: (pExt.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 = pExt.Ajax.request(o);
	        }
	    },	    	
	    formUpdate : function(form, url, reset, callback){
		    var me = this;
	        if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
	            if(pExt.isFunction(url)){
	                url = url.call(me);
	            }
	            form = pExt.getDom(form)
	            me.transaction = pExt.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){
	            pExt.Ajax.abort(this.transaction);
	        }
	    },
	    isUpdating : function(){        
	    	return this.transaction ? pExt.Ajax.isLoading(this.transaction) : false;        
	    },
	    refresh : function(callback){
	        if(this.defaultUrl){
	        	this.update(this.defaultUrl, null, callback, true);
	    	}
	    }
    }
}());
pExt.Updater.defaults = {
    timeout : 30,    
    disableCaching : false,
    showLoadIndicator : true,
    indicatorText : '<div class="loading-indicator">Loading...</div>',
    loadScripts : false,
    sslBlankUrl : (pExt.SSL_SECURE_URL || "javascript:false")      
};
pExt.Updater.updateElement = function(el, url, params, options){
    var um = pExt.get(el).getUpdater();
    pExt.apply(um, options);
    um.update(url, params, options ? options.callback : null);
};
pExt.Updater.BasicRenderer = function(){};
pExt.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? pExt.applyIf({
      c: p.c? xf(p.c, currentGroup || "{0}") : p.c
    }, p) : {
        g:0,
        c:null,
        s:pExt.escapeRe(character) 
    }
}
var $f = Date.formatCodeToRegex;
pExt.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,
    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: "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)"
    },
    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, m - 1, d, h, i, s, ms);
        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, pExt.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 = y >= 0? y : pExt.num(def.y, dt.getFullYear());",
                    "m = m >= 0? m : pExt.num(def.m - 1, dt.getMonth());",
                    "d = d >= 0? d : pExt.num(def.d, dt.getDate());",
                    "h  = h || pExt.num(def.h, dt.getHours());",
                    "i  = i || pExt.num(def.i, dt.getMinutes());",
                    "s  = s || pExt.num(def.s, dt.getSeconds());",
                    "ms = ms || pExt.num(def.ms, dt.getMilliseconds());",
                    "if(z >= 0 && y >= 0){",
                        "v = new Date(y, 0, 1, h, i, s, ms);",
                        "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);",
                    "}",
                "}",
            "}",
            "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));",
                "}",
            "}",
            "return v;"
        ].join('\n');
        return function(format) {
            var regexNum = Date.parseRegexes.length,
                currentGroup = 1,
                calc = [],
                regex = [],
                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;
                    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);
                    }
                }
            }
            Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", "i");
            Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
        }
    }(),
    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 pExt.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 == 12) { h = 0; }\n"
                + "} else { if (h < 12) { h += 12; }}",
            s:"(am|pm)"
        },
        A: {
            g:1,
            c:"if (results[{0}] == 'AM') {\n"
                + "if (h == 12) { h = 0; }\n"
                + "} else { if (h < 12) { h += 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')}
                ];
            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+)" 
        }
    }
});
}());
pExt.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 i = 0,
            num = 0,
            d = this.clone(),
            m = this.getMonth();
        for (i = 0, 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();
    },
    getFirstDateOfMonth : function() {
        return new Date(this.getFullYear(), this.getMonth(), 1);
    },
    getLastDateOfMonth : function() {
        return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
    },
    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];
        }
    }(),
    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";
        }
    },
    clone : function() {
        return new Date(this.getTime());
    },
    isDST : function() {
        return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
    },
    clearTime : function(clone) {
        if (clone) {
            return this.clone().clearTime();
        }
        var d = this.getDate();
        this.setHours(0);
        this.setMinutes(0);
        this.setSeconds(0);
        this.setMilliseconds(0);
        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());
        }
        return this;
    },
    add : function(interval, value) {
        var d = this.clone();
        if (!interval || value === 0) return d;
        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;
    },
    between : function(start, end) {
        var t = this.getTime();
        return start.getTime() <= t && t <= end.getTime();
    }
});
Date.prototype.format = Date.prototype.dateFormat;
if (pExt.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
    pExt.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);
            }
        },
        setDate : function(d) {
            return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
        }
    });
}
pExt.util.DelayedTask = function(fn, scope, args){
    var me = this,
    	id,    	
    	call = function(){
    		clearInterval(id);
	        id = null;
	        fn.apply(scope, args || []);
	    };
    me.delay = function(delay, newFn, newScope, newArgs){
        me.cancel();
        fn = newFn || fn;
        scope = newScope || scope;
        args = newArgs || args;
        id = setInterval(call, delay);
    };
    me.cancel = function(){
        if(id){
            clearInterval(id);
            id = null;
        }
    };
};
pExt.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;
    }
    pExt.util.MixedCollection.superclass.constructor.call(this);
};
pExt.extend(pExt.util.MixedCollection, pExt.util.Observable, {
    allowFunctions : false,
    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;
    },
    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;
    },
    addAll : function(objs){
        if(arguments.length > 1 || pExt.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]);
                }
            }
        }
    },
    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;
            }
        }
    },
    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;
    },
    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;
    },
    removeKey : function(key){
        return this.removeAt(this.indexOfKey(key));
    },
    getCount : function(){
        return this.length;
    },
    indexOf : function(o){
        return this.items.indexOf(o);
    },
    indexOfKey : function(key){
        return this.keys.indexOf(key);
    },
    item : function(key){
        var mk = this.map[key],
            item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
        return !pExt.isFunction(item) || this.allowFunctions ? item : null; 
    },
    itemAt : function(index){
        return this.items[index];
    },
    key : function(key){
        return this.map[key];
    },
    contains : function(o){
        return this.indexOf(o) != -1;
    },
    containsKey : function(key){
        return typeof this.map[key] != "undefined";
    },
    clear : function(){
        this.length = 0;
        this.items = [];
        this.keys = [];
        this.map = {};
        this.fireEvent("clear");
    },
    first : function(){
        return this.items[0];
    },
    last : function(){
        return this.items[this.length-1];
    },
    _sort : function(property, dir, fn){
        var i,
            len,
            dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1,
            c = [], k = this.keys, items = this.items;
        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);
            }
            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);
    },
    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);
        });
    },
    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;
    },
    filter : function(property, value, anyMatch, caseSensitive){
        if(pExt.isEmpty(value, false)){
            return this.clone();
        }
        value = this.createValueMatcher(value, anyMatch, caseSensitive);
        return this.filterBy(function(o){
            return o && value.test(o[property]);
        });
    },
    filterBy : function(fn, scope){
        var r = new pExt.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;
    },
    findIndex : function(property, value, start, anyMatch, caseSensitive){
        if(pExt.isEmpty(value, false)){
            return -1;
        }
        value = this.createValueMatcher(value, anyMatch, caseSensitive);
        return this.findIndexBy(function(o){
            return o && value.test(o[property]);
        }, null, start);
    },
    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;
    },
    createValueMatcher : function(value, anyMatch, caseSensitive){
        if(!value.exec){ 
            value = String(value);
            value = new RegExp((anyMatch === true ? '' : '^') + pExt.escapeRe(value), caseSensitive ? '' : 'i');
        }
        return value;
    },
    clone : function(){
        var r = new pExt.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;
    }
});
pExt.util.MixedCollection.prototype.get = pExt.util.MixedCollection.prototype.item;
pExt.ComponentMgr = function(){
    var all = new pExt.util.MixedCollection();
    var types = {};
    var ptypes = {};
    return {
        register : function(c){
            all.add(c);
        },
        unregister : function(c){
            all.remove(c);
        },
        get : function(id){
            return all.get(id);
        },
        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);
                }
            });
        },
        all : all,
        isRegistered : function(xtype){
            return types[xtype] !== undefined;    
        },
        registerType : function(xtype, cls){
            types[xtype] = cls;
            cls.xtype = xtype;
        },
        create : function(config, defaultType){
            return config.render ? config : new types[config.xtype || defaultType](config);
        },
        registerPlugin : function(ptype, cls){
            ptypes[ptype] = cls;
            cls.ptype = ptype;
        },
        createPlugin : function(config, defaultType){
            return new ptypes[config.ptype || defaultType](config);
        }
    };
}();
pExt.reg = pExt.ComponentMgr.registerType; 
pExt.preg = pExt.ComponentMgr.registerPlugin;
pExt.create = pExt.ComponentMgr.create;
pExt.util.JSON = new (function(){
    var useHasOwn = !!{}.hasOwnProperty,
        isNative = function() {
            var useNative = null;
            return function() {
                if (useNative === null) {
                    useNative = pExt.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
                }
                return useNative;
            };
        }(),
        pad = function(n) {
            return n < 10 ? "0" + n : n;
        },
        doDecode = function(json){
            return eval("(" + json + ')');    
        },
        doEncode = function(o){
            if(typeof o == "undefined" || o === null){
                return "null";
            }else if(pExt.isArray(o)){
                return encodeArray(o);
            }else if(Object.prototype.toString.apply(o) === '[object Date]'){
                return pExt.util.JSON.encodeDate(o);
            }else if(typeof o == "string"){
                return encodeString(o);
            }else if(typeof o == "number"){
                return isFinite(o) ? String(o) : "null";
            }else if(typeof o == "boolean"){
                return String(o);
            }else {
                var a = ["{"], b, i, v;
                for (i in o) {
                    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 '"' + 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" : pExt.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 ec(o);
        };
    }();
    this.decode = function() {
        var dc;
        return function(json) {
            if (!dc) {
                dc = isNative() ? JSON.parse : doDecode;
            }
            return dc(json);
        };
    }();
})();
pExt.encode = pExt.util.JSON.encode;
pExt.decode = pExt.util.JSON.decode;
pExt.util.Format = function(){
    var trimRe = /^\s+|\s+$/g;
    return {
        ellipsis : function(value, len, word){
            if(value && value.length > len){
                if(word){
                    var vs = value.substr(0, len - 2);
                    var 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();
        },
        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);
            }
        },
        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('.');
            var whole = ps[0];
            var sub = ps[1] ? '.'+ ps[1] : '.00';
            var 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;
        },
        date : function(v, format){
            if(!v){
                return "";
            }
            if(!pExt.isDate(v)){
                v = new Date(Date.parse(v));
            }
            return v.dateFormat(format || "m/d/Y");
        },
        dateRenderer : function(format){
            return function(v){
                return pExt.util.Format.date(v, format);
            };
        },
        stripTagsRE : /<\/?[^>]+>/gi,
        stripTags : function(v){
            return !v ? v : String(v).replace(this.stripTagsRE, "");
        },
        stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
        stripScripts : function(v){
            return !v ? v : String(v).replace(this.stripScriptsRe, "");
        },
        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";
            }
        },
        math : function(){
            var fns = {};
            return function(v, a){
                if(!fns[a]){
                    fns[a] = new Function('v', 'return v ' + a + ';');
                }
                return fns[a](v);
            }
        }(),
        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;
        },
        number: function(v, format) {
            if(!format){
		        return v;
		    }
		    v = pExt.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);
        },
        numberRenderer : function(format){
            return function(v){
                return pExt.util.Format.number(v, format);
            };
        },
        plural : function(v, s, p){
            return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
        },
        nl2br : function(v){
            return v === undefined || v === null ? '' : v.replace(/\n/g, '<br/>');
        }
    }
}();
pExt.XTemplate = function(){
    pExt.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('');
    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] : '';
       if (m3) {
           exp = m3 && m3[1] ? m3[1] : null;
           if(exp){
               fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(pExt.util.Format.htmlDecode(exp))+'; }');
           }
       }
       if (m4) {
           exp = m4 && m4[1] ? m4[1] : null;
           if(exp){
               exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(pExt.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;
    }
	pExt.each(tpls, function(t) {
        me.compileTpl(t);
    });
    me.master = tpls[tpls.length-1];
    me.tpls = tpls;
};
pExt.extend(pExt.XTemplate, pExt.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 && pExt.isArray(vs)){
	        pExt.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);
    },
    compileTpl : function(tpl){
        var fm = pExt.util.Format,
       		useF = this.disableFormats !== true,
            sep = pExt.isGecko ? "+" : ",",
            body;
        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+"'";
        }
        function codeFn(m, code){
            return "'"+ sep +'('+code+')'+sep+"'";
        }
        if(pExt.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;
    },
    applyTemplate : function(values){
        return this.master.compiled.call(this, values, {}, 1, 1);
    },
    compile : function(){return this;}
});
pExt.XTemplate.prototype.apply = pExt.XTemplate.prototype.applyTemplate;
pExt.XTemplate.from = function(el){
    el = pExt.getDom(el);
    return new pExt.XTemplate(el.value || el.innerHTML);
};
pExt.util.CSS = function(){
	var rules = null;
   	var doc = document;
    var camelRe = /(-[a-z])/gi;
    var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
   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(pExt.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);
       }
   },
   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] = 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(!pExt.isArray(selector)){
   		    return rs[selector];
   		}
   		for(var i = 0; i < selector.length; i++){
			if(rs[selector[i]]){
				return rs[selector[i]];
			}
		}
		return null;
   	},
   updateRule : function(selector, property, value){
   		if(!pExt.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;
   	}
   };	
}();
pExt.util.ClickRepeater = function(el, config)
{
    this.el = pExt.get(el);
    this.el.unselectable();
    pExt.apply(this, config);
    this.addEvents(
        "mousedown",
        "click",
        "mouseup"
    );
    if(!this.disabled){
        this.disabled = true;
        this.enable();
    }
    if(this.handler){
        this.on("click", this.handler,  this.scope || this);
    }
    pExt.util.ClickRepeater.superclass.constructor.call(this);
};
pExt.extend(pExt.util.ClickRepeater, pExt.util.Observable, {
    interval : 20,
    delay: 250,
    preventDefault : true,
    stopDefault : false,
    timer : 0,
    enable: function(){
        if(this.disabled){
            this.el.on('mousedown', this.handleMouseDown, this);
            if(this.preventDefault || this.stopDefault){
                this.el.on('click', this.eventOptions, this);
            }
        }
        this.disabled = false;
    },
    disable: function(  force){
        if(force || !this.disabled){
            clearTimeout(this.timer);
            if(this.pressClass){
                this.el.removeClass(this.pressClass);
            }
            pExt.getDoc().un('mouseup', this.handleMouseUp, this);
            this.el.removeAllListeners();
        }
        this.disabled = true;
    },
    setDisabled: function(disabled){
        this[disabled ? 'disable' : 'enable']();    
    },
    eventOptions: function(e){
        if(this.preventDefault){
            e.preventDefault();
        }
        if(this.stopDefault){
            e.stopEvent();
        }       
    },
    destroy : function() {
        this.disable(true);
        pExt.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();
        pExt.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);
    },
    easeOutExpo : function (t, b, c, d) {
        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
    },
    handleMouseOut : function(){
        clearTimeout(this.timer);
        if(this.pressClass){
            this.el.removeClass(this.pressClass);
        }
        this.el.on("mouseover", this.handleMouseReturn, this);
    },
    handleMouseReturn : function(){
        this.el.un("mouseover", this.handleMouseReturn, this);
        if(this.pressClass){
            this.el.addClass(this.pressClass);
        }
        this.click();
    },
    handleMouseUp : function(){
        clearTimeout(this.timer);
        this.el.un("mouseover", this.handleMouseReturn, this);
        this.el.un("mouseout", this.handleMouseOut, this);
        pExt.getDoc().un("mouseup", this.handleMouseUp, this);
        this.el.removeClass(this.pressClass);
        this.fireEvent("mouseup", this);
    }
});
pExt.KeyNav = function(el, config){
    this.el = pExt.get(el);
    pExt.apply(this, config);
    if(!this.disabled){
        this.disabled = true;
        this.enable();
    }
};
pExt.KeyNav.prototype = {
    disabled : false,
    defaultEventAction: "stopEvent",
    forceKeyDown : false,
    prepareEvent : function(e){
        var k = e.getKey();
        var h = this.keyToHandler[k];
        if(pExt.isSafari2 && h && k >= 37 && k <= 40){
            e.stopEvent();
        }
    },
    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]();
            }
        }
    },
    doRelay : function(e, h, hname){
        return h.call(this.scope || this, e);
    },
    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"
    },
	enable: function(){
		if(this.disabled){
            if(this.isKeydown()){
                this.el.on("keydown", this.relay,  this);
            }else{
                this.el.on("keydown", this.prepareEvent,  this);
                this.el.on("keypress", this.relay,  this);
            }
		    this.disabled = false;
		}
	},
	disable: function(){
		if(!this.disabled){
		    if(this.isKeydown()){
                this.el.un("keydown", this.relay, this);
            }else{
                this.el.un("keydown", this.prepareEvent, this);
                this.el.un("keypress", this.relay, this);
            }
		    this.disabled = true;
		}
	},
    setDisabled : function(disabled){
        this[disabled ? "disable" : "enable"]();
    },
    isKeydown: function(){
        return this.forceKeyDown || pExt.EventManager.useKeydown;
    }
};
pExt.KeyMap = function(el, config, eventName){
    this.el  = pExt.get(el);
    this.eventName = eventName || "keydown";
    this.bindings = [];
    if(config){
        this.addBinding(config);
    }
    this.enable();
};
pExt.KeyMap.prototype = {
    stopEvent : false,
	addBinding : function(config){
        if(pExt.isArray(config)){
            pExt.each(config, function(c){
                this.addBinding(c);
            }, this);
            return;
        }
        var keyCode = config.key,
            fn = config.fn || config.handler,
            scope = config.scope;
	if (config.stopEvent) {
	    this.stopEvent = config.stopEvent;    
	}	
        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 = pExt.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);
                    }
                }
            }
        };
        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" && !pExt.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);
    	    }
	    }
	},
	isEnabled : function(){
	    return this.enabled;
	},
	enable: function(){
		if(!this.enabled){
		    this.el.on(this.eventName, this.handleKeyDown, this);
		    this.enabled = true;
		}
	},
	disable: function(){
		if(this.enabled){
		    this.el.removeListener(this.eventName, this.handleKeyDown, this);
		    this.enabled = false;
		}
	},
    setDisabled : function(disabled){
        this[disabled ? "disable" : "enable"]();
    }
};
pExt.util.TextMetrics = function(){
    var shared;
    return {
        measure : function(el, text, fixedWidth){
            if(!shared){
                shared = pExt.util.TextMetrics.Instance(el, fixedWidth);
            }
            shared.bind(el);
            shared.setFixedWidth(fixedWidth || 'auto');
            return shared.getSize(text);
        },
        createInstance : function(el, fixedWidth){
            return pExt.util.TextMetrics.Instance(el, fixedWidth);
        }
    };
}();
pExt.util.TextMetrics.Instance = function(bindTo, fixedWidth){
    var ml = new pExt.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(
                pExt.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;
        }
    };
    instance.bind(bindTo);
    return instance;
};
pExt.Element.addMethods({
    getTextWidth : function(text, min, max){
        return (pExt.util.TextMetrics.measure(this.dom, pExt.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
    }
});
(function() {
var Event=pExt.EventManager;
var Dom=pExt.lib.Dom;
pExt.dd.DragDrop = function(id, sGroup, config) {
    if(id) {
        this.init(id, sGroup, config);
    }
};
pExt.dd.DragDrop.prototype = {
    id: null,
    config: null,
    dragElId: null,
    handleElId: null,
    invalidHandleTypes: null,
    invalidHandleIds: null,
    invalidHandleClasses: null,
    startPageX: 0,
    startPageY: 0,
    groups: null,
    locked: false,
    lock: function() { this.locked = true; },
    moveOnly: false,
    unlock: function() { this.locked = false; },
    isTarget: true,
    padding: null,
    _domRef: null,
    __ygDragDrop: true,
    constrainX: false,
    constrainY: false,
    minX: 0,
    maxX: 0,
    minY: 0,
    maxY: 0,
    maintainOffset: false,
    xTicks: null,
    yTicks: null,
    primaryButtonOnly: true,
    available: false,
    hasOuterHandles: false,
    b4StartDrag: function(x, y) { },
    startDrag: function(x, y) {   },
    b4Drag: function(e) { },
    onDrag: function(e) {   },
    onDragEnter: function(e, id) {   },
    b4DragOver: function(e) { },
    onDragOver: function(e, id) {   },
    b4DragOut: function(e) { },
    onDragOut: function(e, id) {   },
    b4DragDrop: function(e) { },
    onDragDrop: function(e, id) {   },
    onInvalidDrop: function(e) {   },
    b4EndDrag: function(e) { },
    endDrag: function(e) {   },
    b4MouseDown: function(e) {  },
    onMouseDown: function(e) {   },
    onMouseUp: function(e) {   },
    onAvailable: function () {
    },
    defaultPadding : {left:0, right:0, top:0, bottom:0},
    constrainTo : function(constrainTo, pad, inContent){
        if(typeof pad == "number"){
            pad = {left: pad, right:pad, top:pad, bottom:pad};
        }
        pad = pad || this.defaultPadding;
        var b = pExt.get(this.getEl()).getBox();
        var ce = pExt.get(constrainTo);
        var s = ce.getScroll();
        var c, cd = ce.dom;
        if(cd == document.body){
            c = { x: s.left, y: s.top, width: pExt.lib.Dom.getViewWidth(), height: pExt.lib.Dom.getViewHeight()};
        }else{
            var xy = ce.getXY();
            c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};
        }
        var topSpace = b.y - c.y;
        var leftSpace = b.x - c.x;
        this.resetConstraints();
        this.setXConstraint(leftSpace - (pad.left||0), 
                c.width - leftSpace - b.width - (pad.right||0), 
				this.xTickSize
        );
        this.setYConstraint(topSpace - (pad.top||0), 
                c.height - topSpace - b.height - (pad.bottom||0), 
				this.yTickSize
        );
    },
    getEl: function() {
        if (!this._domRef) {
            this._domRef = pExt.getDom(this.id);
        }
        return this._domRef;
    },
    getDragEl: function() {
        return pExt.getDom(this.dragElId);
    },
    init: function(id, sGroup, config) {
        this.initTarget(id, sGroup, config);
        Event.on(this.id, "mousedown", this.handleMouseDown, this);
    },
    initTarget: function(id, sGroup, config) {
        this.config = config || {};
        this.DDM = pExt.dd.DDM;
        this.groups = {};
        if (typeof id !== "string") {
            id = pExt.id(id);
        }
        this.id = id;
        this.addToGroup((sGroup) ? sGroup : "default");
        this.handleElId = id;
        this.setDragElId(id);
        this.invalidHandleTypes = { A: "A" };
        this.invalidHandleIds = {};
        this.invalidHandleClasses = [];
        this.applyConfig();
        this.handleOnAvailable();
    },
    applyConfig: function() {
        this.padding           = this.config.padding || [0, 0, 0, 0];
        this.isTarget          = (this.config.isTarget !== false);
        this.maintainOffset    = (this.config.maintainOffset);
        this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
    },
    handleOnAvailable: function() {
        this.available = true;
        this.resetConstraints();
        this.onAvailable();
    },
    setPadding: function(iTop, iRight, iBot, iLeft) {
        if (!iRight && 0 !== iRight) {
            this.padding = [iTop, iTop, iTop, iTop];
        } else if (!iBot && 0 !== iBot) {
            this.padding = [iTop, iRight, iTop, iRight];
        } else {
            this.padding = [iTop, iRight, iBot, iLeft];
        }
    },
    setInitPosition: function(diffX, diffY) {
        var el = this.getEl();
        if (!this.DDM.verifyEl(el)) {
            return;
        }
        var dx = diffX || 0;
        var dy = diffY || 0;
        var p = Dom.getXY( el );
        this.initPageX = p[0] - dx;
        this.initPageY = p[1] - dy;
        this.lastPageX = p[0];
        this.lastPageY = p[1];
        this.setStartPosition(p);
    },
    setStartPosition: function(pos) {
        var p = pos || Dom.getXY( this.getEl() );
        this.deltaSetXY = null;
        this.startPageX = p[0];
        this.startPageY = p[1];
    },
    addToGroup: function(sGroup) {
        this.groups[sGroup] = true;
        this.DDM.regDragDrop(this, sGroup);
    },
    removeFromGroup: function(sGroup) {
        if (this.groups[sGroup]) {
            delete this.groups[sGroup];
        }
        this.DDM.removeDDFromGroup(this, sGroup);
    },
    setDragElId: function(id) {
        this.dragElId = id;
    },
    setHandleElId: function(id) {
        if (typeof id !== "string") {
            id = pExt.id(id);
        }
        this.handleElId = id;
        this.DDM.regHandle(this.id, id);
    },
    setOuterHandleElId: function(id) {
        if (typeof id !== "string") {
            id = pExt.id(id);
        }
        Event.on(id, "mousedown",
                this.handleMouseDown, this);
        this.setHandleElId(id);
        this.hasOuterHandles = true;
    },
    unreg: function() {
        Event.un(this.id, "mousedown",
                this.handleMouseDown);
        this._domRef = null;
        this.DDM._remove(this);
    },
    destroy : function(){
        this.unreg();
    },
    isLocked: function() {
        return (this.DDM.isLocked() || this.locked);
    },
    handleMouseDown: function(e, oDD){
        if (this.primaryButtonOnly && e.button != 0) {
            return;
        }
        if (this.isLocked()) {
            return;
        }
        this.DDM.refreshCache(this.groups);
        var pt = new pExt.lib.Point(pExt.lib.Event.getPageX(e), pExt.lib.Event.getPageY(e));
        if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) )  {
        } else {
            if (this.clickValidator(e)) {
                this.setStartPosition();
                this.b4MouseDown(e);
                this.onMouseDown(e);
                this.DDM.handleMouseDown(e, this);
                this.DDM.stopEvent(e);
            } else {
            }
        }
    },
    clickValidator: function(e) {
        var target = e.getTarget();
        return ( this.isValidHandleChild(target) &&
                    (this.id == this.handleElId ||
                        this.DDM.handleWasClicked(target, this.id)) );
    },
    addInvalidHandleType: function(tagName) {
        var type = tagName.toUpperCase();
        this.invalidHandleTypes[type] = type;
    },
    addInvalidHandleId: function(id) {
        if (typeof id !== "string") {
            id = pExt.id(id);
        }
        this.invalidHandleIds[id] = id;
    },
    addInvalidHandleClass: function(cssClass) {
        this.invalidHandleClasses.push(cssClass);
    },
    removeInvalidHandleType: function(tagName) {
        var type = tagName.toUpperCase();
        delete this.invalidHandleTypes[type];
    },
    removeInvalidHandleId: function(id) {
        if (typeof id !== "string") {
            id = pExt.id(id);
        }
        delete this.invalidHandleIds[id];
    },
    removeInvalidHandleClass: function(cssClass) {
        for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
            if (this.invalidHandleClasses[i] == cssClass) {
                delete this.invalidHandleClasses[i];
            }
        }
    },
    isValidHandleChild: function(node) {
        var valid = true;
        var nodeName;
        try {
            nodeName = node.nodeName.toUpperCase();
        } catch(e) {
            nodeName = node.nodeName;
        }
        valid = valid && !this.invalidHandleTypes[nodeName];
        valid = valid && !this.invalidHandleIds[node.id];
        for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
            valid = !pExt.fly(node).hasClass(this.invalidHandleClasses[i]);
        }
        return valid;
    },
    setXTicks: function(iStartX, iTickSize) {
        this.xTicks = [];
        this.xTickSize = iTickSize;
        var tickMap = {};
        for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
            if (!tickMap[i]) {
                this.xTicks[this.xTicks.length] = i;
                tickMap[i] = true;
            }
        }
        for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
            if (!tickMap[i]) {
                this.xTicks[this.xTicks.length] = i;
                tickMap[i] = true;
            }
        }
        this.xTicks.sort(this.DDM.numericSort) ;
    },
    setYTicks: function(iStartY, iTickSize) {
        this.yTicks = [];
        this.yTickSize = iTickSize;
        var tickMap = {};
        for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
            if (!tickMap[i]) {
                this.yTicks[this.yTicks.length] = i;
                tickMap[i] = true;
            }
        }
        for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
            if (!tickMap[i]) {
                this.yTicks[this.yTicks.length] = i;
                tickMap[i] = true;
            }
        }
        this.yTicks.sort(this.DDM.numericSort) ;
    },
    setXConstraint: function(iLeft, iRight, iTickSize) {
        this.leftConstraint = iLeft;
        this.rightConstraint = iRight;
        this.minX = this.initPageX - iLeft;
        this.maxX = this.initPageX + iRight;
        if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
        this.constrainX = true;
    },
    clearConstraints: function() {
        this.constrainX = false;
        this.constrainY = false;
        this.clearTicks();
    },
    clearTicks: function() {
        this.xTicks = null;
        this.yTicks = null;
        this.xTickSize = 0;
        this.yTickSize = 0;
    },
    setYConstraint: function(iUp, iDown, iTickSize) {
        this.topConstraint = iUp;
        this.bottomConstraint = iDown;
        this.minY = this.initPageY - iUp;
        this.maxY = this.initPageY + iDown;
        if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
        this.constrainY = true;
    },
    resetConstraints: function() {
        if (this.initPageX || this.initPageX === 0) {
            var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
            var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
            this.setInitPosition(dx, dy);
        } else {
            this.setInitPosition();
        }
        if (this.constrainX) {
            this.setXConstraint( this.leftConstraint,
                                 this.rightConstraint,
                                 this.xTickSize        );
        }
        if (this.constrainY) {
            this.setYConstraint( this.topConstraint,
                                 this.bottomConstraint,
                                 this.yTickSize         );
        }
    },
    getTick: function(val, tickArray) {
        if (!tickArray) {
            return val;
        } else if (tickArray[0] >= val) {
            return tickArray[0];
        } else {
            for (var i=0, len=tickArray.length; i<len; ++i) {
                var next = i + 1;
                if (tickArray[next] && tickArray[next] >= val) {
                    var diff1 = val - tickArray[i];
                    var diff2 = tickArray[next] - val;
                    return (diff2 > diff1) ? tickArray[i] : tickArray[next];
                }
            }
            return tickArray[tickArray.length - 1];
        }
    },
    toString: function() {
        return ("DragDrop " + this.id);
    }
};
})();
if (!pExt.dd.DragDropMgr) {
pExt.dd.DragDropMgr = function() {
    var Event = pExt.EventManager;
    return {
        ids: {},
        handleIds: {},
        dragCurrent: null,
        dragOvers: {},
        deltaX: 0,
        deltaY: 0,
        preventDefault: true,
        stopPropagation: true,
        initialized: false,
        locked: false,
        init: function() {
            this.initialized = true;
        },
        POINT: 0,
        INTERSECT: 1,
        mode: 0,
        _execOnAll: function(sMethod, args) {
            for (var i in this.ids) {
                for (var j in this.ids[i]) {
                    var oDD = this.ids[i][j];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }
                    oDD[sMethod].apply(oDD, args);
                }
            }
        },
        _onLoad: function() {
            this.init();
            Event.on(document, "mouseup",   this.handleMouseUp, this, true);
            Event.on(document, "mousemove", this.handleMouseMove, this, true);
            Event.on(window,   "unload",    this._onUnload, this, true);
            Event.on(window,   "resize",    this._onResize, this, true);
        },
        _onResize: function(e) {
            this._execOnAll("resetConstraints", []);
        },
        lock: function() { this.locked = true; },
        unlock: function() { this.locked = false; },
        isLocked: function() { return this.locked; },
        locationCache: {},
        useCache: true,
        clickPixelThresh: 3,
        clickTimeThresh: 350,
        dragThreshMet: false,
        clickTimeout: null,
        startX: 0,
        startY: 0,
        regDragDrop: function(oDD, sGroup) {
            if (!this.initialized) { this.init(); }
            if (!this.ids[sGroup]) {
                this.ids[sGroup] = {};
            }
            this.ids[sGroup][oDD.id] = oDD;
        },
        removeDDFromGroup: function(oDD, sGroup) {
            if (!this.ids[sGroup]) {
                this.ids[sGroup] = {};
            }
            var obj = this.ids[sGroup];
            if (obj && obj[oDD.id]) {
                delete obj[oDD.id];
            }
        },
        _remove: function(oDD) {
            for (var g in oDD.groups) {
                if (g && this.ids[g] && this.ids[g][oDD.id]) {
                    delete this.ids[g][oDD.id];
                }
            }
            delete this.handleIds[oDD.id];
        },
        regHandle: function(sDDId, sHandleId) {
            if (!this.handleIds[sDDId]) {
                this.handleIds[sDDId] = {};
            }
            this.handleIds[sDDId][sHandleId] = sHandleId;
        },
        isDragDrop: function(id) {
            return ( this.getDDById(id) ) ? true : false;
        },
        getRelated: function(p_oDD, bTargetsOnly) {
            var oDDs = [];
            for (var i in p_oDD.groups) {
                for (var j in this.ids[i]) {
                    var dd = this.ids[i][j];
                    if (! this.isTypeOfDD(dd)) {
                        continue;
                    }
                    if (!bTargetsOnly || dd.isTarget) {
                        oDDs[oDDs.length] = dd;
                    }
                }
            }
            return oDDs;
        },
        isLegalTarget: function (oDD, oTargetDD) {
            var targets = this.getRelated(oDD, true);
            for (var i=0, len=targets.length;i<len;++i) {
                if (targets[i].id == oTargetDD.id) {
                    return true;
                }
            }
            return false;
        },
        isTypeOfDD: function (oDD) {
            return (oDD && oDD.__ygDragDrop);
        },
        isHandle: function(sDDId, sHandleId) {
            return ( this.handleIds[sDDId] &&
                            this.handleIds[sDDId][sHandleId] );
        },
        getDDById: function(id) {
            for (var i in this.ids) {
                if (this.ids[i][id]) {
                    return this.ids[i][id];
                }
            }
            return null;
        },
        handleMouseDown: function(e, oDD) {
            if(pExt.QuickTips){
                pExt.QuickTips.disable();
            }
            if(this.dragCurrent){
                this.handleMouseUp(e);
            }
            this.currentTarget = e.getTarget();
            this.dragCurrent = oDD;
            var el = oDD.getEl();
            this.startX = e.getPageX();
            this.startY = e.getPageY();
            this.deltaX = this.startX - el.offsetLeft;
            this.deltaY = this.startY - el.offsetTop;
            this.dragThreshMet = false;
            this.clickTimeout = setTimeout(
                    function() {
                        var DDM = pExt.dd.DDM;
                        DDM.startDrag(DDM.startX, DDM.startY);
                    },
                    this.clickTimeThresh );
        },
        startDrag: function(x, y) {
            clearTimeout(this.clickTimeout);
            if (this.dragCurrent) {
                this.dragCurrent.b4StartDrag(x, y);
                this.dragCurrent.startDrag(x, y);
            }
            this.dragThreshMet = true;
        },
        handleMouseUp: function(e) {
            if(pExt.QuickTips){
                pExt.QuickTips.enable();
            }
            if (! this.dragCurrent) {
                return;
            }
            clearTimeout(this.clickTimeout);
            if (this.dragThreshMet) {
                this.fireEvents(e, true);
            } else {
            }
            this.stopDrag(e);
            this.stopEvent(e);
        },
        stopEvent: function(e){
            if(this.stopPropagation) {
                e.stopPropagation();
            }
            if (this.preventDefault) {
                e.preventDefault();
            }
        },
        stopDrag: function(e) {
            if (this.dragCurrent) {
                if (this.dragThreshMet) {
                    this.dragCurrent.b4EndDrag(e);
                    this.dragCurrent.endDrag(e);
                }
                this.dragCurrent.onMouseUp(e);
            }
            this.dragCurrent = null;
            this.dragOvers = {};
        },
        handleMouseMove: function(e) {
            if (! this.dragCurrent) {
                return true;
            }
            if (pExt.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
                this.stopEvent(e);
                return this.handleMouseUp(e);
            }
            if (!this.dragThreshMet) {
                var diffX = Math.abs(this.startX - e.getPageX());
                var diffY = Math.abs(this.startY - e.getPageY());
                if (diffX > this.clickPixelThresh ||
                            diffY > this.clickPixelThresh) {
                    this.startDrag(this.startX, this.startY);
                }
            }
            if (this.dragThreshMet) {
                this.dragCurrent.b4Drag(e);
                this.dragCurrent.onDrag(e);
                if(!this.dragCurrent.moveOnly){
                    this.fireEvents(e, false);
                }
            }
            this.stopEvent(e);
            return true;
        },
        fireEvents: function(e, isDrop) {
            var dc = this.dragCurrent;
            if (!dc || dc.isLocked()) {
                return;
            }
            var pt = e.getPoint();
            var oldOvers = [];
            var outEvts   = [];
            var overEvts  = [];
            var dropEvts  = [];
            var enterEvts = [];
            for (var i in this.dragOvers) {
                var ddo = this.dragOvers[i];
                if (! this.isTypeOfDD(ddo)) {
                    continue;
                }
                if (! this.isOverTarget(pt, ddo, this.mode)) {
                    outEvts.push( ddo );
                }
                oldOvers[i] = true;
                delete this.dragOvers[i];
            }
            for (var sGroup in dc.groups) {
                if ("string" != typeof sGroup) {
                    continue;
                }
                for (i in this.ids[sGroup]) {
                    var oDD = this.ids[sGroup][i];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }
                    if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
                        if (this.isOverTarget(pt, oDD, this.mode)) {
                            if (isDrop) {
                                dropEvts.push( oDD );
                            } else {
                                if (!oldOvers[oDD.id]) {
                                    enterEvts.push( oDD );
                                } else {
                                    overEvts.push( oDD );
                                }
                                this.dragOvers[oDD.id] = oDD;
                            }
                        }
                    }
                }
            }
            if (this.mode) {
                if (outEvts.length) {
                    dc.b4DragOut(e, outEvts);
                    dc.onDragOut(e, outEvts);
                }
                if (enterEvts.length) {
                    dc.onDragEnter(e, enterEvts);
                }
                if (overEvts.length) {
                    dc.b4DragOver(e, overEvts);
                    dc.onDragOver(e, overEvts);
                }
                if (dropEvts.length) {
                    dc.b4DragDrop(e, dropEvts);
                    dc.onDragDrop(e, dropEvts);
                }
            } else {
                var len = 0;
                for (i=0, len=outEvts.length; i<len; ++i) {
                    dc.b4DragOut(e, outEvts[i].id);
                    dc.onDragOut(e, outEvts[i].id);
                }
                for (i=0,len=enterEvts.length; i<len; ++i) {
                    dc.onDragEnter(e, enterEvts[i].id);
                }
                for (i=0,len=overEvts.length; i<len; ++i) {
                    dc.b4DragOver(e, overEvts[i].id);
                    dc.onDragOver(e, overEvts[i].id);
                }
                for (i=0, len=dropEvts.length; i<len; ++i) {
                    dc.b4DragDrop(e, dropEvts[i].id);
                    dc.onDragDrop(e, dropEvts[i].id);
                }
            }
            if (isDrop && !dropEvts.length) {
                dc.onInvalidDrop(e);
            }
        },
        getBestMatch: function(dds) {
            var winner = null;
            var len = dds.length;
            if (len == 1) {
                winner = dds[0];
            } else {
                for (var i=0; i<len; ++i) {
                    var dd = dds[i];
                    if (dd.cursorIsOver) {
                        winner = dd;
                        break;
                    } else {
                        if (!winner ||
                            winner.overlap.getArea() < dd.overlap.getArea()) {
                            winner = dd;
                        }
                    }
                }
            }
            return winner;
        },
        refreshCache: function(groups) {
            for (var sGroup in groups) {
                if ("string" != typeof sGroup) {
                    continue;
                }
                for (var i in this.ids[sGroup]) {
                    var oDD = this.ids[sGroup][i];
                    if (this.isTypeOfDD(oDD)) {
                        var loc = this.getLocation(oDD);
                        if (loc) {
                            this.locationCache[oDD.id] = loc;
                        } else {
                            delete this.locationCache[oDD.id];
                        }
                    }
                }
            }
        },
        verifyEl: function(el) {
            if (el) {
                var parent;
                if(pExt.isIE){
                    try{
                        parent = el.offsetParent;
                    }catch(e){}
                }else{
                    parent = el.offsetParent;
                }
                if (parent) {
                    return true;
                }
            }
            return false;
        },
        getLocation: function(oDD) {
            if (! this.isTypeOfDD(oDD)) {
                return null;
            }
            var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
            try {
                pos= pExt.lib.Dom.getXY(el);
            } catch (e) { }
            if (!pos) {
                return null;
            }
            x1 = pos[0];
            x2 = x1 + el.offsetWidth;
            y1 = pos[1];
            y2 = y1 + el.offsetHeight;
            t = y1 - oDD.padding[0];
            r = x2 + oDD.padding[1];
            b = y2 + oDD.padding[2];
            l = x1 - oDD.padding[3];
            return new pExt.lib.Region( t, r, b, l );
        },
        isOverTarget: function(pt, oTarget, intersect) {
            var loc = this.locationCache[oTarget.id];
            if (!loc || !this.useCache) {
                loc = this.getLocation(oTarget);
                this.locationCache[oTarget.id] = loc;
            }
            if (!loc) {
                return false;
            }
            oTarget.cursorIsOver = loc.contains( pt );
            var dc = this.dragCurrent;
            if (!dc || !dc.getTargetCoord ||
                    (!intersect && !dc.constrainX && !dc.constrainY)) {
                return oTarget.cursorIsOver;
            }
            oTarget.overlap = null;
            var pos = dc.getTargetCoord(pt.x, pt.y);
            var el = dc.getDragEl();
            var curRegion = new pExt.lib.Region( pos.y,
                                                   pos.x + el.offsetWidth,
                                                   pos.y + el.offsetHeight,
                                                   pos.x );
            var overlap = curRegion.intersect(loc);
            if (overlap) {
                oTarget.overlap = overlap;
                return (intersect) ? true : oTarget.cursorIsOver;
            } else {
                return false;
            }
        },
        _onUnload: function(e, me) {
            pExt.dd.DragDropMgr.unregAll();
        },
        unregAll: function() {
            if (this.dragCurrent) {
                this.stopDrag();
                this.dragCurrent = null;
            }
            this._execOnAll("unreg", []);
            for (var i in this.elementCache) {
                delete this.elementCache[i];
            }
            this.elementCache = {};
            this.ids = {};
        },
        elementCache: {},
        getElWrapper: function(id) {
            var oWrapper = this.elementCache[id];
            if (!oWrapper || !oWrapper.el) {
                oWrapper = this.elementCache[id] =
                    new this.ElementWrapper(pExt.getDom(id));
            }
            return oWrapper;
        },
        getElement: function(id) {
            return pExt.getDom(id);
        },
        getCss: function(id) {
            var el = pExt.getDom(id);
            return (el) ? el.style : null;
        },
        ElementWrapper: function(el) {
                this.el = el || null;
                this.id = this.el && el.id;
                this.css = this.el && el.style;
            },
        getPosX: function(el) {
            return pExt.lib.Dom.getX(el);
        },
        getPosY: function(el) {
            return pExt.lib.Dom.getY(el);
        },
        swapNode: function(n1, n2) {
            if (n1.swapNode) {
                n1.swapNode(n2);
            } else {
                var p = n2.parentNode;
                var s = n2.nextSibling;
                if (s == n1) {
                    p.insertBefore(n1, n2);
                } else if (n2 == n1.nextSibling) {
                    p.insertBefore(n2, n1);
                } else {
                    n1.parentNode.replaceChild(n2, n1);
                    p.insertBefore(n1, s);
                }
            }
        },
        getScroll: function () {
            var t, l, dde=document.documentElement, db=document.body;
            if (dde && (dde.scrollTop || dde.scrollLeft)) {
                t = dde.scrollTop;
                l = dde.scrollLeft;
            } else if (db) {
                t = db.scrollTop;
                l = db.scrollLeft;
            } else {
            }
            return { top: t, left: l };
        },
        getStyle: function(el, styleProp) {
            return pExt.fly(el).getStyle(styleProp);
        },
        getScrollTop: function () { return this.getScroll().top; },
        getScrollLeft: function () { return this.getScroll().left; },
        moveToEl: function (moveEl, targetEl) {
            var aCoord = pExt.lib.Dom.getXY(targetEl);
            pExt.lib.Dom.setXY(moveEl, aCoord);
        },
        numericSort: function(a, b) { return (a - b); },
        _timeoutCount: 0,
        _addListeners: function() {
            var DDM = pExt.dd.DDM;
            if ( pExt.lib.Event && document ) {
                DDM._onLoad();
            } else {
                if (DDM._timeoutCount > 2000) {
                } else {
                    setTimeout(DDM._addListeners, 10);
                    if (document && document.body) {
                        DDM._timeoutCount += 1;
                    }
                }
            }
        },
        handleWasClicked: function(node, id) {
            if (this.isHandle(id, node.id)) {
                return true;
            } else {
                var p = node.parentNode;
                while (p) {
                    if (this.isHandle(id, p.id)) {
                        return true;
                    } else {
                        p = p.parentNode;
                    }
                }
            }
            return false;
        }
    };
}();
pExt.dd.DDM = pExt.dd.DragDropMgr;
pExt.dd.DDM._addListeners();
}
pExt.dd.DD = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config);
    }
};
pExt.extend(pExt.dd.DD, pExt.dd.DragDrop, {
    scroll: true,
    autoOffset: function(iPageX, iPageY) {
        var x = iPageX - this.startPageX;
        var y = iPageY - this.startPageY;
        this.setDelta(x, y);
    },
    setDelta: function(iDeltaX, iDeltaY) {
        this.deltaX = iDeltaX;
        this.deltaY = iDeltaY;
    },
    setDragElPos: function(iPageX, iPageY) {
        var el = this.getDragEl();
        this.alignElWithMouse(el, iPageX, iPageY);
    },
    alignElWithMouse: function(el, iPageX, iPageY) {
        var oCoord = this.getTargetCoord(iPageX, iPageY);
        var fly = el.dom ? el : pExt.fly(el, '_dd');
        if (!this.deltaSetXY) {
            var aCoord = [oCoord.x, oCoord.y];
            fly.setXY(aCoord);
            var newLeft = fly.getLeft(true);
            var newTop  = fly.getTop(true);
            this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
        } else {
            fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
        }
        this.cachePosition(oCoord.x, oCoord.y);
        this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
        return oCoord;
    },
    cachePosition: function(iPageX, iPageY) {
        if (iPageX) {
            this.lastPageX = iPageX;
            this.lastPageY = iPageY;
        } else {
            var aCoord = pExt.lib.Dom.getXY(this.getEl());
            this.lastPageX = aCoord[0];
            this.lastPageY = aCoord[1];
        }
    },
    autoScroll: function(x, y, h, w) {
        if (this.scroll) {
            var clientH = pExt.lib.Dom.getViewHeight();
            var clientW = pExt.lib.Dom.getViewWidth();
            var st = this.DDM.getScrollTop();
            var sl = this.DDM.getScrollLeft();
            var bot = h + y;
            var right = w + x;
            var toBot = (clientH + st - y - this.deltaY);
            var toRight = (clientW + sl - x - this.deltaX);
            var thresh = 40;
            var scrAmt = (document.all) ? 80 : 30;
            if ( bot > clientH && toBot < thresh ) {
                window.scrollTo(sl, st + scrAmt);
            }
            if ( y < st && st > 0 && y - st < thresh ) {
                window.scrollTo(sl, st - scrAmt);
            }
            if ( right > clientW && toRight < thresh ) {
                window.scrollTo(sl + scrAmt, st);
            }
            if ( x < sl && sl > 0 && x - sl < thresh ) {
                window.scrollTo(sl - scrAmt, st);
            }
        }
    },
    getTargetCoord: function(iPageX, iPageY) {
        var x = iPageX - this.deltaX;
        var y = iPageY - this.deltaY;
        if (this.constrainX) {
            if (x < this.minX) { x = this.minX; }
            if (x > this.maxX) { x = this.maxX; }
        }
        if (this.constrainY) {
            if (y < this.minY) { y = this.minY; }
            if (y > this.maxY) { y = this.maxY; }
        }
        x = this.getTick(x, this.xTicks);
        y = this.getTick(y, this.yTicks);
        return {x:x, y:y};
    },
    applyConfig: function() {
        pExt.dd.DD.superclass.applyConfig.call(this);
        this.scroll = (this.config.scroll !== false);
    },
    b4MouseDown: function(e) {
        this.autoOffset(e.getPageX(),
                            e.getPageY());
    },
    b4Drag: function(e) {
        this.setDragElPos(e.getPageX(),
                            e.getPageY());
    },
    toString: function() {
        return ("DD " + this.id);
    }
});
pExt.dd.DDProxy = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config);
        this.initFrame();
    }
};
pExt.dd.DDProxy.dragElId = "ygddfdiv";
pExt.extend(pExt.dd.DDProxy, pExt.dd.DD, {
    resizeFrame: true,
    centerFrame: false,
    createFrame: function() {
        var self = this;
        var body = document.body;
        if (!body || !body.firstChild) {
            setTimeout( function() { self.createFrame(); }, 50 );
            return;
        }
        var div = this.getDragEl();
        if (!div) {
            div    = document.createElement("div");
            div.id = this.dragElId;
            var s  = div.style;
            s.position   = "absolute";
            s.visibility = "hidden";
            s.cursor     = "move";
            s.border     = "2px solid #aaa";
            s.zIndex     = 999;
            body.insertBefore(div, body.firstChild);
        }
    },
    initFrame: function() {
        this.createFrame();
    },
    applyConfig: function() {
        pExt.dd.DDProxy.superclass.applyConfig.call(this);
        this.resizeFrame = (this.config.resizeFrame !== false);
        this.centerFrame = (this.config.centerFrame);
        this.setDragElId(this.config.dragElId || pExt.dd.DDProxy.dragElId);
    },
    showFrame: function(iPageX, iPageY) {
        var el = this.getEl();
        var dragEl = this.getDragEl();
        var s = dragEl.style;
        this._resizeProxy();
        if (this.centerFrame) {
            this.setDelta( Math.round(parseInt(s.width,  10)/2),
                           Math.round(parseInt(s.height, 10)/2) );
        }
        this.setDragElPos(iPageX, iPageY);
        pExt.fly(dragEl).show();
    },
    _resizeProxy: function() {
        if (this.resizeFrame) {
            var el = this.getEl();
            pExt.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
        }
    },
    b4MouseDown: function(e) {
        var x = e.getPageX();
        var y = e.getPageY();
        this.autoOffset(x, y);
        this.setDragElPos(x, y);
    },
    b4StartDrag: function(x, y) {
        this.showFrame(x, y);
    },
    b4EndDrag: function(e) {
        pExt.fly(this.getDragEl()).hide();
    },
    endDrag: function(e) {
        var lel = this.getEl();
        var del = this.getDragEl();
        del.style.visibility = "";
        this.beforeMove();
        lel.style.visibility = "hidden";
        pExt.dd.DDM.moveToEl(lel, del);
        del.style.visibility = "hidden";
        lel.style.visibility = "";
        this.afterDrag();
    },
    beforeMove : function(){
    },
    afterDrag : function(){
    },
    toString: function() {
        return ("DDProxy " + this.id);
    }
});
pExt.dd.DDTarget = function(id, sGroup, config) {
    if (id) {
        this.initTarget(id, sGroup, config);
    }
};
pExt.extend(pExt.dd.DDTarget, pExt.dd.DragDrop, {
    toString: function() {
        return ("DDTarget " + this.id);
    }
});
pExt.dd.DragTracker = function(config){
    pExt.apply(this, config);
    this.addEvents(
        'mousedown',
        'mouseup',
        'mousemove',
        'dragstart',
        'dragend',
        'drag'
    );
    this.dragRegion = new pExt.lib.Region(0,0,0,0);
    if(this.el){
        this.initEl(this.el);
    }
}
pExt.extend(pExt.dd.DragTracker, pExt.util.Observable,  {
    active: false,
    tolerance: 5,
    autoStart: false,
    initEl: function(el){
        this.el = pExt.get(el);
        el.on('mousedown', this.onMouseDown, this,
                this.delegate ? {delegate: this.delegate} : undefined);
    },
    destroy : function(){
        this.el.un('mousedown', this.onMouseDown, this);
    },
    onMouseDown: function(e, target){
        if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
            this.startXY = this.lastXY = e.getXY();
            this.dragTarget = this.delegate ? target : this.el.dom;
            if(this.preventDefault !== false){
                e.preventDefault();
            }
            var doc = pExt.getDoc();
            doc.on('mouseup', this.onMouseUp, this);
            doc.on('mousemove', this.onMouseMove, this);
            doc.on('selectstart', this.stopSelect, this);
            if(this.autoStart){
                this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
            }
        }
    },
    onMouseMove: function(e, target){
        if(this.active && pExt.isIE && !e.browserEvent.button){
            e.preventDefault();
            this.onMouseUp(e);
            return;
        }
        e.preventDefault();
        var xy = e.getXY(), s = this.startXY;
        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();
            }else{
                return;
            }
        }
        this.fireEvent('mousemove', this, e);
        this.onDrag(e);
        this.fireEvent('drag', this, e);
    },
    onMouseUp: function(e){
        var doc = pExt.getDoc();
        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);
        if(wasActive){
            this.onEnd(e);
            this.fireEvent('dragend', this, e);
        }
    },
    triggerStart: function(isTimer){
        this.clearStart();
        this.active = true;
        this.onStart(this.startXY);
        this.fireEvent('dragstart', this, this.startXY);
    },
    clearStart : function(){
        if(this.timer){
            clearTimeout(this.timer);
            delete this.timer;
        }
    },
    stopSelect : function(e){
        e.stopEvent();
        return false;
    },
    onBeforeStart : function(e){
    },
    onStart : function(xy){
    },
    onDrag : function(e){
    },
    onEnd : function(e){
    },
    getDragTarget : function(){
        return this.dragTarget;
    },
    getDragCt : function(){
        return this.el;
    },
    getXY : function(constrain){
        return constrain ?
               this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
    },
    getOffset : function(constrain){
        var xy = this.getXY(constrain);
        var s = this.startXY;
        return [s[0]-xy[0], s[1]-xy[1]];
    },
    constrainModes: {
        'point' : function(xy){
            if(!this.elRegion){
                this.elRegion = this.getDragCt().getRegion();
            }
            var dr = this.dragRegion;
            dr.left = xy[0];
            dr.top = xy[1];
            dr.right = xy[0];
            dr.bottom = xy[1];
            dr.constrainTo(this.elRegion);
            return [dr.left, dr.top];
        }
    }
});
pExt.dd.ScrollManager = function(){
    var ddm = pExt.dd.DragDropMgr;
    var els = {};
    var dragEl = null;
    var proc = {};
    var onStop = function(e){
        dragEl = null;
        clearProc();
    };
    var triggerRefresh = function(){
        if(ddm.dragCurrent){
             ddm.refreshCache(ddm.dragCurrent.groups);
        }
    };
    var doScroll = function(){
        if(ddm.dragCurrent){
            var dds = pExt.dd.ScrollManager;
            var inc = proc.el.ddScrollConfig ?
                      proc.el.ddScrollConfig.increment : dds.increment;
            if(!dds.animate){
                if(proc.el.scroll(proc.dir, inc)){
                    triggerRefresh();
                }
            }else{
                proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
            }
        }
    };
    var clearProc = function(){
        if(proc.id){
            clearInterval(proc.id);
        }
        proc.id = 0;
        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 : pExt.dd.ScrollManager.frequency;
        proc.id = setInterval(doScroll, freq);
    };
    var onFire = function(e, isDrop){
        if(isDrop || !ddm.dragCurrent){ return; }
        var dds = pExt.dd.ScrollManager;
        if(!dragEl || dragEl != ddm.dragCurrent){
            dragEl = ddm.dragCurrent;
            dds.refreshCache();
        }
        var xy = pExt.lib.Event.getXY(e);
        var pt = new pExt.lib.Point(xy[0], xy[1]);
        for(var id in els){
            var el = els[id], r = el._region;
            var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
            if(r && r.contains(pt) && el.isScrollable()){
                if(r.bottom - pt.y <= c.vthresh){
                    if(proc.el != el){
                        startProc(el, "down");
                    }
                    return;
                }else if(r.right - pt.x <= c.hthresh){
                    if(proc.el != el){
                        startProc(el, "left");
                    }
                    return;
                }else if(pt.y - r.top <= c.vthresh){
                    if(proc.el != el){
                        startProc(el, "up");
                    }
                    return;
                }else if(pt.x - r.left <= c.hthresh){
                    if(proc.el != el){
                        startProc(el, "right");
                    }
                    return;
                }
            }
        }
        clearProc();
    };
    ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
    ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
    return {
        register : function(el){
            if(pExt.isArray(el)){
                for(var i = 0, len = el.length; i < len; i++) {
                	this.register(el[i]);
                }
            }else{
                el = pExt.get(el);
                els[el.id] = el;
            }
        },
        unregister : function(el){
            if(pExt.isArray(el)){
                for(var i = 0, len = el.length; i < len; i++) {
                	this.unregister(el[i]);
                }
            }else{
                el = pExt.get(el);
                delete els[el.id];
            }
        },
        vthresh : 25,
        hthresh : 25,
        increment : 100,
        frequency : 500,
        animate: true,
        animDuration: .4,
        refreshCache : function(){
            for(var id in els){
                if(typeof els[id] == 'object'){ 
                    els[id]._region = els[id].getRegion();
                }
            }
        }
    };
}();
pExt.dd.Registry = function(){
    var elements = {}; 
    var handles = {}; 
    var autoIdSeed = 0;
    var getId = function(el, autogen){
        if(typeof el == "string"){
            return el;
        }
        var id = el.id;
        if(!id && autogen !== false){
            id = "extdd-" + (++autoIdSeed);
            el.id = id;
        }
        return id;
    };
    return {
        register : function(el, data){
            data = data || {};
            if(typeof el == "string"){
                el = document.getElementById(el);
            }
            data.ddel = el;
            elements[getId(el)] = data;
            if(data.isHandle !== false){
                handles[data.ddel.id] = data;
            }
            if(data.handles){
                var hs = data.handles;
                for(var i = 0, len = hs.length; i < len; i++){
                	handles[getId(hs[i])] = data;
                }
            }
        },
        unregister : function(el){
            var id = getId(el, false);
            var data = elements[id];
            if(data){
                delete elements[id];
                if(data.handles){
                    var hs = data.handles;
                    for(var i = 0, len = hs.length; i < len; i++){
                    	delete handles[getId(hs[i], false)];
                    }
                }
            }
        },
        getHandle : function(id){
            if(typeof id != "string"){ 
                id = id.id;
            }
            return handles[id];
        },
        getHandleFromEvent : function(e){
            var t = pExt.lib.Event.getTarget(e);
            return t ? handles[t.id] : null;
        },
        getTarget : function(id){
            if(typeof id != "string"){ 
                id = id.id;
            }
            return elements[id];
        },
        getTargetFromEvent : function(e){
            var t = pExt.lib.Event.getTarget(e);
            return t ? elements[t.id] || handles[t.id] : null;
        }
    };
}();
pExt.dd.StatusProxy = function(config){
    pExt.apply(this, config);
    this.id = this.id || pExt.id();
    this.el = new pExt.Layer({
        dh: {
            id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
                {tag: "div", cls: "x-dd-drop-icon"},
                {tag: "div", cls: "x-dd-drag-ghost"}
            ]
        }, 
        shadow: !config || config.shadow !== false
    });
    this.ghost = pExt.get(this.el.dom.childNodes[1]);
    this.dropStatus = this.dropNotAllowed;
};
pExt.dd.StatusProxy.prototype = {
    dropAllowed : "x-dd-drop-ok",
    dropNotAllowed : "x-dd-drop-nodrop",
    setStatus : function(cssClass){
        cssClass = cssClass || this.dropNotAllowed;
        if(this.dropStatus != cssClass){
            this.el.replaceClass(this.dropStatus, cssClass);
            this.dropStatus = cssClass;
        }
    },
    reset : function(clearGhost){
        this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
        this.dropStatus = this.dropNotAllowed;
        if(clearGhost){
            this.ghost.update("");
        }
    },
    update : function(html){
        if(typeof html == "string"){
            this.ghost.update(html);
        }else{
            this.ghost.update("");
            html.style.margin = "0";
            this.ghost.dom.appendChild(html);
        }
        var el = this.ghost.dom.firstChild; 
        if(el){
            pExt.fly(el).setStyle('float', 'none');
        }
    },
    getEl : function(){
        return this.el;
    },
    getGhost : function(){
        return this.ghost;
    },
    hide : function(clear){
        this.el.hide();
        if(clear){
            this.reset(true);
        }
    },
    stop : function(){
        if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
            this.anim.stop();
        }
    },
    show : function(){
        this.el.show();
    },
    sync : function(){
        this.el.sync();
    },
    repair : function(xy, callback, scope){
        this.callback = callback;
        this.scope = scope;
        if(xy && this.animRepair !== false){
            this.el.addClass("x-dd-drag-repair");
            this.el.hideUnders(true);
            this.anim = this.el.shift({
                duration: this.repairDuration || .5,
                easing: 'easeOut',
                xy: xy,
                stopFx: true,
                callback: this.afterRepair,
                scope: this
            });
        }else{
            this.afterRepair();
        }
    },
    afterRepair : function(){
        this.hide(true);
        if(typeof this.callback == "function"){
            this.callback.call(this.scope || this);
        }
        this.callback = null;
        this.scope = null;
    }
};
pExt.dd.DragSource = function(el, config){
    this.el = pExt.get(el);
    if(!this.dragData){
        this.dragData = {};
    }
    pExt.apply(this, config);
    if(!this.proxy){
        this.proxy = new pExt.dd.StatusProxy();
    }
    pExt.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, 
          {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
    this.dragging = false;
};
pExt.extend(pExt.dd.DragSource, pExt.dd.DDProxy, {
    dropAllowed : "x-dd-drop-ok",
    dropNotAllowed : "x-dd-drop-nodrop",
    getDragData : function(e){
        return this.dragData;
    },
    onDragEnter : function(e, id){
        var target = pExt.dd.DragDropMgr.getDDById(id);
        this.cachedTarget = target;
        if(this.beforeDragEnter(target, e, id) !== false){
            if(target.isNotifyTarget){
                var status = target.notifyEnter(this, e, this.dragData);
                this.proxy.setStatus(status);
            }else{
                this.proxy.setStatus(this.dropAllowed);
            }
            if(this.afterDragEnter){
                this.afterDragEnter(target, e, id);
            }
        }
    },
    beforeDragEnter : function(target, e, id){
        return true;
    },
    alignElWithMouse: function() {
        pExt.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
        this.proxy.sync();
    },
    onDragOver : function(e, id){
        var target = this.cachedTarget || pExt.dd.DragDropMgr.getDDById(id);
        if(this.beforeDragOver(target, e, id) !== false){
            if(target.isNotifyTarget){
                var status = target.notifyOver(this, e, this.dragData);
                this.proxy.setStatus(status);
            }
            if(this.afterDragOver){
                this.afterDragOver(target, e, id);
            }
        }
    },
    beforeDragOver : function(target, e, id){
        return true;
    },
    onDragOut : function(e, id){
        var target = this.cachedTarget || pExt.dd.DragDropMgr.getDDById(id);
        if(this.beforeDragOut(target, e, id) !== false){
            if(target.isNotifyTarget){
                target.notifyOut(this, e, this.dragData);
            }
            this.proxy.reset();
            if(this.afterDragOut){
                this.afterDragOut(target, e, id);
            }
        }
        this.cachedTarget = null;
    },
    beforeDragOut : function(target, e, id){
        return true;
    },
    onDragDrop : function(e, id){
        var target = this.cachedTarget || pExt.dd.DragDropMgr.getDDById(id);
        if(this.beforeDragDrop(target, e, id) !== false){
            if(target.isNotifyTarget){
                if(target.notifyDrop(this, e, this.dragData)){ 
                    this.onValidDrop(target, e, id);
                }else{
                    this.onInvalidDrop(target, e, id);
                }
            }else{
                this.onValidDrop(target, e, id);
            }
            if(this.afterDragDrop){
                this.afterDragDrop(target, e, id);
            }
        }
        delete this.cachedTarget;
    },
    beforeDragDrop : function(target, e, id){
        return true;
    },
    onValidDrop : function(target, e, id){
        this.hideProxy();
        if(this.afterValidDrop){
            this.afterValidDrop(target, e, id);
        }
    },
    getRepairXY : function(e, data){
        return this.el.getXY();  
    },
    onInvalidDrop : function(target, e, id){
        this.beforeInvalidDrop(target, e, id);
        if(this.cachedTarget){
            if(this.cachedTarget.isNotifyTarget){
                this.cachedTarget.notifyOut(this, e, this.dragData);
            }
            this.cacheTarget = null;
        }
        this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
        if(this.afterInvalidDrop){
            this.afterInvalidDrop(e, id);
        }
    },
    afterRepair : function(){
        if(pExt.enableFx){
            this.el.highlight(this.hlColor || "c3daf9");
        }
        this.dragging = false;
    },
    beforeInvalidDrop : function(target, e, id){
        return true;
    },
    handleMouseDown : function(e){
        if(this.dragging) {
            return;
        }
        var data = this.getDragData(e);
        if(data && this.onBeforeDrag(data, e) !== false){
            this.dragData = data;
            this.proxy.stop();
            pExt.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
        } 
    },
    onBeforeDrag : function(data, e){
        return true;
    },
    onStartDrag : pExt.emptyFn,
    startDrag : function(x, y){
        this.proxy.reset();
        this.dragging = true;
        this.proxy.update("");
        this.onInitDrag(x, y);
        this.proxy.show();
    },
    onInitDrag : function(x, y){
        var clone = this.el.dom.cloneNode(true);
        clone.id = pExt.id(); 
        this.proxy.update(clone);
        this.onStartDrag(x, y);
        return true;
    },
    getProxy : function(){
        return this.proxy;  
    },
    hideProxy : function(){
        this.proxy.hide();  
        this.proxy.reset(true);
        this.dragging = false;
    },
    triggerCacheRefresh : function(){
        pExt.dd.DDM.refreshCache(this.groups);
    },
    b4EndDrag: function(e) {
    },
    endDrag : function(e){
        this.onEndDrag(this.dragData, e);
    },
    onEndDrag : function(data, e){
    },
    autoOffset : function(x, y) {
        this.setDelta(-12, -20);
    }    
});
pExt.dd.DropTarget = function(el, config){
    this.el = pExt.get(el);
    pExt.apply(this, config);
    if(this.containerScroll){
        pExt.dd.ScrollManager.register(this.el);
    }
    pExt.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, 
          {isTarget: true});
};
pExt.extend(pExt.dd.DropTarget, pExt.dd.DDTarget, {
    dropAllowed : "x-dd-drop-ok",
    dropNotAllowed : "x-dd-drop-nodrop",
    isTarget : true,
    isNotifyTarget : true,
    notifyEnter : function(dd, e, data){
        if(this.overClass){
            this.el.addClass(this.overClass);
        }
        return this.dropAllowed;
    },
    notifyOver : function(dd, e, data){
        return this.dropAllowed;
    },
    notifyOut : function(dd, e, data){
        if(this.overClass){
            this.el.removeClass(this.overClass);
        }
    },
    notifyDrop : function(dd, e, data){
        return false;
    }
});
pExt.dd.DragZone = function(el, config){
    pExt.dd.DragZone.superclass.constructor.call(this, el, config);
    if(this.containerScroll){
        pExt.dd.ScrollManager.register(this.el);
    }
};
pExt.extend(pExt.dd.DragZone, pExt.dd.DragSource, {
    getDragData : function(e){
        return pExt.dd.Registry.getHandleFromEvent(e);
    },
    onInitDrag : function(x, y){
        this.proxy.update(this.dragData.ddel.cloneNode(true));
        this.onStartDrag(x, y);
        return true;
    },
    afterRepair : function(){
        if(pExt.enableFx){
            pExt.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
        }
        this.dragging = false;
    },
    getRepairXY : function(e){
        return pExt.Element.fly(this.dragData.ddel).getXY();  
    }
});
pExt.dd.DropZone = function(el, config){
    pExt.dd.DropZone.superclass.constructor.call(this, el, config);
};
pExt.extend(pExt.dd.DropZone, pExt.dd.DropTarget, {
    getTargetFromEvent : function(e){
        return pExt.dd.Registry.getTargetFromEvent(e);
    },
    onNodeEnter : function(n, dd, e, data){
    },
    onNodeOver : function(n, dd, e, data){
        return this.dropAllowed;
    },
    onNodeOut : function(n, dd, e, data){
    },
    onNodeDrop : function(n, dd, e, data){
        return false;
    },
    onContainerOver : function(dd, e, data){
        return this.dropNotAllowed;
    },
    onContainerDrop : function(dd, e, data){
        return false;
    },
    notifyEnter : function(dd, e, data){
        return this.dropNotAllowed;
    },
    notifyOver : function(dd, e, data){
        var n = this.getTargetFromEvent(e);
        if(!n){ 
            if(this.lastOverNode){
                this.onNodeOut(this.lastOverNode, dd, e, data);
                this.lastOverNode = null;
            }
            return this.onContainerOver(dd, e, data);
        }
        if(this.lastOverNode != n){
            if(this.lastOverNode){
                this.onNodeOut(this.lastOverNode, dd, e, data);
            }
            this.onNodeEnter(n, dd, e, data);
            this.lastOverNode = n;
        }
        return this.onNodeOver(n, dd, e, data);
    },
    notifyOut : function(dd, e, data){
        if(this.lastOverNode){
            this.onNodeOut(this.lastOverNode, dd, e, data);
            this.lastOverNode = null;
        }
    },
    notifyDrop : function(dd, e, data){
        if(this.lastOverNode){
            this.onNodeOut(this.lastOverNode, dd, e, data);
            this.lastOverNode = null;
        }
        var n = this.getTargetFromEvent(e);
        return n ?
            this.onNodeDrop(n, dd, e, data) :
            this.onContainerDrop(dd, e, data);
    },
    triggerCacheRefresh : function(){
        pExt.dd.DDM.refreshCache(this.groups);
    }  
});
pExt.data.Api = (function() {
    var validActions = {};
    return {
        actions : {
            create  : 'create',
            read    : 'read',
            update  : 'update',
            destroy : 'destroy'
        },
        restActions : {
            create  : 'POST',
            read    : 'GET',
            update  : 'PUT',
            destroy : 'DELETE'
        },
        isAction : function(action) {
            return (pExt.data.Api.actions[action]) ? true : false;
        },
        getVerb : function(name) {
            if (validActions[name]) {
                return validActions[name];  
            }
            for (var verb in this.actions) {
                if (this.actions[verb] === name) {
                    validActions[name] = verb;
                    break;
                }
            }
            return (validActions[name] !== undefined) ? validActions[name] : null;
        },
        isValid : function(api){
            var invalid = [];
            var crud = this.actions; 
            for (var action in api) {
                if (!(action in crud)) {
                    invalid.push(action);
                }
            }
            return (!invalid.length) ? true : invalid;
        },
        hasUniqueUrl : function(proxy, verb) {
            var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
            var unique = true;
            for (var action in proxy.api) {
                if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
                    break;
                }
            }
            return unique;
        },
        prepare : function(proxy) {
            if (!proxy.api) {
                proxy.api = {}; 
            }
            for (var verb in this.actions) {
                var action = this.actions[verb];
                proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
                if (typeof(proxy.api[action]) == 'string') {
                    proxy.api[action] = {
                        url: proxy.api[action]
                    };
                }
            }
        },
        restify : function(proxy) {
            proxy.restful = true;
            for (var verb in this.restActions) {
                proxy.api[this.actions[verb]].method = this.restActions[verb];
            }
        }
    };
})();
pExt.data.Api.Error = pExt.extend(pExt.Error, {
    constructor : function(message, arg) {
        this.arg = arg;
        pExt.Error.call(this, message);
    },
    name: 'pExt.data.Api'
});
pExt.apply(pExt.data.Api.Error.prototype, {
    lang: {
        'action-url-undefined': 'No fallback url defined for this action.  When defining a DataProxy api, please be sure to define an url for each CRUD action in pExt.data.Api.actions or define a default url in addition to your api-configuration.',
        'invalid': 'received an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions defined in pExt.data.Api.actions',
        'invalid-url': 'Invalid url.  Please review your proxy configuration.',
        'execute': 'Attempted to execute an unknown action.  Valid API actions are defined in pExt.data.Api.actions"'
    }
});
pExt.data.SortTypes = {
    none : function(s){
        return s;
    },
    stripTagsRE : /<\/?[^>]+>/gi,
    asText : function(s){
        return String(s).replace(this.stripTagsRE, "");
    },
    asUCText : function(s){
        return String(s).toUpperCase().replace(this.stripTagsRE, "");
    },
    asUCString : function(s) {
    	return String(s).toUpperCase();
    },
    asDate : function(s) {
        if(!s){
            return 0;
        }
        if(pExt.isDate(s)){
            return s.getTime();
        }
    	return Date.parse(String(s));
    },
    asFloat : function(s) {
    	var val = parseFloat(String(s).replace(/,/g, ""));
    	return isNaN(val) ? 0 : val;
    },
    asInt : function(s) {
        var val = parseInt(String(s).replace(/,/g, ""), 10);
        return isNaN(val) ? 0 : val;
    }
};
pExt.data.Record = function(data, id){
    this.id = (id || id === 0) ? id : pExt.data.Record.id(this);
    this.data = data || {};
};
pExt.data.Record.create = function(o){
    var f = pExt.extend(pExt.data.Record, {});
    var p = f.prototype;
    p.fields = new pExt.util.MixedCollection(false, function(field){
        return field.name;
    });
    for(var i = 0, len = o.length; i < len; i++){
        p.fields.add(new pExt.data.Field(o[i]));
    }
    f.getField = function(name){
        return p.fields.get(name);
    };
    return f;
};
pExt.data.Record.PREFIX = 'pext-record';
pExt.data.Record.AUTO_ID = 1;
pExt.data.Record.EDIT = 'edit';
pExt.data.Record.REJECT = 'reject';
pExt.data.Record.COMMIT = 'commit';
pExt.data.Record.id = function(rec) {
    rec.phantom = true;
    return [pExt.data.Record.PREFIX, '-', pExt.data.Record.AUTO_ID++].join('');
};
pExt.data.Record.prototype = {
    dirty : false,
    editing : false,
    error: null,
    modified: null,
    phantom : false,
    join : function(store){
        this.store = store;
    },
    set : function(name, value){
        var isObj = (typeof value === 'object');
        if(!isObj && String(this.data[name]) === String(value)){
            return;
        } else if (isObj && pExt.encode(this.data[name]) === pExt.encode(value)) {
            return;
        }
        this.dirty = true;
        if(!this.modified){
            this.modified = {};
        }
        if(typeof this.modified[name] == 'undefined'){
            this.modified[name] = this.data[name];
        }
        this.data[name] = value;
        if(!this.editing){
            this.afterEdit();
        }
    },
    afterEdit: function(){
        if(this.store){
            this.store.afterEdit(this);
        }
    },
    afterReject: function(){
        if(this.store){
            this.store.afterReject(this);
        }
    },
    afterCommit: function(){
        if(this.store){
            this.store.afterCommit(this);
        }
    },
    get : function(name){
        return this.data[name];
    },
    beginEdit : function(){
        this.editing = true;
        this.modified = this.modified || {};
    },
    cancelEdit : function(){
        this.editing = false;
        delete this.modified;
    },
    endEdit : function(){
        this.editing = false;
        if(this.dirty){
            this.afterEdit();
        }
    },
    reject : function(silent){
        var m = this.modified;
        for(var n in m){
            if(typeof m[n] != "function"){
                this.data[n] = m[n];
            }
        }
        this.dirty = false;
        delete this.modified;
        this.editing = false;
        if(silent !== true){
            this.afterReject();
        }
    },
    commit : function(silent){
        this.dirty = false;
        delete this.modified;
        this.editing = false;
        if(silent !== true){
            this.afterCommit();
        }
    },
    getChanges : function(){
        var m = this.modified, cs = {};
        for(var n in m){
            if(m.hasOwnProperty(n)){
                cs[n] = this.data[n];
            }
        }
        return cs;
    },
    hasError : function(){
        return this.error !== null;
    },
    clearError : function(){
        this.error = null;
    },
    copy : function(newId) {
        return new this.constructor(pExt.apply({}, this.data), newId || this.id);
    },
    isModified : function(fieldName){
        return !!(this.modified && this.modified.hasOwnProperty(fieldName));
    },
    isValid : function() {
        return this.fields.find(function(f) {
            return (f.allowBlank === false && pExt.isEmpty(this.data[f.name])) ? true : false;
        },this) ? false : true;
    },
    markDirty : function(){
        this.dirty = true;
        if(!this.modified){
            this.modified = {};
        }
        this.fields.each(function(f) {
            this.modified[f.name] = this.data[f.name];
        },this);
    }
};
pExt.StoreMgr = pExt.apply(new pExt.util.MixedCollection(), {
    register : function(){
        for(var i = 0, s; (s = arguments[i]); i++){
            this.add(s);
        }
    },
    unregister : function(){
        for(var i = 0, s; (s = arguments[i]); i++){
            this.remove(this.lookup(s));
        }
    },
    lookup : function(id){
        if(pExt.isArray(id)){
            var fields = ['field1'], expand = !pExt.isArray(id[0]);
            if(!expand){
                for(var i = 2, len = id[0].length; i <= len; ++i){
                    fields.push('field' + i);
                }
            }
            return new pExt.data.ArrayStore({
                fields: fields,
                data: id,
                expandData: expand,
                autoDestroy: true,
                autoCreated: true
            });
        }
        return pExt.isObject(id) ? (id.events ? id : pExt.create(id, 'store')) : this.get(id);
    },
    getKey : function(o){
         return o.storeId;
    }
});
pExt.data.Store = function(config){
    this.data = new pExt.util.MixedCollection(false);
    this.data.getKey = function(o){
        return o.id;
    };
    this.baseParams = {};
    this.removed = [];
    if(config && config.data){
        this.inlineData = config.data;
        delete config.data;
    }
    pExt.apply(this, config);
    this.paramNames = pExt.applyIf(this.paramNames || {}, this.defaultParamNames);
    if(this.url && !this.proxy){
        this.proxy = new pExt.data.HttpProxy({url: this.url});
    }
    if (this.restful === true && this.proxy) {
        this.batch = false;
        pExt.data.Api.restify(this.proxy);
    }
    if(this.reader){ 
        if(!this.recordType){
            this.recordType = this.reader.recordType;
        }
        if(this.reader.onMetaChange){
            this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
        }
        if (this.writer) { 
            this.writer.meta = this.reader.meta;
            this.pruneModifiedRecords = true;
        }
    }
    if(this.recordType){
        this.fields = this.recordType.prototype.fields;
    }
    this.modified = [];
    this.addEvents(
        'datachanged',
        'metachange',
        'add',
        'remove',
        'update',
        'clear',
        'exception',
        'beforeload',
        'load',
        'loadexception',
        'beforewrite',
        'write'
    );
    if(this.proxy){
        this.relayEvents(this.proxy,  ['loadexception', 'exception']);
    }
    if (this.writer) {
        this.on({
            scope: this,
            add: this.createRecords,
            remove: this.destroyRecord,
            update: this.updateRecord
        });
    }
    this.sortToggle = {};
    if(this.sortField){
        this.setDefaultSort(this.sortField, this.sortDir);
    }else if(this.sortInfo){
        this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
    }
    pExt.data.Store.superclass.constructor.call(this);
    if(this.id){
        this.storeId = this.id;
        delete this.id;
    }
    if(this.storeId){
        pExt.StoreMgr.register(this);
    }
    if(this.inlineData){
        this.loadData(this.inlineData);
        delete this.inlineData;
    }else if(this.autoLoad){
        this.load.defer(10, this, [
            typeof this.autoLoad == 'object' ?
                this.autoLoad : undefined]);
    }
};
pExt.extend(pExt.data.Store, pExt.util.Observable, {
    writer : undefined,
    remoteSort : false,
    autoDestroy : false,
    pruneModifiedRecords : false,
    lastOptions : null,
    autoSave : true,
    batch : true,
    restful: false,
    paramNames : undefined,
    defaultParamNames : {
        start : 'start',
        limit : 'limit',
        sort : 'sort',
        dir : 'dir'
    },
    destroy : function(){
        if(this.storeId){
            pExt.StoreMgr.unregister(this);
        }
        this.data = null;
        pExt.destroy(this.proxy);
        this.reader = this.writer = null;
        this.purgeListeners();
    },
    add : function(records){
        records = [].concat(records);
        if(records.length < 1){
            return;
        }
        for(var i = 0, len = records.length; i < len; i++){
            records[i].join(this);
        }
        var index = this.data.length;
        this.data.addAll(records);
        if(this.snapshot){
            this.snapshot.addAll(records);
        }
        this.fireEvent('add', this, records, index);
    },
    addSorted : function(record){
        var index = this.findInsertIndex(record);
        this.insert(index, record);
    },
    remove : function(record){
        var index = this.data.indexOf(record);
        if(index > -1){
            this.data.removeAt(index);
            if(this.pruneModifiedRecords){
                this.modified.remove(record);
            }
            if(this.snapshot){
                this.snapshot.remove(record);
            }
            this.fireEvent('remove', this, record, index);
        }
    },
    removeAt : function(index){
        this.remove(this.getAt(index));
    },
    removeAll : function(){
        this.data.clear();
        if(this.snapshot){
            this.snapshot.clear();
        }
        if(this.pruneModifiedRecords){
            this.modified = [];
        }
        this.fireEvent('clear', this);
    },
    insert : function(index, records){
        records = [].concat(records);
        for(var i = 0, len = records.length; i < len; i++){
            this.data.insert(index, records[i]);
            records[i].join(this);
        }
        this.fireEvent('add', this, records, index);
    },
    indexOf : function(record){
        return this.data.indexOf(record);
    },
    indexOfId : function(id){
        return this.data.indexOfKey(id);
    },
    getById : function(id){
        return this.data.key(id);
    },
    getAt : function(index){
        return this.data.itemAt(index);
    },
    getRange : function(start, end){
        return this.data.getRange(start, end);
    },
    storeOptions : function(o){
        o = pExt.apply({}, o);
        delete o.callback;
        delete o.scope;
        this.lastOptions = o;
    },
    load : function(options) {
        options = options || {};
        this.storeOptions(options);
        if(this.sortInfo && this.remoteSort){
            var pn = this.paramNames;
            options.params = options.params || {};
            options.params[pn.sort] = this.sortInfo.field;
            options.params[pn.dir] = this.sortInfo.direction;
        }
        try {
            return this.execute('read', null, options); 
        } catch(e) {
            this.handleException(e);
            return false;
        }
    },
    updateRecord : function(store, record, action) {
        if (action == pExt.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid))) {
            this.save();
        }
    },
    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]);  
            }
        }
        if (this.autoSave === true) {
            this.save();
        }
    },
    destroyRecord : function(store, record, index) {
        if (this.modified.indexOf(record) != -1) {  
            this.modified.remove(record);
        }
        if (!record.phantom) {
            this.removed.push(record);
            record.lastIndex = index;
            if (this.autoSave === true) {
                this.save();
            }
        }
    },
    execute : function(action, rs, options) {
        if (!pExt.data.Api.isAction(action)) {
            throw new pExt.data.Api.Error('execute', action);
        }
        options = pExt.applyIf(options||{}, {
            params: {}
        });
        var doRequest = true;
        if (action === 'read') {
            doRequest = this.fireEvent('beforeload', this, options);
        }
        else {
            if (this.writer.listful === true && this.restful !== true) {
                rs = (pExt.isArray(rs)) ? rs : [rs];
            }
            else if (pExt.isArray(rs) && rs.length == 1) {
                rs = rs.shift();
            }
            if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
                this.writer.write(action, options.params, rs);
            }
        }
        if (doRequest !== false) {
            var params = pExt.apply({}, options.params, this.baseParams);
            if (this.writer && this.proxy.url && !this.proxy.restful && !pExt.data.Api.hasUniqueUrl(this.proxy, action)) {
                params.xaction = action;
            }
            this.proxy.request(pExt.data.Api.actions[action], rs, params, this.reader, this.createCallback(action, rs), this, options);
        }
        return doRequest;
    },
    save : function() {
        if (!this.writer) {
            throw new pExt.data.Store.Error('writer-undefined');
        }
        if (this.removed.length) {
            this.doTransaction('destroy', this.removed);
        }
        var rs = [].concat(this.getModifiedRecords());
        if (!rs.length) { 
            return true;
        }
        var phantoms = [];
        for (var i = rs.length-1; i >= 0; i--) {
            if (rs[i].phantom === true) {
                var rec = rs.splice(i, 1).shift();
                if (rec.isValid()) {
                    phantoms.push(rec);
                }
            } else if (!rs[i].isValid()) { 
                rs.splice(i,1);
            }
        }
        if (phantoms.length) {
            this.doTransaction('create', phantoms);
        }
        if (rs.length) {
            this.doTransaction('update', rs);
        }
        return true;
    },
    doTransaction : function(action, rs) {
        function transaction(records) {
            try {
                this.execute(action, records);
            } catch (e) {
                this.handleException(e);
            }
        }
        if (this.batch === false) {
            for (var i = 0, len = rs.length; i < len; i++) {
                transaction.call(this, rs[i]);
            }
        } else {
            transaction.call(this, rs);
        }
    },
    createCallback : function(action, rs) {
        var actions = pExt.data.Api.actions;
        return (action == 'read') ? this.loadRecords : function(data, response, success) {
            this['on' + pExt.util.Format.capitalize(action) + 'Records'](success, rs, data);
            if (success === true) {
                this.fireEvent('write', this, action, data, response, rs);
            }
        };
    },
    clearModified : function(rs) {
        if (pExt.isArray(rs)) {
            for (var n=rs.length-1;n>=0;n--) {
                this.modified.splice(this.modified.indexOf(rs[n]), 1);
            }
        } else {
            this.modified.splice(this.modified.indexOf(rs), 1);
        }
    },
    reMap : function(record) {
        if (pExt.isArray(record)) {
            for (var i = 0, len = record.length; i < len; i++) {
                this.reMap(record[i]);
            }
        } else {
            delete this.data.map[record._phid];
            this.data.map[record.id] = record;
            var index = this.data.keys.indexOf(record._phid);
            this.data.keys.splice(index, 1, record.id);
            delete record._phid;
        }
    },
    onCreateRecords : function(success, rs, data) {
        if (success === true) {
            try {
                this.reader.realize(rs, data);
                this.reMap(rs);
            }
            catch (e) {
                this.handleException(e);
                if (pExt.isArray(rs)) {
                    this.onCreateRecords(success, rs, data);
                }
            }
        }
    },
    onUpdateRecords : function(success, rs, data) {
        if (success === true) {
            try {
                this.reader.update(rs, data);
            } catch (e) {
                this.handleException(e);
                if (pExt.isArray(rs)) {
                    this.onUpdateRecords(success, rs, data);
                }
            }
        }
    },
    onDestroyRecords : function(success, rs, data) {
        rs = (rs instanceof pExt.data.Record) ? [rs] : rs;
        for (var i=0,len=rs.length;i<len;i++) {
            this.removed.splice(this.removed.indexOf(rs[i]), 1);
        }
        if (success === false) {
            for (i=rs.length-1;i>=0;i--) {
                this.insert(rs[i].lastIndex, rs[i]);    
            }
        }
    },
    handleException : function(e) {
        pExt.handleError(e);
    },
    reload : function(options){
        this.load(pExt.applyIf(options||{}, this.lastOptions));
    },
    loadRecords : function(o, options, success){
        if(!o || success === false){
            if(success !== false){
                this.fireEvent('load', this, [], options);
            }
            if(options.callback){
                options.callback.call(options.scope || this, [], options, false, o);
            }
            return;
        }
        var r = o.records, t = o.totalRecords || r.length;
        if(!options || options.add !== true){
            if(this.pruneModifiedRecords){
                this.modified = [];
            }
            for(var i = 0, len = r.length; i < len; i++){
                r[i].join(this);
            }
            if(this.snapshot){
                this.data = this.snapshot;
                delete this.snapshot;
            }
            this.data.clear();
            this.data.addAll(r);
            this.totalLength = t;
            this.applySort();
            this.fireEvent('datachanged', this);
        }else{
            this.totalLength = Math.max(t, this.data.length+r.length);
            this.add(r);
        }
        this.fireEvent('load', this, r, options);
        if(options.callback){
            options.callback.call(options.scope || this, r, options, true);
        }
    },
    loadData : function(o, append){
        var r = this.reader.readRecords(o);
        this.loadRecords(r, {add: append}, true);
    },
    getCount : function(){
        return this.data.length || 0;
    },
    getTotalCount : function(){
        return this.totalLength || 0;
    },
    getSortState : function(){
        return this.sortInfo;
    },
    applySort : function(){
        if(this.sortInfo && !this.remoteSort){
            var s = this.sortInfo, f = s.field;
            this.sortData(f, s.direction);
        }
    },
    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);
        };
        this.data.sort(direction, fn);
        if(this.snapshot && this.snapshot != this.data){
            this.snapshot.sort(direction, fn);
        }
    },
    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){
            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 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{
            if (!this.load(this.lastOptions)) {
                if (st) {
                    this.sortToggle[f.name] = st;
                }
                if (si) {
                    this.sortInfo = si;
                }
            }
        }
    },
    each : function(fn, scope){
        this.data.each(fn, scope);
    },
    getModifiedRecords : function(){
        return this.modified;
    },
    createFilterFn : function(property, value, anyMatch, caseSensitive){
        if(pExt.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;
        end = (end || end === 0) ? end : rs.length-1;
        for(var i = start; i <= end; i++){
            v += (rs[i].data[property] || 0);
        }
        return v;
    },
    filter : function(property, value, anyMatch, caseSensitive){
        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
        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.fireEvent('datachanged', this);
    },
    query : function(property, value, anyMatch, caseSensitive){
        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
        return fn ? this.queryBy(fn) : this.data.clone();
    },
    queryBy : function(fn, scope){
        var data = this.snapshot || this.data;
        return data.filterBy(fn, scope||this);
    },
    find : function(property, value, start, anyMatch, caseSensitive){
        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
        return fn ? this.data.findIndexBy(fn, null, start) : -1;
    },
    findExact: function(property, value, start){
        return this.data.findIndexBy(function(rec){
            return rec.get(property) === value;
        }, this, start);
    },
    findBy : function(fn, scope, start){
        return this.data.findIndexBy(fn, scope, start);
    },
    collect : function(dataIndex, allowNull, bypassFilter){
        var d = (bypassFilter === true && this.snapshot) ?
                this.snapshot.items : this.data.items;
        var v, sv, r = [], l = {};
        for(var i = 0, len = d.length; i < len; i++){
            v = d[i].data[dataIndex];
            sv = String(v);
            if((allowNull || !pExt.isEmpty(v)) && !l[sv]){
                l[sv] = true;
                r[r.length] = v;
            }
        }
        return r;
    },
    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);
        }
        this.fireEvent('update', this, record, pExt.data.Record.EDIT);
    },
    afterReject : function(record){
        this.modified.remove(record);
        this.fireEvent('update', this, record, pExt.data.Record.REJECT);
    },
    afterCommit : function(record){
        this.modified.remove(record);
        this.fireEvent('update', this, record, pExt.data.Record.COMMIT);
    },
    commitChanges : function(){
        var m = this.modified.slice(0);
        this.modified = [];
        for(var i = 0, len = m.length; i < len; i++){
            m[i].commit();
        }
    },
    rejectChanges : function(){
        var m = this.modified.slice(0);
        this.modified = [];
        for(var i = 0, len = m.length; i < len; i++){
            m[i].reject();
        }
    },
    onMetaChange : function(meta, rtype, o){
        this.recordType = rtype;
        this.fields = rtype.prototype.fields;
        delete this.snapshot;
        if(meta.sortInfo){
            this.sortInfo = meta.sortInfo;
        }else if(this.sortInfo  && !this.fields.get(this.sortInfo.field)){
            delete this.sortInfo;
        }
        this.modified = [];
        this.fireEvent('metachange', this, this.reader.meta);
    },
    findInsertIndex : function(record){
        this.suspendEvents();
        var data = this.data.clone();
        this.data.add(record);
        this.applySort();
        var index = this.data.indexOf(record);
        this.data = data;
        this.resumeEvents();
        return index;
    },
    setBaseParam : function (name, value){
        this.baseParams = this.baseParams || {};
        this.baseParams[name] = value;
    }
});
pExt.reg('store', pExt.data.Store);
pExt.data.Store.Error = pExt.extend(pExt.Error, {
    name: 'pExt.data.Store'
});
pExt.apply(pExt.data.Store.Error.prototype, {
    lang: {
        'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
    }
});
pExt.data.DirectStore = function(c){
    c.batchTransactions = false;
    pExt.data.DirectStore.superclass.constructor.call(this, pExt.apply(c, {
        proxy: (typeof(c.proxy) == 'undefined') ? new pExt.data.DirectProxy(pExt.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')) : c.proxy,
        reader: (typeof(c.reader) == 'undefined' && typeof(c.fields) == 'object') ? new pExt.data.JsonReader(pExt.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
    }));
};
pExt.extend(pExt.data.DirectStore, pExt.data.Store, {});
pExt.reg('directstore', pExt.data.DirectStore);
pExt.data.JsonStore = pExt.extend(pExt.data.Store, {
    constructor: function(config){
        pExt.data.JsonStore.superclass.constructor.call(this, pExt.apply(config, {
            reader: new pExt.data.JsonReader(config)
        }));
    }
});
pExt.reg('jsonstore', pExt.data.JsonStore);
pExt.data.XmlStore = pExt.extend(pExt.data.Store, {
    constructor: function(config){
        pExt.data.XmlStore.superclass.constructor.call(this, pExt.apply(config, {
            reader: new pExt.data.XmlReader(config)
        }));
    }
});
pExt.reg('xmlstore', pExt.data.XmlStore);
pExt.data.ArrayStore = pExt.extend(pExt.data.Store, {
    constructor: function(config){
        pExt.data.ArrayStore.superclass.constructor.call(this, pExt.apply(config, {
            reader: new pExt.data.ArrayReader(config)
        }));
    },
    loadData : function(data, append){
        if(this.expandData === true){
            var r = [];
            for(var i = 0, len = data.length; i < len; i++){
                r[r.length] = [data[i]];
            }
            data = r;
        }
        pExt.data.ArrayStore.superclass.loadData.call(this, data, append);
    }
});
pExt.reg('arraystore', pExt.data.ArrayStore);
pExt.data.SimpleStore = pExt.data.ArrayStore;
pExt.reg('simplestore', pExt.data.SimpleStore);
pExt.data.Field = function(config){
    if(typeof config == "string"){
        config = {name: config};
    }
    pExt.apply(this, config);
    if(!this.type){
        this.type = "auto";
    }
    var st = pExt.data.SortTypes;
    if(typeof this.sortType == "string"){
        this.sortType = st[this.sortType];
    }
    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;
        }
    }
    var stripRe = /[\$,%]/g;
    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":
            case "boolean":
                cv = function(v){ return v === true || v === "true" || v == 1; };
                break;
            case "date":
                cv = function(v){
                    if(!v){
                        return '';
                    }
                    if(pExt.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;
        }
        this.convert = cv;
    }
};
pExt.data.Field.prototype = {
    dateFormat: null,
    defaultValue: "",
    mapping: null,
    sortType : null,
    sortDir : "ASC",
	allowBlank : true
};
pExt.data.DataReader = function(meta, recordType){
    this.meta = meta;
    this.recordType = pExt.isArray(recordType) ?
        pExt.data.Record.create(recordType) : recordType;
};
pExt.data.DataReader.prototype = {
    buildpExtractors : pExt.emptyFn,
    realize: function(rs, data){
        if (pExt.isArray(rs)) {
            for (var i = rs.length - 1; i >= 0; i--) {
                if (pExt.isArray(data)) {
                    this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
                }
                else {
                    this.realize(rs.splice(i,1).shift(), data);
                }
            }
        }
        else {
            if (pExt.isArray(data) && data.length == 1) {
                data = data.shift();
            }
            if (!this.isData(data)) {
                throw new pExt.data.DataReader.Error('realize', rs);
            }
            this.buildpExtractors();
            var values = this.extractValues(data, rs.fields.items, rs.fields.items.length);
            rs.phantom = false; 
            rs._phid = rs.id;  
            rs.id = data[this.meta.idProperty];
            rs.data = values;
            rs.commit();
        }
    },
    update : function(rs, data) {
        if (pExt.isArray(rs)) {
            for (var i=rs.length-1; i >= 0; i--) {
                if (pExt.isArray(data)) {
                    this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
                }
                else {
                    this.update(rs.splice(i,1).shift(), data);
                }
            }
        }
        else {
            if (pExt.isArray(data) && data.length == 1) {
                data = data.shift();
            }
            if (!this.isData(data)) {
                rs.commit();
                throw new pExt.data.DataReader.Error('update', rs);
            }
            this.buildpExtractors();
            rs.data = this.extractValues(pExt.apply(rs.data, data), rs.fields.items, rs.fields.items.length);
            rs.commit();
        }
    },
    isData : function(data) {
        return (data && pExt.isObject(data) && !pExt.isEmpty(data[this.meta.idProperty])) ? true : false;
    }
};
pExt.data.DataReader.Error = pExt.extend(pExt.Error, {
    constructor : function(message, arg) {
        this.arg = arg;
        pExt.Error.call(this, message);
    },
    name: 'pExt.data.DataReader'
});
pExt.apply(pExt.data.DataReader.Error.prototype, {
    lang : {
        'update': "#update received invalid data from server.  Please see docs for DataReader#update and review your DataReader configuration.",
        'realize': "#realize was called with invalid remote-data.  Please see the docs for DataReader#realize and review your DataReader configuration.",
        'invalid-response': "#readResponse received an invalid response from the server."
    }
});
pExt.data.DataWriter = function(config){
    pExt.apply(this, config);
};
pExt.data.DataWriter.prototype = {
    writeAllFields : false,
    listful : false,    
    write : function(action, params, rs) {
        this.render(action, rs, params, this[action](rs));
    },
    render : pExt.emptyFn,
    update : function(rs) {
        var params = {};
        if (pExt.isArray(rs)) {
            var data = [],
                ids = [];
            pExt.each(rs, function(val){
                ids.push(val.id);
                data.push(this.updateRecord(val));
            }, this);
            params[this.meta.idProperty] = ids;
            params[this.meta.root] = data;
        }
        else if (rs instanceof pExt.data.Record) {
            params[this.meta.idProperty] = rs.id;
            params[this.meta.root] = this.updateRecord(rs);
        }
        return params;
    },
    updateRecord : pExt.emptyFn,
    create : function(rs) {
        var params = {};
        if (pExt.isArray(rs)) {
            var data = [];
            pExt.each(rs, function(val){
                data.push(this.createRecord(val));
            }, this);
            params[this.meta.root] = data;
        }
        else if (rs instanceof pExt.data.Record) {
            params[this.meta.root] = this.createRecord(rs);
        }
        return params;
    },
    createRecord : pExt.emptyFn,
    destroy : function(rs) {
        var params = {};
        if (pExt.isArray(rs)) {
            var data = [],
                ids = [];
            pExt.each(rs, function(val){
                data.push(this.destroyRecord(val));
            }, this);
            params[this.meta.root] = data;
        } else if (rs instanceof pExt.data.Record) {
            params[this.meta.root] = this.destroyRecord(rs);
        }
        return params;
    },
    destroyRecord : pExt.emptyFn,
    toHash : function(rec) {
        var map = rec.fields.map,
            data = {},
            raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
            m;
        pExt.iterate(raw, function(prop, value){
            if((m = map[prop])){
                data[m.mapping ? m.mapping : m.name] = value;
            }
        });
        data[this.meta.idProperty] = rec.id;
        return data;
    }
};
pExt.data.JsonWriter = function(config) {
    pExt.data.JsonWriter.superclass.constructor.call(this, config);
    if (this.returnJson != undefined) {
        this.encode = this.returnJson;
    }
}
pExt.extend(pExt.data.JsonWriter, pExt.data.DataWriter, {
    returnJson : undefined,
    encode : true,
    render : function(action, rs, params, data) {
        pExt.apply(params, data);
        if (this.encode === true) { 
            if (pExt.isArray(rs) && data[this.meta.idProperty]) {
                params[this.meta.idProperty] = pExt.encode(params[this.meta.idProperty]);
            }
            params[this.meta.root] = pExt.encode(params[this.meta.root]);
        }
    },
    createRecord : function(rec) {
        return this.toHash(rec);
    },
    updateRecord : function(rec) {
        return this.toHash(rec);
    },
    destroyRecord : function(rec) {
        return rec.id;
    }
});
pExt.data.DataProxy = function(conn){
    conn = conn || {};
    this.api     = conn.api;
    this.url     = conn.url;
    this.restful = conn.restful;
    this.listeners = conn.listeners;
    this.prettyUrls = conn.prettyUrls;
    try {
        pExt.data.Api.prepare(this);
    } catch (e) {
        if (e instanceof pExt.data.Api.Error) {
            e.toConsole();
        }
    }
    this.addEvents(
        'exception',
        'beforeload',
        'load',
        'loadexception',
        'beforewrite',
        'write'
    );
    pExt.data.DataProxy.superclass.constructor.call(this);
};
pExt.extend(pExt.data.DataProxy, pExt.util.Observable, {
    restful: false,
    setApi : function() {
        if (arguments.length == 1) {
            var valid = pExt.data.Api.isValid(arguments[0]);
            if (valid === true) {
                this.api = arguments[0];
            }
            else {
                throw new pExt.data.Api.Error('invalid', valid);
            }
        }
        else if (arguments.length == 2) {
            if (!pExt.data.Api.isAction(arguments[0])) {
                throw new pExt.data.Api.Error('invalid', arguments[0]);
            }
            this.api[arguments[0]] = arguments[1];
        }
        pExt.data.Api.prepare(this);
    },
    isApiAction : function(action) {
        return (this.api[action]) ? true : false;
    },
    request : function(action, rs, params, reader, callback, scope, options) {
        if (!this.api[action] && !this.load) {
            throw new pExt.data.DataProxy.Error('action-undefined', action);
        }
        params = params || {};
        if ((action === pExt.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
            this.doRequest.apply(this, arguments);
        }
        else {
            callback.call(scope || this, null, options, false);
        }
    },
    load : null,
    doRequest : function(action, rs, params, reader, callback, scope, options) {
        this.load(params, reader, callback, scope, options);
    },
    buildUrl : function(action, record) {
        record = record || null;
        var url = (this.api[action]) ? this.api[action].url : this.url;
        if (!url) {
            throw new pExt.data.Api.Error('invalid-url', action);
        }
        var format = null;
        var m = url.match(/(.*)(\.\w+)$/);  
        if (m) {
            format = m[2];
            url = m[1];
        }
        if ((this.prettyUrls === true || this.restful === true) && record instanceof pExt.data.Record && !record.phantom) {
            url += '/' + record.id;
        }
        if (format) {   
            url += format;
        }
        return url;
    },
    destroy: function(){
        this.purgeListeners();
    }
});
pExt.data.DataProxy.Error = pExt.extend(pExt.Error, {
    constructor : function(message, arg) {
        this.arg = arg;
        pExt.Error.call(this, message);
    },
    name: 'pExt.data.DataProxy'
});
pExt.apply(pExt.data.DataProxy.Error.prototype, {
    lang: {
        'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function.  Please review your Proxy url/api-configuration.",
        'api-invalid': 'Recieved an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions from pExt.data.Api.actions.'
    }
});
pExt.data.MemoryProxy = function(data){
    var api = {};
    api[pExt.data.Api.actions.read] = true;
    pExt.data.MemoryProxy.superclass.constructor.call(this, {
        api: api
    });
    this.data = data;
};
pExt.extend(pExt.data.MemoryProxy, pExt.data.DataProxy, {
    doRequest : function(action, rs, params, reader, callback, scope, arg) {
        params = params || {};
        var result;
        try {
            result = reader.readRecords(this.data);
        }catch(e){
            this.fireEvent("loadexception", this, null, arg, e);
            this.fireEvent('exception', this, 'response', action, arg, null, e);
            callback.call(scope, null, arg, false);
            return;
        }
        callback.call(scope, result, arg, true);
    }
});
pExt.data.HttpProxy = function(conn){
    pExt.data.HttpProxy.superclass.constructor.call(this, conn);
    this.conn = conn;
    this.conn.url = null;
    this.useAjax = !conn || !conn.events;
    var actions = pExt.data.Api.actions;
    this.activeRequest = {};
    for (var verb in actions) {
        this.activeRequest[actions[verb]] = undefined;
    }
};
pExt.extend(pExt.data.HttpProxy, pExt.data.DataProxy, {
    getConnection : function() {
        return this.useAjax ? pExt.Ajax : this.conn;
    },
    setUrl : function(url, makePermanent) {
        this.conn.url = url;
        if (makePermanent === true) {
            this.url = url;
            pExt.data.Api.prepare(this);
        }
    },
    doRequest : function(action, rs, params, reader, cb, scope, arg) {
        var  o = {
            method: (this.api[action]) ? this.api[action]['method'] : undefined,
            request: {
                callback : cb,
                scope : scope,
                arg : arg
            },
            reader: reader,
            callback : this.createCallback(action, rs),
            scope: this
        };
        if (typeof(params[reader.meta.root]) === 'object') {
            o.jsonData = params;
        } else {
            o.params = params || {};
        }
        if (this.conn.url === null) {
            this.conn.url = this.buildUrl(action, rs);
        }
        else if (this.restful === true && rs instanceof pExt.data.Record && !rs.phantom) {
            this.conn.url += '/' + rs.id;
        }
        if(this.useAjax){
            pExt.applyIf(o, this.conn);
            if (this.activeRequest[action]) {
            }
            this.activeRequest[action] = pExt.Ajax.request(o);
        }else{
            this.conn.request(o);
        }
        this.conn.url = null;
    },
    createCallback : function(action, rs) {
        return function(o, success, response) {
            this.activeRequest[action] = undefined;
            if (!success) {
                if (action === pExt.data.Api.actions.read) {
                    this.fireEvent('loadexception', this, o, response);
                }
                this.fireEvent('exception', this, 'response', action, o, response);
                o.request.callback.call(o.request.scope, null, o.request.arg, false);
                return;
            }
            if (action === pExt.data.Api.actions.read) {
                this.onRead(action, o, response);
            } else {
                this.onWrite(action, o, response, rs);
            }
        }
    },
    onRead : function(action, o, response) {
        var result;
        try {
            result = o.reader.read(response);
        }catch(e){
            this.fireEvent('loadexception', this, o, response, e);
            this.fireEvent('exception', this, 'response', action, o, response, e);
            o.request.callback.call(o.request.scope, null, o.request.arg, false);
            return;
        }
        if (result.success === false) {
            this.fireEvent('loadexception', this, o, response);
            var res = o.reader.readResponse(action, response);
            this.fireEvent('exception', this, 'remote', action, o, res, null);
        }
        else {
            this.fireEvent('load', this, o, o.request.arg);
        }
        o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
    },
    onWrite : function(action, o, response, rs) {
        var reader = o.reader;
        var res;
        try {
            res = reader.readResponse(action, response);
        } catch (e) {
            this.fireEvent('exception', this, 'response', action, o, response, e);
            o.request.callback.call(o.request.scope, null, o.request.arg, false);
            return;
        }
        if (res[reader.meta.successProperty] === false) {
            this.fireEvent('exception', this, 'remote', action, o, res, rs);
        } else {
            this.fireEvent('write', this, action, res[reader.meta.root], res, rs, o.request.arg);
        }
        o.request.callback.call(o.request.scope, res[reader.meta.root], res, res[reader.meta.successProperty]);
    },
    destroy: function(){
        if(!this.useAjax){
            this.conn.abort();
        }else if(this.activeRequest){
            var actions = pExt.data.Api.actions;
            for (var verb in actions) {
                if(this.activeRequest[actions[verb]]){
                    pExt.Ajax.abort(this.activeRequest[actions[verb]]);
                }
            }
        }
        pExt.data.HttpProxy.superclass.destroy.call(this);
    }
});
pExt.data.ScriptTagProxy = function(config){
    pExt.apply(this, config);
    pExt.data.ScriptTagProxy.superclass.constructor.call(this, config);
    this.head = document.getElementsByTagName("head")[0];
};
pExt.data.ScriptTagProxy.TRANS_ID = 1000;
pExt.extend(pExt.data.ScriptTagProxy, pExt.data.DataProxy, {
    timeout : 30000,
    callbackParam : "callback",
    nocache : true,
    doRequest : function(action, rs, params, reader, callback, scope, arg) {
        var p = pExt.urlEncode(pExt.apply(params, this.extraParams));
        var url = this.buildUrl(action, rs);
        if (!url) {
            throw new pExt.data.Api.Error('invalid-url', url);
        }
        url = pExt.urlAppend(url, p);
        if(this.nocache){
            url = pExt.urlAppend(url, '_dc=' + (new Date().getTime()));
        }
        var transId = ++pExt.data.ScriptTagProxy.TRANS_ID;
        var trans = {
            id : transId,
            action: action,
            cb : "stcCallback"+transId,
            scriptId : "stcScript"+transId,
            params : params,
            arg : arg,
            url : url,
            callback : callback,
            scope : scope,
            reader : reader
        };
        window[trans.cb] = this.createCallback(action, rs, trans);
        url += String.format("&{0}={1}", this.callbackParam, trans.cb);
        if(this.autoAbort !== false){
            this.abort();
        }
        trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
        var script = document.createElement("script");
        script.setAttribute("src", url);
        script.setAttribute("type", "text/javascript");
        script.setAttribute("id", trans.scriptId);
        this.head.appendChild(script);
        this.trans = trans;
    },
    createCallback : function(action, rs, trans) {
        var self = this;
        return function(res) {
            self.trans = false;
            self.destroyTrans(trans, true);
            if (action === pExt.data.Api.actions.read) {
                self.onRead.call(self, action, trans, res);
            } else {
                self.onWrite.call(self, action, trans, res, rs);
            }
        };
    },
    onRead : function(action, trans, res) {
        var result;
        try {
            result = trans.reader.readRecords(res);
        }catch(e){
            this.fireEvent("loadexception", this, trans, res, e);
            this.fireEvent('exception', this, 'response', action, trans, res, e);
            trans.callback.call(trans.scope||window, null, trans.arg, false);
            return;
        }
        if (result.success === false) {
            this.fireEvent('loadexception', this, trans, res);
            this.fireEvent('exception', this, 'remote', action, trans, res, null);
        } else {
            this.fireEvent("load", this, res, trans.arg);
        }
        trans.callback.call(trans.scope||window, result, trans.arg, result.success);
    },
    onWrite : function(action, trans, res, rs) {
        var reader = trans.reader;
        try {
            reader.readResponse(action, res);
        } catch (e) {
            this.fireEvent('exception', this, 'response', action, trans, res, e);
            trans.callback.call(trans.scope||window, null, res, false);
            return;
        }
        if(!res[reader.meta.successProperty] === true){
            this.fireEvent('exception', this, 'remote', action, trans, res, rs);
            trans.callback.call(trans.scope||window, null, res, false);
            return;
        }
        this.fireEvent("write", this, action, res[reader.meta.root], res, rs, trans.arg );
        trans.callback.call(trans.scope||window, res[reader.meta.root], res, true);
    },
    isLoading : function(){
        return this.trans ? true : false;
    },
    abort : function(){
        if(this.isLoading()){
            this.destroyTrans(this.trans);
        }
    },
    destroyTrans : function(trans, isLoaded){
        this.head.removeChild(document.getElementById(trans.scriptId));
        clearTimeout(trans.timeoutId);
        if(isLoaded){
            window[trans.cb] = undefined;
            try{
                delete window[trans.cb];
            }catch(e){}
        }else{
            window[trans.cb] = function(){
                window[trans.cb] = undefined;
                try{
                    delete window[trans.cb];
                }catch(e){}
            };
        }
    },
    handleFailure : function(trans){
        this.trans = false;
        this.destroyTrans(trans, false);
        if (trans.action === pExt.data.Api.actions.read) {
            this.fireEvent("loadexception", this, null, trans.arg);
        }
        this.fireEvent('exception', this, 'response', trans.action, {
            response: null,
            options: trans.arg
        });
        trans.callback.call(trans.scope||window, null, trans.arg, false);
    },
    destroy: function(){
        this.abort();
        pExt.data.ScriptTagProxy.superclass.destroy.call(this);
    }
});
pExt.data.DirectProxy = function(config){
    pExt.apply(this, config);
    if(typeof this.paramOrder == 'string'){
        this.paramOrder = this.paramOrder.split(/[\s,|]/);
    }
    pExt.data.DirectProxy.superclass.constructor.call(this, config);
};
pExt.extend(pExt.data.DirectProxy, pExt.data.DataProxy, {
    paramOrder: undefined,
    paramsAsHash: true,
    directFn : undefined,
    doRequest : function(action, rs, params, reader, callback, scope, options) {
        var args = [];
        var directFn = this.api[action] || this.directFn;
        switch (action) {
            case pExt.data.Api.actions.create:
                args.push(params[reader.meta.root]);		
                break;
            case pExt.data.Api.actions.read:
                if(this.paramOrder){
                    for(var i = 0, len = this.paramOrder.length; i < len; i++){
                        args.push(params[this.paramOrder[i]]);
                    }
                }else if(this.paramsAsHash){
                    args.push(params);
                }
                break;
            case pExt.data.Api.actions.update:
                args.push(params[reader.meta.idProperty]);  
                args.push(params[reader.meta.root]);
                break;
            case pExt.data.Api.actions.destroy:
                args.push(params[reader.meta.root]);        
                break;
        }
        var trans = {
            params : params || {},
            callback : callback,
            scope : scope,
            arg : options,
            reader: reader
        };
        args.push(this.createCallback(action, rs, trans), this);
        directFn.apply(window, args);
    },
    createCallback : function(action, rs, trans) {
        return function(result, res) {
            if (!res.status) {
                if (action === pExt.data.Api.actions.read) {
                    this.fireEvent("loadexception", this, trans, res, null);
                }
                this.fireEvent('exception', this, 'remote', action, trans, res, null);
                trans.callback.call(trans.scope, null, trans.arg, false);
                return;
            }
            if (action === pExt.data.Api.actions.read) {
                this.onRead(action, trans, result, res);
            } else {
                this.onWrite(action, trans, result, res, rs);
            }
        };
    },
    onRead : function(action, trans, result, res) {
        var records;
        try {
            records = trans.reader.readRecords(result);
        }
        catch (ex) {
            this.fireEvent("loadexception", this, trans, res, ex);
            this.fireEvent('exception', this, 'response', action, trans, res, ex);
            trans.callback.call(trans.scope, null, trans.arg, false);
            return;
        }
        this.fireEvent("load", this, res, trans.arg);
        trans.callback.call(trans.scope, records, trans.arg, true);
    },
    onWrite : function(action, trans, result, res, rs) {
        this.fireEvent("write", this, action, result, res, rs, trans.arg);
        trans.callback.call(trans.scope, result, res, true);
    }
});
pExt.data.JsonReader = function(meta, recordType){
    meta = meta || {};
    pExt.applyIf(meta, {
        idProperty: 'id',
        successProperty: 'success',
        totalProperty: 'total'
    });
    pExt.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
pExt.extend(pExt.data.JsonReader, pExt.data.DataReader, {
    read : function(response){
        var json = response.responseText;
        var o = pExt.decode(json);
        if(!o) {
            throw {message: "JsonReader.read: Json object not found"};
        }
        return this.readRecords(o);
    },
    onMetaChange : function(meta, recordType, o){
    },
    simpleAccess: function(obj, subsc) {
        return obj[subsc];
    },
    getJsonAccessor: 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 pExt.emptyFn;
        };
    }(),
    readRecords : function(o){
        this.jsonData = o;
        if(o.metaData){
            delete this.ef;
            this.meta = o.metaData;
            this.recordType = pExt.data.Record.create(o.metaData.fields);
            this.onMetaChange(this.meta, this.recordType, o);
        }
        var s = this.meta, Record = this.recordType,
            f = Record.prototype.fields, fi = f.items, fl = f.length, v;
        this.buildpExtractors();
        var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
        if(s.totalProperty){
            v = parseInt(this.getTotal(o), 10);
            if(!isNaN(v)){
                totalRecords = v;
            }
        }
        if(s.successProperty){
            v = this.getSuccess(o);
            if(v === false || v === 'false'){
                success = false;
            }
        }
        var records = [];
        for(var i = 0; i < c; i++){
            var n = root[i];
            var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
            record.json = n;
            records[i] = record;
        }
        return {
            success : success,
            records : records,
            totalRecords : totalRecords
        };
    },
    buildpExtractors : function() {
        if(this.ef){
            return;
        }
        var s = this.meta, Record = this.recordType,
            f = Record.prototype.fields, fi = f.items, fl = f.length;
        if(s.totalProperty) {
            this.getTotal = this.getJsonAccessor(s.totalProperty);
        }
        if(s.successProperty) {
            this.getSuccess = this.getJsonAccessor(s.successProperty);
        }
        this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
        if (s.id || s.idProperty) {
            var g = this.getJsonAccessor(s.id || s.idProperty);
            this.getId = function(rec) {
                var r = g(rec);
                return (r === undefined || r === "") ? null : r;
            };
        } else {
            this.getId = function(){return null;};
        }
        var ef = [];
        for(var i = 0; i < fl; i++){
            f = fi[i];
            var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
            ef.push(this.getJsonAccessor(map));
        }
        this.ef = ef;
    },
    extractValues: function(data, items, len) {
        var f, values = {};
        for(var j = 0; j < len; j++){
            f = items[j];
            var v = this.ef[j](data);
            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
        }
        return values;
    },
    readResponse : function(action, response) {
        var o = (response.responseText !== undefined) ? pExt.decode(response.responseText) : response;
        if(!o) {
            throw new pExt.data.JsonReader.Error('response');
        }
        if (pExt.isEmpty(o[this.meta.successProperty])) {
            throw new pExt.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
        }
        if ((action === pExt.data.Api.actions.create || action === pExt.data.Api.actions.update)) {
            if (pExt.isEmpty(o[this.meta.root])) {
                throw new pExt.data.JsonReader.Error('root-emtpy', this.meta.root);
            }
            else if (o[this.meta.root] === undefined) {
                throw new pExt.data.JsonReader.Error('root-undefined-response', this.meta.root);
            }
        }
        this.ef = this.buildpExtractors();
        return o;
    }
});
pExt.data.JsonReader.Error = pExt.extend(pExt.Error, {
    constructor : function(message, arg) {
        this.arg = arg;
        pExt.Error.call(this, message);
    },
    name : 'pExt.data.JsonReader'
});
pExt.apply(pExt.data.JsonReader.Error.prototype, {
    lang: {
        'response': "An error occurred while json-decoding your server response",
        'successProperty-response': 'Could not locate your "successProperty" in your server response.  Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response.  See the JsonReader docs.',
        'root-undefined-response': 'Could not locate your "root" property in your server response.  Please review your JsonReader config to ensure the config-property "root" matches the property your server-response.  See the JsonReader docs.',
        'root-undefined-config': 'Your JsonReader was configured without a "root" property.  Please review your JsonReader config and make sure to define the root property.  See the JsonReader docs.',
        'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty"  Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id").  See the JsonReader docs.',
        'root-emtpy': 'Data was expected to be returned by the server in the "root" property of the response.  Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response.  See JsonReader docs.'
    }
});
pExt.data.XmlReader = function(meta, recordType){
    meta = meta || {};
    pExt.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
pExt.extend(pExt.data.XmlReader, pExt.data.DataReader, {
    read : function(response){
        var doc = response.responseXML;
        if(!doc) {
            throw {message: "XmlReader.read: XML Document not available"};
        }
        return this.readRecords(doc);
    },
    readRecords : function(doc){
        this.xmlData = doc;
        var root = doc.documentElement || doc;
        var q = pExt.DomQuery;
        var recordType = this.recordType, fields = recordType.prototype.fields;
        var sid = this.meta.idPath || this.meta.id;
        var totalRecords = 0, success = true;
        if(this.meta.totalRecords){
            totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
        }
        if(this.meta.success){
            var sv = q.selectValue(this.meta.success, root, true);
            success = sv !== false && sv !== 'false';
        }
        var records = [];
        var ns = q.select(this.meta.record, root);
        for(var i = 0, len = ns.length; i < len; i++) {
            var n = ns[i];
            var values = {};
            var id = sid ? q.selectValue(sid, n) : undefined;
            for(var j = 0, jlen = fields.length; j < jlen; j++){
                var f = fields.items[j];
                var v = q.selectValue(pExt.value(f.mapping, f.name, true), n, f.defaultValue);
                v = f.convert(v, n);
                values[f.name] = v;
            }
            var record = new recordType(values, id);
            record.node = n;
            records[records.length] = record;
        }
        return {
            success : success,
            records : records,
            totalRecords : totalRecords || records.length
        };
    },
    readResponse : pExt.emptyFn
});
pExt.data.ArrayReader = pExt.extend(pExt.data.JsonReader, {
    readRecords : function(o){
        this.arrayData = o;
        var s = this.meta,
            sid = s ? pExt.num(s.idIndex, s.id) : null,
            recordType = this.recordType, 
            fields = recordType.prototype.fields,
            records = [],
            v;
        if(!this.getRoot) {
            this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p) {return p;};
            if(s.totalProperty) {
                this.getTotal = this.getJsonAccessor(s.totalProperty);
            }
        }
        var root = this.getRoot(o);
        for(var i = 0; i < root.length; i++) {
            var n = root[i];
            var values = {};
            var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
            for(var j = 0, jlen = fields.length; j < jlen; j++) {
                var f = fields.items[j];
                var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
                v = n[k] !== undefined ? n[k] : f.defaultValue;
                v = f.convert(v, n);
                values[f.name] = v;
            }
            var record = new recordType(values, id);
            record.json = n;
            records[records.length] = record;
        }
        var totalRecords = records.length;
        if(s.totalProperty) {
            v = parseInt(this.getTotal(o), 10);
            if(!isNaN(v)) {
                totalRecords = v;
            }
        }
        return {
            records : records,
            totalRecords : totalRecords
        };
    }
});
pExt.Direct = pExt.extend(pExt.util.Observable, {
    exceptions: {
        TRANSPORT: 'xhr',
        PARSE: 'parse',
        LOGIN: 'login',
        SERVER: 'exception'
    },
    constructor: function(){
        this.addEvents(
            'event',
            'exception'
        );
        this.transactions = {};
        this.providers = {};
    },
    addProvider : function(provider){        
        var a = arguments;
        if(a.length > 1){
            for(var i = 0, len = a.length; i < len; i++){
                this.addProvider(a[i]);
            }
            return;
        }
        if(!provider.events){
            provider = new pExt.Direct.PROVIDERS[provider.type](provider);
        }
        provider.id = provider.id || pExt.id();
        this.providers[provider.id] = provider;
        provider.on('data', this.onProviderData, this);
        provider.on('exception', this.onProviderException, this);
        if(!provider.isConnected()){
            provider.connect();
        }
        return provider;
    },
    getProvider : function(id){
        return this.providers[id];
    },
    removeProvider : function(id){
        var provider = id.id ? id : this.providers[id.id];
        provider.un('data', this.onProviderData, this);
        provider.un('exception', this.onProviderException, this);
        delete this.providers[provider.id];
        return provider;
    },
    addTransaction: function(t){
        this.transactions[t.tid] = t;
        return t;
    },
    removeTransaction: function(t){
        delete this.transactions[t.tid || t];
        return t;
    },
    getTransaction: function(tid){
        return this.transactions[tid.tid || tid];
    },
    onProviderData : function(provider, e){
        if(pExt.isArray(e)){
            for(var i = 0, len = e.length; i < len; i++){
                this.onProviderData(provider, e[i]);
            }
            return;
        }
        if(e.name && e.name != 'event' && e.name != 'exception'){
            this.fireEvent(e.name, e);
        }else if(e.type == 'exception'){
            this.fireEvent('exception', e);
        }
        this.fireEvent('event', e, provider);
    },
    createEvent : function(response, extraProps){
        return new pExt.Direct.eventTypes[response.type](pExt.apply(response, extraProps));
    }
});
pExt.Direct = new pExt.Direct();
pExt.Direct.TID = 1;
pExt.Direct.PROVIDERS = {};
pExt.Direct.Transaction = function(config){
    pExt.apply(this, config);
    this.tid = ++pExt.Direct.TID;
    this.retryCount = 0;
};
pExt.Direct.Transaction.prototype = {
    send: function(){
        this.provider.queueTransaction(this);
    },
    retry: function(){
        this.retryCount++;
        this.send();
    },
    getProvider: function(){
        return this.provider;
    }
};
pExt.Direct.Event = function(config){
    pExt.apply(this, config);
}
pExt.Direct.Event.prototype = {
    status: true,
    getData: function(){
        return this.data;
    }
};
pExt.Direct.RemotingEvent = pExt.extend(pExt.Direct.Event, {
    type: 'rpc',
    getTransaction: function(){
        return this.transaction || pExt.Direct.getTransaction(this.tid);
    }
});
pExt.Direct.ExceptionEvent = pExt.extend(pExt.Direct.RemotingEvent, {
    status: false,
    type: 'exception'
});
pExt.Direct.eventTypes = {
    'rpc':  pExt.Direct.RemotingEvent,
    'event':  pExt.Direct.Event,
    'exception':  pExt.Direct.ExceptionEvent
};
pExt.direct.Provider = pExt.extend(pExt.util.Observable, {    
    priority: 1,
    constructor : function(config){
        pExt.apply(this, config);
        this.addEvents(
            'connect',
            'disconnect',
            'data',
            'exception'
        );
        pExt.direct.Provider.superclass.constructor.call(this, config);
    },
    isConnected: function(){
        return false;
    },
    connect: pExt.emptyFn,
    disconnect: pExt.emptyFn
});
pExt.direct.JsonProvider = pExt.extend(pExt.direct.Provider, {
    parseResponse: function(xhr){
        if(!pExt.isEmpty(xhr.responseText)){
            if(typeof xhr.responseText == 'object'){
                return xhr.responseText;
            }
            return pExt.decode(xhr.responseText);
        }
        return null;
    },
    getEvents: function(xhr){
        var data = null;
        try{
            data = this.parseResponse(xhr);
        }catch(e){
            var event = new pExt.Direct.ExceptionEvent({
                data: e,
                xhr: xhr,
                code: pExt.Direct.exceptions.PARSE,
                message: 'Error parsing json response: \n\n ' + data
            })
            return [event];
        }
        var events = [];
        if(pExt.isArray(data)){
            for(var i = 0, len = data.length; i < len; i++){
                events.push(pExt.Direct.createEvent(data[i]));
            }
        }else{
            events.push(pExt.Direct.createEvent(data));
        }
        return events;
    }
});
pExt.direct.PollingProvider = pExt.extend(pExt.direct.JsonProvider, {
    priority: 3,
    interval: 3000,
    constructor : function(config){
        pExt.direct.PollingProvider.superclass.constructor.call(this, config);
        this.addEvents(
            'beforepoll',            
            'poll'
        );
    },
    isConnected: function(){
        return !!this.pollTask;
    },
    connect: function(){
        if(this.url && !this.pollTask){
            this.pollTask = pExt.TaskMgr.start({
                run: function(){
                    if(this.fireEvent('beforepoll', this) !== false){
                        if(typeof this.url == 'function'){
                            this.url(this.baseParams);
                        }else{
                            pExt.Ajax.request({
                                url: this.url,
                                callback: this.onData,
                                scope: this,
                                params: this.baseParams
                            });
                        }
                    }
                },
                interval: this.interval,
                scope: this
            });
            this.fireEvent('connect', this);
        }else if(!this.url){
            throw 'Error initializing PollingProvider, no url configured.';
        }
    },
    disconnect: function(){
        if(this.pollTask){
            pExt.TaskMgr.stop(this.pollTask);
            delete this.pollTask;
            this.fireEvent('disconnect', this);
        }
    },
    onData: function(opt, success, xhr){
        if(success){
            var events = this.getEvents(xhr);
            for(var i = 0, len = events.length; i < len; i++){
                var e = events[i];
                this.fireEvent('data', this, e);
            }
        }else{
            var e = new pExt.Direct.ExceptionEvent({
                data: e,
                code: pExt.Direct.exceptions.TRANSPORT,
                message: 'Unable to connect to the server.',
                xhr: xhr
            });
            this.fireEvent('data', this, e);
        }
    }
});
pExt.Direct.PROVIDERS['polling'] = pExt.direct.PollingProvider;
pExt.direct.RemotingProvider = pExt.extend(pExt.direct.JsonProvider, {       
    enableBuffer: 10,
    maxRetries: 1,
    constructor : function(config){
        pExt.direct.RemotingProvider.superclass.constructor.call(this, config);
        this.addEvents(
            'beforecall',
            'call'
        );
        this.namespace = (typeof this.namespace === 'string') ? pExt.ns(this.namespace) : this.namespace || window;
        this.transactions = {};
        this.callBuffer = [];
    },
    initAPI : function(){
        var o = this.actions;
        for(var c in o){
            var cls = this.namespace[c] || (this.namespace[c] = {});
            var ms = o[c];
            for(var i = 0, len = ms.length; i < len; i++){
                var m = ms[i];
                cls[m.name] = this.createMethod(c, m);
            }
        }
    },
    isConnected: function(){
        return !!this.connected;
    },
    connect: function(){
        if(this.url){
            this.initAPI();
            this.connected = true;
            this.fireEvent('connect', this);
        }else if(!this.url){
            throw 'Error initializing RemotingProvider, no url configured.';
        }
    },
    disconnect: function(){
        if(this.connected){
            this.connected = false;
            this.fireEvent('disconnect', this);
        }
    },
    onData: function(opt, success, xhr){
        if(success){
            var events = this.getEvents(xhr);
            for(var i = 0, len = events.length; i < len; i++){
                var e = events[i];
                var t = this.getTransaction(e);
                this.fireEvent('data', this, e);
                if(t){
                    this.doCallback(t, e, true);
                    pExt.Direct.removeTransaction(t);
                }
            }
        }else{
            var ts = [].concat(opt.ts);
            for(var i = 0, len = ts.length; i < len; i++){
                var t = this.getTransaction(ts[i]);
                if(t && t.retryCount < this.maxRetries){
                    t.retry();
                }else{
                    var e = new pExt.Direct.ExceptionEvent({
                        data: e,
                        transaction: t,
                        code: pExt.Direct.exceptions.TRANSPORT,
                        message: 'Unable to connect to the server.',
                        xhr: xhr
                    });
                    this.fireEvent('data', this, e);
                    if(t){
                        this.doCallback(t, e, false);
                        pExt.Direct.removeTransaction(t);
                    }
                }
            }
        }
    },
    getCallData: function(t){
        return {
            action: t.action,
            method: t.method,
            data: t.data,
            type: 'rpc',
            tid: t.tid
        };
    },
    doSend : function(data){
        var o = {
            url: this.url,
            callback: this.onData,
            scope: this,
            ts: data
        };
        var callData;
        if(pExt.isArray(data)){
            callData = [];
            for(var i = 0, len = data.length; i < len; i++){
                callData.push(this.getCallData(data[i]));
            }
        }else{
            callData = this.getCallData(data);
        }
        if(this.enableUrlEncode){
            var params = {};
            params[typeof this.enableUrlEncode == 'string' ? this.enableUrlEncode : 'data'] = pExt.encode(callData);
            o.params = params;
        }else{
            o.jsonData = callData;
        }
        pExt.Ajax.request(o);
    },
    combineAndSend : function(){
        var len = this.callBuffer.length;
        if(len > 0){
            this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
            this.callBuffer = [];
        }
    },
    queueTransaction: function(t){
        if(t.form){
            this.processForm(t);
            return;
        }
        this.callBuffer.push(t);
        if(this.enableBuffer){
            if(!this.callTask){
                this.callTask = new pExt.util.DelayedTask(this.combineAndSend, this);
            }
            this.callTask.delay(typeof this.enableBuffer == 'number' ? this.enableBuffer : 10);
        }else{
            this.combineAndSend();
        }
    },
    doCall : function(c, m, args){
        var data = null, hs = args[m.len], scope = args[m.len+1];
        if(m.len !== 0){
            data = args.slice(0, m.len);
        }
        var t = new pExt.Direct.Transaction({
            provider: this,
            args: args,
            action: c,
            method: m.name,
            data: data,
            cb: scope && pExt.isFunction(hs) ? hs.createDelegate(scope) : hs
        });
        if(this.fireEvent('beforecall', this, t) !== false){
            pExt.Direct.addTransaction(t);
            this.queueTransaction(t);
            this.fireEvent('call', this, t);
        }
    },
    doForm : function(c, m, form, callback, scope){
        var t = new pExt.Direct.Transaction({
            provider: this,
            action: c,
            method: m.name,
            args:[form, callback, scope],
            cb: scope && pExt.isFunction(callback) ? callback.createDelegate(scope) : callback,
            isForm: true
        });
        if(this.fireEvent('beforecall', this, t) !== false){
            pExt.Direct.addTransaction(t);
            var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
                params = {
                    extTID: t.tid,
                    extAction: c,
                    extMethod: m.name,
                    extType: 'rpc',
                    extUpload: String(isUpload)
                };
            pExt.apply(t, {
                form: pExt.getDom(form),
                isUpload: isUpload,
                params: callback && pExt.isObject(callback.params) ? pExt.apply(params, callback.params) : params
            });
            this.fireEvent('call', this, t);
            this.processForm(t);
        }
    },
    processForm: function(t){
        pExt.Ajax.request({
            url: this.url,
            params: t.params,
            callback: this.onData,
            scope: this,
            form: t.form,
            isUpload: t.isUpload,
            ts: t
        });
    },
    createMethod : function(c, m){
        var f;
        if(!m.formHandler){
            f = function(){
                this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
            }.createDelegate(this);
        }else{
            f = function(form, callback, scope){
                this.doForm(c, m, form, callback, scope);
            }.createDelegate(this);
        }
        f.directCfg = {
            action: c,
            method: m
        };
        return f;
    },
    getTransaction: function(opt){
        return opt && opt.tid ? pExt.Direct.getTransaction(opt.tid) : null;
    },
    doCallback: function(t, e){
        var fn = e.status ? 'success' : 'failure';
        if(t && t.cb){
            var hs = t.cb;
            var result = e.result || e.data;
            if(pExt.isFunction(hs)){
                hs(result, e);
            } else{
                pExt.callback(hs[fn], hs.scope, [result, e]);
                pExt.callback(hs.callback, hs.scope, [result, e]);
            }
        }
    }
});
pExt.Direct.PROVIDERS['remoting'] = pExt.direct.RemotingProvider;
pExt.data.Tree = function(root){
   this.nodeHash = {};
   this.root = null;
   if(root){
       this.setRootNode(root);
   }
   this.addEvents(
       "append",
       "remove",
       "move",
       "insert",
       "beforeappend",
       "beforeremove",
       "beforemove",
       "beforeinsert"
   );
    pExt.data.Tree.superclass.constructor.call(this);
};
pExt.extend(pExt.data.Tree, pExt.util.Observable, {
    pathSeparator: "/",
    proxyNodeEvent : function(){
        return this.fireEvent.apply(this, arguments);
    },
    getRootNode : function(){
        return this.root;
    },
    setRootNode : function(node){
        this.root = node;
        node.ownerTree = this;
        node.isRoot = true;
        this.registerNode(node);
        return node;
    },
    getNodeById : function(id){
        return this.nodeHash[id];
    },
    registerNode : function(node){
        this.nodeHash[node.id] = node;
    },
    unregisterNode : function(node){
        delete this.nodeHash[node.id];
    },
    toString : function(){
        return "[Tree"+(this.id?" "+this.id:"")+"]";
    }
});
pExt.data.Node = function(attributes){
    this.attributes = attributes || {};
    this.leaf = this.attributes.leaf;
    this.id = this.attributes.id;
    if(!this.id){
        this.id = pExt.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;
    pExt.data.Node.superclass.constructor.call(this);
};
pExt.extend(pExt.data.Node, pExt.util.Observable, {
    fireEvent : function(evtName){
        if(pExt.data.Node.superclass.fireEvent.apply(this, arguments) === false){
            return false;
        }
        var ot = this.getOwnerTree();
        if(ot){
            if(ot.proxyNodeEvent.apply(ot, arguments) === false){
                return false;
            }
        }
        return true;
    },
    isLeaf : function(){
        return this.leaf === true;
    },
    setFirstChild : function(node){
        this.firstChild = node;
    },
    setLastChild : function(node){
        this.lastChild = node;
    },
    isLast : function(){
       return (!this.parentNode ? true : this.parentNode.lastChild == this);
    },
    isFirst : function(){
       return (!this.parentNode ? true : this.parentNode.firstChild == this);
    },
    hasChildNodes : function(){
        return !this.isLeaf() && this.childNodes.length > 0;
    },
    isExpandable : function(){
        return this.attributes.expandable || this.hasChildNodes();
    },
    appendChild : function(node){
        var multi = false;
        if(pExt.isArray(node)){
            multi = node;
        }else if(arguments.length > 1){
            multi = arguments;
        }
        if(multi){
            for(var i = 0, len = multi.length; i < len; i++) {
            	this.appendChild(multi[i]);
            }
        }else{
            if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
                return false;
            }
            var index = this.childNodes.length;
            var oldParent = node.parentNode;
            if(oldParent){
                if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
                    return false;
                }
                oldParent.removeChild(node);
            }
            index = this.childNodes.length;
            if(index === 0){
                this.setFirstChild(node);
            }
            this.childNodes.push(node);
            node.parentNode = this;
            var ps = this.childNodes[index-1];
            if(ps){
                node.previousSibling = ps;
                ps.nextSibling = node;
            }else{
                node.previousSibling = null;
            }
            node.nextSibling = null;
            this.setLastChild(node);
            node.setOwnerTree(this.getOwnerTree());
            this.fireEvent("append", this.ownerTree, this, node, index);
            if(oldParent){
                node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
            }
            return node;
        }
    },
    removeChild : function(node){
        var index = this.childNodes.indexOf(node);
        if(index == -1){
            return false;
        }
        if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
            return false;
        }
        this.childNodes.splice(index, 1);
        if(node.previousSibling){
            node.previousSibling.nextSibling = node.nextSibling;
        }
        if(node.nextSibling){
            node.nextSibling.previousSibling = node.previousSibling;
        }
        if(this.firstChild == node){
            this.setFirstChild(node.nextSibling);
        }
        if(this.lastChild == node){
            this.setLastChild(node.previousSibling);
        }
        node.setOwnerTree(null);
        node.parentNode = null;
        node.previousSibling = null;
        node.nextSibling = null;
        this.fireEvent("remove", this.ownerTree, this, node);
        return node;
    },
    insertBefore : function(node, refNode){
        if(!refNode){ 
            return this.appendChild(node);
        }
        if(node == refNode){
            return false;
        }
        if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
            return false;
        }
        var index = this.childNodes.indexOf(refNode);
        var oldParent = node.parentNode;
        var refIndex = index;
        if(oldParent == this && this.childNodes.indexOf(node) < index){
            refIndex--;
        }
        if(oldParent){
            if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
                return false;
            }
            oldParent.removeChild(node);
        }
        if(refIndex === 0){
            this.setFirstChild(node);
        }
        this.childNodes.splice(refIndex, 0, node);
        node.parentNode = this;
        var ps = this.childNodes[refIndex-1];
        if(ps){
            node.previousSibling = ps;
            ps.nextSibling = node;
        }else{
            node.previousSibling = null;
        }
        node.nextSibling = refNode;
        refNode.previousSibling = node;
        node.setOwnerTree(this.getOwnerTree());
        this.fireEvent("insert", this.ownerTree, this, node, refNode);
        if(oldParent){
            node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
        }
        return node;
    },
    remove : function(){
        this.parentNode.removeChild(this);
        return this;
    },
    item : function(index){
        return this.childNodes[index];
    },
    replaceChild : function(newChild, oldChild){
        var s = oldChild ? oldChild.nextSibling : null;
        this.removeChild(oldChild);
        this.insertBefore(newChild, s);
        return oldChild;
    },
    indexOf : function(child){
        return this.childNodes.indexOf(child);
    },
    getOwnerTree : function(){
        if(!this.ownerTree){
            var p = this;
            while(p){
                if(p.ownerTree){
                    this.ownerTree = p.ownerTree;
                    break;
                }
                p = p.parentNode;
            }
        }
        return this.ownerTree;
    },
    getDepth : function(){
        var depth = 0;
        var p = this;
        while(p.parentNode){
            ++depth;
            p = p.parentNode;
        }
        return depth;
    },
    setOwnerTree : function(tree){
        if(tree != this.ownerTree){
            if(this.ownerTree){
                this.ownerTree.unregisterNode(this);
            }
            this.ownerTree = tree;
            var cs = this.childNodes;
            for(var i = 0, len = cs.length; i < len; i++) {
            	cs[i].setOwnerTree(tree);
            }
            if(tree){
                tree.registerNode(this);
            }
        }
    },
    setId: function(id){
        if(id !== this.id){
            var t = this.ownerTree;
            if(t){
                t.unregisterNode(this);
            }
            this.id = id;
            if(t){
                t.registerNode(this);
            }
            this.onIdChange(id);
        }
    },
    onIdChange: pExt.emptyFn,
    getPath : function(attr){
        attr = attr || "id";
        var p = this.parentNode;
        var b = [this.attributes[attr]];
        while(p){
            b.unshift(p.attributes[attr]);
            p = p.parentNode;
        }
        var sep = this.getOwnerTree().pathSeparator;
        return sep + b.join(sep);
    },
    bubble : function(fn, scope, args){
        var p = this;
        while(p){
            if(fn.apply(scope || p, args || [p]) === false){
                break;
            }
            p = p.parentNode;
        }
    },
    cascade : function(fn, scope, args){
        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);
            }
        }
    },
    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;
        	}
        }
    },
    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;
    },
    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];
        	}
        }
        return null;
    },
    sort : function(fn, scope){
        var cs = this.childNodes;
        var len = cs.length;
        if(len > 0){
            var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
            cs.sort(sortFn);
            for(var i = 0; i < len; i++){
                var n = cs[i];
                n.previousSibling = cs[i-1];
                n.nextSibling = cs[i+1];
                if(i === 0){
                    this.setFirstChild(n);
                }
                if(i == len-1){
                    this.setLastChild(n);
                }
            }
        }
    },
    contains : function(node){
        return node.isAncestor(this);
    },
    isAncestor : function(node){
        var p = this.parentNode;
        while(p){
            if(p == node){
                return true;
            }
            p = p.parentNode;
        }
        return false;
    },
    toString : function(){
        return "[Node"+(this.id?" "+this.id:"")+"]";
    }
});
pExt.data.GroupingStore = pExt.extend(pExt.data.Store, {
    constructor: function(config){
        pExt.data.GroupingStore.superclass.constructor.call(this, config);
        this.applyGroupField();
    },
    remoteGroup : false,
    groupOnSort:false,
	groupDir : 'ASC',
    clearGrouping : function(){
        this.groupField = false;
        if(this.remoteGroup){
            if(this.baseParams){
                delete this.baseParams.groupBy;
            }
            var lo = this.lastOptions;
            if(lo && lo.params){
                delete lo.params.groupBy;
            }
            this.reload();
        }else{
            this.applySort();
            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){
            return; 
        }
        this.groupField = field;
		this.groupDir = direction;
        this.applyGroupField();
        if(this.groupOnSort){
            this.sort(field, direction);
            return;
        }
        if(this.remoteGroup){
            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);
        }
    },
    applyGroupField: function(){
        if(this.remoteGroup){
            if(!this.baseParams){
                this.baseParams = {};
            }
            this.baseParams.groupBy = this.groupField;
            this.baseParams.groupDir = this.groupDir;
        }
    },
    applySort : function(){
        pExt.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);
            }
        }
    },
    applyGrouping : function(alwaysFireChange){
        if(this.groupField !== false){
            this.groupBy(this.groupField, true, this.groupDir);
            return true;
        }else{
            if(alwaysFireChange === true){
                this.fireEvent('datachanged', this);
            }
            return false;
        }
    },
    getGroupState : function(){
        return this.groupOnSort && this.groupField !== false ?
               (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
    }
});
pExt.reg('groupingstore', pExt.data.GroupingStore);
pExt.Component = function(config){
    config = config || {};
    if(config.initialConfig){
        if(config.isAction){           
            this.baseAction = config;
        }
        config = config.initialConfig; 
    }else if(config.tagName || config.dom || pExt.isString(config)){ 
        config = {applyTo: config, id: config.id || config};
    }
    this.initialConfig = config;
    pExt.apply(this, config);
    this.addEvents(
        'disable',
        'enable',
        'beforeshow',
        'show',
        'beforehide',
        'hide',
        'beforerender',
        'render',
        'afterrender',
        'beforedestroy',
        'destroy',
        'beforestaterestore',
        'staterestore',
        'beforestatesave',
        'statesave'
    );
    this.getId();
    pExt.ComponentMgr.register(this);
    pExt.Component.superclass.constructor.call(this);
    if(this.baseAction){
        this.baseAction.addComponent(this);
    }
    this.initComponent();
    if(this.plugins){
        if(pExt.isArray(this.plugins)){
            for(var i = 0, len = this.plugins.length; i < len; i++){
                this.plugins[i] = this.initPlugin(this.plugins[i]);
            }
        }else{
            this.plugins = this.initPlugin(this.plugins);
        }
    }
    if(this.stateful !== false){
        this.initState(config);
    }
    if(this.applyTo){
        this.applyToMarkup(this.applyTo);
        delete this.applyTo;
    }else if(this.renderTo){
        this.render(this.renderTo);
        delete this.renderTo;
    }
};
pExt.Component.AUTO_ID = 1000;
pExt.extend(pExt.Component, pExt.util.Observable, {
    disabled : false,
    hidden : false,
    autoEl : 'div',
    disabledClass : 'x-item-disabled',
    allowDomMove : true,
    autoShow : false,
    hideMode : 'display',
    hideParent : false,
    rendered : false,
    ctype : 'pExt.Component',
    actionMode : 'el',
    getActionEl : function(){
        return this[this.actionMode];
    },
    initPlugin : function(p){
        if(p.ptype && !pExt.isFunction(p.init)){
            p = pExt.ComponentMgr.createPlugin(p);
        }else if(pExt.isString(p)){
            p = pExt.ComponentMgr.createPlugin({
                ptype: p
            });
        }
        p.init(this);
        return p;
    },
    initComponent : pExt.emptyFn,
    render : function(container, position){
        if(!this.rendered && this.fireEvent('beforerender', this) !== false){
            if(!container && this.el){
                this.el = pExt.get(this.el);
                container = this.el.dom.parentNode;
                this.allowDomMove = false;
            }
            this.container = pExt.get(container);
            if(this.ctCls){
                this.container.addClass(this.ctCls);
            }
            this.rendered = true;
            if(position !== undefined){
                if(pExt.isNumber(position)){
                    position = this.container.dom.childNodes[position];
                }else{
                    position = pExt.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);
            this.afterRender(this.container);
            if(this.hidden){
                this.doHide();
            }
            if(this.disabled){
                this.disable(true);
            }
            if(this.stateful !== false){
                this.initStateEvents();
            }
            this.initRef();
            this.fireEvent('afterrender', this);
        }
        return this;
    },
    initRef : function(){
        if(this.ref){
            var levels = this.ref.split('/');
            var last = levels.length, i = 0;
            var t = this;
            while(i < last){
                if(t.ownerCt){
                    t = t.ownerCt;
                }
                i++;
            }
            t[levels[--i]] = this;
        }
    },
    initState : function(config){
        if(pExt.state.Manager){
            var id = this.getStateId();
            if(id){
                var state = pExt.state.Manager.get(id);
                if(state){
                    if(this.fireEvent('beforestaterestore', this, state) !== false){
                        this.applyState(state);
                        this.fireEvent('staterestore', this, state);
                    }
                }
            }
        }
    },
    getStateId : function(){
        return this.stateId || ((this.id.indexOf('pext-comp-') == 0 || this.id.indexOf('pext-gen') == 0) ? null : this.id);
    },
    initStateEvents : function(){
        if(this.stateEvents){
            for(var i = 0, e; e = this.stateEvents[i]; i++){
                this.on(e, this.saveState, this, {delay:100});
            }
        }
    },
    applyState : function(state, config){
        if(state){
            pExt.apply(this, state);
        }
    },
    getState : function(){
        return null;
    },
    saveState : function(){
        if(pExt.state.Manager && this.stateful !== false){
            var id = this.getStateId();
            if(id){
                var state = this.getState();
                if(this.fireEvent('beforestatesave', this, state) !== false){
                    pExt.state.Manager.set(id, state);
                    this.fireEvent('statesave', this, state);
                }
            }
        }
    },
    applyToMarkup : function(el){
        this.allowDomMove = false;
        this.el = pExt.get(el);
        this.render(this.el.dom.parentNode);
    },
    addClass : function(cls){
        if(this.el){
            this.el.addClass(cls);
        }else{
            this.cls = this.cls ? this.cls + ' ' + cls : cls;
        }
        return this;
    },
    removeClass : function(cls){
        if(this.el){
            this.el.removeClass(cls);
        }else if(this.cls){
            this.cls = this.cls.split(' ').remove(cls).join(' ');
        }
        return this;
    },
    onRender : function(ct, position){
        if(!this.el && this.autoEl){
            if(pExt.isString(this.autoEl)){
                this.el = document.createElement(this.autoEl);
            }else{
                var div = document.createElement('div');
                pExt.DomHelper.overwrite(div, this.autoEl);
                this.el = div.firstChild;
            }
            if (!this.el.id) {
                this.el.id = this.getId();
            }
        }
        if(this.el){
            this.el = pExt.get(this.el);
            if(this.allowDomMove !== false){
                ct.dom.insertBefore(this.el.dom, position);
            }
        }
    },
    getAutoCreate : function(){
        var cfg = pExt.isObject(this.autoCreate) ?
                      this.autoCreate : pExt.apply({}, this.defaultAutoCreate);
        if(this.id && !cfg.id){
            cfg.id = this.id;
        }
        return cfg;
    },
    afterRender : pExt.emptyFn,
    destroy : function(){
        if(this.fireEvent('beforedestroy', this) !== false){
            this.beforeDestroy();
            if(this.rendered){
                this.el.removeAllListeners();
                this.el.remove();
                if(this.actionMode == 'container' || this.removeMode == 'container'){
                    this.container.remove();
                }
            }
            this.onDestroy();
            pExt.ComponentMgr.unregister(this);
            this.fireEvent('destroy', this);
            this.purgeListeners();
        }
    },
    beforeDestroy : pExt.emptyFn,
    onDestroy  : pExt.emptyFn,
    getEl : function(){
        return this.el;
    },
    getId : function(){
        return this.id || (this.id = 'pext-comp-' + (++pExt.Component.AUTO_ID));
    },
    getItemId : function(){
        return this.itemId || this.getId();
    },
    focus : function(selectText, delay){
        if(delay){
            this.focus.defer(pExt.isNumber(delay) ? delay : 10, this, [selectText, false]);
            return;
        }
        if(this.rendered){
            this.el.focus();
            if(selectText === true){
                this.el.dom.select();
            }
        }
        return this;
    },
    blur : function(){
        if(this.rendered){
            this.el.blur();
        }
        return this;
    },
    disable : function(  silent){
        if(this.rendered){
            this.onDisable();
        }
        this.disabled = true;
        if(silent !== true){
            this.fireEvent('disable', this);
        }
        return this;
    },
    onDisable : function(){
        this.getActionEl().addClass(this.disabledClass);
        this.el.dom.disabled = true;
    },
    enable : function(){
        if(this.rendered){
            this.onEnable();
        }
        this.disabled = false;
        this.fireEvent('enable', this);
        return this;
    },
    onEnable : function(){
        this.getActionEl().removeClass(this.disabledClass);
        this.el.dom.disabled = false;
    },
    setDisabled : function(disabled){
        return this[disabled ? 'disable' : 'enable']();
    },
    show : function(){
        if(this.fireEvent('beforeshow', this) !== false){
            this.hidden = false;
            if(this.autoRender){
                this.render(pExt.isBoolean(this.autoRender) ? pExt.getBody() : this.autoRender);
            }
            if(this.rendered){
                this.onShow();
            }
            this.fireEvent('show', this);
        }
        return this;
    },
    onShow : function(){
        this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);
    },
    hide : function(){
        if(this.fireEvent('beforehide', this) !== false){
            this.doHide();
            this.fireEvent('hide', this);
        }
        return this;
    },
    doHide: function(){
        this.hidden = true;
        if(this.rendered){
            this.onHide();
        }
    },
    onHide : function(){
        this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);
    },
    getVisibiltyEl : function(){
        return this.hideParent ? this.container : this.getActionEl();
    },
    setVisible : function(visible){
        return this[visible ? 'show' : 'hide']();
    },
    isVisible : function(){
        return this.rendered && this.getVisibiltyEl().isVisible();
    },
    cloneConfig : function(overrides){
        overrides = overrides || {};
        var id = overrides.id || pExt.id();
        var cfg = pExt.applyIf(overrides, this.initialConfig);
        cfg.id = id; 
        return new this.constructor(cfg);
    },
    getXType : function(){
        return this.constructor.xtype;
    },
    isXType : function(xtype, shallow){
        if (pExt.isFunction(xtype)){
            xtype = xtype.xtype; 
        }else if (pExt.isObject(xtype)){
            xtype = xtype.constructor.xtype; 
        }
        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
    },
    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;
    },
    findParentByType : function(xtype) {
        return pExt.isFunction(xtype) ?
            this.findParentBy(function(p){
                return p.constructor === xtype;
            }) :
            this.findParentBy(function(p){
                return p.constructor.xtype === xtype;
            });
    },
    getDomPositionEl : function(){
        return this.getPositionEl ? this.getPositionEl() : this.getEl();
    },
    purgeListeners : function(){
        pExt.Component.superclass.purgeListeners.call(this);
        if(this.mons){
            this.on('beforedestroy', this.clearMons, this, {single: true});
        }
    },
    clearMons : function(){
        pExt.each(this.mons, function(m){
            m.item.un(m.ename, m.fn, m.scope);
        }, this);
        this.mons = [];
    },
    mon : function(item, ename, fn, scope, opt){
        if(!this.mons){
            this.mons = [];
            this.on('beforedestroy', this.clearMons, this, {single: true});
        }
        if(pExt.isObject(ename)){
        	var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
            var o = ename;
            for(var e in o){
                if(propRe.test(e)){
                    continue;
                }
                if(pExt.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]);
                }
            }
            return;
        }
        this.mons.push({
            item: item, ename: ename, fn: fn, scope: scope
        });
        item.on(ename, fn, scope, opt);
    },
    mun : function(item, ename, fn, scope){
        var found, mon;
        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;
    }
});
pExt.reg('component', pExt.Component);
pExt.Action = function(config){
    this.initialConfig = config;
    this.itemId = config.itemId = (config.itemId || config.id || pExt.id());
    this.items = [];
}
pExt.Action.prototype = {
    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;
    },
    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;
    },
    setHidden : function(v){
        this.initialConfig.hidden = v;
        this.callEach('setVisible', [!v]);
    },
    show : function(){
        this.setHidden(false);
    },
    hide : function(){
        this.setHidden(true);
    },
    isHidden : function(){
        return this.initialConfig.hidden;
    },
    setHandler : function(fn, scope){
        this.initialConfig.handler = fn;
        this.initialConfig.scope = scope;
        this.callEach('setHandler', [fn, scope]);
    },
    each : function(fn, scope){
        pExt.each(this.items, fn, scope);
    },
    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);
        }
    },
    addComponent : function(comp){
        this.items.push(comp);
        comp.on('destroy', this.removeComponent, this);
    },
    removeComponent : function(comp){
        this.items.remove(comp);
    },
    execute : function(){
        this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
    }
};
(function(){
pExt.Layer = function(config, existingEl){
    config = config || {};
    var dh = pExt.DomHelper;
    var cp = config.parentEl, pel = cp ? pExt.getDom(cp) : document.body;
    if(existingEl){
        this.dom = pExt.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(pExt.Element.VISIBILITY);
    if(config.id){
        this.id = this.dom.id = config.id;
    }else{
        this.id = pExt.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 pExt.Shadow({
            offset : this.shadowOffset,
            mode : config.shadow
        });
    }else{
        this.shadowOffset = 0;
    }
    this.useShim = config.shim !== false && pExt.useShims;
    this.useDisplay = config.useDisplay;
    this.hide();
};
var supr = pExt.Element.prototype;
var shims = [];
pExt.extend(pExt.Layer, pExt.Element, {
    getZIndex : function(){
        return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
    },
    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;
    },
    hideShim : function(){
        if(this.shim){
            this.shim.setDisplayed(false);
            shims.push(this.shim);
            delete this.shim;
        }
    },
    disableShadow : function(){
        if(this.shadow){
            this.shadowDisabled = true;
            this.shadow.hide();
            this.lastShadowOffset = this.shadowOffset;
            this.shadowOffset = 0;
        }
    },
    enableShadow : function(show){
        if(this.shadow){
            this.shadowDisabled = false;
            this.shadowOffset = this.lastShadowOffset;
            delete this.lastShadowOffset;
            if(show){
                this.sync(true);
            }
        }
    },
    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);
            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();
        pExt.removeNode(this.dom);
        pExt.Element.uncache(this.id);
    },
    remove : function(){
        this.destroy();
    },
    beginUpdate : function(){
        this.updating = true;
    },
    endUpdate : function(){
        this.updating = false;
        this.sync(true);
    },
    hideUnders : function(negOffset){
        if(this.shadow){
            this.shadow.hide();
        }
        this.hideShim();
    },
    constrainXY : function(){
        if(this.constrain){
            var vw = pExt.lib.Dom.getViewWidth(),
                vh = pExt.lib.Dom.getViewHeight();
            var s = pExt.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;
    },
    isVisible : function(){
        return this.visible;
    },
    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]);
        }
    },
    hideAction : function(){
        this.visible = false;
        if(this.useDisplay === true){
            this.setDisplayed(false);
        }else{
            this.setLeftTop(-10000,-10000);
        }
    },
    setVisible : function(v, a, d, c, e){
        if(v){
            this.showAction();
        }
        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];
    },
    beforeFx : function(){
        this.beforeAction();
        return pExt.Layer.superclass.beforeFx.apply(this, arguments);
    },
    afterFx : function(){
        pExt.Layer.superclass.afterFx.apply(this, arguments);
        this.sync(this.isVisible());
    },
    beforeAction : function(){
        if(!this.updating && this.shadow){
            this.shadow.hide();
        }
    },
    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;
    },
    createCB : function(c){
        var el = this;
        return function(){
            el.constrainXY();
            el.sync(true);
            if(c){
                c();
            }
        };
    },
    setX : function(x, a, d, c, e){
        this.setXY([x, this.getY()], a, d, c, e);
        return this;
    },
    setY : function(y, a, d, c, e){
        this.setXY([this.getX(), y], a, d, c, e);
        return this;
    },
    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;
    },
    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;
    },
    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;
    },
    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;
    },
    setZIndex : function(zindex){
        this.zindex = zindex;
        this.setStyle('z-index', zindex + 2);
        if(this.shadow){
            this.shadow.setZIndex(zindex + 1);
        }
        if(this.shim){
            this.shim.setStyle('z-index', zindex);
        }
        return this;
    }
});
})();
pExt.Shadow = function(config){
    pExt.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(pExt.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(pExt.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(pExt.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;
};
pExt.Shadow.prototype = {
    offset: 4,
    defaultMode: "drop",
    show : function(target){
        target = pExt.get(target);
        if(!this.el){
            this.el = pExt.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(pExt.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";
    },
    isVisible : function(){
        return this.el ? true : false;  
    },
    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(!pExt.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";
            }
        }
    },
    hide : function(){
        if(this.el){
            this.el.dom.style.display = "none";
            pExt.Shadow.Pool.push(this.el);
            delete this.el;
        }
    },
    setZIndex : function(z){
        this.zIndex = z;
        if(this.el){
            this.el.setStyle("z-index", z);
        }
    }
};
pExt.Shadow.Pool = function(){
    var p = [];
    var markup = pExt.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 = pExt.get(pExt.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
                sh.autoBoxAdjust = false;
            }
            return sh;
        },
        push : function(sh){
            p.push(sh);
        }
    };
}();
pExt.BoxComponent = pExt.extend(pExt.Component, {
    initComponent : function(){
        pExt.BoxComponent.superclass.initComponent.call(this);
        this.addEvents(
            'resize',
            'move'
        );
    },
    boxReady : false,
    deferHeight: false,
    setSize : function(w, h){
        if(typeof w == 'object'){
            h = w.height;
            w = w.width;
        }
        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);
        var aw = adj.width, ah = adj.height;
        if(aw !== undefined || ah !== undefined){ 
            var 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;
    },
    setWidth : function(width){
        return this.setSize(width);
    },
    setHeight : function(height){
        return this.setSize(undefined, height);
    },
    getSize : function(){
        return this.getResizeEl().getSize();
    },
    getWidth : function(){
        return this.getResizeEl().getWidth();
    },
    getHeight : function(){
        return this.getResizeEl().getHeight();
    },
    getOuterSize : function(){
        var el = this.getResizeEl();
        return {width: el.getWidth() + el.getMargins('lr'),
                height: el.getHeight() + el.getMargins('tb')};
    },
    getPosition : function(local){
        var el = this.getPositionEl();
        if(local === true){
            return [el.getLeft(true), el.getTop(true)];
        }
        return this.xy || el.getXY();
    },
    getBox : function(local){
        var pos = this.getPosition(local);
        var s = this.getSize();
        s.x = pos[0];
        s.y = pos[1];
        return s;
    },
    updateBox : function(box){
        this.setSize(box.width, box.height);
        this.setPagePosition(box.x, box.y);
        return this;
    },
    getResizeEl : function(){
        return this.resizeEl || this.el;
    },
    getPositionEl : function(){
        return this.positionEl || this.el;
    },
    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 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);
            }
            this.onPosition(ax, ay);
            this.fireEvent('move', this, ax, ay);
        }
        return this;
    },
    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;
    },
    onRender : function(ct, position){
        pExt.BoxComponent.superclass.onRender.call(this, ct, position);
        if(this.resizeEl){
            this.resizeEl = pExt.get(this.resizeEl);
        }
        if(this.positionEl){
            this.positionEl = pExt.get(this.positionEl);
        }
    },
    afterRender : function(){
        pExt.BoxComponent.superclass.afterRender.call(this);
        this.boxReady = true;
        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){
    },
    onPosition : function(x, y){
    },
    adjustSize : function(w, h){
        if(this.autoWidth){
            w = 'auto';
        }
        if(this.autoHeight){
            h = 'auto';
        }
        return {width : w, height: h};
    },
    adjustPosition : function(x, y){
        return {x : x, y: y};
    }
});
pExt.reg('box', pExt.BoxComponent);
pExt.Spacer = pExt.extend(pExt.BoxComponent, {
    autoEl:'div'
});
pExt.reg('spacer', pExt.Spacer);
pExt.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
    this.el = pExt.get(dragElement, true);
    this.el.dom.unselectable = "on";
    this.resizingEl = pExt.get(resizingElement, true);
    this.orientation = orientation || pExt.SplitBar.HORIZONTAL;
    this.minSize = 0;
    this.maxSize = 2000;
    this.animate = false;
    this.useShim = false;
    this.shim = null;
    if(!existingProxy){
        this.proxy = pExt.SplitBar.createProxy(this.orientation);
    }else{
        this.proxy = pExt.get(existingProxy).dom;
    }
    this.dd = new pExt.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
    this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
    this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
    this.dragSpecs = {};
    this.adapter = new pExt.SplitBar.BasicLayoutAdapter();
    this.adapter.init(this);
    if(this.orientation == pExt.SplitBar.HORIZONTAL){
        this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? pExt.SplitBar.LEFT : pExt.SplitBar.RIGHT);
        this.el.addClass("x-splitbar-h");
    }else{
        this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? pExt.SplitBar.TOP : pExt.SplitBar.BOTTOM);
        this.el.addClass("x-splitbar-v");
    }
    this.addEvents(
        "resize",
        "moved",
        "beforeresize",
        "beforeapply"
    );
    pExt.SplitBar.superclass.constructor.call(this);
};
pExt.extend(pExt.SplitBar, pExt.util.Observable, {
    onStartProxyDrag : function(x, y){
        this.fireEvent("beforeresize", this);
        this.overlay =  pExt.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);
        this.overlay.unselectable();
        this.overlay.setSize(pExt.lib.Dom.getViewWidth(true), pExt.lib.Dom.getViewHeight(true));
        this.overlay.show();
        pExt.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 == pExt.SplitBar.HORIZONTAL){
            this.dd.resetConstraints();
            this.dd.setXConstraint(
                this.placement == pExt.SplitBar.LEFT ? c1 : c2, 
                this.placement == pExt.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 == pExt.SplitBar.TOP ? c1 : c2, 
                this.placement == pExt.SplitBar.TOP ? c2 : c1,
                this.tickSize
            );
         }
        this.dragSpecs.startSize = size;
        this.dragSpecs.startPoint = [x, y];
        pExt.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
    },
    onEndProxyDrag : function(e){
        pExt.get(this.proxy).setDisplayed(false);
        var endPoint = pExt.lib.Event.getXY(e);
        if(this.overlay){
            pExt.destroy(this.overlay);
            delete this.overlay;
        }
        var newSize;
        if(this.orientation == pExt.SplitBar.HORIZONTAL){
            newSize = this.dragSpecs.startSize + 
                (this.placement == pExt.SplitBar.LEFT ?
                    endPoint[0] - this.dragSpecs.startPoint[0] :
                    this.dragSpecs.startPoint[0] - endPoint[0]
                );
        }else{
            newSize = this.dragSpecs.startSize + 
                (this.placement == pExt.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);
            }
        }
    },
    getAdapter : function(){
        return this.adapter;
    },
    setAdapter : function(adapter){
        this.adapter = adapter;
        this.adapter.init(this);
    },
    getMinimumSize : function(){
        return this.minSize;
    },
    setMinimumSize : function(minSize){
        this.minSize = minSize;
    },
    getMaximumSize : function(){
        return this.maxSize;
    },
    setMaximumSize : function(maxSize){
        this.maxSize = maxSize;
    },
    setCurrentSize : function(size){
        var oldAnimate = this.animate;
        this.animate = false;
        this.adapter.setElementSize(this, size);
        this.animate = oldAnimate;
    },
    destroy : function(removeEl){
		pExt.destroy(this.shim, pExt.get(this.proxy));
        this.dd.unreg();
        if(removeEl){
            this.el.remove();
        }
		this.purgeListeners();
    }
});
pExt.SplitBar.createProxy = function(dir){
    var proxy = new pExt.Element(document.createElement("div"));
    proxy.unselectable();
    var cls = 'x-splitbar-proxy';
    proxy.addClass(cls + ' ' + (dir == pExt.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
    document.body.appendChild(proxy.dom);
    return proxy.dom;
};
pExt.SplitBar.BasicLayoutAdapter = function(){
};
pExt.SplitBar.BasicLayoutAdapter.prototype = {
    init : function(s){
    },
     getElementSize : function(s){
        if(s.orientation == pExt.SplitBar.HORIZONTAL){
            return s.resizingEl.getWidth();
        }else{
            return s.resizingEl.getHeight();
        }
    },
    setElementSize : function(s, newSize, onComplete){
        if(s.orientation == pExt.SplitBar.HORIZONTAL){
            if(!s.animate){
                s.resizingEl.setWidth(newSize);
                if(onComplete){
                    onComplete(s, newSize);
                }
            }else{
                s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
            }
        }else{
            if(!s.animate){
                s.resizingEl.setHeight(newSize);
                if(onComplete){
                    onComplete(s, newSize);
                }
            }else{
                s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
            }
        }
    }
};
pExt.SplitBar.AbsoluteLayoutAdapter = function(container){
    this.basic = new pExt.SplitBar.BasicLayoutAdapter();
    this.container = pExt.get(container);
};
pExt.SplitBar.AbsoluteLayoutAdapter.prototype = {
    init : function(s){
        this.basic.init(s);
    },
    getElementSize : function(s){
        return this.basic.getElementSize(s);
    },
    setElementSize : function(s, newSize, onComplete){
        this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
    },
    moveSplitter : function(s){
        var yes = pExt.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;
        }
    }
};
pExt.SplitBar.VERTICAL = 1;
pExt.SplitBar.HORIZONTAL = 2;
pExt.SplitBar.LEFT = 1;
pExt.SplitBar.RIGHT = 2;
pExt.SplitBar.TOP = 3;
pExt.SplitBar.BOTTOM = 4;
pExt.Container = pExt.extend(pExt.BoxComponent, {
    bufferResize: 100,
    autoDestroy : true,
    forceLayout: false,
    defaultType : 'panel',
    initComponent : function(){
        pExt.Container.superclass.initComponent.call(this);
        this.addEvents(
            'afterlayout',
            'beforeadd',
            'beforeremove',
            'add',
            'remove'
        );
		this.enableBubble('add', 'remove');
        var items = this.items;
        if(items){
            delete this.items;
            if(pExt.isArray(items) && items.length > 0){
                this.add.apply(this, items);
            }else{
                this.add(items);
            }
        }
    },
    initItems : function(){
        if(!this.items){
            this.items = new pExt.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);
    },
    render : function(){
        pExt.Container.superclass.render.apply(this, arguments);
        if(this.layout){
            if(pExt.isObject(this.layout) && !this.layout.layout){
                this.layoutConfig = this.layout;
                this.layout = this.layoutConfig.type;
            }
            if(typeof this.layout == 'string'){
                this.layout = new pExt.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
            }
            this.setLayout(this.layout);
            if(this.activeItem !== undefined){
                var item = this.activeItem;
                delete this.activeItem;
                this.layout.setActiveItem(item);
            }
        }
        if(!this.ownerCt){
            this.doLayout(false, true);
        }
        if(this.monitorResize === true){
            pExt.EventManager.onWindowResize(this.doLayout, this, [false]);
        }
    },
    getLayoutTarget : function(){
        return this.el;
    },
    getComponentId : function(comp){
        return comp.getItemId();
    },
    add : function(comp){
        this.initItems();
        var args = arguments.length > 1;
        if(args || pExt.isArray(comp)){
            pExt.each(args ? arguments : comp, function(c){
                this.add(c);
            }, this);
            return;
        }
        var c = this.lookupComponent(this.applyDefaults(comp));
        var pos = this.items.length;
        if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
            this.items.add(c);
            c.ownerCt = this;
            this.fireEvent('add', this, c, pos);
        }
        return c;
    },
    insert : function(index, comp){
        this.initItems();
        var a = arguments, len = a.length;
        if(len > 2){
            for(var i = len-1; i >= 1; --i) {
                this.insert(index, a[i]);
            }
            return;
        }
        var c = this.lookupComponent(this.applyDefaults(comp));
        if(c.ownerCt == this && this.items.indexOf(c) < index){
            --index;
        }
        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
            this.items.insert(index, c);
            c.ownerCt = this;
            this.fireEvent('add', this, c, index);
        }
        return c;
    },
    applyDefaults : function(c){
        if(this.defaults){
            if(typeof c == 'string'){
                c = pExt.ComponentMgr.get(c);
                pExt.apply(c, this.defaults);
            }else if(!c.events){
                pExt.applyIf(c, this.defaults);
            }else{
                pExt.apply(c, this.defaults);
            }
        }
        return c;
    },
    onBeforeAdd : function(item){
        if(item.ownerCt){
            item.ownerCt.remove(item, false);
        }
        if(this.hideBorders === true){
            item.border = (item.border === true);
        }
    },
    remove : function(comp, autoDestroy){
        this.initItems();
        var c = this.getComponent(comp);
        if(c && this.fireEvent('beforeremove', this, c) !== false){
            this.items.remove(c);
            delete c.ownerCt;
            if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
                c.destroy();
            }
            if(this.layout && this.layout.activeItem == c){
                delete this.layout.activeItem;
            }
            this.fireEvent('remove', this, c);
        }
        return c;
    },
    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);
            }
        }
        return items;
    },
    getComponent : function(comp){
        if(pExt.isObject(comp)){
            return comp;
        }
        return this.items.get(comp);
    },
    lookupComponent : function(comp){
        if(typeof comp == 'string'){
            return pExt.ComponentMgr.get(comp);
        }else if(!comp.events){
            return this.createComponent(comp);
        }
        return comp;
    },
    createComponent : function(config){
        return pExt.create(config, this.defaultType);
    },
    doLayout: function(shallow, force){
        var rendered = this.rendered,
            forceLayout = this.forceLayout;
        if(!this.isVisible() || this.collapsed){
            this.deferLayout = this.deferLayout || !shallow;
            if(!(force || forceLayout)){
                return;
            }
            shallow = shallow && !this.deferLayout;
        } else {
            delete this.deferLayout;
        }
        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.forceLayout = forceLayout;
                    c.doLayout();
                }
            }
        }
        if(rendered){
            this.onLayout(shallow, force);
        }
        delete this.forceLayout;
    },
    onLayout : pExt.emptyFn,
    onShow : function(){
        pExt.Container.superclass.onShow.call(this);
        if(this.deferLayout !== undefined){
            this.doLayout(true);
        }
    },
    getLayout : function(){
        if(!this.layout){
            var layout = new pExt.layout.ContainerLayout(this.layoutConfig);
            this.setLayout(layout);
        }
        return this.layout;
    },
    beforeDestroy : function(){
        if(this.items){
            pExt.destroy.apply(pExt, this.items.items);
        }
        if(this.monitorResize){
            pExt.EventManager.removeResizeListener(this.doLayout, this);
        }
        pExt.destroy(this.layout);
        pExt.Container.superclass.beforeDestroy.call(this);
    },
    bubble : function(fn, scope, args){
        var p = this;
        while(p){
            if(fn.apply(scope || p, args || [p]) === false){
                break;
            }
            p = p.ownerCt;
        }
        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;
    },
    findById : function(id){
        var m, ct = this;
        this.cascade(function(c){
            if(ct != c && c.id === id){
                m = c;
                return false;
            }
        });
        return m || null;
    },
    findByType : function(xtype, shallow){
        return this.findBy(function(c){
            return c.isXType(xtype, shallow);
        });
    },
    find : function(prop, value){
        return this.findBy(function(c){
            return c[prop] === value;
        });
    },
    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;
    },
    get : function(key){
        return this.items.get(key);
    }
});
pExt.Container.LAYOUTS = {};
pExt.reg('container', pExt.Container);
pExt.layout.ContainerLayout = function(config){
    pExt.apply(this, config);
};
pExt.layout.ContainerLayout.prototype = {
    monitorResize:false,
    activeItem : null,
    layout : function(){
        var target = this.container.getLayoutTarget();
        this.onLayout(this.container, target);
        this.container.fireEvent('afterlayout', this.container, this);
    },
    onLayout : function(ct, target){
        this.renderAll(ct, target);
    },
    isValidParent : function(c, target){
		return target && c.getDomPositionEl().dom.parentNode == (target.dom || target);
    },
    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);
            }
        }
    },
    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(typeof position == 'number'){
                position = target.dom.childNodes[position];
            }
            target.dom.insertBefore(c.getDomPositionEl().dom, position || null);
            c.container = target;
            this.configureItem(c, position);
        }
    },
    configureItem: function(c, position){
        if(this.extraCls){
            var t = c.getPositionEl ? c.getPositionEl() : c;
            t.addClass(this.extraCls);
        }
        if (this.renderHidden && c != this.activeItem) {
            c.hide();
        }
        if(c.doLayout){
            c.doLayout(false, this.forceLayout);
        }
    },
    onResize: function(){
        if(this.container.collapsed){
            return;
        }
        var b = this.container.bufferResize;
        if(b){
            if(!this.resizeTask){
                this.resizeTask = new pExt.util.DelayedTask(this.runLayout, this);
                this.resizeBuffer = typeof b == 'number' ? b : 100;
            }
            this.resizeTask.delay(this.resizeBuffer);
        }else{
            this.runLayout();
        }
    },
    runLayout: function(){
        this.layout();
        this.container.onLayout();
    },
    setContainer : function(ct){
        if(this.monitorResize && ct != this.container){
            if(this.container){
                this.container.un('resize', this.onResize, this);
                this.container.un('bodyresize', this.onResize, this);
            }
            if(ct){
                ct.on({
                    scope: this,
                    resize: this.onResize,
                    bodyresize: this.onResize
                });
            }
        }
        this.container = ct;
    },
    parseMargins : function(v){
        if(typeof v == 'number'){
            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];
        }
        if(len == 3){
            ms[3] = ms[1];
        }
        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 pExt.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 : pExt.emptyFn
};
pExt.Container.LAYOUTS['auto'] = pExt.layout.ContainerLayout;
pExt.layout.FitLayout = pExt.extend(pExt.layout.ContainerLayout, {
    monitorResize:true,
    onLayout : function(ct, target){
        pExt.layout.FitLayout.superclass.onLayout.call(this, ct, target);
        if(!this.container.collapsed){
            var sz = (pExt.isIE6 && pExt.isStrict && target.dom == document.body) ? target.getViewSize() : target.getStyleSize();
            this.setItemSize(this.activeItem || ct.items.itemAt(0), sz);
        }
    },
    setItemSize : function(item, size){
        if(item && size.height > 0){ 
            item.setSize(size);
        }
    }
});
pExt.Container.LAYOUTS['fit'] = pExt.layout.FitLayout;
pExt.layout.CardLayout = pExt.extend(pExt.layout.FitLayout, {
    deferredRender : false,
    layoutOnCardChange : false,
    renderHidden : true,
    constructor: function(config){
        pExt.layout.CardLayout.superclass.constructor.call(this, config);
        this.forceLayout = (this.deferredRender === false);
    },
    setActiveItem : function(item){
        item = this.container.getComponent(item);
        if(this.activeItem != item){
            if(this.activeItem){
                this.activeItem.hide();
            }
            this.activeItem = item;
            item.show();
            this.container.doLayout();
            if(this.layoutOnCardChange && item.doLayout){
                item.doLayout();
            }
        }
    },
    renderAll : function(ct, target){
        if(this.deferredRender){
            this.renderItem(this.activeItem, undefined, target);
        }else{
            pExt.layout.CardLayout.superclass.renderAll.call(this, ct, target);
        }
    }
});
pExt.Container.LAYOUTS['card'] = pExt.layout.CardLayout;
pExt.layout.AnchorLayout = pExt.extend(pExt.layout.ContainerLayout, {
    monitorResize:true,
    getAnchorViewSize : function(ct, target){
        return target.dom == document.body ?
                   target.getViewSize() : target.getStyleSize();
    },
    onLayout : function(ct, target){
        pExt.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
        var size = this.getAnchorViewSize(ct, target);
        var w = size.width, h = size.height;
        if(w < 20 && h < 20){
            return;
        }
        var aw, ah;
        if(ct.anchorSize){
            if(typeof ct.anchorSize == 'number'){
                aw = ct.anchorSize;
            }else{
                aw = ct.anchorSize.width;
                ah = ct.anchorSize.height;
            }
        }else{
            aw = ct.initialConfig.width;
            ah = ct.initialConfig.height;
        }
        var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
        for(i = 0; i < len; i++){
            c = cs[i];
            if(c.anchor){
                a = c.anchorSpec;
                if(!a){ 
                    var 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), c) : undefined;
                ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
                if(cw || ch){
                    c.setSize(cw || undefined, ch || undefined);
                }
            }
        }
    },
    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;
                        }
                    }
                }
            }
        }
        return false;
    },
    adjustWidthAnchor : function(value, comp){
        return value;
    },
    adjustHeightAnchor : function(value, comp){
        return value;
    }
});
pExt.Container.LAYOUTS['anchor'] = pExt.layout.AnchorLayout;
pExt.layout.ColumnLayout = pExt.extend(pExt.layout.ContainerLayout, {
    monitorResize:true,
    extraCls: 'x-column',
    scrollOffset : 0,
    isValidParent : function(c, target){
        return (c.getPositionEl ? c.getPositionEl() : c.getEl()).dom.parentNode == this.innerCt.dom;
    },
    onLayout : function(ct, target){
        var cs = ct.items.items, len = cs.length, c, i;
        if(!this.innerCt){
            target.addClass('x-column-layout-ct');
            this.innerCt = target.createChild({cls:'x-column-inner'});
            this.innerCt.createChild({cls:'x-clear'});
        }
        this.renderAll(ct, this.innerCt);
        var size = pExt.isIE && target.dom != pExt.getBody().dom ? target.getStyleSize() : target.getViewSize();
        if(size.width < 1 && size.height < 1){ 
            return;
        }
        var w = size.width - target.getPadding('lr') - this.scrollOffset,
            h = size.height - target.getPadding('tb'),
            pw = w;
        this.innerCt.setWidth(w);
        for(i = 0; i < len; i++){
            c = cs[i];
            if(!c.columnWidth){
                pw -= (c.getSize().width + c.getEl().getMargins('lr'));
            }
        }
        pw = pw < 0 ? 0 : pw;
        for(i = 0; i < len; i++){
            c = cs[i];
            if(c.columnWidth){
                c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
            }
        }
    }
});
pExt.Container.LAYOUTS['column'] = pExt.layout.ColumnLayout;
pExt.layout.BorderLayout = pExt.extend(pExt.layout.ContainerLayout, {
    monitorResize:true,
    rendered : false,
    onLayout : function(ct, target){
        var collapsed;
        if(!this.rendered){
            target.addClass('x-border-layout-ct');
            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.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
                    c.render(target, i);
                }
                this[pos] = pos != 'center' && c.split ?
                    new pExt.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
                    new pExt.layout.BorderLayout.Region(this, c.initialConfig, pos);
                this[pos].render(target, c);
            }
            this.rendered = true;
        }
        var size = target.getViewSize();
        if(size.width < 20 || size.height < 20){ 
            if(collapsed){
                this.restoreCollapsed = collapsed;
            }
            return;
        }else if(this.restoreCollapsed){
            collapsed = this.restoreCollapsed;
            delete this.restoreCollapsed;
        }
        var w = size.width, h = size.height;
        var centerW = w, centerH = h, centerY = 0, centerX = 0;
        var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
        if(!c && pExt.layout.BorderLayout.WARN !== false){
            throw 'No center region defined in BorderLayout ' + ct.id;
        }
        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(pExt.isIE && pExt.isStrict){ 
            target.repaint();
        }
    },
    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);
                }
            }
        }
        pExt.layout.BorderLayout.superclass.destroy.call(this);
    }
});
pExt.layout.BorderLayout.Region = function(layout, config, pos){
    pExt.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 = pExt.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 = pExt.applyIf(this.cmargins || {},
                pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
        }
    }
};
pExt.layout.BorderLayout.Region.prototype = {
    collapsible : false,
    split:false,
    floatable: true,
    minWidth:50,
    minHeight:50,
    defaultMargins : {left:0,top:0,right:0,bottom:0},
    defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
    defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
    floatingZIndex: 100,
    isCollapsed : false,
    render : function(ct, p){
        this.panel = p;
        p.el.enableDisplayMode();
        this.targetEl = ct;
        this.el = p.el;
        var gs = p.getState, ps = this.position;
        p.getState = function(){
            return pExt.apply(gs.call(p) || {}, this.state);
        }.createDelegate(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');
            }
        }
    },
    getCollapsedEl : function(){
        if(!this.collapsedEl){
            if(!this.toolTemplate){
                var tt = new pExt.Template(
                     '<div class="x-tool x-tool-{id}">&#160;</div>'
                );
                tt.disableFormats = true;
                tt.compile();
                pExt.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);
                }
            }
        }
        return this.collapsedEl;
    },
    onExpandClick : function(e){
        if(this.isSlid){
            this.afterSlideIn();
            this.panel.expand(false);
        }else{
            this.panel.expand();
        }
    },
    onCollapseClick : function(e){
        this.panel.collapse();
    },
    beforeCollapse : function(p, animate){
        this.lastAnim = animate;
        if(this.splitEl){
            this.splitEl.hide();
        }
        this.getCollapsedEl().show();
        this.panel.el.setStyle('z-index', 100);
        this.isCollapsed = true;
        this.layout.layout();
    },
    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){
        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);
    },
    onExpand : function(){
        this.isCollapsed = false;
        if(this.splitEl){
            this.splitEl.show();
        }
        this.layout.layout();
        this.panel.el.setStyle('z-index', 1);
        this.state.collapsed = false;
        this.panel.saveState();
    },
    collapseClick : function(e){
        if(this.isSlid){
           e.stopPropagation();
           this.slideIn();
        }else{
           e.stopPropagation();
           this.slideOut();
        }
    },
    onHide : function(){
        if(this.isCollapsed){
            this.getCollapsedEl().hide();
        }else if(this.splitEl){
            this.splitEl.hide();
        }
    },
    onShow : function(){
        if(this.isCollapsed){
            this.getCollapsedEl().show();
        }else if(this.splitEl){
            this.splitEl.show();
        }
    },
    isVisible : function(){
        return !this.panel.hidden;
    },
    getMargins : function(){
        return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
    },
    getSize : function(){
        return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
    },
    setPanel : function(panel){
        this.panel = panel;
    },
    getMinWidth: function(){
        return this.minWidth;
    },
    getMinHeight: function(){
        return this.minHeight;
    },
    applyLayoutCollapsed : function(box){
        var ce = this.getCollapsedEl();
        ce.setLeftTop(box.x, box.y);
        ce.setSize(box.width, box.height);
    },
    applyLayout : function(box){
        if(this.isCollapsed){
            this.applyLayoutCollapsed(box);
        }else{
            this.panel.setPosition(box.x, box.y);
            this.panel.setSize(box.width, box.height);
        }
    },
    beforeSlide: function(){
        this.panel.beforeEffect();
    },
    afterSlide : function(){
        this.panel.afterEffect();
    },
    initAutoHide : function(){
        if(this.autoHide !== false){
            if(!this.autoHideHd){
                var st = new pExt.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);
        }
    },
    clearAutoHide : function(){
        if(this.autoHide !== false){
            this.el.un("mouseout", this.autoHideHd.mouseout);
            this.el.un("mouseover", this.autoHideHd.mouseover);
        }
    },
    clearMonitor : function(){
        pExt.getDoc().un("click", this.slideInIf, this);
    },
    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();
                    pExt.getDoc().on("click", this.slideInIf, this);
                },
                scope: this,
                block: true
            });
        }else{
            this.initAutoHide();
             pExt.getDoc().on("click", this.slideInIf, this);
        }
    },
    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];
        var ts = this.panel.tools;
        if(ts && ts.toggle){
            ts.toggle.show();
        }
    },
    slideIn : function(cb){
        if(!this.isSlid || this.el.hasActiveFx()){
            pExt.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();
                    pExt.callback(cb);
                },
                scope: this,
                block: true
            });
        }else{
            this.el.hide();
            this.afterSlideIn();
        }
    },
    slideInIf : function(e){
        if(!e.within(this.el)){
            this.slideIn();
        }
    },
    anchors : {
        "west" : "left",
        "east" : "right",
        "north" : "top",
        "south" : "bottom"
    },
    sanchors : {
        "west" : "l",
        "east" : "r",
        "north" : "t",
        "south" : "b"
    },
    canchors : {
        "west" : "tl-tr",
        "east" : "tr-tl",
        "north" : "tl-bl",
        "south" : "bl-tl"
    },
    getAnchor : function(){
        return this.anchors[this.position];
    },
    getCollapseAnchor : function(){
        return this.canchors[this.position];
    },
    getSlideAnchor : function(){
        return this.sanchors[this.position];
    },
    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;
        }
    },
    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;
        }
    }
};
pExt.layout.BorderLayout.SplitRegion = function(layout, config, pos){
    pExt.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
    this.applyLayout = this.applyFns[pos];
};
pExt.extend(pExt.layout.BorderLayout.SplitRegion, pExt.layout.BorderLayout.Region, {
    splitTip : "Drag to resize.",
    collapsibleSplitTip : "Drag to resize. Double click to hide.",
    useSplitTips : false,
    splitSettings : {
        north : {
            orientation: pExt.SplitBar.VERTICAL,
            placement: pExt.SplitBar.TOP,
            maxFn : 'getVMaxSize',
            minProp: 'minHeight',
            maxProp: 'maxHeight'
        },
        south : {
            orientation: pExt.SplitBar.VERTICAL,
            placement: pExt.SplitBar.BOTTOM,
            maxFn : 'getVMaxSize',
            minProp: 'minHeight',
            maxProp: 'maxHeight'
        },
        east : {
            orientation: pExt.SplitBar.HORIZONTAL,
            placement: pExt.SplitBar.RIGHT,
            maxFn : 'getHMaxSize',
            minProp: 'minWidth',
            maxProp: 'maxWidth'
        },
        west : {
            orientation: pExt.SplitBar.HORIZONTAL,
            placement: pExt.SplitBar.LEFT,
            maxFn : 'getHMaxSize',
            minProp: 'minWidth',
            maxProp: 'maxWidth'
        }
    },
    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);
            }
            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);
        }
    },
    render : function(ct, p){
        pExt.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
        var ps = this.position;
        this.splitEl = ct.createChild({
            cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
            id: this.panel.id + '-xsplit'
        });
        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 s = this.splitSettings[ps];
        this.split = new pExt.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(p.hidden){
            this.splitEl.hide();
        }
        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{
            s.width += this.splitEl.dom.offsetWidth;
        }
        return s;
    },
    getHMaxSize : function(){
         var cmax = this.maxSize || 10000;
         var center = this.layout.center;
         return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
    },
    getVMaxSize : function(){
        var cmax = this.maxSize || 10000;
        var center = this.layout.center;
        return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
    },
    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;
    },
    getSplitBar : function(){
        return this.split;
    },
    destroy : function() {
        pExt.destroy(
            this.miniSplitEl,
            this.split,
            this.splitEl
        );
    }
});
pExt.Container.LAYOUTS['border'] = pExt.layout.BorderLayout;
pExt.layout.FormLayout = pExt.extend(pExt.layout.AnchorLayout, {
    labelSeparator : ':',
    setContainer : function(ct){
        pExt.layout.FormLayout.superclass.setContainer.call(this, ct);
        if(ct.labelAlign){
            ct.addClass('x-form-label-'+ct.labelAlign);
        }
        if(ct.hideLabels){
            this.labelStyle = "display:none";
            this.elementStyle = "padding-left:0;";
            this.labelAdjust = 0;
        }else{
            this.labelSeparator = ct.labelSeparator || this.labelSeparator;
            ct.labelWidth = ct.labelWidth || 100;
            if(typeof ct.labelWidth == 'number'){
                var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
                this.labelAdjust = ct.labelWidth+pad;
                this.labelStyle = "width:"+ct.labelWidth+"px;";
                this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
            }
            if(ct.labelAlign == 'top'){
                this.labelStyle = "width:auto;";
                this.labelAdjust = 0;
                this.elementStyle = "padding-left:0;";
            }
        }
    },
    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;
    },
    renderItem : function(c, position, target){
        if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
            var args = this.getTemplateArgs(c);
            if(typeof position == 'number'){
                position = target.dom.childNodes[position] || null;
            }
            if(position){
                this.fieldTpl.insertBefore(position, args);
            }else{
                this.fieldTpl.append(target, args);
            }
            c.render('x-form-el-'+c.id);
        }else {
            pExt.layout.FormLayout.superclass.renderItem.apply(this, arguments);
        }
    },
    getTemplateArgs: function(field) {
        var noLabelSep = !field.fieldLabel || field.hideLabel;
        return {
            id: field.id,
            label: field.fieldLabel,
            labelStyle: field.labelStyle||this.labelStyle||'',
            elementStyle: this.elementStyle||'',
            labelSeparator: noLabelSep ? '' : (typeof field.labelSeparator == 'undefined' ? this.labelSeparator : field.labelSeparator),
            itemCls: (field.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''),
            clearCls: field.clearCls || 'x-form-clear-left'
        };
    },
    adjustWidthAnchor : function(value, comp){
        return value - (comp.isFormField || comp.fieldLabel  ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
    },
    isValidParent : function(c, target){
        return true;
    }
});
pExt.Container.LAYOUTS['form'] = pExt.layout.FormLayout;
pExt.layout.AccordionLayout = pExt.extend(pExt.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.activeItem = c;
        }else if(this.activeItem && this.activeItem != c){
            c.collapsed = true;
        }
        pExt.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
        c.header.addClass('x-accordion-hd');
        c.on('beforeexpand', this.beforeExpand, 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);
            }
        }
        this.activeItem = 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();
                }    
            });
            size.height -= hh;
            item.setSize(size);
        }
    },
    setActiveItem : function(item){
        item = this.container.getComponent(item);
        if(this.activeItem != item){
            if(item.rendered && item.collapsed){
                item.expand();
            }else{
                this.activeItem = item;
            }
        }
    }
});
pExt.Container.LAYOUTS.accordion = pExt.layout.AccordionLayout;
pExt.layout.Accordion = pExt.layout.AccordionLayout;
pExt.layout.TableLayout = pExt.extend(pExt.layout.ContainerLayout, {
    monitorResize:false,
    tableAttrs:null,
    setContainer : function(ct){
        pExt.layout.TableLayout.superclass.setContainer.call(this, ct);
        this.currentRow = 0;
        this.currentColumn = 0;
        this.cells = [];
    },
    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(
                pExt.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
        }
        this.renderAll(ct, target);
    },
    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;
    },
    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;
    },
    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];
    },
    renderItem : function(c, position, target){
        if(c && !c.rendered){
            c.render(this.getNextCell(c));
            if(this.extraCls){
                var t = c.getPositionEl ? c.getPositionEl() : c;
                t.addClass(this.extraCls);
            }
        }
    },
    isValidParent : function(c, target){
        return true;
    }
});
pExt.Container.LAYOUTS['table'] = pExt.layout.TableLayout;
pExt.layout.AbsoluteLayout = pExt.extend(pExt.layout.AnchorLayout, {
    extraCls: 'x-abs-layout-item',
    onLayout : function(ct, target){
        target.position();
        this.paddingLeft = target.getPadding('l');
        this.paddingTop = target.getPadding('t');
        pExt.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
    },
    adjustWidthAnchor : function(value, comp){
        return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
    },
    adjustHeightAnchor : function(value, comp){
        return  value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
    }
});
pExt.Container.LAYOUTS['absolute'] = pExt.layout.AbsoluteLayout;
pExt.layout.BoxLayout = pExt.extend(pExt.layout.ContainerLayout, {
    defaultMargins : {left:0,top:0,right:0,bottom:0},
    padding : '0',
    pack : 'start',
    monitorResize : true,
    scrollOffset : 0,
    extraCls : 'x-box-item',
    ctCls : 'x-box-layout-ct',
    innerCls : 'x-box-inner',
    isValidParent : function(c, target){
        return c.getEl().dom.parentNode == this.innerCt.dom;
    },
    onLayout : function(ct, target){
        var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;
        if(!this.innerCt){
            target.addClass(this.ctCls);
            this.innerCt = target.createChild({cls:this.innerCls});
            this.padding = this.parseMargins(this.padding); 
        }
        this.renderAll(ct, this.innerCt);
    },
    renderItem : function(c){
        if(typeof c.margins == 'string'){
            c.margins = this.parseMargins(c.margins);
        }else if(!c.margins){
            c.margins = this.defaultMargins;
        }
        pExt.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
    },
    getTargetSize : function(target){
        return (pExt.isIE6 && pExt.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize();
    },
    getItems: function(ct){
        var items = [];
        ct.items.each(function(c){
            if(c.isVisible()){
                items.push(c);
            }
        });
        return items;
    }
});
pExt.layout.VBoxLayout = pExt.extend(pExt.layout.BoxLayout, {
    align : 'left', 
    onLayout : function(ct, target){
        pExt.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);
        var cs = this.getItems(ct), cm, ch, margin,
            size = this.getTargetSize(target),
            w = size.width - target.getPadding('lr') - this.scrollOffset,
            h = size.height - target.getPadding('tb'),
            l = this.padding.left, t = this.padding.top,
            isStart = this.pack == 'start',
            isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
            stretchWidth = w - (this.padding.left + this.padding.right),
            extraHeight = 0,
            maxWidth = 0,
            totalFlex = 0,
            flexHeight = 0,
            usedHeight = 0;
        pExt.each(cs, function(c){
            cm = c.margins;
            totalFlex += c.flex || 0;
            ch = c.getHeight();
            margin = cm.top + cm.bottom;
            extraHeight += ch + margin;
            flexHeight += margin + (c.flex ? 0 : ch);
            maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
        });
        extraHeight = h - extraHeight - this.padding.top - this.padding.bottom;
        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;
        }
        var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight),
            leftOver = availHeight,
            heights = [],
            restore = [],
            idx = 0,
            availableWidth = Math.max(0, w - this.padding.left - this.padding.right);
        pExt.each(cs, function(c){
            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;
        }
        pExt.each(cs, function(c){
            cm = c.margins;
            t += cm.top;
            c.setPosition(l + cm.left, t);
            if(isStart && c.flex){
                ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0));
                if(isRestore){
                    restore.push(c.getWidth());
                }
                c.setSize(availableWidth, ch);
            }else{
                ch = c.getHeight();
            }
            t += ch + cm.bottom;
        });
        idx = 0;
        pExt.each(cs, function(c){
            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(this.align == 'center'){
                    var diff = availableWidth - (c.getWidth() + cm.left + cm.right);
                    if(diff > 0){
                        c.setPosition(l + cm.left + (diff/2), c.y);
                    }
                }
                if(isStart && c.flex){
                    c.setWidth(restore[idx++]);
                }
            }
        }, this);
    }
});
pExt.Container.LAYOUTS.vbox = pExt.layout.VBoxLayout;
pExt.layout.HBoxLayout = pExt.extend(pExt.layout.BoxLayout, {
    align : 'top', 
    onLayout : function(ct, target){
        pExt.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
        var cs = this.getItems(ct), cm, cw, margin,
            size = this.getTargetSize(target),
            w = size.width - target.getPadding('lr') - this.scrollOffset,
            h = size.height - target.getPadding('tb'),
            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;
        pExt.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;
        }
        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);
        pExt.each(cs, function(c){
            if(isStart && c.flex){
                cw = Math.floor(availWidth * (c.flex / totalFlex));
                leftOver -= cw;
                widths.push(cw);
            }
        }); 
        if(this.pack == 'center'){
            l += extraWidth ? extraWidth / 2 : 0;
        }else if(this.pack == 'end'){
            l += extraWidth;
        }
        pExt.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;
        });
        idx = 0;
        pExt.each(cs, function(c){
            var cm = c.margins;
            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'){
                    var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom);
                    if(diff > 0){
                        c.setPosition(c.x, t + cm.top + (diff/2));
                    }
                }
                if(isStart && c.flex){
                    c.setHeight(restore[idx++]);
                }
            }
        }, this);
    }
});
pExt.Container.LAYOUTS.hbox = pExt.layout.HBoxLayout;
pExt.Viewport = pExt.extend(pExt.Container, {
    initComponent : function() {
        pExt.Viewport.superclass.initComponent.call(this);
        document.getElementsByTagName('html')[0].className += ' x-viewport';
        this.el = pExt.getBody();
        this.el.setHeight = pExt.emptyFn;
        this.el.setWidth = pExt.emptyFn;
        this.el.setSize = pExt.emptyFn;
        this.el.dom.scroll = 'no';
        this.allowDomMove = false;
        this.autoWidth = true;
        this.autoHeight = true;
        pExt.EventManager.onWindowResize(this.fireResize, this);
        this.renderTo = this.el;
    },
    fireResize : function(w, h){
        this.fireEvent('resize', this, w, h, w, h);
    }
});
pExt.reg('viewport', pExt.Viewport);
pExt.Panel = pExt.extend(pExt.Container, {
    baseCls : 'x-panel',
    collapsedCls : 'x-panel-collapsed',
    maskDisabled : true,
    animCollapse : pExt.enableFx,
    headerAsText : true,
    buttonAlign : 'right',
    collapsed : false,
    collapseFirst : true,
    minButtonWidth : 75,
    elements : 'body',
    preventBodyReset : false,
    toolTarget : 'header',
    collapseEl : 'bwrap',
    slideAnchor : 't',
    disabledClass : '',
    deferHeight : true,
    expandDefaults: {
        duration : 0.25
    },
    collapseDefaults : {
        duration : 0.25
    },
    initComponent : function(){
        pExt.Panel.superclass.initComponent.call(this);
        this.addEvents(
            'bodyresize',
            'titlechange',
            'iconchange',
            'collapse',
            'expand',
            'beforecollapse',
            'beforeexpand',
            'beforeclose',
            'close',
            'activate',
            'deactivate'
        );
        if(this.unstyled){
            this.baseCls = 'x-plain';
        }
        if(this.tbar){
            this.elements += ',tbar';
            if(pExt.isObject(this.tbar)){
                this.topToolbar = this.tbar;
            }
            delete this.tbar;
        }
        if(this.bbar){
            this.elements += ',bbar';
            if(pExt.isObject(this.bbar)){
                this.bottomToolbar = this.bbar;
            }
            delete this.bbar;
        }
        if(this.header === true){
            this.elements += ',header';
            delete this.header;
        }else if(this.headerCfg || (this.title && this.header !== false)){
            this.elements += ',header';
        }
        if(this.footerCfg || this.footer === true){
            this.elements += ',footer';
            delete this.footer;
        }
        if(this.buttons){
            this.elements += ',footer';
            var btns = this.buttons;
            this.buttons = [];
            for(var i = 0, len = btns.length; i < len; i++) {
                if(btns[i].render){ 
                    this.buttons.push(btns[i]);
                }else if(btns[i].xtype){
                    this.buttons.push(pExt.create(btns[i], 'button'));
                }else{
                    this.addButton(btns[i]);
                }
            }
        }
        if(this.fbar){
            this.elements += ',footer';
        }
        if(this.autoLoad){
            this.on('render', this.doAutoLoad, this, {delay:10});
        }
    },
    createElement : function(name, pnode){
        if(this[name]){
            pnode.appendChild(this[name].dom);
            return;
        }
        if(name === 'bwrap' || this.elements.indexOf(name) != -1){
            if(this[name+'Cfg']){
                this[name] = pExt.fly(pnode).createChild(this[name+'Cfg']);
            }else{
                var el = document.createElement('div');
                el.className = this[name+'Cls'];
                this[name] = pExt.get(pnode.appendChild(el));
            }
            if(this[name+'CssClass']){
                this[name].addClass(this[name+'CssClass']);
            }
            if(this[name+'Style']){
                this[name].applyStyles(this[name+'Style']);
            }
        }
    },
    onRender : function(ct, position){
        pExt.Panel.superclass.onRender.call(this, ct, position);
        this.createClasses();
        var el = this.el,
            d = el.dom,
            bw;
        el.addClass(this.baseCls);
        if(d.firstChild){ 
            this.header = el.down('.'+this.headerCls);
            this.bwrap = el.down('.'+this.bwrapCls);
            var cp = this.bwrap ? this.bwrap : el;
            this.tbar = cp.down('.'+this.tbarCls);
            this.body = cp.down('.'+this.bodyCls);
            this.bbar = cp.down('.'+this.bbarCls);
            this.footer = cp.down('.'+this.footerCls);
            this.fromMarkup = true;
        }
        if (this.preventBodyReset === true) {
            el.addClass('x-panel-reset');
        }
        if(this.cls){
            el.addClass(this.cls);
        }
        if(this.buttons){
            this.elements += ',footer';
        }
        if(this.frame){
            el.insertHtml('afterBegin', String.format(pExt.Element.boxMarkup, this.baseCls));
            this.createElement('header', d.firstChild.firstChild.firstChild);
            this.createElement('bwrap', d);
            bw = this.bwrap.dom;
            var ml = d.childNodes[1], bl = d.childNodes[2];
            bw.appendChild(ml);
            bw.appendChild(bl);
            var mc = bw.firstChild.firstChild.firstChild;
            this.createElement('tbar', mc);
            this.createElement('body', mc);
            this.createElement('bbar', mc);
            this.createElement('footer', bw.lastChild.firstChild.firstChild);
            if(!this.footer){
                this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
            }
        }else{
            this.createElement('header', d);
            this.createElement('bwrap', d);
            bw = this.bwrap.dom;
            this.createElement('tbar', bw);
            this.createElement('body', bw);
            this.createElement('bbar', bw);
            this.createElement('footer', bw);
            if(!this.header){
                this.body.addClass(this.bodyCls + '-noheader');
                if(this.tbar){
                    this.tbar.addClass(this.tbarCls + '-noheader');
                }
            }
        }
        if(this.padding !== undefined) {
            this.body.setStyle('padding', this.body.addUnits(this.padding));
        }
        if(this.border === false){
            this.el.addClass(this.baseCls + '-noborder');
            this.body.addClass(this.bodyCls + '-noborder');
            if(this.header){
                this.header.addClass(this.headerCls + '-noborder');
            }
            if(this.footer){
                this.footer.addClass(this.footerCls + '-noborder');
            }
            if(this.tbar){
                this.tbar.addClass(this.tbarCls + '-noborder');
            }
            if(this.bbar){
                this.bbar.addClass(this.bbarCls + '-noborder');
            }
        }
        if(this.bodyBorder === false){
           this.body.addClass(this.bodyCls + '-noborder');
        }
        this.bwrap.enableDisplayMode('block');
        if(this.header){
            this.header.unselectable();
            if(this.headerAsText){
                this.header.dom.innerHTML =
                    '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
                if(this.iconCls){
                    this.setIconClass(this.iconCls);
                }
            }
        }
        if(this.floating){
            this.makeFloating(this.floating);
        }
        if(this.collapsible){
            this.tools = this.tools ? this.tools.slice(0) : [];
            if(!this.hideCollapseTool){
                this.tools[this.collapseFirst?'unshift':'push']({
                    id: 'toggle',
                    handler : this.toggleCollapse,
                    scope: this
                });
            }
            if(this.titleCollapse && this.header){
                this.mon(this.header, 'click', this.toggleCollapse, this);
                this.header.setStyle('cursor', 'pointer');
            }
        }
        if(this.tools){
            var ts = this.tools;
            this.tools = {};
            this.addTool.apply(this, ts);
        }else{
            this.tools = {};
        }
        if(this.buttons && this.buttons.length > 0){
            this.fbar = new pExt.Toolbar({
                items: this.buttons,
                toolbarCls: 'x-panel-fbar'
            });
        }
        this.toolbars = [];
        if(this.fbar){
            this.fbar = pExt.create(this.fbar, 'toolbar');
            this.fbar.enableOverflow = false;
            if(this.fbar.items){
                this.fbar.items.each(function(c){
                    c.minWidth = c.minWidth || this.minButtonWidth;
                }, this);
            }
            this.fbar.toolbarCls = 'x-panel-fbar';
            var bct = this.footer.createChild({cls: 'x-panel-btns x-panel-btns-'+this.buttonAlign});
            this.fbar.ownerCt = this;
            this.fbar.render(bct);
            bct.createChild({cls:'x-clear'});
            this.toolbars.push(this.fbar);
        }
        if(this.tbar && this.topToolbar){
            if(pExt.isArray(this.topToolbar)){
                this.topToolbar = new pExt.Toolbar(this.topToolbar);
            }else if(!this.topToolbar.events){
                this.topToolbar = pExt.create(this.topToolbar, 'toolbar');
            }
            this.topToolbar.ownerCt = this;
            this.topToolbar.render(this.tbar);
            this.toolbars.push(this.topToolbar);
        }
        if(this.bbar && this.bottomToolbar){
            if(pExt.isArray(this.bottomToolbar)){
                this.bottomToolbar = new pExt.Toolbar(this.bottomToolbar);
            }else if(!this.bottomToolbar.events){
                this.bottomToolbar = pExt.create(this.bottomToolbar, 'toolbar');
            }
            this.bottomToolbar.ownerCt = this;
            this.bottomToolbar.render(this.bbar);
            this.toolbars.push(this.bottomToolbar);
        }
        pExt.each(this.toolbars, function(tb){
            tb.on({
                scope: this,
                afterlayout: this.syncHeight,
                remove: this.syncHeight
            });
        }, this);
    },
    setIconClass : function(cls){
        var old = this.iconCls;
        this.iconCls = cls;
        if(this.rendered && this.header){
            if(this.frame){
                this.header.addClass('x-panel-icon');
                this.header.replaceClass(old, this.iconCls);
            }else{
                var hd = this.header.dom;
                var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
                if(img){
                    pExt.fly(img).replaceClass(old, this.iconCls);
                }else{
                    pExt.DomHelper.insertBefore(hd.firstChild, {
                        tag:'img', src: pExt.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
                    });
                 }
            }
        }
        this.fireEvent('iconchange', this, cls, old);
    },
    makeFloating : function(cfg){
        this.floating = true;
        this.el = new pExt.Layer(
            pExt.isObject(cfg) ? cfg : {
                shadow: this.shadow !== undefined ? this.shadow : 'sides',
                shadowOffset: this.shadowOffset,
                constrain:false,
                shim: this.shim === false ? false : undefined
            }, this.el
        );
    },
    getTopToolbar : function(){
        return this.topToolbar;
    },
    getBottomToolbar : function(){
        return this.bottomToolbar;
    },
    addButton : function(config, handler, scope){
        var bc = {
            handler: handler,
            scope: scope,
            minWidth: this.minButtonWidth,
            hideParent:true
        };
        if(typeof config == "string"){
            bc.text = config;
        }else{
            pExt.apply(bc, config);
        }
        var btn = new pExt.Button(bc);
        if(!this.buttons){
            this.buttons = [];
        }
        this.buttons.push(btn);
        return btn;
    },
    addTool : function(){
        if(!this[this.toolTarget]) { 
            return;
        }
        if(!this.toolTemplate){
            var tt = new pExt.Template(
                 '<div class="x-tool x-tool-{id}">&#160;</div>'
            );
            tt.disableFormats = true;
            tt.compile();
            pExt.Panel.prototype.toolTemplate = tt;
        }
        for(var i = 0, a = arguments, len = a.length; i < len; i++) {
            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);
                this.tools[tc.id] = t;
                t.enableDisplayMode('block');
                this.mon(t, 'click',  this.createToolHandler(t, tc, overCls, this));
                if(tc.on){
                    this.mon(t, tc.on);
                }
                if(tc.hidden){
                    t.hide();
                }
                if(tc.qtip){
                    if(pExt.isObject(tc.qtip)){
                        pExt.QuickTips.register(pExt.apply({
                              target: t.id
                        }, tc.qtip));
                    } else {
                        t.dom.qtip = tc.qtip;
                    }
                }
                t.addClassOnOver(overCls);
            }
        }
    },
    onLayout : function(){
        if(this.toolbars.length > 0){
            this.duringLayout = true;
            pExt.each(this.toolbars, function(tb){
                tb.doLayout();
            });
            delete this.duringLayout;
            this.syncHeight();
        }
    },
    syncHeight : function(){
        if(!(this.autoHeight || this.duringLayout)){
            var last = this.lastSize;
            if(last && !pExt.isEmpty(last.height)){
                var old = last.height, h = this.el.getHeight();
                if(old != 'auto' && old != h){
                    var bd = this.body, bdh = bd.getHeight();
                    h = Math.max(bdh + old - h, 0);
                    if(bdh > 0 && bdh != h){
                        bd.setHeight(h);
                        if(pExt.isIE && h <= 0){
                            return;
                        }
                        var sz = bd.getSize();
                        this.fireEvent('bodyresize', sz.width, sz.height);
                    }
                }
            }
        }
    },
    onShow : function(){
        if(this.floating){
            return this.el.show();
        }
        pExt.Panel.superclass.onShow.call(this);
    },
    onHide : function(){
        if(this.floating){
            return this.el.hide();
        }
        pExt.Panel.superclass.onHide.call(this);
    },
    createToolHandler : function(t, tc, overCls, panel){
        return function(e){
            t.removeClass(overCls);
            if(tc.stopEvent !== false){
                e.stopEvent();
            }
            if(tc.handler){
                tc.handler.call(tc.scope || t, e, t, panel, tc);
            }
        };
    },
    afterRender : function(){
        if(this.floating && !this.hidden){
            this.el.show();
        }
        if(this.title){
            this.setTitle(this.title);
        }
        this.setAutoScroll();
        if(this.html){
            this.body.update(pExt.isObject(this.html) ?
                             pExt.DomHelper.markup(this.html) :
                             this.html);
            delete this.html;
        }
        if(this.contentEl){
            var ce = pExt.getDom(this.contentEl);
            pExt.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
            this.body.dom.appendChild(ce);
        }
        if(this.collapsed){
            this.collapsed = false;
            this.collapse(false);
        }
        pExt.Panel.superclass.afterRender.call(this); 
        this.initEvents();
    },
    setAutoScroll : function(){
        if(this.rendered && this.autoScroll){
            var el = this.body || this.el;
            if(el){
                el.setOverflow('auto');
            }
        }
    },
    getKeyMap : function(){
        if(!this.keyMap){
            this.keyMap = new pExt.KeyMap(this.el, this.keys);
        }
        return this.keyMap;
    },
    initEvents : function(){
        if(this.keys){
            this.getKeyMap();
        }
        if(this.draggable){
            this.initDraggable();
        }
    },
    initDraggable : function(){
        this.dd = new pExt.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
    },
    beforeEffect : function(){
        if(this.floating){
            this.el.beforeAction();
        }
        this.el.addClass('x-panel-animated');
    },
    afterEffect : function(){
        this.syncShadow();
        this.el.removeClass('x-panel-animated');
    },
    createEffect : function(a, cb, scope){
        var o = {
            scope:scope,
            block:true
        };
        if(a === true){
            o.callback = cb;
            return o;
        }else if(!a.callback){
            o.callback = cb;
        }else { 
            o.callback = function(){
                cb.call(scope);
                pExt.callback(a.callback, a.scope);
            };
        }
        return pExt.applyIf(o, a);
    },
    collapse : function(animate){
        if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
            return;
        }
        var doAnim = animate === true || (animate !== false && this.animCollapse);
        this.beforeEffect();
        this.onCollapse(doAnim, animate);
        return this;
    },
    onCollapse : function(doAnim, animArg){
        if(doAnim){
            this[this.collapseEl].slideOut(this.slideAnchor,
                    pExt.apply(this.createEffect(animArg||true, this.afterCollapse, this),
                        this.collapseDefaults));
        }else{
            this[this.collapseEl].hide();
            this.afterCollapse();
        }
    },
    afterCollapse : function(){
        this.collapsed = true;
        this.el.addClass(this.collapsedCls);
        this.afterEffect();
        this.fireEvent('collapse', this);
    },
    expand : function(animate){
        if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
            return;
        }
        var doAnim = animate === true || (animate !== false && this.animCollapse);
        this.el.removeClass(this.collapsedCls);
        this.beforeEffect();
        this.onExpand(doAnim, animate);
        return this;
    },
    onExpand : function(doAnim, animArg){
        if(doAnim){
            this[this.collapseEl].slideIn(this.slideAnchor,
                    pExt.apply(this.createEffect(animArg||true, this.afterExpand, this),
                        this.expandDefaults));
        }else{
            this[this.collapseEl].show();
            this.afterExpand();
        }
    },
    afterExpand : function(){
        this.collapsed = false;
        this.afterEffect();
        if(this.deferLayout !== undefined){
            this.doLayout(true);
        }
        this.fireEvent('expand', this);
    },
    toggleCollapse : function(animate){
        this[this.collapsed ? 'expand' : 'collapse'](animate);
        return this;
    },
    onDisable : function(){
        if(this.rendered && this.maskDisabled){
            this.el.mask();
        }
        pExt.Panel.superclass.onDisable.call(this);
    },
    onEnable : function(){
        if(this.rendered && this.maskDisabled){
            this.el.unmask();
        }
        pExt.Panel.superclass.onEnable.call(this);
    },
    onResize : function(w, h){
        if(w !== undefined || h !== undefined){
            if(!this.collapsed){
                if(typeof w == 'number'){
                    w = this.adjustBodyWidth(w - this.getFrameWidth());
                    if(this.tbar){
                        this.tbar.setWidth(w);
                        if(this.topToolbar){
                            this.topToolbar.setSize(w);
                        }
                    }
                    if(this.bbar){
                        this.bbar.setWidth(w);
                        if(this.bottomToolbar){
                            this.bottomToolbar.setSize(w);
                        }
                    }
                    if(this.fbar){
                        var f = this.fbar,
                            fWidth = 1,
                            strict = pExt.isStrict;
                        if(this.buttonAlign == 'left'){
                           fWidth = w - f.container.getFrameWidth('lr');
                        }else{
                            if(pExt.isIE || pExt.isWebKit){
                                if(!(this.buttonAlign == 'center' && pExt.isWebKit) && (!strict || (!pExt.isIE8 && strict))){
                                    (function(){
                                        f.setWidth(f.getEl().child('.x-toolbar-ct').getWidth());
                                    }).defer(1);
                                }else{
                                    fWidth = 'auto';
                                }
                            }else{
                                fWidth = 'auto';
                            }
                        }
                        f.setWidth(fWidth);
                    }
                    this.body.setWidth(w);
                }else if(w == 'auto'){
                    this.body.setWidth(w);
                }
                if(typeof h == 'number'){
                    h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight()));
                    this.body.setHeight(h);
                }else if(h == 'auto'){
                    this.body.setHeight(h);
                }
                if(this.disabled && this.el._mask){
                    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;
                    this.on('expand', function(){
                        delete this.queuedExpand;
                        this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
                        this.doLayout();
                    }, this, {single:true});
                }
            }
            this.fireEvent('bodyresize', this, w, h);
        }
        this.syncShadow();
    },
    adjustBodyHeight : function(h){
        return h;
    },
    adjustBodyWidth : function(w){
        return w;
    },
    onPosition : function(){
        this.syncShadow();
    },
    getFrameWidth : function(){
        var w = this.el.getFrameWidth('lr')+this.bwrap.getFrameWidth('lr');
        if(this.frame){
            var l = this.bwrap.dom.firstChild;
            w += (pExt.fly(l).getFrameWidth('l') + pExt.fly(l.firstChild).getFrameWidth('r'));
            var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
            w += pExt.fly(mc).getFrameWidth('lr');
        }
        return w;
    },
    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);
        if(this.frame){
            var hd = this.el.dom.firstChild;
            var ft = this.bwrap.dom.lastChild;
            h += (hd.offsetHeight + ft.offsetHeight);
            var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
            h += pExt.fly(mc).getFrameWidth('tb');
        }else{
            h += (this.header ? this.header.getHeight() : 0) +
                (this.footer ? this.footer.getHeight() : 0);
        }
        return h;
    },
    getInnerWidth : function(){
        return this.getSize().width - this.getFrameWidth();
    },
    getInnerHeight : function(){
        return this.getSize().height - this.getFrameHeight();
    },
    syncShadow : function(){
        if(this.floating){
            this.el.sync(true);
        }
    },
    getLayoutTarget : function(){
        return this.body;
    },
    setTitle : function(title, iconCls){
        this.title = title;
        if(this.header && this.headerAsText){
            this.header.child('span').update(title);
        }
        if(iconCls){
            this.setIconClass(iconCls);
        }
        this.fireEvent('titlechange', this, title);
        return this;
    },
    getUpdater : function(){
        return this.body.getUpdater();
    },
    load : function(){
        var um = this.body.getUpdater();
        um.update.apply(um, arguments);
        return this;
    },
    beforeDestroy : function(){
        if(this.header){
            this.header.removeAllListeners();
            if(this.headerAsText){
                pExt.Element.uncache(this.header.child('span'));
            }
        }
        pExt.Element.uncache(
            this.header,
            this.tbar,
            this.bbar,
            this.footer,
            this.body,
            this.bwrap
        );
        if(this.tools){
            for(var k in this.tools){
                pExt.destroy(this.tools[k]);
            }
        }
        if(this.buttons){
            for(var b in this.buttons){
                pExt.destroy(this.buttons[b]);
            }
        }
        pExt.destroy(this.toolbars);
        pExt.Panel.superclass.beforeDestroy.call(this);
    },
    createClasses : function(){
        this.headerCls = this.baseCls + '-header';
        this.headerTextCls = this.baseCls + '-header-text';
        this.bwrapCls = this.baseCls + '-bwrap';
        this.tbarCls = this.baseCls + '-tbar';
        this.bodyCls = this.baseCls + '-body';
        this.bbarCls = this.baseCls + '-bbar';
        this.footerCls = this.baseCls + '-footer';
    },
    createGhost : function(cls, useShim, appendTo){
        var el = document.createElement('div');
        el.className = 'x-panel-ghost ' + (cls ? cls : '');
        if(this.header){
            el.appendChild(this.el.dom.firstChild.cloneNode(true));
        }
        pExt.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
        el.style.width = this.el.dom.offsetWidth + 'px';;
        if(!appendTo){
            this.container.dom.appendChild(el);
        }else{
            pExt.getDom(appendTo).appendChild(el);
        }
        if(useShim !== false && this.el.useShim !== false){
            var layer = new pExt.Layer({shadow:false, useDisplay:true, constrain:false}, el);
            layer.show();
            return layer;
        }else{
            return new pExt.Element(el);
        }
    },
    doAutoLoad : function(){
        var u = this.body.getUpdater();
        if(this.renderer){
            u.setRenderer(this.renderer);
        }
        u.update(pExt.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
    },
    getTool : function(id) {
        return this.tools[id];
    }
});
pExt.reg('panel', pExt.Panel);
pExt.Window = pExt.extend(pExt.Panel, {
    baseCls : 'x-window',
    resizable : true,
    draggable : true,
    closable : true,
    closeAction : 'close',
    constrain : false,
    constrainHeader : false,
    plain : false,
    minimizable : false,
    maximizable : false,
    minHeight : 100,
    minWidth : 200,
    expandOnShow : true,
    collapsible : false,
    initHidden : true,
    monitorResize : true,
    elements : 'header,body',
    frame : true,
    floating : true,
    initComponent : function(){
        pExt.Window.superclass.initComponent.call(this);
        this.addEvents(
            'resize',
            'maximize',
            'minimize',
            'restore'
        );
        if(this.initHidden === false){
            this.show();
        }else{
            this.hidden = true;
        }
    },
    getState : function(){
        return pExt.apply(pExt.Window.superclass.getState.call(this) || {}, this.getBox(true));
    },
    onRender : function(ct, position){
        pExt.Window.superclass.onRender.call(this, ct, position);
        if(this.plain){
            this.el.addClass('x-window-plain');
        }
        this.focusEl = this.el.createChild({
                    tag: 'a', href:'#', cls:'x-dlg-focus',
                    tabIndex:'-1', html: '&#160;'});
        this.focusEl.swallowEvent('click', true);
        this.proxy = this.el.createProxy('x-window-proxy');
        this.proxy.enableDisplayMode('block');
        if(this.modal){
            this.mask = this.container.createChild({cls:'pext-el-mask'}, this.el.dom);
            this.mask.enableDisplayMode('block');
            this.mask.hide();
            this.mon(this.mask, 'click', this.focus, this);
        }
        this.initTools();
    },
    initEvents : function(){
        pExt.Window.superclass.initEvents.call(this);
        if(this.animateTarget){
            this.setAnimateTarget(this.animateTarget);
        }
        if(this.resizable){
            this.resizer = new pExt.Resizable(this.el, {
                minWidth: this.minWidth,
                minHeight:this.minHeight,
                handles: this.resizeHandles || 'all',
                pinned: true,
                resizeElement : this.resizerAction
            });
            this.resizer.window = this;
            this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
        }
        if(this.draggable){
            this.header.addClass('x-window-draggable');
        }
        this.mon(this.el, 'mousedown', this.toFront, this);
        this.manager = this.manager || pExt.WindowMgr;
        this.manager.register(this);
        if(this.maximized){
            this.maximized = false;
            this.maximize();
        }
        if(this.closable){
            var km = this.getKeyMap();
            km.on(27, this.onEsc, this);
            km.disable();
        }
    },
    initDraggable : function(){
        this.dd = new pExt.Window.DD(this);
    },
    onEsc : function(){
        this[this.closeAction]();
    },
    beforeDestroy : function(){
        if (this.rendered){
            this.hide();
          if(this.doAnchor){
                pExt.EventManager.removeResizeListener(this.doAnchor, this);
              pExt.EventManager.un(window, 'scroll', this.doAnchor, this);
            }
            pExt.destroy(
                this.focusEl,
                this.resizer,
                this.dd,
                this.proxy,
                this.mask
            );
        }
        pExt.Window.superclass.beforeDestroy.call(this);
    },
    onDestroy : function(){
        if(this.manager){
            this.manager.unregister(this);
        }
        pExt.Window.superclass.onDestroy.call(this);
    },
    initTools : function(){
        if(this.minimizable){
            this.addTool({
                id: 'minimize',
                handler: this.minimize.createDelegate(this, [])
            });
        }
        if(this.maximizable){
            this.addTool({
                id: 'maximize',
                handler: this.maximize.createDelegate(this, [])
            });
            this.addTool({
                id: 'restore',
                handler: this.restore.createDelegate(this, []),
                hidden:true
            });
            this.mon(this.header, 'dblclick', this.toggleMaximize, this);
        }
        if(this.closable){
            this.addTool({
                id: 'close',
                handler: this[this.closeAction].createDelegate(this, [])
            });
        }
    },
    resizerAction : function(){
        var box = this.proxy.getBox();
        this.proxy.hide();
        this.window.handleResize(box);
        return box;
    },
    beforeResize : function(){
        this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); 
        this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
        this.resizeBox = this.el.getBox();
    },
    updateHandles : function(){
        if(pExt.isIE && this.resizer){
            this.resizer.syncHandleHeight();
            this.el.repaint();
        }
    },
    handleResize : function(box){
        var rz = this.resizeBox;
        if(rz.x != box.x || rz.y != box.y){
            this.updateBox(box);
        }else{
            this.setSize(box);
        }
        this.focus();
        this.updateHandles();
        this.saveState();
        this.doLayout();
        this.fireEvent('resize', this, box.width, box.height);
    },
    focus : function(){
        var f = this.focusEl, db = this.defaultButton, t = typeof db;
        if(t != 'undefined'){
            if(t == 'number' && this.fbar){
                f = this.fbar.items.get(db);
            }else if(t == 'string'){
                f = pExt.getCmp(db);
            }else{
                f = db;
            }
        }
        f = f || this.focusEl;
        f.focus.defer(10, f);
    },
    setAnimateTarget : function(el){
        el = pExt.get(el);
        this.animateTarget = el;
    },
    beforeShow : function(){
        delete this.el.lastXY;
        delete this.el.lastLT;
        if(this.x === undefined || this.y === undefined){
            var xy = this.el.getAlignToXY(this.container, 'c-c');
            var pos = this.el.translatePoints(xy[0], xy[1]);
            this.x = this.x === undefined? pos.left : this.x;
            this.y = this.y === undefined? pos.top : this.y;
        }
        this.el.setLeftTop(this.x, this.y);
        if(this.expandOnShow){
            this.expand(false);
        }
        if(this.modal){
            pExt.getBody().addClass('x-body-masked');
            this.mask.setSize(pExt.lib.Dom.getViewWidth(true), pExt.lib.Dom.getViewHeight(true));
            this.mask.show();
        }
    },
    show : function(animateTarget, cb, scope){
        if(!this.rendered){
            this.render(pExt.getBody());
        }
        if(this.hidden === false){
            this.toFront();
            return this;
        }
        if(this.fireEvent('beforeshow', this) === false){
            return this;
        }
        if(cb){
            this.on('show', cb, scope, {single:true});
        }
        this.hidden = false;
        if(animateTarget !== undefined){
            this.setAnimateTarget(animateTarget);
        }
        this.beforeShow();
        if(this.animateTarget){
            this.animShow();
        }else{
            this.afterShow();
        }
        return this;
    },
    afterShow : function(isAnim){
        this.proxy.hide();
        this.el.setStyle('display', 'block');
        this.el.show();
        if(this.maximized){
            this.fitContainer();
        }
        if(pExt.isMac && pExt.isGecko){ 
            this.cascade(this.setAutoScroll);
        }
        if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
            pExt.EventManager.onWindowResize(this.onWindowResize, this);
        }
        this.doConstrain();
        this.doLayout();
        if(this.keyMap){
            this.keyMap.enable();
        }
        this.toFront();
        this.updateHandles();
        if(isAnim && (pExt.isIE || pExt.isWebKit)){
            var sz = this.getSize();
            this.onResize(sz.width, sz.height);
        }
        this.fireEvent('show', this);
    },
    animShow : function(){
        this.proxy.show();
        this.proxy.setBox(this.animateTarget.getB