source: trunk/web/addons/job_monarch/lib/extjs-30/adapter/ext/ext-base-debug.js @ 625

Last change on this file since 625 was 625, checked in by ramonb, 15 years ago

lib/extjs-30:

  • new ExtJS 3.0
File size: 121.0 KB
Line 
1/*!
2 * Ext JS Library 3.0.0
3 * Copyright(c) 2006-2009 Ext JS, LLC
4 * licensing@extjs.com
5 * http://www.extjs.com/license
6 */
7
8// for old browsers
9window.undefined = window.undefined;
10
11/**
12 * @class Ext
13 * Ext core utilities and functions.
14 * @singleton
15 */
16
17Ext = {
18    /**
19     * The version of the framework
20     * @type String
21     */
22    version : '3.0'
23};
24
25/**
26 * Copies all the properties of config to obj.
27 * @param {Object} obj The receiver of the properties
28 * @param {Object} config The source of the properties
29 * @param {Object} defaults A different object that will also be applied for default values
30 * @return {Object} returns obj
31 * @member Ext apply
32 */
33Ext.apply = function(o, c, defaults){
34    // no "this" reference for friendly out of scope calls
35    if(defaults){
36        Ext.apply(o, defaults);
37    }
38    if(o && c && typeof c == 'object'){
39        for(var p in c){
40            o[p] = c[p];
41        }
42    }
43    return o;
44};
45
46(function(){
47    var idSeed = 0,
48        toString = Object.prototype.toString,
49        //assume it's not null and not an array
50        isIterable = function(v){
51            //check for array or arguments
52            if(Ext.isArray(v) || v.callee){
53                return true;
54            }
55            //check for node list type
56            if(/NodeList|HTMLCollection/.test(toString.call(v))){
57                return true;
58            }
59            //NodeList has an item and length property
60            //IXMLDOMNodeList has nextNode method, needs to be checked first.
61            return ((v.nextNode || v.item) && Ext.isNumber(v.length));
62        },
63        ua = navigator.userAgent.toLowerCase(),
64        check = function(r){
65            return r.test(ua);
66        },
67        DOC = document,
68        isStrict = DOC.compatMode == "CSS1Compat",
69        isOpera = check(/opera/),
70        isChrome = check(/chrome/),
71        isWebKit = check(/webkit/),
72        isSafari = !isChrome && check(/safari/),
73        isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
74        isSafari3 = isSafari && check(/version\/3/),
75        isSafari4 = isSafari && check(/version\/4/),
76        isIE = !isOpera && check(/msie/),
77        isIE7 = isIE && check(/msie 7/),
78        isIE8 = isIE && check(/msie 8/),
79        isIE6 = isIE && !isIE7 && !isIE8,
80        isGecko = !isWebKit && check(/gecko/),
81        isGecko2 = isGecko && check(/rv:1\.8/),
82        isGecko3 = isGecko && check(/rv:1\.9/),
83        isBorderBox = isIE && !isStrict,
84        isWindows = check(/windows|win32/),
85        isMac = check(/macintosh|mac os x/),
86        isAir = check(/adobeair/),
87        isLinux = check(/linux/),
88        isSecure = /^https/i.test(window.location.protocol);
89
90    // remove css image flicker
91    if(isIE6){
92        try{
93            DOC.execCommand("BackgroundImageCache", false, true);
94        }catch(e){}
95    }
96
97    Ext.apply(Ext, {
98        /**
99         * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
100         * the IE insecure content warning (defaults to javascript:false).
101         * @type String
102         */
103        SSL_SECURE_URL : 'javascript:false',
104        /**
105         * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
106         * @type Boolean
107         */
108        isStrict : isStrict,
109        /**
110         * True if the page is running over SSL
111         * @type Boolean
112         */
113        isSecure : isSecure,
114        /**
115         * True when the document is fully initialized and ready for action
116         * @type Boolean
117         */
118        isReady : false,
119
120        /**
121         * True if the {@link Ext.Fx} Class is available
122         * @type Boolean
123         * @property enableFx
124         */
125
126        /**
127         * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
128         * @type Boolean
129         */
130        enableGarbageCollector : true,
131
132        /**
133         * True to automatically purge event listeners after uncaching an element (defaults to false).
134         * Note: this only happens if {@link #enableGarbageCollector} is true.
135         * @type Boolean
136         */
137        enableListenerCollection : false,
138
139        /**
140         * Indicates whether to use native browser parsing for JSON methods.
141         * This option is ignored if the browser does not support native JSON methods.
142         * <b>Note: Native JSON methods will not work with objects that have functions.
143         * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
144         * @type Boolean
145         */
146        USE_NATIVE_JSON : false,
147
148        /**
149         * Copies all the properties of config to obj if they don't already exist.
150         * @param {Object} obj The receiver of the properties
151         * @param {Object} config The source of the properties
152         * @return {Object} returns obj
153         */
154        applyIf : function(o, c){
155            if(o){
156                for(var p in c){
157                    if(Ext.isEmpty(o[p])){
158                        o[p] = c[p];
159                    }
160                }
161            }
162            return o;
163        },
164
165        /**
166         * Generates unique ids. If the element already has an id, it is unchanged
167         * @param {Mixed} el (optional) The element to generate an id for
168         * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
169         * @return {String} The generated Id.
170         */
171        id : function(el, prefix){
172            return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed);
173        },
174
175        /**
176         * Extends one class with another class and optionally overrides members with the passed literal. This class
177         * also adds the function "override()" to the class that can be used to override
178         * members on an instance.
179         * * <p>
180         * This function also supports a 2-argument call in which the subclass's constructor is
181         * not passed as an argument. In this form, the parameters are as follows:</p><p>
182         * <div class="mdetail-params"><ul>
183         * <li><code>superclass</code>
184         * <div class="sub-desc">The class being extended</div></li>
185         * <li><code>overrides</code>
186         * <div class="sub-desc">A literal with members which are copied into the subclass's
187         * prototype, and are therefore shared among all instances of the new class.<p>
188         * This may contain a special member named <tt><b>constructor</b></tt>. This is used
189         * to define the constructor of the new class, and is returned. If this property is
190         * <i>not</i> specified, a constructor is generated and returned which just calls the
191         * superclass's constructor passing on its parameters.</p></div></li>
192         * </ul></div></p><p>
193         * For example, to create a subclass of the Ext GridPanel:
194         * <pre><code>
195MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
196    constructor: function(config) {
197        // Your preprocessing here
198        MyGridPanel.superclass.constructor.apply(this, arguments);
199        // Your postprocessing here
200    },
201
202    yourMethod: function() {
203        // etc.
204    }
205});
206</code></pre>
207         * </p>
208         * @param {Function} subclass The class inheriting the functionality
209         * @param {Function} superclass The class being extended
210         * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
211         * prototype, and are therefore shared between all instances of the new class.
212         * @return {Function} The subclass constructor.
213         * @method extend
214         */
215        extend : function(){
216            // inline overrides
217            var io = function(o){
218                for(var m in o){
219                    this[m] = o[m];
220                }
221            };
222            var oc = Object.prototype.constructor;
223
224            return function(sb, sp, overrides){
225                if(Ext.isObject(sp)){
226                    overrides = sp;
227                    sp = sb;
228                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
229                }
230                var F = function(){},
231                    sbp,
232                    spp = sp.prototype;
233
234                F.prototype = spp;
235                sbp = sb.prototype = new F();
236                sbp.constructor=sb;
237                sb.superclass=spp;
238                if(spp.constructor == oc){
239                    spp.constructor=sp;
240                }
241                sb.override = function(o){
242                    Ext.override(sb, o);
243                };
244                sbp.superclass = sbp.supr = (function(){
245                    return spp;
246                });
247                sbp.override = io;
248                Ext.override(sb, overrides);
249                sb.extend = function(o){Ext.extend(sb, o);};
250                return sb;
251            };
252        }(),
253
254        /**
255         * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
256         * Usage:<pre><code>
257Ext.override(MyClass, {
258    newMethod1: function(){
259        // etc.
260    },
261    newMethod2: function(foo){
262        // etc.
263    }
264});
265</code></pre>
266         * @param {Object} origclass The class to override
267         * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
268         * containing one or more methods.
269         * @method override
270         */
271        override : function(origclass, overrides){
272            if(overrides){
273                var p = origclass.prototype;
274                Ext.apply(p, overrides);
275                if(Ext.isIE && overrides.toString != origclass.toString){
276                    p.toString = overrides.toString;
277                }
278            }
279        },
280
281        /**
282         * Creates namespaces to be used for scoping variables and classes so that they are not global.
283         * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
284         * <pre><code>
285Ext.namespace('Company', 'Company.data');
286Ext.namespace('Company.data'); // equivalent and preferable to above syntax
287Company.Widget = function() { ... }
288Company.data.CustomStore = function(config) { ... }
289</code></pre>
290         * @param {String} namespace1
291         * @param {String} namespace2
292         * @param {String} etc
293         * @method namespace
294         */
295        namespace : function(){
296            var o, d;
297            Ext.each(arguments, function(v) {
298                d = v.split(".");
299                o = window[d[0]] = window[d[0]] || {};
300                Ext.each(d.slice(1), function(v2){
301                    o = o[v2] = o[v2] || {};
302                });
303            });
304            return o;
305        },
306
307        /**
308         * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2".  Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
309         * @param {Object} o
310         * @param {String} pre (optional) A prefix to add to the url encoded string
311         * @return {String}
312         */
313        urlEncode: function(o, pre){
314            var undef, buf = [], key, e = encodeURIComponent;
315
316            for(key in o){
317                undef = !Ext.isDefined(o[key]);
318                Ext.each(undef ? key : o[key], function(val, i){
319                    buf.push("&", e(key), "=", (val != key || !undef) ? e(val) : "");
320                });
321            }
322            if(!pre){
323                buf.shift();
324                pre = "";
325            }
326            return pre + buf.join('');
327        },
328
329        /**
330         * Takes an encoded URL and and converts it to an object. Example: <pre><code>
331Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
332Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
333</code></pre>
334         * @param {String} string
335         * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
336         * @return {Object} A literal with members
337         */
338        urlDecode : function(string, overwrite){
339            var obj = {},
340                pairs = string.split('&'),
341                d = decodeURIComponent,
342                name,
343                value;
344            Ext.each(pairs, function(pair) {
345                pair = pair.split('=');
346                name = d(pair[0]);
347                value = d(pair[1]);
348                obj[name] = overwrite || !obj[name] ? value :
349                            [].concat(obj[name]).concat(value);
350            });
351            return obj;
352        },
353
354        /**
355         * Appends content to the query string of a URL, which handles logic for whether to place
356         * a question mark or ampersand.
357         * @param {String} url The url to append to.
358         * @@param {String} s The content to append to the url.
359         * @return (String) The appended string
360         */
361        urlAppend : function(url, s){
362            if(!Ext.isEmpty(s)){
363                return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
364            }
365            return url;
366        },
367
368        /**
369         * Converts any iterable (numeric indices and a length property) into a true array
370         * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
371         * For strings, use this instead: "abc".match(/./g) => [a,b,c];
372         * @param {Iterable} the iterable object to be turned into a true Array.
373         * @return (Array) array
374         */
375        toArray : function(){
376            return isIE ?
377                function(a, i, j, res){
378                    res = [];
379                    Ext.each(a, function(v) {
380                        res.push(v);
381                    });
382                    return res.slice(i || 0, j || res.length);
383                } :
384                function(a, i, j){
385                    return Array.prototype.slice.call(a, i || 0, j || a.length);
386                }
387        }(),
388
389        /**
390         * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
391         * passed array is not really an array, your function is called once with it.
392         * The supplied function is called with (Object item, Number index, Array allItems).
393         * @param {Array/NodeList/Mixed} array
394         * @param {Function} fn
395         * @param {Object} scope
396         */
397        each: function(array, fn, scope){
398            if(Ext.isEmpty(array, true)){
399                return;
400            }
401            if(!isIterable(array) || Ext.isPrimitive(array)){
402                array = [array];
403            }
404            for(var i = 0, len = array.length; i < len; i++){
405                if(fn.call(scope || array[i], array[i], i, array) === false){
406                    return i;
407                };
408            }
409        },
410
411        /**
412         * Iterates either the elements in an array, or each of the properties in an object.
413         * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
414         * @param {Object/Array} object The object or array to be iterated
415         * @param {Function} fn The function to be called for each iteration.
416         * The iteration will stop if the supplied function returns false, or
417         * all array elements / object properties have been covered. The signature
418         * varies depending on the type of object being interated:
419         * <div class="mdetail-params"><ul>
420         * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
421         * <div class="sub-desc">
422         * When iterating an array, the supplied function is called with each item.</div></li>
423         * <li>Objects : <tt>(String key, Object value)</tt>
424         * <div class="sub-desc">
425         * When iterating an object, the supplied function is called with each key-value pair in
426         * the object.</div></li>
427         * </ul></div>
428         * @param {Object} scope The scope to call the supplied function with, defaults to
429         * the specified <tt>object</tt>
430         */
431        iterate : function(obj, fn, scope){
432            if(isIterable(obj)){
433                Ext.each(obj, fn, scope);
434                return;
435            }else if(Ext.isObject(obj)){
436                for(var prop in obj){
437                    if(obj.hasOwnProperty(prop)){
438                        if(fn.call(scope || obj, prop, obj[prop]) === false){
439                            return;
440                        };
441                    }
442                }
443            }
444        },
445
446        /**
447         * Return the dom node for the passed String (id), dom node, or Ext.Element.
448         * Here are some examples:
449         * <pre><code>
450// gets dom node based on id
451var elDom = Ext.getDom('elId');
452// gets dom node based on the dom node
453var elDom1 = Ext.getDom(elDom);
454
455// If we don&#39;t know if we are working with an
456// Ext.Element or a dom node use Ext.getDom
457function(el){
458    var dom = Ext.getDom(el);
459    // do something with the dom node
460}
461         * </code></pre>
462         * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
463         * when this method is called to be successful.
464         * @param {Mixed} el
465         * @return HTMLElement
466         */
467        getDom : function(el){
468            if(!el || !DOC){
469                return null;
470            }
471            return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);
472        },
473
474        /**
475         * Returns the current document body as an {@link Ext.Element}.
476         * @return Ext.Element The document body
477         */
478        getBody : function(){
479            return Ext.get(DOC.body || DOC.documentElement);
480        },
481
482        /**
483         * Removes a DOM node from the document.  The body node will be ignored if passed in.
484         * @param {HTMLElement} node The node to remove
485         */
486        removeNode : isIE ? function(){
487            var d;
488            return function(n){
489                if(n && n.tagName != 'BODY'){
490                    d = d || DOC.createElement('div');
491                    d.appendChild(n);
492                    d.innerHTML = '';
493                }
494            }
495        }() : function(n){
496            if(n && n.parentNode && n.tagName != 'BODY'){
497                n.parentNode.removeChild(n);
498            }
499        },
500
501        /**
502         * <p>Returns true if the passed value is empty.</p>
503         * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
504         * <li>null</li>
505         * <li>undefined</li>
506         * <li>an empty array</li>
507         * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
508         * </ul></div>
509         * @param {Mixed} value The value to test
510         * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
511         * @return {Boolean}
512         */
513        isEmpty : function(v, allowBlank){
514            return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
515        },
516
517        /**
518         * Returns true if the passed object is a JavaScript array, otherwise false.
519         * @param {Object} object The object to test
520         * @return {Boolean}
521         */
522        isArray : function(v){
523            return toString.apply(v) === '[object Array]';
524        },
525
526        /**
527         * Returns true if the passed object is a JavaScript Object, otherwise false.
528         * @param {Object} object The object to test
529         * @return {Boolean}
530         */
531        isObject : function(v){
532            return v && typeof v == "object";
533        },
534
535        /**
536         * Returns true if the passed object is a JavaScript 'primitive', a string, number or boolean.
537         * @param {Mixed} value The value to test
538         * @return {Boolean}
539         */
540        isPrimitive : function(v){
541            return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
542        },
543
544        /**
545         * Returns true if the passed object is a JavaScript Function, otherwise false.
546         * @param {Object} object The object to test
547         * @return {Boolean}
548         */
549        isFunction : function(v){
550            return toString.apply(v) === '[object Function]';
551        },
552
553        /**
554         * Returns true if the passed object is a number. Returns false for non-finite numbers.
555         * @param {Object} v The object to test
556         * @return {Boolean}
557         */
558        isNumber: function(v){
559            return typeof v === 'number' && isFinite(v);
560        },
561
562        /**
563         * Returns true if the passed object is a string.
564         * @param {Object} v The object to test
565         * @return {Boolean}
566         */
567        isString: function(v){
568            return typeof v === 'string';
569        },
570
571        /**
572         * Returns true if the passed object is a boolean.
573         * @param {Object} v The object to test
574         * @return {Boolean}
575         */
576        isBoolean: function(v){
577            return typeof v === 'boolean';
578        },
579
580        /**
581         * Returns true if the passed object is not undefined.
582         * @param {Object} v The object to test
583         * @return {Boolean}
584         */
585        isDefined: function(v){
586            return typeof v !== 'undefined';
587        },
588
589        /**
590         * True if the detected browser is Opera.
591         * @type Boolean
592         */
593        isOpera : isOpera,
594        /**
595         * True if the detected browser uses WebKit.
596         * @type Boolean
597         */
598        isWebKit: isWebKit,
599        /**
600         * True if the detected browser is Chrome.
601         * @type Boolean
602         */
603        isChrome : isChrome,
604        /**
605         * True if the detected browser is Safari.
606         * @type Boolean
607         */
608        isSafari : isSafari,
609        /**
610         * True if the detected browser is Safari 3.x.
611         * @type Boolean
612         */
613        isSafari3 : isSafari3,
614        /**
615         * True if the detected browser is Safari 4.x.
616         * @type Boolean
617         */
618        isSafari4 : isSafari4,
619        /**
620         * True if the detected browser is Safari 2.x.
621         * @type Boolean
622         */
623        isSafari2 : isSafari2,
624        /**
625         * True if the detected browser is Internet Explorer.
626         * @type Boolean
627         */
628        isIE : isIE,
629        /**
630         * True if the detected browser is Internet Explorer 6.x.
631         * @type Boolean
632         */
633        isIE6 : isIE6,
634        /**
635         * True if the detected browser is Internet Explorer 7.x.
636         * @type Boolean
637         */
638        isIE7 : isIE7,
639        /**
640         * True if the detected browser is Internet Explorer 8.x.
641         * @type Boolean
642         */
643        isIE8 : isIE8,
644        /**
645         * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
646         * @type Boolean
647         */
648        isGecko : isGecko,
649        /**
650         * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
651         * @type Boolean
652         */
653        isGecko2 : isGecko2,
654        /**
655         * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
656         * @type Boolean
657         */
658        isGecko3 : isGecko3,
659        /**
660         * True if the detected browser is Internet Explorer running in non-strict mode.
661         * @type Boolean
662         */
663        isBorderBox : isBorderBox,
664        /**
665         * True if the detected platform is Linux.
666         * @type Boolean
667         */
668        isLinux : isLinux,
669        /**
670         * True if the detected platform is Windows.
671         * @type Boolean
672         */
673        isWindows : isWindows,
674        /**
675         * True if the detected platform is Mac OS.
676         * @type Boolean
677         */
678        isMac : isMac,
679        /**
680         * True if the detected platform is Adobe Air.
681         * @type Boolean
682         */
683        isAir : isAir
684    });
685
686    /**
687     * Creates namespaces to be used for scoping variables and classes so that they are not global.
688     * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
689     * <pre><code>
690Ext.namespace('Company', 'Company.data');
691Ext.namespace('Company.data'); // equivalent and preferable to above syntax
692Company.Widget = function() { ... }
693Company.data.CustomStore = function(config) { ... }
694</code></pre>
695     * @param {String} namespace1
696     * @param {String} namespace2
697     * @param {String} etc
698     * @method namespace
699     */
700    Ext.ns = Ext.namespace;
701})();
702
703Ext.ns("Ext", "Ext.util", "Ext.lib", "Ext.data");
704
705
706/**
707 * @class Function
708 * These functions are available on every Function object (any JavaScript function).
709 */
710Ext.apply(Function.prototype, {
711     /**
712     * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,
713     * the original one is not called. The resulting function returns the results of the original function.
714     * The passed fcn is called with the parameters of the original function. Example usage:
715     * <pre><code>
716var sayHi = function(name){
717    alert('Hi, ' + name);
718}
719
720sayHi('Fred'); // alerts "Hi, Fred"
721
722// create a new function that validates input without
723// directly modifying the original function:
724var sayHiToFriend = sayHi.createInterceptor(function(name){
725    return name == 'Brian';
726});
727
728sayHiToFriend('Fred');  // no alert
729sayHiToFriend('Brian'); // alerts "Hi, Brian"
730</code></pre>
731     * @param {Function} fcn The function to call before the original
732     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
733     * @return {Function} The new function
734     */
735    createInterceptor : function(fcn, scope){
736        var method = this;
737        return !Ext.isFunction(fcn) ?
738                this :
739                function() {
740                    var me = this,
741                        args = arguments;
742                    fcn.target = me;
743                    fcn.method = method;
744                    return (fcn.apply(scope || me || window, args) !== false) ?
745                            method.apply(me || window, args) :
746                            null;
747                };
748    },
749
750     /**
751     * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
752     * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
753     * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
754     * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
755     * executes in the window scope.
756     * <p>This method is required when you want to pass arguments to a callback function.  If no arguments
757     * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
758     * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
759     * would simply execute immediately when the code is parsed. Example usage:
760     * <pre><code>
761var sayHi = function(name){
762    alert('Hi, ' + name);
763}
764
765// clicking the button alerts "Hi, Fred"
766new Ext.Button({
767    text: 'Say Hi',
768    renderTo: Ext.getBody(),
769    handler: sayHi.createCallback('Fred')
770});
771</code></pre>
772     * @return {Function} The new function
773    */
774    createCallback : function(/*args...*/){
775        // make args available, in function below
776        var args = arguments,
777            method = this;
778        return function() {
779            return method.apply(window, args);
780        };
781    },
782
783    /**
784     * Creates a delegate (callback) that sets the scope to obj.
785     * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
786     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
787     * callback points to obj. Example usage:
788     * <pre><code>
789var sayHi = function(name){
790    // Note this use of "this.text" here.  This function expects to
791    // execute within a scope that contains a text property.  In this
792    // example, the "this" variable is pointing to the btn object that
793    // was passed in createDelegate below.
794    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
795}
796
797var btn = new Ext.Button({
798    text: 'Say Hi',
799    renderTo: Ext.getBody()
800});
801
802// This callback will execute in the scope of the
803// button instance. Clicking the button alerts
804// "Hi, Fred. You clicked the "Say Hi" button."
805btn.on('click', sayHi.createDelegate(btn, ['Fred']));
806</code></pre>
807     * @param {Object} obj (optional) The object for which the scope is set
808     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
809     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
810     *                                             if a number the args are inserted at the specified position
811     * @return {Function} The new function
812     */
813    createDelegate : function(obj, args, appendArgs){
814        var method = this;
815        return function() {
816            var callArgs = args || arguments;
817            if (appendArgs === true){
818                callArgs = Array.prototype.slice.call(arguments, 0);
819                callArgs = callArgs.concat(args);
820            }else if (Ext.isNumber(appendArgs)){
821                callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
822                var applyArgs = [appendArgs, 0].concat(args); // create method call params
823                Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
824            }
825            return method.apply(obj || window, callArgs);
826        };
827    },
828
829    /**
830     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
831     * <pre><code>
832var sayHi = function(name){
833    alert('Hi, ' + name);
834}
835
836// executes immediately:
837sayHi('Fred');
838
839// executes after 2 seconds:
840sayHi.defer(2000, this, ['Fred']);
841
842// this syntax is sometimes useful for deferring
843// execution of an anonymous function:
844(function(){
845    alert('Anonymous');
846}).defer(100);
847</code></pre>
848     * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
849     * @param {Object} obj (optional) The object for which the scope is set
850     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
851     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
852     *                                             if a number the args are inserted at the specified position
853     * @return {Number} The timeout id that can be used with clearTimeout
854     */
855    defer : function(millis, obj, args, appendArgs){
856        var fn = this.createDelegate(obj, args, appendArgs);
857        if(millis > 0){
858            return setTimeout(fn, millis);
859        }
860        fn();
861        return 0;
862    }
863});
864
865/**
866 * @class String
867 * These functions are available on every String object.
868 */
869Ext.applyIf(String, {
870    /**
871     * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
872     * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
873     * <pre><code>
874var cls = 'my-class', text = 'Some text';
875var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
876// s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
877     * </code></pre>
878     * @param {String} string The tokenized string to be formatted
879     * @param {String} value1 The value to replace token {0}
880     * @param {String} value2 Etc...
881     * @return {String} The formatted string
882     * @static
883     */
884    format : function(format){
885        var args = Ext.toArray(arguments, 1);
886        return format.replace(/\{(\d+)\}/g, function(m, i){
887            return args[i];
888        });
889    }
890});
891
892/**
893 * @class Array
894 */
895Ext.applyIf(Array.prototype, {
896    /**
897     * Checks whether or not the specified object exists in the array.
898     * @param {Object} o The object to check for
899     * @return {Number} The index of o in the array (or -1 if it is not found)
900     */
901    indexOf : function(o){
902        for (var i = 0, len = this.length; i < len; i++){
903            if(this[i] == o){
904                return i;
905            }
906        }
907        return -1;
908    },
909
910    /**
911     * Removes the specified object from the array.  If the object is not found nothing happens.
912     * @param {Object} o The object to remove
913     * @return {Array} this array
914     */
915    remove : function(o){
916        var index = this.indexOf(o);
917        if(index != -1){
918            this.splice(index, 1);
919        }
920        return this;
921    }
922});
923/**
924 * @class Ext
925 */
926
927Ext.ns("Ext.grid", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
928       "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
929    /**
930     * Namespace alloted for extensions to the framework.
931     * @property ux
932     * @type Object
933     */
934
935Ext.apply(Ext, function(){
936    var E = Ext, idSeed = 0;
937
938    return {
939        /**
940        * A reusable empty function
941        * @property
942        * @type Function
943        */
944        emptyFn : function(){},
945
946        /**
947         * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images.
948         * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server.
949         * For other browsers it uses an inline data URL.
950         * @type String
951         */
952        BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 ?
953                            'http:/' + '/extjs.com/s.gif' :
954                            'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
955
956        extendX : function(supr, fn){
957            return Ext.extend(supr, fn(supr.prototype));
958        },
959
960        /**
961         * Returns the current HTML document object as an {@link Ext.Element}.
962         * @return Ext.Element The document
963         */
964        getDoc : function(){
965            return Ext.get(document);
966        },
967
968        /**
969         * Returns true if the passed object is a JavaScript date object, otherwise false.
970         * @param {Object} object The object to test
971         * @return {Boolean}
972         */
973        isDate : function(v){
974            return Object.prototype.toString.apply(v) === '[object Date]';
975        },
976
977        /**
978         * Utility method for validating that a value is numeric, returning the specified default value if it is not.
979         * @param {Mixed} value Should be a number, but any type will be handled appropriately
980         * @param {Number} defaultValue The value to return if the original value is non-numeric
981         * @return {Number} Value, if numeric, else defaultValue
982         */
983        num : function(v, defaultValue){
984            v = Number(v === null || typeof v == 'boolean'? NaN : v);
985            return isNaN(v)? defaultValue : v;
986        },
987
988        /**
989         * <p>Utility method for returning a default value if the passed value is empty.</p>
990         * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
991         * <li>null</li>
992         * <li>undefined</li>
993         * <li>an empty array</li>
994         * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
995         * </ul></div>
996         * @param {Mixed} value The value to test
997         * @param {Mixed} defaultValue The value to return if the original value is empty
998         * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
999         * @return {Mixed} value, if non-empty, else defaultValue
1000         */
1001        value : function(v, defaultValue, allowBlank){
1002            return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
1003        },
1004
1005        /**
1006         * Escapes the passed string for use in a regular expression
1007         * @param {String} str
1008         * @return {String}
1009         */
1010        escapeRe : function(s) {
1011            return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
1012        },
1013
1014        sequence : function(o, name, fn, scope){
1015            o[name] = o[name].createSequence(fn, scope);
1016        },
1017
1018        /**
1019         * Applies event listeners to elements by selectors when the document is ready.
1020         * The event name is specified with an <tt>&#64;</tt> suffix.
1021         * <pre><code>
1022Ext.addBehaviors({
1023    // add a listener for click on all anchors in element with id foo
1024    '#foo a&#64;click' : function(e, t){
1025        // do something
1026    },
1027   
1028    // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
1029    '#foo a, #bar span.some-class&#64;mouseover' : function(){
1030        // do something
1031    }
1032});
1033         * </code></pre>
1034         * @param {Object} obj The list of behaviors to apply
1035         */
1036        addBehaviors : function(o){
1037            if(!Ext.isReady){
1038                Ext.onReady(function(){
1039                    Ext.addBehaviors(o);
1040                });
1041            } else {
1042                var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
1043                    parts,
1044                    b,
1045                    s;
1046                for (b in o) {
1047                    if ((parts = b.split('@'))[1]) { // for Object prototype breakers
1048                        s = parts[0];
1049                        if(!cache[s]){
1050                            cache[s] = Ext.select(s);
1051                        }
1052                        cache[s].on(parts[1], o[b]);
1053                    }
1054                }
1055                cache = null;
1056            }
1057        },
1058
1059
1060        // deprecated
1061        combine : function(){
1062            var as = arguments, l = as.length, r = [];
1063            for(var i = 0; i < l; i++){
1064                var a = as[i];
1065                if(Ext.isArray(a)){
1066                    r = r.concat(a);
1067                }else if(a.length !== undefined && !a.substr){
1068                    r = r.concat(Array.prototype.slice.call(a, 0));
1069                }else{
1070                    r.push(a);
1071                }
1072            }
1073            return r;
1074        },
1075
1076        /**
1077         * Copies a set of named properties fom the source object to the destination object.
1078         * <p>example:<pre><code>
1079ImageComponent = Ext.extend(Ext.BoxComponent, {
1080    initComponent: function() {
1081        this.autoEl = { tag: 'img' };
1082        MyComponent.superclass.initComponent.apply(this, arguments);
1083        this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
1084    }
1085});
1086         * </code></pre>
1087         * @param {Object} The destination object.
1088         * @param {Object} The source object.
1089         * @param {Array/String} Either an Array of property names, or a comma-delimited list
1090         * of property names to copy.
1091         * @return {Object} The modified object.
1092        */
1093        copyTo : function(dest, source, names){
1094            if(typeof names == 'string'){
1095                names = names.split(/[,;\s]/);
1096            }
1097            Ext.each(names, function(name){
1098                if(source.hasOwnProperty(name)){
1099                    dest[name] = source[name];
1100                }
1101            }, this);
1102            return dest;
1103        },
1104
1105        /**
1106         * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
1107         * DOM (if applicable) and calling their destroy functions (if available).  This method is primarily
1108         * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
1109         * {@link Ext.util.Observable} can be passed in.  Any number of elements and/or components can be
1110         * passed into this function in a single call as separate arguments.
1111         * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
1112         * @param {Mixed} arg2 (optional)
1113         * @param {Mixed} etc... (optional)
1114         */
1115        destroy : function(){
1116            Ext.each(arguments, function(arg){
1117                if(arg){
1118                    if(Ext.isArray(arg)){
1119                        this.destroy.apply(this, arg);
1120                    }else if(Ext.isFunction(arg.destroy)){
1121                        arg.destroy();
1122                    }else if(arg.dom){
1123                        arg.remove();
1124                    }   
1125                }
1126            }, this);
1127        },
1128
1129        /**
1130         * Attempts to destroy and then remove a set of named properties of the passed object.
1131         * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
1132         * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
1133         * @param {Mixed} etc... More property names to destroy and remove.
1134         */
1135        destroyMembers : function(o, arg1, arg2, etc){
1136            for(var i = 1, a = arguments, len = a.length; i < len; i++) {
1137                Ext.destroy(o[a[i]]);
1138                delete o[a[i]];
1139            }
1140        },
1141
1142        /**
1143         * Creates a copy of the passed Array with falsy values removed.
1144         * @param {Array/NodeList} arr The Array from which to remove falsy values.
1145         * @return {Array} The new, compressed Array.
1146         */
1147        clean : function(arr){
1148            var ret = [];
1149            Ext.each(arr, function(v){
1150                if(!!v){
1151                    ret.push(v);
1152                }
1153            });
1154            return ret;
1155        },
1156
1157        /**
1158         * Creates a copy of the passed Array, filtered to contain only unique values.
1159         * @param {Array} arr The Array to filter
1160         * @return {Array} The new Array containing unique values.
1161         */
1162        unique : function(arr){
1163            var ret = [],
1164                collect = {};
1165
1166            Ext.each(arr, function(v) {
1167                if(!collect[v]){
1168                    ret.push(v);
1169                }
1170                collect[v] = true;
1171            });
1172            return ret;
1173        },
1174
1175        /**
1176         * Recursively flattens into 1-d Array. Injects Arrays inline.
1177         * @param {Array} arr The array to flatten
1178         * @return {Array} The new, flattened array.
1179         */
1180        flatten : function(arr){
1181            var worker = [];
1182            function rFlatten(a) {
1183                Ext.each(a, function(v) {
1184                    if(Ext.isArray(v)){
1185                        rFlatten(v);
1186                    }else{
1187                        worker.push(v);
1188                    }
1189                });
1190                return worker;
1191            }
1192            return rFlatten(arr);
1193        },
1194
1195        /**
1196         * Returns the minimum value in the Array.
1197         * @param {Array|NodeList} arr The Array from which to select the minimum value.
1198         * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
1199         *                   If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
1200         * @return {Object} The minimum value in the Array.
1201         */
1202        min : function(arr, comp){
1203            var ret = arr[0];
1204            comp = comp || function(a,b){ return a < b ? -1 : 1; };
1205            Ext.each(arr, function(v) {
1206                ret = comp(ret, v) == -1 ? ret : v;
1207            });
1208            return ret;
1209        },
1210
1211        /**
1212         * Returns the maximum value in the Array
1213         * @param {Array|NodeList} arr The Array from which to select the maximum value.
1214         * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
1215         *                   If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
1216         * @return {Object} The maximum value in the Array.
1217         */
1218        max : function(arr, comp){
1219            var ret = arr[0];
1220            comp = comp || function(a,b){ return a > b ? 1 : -1; };
1221            Ext.each(arr, function(v) {
1222                ret = comp(ret, v) == 1 ? ret : v;
1223            });
1224            return ret;
1225        },
1226
1227        /**
1228         * Calculates the mean of the Array
1229         * @param {Array} arr The Array to calculate the mean value of.
1230         * @return {Number} The mean.
1231         */
1232        mean : function(arr){
1233           return Ext.sum(arr) / arr.length;
1234        },
1235
1236        /**
1237         * Calculates the sum of the Array
1238         * @param {Array} arr The Array to calculate the sum value of.
1239         * @return {Number} The sum.
1240         */
1241        sum : function(arr){
1242           var ret = 0;
1243           Ext.each(arr, function(v) {
1244               ret += v;
1245           });
1246           return ret;
1247        },
1248
1249        /**
1250         * Partitions the set into two sets: a true set and a false set.
1251         * Example:
1252         * Example2:
1253         * <pre><code>
1254// Example 1:
1255Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
1256
1257// Example 2:
1258Ext.partition(
1259    Ext.query("p"),
1260    function(val){
1261        return val.className == "class1"
1262    }
1263);
1264// true are those paragraph elements with a className of "class1",
1265// false set are those that do not have that className.
1266         * </code></pre>
1267         * @param {Array|NodeList} arr The array to partition
1268         * @param {Function} truth (optional) a function to determine truth.  If this is omitted the element
1269         *                   itself must be able to be evaluated for its truthfulness.
1270         * @return {Array} [true<Array>,false<Array>]
1271         */
1272        partition : function(arr, truth){
1273            var ret = [[],[]];
1274            Ext.each(arr, function(v, i, a) {
1275                ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
1276            });
1277            return ret;
1278        },
1279
1280        /**
1281         * Invokes a method on each item in an Array.
1282         * <pre><code>
1283// Example:
1284Ext.invoke(Ext.query("p"), "getAttribute", "id");
1285// [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
1286         * </code></pre>
1287         * @param {Array|NodeList} arr The Array of items to invoke the method on.
1288         * @param {String} methodName The method name to invoke.
1289         * @param {Anything} ... Arguments to send into the method invocation.
1290         * @return {Array} The results of invoking the method on each item in the array.
1291         */
1292        invoke : function(arr, methodName){
1293            var ret = [],
1294                args = Array.prototype.slice.call(arguments, 2);
1295            Ext.each(arr, function(v,i) {
1296                if (v && typeof v[methodName] == "function") {
1297                    ret.push(v[methodName].apply(v, args));
1298                } else {
1299                    ret.push(undefined);
1300                }
1301            });
1302            return ret;
1303        },
1304
1305        /**
1306         * Plucks the value of a property from each item in the Array
1307         * <pre><code>
1308// Example:
1309Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
1310         * </code></pre>
1311         * @param {Array|NodeList} arr The Array of items to pluck the value from.
1312         * @param {String} prop The property name to pluck from each element.
1313         * @return {Array} The value from each item in the Array.
1314         */
1315        pluck : function(arr, prop){
1316            var ret = [];
1317            Ext.each(arr, function(v) {
1318                ret.push( v[prop] );
1319            });
1320            return ret;
1321        },
1322
1323        /**
1324         * <p>Zips N sets together.</p>
1325         * <pre><code>
1326// Example 1:
1327Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
1328// Example 2:
1329Ext.zip(
1330    [ "+", "-", "+"],
1331    [  12,  10,  22],
1332    [  43,  15,  96],
1333    function(a, b, c){
1334        return "$" + a + "" + b + "." + c
1335    }
1336); // ["$+12.43", "$-10.15", "$+22.96"]
1337         * </code></pre>
1338         * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
1339         * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
1340         * @return {Array} The zipped set.
1341         */
1342        zip : function(){
1343            var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
1344                arrs = parts[0],
1345                fn = parts[1][0],
1346                len = Ext.max(Ext.pluck(arrs, "length")),
1347                ret = [];
1348
1349            for (var i = 0; i < len; i++) {
1350                ret[i] = [];
1351                if(fn){
1352                    ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
1353                }else{
1354                    for (var j = 0, aLen = arrs.length; j < aLen; j++){
1355                        ret[i].push( arrs[j][i] );
1356                    }
1357                }
1358            }
1359            return ret;
1360        },
1361
1362        /**
1363         * This is shorthand reference to {@link Ext.ComponentMgr#get}.
1364         * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
1365         * @param {String} id The component {@link Ext.Component#id id}
1366         * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
1367         * Class was found.
1368        */
1369        getCmp : function(id){
1370            return Ext.ComponentMgr.get(id);
1371        },
1372
1373        /**
1374         * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
1375         * you may want to set this to true.
1376         * @type Boolean
1377         */
1378        useShims: E.isIE6 || (E.isMac && E.isGecko2),
1379
1380        // inpired by a similar function in mootools library
1381        /**
1382         * Returns the type of object that is passed in. If the object passed in is null or undefined it
1383         * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul>
1384         * <li><b>string</b>: If the object passed is a string</li>
1385         * <li><b>number</b>: If the object passed is a number</li>
1386         * <li><b>boolean</b>: If the object passed is a boolean value</li>
1387         * <li><b>date</b>: If the object passed is a Date object</li>
1388         * <li><b>function</b>: If the object passed is a function reference</li>
1389         * <li><b>object</b>: If the object passed is an object</li>
1390         * <li><b>array</b>: If the object passed is an array</li>
1391         * <li><b>regexp</b>: If the object passed is a regular expression</li>
1392         * <li><b>element</b>: If the object passed is a DOM Element</li>
1393         * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
1394         * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
1395         * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
1396         * </ul></div>
1397         * @param {Mixed} object
1398         * @return {String}
1399         */
1400        type : function(o){
1401            if(o === undefined || o === null){
1402                return false;
1403            }
1404            if(o.htmlElement){
1405                return 'element';
1406            }
1407            var t = typeof o;
1408            if(t == 'object' && o.nodeName) {
1409                switch(o.nodeType) {
1410                    case 1: return 'element';
1411                    case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
1412                }
1413            }
1414            if(t == 'object' || t == 'function') {
1415                switch(o.constructor) {
1416                    case Array: return 'array';
1417                    case RegExp: return 'regexp';
1418                    case Date: return 'date';
1419                }
1420                if(typeof o.length == 'number' && typeof o.item == 'function') {
1421                    return 'nodelist';
1422                }
1423            }
1424            return t;
1425        },
1426
1427        intercept : function(o, name, fn, scope){
1428            o[name] = o[name].createInterceptor(fn, scope);
1429        },
1430
1431        // internal
1432        callback : function(cb, scope, args, delay){
1433            if(Ext.isFunction(cb)){
1434                if(delay){
1435                    cb.defer(delay, scope, args || []);
1436                }else{
1437                    cb.apply(scope, args || []);
1438                }
1439            }
1440        }
1441    };
1442}());
1443
1444/**
1445 * @class Function
1446 * These functions are available on every Function object (any JavaScript function).
1447 */
1448Ext.apply(Function.prototype, {
1449    /**
1450     * Create a combined function call sequence of the original function + the passed function.
1451     * The resulting function returns the results of the original function.
1452     * The passed fcn is called with the parameters of the original function. Example usage:
1453     * <pre><code>
1454var sayHi = function(name){
1455    alert('Hi, ' + name);
1456}
1457
1458sayHi('Fred'); // alerts "Hi, Fred"
1459
1460var sayGoodbye = sayHi.createSequence(function(name){
1461    alert('Bye, ' + name);
1462});
1463
1464sayGoodbye('Fred'); // both alerts show
1465</code></pre>
1466     * @param {Function} fcn The function to sequence
1467     * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
1468     * @return {Function} The new function
1469     */
1470    createSequence : function(fcn, scope){
1471        var method = this;
1472        return !Ext.isFunction(fcn) ?
1473                this :
1474                function(){
1475                    var retval = method.apply(this || window, arguments);
1476                    fcn.apply(scope || this || window, arguments);
1477                    return retval;
1478                };
1479    }
1480});
1481
1482
1483/**
1484 * @class String
1485 * These functions are available as static methods on the JavaScript String object.
1486 */
1487Ext.applyIf(String, {
1488
1489    /**
1490     * Escapes the passed string for ' and \
1491     * @param {String} string The string to escape
1492     * @return {String} The escaped string
1493     * @static
1494     */
1495    escape : function(string) {
1496        return string.replace(/('|\\)/g, "\\$1");
1497    },
1498
1499    /**
1500     * Pads the left side of a string with a specified character.  This is especially useful
1501     * for normalizing number and date strings.  Example usage:
1502     * <pre><code>
1503var s = String.leftPad('123', 5, '0');
1504// s now contains the string: '00123'
1505     * </code></pre>
1506     * @param {String} string The original string
1507     * @param {Number} size The total length of the output string
1508     * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
1509     * @return {String} The padded string
1510     * @static
1511     */
1512    leftPad : function (val, size, ch) {
1513        var result = String(val);
1514        if(!ch) {
1515            ch = " ";
1516        }
1517        while (result.length < size) {
1518            result = ch + result;
1519        }
1520        return result;
1521    }
1522});
1523
1524/**
1525 * Utility function that allows you to easily switch a string between two alternating values.  The passed value
1526 * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
1527 * they are already different, the first value passed in is returned.  Note that this method returns the new value
1528 * but does not change the current string.
1529 * <pre><code>
1530// alternate sort directions
1531sort = sort.toggle('ASC', 'DESC');
1532
1533// instead of conditional logic:
1534sort = (sort == 'ASC' ? 'DESC' : 'ASC');
1535</code></pre>
1536 * @param {String} value The value to compare to the current string
1537 * @param {String} other The new value to use if the string already equals the first value passed in
1538 * @return {String} The new value
1539 */
1540String.prototype.toggle = function(value, other){
1541    return this == value ? other : value;
1542};
1543
1544/**
1545 * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
1546 * <pre><code>
1547var s = '  foo bar  ';
1548alert('-' + s + '-');         //alerts "- foo bar -"
1549alert('-' + s.trim() + '-');  //alerts "-foo bar-"
1550</code></pre>
1551 * @return {String} The trimmed string
1552 */
1553String.prototype.trim = function(){
1554    var re = /^\s+|\s+$/g;
1555    return function(){ return this.replace(re, ""); };
1556}();
1557
1558// here to prevent dependency on Date.js
1559/**
1560 Returns the number of milliseconds between this date and date
1561 @param {Date} date (optional) Defaults to now
1562 @return {Number} The diff in milliseconds
1563 @member Date getElapsed
1564 */
1565Date.prototype.getElapsed = function(date) {
1566    return Math.abs((date || new Date()).getTime()-this.getTime());
1567};
1568
1569
1570/**
1571 * @class Number
1572 */
1573Ext.applyIf(Number.prototype, {
1574    /**
1575     * Checks whether or not the current number is within a desired range.  If the number is already within the
1576     * range it is returned, otherwise the min or max value is returned depending on which side of the range is
1577     * exceeded.  Note that this method returns the constrained value but does not change the current number.
1578     * @param {Number} min The minimum number in the range
1579     * @param {Number} max The maximum number in the range
1580     * @return {Number} The constrained value if outside the range, otherwise the current value
1581     */
1582    constrain : function(min, max){
1583        return Math.min(Math.max(this, min), max);
1584    }
1585});
1586/**
1587 * @class Ext.util.TaskRunner
1588 * Provides the ability to execute one or more arbitrary tasks in a multithreaded
1589 * manner.  Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
1590 * if needed, you can create separate instances of TaskRunner.  Any number of
1591 * separate tasks can be started at any time and will run independently of each
1592 * other. Example usage:
1593 * <pre><code>
1594// Start a simple clock task that updates a div once per second
1595var updateClock = function(){
1596    Ext.fly('clock').update(new Date().format('g:i:s A'));
1597}
1598var task = {
1599    run: updateClock,
1600    interval: 1000 //1 second
1601}
1602var runner = new Ext.util.TaskRunner();
1603runner.start(task);
1604
1605// equivalent using TaskMgr
1606Ext.TaskMgr.start({
1607    run: updateClock,
1608    interval: 1000
1609});
1610
1611 * </code></pre>
1612 * Also see {@link Ext.util.DelayedTask}.
1613 *
1614 * @constructor
1615 * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
1616 * (defaults to 10)
1617 */
1618Ext.util.TaskRunner = function(interval){
1619    interval = interval || 10;
1620    var tasks = [], 
1621        removeQueue = [],
1622        id = 0,
1623        running = false,
1624
1625        // private
1626        stopThread = function(){
1627                running = false;
1628                clearInterval(id);
1629                id = 0;
1630            },
1631
1632        // private
1633        startThread = function(){
1634                if(!running){
1635                    running = true;
1636                    id = setInterval(runTasks, interval);
1637                }
1638            },
1639
1640        // private
1641        removeTask = function(t){
1642                removeQueue.push(t);
1643                if(t.onStop){
1644                    t.onStop.apply(t.scope || t);
1645                }
1646            },
1647           
1648        // private
1649        runTasks = function(){
1650                var rqLen = removeQueue.length,
1651                        now = new Date().getTime();                                             
1652           
1653                if(rqLen > 0){
1654                    for(var i = 0; i < rqLen; i++){
1655                        tasks.remove(removeQueue[i]);
1656                    }
1657                    removeQueue = [];
1658                    if(tasks.length < 1){
1659                        stopThread();
1660                        return;
1661                    }
1662                }               
1663                for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
1664                    t = tasks[i];
1665                    itime = now - t.taskRunTime;
1666                    if(t.interval <= itime){
1667                        rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
1668                        t.taskRunTime = now;
1669                        if(rt === false || t.taskRunCount === t.repeat){
1670                            removeTask(t);
1671                            return;
1672                        }
1673                    }
1674                    if(t.duration && t.duration <= (now - t.taskStartTime)){
1675                        removeTask(t);
1676                    }
1677                }
1678            };
1679
1680    /**
1681     * Starts a new task.
1682     * @method start
1683     * @param {Object} task A config object that supports the following properties:<ul>
1684     * <li><code>run</code> : Function<div class="sub-desc">The function to execute each time the task is run. The
1685     * function will be called at each interval and passed the <code>args</code> argument if specified.  If a
1686     * particular scope is required, be sure to specify it using the <code>scope</code> argument.</div></li>
1687     * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task
1688     * should be executed.</div></li>
1689     * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function
1690     * specified by <code>run</code>.</div></li>
1691     * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope (<tt>this</tt> reference) in which to execute the
1692     * <code>run</code> function. Defaults to the task config object.</div></li>
1693     * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to execute
1694     * the task before stopping automatically (defaults to indefinite).</div></li>
1695     * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to execute the task before
1696     * stopping automatically (defaults to indefinite).</div></li>
1697     * </ul>
1698     * @return {Object} The task
1699     */
1700    this.start = function(task){
1701        tasks.push(task);
1702        task.taskStartTime = new Date().getTime();
1703        task.taskRunTime = 0;
1704        task.taskRunCount = 0;
1705        startThread();
1706        return task;
1707    };
1708
1709    /**
1710     * Stops an existing running task.
1711     * @method stop
1712     * @param {Object} task The task to stop
1713     * @return {Object} The task
1714     */
1715    this.stop = function(task){
1716        removeTask(task);
1717        return task;
1718    };
1719
1720    /**
1721     * Stops all tasks that are currently running.
1722     * @method stopAll
1723     */
1724    this.stopAll = function(){
1725        stopThread();
1726        for(var i = 0, len = tasks.length; i < len; i++){
1727            if(tasks[i].onStop){
1728                tasks[i].onStop();
1729            }
1730        }
1731        tasks = [];
1732        removeQueue = [];
1733    };
1734};
1735
1736/**
1737 * @class Ext.TaskMgr
1738 * @extends Ext.util.TaskRunner
1739 * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks.  See
1740 * {@link Ext.util.TaskRunner} for supported methods and task config properties.
1741 * <pre><code>
1742// Start a simple clock task that updates a div once per second
1743var task = {
1744    run: function(){
1745        Ext.fly('clock').update(new Date().format('g:i:s A'));
1746    },
1747    interval: 1000 //1 second
1748}
1749Ext.TaskMgr.start(task);
1750</code></pre>
1751 * @singleton
1752 */
1753Ext.TaskMgr = new Ext.util.TaskRunner();(function(){
1754        var libFlyweight;
1755       
1756        function fly(el) {
1757        if (!libFlyweight) {
1758            libFlyweight = new Ext.Element.Flyweight();
1759        }
1760        libFlyweight.dom = el;
1761        return libFlyweight;
1762    }
1763   
1764    (function(){
1765        var doc = document,
1766                isCSS1 = doc.compatMode == "CSS1Compat",
1767                MAX = Math.max,         
1768                PARSEINT = parseInt;
1769               
1770        Ext.lib.Dom = {
1771            isAncestor : function(p, c) {
1772                    var ret = false;
1773                       
1774                        p = Ext.getDom(p);
1775                        c = Ext.getDom(c);
1776                        if (p && c) {
1777                                if (p.contains) {
1778                                        return p.contains(c);
1779                                } else if (p.compareDocumentPosition) {
1780                                        return !!(p.compareDocumentPosition(c) & 16);
1781                                } else {
1782                                        while (c = c.parentNode) {
1783                                                ret = c == p || ret;                                   
1784                                        }
1785                                }                   
1786                        }       
1787                        return ret;
1788                },
1789               
1790        getViewWidth : function(full) {
1791            return full ? this.getDocumentWidth() : this.getViewportWidth();
1792        },
1793
1794        getViewHeight : function(full) {
1795            return full ? this.getDocumentHeight() : this.getViewportHeight();
1796        },
1797
1798        getDocumentHeight: function() {           
1799            return MAX(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, this.getViewportHeight());
1800        },
1801
1802        getDocumentWidth: function() {           
1803            return MAX(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, this.getViewportWidth());
1804        },
1805
1806        getViewportHeight: function(){
1807                return Ext.isIE ? 
1808                           (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) :
1809                           self.innerHeight;
1810        },
1811
1812        getViewportWidth : function() {
1813                return !Ext.isStrict && !Ext.isOpera ? doc.body.clientWidth :
1814                           Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth;
1815        },
1816       
1817        getY : function(el) {
1818            return this.getXY(el)[1];
1819        },
1820
1821        getX : function(el) {
1822            return this.getXY(el)[0];
1823        },
1824
1825        getXY : function(el) {
1826            var p, 
1827                pe, 
1828                b,
1829                bt, 
1830                bl,     
1831                dbd,           
1832                x = 0,
1833                y = 0, 
1834                scroll,
1835                hasAbsolute, 
1836                bd = (doc.body || doc.documentElement),
1837                ret = [0,0];
1838               
1839            el = Ext.getDom(el);
1840
1841            if(el != bd){
1842                    if (el.getBoundingClientRect) {
1843                        b = el.getBoundingClientRect();
1844                        scroll = fly(document).getScroll();
1845                        ret = [b.left + scroll.left, b.top + scroll.top];
1846                    } else { 
1847                            p = el;             
1848                            hasAbsolute = fly(el).isStyle("position", "absolute");
1849               
1850                            while (p) {
1851                                    pe = fly(p);               
1852                                x += p.offsetLeft;
1853                                y += p.offsetTop;
1854               
1855                                hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");
1856                                               
1857                                if (Ext.isGecko) {                                 
1858                                    y += bt = PARSEINT(pe.getStyle("borderTopWidth"), 10) || 0;
1859                                    x += bl = PARSEINT(pe.getStyle("borderLeftWidth"), 10) || 0;       
1860               
1861                                    if (p != el && !pe.isStyle('overflow','visible')) {
1862                                        x += bl;
1863                                        y += bt;
1864                                    }
1865                                }
1866                                p = p.offsetParent;
1867                            }
1868               
1869                            if (Ext.isSafari && hasAbsolute) {
1870                                x -= bd.offsetLeft;
1871                                y -= bd.offsetTop;
1872                            }
1873               
1874                            if (Ext.isGecko && !hasAbsolute) {
1875                                dbd = fly(bd);
1876                                x += PARSEINT(dbd.getStyle("borderLeftWidth"), 10) || 0;
1877                                y += PARSEINT(dbd.getStyle("borderTopWidth"), 10) || 0;
1878                            }
1879               
1880                            p = el.parentNode;
1881                            while (p && p != bd) {
1882                                if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {
1883                                    x -= p.scrollLeft;
1884                                    y -= p.scrollTop;
1885                                }
1886                                p = p.parentNode;
1887                            }
1888                            ret = [x,y];
1889                    }
1890                }
1891            return ret
1892        },
1893
1894        setXY : function(el, xy) {
1895            (el = Ext.fly(el, '_setXY')).position();
1896           
1897            var pts = el.translatePoints(xy),
1898                style = el.dom.style,
1899                pos;                   
1900           
1901            for (pos in pts) {             
1902                    if(!isNaN(pts[pos])) style[pos] = pts[pos] + "px"
1903            }
1904        },
1905
1906        setX : function(el, x) {
1907            this.setXY(el, [x, false]);
1908        },
1909
1910        setY : function(el, y) {
1911            this.setXY(el, [false, y]);
1912        }
1913    };
1914})();Ext.lib.Dom.getRegion = function(el) {
1915    return Ext.lib.Region.getRegion(el);
1916};Ext.lib.Event = function() {
1917    var loadComplete = false,
1918        listeners = [],
1919        unloadListeners = [],
1920        retryCount = 0,
1921        onAvailStack = [],
1922        _interval,
1923        locked = false,
1924        win = window,
1925        doc = document,
1926       
1927        // constants           
1928        POLL_RETRYS = 200,
1929        POLL_INTERVAL = 20,
1930        EL = 0,
1931        TYPE = 1,
1932        FN = 2,
1933        WFN = 3,
1934        OBJ = 3,
1935        ADJ_SCOPE = 4,   
1936        SCROLLLEFT = 'scrollLeft',
1937        SCROLLTOP = 'scrollTop',
1938        UNLOAD = 'unload',
1939        MOUSEOVER = 'mouseover',
1940        MOUSEOUT = 'mouseout',
1941        // private
1942        doAdd = function() {
1943            var ret;
1944            if (win.addEventListener) {
1945                ret = function(el, eventName, fn, capture) {
1946                    if (eventName == 'mouseenter') {
1947                        fn = fn.createInterceptor(checkRelatedTarget);
1948                        el.addEventListener(MOUSEOVER, fn, (capture));
1949                    } else if (eventName == 'mouseleave') {
1950                        fn = fn.createInterceptor(checkRelatedTarget);
1951                        el.addEventListener(MOUSEOUT, fn, (capture));
1952                    } else {
1953                        el.addEventListener(eventName, fn, (capture));
1954                    }
1955                    return fn;
1956                };
1957            } else if (win.attachEvent) {
1958                ret = function(el, eventName, fn, capture) {
1959                    el.attachEvent("on" + eventName, fn);
1960                    return fn;
1961                };
1962            } else {
1963                ret = function(){};
1964            }
1965            return ret;
1966        }(),   
1967        // private
1968        doRemove = function(){
1969            var ret;
1970            if (win.removeEventListener) {
1971                ret = function (el, eventName, fn, capture) {
1972                    if (eventName == 'mouseenter') {
1973                        eventName = MOUSEOVER;
1974                    } else if (eventName == 'mouseleave') {
1975                        eventName = MOUSEOUT;
1976                    }                       
1977                    el.removeEventListener(eventName, fn, (capture));
1978                };
1979            } else if (win.detachEvent) {
1980                ret = function (el, eventName, fn) {
1981                    el.detachEvent("on" + eventName, fn);
1982                };
1983            } else {
1984                ret = function(){};
1985            }
1986            return ret;
1987        }();       
1988
1989    var isXUL = Ext.isGecko ? function(node){ 
1990        return Object.prototype.toString.call(node) == '[object XULElement]';
1991    } : function(){};
1992       
1993    var isTextNode = Ext.isGecko ? function(node){
1994        try{
1995            return node.nodeType == 3;
1996        }catch(e) {
1997            return false;
1998        }
1999
2000    } : function(node){
2001        return node.nodeType == 3;
2002    };
2003       
2004    function checkRelatedTarget(e) {
2005        var related = pub.getRelatedTarget(e);
2006        return !(isXUL(related) || elContains(e.currentTarget,related));
2007    }
2008
2009    function elContains(parent, child) {
2010       if(parent && parent.firstChild){ 
2011         while(child) {
2012            if(child === parent) {
2013                return true;
2014            }
2015            try {
2016                child = child.parentNode;
2017            } catch(e) {
2018                // In FF if you mouseout an text input element
2019                // thats inside a div sometimes it randomly throws
2020                // Permission denied to get property HTMLDivElement.parentNode
2021                // See https://bugzilla.mozilla.org/show_bug.cgi?id=208427
2022               
2023                return false;
2024            }               
2025            if(child && (child.nodeType != 1)) {
2026                child = null;
2027            }
2028          }
2029        }
2030        return false;
2031    }
2032
2033       
2034    // private 
2035    function _getCacheIndex(el, eventName, fn) {
2036        var index = -1;
2037        Ext.each(listeners, function (v,i) {
2038            if(v && v[FN] == fn && v[EL] == el && v[TYPE] == eventName) {
2039                index = i;
2040            }
2041        });
2042        return index;
2043    }
2044                   
2045    // private
2046    function _tryPreloadAttach() {
2047        var ret = false,               
2048            notAvail = [],
2049            element,
2050            tryAgain = !loadComplete || (retryCount > 0);                       
2051       
2052        if (!locked) {
2053            locked = true;
2054           
2055            Ext.each(onAvailStack, function (v,i,a){
2056                if(v && (element = doc.getElementById(v.id))){
2057                    if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
2058                        element = v.override ? (v.override === true ? v.obj : v.override) : element;
2059                        v.fn.call(element, v.obj);
2060                        onAvailStack[i] = null;
2061                    } else {
2062                        notAvail.push(v);
2063                    }
2064                }   
2065            });
2066
2067            retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
2068
2069            if (tryAgain) { 
2070                startInterval();
2071            } else {
2072                clearInterval(_interval);
2073                _interval = null;
2074            }
2075
2076            ret = !(locked = false);
2077        }
2078        return ret;
2079    }
2080   
2081    // private             
2082    function startInterval() {           
2083        if(!_interval){                   
2084            var callback = function() {
2085                _tryPreloadAttach();
2086            };
2087            _interval = setInterval(callback, POLL_INTERVAL);
2088        }
2089    }
2090   
2091    // private
2092    function getScroll() {
2093        var dd = doc.documentElement, 
2094            db = doc.body;
2095        if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
2096            return [dd[SCROLLLEFT], dd[SCROLLTOP]];
2097        }else if(db){
2098            return [db[SCROLLLEFT], db[SCROLLTOP]];
2099        }else{
2100            return [0, 0];
2101        }
2102    }
2103       
2104    // private
2105    function getPageCoord (ev, xy) {
2106        ev = ev.browserEvent || ev;
2107        var coord  = ev['page' + xy];
2108        if (!coord && coord !== 0) {
2109            coord = ev['client' + xy] || 0;
2110
2111            if (Ext.isIE) {
2112                coord += getScroll()[xy == "X" ? 0 : 1];
2113            }
2114        }
2115
2116        return coord;
2117    }
2118
2119    var pub =  {
2120        onAvailable : function(p_id, p_fn, p_obj, p_override) {             
2121            onAvailStack.push({ 
2122                id:         p_id,
2123                fn:         p_fn,
2124                obj:        p_obj,
2125                override:   p_override,
2126                checkReady: false });
2127
2128            retryCount = POLL_RETRYS;
2129            startInterval();
2130        },
2131
2132
2133        addListener: function(el, eventName, fn) {
2134            var ret;               
2135            el = Ext.getDom(el);               
2136            if (el && fn) {
2137                if (UNLOAD == eventName) {
2138                    ret = !!(unloadListeners[unloadListeners.length] = [el, eventName, fn]);                   
2139                } else {
2140                    listeners.push([el, eventName, fn, ret = doAdd(el, eventName, fn, false)]);
2141                }
2142            }
2143            return !!ret;
2144        },
2145
2146        removeListener: function(el, eventName, fn) {
2147            var ret = false,
2148                index, 
2149                cacheItem;
2150
2151            el = Ext.getDom(el);
2152
2153            if(!fn) {                   
2154                ret = this.purgeElement(el, false, eventName);
2155            } else if (UNLOAD == eventName) {   
2156                Ext.each(unloadListeners, function(v, i, a) {
2157                    if( v && v[0] == el && v[1] == eventName && v[2] == fn) {
2158                        unloadListeners.splice(i, 1);
2159                        ret = true;
2160                    }
2161                });
2162            } else {   
2163                index = arguments[3] || _getCacheIndex(el, eventName, fn);
2164                cacheItem = listeners[index];
2165               
2166                if (el && cacheItem) {
2167                    doRemove(el, eventName, cacheItem[WFN], false);     
2168                    cacheItem[WFN] = cacheItem[FN] = null;                       
2169                    listeners.splice(index, 1);     
2170                    ret = true;
2171                }
2172            }
2173            return ret;
2174        },
2175
2176        getTarget : function(ev) {
2177            ev = ev.browserEvent || ev;               
2178            return this.resolveTextNode(ev.target || ev.srcElement);
2179        },
2180
2181        resolveTextNode : function(node) {
2182            return node && !isXUL(node) && isTextNode(node) ? node.parentNode : node;
2183        },
2184
2185        getRelatedTarget : function(ev) {
2186            ev = ev.browserEvent || ev;
2187            return this.resolveTextNode(ev.relatedTarget || 
2188                    (ev.type == MOUSEOUT ? ev.toElement :
2189                     ev.type == MOUSEOVER ? ev.fromElement : null));
2190        },
2191       
2192        getPageX : function(ev) {
2193            return getPageCoord(ev, "X");
2194        },
2195
2196        getPageY : function(ev) {
2197            return getPageCoord(ev, "Y");
2198        },
2199
2200
2201        getXY : function(ev) {                             
2202            return [this.getPageX(ev), this.getPageY(ev)];
2203        },
2204
2205// Is this useful?  Removing to save space unless use case exists.
2206//             getTime: function(ev) {
2207//                 ev = ev.browserEvent || ev;
2208//                 if (!ev.time) {
2209//                     var t = new Date().getTime();
2210//                     try {
2211//                         ev.time = t;
2212//                     } catch(ex) {
2213//                         return t;
2214//                     }
2215//                 }
2216
2217//                 return ev.time;
2218//             },
2219
2220        stopEvent : function(ev) {                           
2221            this.stopPropagation(ev);
2222            this.preventDefault(ev);
2223        },
2224
2225        stopPropagation : function(ev) {
2226            ev = ev.browserEvent || ev;
2227            if (ev.stopPropagation) {
2228                ev.stopPropagation();
2229            } else {
2230                ev.cancelBubble = true;
2231            }
2232        },
2233
2234        preventDefault : function(ev) {
2235            ev = ev.browserEvent || ev;
2236            if (ev.preventDefault) {
2237                ev.preventDefault();
2238            } else {
2239                ev.returnValue = false;
2240            }
2241        },
2242       
2243        getEvent : function(e) {
2244            e = e || win.event;
2245            if (!e) {
2246                var c = this.getEvent.caller;
2247                while (c) {
2248                    e = c.arguments[0];
2249                    if (e && Event == e.constructor) {
2250                        break;
2251                    }
2252                    c = c.caller;
2253                }
2254            }
2255            return e;
2256        },
2257
2258        getCharCode : function(ev) {
2259            ev = ev.browserEvent || ev;
2260            return ev.charCode || ev.keyCode || 0;
2261        },
2262
2263        //clearCache: function() {},
2264
2265        _load : function(e) {
2266            loadComplete = true;
2267            var EU = Ext.lib.Event;   
2268            if (Ext.isIE && e !== true) {
2269        // IE8 complains that _load is null or not an object
2270        // so lets remove self via arguments.callee
2271                doRemove(win, "load", arguments.callee);
2272            }
2273        },           
2274       
2275        purgeElement : function(el, recurse, eventName) {
2276            var me = this;
2277            Ext.each( me.getListeners(el, eventName), function(v){
2278                if(v){
2279                    me.removeListener(el, v.type, v.fn);
2280                }
2281            });
2282
2283            if (recurse && el && el.childNodes) {
2284                Ext.each(el.childNodes, function(v){
2285                    me.purgeElement(v, recurse, eventName);
2286                });
2287            }
2288        },
2289
2290        getListeners : function(el, eventName) {
2291            var me = this,
2292                results = [], 
2293                searchLists;
2294
2295            if (eventName){ 
2296                searchLists = eventName == UNLOAD ? unloadListeners : listeners;
2297            }else{
2298                searchLists = listeners.concat(unloadListeners);
2299            }
2300
2301            Ext.each(searchLists, function(v, i){
2302                if (v && v[EL] == el && (!eventName || eventName == v[TYPE])) {
2303                    results.push({
2304                                type:   v[TYPE],
2305                                fn:     v[FN],
2306                                obj:    v[OBJ],
2307                                adjust: v[ADJ_SCOPE],
2308                                index:  i
2309                            });
2310                }   
2311            });               
2312
2313            return results.length ? results : null;
2314        },
2315
2316        _unload : function(e) {
2317             var EU = Ext.lib.Event, 
2318                i, 
2319                j, 
2320                l, 
2321                len, 
2322                index,
2323                scope;
2324               
2325
2326            Ext.each(unloadListeners, function(v) {
2327                if (v) {
2328                    try{
2329                        scope =  v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) :  win; 
2330                        v[FN].call(scope, EU.getEvent(e), v[OBJ]);
2331                    }catch(ex){}
2332                }   
2333            });     
2334
2335            unloadListeners = null;
2336
2337            if(listeners && (j = listeners.length)){                   
2338                while(j){                       
2339                    if((l = listeners[index = --j])){
2340                        EU.removeListener(l[EL], l[TYPE], l[FN], index);
2341                    }                       
2342                }
2343                //EU.clearCache();
2344            }
2345
2346            doRemove(win, UNLOAD, EU._unload);
2347        }           
2348    };       
2349   
2350    // Initialize stuff.
2351    pub.on = pub.addListener;
2352    pub.un = pub.removeListener;
2353    if (doc && doc.body) {
2354        pub._load(true);
2355    } else {
2356        doAdd(win, "load", pub._load);
2357    }
2358    doAdd(win, UNLOAD, pub._unload);   
2359    _tryPreloadAttach();
2360   
2361    return pub;
2362}();/*
2363 * Portions of this file are based on pieces of Yahoo User Interface Library
2364 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
2365 * YUI licensed under the BSD License:
2366 * http://developer.yahoo.net/yui/license.txt
2367 */
2368    Ext.lib.Ajax = function() {     
2369            var activeX = ['MSXML2.XMLHTTP.3.0',
2370                                   'MSXML2.XMLHTTP',
2371                                   'Microsoft.XMLHTTP'],
2372            CONTENTTYPE = 'Content-Type';
2373                                   
2374                // private
2375                function setHeader(o) {
2376                var conn = o.conn,
2377                        prop;
2378               
2379                function setTheHeaders(conn, headers){
2380                        for (prop in headers) {
2381                    if (headers.hasOwnProperty(prop)) {
2382                        conn.setRequestHeader(prop, headers[prop]);
2383                    }
2384                }   
2385                }               
2386               
2387            if (pub.defaultHeaders) {
2388                    setTheHeaders(conn, pub.defaultHeaders);
2389            }
2390
2391            if (pub.headers) {
2392                                setTheHeaders(conn, pub.headers);
2393                pub.headers = null;               
2394            }
2395        }   
2396       
2397        // private
2398        function createExceptionObject(tId, callbackArg, isAbort, isTimeout) {         
2399            return {
2400                    tId : tId,
2401                    status : isAbort ? -1 : 0,
2402                    statusText : isAbort ? 'transaction aborted' : 'communication failure',
2403                    isAbort: true,
2404                    isTimeout: true,
2405                    argument : callbackArg
2406            };
2407        } 
2408       
2409        // private
2410        function initHeader(label, value) {         
2411                        (pub.headers = pub.headers || {})[label] = value;                                   
2412        }
2413           
2414        // private
2415        function createResponseObject(o, callbackArg) {
2416            var headerObj = {},
2417                headerStr,             
2418                conn = o.conn,
2419                t,
2420                s;
2421
2422            try {
2423                headerStr = o.conn.getAllResponseHeaders();   
2424                Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){
2425                    t = v.indexOf(':');
2426                    if(t >= 0){
2427                        s = v.substr(0, t).toLowerCase();
2428                        if(v.charAt(t + 1) == ' '){
2429                            ++t;
2430                        }
2431                        headerObj[s] = v.substr(t + 1);
2432                    }
2433                });
2434            } catch(e) {}
2435                       
2436            return {
2437                tId : o.tId,
2438                status : conn.status,
2439                statusText : conn.statusText,
2440                getResponseHeader : function(header){return headerObj[header.toLowerCase()];},
2441                getAllResponseHeaders : function(){return headerStr},
2442                responseText : conn.responseText,
2443                responseXML : conn.responseXML,
2444                argument : callbackArg
2445            };
2446        }
2447       
2448        // private
2449        function releaseObject(o) {
2450            o.conn = null;
2451            o = null;
2452        }       
2453           
2454        // private
2455        function handleTransactionResponse(o, callback, isAbort, isTimeout) {
2456            if (!callback) {
2457                releaseObject(o);
2458                return;
2459            }
2460
2461            var httpStatus, responseObject;
2462
2463            try {
2464                if (o.conn.status !== undefined && o.conn.status != 0) {
2465                    httpStatus = o.conn.status;
2466                }
2467                else {
2468                    httpStatus = 13030;
2469                }
2470            }
2471            catch(e) {
2472                httpStatus = 13030;
2473            }
2474
2475            if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) {
2476                responseObject = createResponseObject(o, callback.argument);
2477                if (callback.success) {
2478                    if (!callback.scope) {
2479                        callback.success(responseObject);
2480                    }
2481                    else {
2482                        callback.success.apply(callback.scope, [responseObject]);
2483                    }
2484                }
2485            }
2486            else {
2487                switch (httpStatus) {
2488                    case 12002:
2489                    case 12029:
2490                    case 12030:
2491                    case 12031:
2492                    case 12152:
2493                    case 13030:
2494                        responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout);
2495                        if (callback.failure) {
2496                            if (!callback.scope) {
2497                                callback.failure(responseObject);
2498                            }
2499                            else {
2500                                callback.failure.apply(callback.scope, [responseObject]);
2501                            }
2502                        }
2503                        break;
2504                    default:
2505                        responseObject = createResponseObject(o, callback.argument);
2506                        if (callback.failure) {
2507                            if (!callback.scope) {
2508                                callback.failure(responseObject);
2509                            }
2510                            else {
2511                                callback.failure.apply(callback.scope, [responseObject]);
2512                            }
2513                        }
2514                }
2515            }
2516
2517            releaseObject(o);
2518            responseObject = null;
2519        } 
2520       
2521        // private
2522        function handleReadyState(o, callback){
2523            callback = callback || {};
2524            var conn = o.conn,
2525                tId = o.tId,
2526                poll = pub.poll,
2527                cbTimeout = callback.timeout || null;
2528
2529            if (cbTimeout) {
2530                pub.timeout[tId] = setTimeout(function() {
2531                    pub.abort(o, callback, true);
2532                }, cbTimeout);
2533            }
2534
2535            poll[tId] = setInterval(
2536                function() {
2537                    if (conn && conn.readyState == 4) {
2538                        clearInterval(poll[tId]);
2539                        poll[tId] = null;
2540
2541                        if (cbTimeout) {
2542                            clearTimeout(pub.timeout[tId]);
2543                            pub.timeout[tId] = null;
2544                        }
2545
2546                        handleTransactionResponse(o, callback);
2547                    }
2548                },
2549                pub.pollInterval);
2550        }
2551       
2552        // private
2553        function asyncRequest(method, uri, callback, postData) {
2554            var o = getConnectionObject() || null;
2555
2556            if (o) {
2557                o.conn.open(method, uri, true);
2558
2559                if (pub.useDefaultXhrHeader) {                   
2560                        initHeader('X-Requested-With', pub.defaultXhrHeader);
2561                }
2562
2563                if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){
2564                    initHeader(CONTENTTYPE, pub.defaultPostHeader);
2565                }
2566
2567                if (pub.defaultHeaders || pub.headers) {
2568                    setHeader(o);
2569                }
2570
2571                handleReadyState(o, callback);
2572                o.conn.send(postData || null);
2573            }
2574            return o;
2575        }
2576       
2577        // private
2578        function getConnectionObject() {
2579            var o;             
2580
2581            try {
2582                if (o = createXhrObject(pub.transactionId)) {
2583                    pub.transactionId++;
2584                }
2585            } catch(e) {
2586            } finally {
2587                return o;
2588            }
2589        }
2590               
2591        // private
2592        function createXhrObject(transactionId) {
2593            var http;
2594               
2595            try {
2596                http = new XMLHttpRequest();               
2597            } catch(e) {
2598                for (var i = 0; i < activeX.length; ++i) {                 
2599                    try {
2600                        http = new ActiveXObject(activeX[i]);                       
2601                        break;
2602                    } catch(e) {}
2603                }
2604            } finally {
2605                return {conn : http, tId : transactionId};
2606            }
2607        }
2608                 
2609            var pub = {
2610                request : function(method, uri, cb, data, options) {
2611                            if(options){
2612                                var me = this,                 
2613                                        xmlData = options.xmlData,
2614                                        jsonData = options.jsonData,
2615                        hs;
2616                                       
2617                                Ext.applyIf(me, options);               
2618                           
2619                            if(xmlData || jsonData){
2620                        hs = me.headers;
2621                        if(!hs || !hs[CONTENTTYPE]){
2622                                        initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json');
2623                        }
2624                                    data = xmlData || (Ext.isObject(jsonData) ? Ext.encode(jsonData) : jsonData);
2625                                }
2626                            }                               
2627                            return asyncRequest(method || options.method || "POST", uri, cb, data);
2628                },
2629       
2630                serializeForm : function(form) {
2631                        var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
2632                        hasSubmit = false,
2633                        encoder = encodeURIComponent,
2634                                element,
2635                        options, 
2636                        name, 
2637                        val,                   
2638                        data = '',
2639                        type;
2640                       
2641                        Ext.each(fElements, function(element) {                     
2642                        name = element.name;                 
2643                                        type = element.type;
2644                                       
2645                        if (!element.disabled && name){
2646                                if(/select-(one|multiple)/i.test(type)){                                       
2647                                            Ext.each(element.options, function(opt) {
2648                                                    if (opt.selected) {
2649                                                            data += String.format("{0}={1}&",                                                                                             
2650                                                                                                 encoder(name),                                                                                         
2651                                                                                                  (opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified) ? opt.value : opt.text);
2652                                }                                                               
2653                            });
2654                                } else if(!/file|undefined|reset|button/i.test(type)) {
2655                                        if(!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){
2656                                   
2657                                data += encoder(name) + '=' + encoder(element.value) + '&';                     
2658                                hasSubmit = /submit/i.test(type);   
2659                            }                           
2660                                } 
2661                        }
2662                    });           
2663                    return data.substr(0, data.length - 1);
2664                },
2665               
2666                useDefaultHeader : true,
2667                defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',
2668                useDefaultXhrHeader : true,
2669                defaultXhrHeader : 'XMLHttpRequest',       
2670                poll : {},
2671                timeout : {},
2672                pollInterval : 50,
2673                transactionId : 0,
2674               
2675//      This is never called - Is it worth exposing this?                       
2676//              setProgId : function(id) {
2677//                  activeX.unshift(id);
2678//              },
2679
2680//      This is never called - Is it worth exposing this?       
2681//              setDefaultPostHeader : function(b) {
2682//                  this.useDefaultHeader = b;
2683//              },
2684               
2685//      This is never called - Is it worth exposing this?       
2686//              setDefaultXhrHeader : function(b) {
2687//                  this.useDefaultXhrHeader = b;
2688//              },
2689
2690//      This is never called - Is it worth exposing this?               
2691//              setPollingInterval : function(i) {
2692//                  if (typeof i == 'number' && isFinite(i)) {
2693//                      this.pollInterval = i;
2694//                  }
2695//              },
2696               
2697//      This is never called - Is it worth exposing this?
2698//              resetDefaultHeaders : function() {
2699//                  this.defaultHeaders = null;
2700//              },
2701       
2702                abort : function(o, callback, isTimeout) {
2703                        var me = this,
2704                                tId = o.tId,
2705                                isAbort = false;
2706                       
2707                    if (me.isCallInProgress(o)) {
2708                        o.conn.abort();
2709                        clearInterval(me.poll[tId]);
2710                        me.poll[tId] = null;
2711                        if (isTimeout) {
2712                            me.timeout[tId] = null;
2713                        }
2714                                       
2715                        handleTransactionResponse(o, callback, (isAbort = true), isTimeout);               
2716                    }
2717                    return isAbort;
2718                },
2719       
2720                isCallInProgress : function(o) {
2721                    // if there is a connection and readyState is not 0 or 4
2722                    return o.conn && !{0:true,4:true}[o.conn.readyState];               
2723                }
2724            };
2725            return pub;
2726    }();        Ext.lib.Region = function(t, r, b, l) {
2727                var me = this;
2728        me.top = t;
2729        me[1] = t;
2730        me.right = r;
2731        me.bottom = b;
2732        me.left = l;
2733        me[0] = l;
2734    };
2735
2736    Ext.lib.Region.prototype = {
2737        contains : function(region) {
2738                var me = this;
2739            return ( region.left >= me.left &&
2740                     region.right <= me.right &&
2741                     region.top >= me.top &&
2742                     region.bottom <= me.bottom );
2743
2744        },
2745
2746        getArea : function() {
2747                var me = this;
2748            return ( (me.bottom - me.top) * (me.right - me.left) );
2749        },
2750
2751        intersect : function(region) {
2752            var me = this,
2753                t = Math.max(me.top, region.top),
2754                r = Math.min(me.right, region.right),
2755                b = Math.min(me.bottom, region.bottom),
2756                l = Math.max(me.left, region.left);
2757
2758            if (b >= t && r >= l) {
2759                return new Ext.lib.Region(t, r, b, l);
2760            }
2761        },
2762       
2763        union : function(region) {
2764                var me = this,
2765                t = Math.min(me.top, region.top),
2766                r = Math.max(me.right, region.right),
2767                b = Math.max(me.bottom, region.bottom),
2768                l = Math.min(me.left, region.left);
2769
2770            return new Ext.lib.Region(t, r, b, l);
2771        },
2772
2773        constrainTo : function(r) {
2774                var me = this;
2775            me.top = me.top.constrain(r.top, r.bottom);
2776            me.bottom = me.bottom.constrain(r.top, r.bottom);
2777            me.left = me.left.constrain(r.left, r.right);
2778            me.right = me.right.constrain(r.left, r.right);
2779            return me;
2780        },
2781
2782        adjust : function(t, l, b, r) {
2783                var me = this;
2784            me.top += t;
2785            me.left += l;
2786            me.right += r;
2787            me.bottom += b;
2788            return me;
2789        }
2790    };
2791
2792    Ext.lib.Region.getRegion = function(el) {
2793        var p = Ext.lib.Dom.getXY(el),
2794                t = p[1],
2795                r = p[0] + el.offsetWidth,
2796                b = p[1] + el.offsetHeight,
2797                l = p[0];
2798
2799        return new Ext.lib.Region(t, r, b, l);
2800    };  Ext.lib.Point = function(x, y) {
2801        if (Ext.isArray(x)) {
2802            y = x[1];
2803            x = x[0];
2804        }
2805        var me = this;
2806        me.x = me.right = me.left = me[0] = x;
2807        me.y = me.top = me.bottom = me[1] = y;
2808    };
2809
2810    Ext.lib.Point.prototype = new Ext.lib.Region();
2811(function(){   
2812    var EXTLIB = Ext.lib,
2813        noNegatives = /width|height|opacity|padding/i,
2814        offsetAttribute = /^((width|height)|(top|left))$/,
2815        defaultUnit = /width|height|top$|bottom$|left$|right$/i,
2816        offsetUnit =  /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i,
2817        isset = function(v){
2818            return typeof v !== 'undefined';
2819        },
2820        now = function(){
2821            return new Date();   
2822        };
2823       
2824    EXTLIB.Anim = {
2825        motion : function(el, args, duration, easing, cb, scope) {
2826            return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion);
2827        },
2828
2829        run : function(el, args, duration, easing, cb, scope, type) {
2830            type = type || Ext.lib.AnimBase;
2831            if (typeof easing == "string") {
2832                easing = Ext.lib.Easing[easing];
2833            }
2834            var anim = new type(el, args, duration, easing);
2835            anim.animateX(function() {
2836                if(Ext.isFunction(cb)){
2837                    cb.call(scope);
2838                }
2839            });
2840            return anim;
2841        }
2842    };
2843   
2844    EXTLIB.AnimBase = function(el, attributes, duration, method) {
2845        if (el) {
2846            this.init(el, attributes, duration, method);
2847        }
2848    };
2849
2850    EXTLIB.AnimBase.prototype = {
2851        doMethod: function(attr, start, end) {
2852            var me = this;
2853            return me.method(me.curFrame, start, end - start, me.totalFrames);
2854        },
2855
2856
2857        setAttr: function(attr, val, unit) {
2858            if (noNegatives.test(attr) && val < 0) {
2859                val = 0;
2860            }
2861            Ext.fly(this.el, '_anim').setStyle(attr, val + unit);
2862        },
2863
2864
2865        getAttr: function(attr) {
2866            var el = Ext.fly(this.el),
2867                val = el.getStyle(attr),
2868                a = offsetAttribute.exec(attr) || []
2869
2870            if (val !== 'auto' && !offsetUnit.test(val)) {
2871                return parseFloat(val);
2872            }
2873
2874            return (!!(a[2]) || (el.getStyle('position') == 'absolute' && !!(a[3]))) ? el.dom['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)] : 0;
2875        },
2876
2877
2878        getDefaultUnit: function(attr) {
2879            return defaultUnit.test(attr) ? 'px' : '';
2880        },
2881
2882        animateX : function(callback, scope) {
2883            var me = this,
2884                f = function() {
2885                me.onComplete.removeListener(f);
2886                if (Ext.isFunction(callback)) {
2887                    callback.call(scope || me, me);
2888                }
2889            };
2890            me.onComplete.addListener(f, me);
2891            me.animate();
2892        },
2893
2894
2895        setRunAttr: function(attr) {           
2896            var me = this,
2897                a = this.attributes[attr],
2898                to = a.to,
2899                by = a.by,
2900                from = a.from,
2901                unit = a.unit,
2902                ra = (this.runAttrs[attr] = {}),
2903                end;
2904
2905            if (!isset(to) && !isset(by)){
2906                return false;
2907            }
2908
2909            var start = isset(from) ? from : me.getAttr(attr);
2910            if (isset(to)) {
2911                end = to;
2912            }else if(isset(by)) {
2913                if (Ext.isArray(start)){
2914                    end = [];
2915                    Ext.each(start, function(v, i){
2916                        end[i] = v + by[i];
2917                    });
2918                }else{
2919                    end = start + by;
2920                }
2921            }
2922
2923            Ext.apply(ra, {
2924                start: start,
2925                end: end,
2926                unit: isset(unit) ? unit : me.getDefaultUnit(attr)
2927            });
2928        },
2929
2930
2931        init: function(el, attributes, duration, method) {
2932            var me = this,
2933                actualFrames = 0,
2934                mgr = EXTLIB.AnimMgr;
2935               
2936            Ext.apply(me, {
2937                isAnimated: false,
2938                startTime: null,
2939                el: Ext.getDom(el),
2940                attributes: attributes || {},
2941                duration: duration || 1,
2942                method: method || EXTLIB.Easing.easeNone,
2943                useSec: true,
2944                curFrame: 0,
2945                totalFrames: mgr.fps,
2946                runAttrs: {},
2947                animate: function(){
2948                    var me = this,
2949                        d = me.duration;
2950                   
2951                    if(me.isAnimated){
2952                        return false;
2953                    }
2954
2955                    me.curFrame = 0;
2956                    me.totalFrames = me.useSec ? Math.ceil(mgr.fps * d) : d;
2957                    mgr.registerElement(me); 
2958                },
2959               
2960                stop: function(finish){
2961                    var me = this;
2962               
2963                    if(finish){
2964                        me.curFrame = me.totalFrames;
2965                        me._onTween.fire();
2966                    }
2967                    mgr.stop(me);
2968                }
2969            });
2970
2971            var onStart = function(){
2972                var me = this,
2973                    attr;
2974               
2975                me.onStart.fire();
2976                me.runAttrs = {};
2977                for(attr in this.attributes){
2978                    this.setRunAttr(attr);
2979                }
2980
2981                me.isAnimated = true;
2982                me.startTime = now();
2983                actualFrames = 0;
2984            };
2985
2986
2987            var onTween = function(){
2988                var me = this;
2989
2990                me.onTween.fire({
2991                    duration: now() - me.startTime,
2992                    curFrame: me.curFrame
2993                });
2994
2995                var ra = me.runAttrs;
2996                for (var attr in ra) {
2997                    this.setAttr(attr, me.doMethod(attr, ra[attr].start, ra[attr].end), ra[attr].unit);
2998                }
2999
3000                ++actualFrames;
3001            };
3002
3003            var onComplete = function() {
3004                var me = this,
3005                    actual = (now() - me.startTime) / 1000,
3006                    data = {
3007                        duration: actual,
3008                        frames: actualFrames,
3009                        fps: actualFrames / actual
3010                    };
3011
3012                me.isAnimated = false;
3013                actualFrames = 0;
3014                me.onComplete.fire(data);
3015            };
3016
3017            me.onStart = new Ext.util.Event(me);
3018            me.onTween = new Ext.util.Event(me);           
3019            me.onComplete = new Ext.util.Event(me);
3020            (me._onStart = new Ext.util.Event(me)).addListener(onStart);
3021            (me._onTween = new Ext.util.Event(me)).addListener(onTween);
3022            (me._onComplete = new Ext.util.Event(me)).addListener(onComplete); 
3023        }
3024    };
3025
3026
3027    Ext.lib.AnimMgr = new function() {
3028        var me = this,
3029            thread = null,
3030            queue = [],
3031            tweenCount = 0;
3032
3033
3034        Ext.apply(me, {
3035            fps: 1000,
3036            delay: 1,
3037            registerElement: function(tween){
3038                queue.push(tween);
3039                ++tweenCount;
3040                tween._onStart.fire();
3041                me.start();
3042            },
3043           
3044            unRegister: function(tween, index){
3045                tween._onComplete.fire();
3046                index = index || getIndex(tween);
3047                if (index != -1) {
3048                    queue.splice(index, 1);
3049                }
3050
3051                if (--tweenCount <= 0) {
3052                    me.stop();
3053                }
3054            },
3055           
3056            start: function(){
3057                if(thread === null){
3058                    thread = setInterval(me.run, me.delay);
3059                }
3060            },
3061           
3062            stop: function(tween){
3063                if(!tween){
3064                    clearInterval(thread);
3065                    for(var i = 0, len = queue.length; i < len; ++i){
3066                        if(queue[0].isAnimated){
3067                            me.unRegister(queue[0], 0);
3068                        }
3069                    }
3070
3071                    queue = [];
3072                    thread = null;
3073                    tweenCount = 0;
3074                }else{
3075                    me.unRegister(tween);
3076                }
3077            },
3078           
3079            run: function(){
3080                var tf;
3081                Ext.each(queue, function(tween){
3082                    if(tween && tween.isAnimated){
3083                        tf = tween.totalFrames;
3084                        if(tween.curFrame < tf || tf === null){
3085                            ++tween.curFrame;
3086                            if(tween.useSec){
3087                                correctFrame(tween);
3088                            }
3089                            tween._onTween.fire();
3090                        }else{
3091                            me.stop(tween);
3092                        }
3093                    }
3094                }, me);
3095            }
3096        });
3097
3098        var getIndex = function(anim) {
3099            var out = -1;
3100            Ext.each(queue, function(item, idx){
3101                if(item == anim){
3102                    out = idx;
3103                    return false;
3104                }
3105            });
3106            return out;
3107        };
3108
3109
3110        var correctFrame = function(tween) {
3111            var frames = tween.totalFrames,
3112                frame = tween.curFrame,
3113                duration = tween.duration,
3114                expected = (frame * duration * 1000 / frames),
3115                elapsed = (now() - tween.startTime),
3116                tweak = 0;
3117
3118            if(elapsed < duration * 1000){
3119                tweak = Math.round((elapsed / expected - 1) * frame);
3120            }else{
3121                tweak = frames - (frame + 1);
3122            }
3123            if(tweak > 0 && isFinite(tweak)){
3124                if(tween.curFrame + tweak >= frames){
3125                    tweak = frames - (frame + 1);
3126                }
3127                tween.curFrame += tweak;
3128            }
3129        };
3130    };
3131
3132    EXTLIB.Bezier = new function() {
3133
3134        this.getPosition = function(points, t) {
3135            var n = points.length,
3136                tmp = [],
3137                c = 1 - t, 
3138                i,
3139                j;
3140
3141            for (i = 0; i < n; ++i) {
3142                tmp[i] = [points[i][0], points[i][1]];
3143            }
3144
3145            for (j = 1; j < n; ++j) {
3146                for (i = 0; i < n - j; ++i) {
3147                    tmp[i][0] = c * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
3148                    tmp[i][1] = c * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
3149                }
3150            }
3151
3152            return [ tmp[0][0], tmp[0][1] ];
3153
3154        };
3155    };
3156
3157
3158    EXTLIB.Easing = {
3159        easeNone: function (t, b, c, d) {
3160            return c * t / d + b;
3161        },
3162
3163
3164        easeIn: function (t, b, c, d) {
3165            return c * (t /= d) * t + b;
3166        },
3167
3168
3169        easeOut: function (t, b, c, d) {
3170            return -c * (t /= d) * (t - 2) + b;
3171        }
3172    };
3173
3174    (function() {
3175        EXTLIB.Motion = function(el, attributes, duration, method) {
3176            if (el) {
3177                EXTLIB.Motion.superclass.constructor.call(this, el, attributes, duration, method);
3178            }
3179        };
3180
3181        Ext.extend(EXTLIB.Motion, Ext.lib.AnimBase);
3182
3183        var superclass = EXTLIB.Motion.superclass,
3184            proto = EXTLIB.Motion.prototype,
3185            pointsRe = /^points$/i;
3186
3187        Ext.apply(EXTLIB.Motion.prototype, {
3188            setAttr: function(attr, val, unit){
3189                var me = this,
3190                    setAttr = superclass.setAttr;
3191                   
3192                if (pointsRe.test(attr)) {
3193                    unit = unit || 'px';
3194                    setAttr.call(me, 'left', val[0], unit);
3195                    setAttr.call(me, 'top', val[1], unit);
3196                } else {
3197                    setAttr.call(me, attr, val, unit);
3198                }
3199            },
3200           
3201            getAttr: function(attr){
3202                var me = this,
3203                    getAttr = superclass.getAttr;
3204                   
3205                return pointsRe.test(attr) ? [getAttr.call(me, 'left'), getAttr.call(me, 'top')] : getAttr.call(me, attr);
3206            },
3207           
3208            doMethod: function(attr, start, end){
3209                var me = this;
3210               
3211                return pointsRe.test(attr)
3212                        ? EXTLIB.Bezier.getPosition(me.runAttrs[attr], me.method(me.curFrame, 0, 100, me.totalFrames) / 100)
3213                        : superclass.doMethod.call(me, attr, start, end);
3214            },
3215           
3216            setRunAttr: function(attr){
3217                if(pointsRe.test(attr)){
3218                   
3219                    var me = this,
3220                        el = this.el,
3221                        points = this.attributes.points,
3222                        control = points.control || [],
3223                        from = points.from,
3224                        to = points.to,
3225                        by = points.by,
3226                        DOM = EXTLIB.Dom,
3227                        start,
3228                        i,
3229                        end,
3230                        len,
3231                        ra;
3232                 
3233
3234                    if(control.length > 0 && !Ext.isArray(control[0])){
3235                        control = [control];
3236                    }else{
3237                        /*
3238                        var tmp = [];
3239                        for (i = 0,len = control.length; i < len; ++i) {
3240                            tmp[i] = control[i];
3241                        }
3242                        control = tmp;
3243                        */
3244                    }
3245
3246                    Ext.fly(el, '_anim').position();
3247                    DOM.setXY(el, isset(from) ? from : DOM.getXY(el));
3248                    start = me.getAttr('points');
3249
3250
3251                    if(isset(to)){
3252                        end = translateValues.call(me, to, start);
3253                        for (i = 0,len = control.length; i < len; ++i) {
3254                            control[i] = translateValues.call(me, control[i], start);
3255                        }
3256                    } else if (isset(by)) {
3257                        end = [start[0] + by[0], start[1] + by[1]];
3258
3259                        for (i = 0,len = control.length; i < len; ++i) {
3260                            control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
3261                        }
3262                    }
3263
3264                    ra = this.runAttrs[attr] = [start];
3265                    if (control.length > 0) {
3266                        ra = ra.concat(control);
3267                    }
3268
3269                    ra[ra.length] = end;
3270                }else{
3271                    superclass.setRunAttr.call(this, attr);
3272                }
3273            }
3274        });
3275
3276        var translateValues = function(val, start) {
3277            var pageXY = EXTLIB.Dom.getXY(this.el);
3278            return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]];
3279        };
3280    })();
3281})();// Easing functions
3282(function(){
3283        // shortcuts to aid compression
3284        var abs = Math.abs,
3285                pi = Math.PI,
3286                asin = Math.asin,
3287                pow = Math.pow,
3288                sin = Math.sin,
3289                EXTLIB = Ext.lib;
3290               
3291    Ext.apply(EXTLIB.Easing, {
3292       
3293        easeBoth: function (t, b, c, d) {
3294                return ((t /= d / 2) < 1)  ?  c / 2 * t * t + b  :  -c / 2 * ((--t) * (t - 2) - 1) + b;               
3295        },
3296       
3297        easeInStrong: function (t, b, c, d) {
3298            return c * (t /= d) * t * t * t + b;
3299        },
3300
3301        easeOutStrong: function (t, b, c, d) {
3302            return -c * ((t = t / d - 1) * t * t * t - 1) + b;
3303        },
3304
3305        easeBothStrong: function (t, b, c, d) {
3306            return ((t /= d / 2) < 1)  ?  c / 2 * t * t * t * t + b  :  -c / 2 * ((t -= 2) * t * t * t - 2) + b;
3307        },
3308
3309        elasticIn: function (t, b, c, d, a, p) {
3310                if (t == 0 || (t /= d) == 1) {
3311                return t == 0 ? b : b + c;
3312            }               
3313            p = p || (d * .3);             
3314
3315                        var s;
3316                        if (a >= abs(c)) {
3317                                s = p / (2 * pi) * asin(c / a);
3318                        } else {
3319                                a = c;
3320                                s = p / 4;
3321                        }
3322       
3323            return -(a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b;
3324                     
3325        },     
3326       
3327                elasticOut: function (t, b, c, d, a, p) {
3328                if (t == 0 || (t /= d) == 1) {
3329                return t == 0 ? b : b + c;
3330            }               
3331            p = p || (d * .3);             
3332
3333                        var s;
3334                        if (a >= abs(c)) {
3335                                s = p / (2 * pi) * asin(c / a);
3336                        } else {
3337                                a = c;
3338                                s = p / 4;
3339                        }
3340       
3341            return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b;       
3342        },     
3343       
3344        elasticBoth: function (t, b, c, d, a, p) {
3345            if (t == 0 || (t /= d / 2) == 2) {
3346                return t == 0 ? b : b + c;
3347            }                           
3348                   
3349            p = p || (d * (.3 * 1.5));             
3350
3351            var s;
3352            if (a >= abs(c)) {
3353                    s = p / (2 * pi) * asin(c / a);
3354            } else {
3355                    a = c;
3356                s = p / 4;
3357            }
3358
3359            return t < 1 ?
3360                        -.5 * (a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b :
3361                    a * pow(2, -10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p) * .5 + c + b;
3362        },
3363
3364        backIn: function (t, b, c, d, s) {
3365            s = s ||  1.70158;             
3366            return c * (t /= d) * t * ((s + 1) * t - s) + b;
3367        },
3368
3369
3370        backOut: function (t, b, c, d, s) {
3371            if (!s) {
3372                s = 1.70158;
3373            }
3374            return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
3375        },
3376
3377
3378        backBoth: function (t, b, c, d, s) {
3379            s = s || 1.70158;               
3380
3381            return ((t /= d / 2 ) < 1) ?
3382                    c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b :                 
3383                        c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
3384        },
3385
3386
3387        bounceIn: function (t, b, c, d) {
3388            return c - EXTLIB.Easing.bounceOut(d - t, 0, c, d) + b;
3389        },
3390
3391
3392        bounceOut: function (t, b, c, d) {
3393        if ((t /= d) < (1 / 2.75)) {
3394                return c * (7.5625 * t * t) + b;
3395            } else if (t < (2 / 2.75)) {
3396                return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
3397            } else if (t < (2.5 / 2.75)) {
3398                return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
3399            }
3400            return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
3401        },
3402
3403
3404        bounceBoth: function (t, b, c, d) {
3405            return (t < d / 2) ?
3406                   EXTLIB.Easing.bounceIn(t * 2, 0, c, d) * .5 + b : 
3407                   EXTLIB.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
3408        }
3409    });
3410})();
3411
3412(function() {
3413    var EXTLIB = Ext.lib;
3414        // Color Animation
3415        EXTLIB.Anim.color = function(el, args, duration, easing, cb, scope) {
3416            return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.ColorAnim);
3417        }
3418       
3419    EXTLIB.ColorAnim = function(el, attributes, duration, method) {
3420        EXTLIB.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
3421    };
3422
3423    Ext.extend(EXTLIB.ColorAnim, EXTLIB.AnimBase);
3424
3425    var superclass = EXTLIB.ColorAnim.superclass,
3426        colorRE = /color$/i,
3427        transparentRE = /^transparent|rgba\(0, 0, 0, 0\)$/,
3428        rgbRE = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
3429        hexRE= /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
3430        hex3RE = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,
3431        isset = function(v){
3432            return typeof v !== 'undefined';
3433        }
3434               
3435        // private     
3436    function parseColor(s) {   
3437        var pi = parseInt,
3438            base,
3439            out = null,
3440            c;
3441       
3442            if (s.length == 3) {
3443            return s;
3444        }
3445       
3446        Ext.each([hexRE, rgbRE, hex3RE], function(re, idx){
3447            base = (idx % 2 == 0) ? 16 : 10;
3448            c = re.exec(s);
3449            if(c && c.length == 4){
3450                out = [pi(c[1], base), pi(c[2], base), pi(c[3], base)];
3451                return false;
3452            }
3453        });
3454        return out;
3455    }   
3456
3457    Ext.apply(EXTLIB.ColorAnim.prototype, {
3458        getAttr : function(attr) {
3459            var me = this,
3460                el = me.el,
3461                val;               
3462            if(colorRE.test(attr)){
3463                while(el && transparentRE.test(val = Ext.fly(el).getStyle(attr))){
3464                    el = el.parentNode;
3465                    val = "fff";
3466                }
3467            }else{
3468                val = superclass.getAttr.call(me, attr);
3469            }
3470            return val;
3471        },
3472
3473        doMethod : function(attr, start, end) {
3474            var me = this,
3475                val,
3476                floor = Math.floor;           
3477
3478            if(colorRE.test(attr)){
3479                val = [];
3480             
3481                    Ext.each(start, function(v, i) {
3482                    val[i] = superclass.doMethod.call(me, attr, v, end[i]);
3483                });
3484
3485                val = 'rgb(' + floor(val[0]) + ',' + floor(val[1]) + ',' + floor(val[2]) + ')';
3486            }else{
3487                val = superclass.doMethod.call(me, attr, start, end);
3488            }
3489            return val;
3490        },
3491
3492        setRunAttr : function(attr) {
3493            var me = this,
3494                a = me.attributes[attr],
3495                to = a.to,
3496                by = a.by,
3497                ra;
3498               
3499            superclass.setRunAttr.call(me, attr);
3500            ra = me.runAttrs[attr];
3501            if(colorRE.test(attr)){
3502                var start = parseColor(ra.start),
3503                    end = parseColor(ra.end);
3504
3505                if(!isset(to) && isset(by)){
3506                    end = parseColor(by);
3507                    Ext.each(start, function(item, i){
3508                        end[i] = item + end[i];
3509                    });
3510                }
3511                ra.start = start;
3512                ra.end = end;
3513            }
3514        }
3515        });
3516})();   
3517
3518       
3519(function() {
3520            // Scroll Animation
3521    var EXTLIB = Ext.lib;
3522        EXTLIB.Anim.scroll = function(el, args, duration, easing, cb, scope) {         
3523            return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.Scroll);
3524        }
3525       
3526    EXTLIB.Scroll = function(el, attributes, duration, method) {
3527        if(el){
3528            EXTLIB.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
3529        }
3530    };
3531
3532    Ext.extend(EXTLIB.Scroll, EXTLIB.ColorAnim);
3533
3534    var superclass = EXTLIB.Scroll.superclass,
3535        SCROLL = 'scroll';
3536
3537    Ext.apply(EXTLIB.Scroll.prototype, {
3538
3539        doMethod : function(attr, start, end) {
3540            var val,
3541                me = this,
3542                curFrame = me.curFrame,
3543                totalFrames = me.totalFrames;
3544
3545            if(attr == SCROLL){
3546                val = [me.method(curFrame, start[0], end[0] - start[0], totalFrames),
3547                       me.method(curFrame, start[1], end[1] - start[1], totalFrames)];
3548            }else{
3549                val = superclass.doMethod.call(me, attr, start, end);
3550            }
3551            return val;
3552        },
3553
3554        getAttr : function(attr) {
3555            var me = this;
3556
3557            if (attr == SCROLL) {
3558                return [me.el.scrollLeft, me.el.scrollTop];
3559            }else{
3560                return superclass.getAttr.call(me, attr);
3561            }
3562        },
3563
3564        setAttr : function(attr, val, unit) {
3565            var me = this;
3566
3567            if(attr == SCROLL){
3568                me.el.scrollLeft = val[0];
3569                me.el.scrollTop = val[1];
3570            }else{
3571                superclass.setAttr.call(me, attr, val, unit);
3572            }
3573        }
3574    });
3575})();   
3576        if(Ext.isIE) {
3577        function fnCleanUp() {
3578            var p = Function.prototype;
3579            delete p.createSequence;
3580            delete p.defer;
3581            delete p.createDelegate;
3582            delete p.createCallback;
3583            delete p.createInterceptor;
3584
3585            window.detachEvent("onunload", fnCleanUp);
3586        }
3587        window.attachEvent("onunload", fnCleanUp);
3588    }
3589})();
Note: See TracBrowser for help on using the repository browser.