ext-all-debug.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:2341k
源码类别:

中间件编程

开发平台:

JavaScript

  1.  * @method select
  2.  */
  3. Ext.Element.select = function(selector, unique, root){
  4.     var els;
  5.     if(typeof selector == "string"){
  6.         els = Ext.Element.selectorFunction(selector, root);
  7.     }else if(selector.length !== undefined){
  8.         els = selector;
  9.     }else{
  10.         throw "Invalid selector";
  11.     }
  12.     return new Ext.CompositeElementLite(els);
  13. };
  14. /**
  15.  * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods
  16.  * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or
  17.  * {@link Ext.CompositeElementLite CompositeElementLite} object.
  18.  * @param {String/Array} selector The CSS selector or an array of elements
  19.  * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object)
  20.  * @param {HTMLElement/String} root (optional) The root element of the query or id of the root
  21.  * @return {CompositeElementLite/CompositeElement}
  22.  * @member Ext
  23.  * @method select
  24.  */
  25. Ext.select = Ext.Element.select;/**
  26.  * @class Ext.CompositeElementLite
  27.  */
  28. Ext.apply(Ext.CompositeElementLite.prototype, {
  29. addElements : function(els, root){
  30.         if(!els){
  31.             return this;
  32.         }
  33.         if(typeof els == "string"){
  34.             els = Ext.Element.selectorFunction(els, root);
  35.         }
  36.         var yels = this.elements;        
  37.     Ext.each(els, function(e) {
  38.          yels.push(Ext.get(e));
  39.         });
  40.         return this;
  41.     },
  42.     
  43.     /**
  44.     * Clears this composite and adds the elements returned by the passed selector.
  45.     * @param {String/Array} els A string CSS selector, an array of elements or an element
  46.     * @return {CompositeElement} this
  47.     */
  48.     fill : function(els){
  49.         this.elements = [];
  50.         this.add(els);
  51.         return this;
  52.     },
  53.     
  54.     /**
  55.      * Returns the first Element
  56.      * @return {Ext.Element}
  57.      */
  58.     first : function(){
  59.         return this.item(0);
  60.     },   
  61.     
  62.     /**
  63.      * Returns the last Element
  64.      * @return {Ext.Element}
  65.      */
  66.     last : function(){
  67.         return this.item(this.getCount()-1);
  68.     },
  69.     
  70.     /**
  71.      * Returns true if this composite contains the passed element
  72.      * @param el {Mixed} The id of an element, or an Ext.Element, or an HtmlElement to find within the composite collection.
  73.      * @return Boolean
  74.      */
  75.     contains : function(el){
  76.         return this.indexOf(el) != -1;
  77.     },
  78.     /**
  79.     * Filters this composite to only elements that match the passed selector.
  80.     * @param {String} selector A string CSS selector
  81.     * @return {CompositeElement} this
  82.     */
  83.     filter : function(selector){
  84.         var els = [];
  85.         this.each(function(el){
  86.             if(el.is(selector)){
  87.                 els[els.length] = el.dom;
  88.             }
  89.         });
  90.         this.fill(els);
  91.         return this;
  92.     },          /**
  93.     * Removes the specified element(s).
  94.     * @param {Mixed} el The id of an element, the Element itself, the index of the element in this composite
  95.     * or an array of any of those.
  96.     * @param {Boolean} removeDom (optional) True to also remove the element from the document
  97.     * @return {CompositeElement} this
  98.     */
  99.     removeElement : function(keys, removeDom){
  100.         var me = this,
  101.         els = this.elements,     
  102.      el;     
  103.     Ext.each(keys, function(val){
  104.     if ((el = (els[val] || els[val = me.indexOf(val)]))) {
  105.      if(removeDom){
  106.                     if(el.dom){
  107.                         el.remove();
  108.                     }else{
  109.                         Ext.removeNode(el);
  110.                     }
  111.                 }
  112.      els.splice(val, 1);     
  113. }
  114.     });
  115.         return this;
  116.     }    
  117. }); /**
  118.  * @class Ext.CompositeElement
  119.  * @extends Ext.CompositeElementLite
  120.  * Standard composite class. Creates a Ext.Element for every element in the collection.
  121.  * <br><br>
  122.  * <b>NOTE: Although they are not listed, this class supports all of the set/update methods of Ext.Element. All Ext.Element
  123.  * actions will be performed on all the elements in this collection.</b>
  124.  * <br><br>
  125.  * All methods return <i>this</i> and can be chained.
  126.  <pre><code>
  127.  var els = Ext.select("#some-el div.some-class", true);
  128.  // or select directly from an existing element
  129.  var el = Ext.get('some-el');
  130.  el.select('div.some-class', true);
  131.  els.setWidth(100); // all elements become 100 width
  132.  els.hide(true); // all elements fade out and hide
  133.  // or
  134.  els.setWidth(100).hide(true);
  135.  </code></pre>
  136.  */
  137. Ext.CompositeElement = function(els, root){
  138.     this.elements = [];
  139.     this.add(els, root);
  140. };
  141. Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
  142.     invoke : function(fn, args){
  143.     Ext.each(this.elements, function(e) {
  144.          Ext.Element.prototype[fn].apply(e, args);
  145.         });
  146.         return this;
  147.     },
  148.     
  149.     /**
  150.     * Adds elements to this composite.
  151.     * @param {String/Array} els A string CSS selector, an array of elements or an element
  152.     * @return {CompositeElement} this
  153.     */
  154.     add : function(els, root){
  155.     if(!els){
  156.             return this;
  157.         }
  158.         if(typeof els == "string"){
  159.             els = Ext.Element.selectorFunction(els, root);
  160.         }
  161.         var yels = this.elements;        
  162.     Ext.each(els, function(e) {
  163.          yels.push(Ext.get(e));
  164.         });
  165.         return this;
  166.     },    
  167.     
  168.     /**
  169.      * Returns the Element object at the specified index
  170.      * @param {Number} index
  171.      * @return {Ext.Element}
  172.      */
  173.     item : function(index){
  174.         return this.elements[index] || null;
  175.     },
  176.     indexOf : function(el){
  177.         return this.elements.indexOf(Ext.get(el));
  178.     },
  179.         
  180.     filter : function(selector){
  181. var me = this,
  182. out = [];
  183. Ext.each(me.elements, function(el) {
  184. if(el.is(selector)){
  185. out.push(Ext.get(el));
  186. }
  187. });
  188. me.elements = out;
  189. return me;
  190. },
  191. /**
  192.     * Calls the passed function passing (el, this, index) for each element in this composite.
  193.     * @param {Function} fn The function to call
  194.     * @param {Object} scope (optional) The <i>this</i> object (defaults to the element)
  195.     * @return {CompositeElement} this
  196.     */
  197.     each : function(fn, scope){        
  198.         Ext.each(this.elements, function(e,i) {
  199.         return fn.call(scope || e, e, this, i);
  200.         }, this);
  201.         return this;
  202.     }
  203. });
  204. /**
  205.  * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods
  206.  * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or
  207.  * {@link Ext.CompositeElementLite CompositeElementLite} object.
  208.  * @param {String/Array} selector The CSS selector or an array of elements
  209.  * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object)
  210.  * @param {HTMLElement/String} root (optional) The root element of the query or id of the root
  211.  * @return {CompositeElementLite/CompositeElement}
  212.  * @member Ext.Element
  213.  * @method select
  214.  */
  215. Ext.Element.select = function(selector, unique, root){
  216.     var els;
  217.     if(typeof selector == "string"){
  218.         els = Ext.Element.selectorFunction(selector, root);
  219.     }else if(selector.length !== undefined){
  220.         els = selector;
  221.     }else{
  222.         throw "Invalid selector";
  223.     }
  224.     return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
  225. };
  226. /**
  227.  * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods
  228.  * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or
  229.  * {@link Ext.CompositeElementLite CompositeElementLite} object.
  230.  * @param {String/Array} selector The CSS selector or an array of elements
  231.  * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object)
  232.  * @param {HTMLElement/String} root (optional) The root element of the query or id of the root
  233.  * @return {CompositeElementLite/CompositeElement}
  234.  * @member Ext.Element
  235.  * @method select
  236.  */
  237. Ext.select = Ext.Element.select;(function(){
  238.     var BEFOREREQUEST = "beforerequest",
  239.         REQUESTCOMPLETE = "requestcomplete",
  240.         REQUESTEXCEPTION = "requestexception",
  241.         UNDEFINED = undefined,
  242.         LOAD = 'load',
  243.         POST = 'POST',
  244.         GET = 'GET',
  245.         WINDOW = window;
  246.     
  247.     /**
  248.      * @class Ext.data.Connection
  249.      * @extends Ext.util.Observable
  250.      * <p>The class encapsulates a connection to the page's originating domain, allowing requests to be made
  251.      * either to a configured URL, or to a URL specified at request time.</p>
  252.      * <p>Requests made by this class are asynchronous, and will return immediately. No data from
  253.      * the server will be available to the statement immediately following the {@link #request} call.
  254.      * To process returned data, use a
  255.      * <a href="#request-option-success" ext:member="request-option-success" ext:cls="Ext.data.Connection">success callback</a>
  256.      * in the request options object,
  257.      * or an {@link #requestcomplete event listener}.</p>
  258.      * <p><h3>File Uploads</h3><a href="#request-option-isUpload" ext:member="request-option-isUpload" ext:cls="Ext.data.Connection">File uploads</a> are not performed using normal "Ajax" techniques, that
  259.      * is they are <b>not</b> performed using XMLHttpRequests. Instead the form is submitted in the standard
  260.      * manner with the DOM <tt>&lt;form></tt> element temporarily modified to have its
  261.      * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer
  262.      * to a dynamically generated, hidden <tt>&lt;iframe></tt> which is inserted into the document
  263.      * but removed after the return data has been gathered.</p>
  264.      * <p>The server response is parsed by the browser to create the document for the IFRAME. If the
  265.      * server is using JSON to send the return object, then the
  266.      * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17">Content-Type</a> header
  267.      * must be set to "text/html" in order to tell the browser to insert the text unchanged into the document body.</p>
  268.      * <p>Characters which are significant to an HTML parser must be sent as HTML entities, so encode
  269.      * "&lt;" as "&amp;lt;", "&amp;" as "&amp;amp;" etc.</p>
  270.      * <p>The response text is retrieved from the document, and a fake XMLHttpRequest object
  271.      * is created containing a <tt>responseText</tt> property in order to conform to the
  272.      * requirements of event handlers and callbacks.</p>
  273.      * <p>Be aware that file upload packets are sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form</a>
  274.      * and some server technologies (notably JEE) may require some custom processing in order to
  275.      * retrieve parameter names and parameter values from the packet content.</p>
  276.      * @constructor
  277.      * @param {Object} config a configuration object.
  278.      */
  279.     Ext.data.Connection = function(config){    
  280.         Ext.apply(this, config);
  281.         this.addEvents(
  282.             /**
  283.              * @event beforerequest
  284.              * Fires before a network request is made to retrieve a data object.
  285.              * @param {Connection} conn This Connection object.
  286.              * @param {Object} options The options config object passed to the {@link #request} method.
  287.              */
  288.             BEFOREREQUEST,
  289.             /**
  290.              * @event requestcomplete
  291.              * Fires if the request was successfully completed.
  292.              * @param {Connection} conn This Connection object.
  293.              * @param {Object} response The XHR object containing the response data.
  294.              * See <a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object</a>
  295.              * for details.
  296.              * @param {Object} options The options config object passed to the {@link #request} method.
  297.              */
  298.             REQUESTCOMPLETE,
  299.             /**
  300.              * @event requestexception
  301.              * Fires if an error HTTP status was returned from the server.
  302.              * See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP Status Code Definitions</a>
  303.              * for details of HTTP status codes.
  304.              * @param {Connection} conn This Connection object.
  305.              * @param {Object} response The XHR object containing the response data.
  306.              * See <a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object</a>
  307.              * for details.
  308.              * @param {Object} options The options config object passed to the {@link #request} method.
  309.              */
  310.             REQUESTEXCEPTION
  311.         );
  312.         Ext.data.Connection.superclass.constructor.call(this);
  313.     };
  314.     // private
  315.     function handleResponse(response){
  316.         this.transId = false;
  317.         var options = response.argument.options;
  318.         response.argument = options ? options.argument : null;
  319.         this.fireEvent(REQUESTCOMPLETE, this, response, options);
  320.         if(options.success){
  321.             options.success.call(options.scope, response, options);
  322.         }
  323.         if(options.callback){
  324.             options.callback.call(options.scope, options, true, response);
  325.         }
  326.     }
  327.     // private
  328.     function handleFailure(response, e){
  329.         this.transId = false;
  330.         var options = response.argument.options;
  331.         response.argument = options ? options.argument : null;
  332.         this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
  333.         if(options.failure){
  334.             options.failure.call(options.scope, response, options);
  335.         }
  336.         if(options.callback){
  337.             options.callback.call(options.scope, options, false, response);
  338.         }
  339.     }
  340.     // private
  341.     function doFormUpload(o, ps, url){
  342.         var id = Ext.id(),
  343.             doc = document,
  344.             frame = doc.createElement('iframe'),
  345.             form = Ext.getDom(o.form),
  346.             hiddens = [],
  347.             hd,
  348.             encoding = 'multipart/form-data',
  349.             buf = {
  350.                 target: form.target,
  351.                 method: form.method,
  352.                 encoding: form.encoding,
  353.                 enctype: form.enctype,
  354.                 action: form.action
  355.             };
  356.             
  357.         Ext.apply(frame, {
  358.             id: id,
  359.             name: id,
  360.             className: 'x-hidden',
  361.             src: Ext.SSL_SECURE_URL // for IE
  362.         });     
  363.         doc.body.appendChild(frame);
  364.         
  365.         // This is required so that IE doesn't pop the response up in a new window.
  366.         if(Ext.isIE){
  367.            document.frames[id].name = id;
  368.         }
  369.         
  370.         Ext.apply(form, {
  371.             target: id,
  372.             method: POST,
  373.             enctype: encoding,
  374.             encoding: encoding,
  375.             action: url || buf.action
  376.         });
  377.         
  378.         // add dynamic params            
  379.         ps = Ext.urlDecode(ps, false);
  380.         for(var k in ps){
  381.             if(ps.hasOwnProperty(k)){
  382.                 hd = doc.createElement('input');
  383.                 hd.type = 'hidden';                    
  384.                 hd.value = ps[hd.name = k];
  385.                 form.appendChild(hd);
  386.                 hiddens.push(hd);
  387.             }
  388.         }        
  389.         function cb(){
  390.             var me = this,
  391.                 // bogus response object
  392.                 r = {responseText : '',
  393.                      responseXML : null,
  394.                      argument : o.argument},
  395.                 doc,
  396.                 firstChild;
  397.             try{ 
  398.                 doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
  399.                 if(doc){
  400.                     if(doc.body){
  401.                         if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ // json response wrapped in textarea                        
  402.                             r.responseText = firstChild.value;
  403.                         }else{
  404.                             r.responseText = doc.body.innerHTML;
  405.                         }
  406.                     }
  407.                     //in IE the document may still have a body even if returns XML.
  408.                     r.responseXML = doc.XMLDocument || doc;
  409.                 }
  410.             }
  411.             catch(e) {}
  412.             Ext.EventManager.removeListener(frame, LOAD, cb, me);
  413.             me.fireEvent(REQUESTCOMPLETE, me, r, o);
  414.             
  415.             function runCallback(fn, scope, args){
  416.                 if(Ext.isFunction(fn)){
  417.                     fn.apply(scope, args);
  418.                 }
  419.             }
  420.             runCallback(o.success, o.scope, [r, o]);
  421.             runCallback(o.callback, o.scope, [o, true, r]);
  422.             if(!me.debugUploads){
  423.                 setTimeout(function(){Ext.removeNode(frame);}, 100);
  424.             }
  425.         }
  426.         Ext.EventManager.on(frame, LOAD, cb, this);
  427.         form.submit();
  428.         
  429.         Ext.apply(form, buf);
  430.         Ext.each(hiddens, function(h) {
  431.             Ext.removeNode(h);
  432.         });
  433.     }
  434.     Ext.extend(Ext.data.Connection, Ext.util.Observable, {
  435.         /**
  436.          * @cfg {String} url (Optional) <p>The default URL to be used for requests to the server. Defaults to undefined.</p>
  437.          * <p>The <code>url</code> config may be a function which <i>returns</i> the URL to use for the Ajax request. The scope
  438.          * (<code><b>this</b></code> reference) of the function is the <code>scope</code> option passed to the {@link #request} method.</p>
  439.          */
  440.         /**
  441.          * @cfg {Object} extraParams (Optional) An object containing properties which are used as
  442.          * extra parameters to each request made by this object. (defaults to undefined)
  443.          */
  444.         /**
  445.          * @cfg {Object} defaultHeaders (Optional) An object containing request headers which are added
  446.          *  to each request made by this object. (defaults to undefined)
  447.          */
  448.         /**
  449.          * @cfg {String} method (Optional) The default HTTP method to be used for requests.
  450.          * (defaults to undefined; if not set, but {@link #request} params are present, POST will be used;
  451.          * otherwise, GET will be used.)
  452.          */
  453.         /**
  454.          * @cfg {Number} timeout (Optional) The timeout in milliseconds to be used for requests. (defaults to 30000)
  455.          */
  456.         timeout : 30000,
  457.         /**
  458.          * @cfg {Boolean} autoAbort (Optional) Whether this request should abort any pending requests. (defaults to false)
  459.          * @type Boolean
  460.          */
  461.         autoAbort:false,
  462.     
  463.         /**
  464.          * @cfg {Boolean} disableCaching (Optional) True to add a unique cache-buster param to GET requests. (defaults to true)
  465.          * @type Boolean
  466.          */
  467.         disableCaching: true,
  468.         
  469.         /**
  470.          * @cfg {String} disableCachingParam (Optional) Change the parameter which is sent went disabling caching
  471.          * through a cache buster. Defaults to '_dc'
  472.          * @type String
  473.          */
  474.         disableCachingParam: '_dc',
  475.         
  476.         /**
  477.          * <p>Sends an HTTP request to a remote server.</p>
  478.          * <p><b>Important:</b> Ajax server requests are asynchronous, and this call will
  479.          * return before the response has been received. Process any returned data
  480.          * in a callback function.</p>
  481.          * <pre><code>
  482. Ext.Ajax.request({
  483.    url: 'ajax_demo/sample.json',
  484.    success: function(response, opts) {
  485.       var obj = Ext.decode(response.responseText);
  486.       console.dir(obj);
  487.    },
  488.    failure: function(response, opts) {
  489.       console.log('server-side failure with status code ' + response.status);
  490.    }
  491. });
  492.          * </code></pre>
  493.          * <p>To execute a callback function in the correct scope, use the <tt>scope</tt> option.</p>
  494.          * @param {Object} options An object which may contain the following properties:<ul>
  495.          * <li><b>url</b> : String/Function (Optional)<div class="sub-desc">The URL to
  496.          * which to send the request, or a function to call which returns a URL string. The scope of the
  497.          * function is specified by the <tt>scope</tt> option. Defaults to the configured
  498.          * <tt>{@link #url}</tt>.</div></li>
  499.          * <li><b>params</b> : Object/String/Function (Optional)<div class="sub-desc">
  500.          * An object containing properties which are used as parameters to the
  501.          * request, a url encoded string or a function to call to get either. The scope of the function
  502.          * is specified by the <tt>scope</tt> option.</div></li>
  503.          * <li><b>method</b> : String (Optional)<div class="sub-desc">The HTTP method to use
  504.          * for the request. Defaults to the configured method, or if no method was configured,
  505.          * "GET" if no parameters are being sent, and "POST" if parameters are being sent.  Note that
  506.          * the method name is case-sensitive and should be all caps.</div></li>
  507.          * <li><b>callback</b> : Function (Optional)<div class="sub-desc">The
  508.          * function to be called upon receipt of the HTTP response. The callback is
  509.          * called regardless of success or failure and is passed the following
  510.          * parameters:<ul>
  511.          * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>
  512.          * <li><b>success</b> : Boolean<div class="sub-desc">True if the request succeeded.</div></li>
  513.          * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data. 
  514.          * See <a href="http://www.w3.org/TR/XMLHttpRequest/">http://www.w3.org/TR/XMLHttpRequest/</a> for details about 
  515.          * accessing elements of the response.</div></li>
  516.          * </ul></div></li>
  517.          * <li><a id="request-option-success"></a><b>success</b> : Function (Optional)<div class="sub-desc">The function
  518.          * to be called upon success of the request. The callback is passed the following
  519.          * parameters:<ul>
  520.          * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.</div></li>
  521.          * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>
  522.          * </ul></div></li>
  523.          * <li><b>failure</b> : Function (Optional)<div class="sub-desc">The function
  524.          * to be called upon failure of the request. The callback is passed the
  525.          * following parameters:<ul>
  526.          * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.</div></li>
  527.          * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>
  528.          * </ul></div></li>
  529.          * <li><b>scope</b> : Object (Optional)<div class="sub-desc">The scope in
  530.          * which to execute the callbacks: The "this" object for the callback function. If the <tt>url</tt>, or <tt>params</tt> options were
  531.          * specified as functions from which to draw values, then this also serves as the scope for those function calls.
  532.          * Defaults to the browser window.</div></li>
  533.          * <li><b>timeout</b> : Number (Optional)<div class="sub-desc">The timeout in milliseconds to be used for this request. Defaults to 30 seconds.</div></li>
  534.          * <li><b>form</b> : Element/HTMLElement/String (Optional)<div class="sub-desc">The <tt>&lt;form&gt;</tt>
  535.          * Element or the id of the <tt>&lt;form&gt;</tt> to pull parameters from.</div></li>
  536.          * <li><a id="request-option-isUpload"></a><b>isUpload</b> : Boolean (Optional)<div class="sub-desc"><b>Only meaningful when used 
  537.          * with the <tt>form</tt> option</b>.
  538.          * <p>True if the form object is a file upload (will be set automatically if the form was
  539.          * configured with <b><tt>enctype</tt></b> "multipart/form-data").</p>
  540.          * <p>File uploads are not performed using normal "Ajax" techniques, that is they are <b>not</b>
  541.          * performed using XMLHttpRequests. Instead the form is submitted in the standard manner with the
  542.          * DOM <tt>&lt;form></tt> element temporarily modified to have its
  543.          * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer
  544.          * to a dynamically generated, hidden <tt>&lt;iframe></tt> which is inserted into the document
  545.          * but removed after the return data has been gathered.</p>
  546.          * <p>The server response is parsed by the browser to create the document for the IFRAME. If the
  547.          * server is using JSON to send the return object, then the
  548.          * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17">Content-Type</a> header
  549.          * must be set to "text/html" in order to tell the browser to insert the text unchanged into the document body.</p>
  550.          * <p>The response text is retrieved from the document, and a fake XMLHttpRequest object
  551.          * is created containing a <tt>responseText</tt> property in order to conform to the
  552.          * requirements of event handlers and callbacks.</p>
  553.          * <p>Be aware that file upload packets are sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form</a>
  554.          * and some server technologies (notably JEE) may require some custom processing in order to
  555.          * retrieve parameter names and parameter values from the packet content.</p>
  556.          * </div></li>
  557.          * <li><b>headers</b> : Object (Optional)<div class="sub-desc">Request
  558.          * headers to set for the request.</div></li>
  559.          * <li><b>xmlData</b> : Object (Optional)<div class="sub-desc">XML document
  560.          * to use for the post. Note: This will be used instead of params for the post
  561.          * data. Any params will be appended to the URL.</div></li>
  562.          * <li><b>jsonData</b> : Object/String (Optional)<div class="sub-desc">JSON
  563.          * data to use as the post. Note: This will be used instead of params for the post
  564.          * data. Any params will be appended to the URL.</div></li>
  565.          * <li><b>disableCaching</b> : Boolean (Optional)<div class="sub-desc">True
  566.          * to add a unique cache-buster param to GET requests.</div></li>
  567.          * </ul></p>
  568.          * <p>The options object may also contain any other property which might be needed to perform
  569.          * postprocessing in a callback because it is passed to callback functions.</p>
  570.          * @return {Number} transactionId The id of the server transaction. This may be used
  571.          * to cancel the request.
  572.          */
  573.         request : function(o){
  574.             var me = this;
  575.             if(me.fireEvent(BEFOREREQUEST, me, o)){
  576.                 if (o.el) {
  577.                     if(!Ext.isEmpty(o.indicatorText)){
  578.                         me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
  579.                     }
  580.                     if(me.indicatorText) {
  581.                         Ext.getDom(o.el).innerHTML = me.indicatorText;                        
  582.                     }
  583.                     o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
  584.                         Ext.getDom(o.el).innerHTML = response.responseText;
  585.                     });
  586.                 }
  587.                 
  588.                 var p = o.params,
  589.                     url = o.url || me.url,                
  590.                     method,
  591.                     cb = {success: handleResponse,
  592.                           failure: handleFailure,
  593.                           scope: me,
  594.                           argument: {options: o},
  595.                           timeout : o.timeout || me.timeout
  596.                     },
  597.                     form,                    
  598.                     serForm;                    
  599.                   
  600.                      
  601.                 if (Ext.isFunction(p)) {
  602.                     p = p.call(o.scope||WINDOW, o);
  603.                 }
  604.                                                            
  605.                 p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);    
  606.                 
  607.                 if (Ext.isFunction(url)) {
  608.                     url = url.call(o.scope || WINDOW, o);
  609.                 }
  610.     
  611.                 if((form = Ext.getDom(o.form))){
  612.                     url = url || form.action;
  613.                      if(o.isUpload || /multipart/form-data/i.test(form.getAttribute("enctype"))) { 
  614.                          return doFormUpload.call(me, o, p, url);
  615.                      }
  616.                     serForm = Ext.lib.Ajax.serializeForm(form);                    
  617.                     p = p ? (p + '&' + serForm) : serForm;
  618.                 }
  619.                 
  620.                 method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
  621.                 
  622.                 if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
  623.                     var dcp = o.disableCachingParam || me.disableCachingParam;
  624.                     url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
  625.                 }
  626.                 
  627.                 o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
  628.                 
  629.                 if(o.autoAbort === true || me.autoAbort) {
  630.                     me.abort();
  631.                 }
  632.                  
  633.                 if((method == GET || o.xmlData || o.jsonData) && p){
  634.                     url = Ext.urlAppend(url, p);  
  635.                     p = '';
  636.                 }
  637.                 return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
  638.             }else{                
  639.                 return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
  640.             }
  641.         },
  642.     
  643.         /**
  644.          * Determine whether this object has a request outstanding.
  645.          * @param {Number} transactionId (Optional) defaults to the last transaction
  646.          * @return {Boolean} True if there is an outstanding request.
  647.          */
  648.         isLoading : function(transId){
  649.             return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;            
  650.         },
  651.     
  652.         /**
  653.          * Aborts any outstanding request.
  654.          * @param {Number} transactionId (Optional) defaults to the last transaction
  655.          */
  656.         abort : function(transId){
  657.             if(transId || this.isLoading()){
  658.                 Ext.lib.Ajax.abort(transId || this.transId);
  659.             }
  660.         }
  661.     });
  662. })();
  663. /**
  664.  * @class Ext.Ajax
  665.  * @extends Ext.data.Connection
  666.  * <p>The global Ajax request class that provides a simple way to make Ajax requests
  667.  * with maximum flexibility.</p>
  668.  * <p>Since Ext.Ajax is a singleton, you can set common properties/events for it once
  669.  * and override them at the request function level only if necessary.</p>
  670.  * <p>Common <b>Properties</b> you may want to set are:<div class="mdetail-params"><ul>
  671.  * <li><b><tt>{@link #method}</tt></b><p class="sub-desc"></p></li>
  672.  * <li><b><tt>{@link #extraParams}</tt></b><p class="sub-desc"></p></li>
  673.  * <li><b><tt>{@link #url}</tt></b><p class="sub-desc"></p></li>
  674.  * </ul></div>
  675.  * <pre><code>
  676. // Default headers to pass in every request
  677. Ext.Ajax.defaultHeaders = {
  678.     'Powered-By': 'Ext'
  679. };
  680.  * </code></pre> 
  681.  * </p>
  682.  * <p>Common <b>Events</b> you may want to set are:<div class="mdetail-params"><ul>
  683.  * <li><b><tt>{@link Ext.data.Connection#beforerequest beforerequest}</tt></b><p class="sub-desc"></p></li>
  684.  * <li><b><tt>{@link Ext.data.Connection#requestcomplete requestcomplete}</tt></b><p class="sub-desc"></p></li>
  685.  * <li><b><tt>{@link Ext.data.Connection#requestexception requestexception}</tt></b><p class="sub-desc"></p></li>
  686.  * </ul></div>
  687.  * <pre><code>
  688. // Example: show a spinner during all Ajax requests
  689. Ext.Ajax.on('beforerequest', this.showSpinner, this);
  690. Ext.Ajax.on('requestcomplete', this.hideSpinner, this);
  691. Ext.Ajax.on('requestexception', this.hideSpinner, this);
  692.  * </code></pre> 
  693.  * </p>
  694.  * <p>An example request:</p>
  695.  * <pre><code>
  696. // Basic request
  697. Ext.Ajax.{@link Ext.data.Connection#request request}({
  698.    url: 'foo.php',
  699.    success: someFn,
  700.    failure: otherFn,
  701.    headers: {
  702.        'my-header': 'foo'
  703.    },
  704.    params: { foo: 'bar' }
  705. });
  706. // Simple ajax form submission
  707. Ext.Ajax.{@link Ext.data.Connection#request request}({
  708.     form: 'some-form',
  709.     params: 'foo=bar'
  710. });
  711.  * </code></pre> 
  712.  * </p>
  713.  * @singleton
  714.  */
  715. Ext.Ajax = new Ext.data.Connection({
  716.     /**
  717.      * @cfg {String} url @hide
  718.      */
  719.     /**
  720.      * @cfg {Object} extraParams @hide
  721.      */
  722.     /**
  723.      * @cfg {Object} defaultHeaders @hide
  724.      */
  725.     /**
  726.      * @cfg {String} method (Optional) @hide
  727.      */
  728.     /**
  729.      * @cfg {Number} timeout (Optional) @hide
  730.      */
  731.     /**
  732.      * @cfg {Boolean} autoAbort (Optional) @hide
  733.      */
  734.     /**
  735.      * @cfg {Boolean} disableCaching (Optional) @hide
  736.      */
  737.     /**
  738.      * @property  disableCaching
  739.      * True to add a unique cache-buster param to GET requests. (defaults to true)
  740.      * @type Boolean
  741.      */
  742.     /**
  743.      * @property  url
  744.      * The default URL to be used for requests to the server. (defaults to undefined)
  745.      * If the server receives all requests through one URL, setting this once is easier than
  746.      * entering it on every request.
  747.      * @type String
  748.      */
  749.     /**
  750.      * @property  extraParams
  751.      * An object containing properties which are used as extra parameters to each request made
  752.      * by this object (defaults to undefined). Session information and other data that you need
  753.      * to pass with each request are commonly put here.
  754.      * @type Object
  755.      */
  756.     /**
  757.      * @property  defaultHeaders
  758.      * An object containing request headers which are added to each request made by this object
  759.      * (defaults to undefined).
  760.      * @type Object
  761.      */
  762.     /**
  763.      * @property  method
  764.      * The default HTTP method to be used for requests. Note that this is case-sensitive and
  765.      * should be all caps (defaults to undefined; if not set but params are present will use
  766.      * <tt>"POST"</tt>, otherwise will use <tt>"GET"</tt>.)
  767.      * @type String
  768.      */
  769.     /**
  770.      * @property  timeout
  771.      * The timeout in milliseconds to be used for requests. (defaults to 30000)
  772.      * @type Number
  773.      */
  774.     /**
  775.      * @property  autoAbort
  776.      * Whether a new request should abort any pending requests. (defaults to false)
  777.      * @type Boolean
  778.      */
  779.     autoAbort : false,
  780.     /**
  781.      * Serialize the passed form into a url encoded string
  782.      * @param {String/HTMLElement} form
  783.      * @return {String}
  784.      */
  785.     serializeForm : function(form){
  786.         return Ext.lib.Ajax.serializeForm(form);
  787.     }
  788. });
  789. /**  * @class Ext.Updater  * @extends Ext.util.Observable  * Provides AJAX-style update capabilities for Element objects.  Updater can be used to {@link #update}  * an {@link Ext.Element} once, or you can use {@link #startAutoRefresh} to set up an auto-updating  * {@link Ext.Element Element} on a specific interval.<br><br>  * Usage:<br>  * <pre><code>  * var el = Ext.get("foo"); // Get Ext.Element object  * var mgr = el.getUpdater();  * mgr.update({         url: "http://myserver.com/index.php",         params: {             param1: "foo",             param2: "bar"         }  * });  * ...  * mgr.formUpdate("myFormId", "http://myserver.com/index.php");  * <br>  * // or directly (returns the same Updater instance)  * var mgr = new Ext.Updater("myElementId");  * mgr.startAutoRefresh(60, "http://myserver.com/index.php");  * mgr.on("update", myFcnNeedsToKnow);  * <br>  * // short handed call directly from the element object  * Ext.get("foo").load({         url: "bar.php",         scripts: true,         params: "param1=foo&amp;param2=bar",         text: "Loading Foo..."  * });  * </code></pre>  * @constructor  * Create new Updater directly.  * @param {Mixed} el The element to update  * @param {Boolean} forceNew (optional) By default the constructor checks to see if the passed element already  * has an Updater and if it does it returns the same instance. This will skip that check (useful for extending this class).  */ Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,  function() { var BEFOREUPDATE = "beforeupdate", UPDATE = "update", FAILURE = "failure"; // private     function processSuccess(response){          var me = this;         me.transaction = null;         if (response.argument.form && response.argument.reset) {             try { // put in try/catch since some older FF releases had problems with this                 response.argument.form.reset();             } catch(e){}         }         if (me.loadScripts) {             me.renderer.render(me.el, response, me,                updateComplete.createDelegate(me, [response]));         } else {             me.renderer.render(me.el, response, me);             updateComplete.call(me, response);         }     }          // private     function updateComplete(response, type, success){         this.fireEvent(type || UPDATE, this.el, response);         if(Ext.isFunction(response.argument.callback)){             response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);         }     }     // private     function processFailure(response){                      updateComplete.call(this, response, FAILURE, !!(this.transaction = null));     }      return {     constructor: function(el, forceNew){     var me = this;         el = Ext.get(el);         if(!forceNew && el.updateManager){             return el.updateManager;         }         /**          * The Element object          * @type Ext.Element          */         me.el = el;         /**          * Cached url to use for refreshes. Overwritten every time update() is called unless "discardUrl" param is set to true.          * @type String          */         me.defaultUrl = null;         me.addEvents(             /**              * @event beforeupdate              * Fired before an update is made, return false from your handler and the update is cancelled.              * @param {Ext.Element} el              * @param {String/Object/Function} url              * @param {String/Object} params              */             BEFOREUPDATE,             /**              * @event update              * Fired after successful update is made.              * @param {Ext.Element} el              * @param {Object} oResponseObject The response Object              */             UPDATE,             /**              * @event failure              * Fired on update failure.              * @param {Ext.Element} el              * @param {Object} oResponseObject The response Object              */             FAILURE         );         Ext.apply(me, Ext.Updater.defaults);         /**          * Blank page URL to use with SSL file uploads (defaults to {@link Ext.Updater.defaults#sslBlankUrl}).          * @property sslBlankUrl          * @type String          */         /**          * Whether to append unique parameter on get request to disable caching (defaults to {@link Ext.Updater.defaults#disableCaching}).          * @property disableCaching          * @type Boolean          */         /**          * Text for loading indicator (defaults to {@link Ext.Updater.defaults#indicatorText}).          * @property indicatorText          * @type String          */         /**          * Whether to show indicatorText when loading (defaults to {@link Ext.Updater.defaults#showLoadIndicator}).          * @property showLoadIndicator          * @type String          */         /**          * Timeout for requests or form posts in seconds (defaults to {@link Ext.Updater.defaults#timeout}).          * @property timeout          * @type Number          */         /**          * True to process scripts in the output (defaults to {@link Ext.Updater.defaults#loadScripts}).          * @property loadScripts          * @type Boolean          */         /**          * Transaction object of the current executing transaction, or null if there is no active transaction.          */         me.transaction = null;         /**          * Delegate for refresh() prebound to "this", use myUpdater.refreshDelegate.createCallback(arg1, arg2) to bind arguments          * @type Function          */         me.refreshDelegate = me.refresh.createDelegate(me);         /**          * Delegate for update() prebound to "this", use myUpdater.updateDelegate.createCallback(arg1, arg2) to bind arguments          * @type Function          */         me.updateDelegate = me.update.createDelegate(me);         /**          * Delegate for formUpdate() prebound to "this", use myUpdater.formUpdateDelegate.createCallback(arg1, arg2) to bind arguments          * @type Function          */         me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);          /**  * The renderer for this Updater (defaults to {@link Ext.Updater.BasicRenderer}).  */         me.renderer = me.renderer || me.getDefaultRenderer();                  Ext.Updater.superclass.constructor.call(me);     },          /**      * Sets the content renderer for this Updater. See {@link Ext.Updater.BasicRenderer#render} for more details.      * @param {Object} renderer The object implementing the render() method      */     setRenderer : function(renderer){         this.renderer = renderer;     },              /**      * Returns the current content renderer for this Updater. See {@link Ext.Updater.BasicRenderer#render} for more details.      * @return {Object}      */     getRenderer : function(){        return this.renderer;     },     /**      * This is an overrideable method which returns a reference to a default      * renderer class if none is specified when creating the Ext.Updater.      * Defaults to {@link Ext.Updater.BasicRenderer}      */     getDefaultRenderer: function() {         return new Ext.Updater.BasicRenderer();     },                      /**      * Sets the default URL used for updates.      * @param {String/Function} defaultUrl The url or a function to call to get the url      */     setDefaultUrl : function(defaultUrl){         this.defaultUrl = defaultUrl;     },              /**      * Get the Element this Updater is bound to      * @return {Ext.Element} The element      */     getEl : function(){         return this.el;     }, /**      * Performs an <b>asynchronous</b> request, updating this element with the response.      * If params are specified it uses POST, otherwise it uses GET.<br><br>      * <b>Note:</b> Due to the asynchronous nature of remote server requests, the Element      * will not have been fully updated when the function returns. To post-process the returned      * data, use the callback option, or an <b><tt>update</tt></b> event handler.      * @param {Object} options A config object containing any of the following options:<ul>      * <li>url : <b>String/Function</b><p class="sub-desc">The URL to request or a function which      * <i>returns</i> the URL (defaults to the value of {@link Ext.Ajax#url} if not specified).</p></li>      * <li>method : <b>String</b><p class="sub-desc">The HTTP method to      * use. Defaults to POST if the <tt>params</tt> argument is present, otherwise GET.</p></li>      * <li>params : <b>String/Object/Function</b><p class="sub-desc">The      * parameters to pass to the server (defaults to none). These may be specified as a url-encoded      * string, or as an object containing properties which represent parameters,      * or as a function, which returns such an object.</p></li>      * <li>scripts : <b>Boolean</b><p class="sub-desc">If <tt>true</tt>      * any &lt;script&gt; tags embedded in the response text will be extracted      * and executed (defaults to {@link Ext.Updater.defaults#loadScripts}). If this option is specified,      * the callback will be called <i>after</i> the execution of the scripts.</p></li>      * <li>callback : <b>Function</b><p class="sub-desc">A function to      * be called when the response from the server arrives. The following      * parameters are passed:<ul>      * <li><b>el</b> : Ext.Element<p class="sub-desc">The Element being updated.</p></li>      * <li><b>success</b> : Boolean<p class="sub-desc">True for success, false for failure.</p></li>      * <li><b>response</b> : XMLHttpRequest<p class="sub-desc">The XMLHttpRequest which processed the update.</p></li>      * <li><b>options</b> : Object<p class="sub-desc">The config object passed to the update call.</p></li></ul>      * </p></li>      * <li>scope : <b>Object</b><p class="sub-desc">The scope in which      * to execute the callback (The callback's <tt>this</tt> reference.) If the      * <tt>params</tt> argument is a function, this scope is used for that function also.</p></li>      * <li>discardUrl : <b>Boolean</b><p class="sub-desc">By default, the URL of this request becomes      * the default URL for this Updater object, and will be subsequently used in {@link #refresh}      * calls.  To bypass this behavior, pass <tt>discardUrl:true</tt> (defaults to false).</p></li>      * <li>timeout : <b>Number</b><p class="sub-desc">The number of seconds to wait for a response before      * timing out (defaults to {@link Ext.Updater.defaults#timeout}).</p></li>      * <li>text : <b>String</b><p class="sub-desc">The text to use as the innerHTML of the      * {@link Ext.Updater.defaults#indicatorText} div (defaults to 'Loading...').  To replace the entire div, not      * just the text, override {@link Ext.Updater.defaults#indicatorText} directly.</p></li>      * <li>nocache : <b>Boolean</b><p class="sub-desc">Only needed for GET      * requests, this option causes an extra, auto-generated parameter to be appended to the request      * to defeat caching (defaults to {@link Ext.Updater.defaults#disableCaching}).</p></li></ul>      * <p>      * For example: <pre><code> um.update({     url: "your-url.php",     params: {param1: "foo", param2: "bar"}, // or a URL encoded string     callback: yourFunction,     scope: yourObject, //(optional scope)     discardUrl: true,     nocache: true,     text: "Loading...",     timeout: 60,     scripts: false // Save time by avoiding RegExp execution. }); </code></pre>      */     update : function(url, params, callback, discardUrl){     var me = this,      cfg,       callerScope;              if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){                          if(Ext.isObject(url)){ // must be config object                 cfg = url;                 url = cfg.url;                 params = params || cfg.params;                 callback = callback || cfg.callback;                 discardUrl = discardUrl || cfg.discardUrl;                 callerScope = cfg.scope;                                  if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};                 if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};                 if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};                 if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};             }             me.showLoading();             if(!discardUrl){                 me.defaultUrl = url;             }             if(Ext.isFunction(url)){                 url = url.call(me);             }             var o = Ext.apply({}, {                 url : url,                 params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,                 success: processSuccess,                 failure: processFailure,                 scope: me,                 callback: undefined,                 timeout: (me.timeout*1000),                 disableCaching: me.disableCaching,                 argument: {                     "options": cfg,                     "url": url,                     "form": null,                     "callback": callback,                     "scope": callerScope || window,                     "params": params                 }             }, cfg);             me.transaction = Ext.Ajax.request(o);         }     },      /**      * <p>Performs an async form post, updating this element with the response. If the form has the attribute      * enctype="<a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form-data</a>", it assumes it's a file upload.      * Uses this.sslBlankUrl for SSL file uploads to prevent IE security warning.</p>      * <p>File uploads are not performed using normal "Ajax" techniques, that is they are <b>not</b>      * performed using XMLHttpRequests. Instead the form is submitted in the standard manner with the      * DOM <tt>&lt;form></tt> element temporarily modified to have its      * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer      * to a dynamically generated, hidden <tt>&lt;iframe></tt> which is inserted into the document      * but removed after the return data has been gathered.</p>      * <p>Be aware that file upload packets, sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form-data</a>      * and some server technologies (notably JEE) may require some custom processing in order to      * retrieve parameter names and parameter values from the packet content.</p>      * @param {String/HTMLElement} form The form Id or form element      * @param {String} url (optional) The url to pass the form to. If omitted the action attribute on the form will be used.      * @param {Boolean} reset (optional) Whether to try to reset the form after the update      * @param {Function} callback (optional) Callback when transaction is complete. The following      * parameters are passed:<ul>      * <li><b>el</b> : Ext.Element<p class="sub-desc">The Element being updated.</p></li>      * <li><b>success</b> : Boolean<p class="sub-desc">True for success, false for failure.</p></li>      * <li><b>response</b> : XMLHttpRequest<p class="sub-desc">The XMLHttpRequest which processed the update.</p></li></ul>      */     formUpdate : function(form, url, reset, callback){     var me = this;         if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){             if(Ext.isFunction(url)){                 url = url.call(me);             }             form = Ext.getDom(form)             me.transaction = Ext.Ajax.request({                 form: form,                 url:url,                 success: processSuccess,                 failure: processFailure,                 scope: me,                 timeout: (me.timeout*1000),                 argument: {                     "url": url,                     "form": form,                     "callback": callback,                     "reset": reset                 }             });             me.showLoading.defer(1, me);         }     },                      /**      * Set this element to auto refresh.  Can be canceled by calling {@link #stopAutoRefresh}.      * @param {Number} interval How often to update (in seconds).      * @param {String/Object/Function} url (optional) The url for this request, a config object in the same format      * supported by {@link #load}, or a function to call to get the url (defaults to the last used url).  Note that while      * the url used in a load call can be reused by this method, other load config options will not be reused and must be      * sepcified as part of a config object passed as this paramter if needed.      * @param {String/Object} params (optional) The parameters to pass as either a url encoded string      * "&param1=1&param2=2" or as an object {param1: 1, param2: 2}      * @param {Function} callback (optional) Callback when transaction is complete - called with signature (oElement, bSuccess)      * @param {Boolean} refreshNow (optional) Whether to execute the refresh now, or wait the interval      */     startAutoRefresh : function(interval, url, params, callback, refreshNow){     var me = this;         if(refreshNow){             me.update(url || me.defaultUrl, params, callback, true);         }         if(me.autoRefreshProcId){             clearInterval(me.autoRefreshProcId);         }         me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);     },     /**      * Stop auto refresh on this element.      */     stopAutoRefresh : function(){         if(this.autoRefreshProcId){             clearInterval(this.autoRefreshProcId);             delete this.autoRefreshProcId;         }     },     /**      * Returns true if the Updater is currently set to auto refresh its content (see {@link #startAutoRefresh}), otherwise false.      */     isAutoRefreshing : function(){        return !!this.autoRefreshProcId;     },     /**      * Display the element's "loading" state. By default, the element is updated with {@link #indicatorText}. This      * method may be overridden to perform a custom action while this Updater is actively updating its contents.      */     showLoading : function(){         if(this.showLoadIndicator){              this.el.dom.innerHTML = this.indicatorText;         }     },     /**      * Aborts the currently executing transaction, if any.      */     abort : function(){         if(this.transaction){             Ext.Ajax.abort(this.transaction);         }     },     /**      * Returns true if an update is in progress, otherwise false.      * @return {Boolean}      */     isUpdating : function(){              return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;             },          /**      * Refresh the element with the last used url or defaultUrl. If there is no url, it returns immediately      * @param {Function} callback (optional) Callback when transaction is complete - called with signature (oElement, bSuccess)      */     refresh : function(callback){         if(this.defaultUrl){          this.update(this.defaultUrl, null, callback, true);      }     }     } }()); /**  * @class Ext.Updater.defaults  * The defaults collection enables customizing the default properties of Updater  */ Ext.Updater.defaults = {    /**      * Timeout for requests or form posts in seconds (defaults to 30 seconds).      * @type Number      */     timeout : 30,         /**      * True to append a unique parameter to GET requests to disable caching (defaults to false).      * @type Boolean      */     disableCaching : false,     /**      * Whether or not to show {@link #indicatorText} during loading (defaults to true).      * @type Boolean      */     showLoadIndicator : true,     /**      * Text for loading indicator (defaults to '&lt;div class="loading-indicator"&gt;Loading...&lt;/div&gt;').      * @type String      */     indicatorText : '<div class="loading-indicator">Loading...</div>',      /**      * True to process scripts by default (defaults to false).      * @type Boolean      */     loadScripts : false,     /**     * Blank page URL to use with SSL file uploads (defaults to {@link Ext#SSL_SECURE_URL} if set, or "javascript:false").     * @type String     */     sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false")       }; /**  * Static convenience method. <b>This method is deprecated in favor of el.load({url:'foo.php', ...})</b>.  * Usage:  * <pre><code>Ext.Updater.updateElement("my-div", "stuff.php");</code></pre>  * @param {Mixed} el The element to update  * @param {String} url The url  * @param {String/Object} params (optional) Url encoded param string or an object of name/value pairs  * @param {Object} options (optional) A config object with any of the Updater properties you want to set - for  * example: {disableCaching:true, indicatorText: "Loading data..."}  * @static  * @deprecated  * @member Ext.Updater  */ Ext.Updater.updateElement = function(el, url, params, options){     var um = Ext.get(el).getUpdater();     Ext.apply(um, options);     um.update(url, params, options ? options.callback : null); }; /**  * @class Ext.Updater.BasicRenderer  * Default Content renderer. Updates the elements innerHTML with the responseText.  */ Ext.Updater.BasicRenderer = function(){}; Ext.Updater.BasicRenderer.prototype = {     /**      * This is called when the transaction is completed and it's time to update the element - The BasicRenderer      * updates the elements innerHTML with the responseText - To perform a custom render (i.e. XML or JSON processing),      * create an object with a "render(el, response)" method and pass it to setRenderer on the Updater.      * @param {Ext.Element} el The element being rendered      * @param {Object} response The XMLHttpRequest object      * @param {Updater} updateManager The calling update manager      * @param {Function} callback A callback that will need to be called if loadScripts is true on the Updater      */      render : function(el, response, updateManager, callback){               el.update(response.responseText, updateManager.loadScripts, callback);     } };/**  * @class Date  *  * The date parsing and formatting syntax contains a subset of  * <a href="http://www.php.net/date">PHP's date() function</a>, and the formats that are  * supported will provide results equivalent to their PHP versions.  *  * The following is a list of all currently supported formats:  * <pre> Format  Description                                                               Example returned values ------  -----------------------------------------------------------------------   -----------------------   d     Day of the month, 2 digits with leading zeros                             01 to 31   D     A short textual representation of the day of the week                     Mon to Sun   j     Day of the month without leading zeros                                    1 to 31   l     A full textual representation of the day of the week                      Sunday to Saturday   N     ISO-8601 numeric representation of the day of the week                    1 (for Monday) through 7 (for Sunday)   S     English ordinal suffix for the day of the month, 2 characters             st, nd, rd or th. Works well with j   w     Numeric representation of the day of the week                             0 (for Sunday) to 6 (for Saturday)   z     The day of the year (starting from 0)                                     0 to 364 (365 in leap years)   W     ISO-8601 week number of year, weeks starting on Monday                    01 to 53   F     A full textual representation of a month, such as January or March        January to December   m     Numeric representation of a month, with leading zeros                     01 to 12   M     A short textual representation of a month                                 Jan to Dec   n     Numeric representation of a month, without leading zeros                  1 to 12   t     Number of days in the given month                                         28 to 31   L     Whether it's a leap year                                                  1 if it is a leap year, 0 otherwise.   o     ISO-8601 year number (identical to (Y), but if the ISO week number (W)    Examples: 1998 or 2004         belongs to the previous or next year, that year is used instead)   Y     A full numeric representation of a year, 4 digits                         Examples: 1999 or 2003   y     A two digit representation of a year                                      Examples: 99 or 03   a     Lowercase Ante meridiem and Post meridiem                                 am or pm   A     Uppercase Ante meridiem and Post meridiem                                 AM or PM   g     12-hour format of an hour without leading zeros                           1 to 12   G     24-hour format of an hour without leading zeros                           0 to 23   h     12-hour format of an hour with leading zeros                              01 to 12   H     24-hour format of an hour with leading zeros                              00 to 23   i     Minutes, with leading zeros                                               00 to 59   s     Seconds, with leading zeros                                               00 to 59   u     Decimal fraction of a second                                              Examples:         (minimum 1 digit, arbitrary number of digits allowed)                     001 (i.e. 0.001s) or                                                                                   100 (i.e. 0.100s) or                                                                                   999 (i.e. 0.999s) or                                                                                   999876543210 (i.e. 0.999876543210s)   O     Difference to Greenwich time (GMT) in hours and minutes                   Example: +1030   P     Difference to Greenwich time (GMT) with colon between hours and minutes   Example: -08:00   T     Timezone abbreviation of the machine running the code                     Examples: EST, MDT, PDT ...   Z     Timezone offset in seconds (negative if west of UTC, positive if east)    -43200 to 50400   c     ISO 8601 date         Notes:                                                                    Examples:         1) If unspecified, the month / day defaults to the current month / day,   1991 or            the time defaults to midnight, while the timezone defaults to the      1992-10 or            browser's timezone. If a time is specified, it must include both hours 1993-09-20 or            and minutes. The "T" delimiter, seconds, milliseconds and timezone     1994-08-19T16:20+01:00 or            are optional.                                                          1995-07-18T17:21:28-02:00 or         2) The decimal fraction of a second, if specified, must contain at        1996-06-17T18:22:29.98765+03:00 or            least 1 digit (there is no limit to the maximum number                 1997-05-16T19:23:30,12345-0400 or            of digits allowed), and may be delimited by either a '.' or a ','      1998-04-15T20:24:31.2468Z or         Refer to the examples on the right for the various levels of              1999-03-14T20:24:32Z or         date-time granularity which are supported, or see                         2000-02-13T21:25:33         http://www.w3.org/TR/NOTE-datetime for more info.                         2001-01-12 22:26:34   U     Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)                1193432466 or -2138434463   M$    Microsoft AJAX serialized dates                                           /Date(1238606590509)/ (i.e. UTC milliseconds since epoch) or                                                                                   /Date(1238606590509+0800)/ </pre>  *  * Example usage (note that you must escape format specifiers with '\' to render them as character literals):  * <pre><code> // Sample date: // 'Wed Jan 10 2007 15:05:01 GMT-0600 (Central Standard Time)' var dt = new Date('1/10/2007 03:05:01 PM GMT-0600'); document.write(dt.format('Y-m-d'));                           // 2007-01-10 document.write(dt.format('F j, Y, g:i a'));                   // January 10, 2007, 3:05 pm document.write(dt.format('l, \t\he jS \of F Y h:i:s A'));  // Wednesday, the 10th of January 2007 03:05:01 PM </code></pre>  *  * Here are some standard date/time patterns that you might find helpful.  They  * are not part of the source of Date.js, but to use them you can simply copy this  * block of code into any script that is included after Date.js and they will also become  * globally available on the Date object.  Feel free to add or remove patterns as needed in your code.  * <pre><code> Date.patterns = {     ISO8601Long:"Y-m-d H:i:s",     ISO8601Short:"Y-m-d",     ShortDate: "n/j/Y",     LongDate: "l, F d, Y",     FullDateTime: "l, F d, Y g:i:s A",     MonthDay: "F d",     ShortTime: "g:i A",     LongTime: "g:i:s A",     SortableDateTime: "Y-m-d\TH:i:s",     UniversalSortableDateTime: "Y-m-d H:i:sO",     YearMonth: "F, Y" }; </code></pre>  *  * Example usage:  * <pre><code> var dt = new Date(); document.write(dt.format(Date.patterns.ShortDate)); </code></pre>  * <p>Developer-written, custom formats may be used by supplying both a formatting and a parsing function  * which perform to specialized requirements. The functions are stored in {@link #parseFunctions} and {@link #formatFunctions}.</p>  */ /*  * Most of the date-formatting functions below are the excellent work of Baron Schwartz.  * (see http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/)  * They generate precompiled functions from format patterns instead of parsing and  * processing each pattern every time a date is formatted. These functions are available  * on every Date object.  */ (function() { /**  * Global flag which determines if strict date parsing should be used.  * Strict date parsing will not roll-over invalid dates, which is the  * default behaviour of javascript Date objects.  * (see {@link #parseDate} for more information)  * Defaults to <tt>false</tt>.  * @static  * @type Boolean */ Date.useStrict = false; // create private copy of Ext's String.format() method // - to remove unnecessary dependency // - to resolve namespace conflict with M$-Ajax's implementation function xf(format) {     var args = Array.prototype.slice.call(arguments, 1);     return format.replace(/{(d+)}/g, function(m, i) {         return args[i];     }); } // private Date.formatCodeToRegex = function(character, currentGroup) {     // Note: currentGroup - position in regex result array (see notes for Date.parseCodes below)     var p = Date.parseCodes[character];     if (p) {       p = typeof p == 'function'? p() : p;       Date.parseCodes[character] = p; // reassign function result to prevent repeated execution     }     return p? Ext.applyIf({       c: p.c? xf(p.c, currentGroup || "{0}") : p.c     }, p) : {         g:0,         c:null,         s:Ext.escapeRe(character) // treat unrecognised characters as literals     } } // private shorthand for Date.formatCodeToRegex since we'll be using it fairly often var $f = Date.formatCodeToRegex; Ext.apply(Date, {     /**      * <p>An object hash in which each property is a date parsing function. The property name is the      * format string which that function parses.</p>      * <p>This object is automatically populated with date parsing functions as      * date formats are requested for Ext standard formatting strings.</p>      * <p>Custom parsing functions may be inserted into this object, keyed by a name which from then on      * may be used as a format string to {@link #parseDate}.<p>      * <p>Example:</p><pre><code> Date.parseFunctions['x-date-format'] = myDateParser; </code></pre>      * <p>A parsing function should return a Date object, and is passed the following parameters:<div class="mdetail-params"><ul>      * <li><code>date</code> : String<div class="sub-desc">The date string to parse.</div></li>      * <li><code>strict</code> : Boolean<div class="sub-desc">True to validate date strings while parsing      * (i.e. prevent javascript Date "rollover") (The default must be false).      * Invalid date strings should return null when parsed.</div></li>      * </ul></div></p>      * <p>To enable Dates to also be <i>formatted</i> according to that format, a corresponding      * formatting function must be placed into the {@link #formatFunctions} property.      * @property parseFunctions      * @static      * @type Object      */     parseFunctions: {         "M$": function(input, strict) {             // note: the timezone offset is ignored since the M$ Ajax server sends             // a UTC milliseconds-since-Unix-epoch value (negative values are allowed)             var re = new RegExp('\/Date\(([-+])?(\d+)(?:[+-]\d{4})?\)\/');             var r = (input || '').match(re);             return r? new Date(((r[1] || '') + r[2]) * 1) : null;         }     },     parseRegexes: [],     /**      * <p>An object hash in which each property is a date formatting function. The property name is the      * format string which corresponds to the produced formatted date string.</p>      * <p>This object is automatically populated with date formatting functions as      * date formats are requested for Ext standard formatting strings.</p>      * <p>Custom formatting functions may be inserted into this object, keyed by a name which from then on      * may be used as a format string to {@link #format}. Example:</p><pre><code> Date.formatFunctions['x-date-format'] = myDateFormatter; </code></pre>      * <p>A formatting function should return a string repesentation of the passed Date object:<div class="mdetail-params"><ul>      * <li><code>date</code> : Date<div class="sub-desc">The Date to format.</div></li>      * </ul></div></p>      * <p>To enable date strings to also be <i>parsed</i> according to that format, a corresponding      * parsing function must be placed into the {@link #parseFunctions} property.      * @property formatFunctions      * @static      * @type Object      */     formatFunctions: {         "M$": function() {             // UTC milliseconds since Unix epoch (M$-AJAX serialized date format (MRSF))             return '\/Date(' + this.getTime() + ')\/';         }     },     y2kYear : 50,     /**      * Date interval constant      * @static      * @type String      */     MILLI : "ms",     /**      * Date interval constant      * @static      * @type String      */     SECOND : "s",     /**      * Date interval constant      * @static      * @type String      */     MINUTE : "mi",     /** Date interval constant      * @static      * @type String      */     HOUR : "h",     /**      * Date interval constant      * @static      * @type String      */     DAY : "d",     /**      * Date interval constant      * @static      * @type String      */     MONTH : "mo",     /**      * Date interval constant      * @static      * @type String      */     YEAR : "y",     /**      * <p>An object hash containing default date values used during date parsing.</p>      * <p>The following properties are available:<div class="mdetail-params"><ul>      * <li><code>y</code> : Number<div class="sub-desc">The default year value. (defaults to undefined)</div></li>      * <li><code>m</code> : Number<div class="sub-desc">The default 1-based month value. (defaults to undefined)</div></li>      * <li><code>d</code> : Number<div class="sub-desc">The default day value. (defaults to undefined)</div></li>      * <li><code>h</code> : Number<div class="sub-desc">The default hour value. (defaults to undefined)</div></li>      * <li><code>i</code> : Number<div class="sub-desc">The default minute value. (defaults to undefined)</div></li>      * <li><code>s</code> : Number<div class="sub-desc">The default second value. (defaults to undefined)</div></li>      * <li><code>ms</code> : Number<div class="sub-desc">The default millisecond value. (defaults to undefined)</div></li>      * </ul></div></p>      * <p>Override these properties to customize the default date values used by the {@link #parseDate} method.</p>      * <p><b>Note: In countries which experience Daylight Saving Time (i.e. DST), the <tt>h</tt>, <tt>i</tt>, <tt>s</tt>      * and <tt>ms</tt> properties may coincide with the exact time in which DST takes effect.      * It is the responsiblity of the developer to account for this.</b></p>      * Example Usage:      * <pre><code> // set default day value to the first day of the month Date.defaults.d = 1; // parse a February date string containing only year and month values. // setting the default day value to 1 prevents weird date rollover issues // when attempting to parse the following date string on, for example, March 31st 2009. Date.parseDate('2009-02', 'Y-m'); // returns a Date object representing February 1st 2009 </code></pre>      * @property defaults      * @static      * @type Object      */     defaults: {},     /**      * An array of textual day names.      * Override these values for international dates.      * Example:      * <pre><code> Date.dayNames = [     'SundayInYourLang',     'MondayInYourLang',     ... ]; </code></pre>      * @type Array      * @static      */     dayNames : [         "Sunday",         "Monday",         "Tuesday",         "Wednesday",         "Thursday",         "Friday",         "Saturday"     ],     /**      * An array of textual month names.      * Override these values for international dates.      * Example:      * <pre><code> Date.monthNames = [     'JanInYourLang',     'FebInYourLang',     ... ]; </code></pre>      * @type Array      * @static      */     monthNames : [         "January",         "February",         "March",         "April",         "May",         "June",         "July",         "August",         "September",         "October",         "November",         "December"     ],     /**      * An object hash of zero-based javascript month numbers (with short month names as keys. note: keys are case-sensitive).      * Override these values for international dates.      * Example:      * <pre><code> Date.monthNumbers = {     'ShortJanNameInYourLang':0,     'ShortFebNameInYourLang':1,     ... }; </code></pre>      * @type Object      * @static      */     monthNumbers : {         Jan:0,         Feb:1,         Mar:2,         Apr:3,         May:4,         Jun:5,         Jul:6,         Aug:7,         Sep:8,         Oct:9,         Nov:10,         Dec:11     },     /**      * Get the short month name for the given month number.      * Override this function for international dates.      * @param {Number} month A zero-based javascript month number.      * @return {String} The short month name.      * @static      */     getShortMonthName : function(month) {         return Date.monthNames[month].substring(0, 3);     },     /**      * Get the short day name for the given day number.      * Override this function for international dates.      * @param {Number} day A zero-based javascript day number.      * @return {String} The short day name.      * @static      */     getShortDayName : function(day) {         return Date.dayNames[day].substring(0, 3);     },     /**      * Get the zero-based javascript month number for the given short/full month name.      * Override this function for international dates.      * @param {String} name The short/full month name.      * @return {Number} The zero-based javascript month number.      * @static      */     getMonthNumber : function(name) {         // handle camel casing for english month names (since the keys for the Date.monthNumbers hash are case sensitive)         return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];     },     /**      * The base format-code to formatting-function hashmap used by the {@link #format} method.      * Formatting functions are strings (or functions which return strings) which      * will return the appropriate value when evaluated in the context of the Date object      * from which the {@link #format} method is called.      * Add to / override these mappings for custom date formatting.      * Note: Date.format() treats characters as literals if an appropriate mapping cannot be found.      * Example:      * <pre><code> Date.formatCodes.x = "String.leftPad(this.getDate(), 2, '0')"; (new Date()).format("X"); // returns the current day of the month </code></pre>      * @type Object      * @static      */     formatCodes : {         d: "String.leftPad(this.getDate(), 2, '0')",         D: "Date.getShortDayName(this.getDay())", // get localised short day name         j: "this.getDate()",         l: "Date.dayNames[this.getDay()]",         N: "(this.getDay() ? this.getDay() : 7)",         S: "this.getSuffix()",         w: "this.getDay()",         z: "this.getDayOfYear()",         W: "String.leftPad(this.getWeekOfYear(), 2, '0')",         F: "Date.monthNames[this.getMonth()]",         m: "String.leftPad(this.getMonth() + 1, 2, '0')",         M: "Date.getShortMonthName(this.getMonth())", // get localised short month name         n: "(this.getMonth() + 1)",         t: "this.getDaysInMonth()",         L: "(this.isLeapYear() ? 1 : 0)",         o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",         Y: "this.getFullYear()",         y: "('' + this.getFullYear()).substring(2, 4)",         a: "(this.getHours() < 12 ? 'am' : 'pm')",         A: "(this.getHours() < 12 ? 'AM' : 'PM')",         g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",         G: "this.getHours()",         h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",         H: "String.leftPad(this.getHours(), 2, '0')",         i: "String.leftPad(this.getMinutes(), 2, '0')",         s: "String.leftPad(this.getSeconds(), 2, '0')",         u: "String.leftPad(this.getMilliseconds(), 3, '0')",         O: "this.getGMTOffset()",         P: "this.getGMTOffset(true)",         T: "this.getTimezone()",         Z: "(this.getTimezoneOffset() * -60)",         c: function() { // ISO-8601 -- GMT format             for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {                 var e = c.charAt(i);                 code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); // treat T as a character literal             }             return code.join(" + ");         },         /*         c: function() { // ISO-8601 -- UTC format             return [               "this.getUTCFullYear()", "'-'",               "String.leftPad(this.getUTCMonth() + 1, 2, '0')", "'-'",               "String.leftPad(this.getUTCDate(), 2, '0')",               "'T'",               "String.leftPad(this.getUTCHours(), 2, '0')", "':'",               "String.leftPad(this.getUTCMinutes(), 2, '0')", "':'",               "String.leftPad(this.getUTCSeconds(), 2, '0')",               "'Z'"             ].join(" + ");         },         */         U: "Math.round(this.getTime() / 1000)"     },     /**      * Checks if the passed Date parameters will cause a javascript Date "rollover".      * @param {Number} year 4-digit year      * @param {Number} month 1-based month-of-year      * @param {Number} day Day of month      * @param {Number} hour (optional) Hour      * @param {Number} minute (optional) Minute      * @param {Number} second (optional) Second      * @param {Number} millisecond (optional) Millisecond      * @return {Boolean} true if the passed parameters do not cause a Date "rollover", false otherwise.      * @static      */     isValid : function(y, m, d, h, i, s, ms) {         // setup defaults         h = h || 0;         i = i || 0;         s = s || 0;         ms = ms || 0;         var dt = new Date(y, m - 1, d, h, i, s, ms);         return y == dt.getFullYear() &&             m == dt.getMonth() + 1 &&             d == dt.getDate() &&             h == dt.getHours() &&             i == dt.getMinutes() &&             s == dt.getSeconds() &&             ms == dt.getMilliseconds();     },     /**      * Parses the passed string using the specified date format.      * Note that this function expects normal calendar dates, meaning that months are 1-based (i.e. 1 = January).      * The {@link #defaults} hash will be used for any date value (i.e. year, month, day, hour, minute, second or millisecond)      * which cannot be found in the passed string. If a corresponding default date value has not been specified in the {@link #defaults} hash,      * the current date's year, month, day or DST-adjusted zero-hour time value will be used instead.      * Keep in mind that the input date string must precisely match the specified format string      * in order for the parse operation to be successful (failed parse operations return a null value).      * <p>Example:</p><pre><code> //dt = Fri May 25 2007 (current date) var dt = new Date(); //dt = Thu May 25 2006 (today&#39;s month/day in 2006) dt = Date.parseDate("2006", "Y"); //dt = Sun Jan 15 2006 (all date parts specified) dt = Date.parseDate("2006-01-15", "Y-m-d"); //dt = Sun Jan 15 2006 15:20:01 dt = Date.parseDate("2006-01-15 3:20:01 PM", "Y-m-d g:i:s A"); // attempt to parse Sun Feb 29 2006 03:20:01 in strict mode dt = Date.parseDate("2006-02-29 03:20:01", "Y-m-d H:i:s", true); // returns null </code></pre>      * @param {String} input The raw date string.      * @param {String} format The expected date string format.      * @param {Boolean} strict (optional) True to validate date strings while parsing (i.e. prevents javascript Date "rollover")                         (defaults to false). Invalid date strings will return null when parsed.      * @return {Date} The parsed Date.      * @static      */     parseDate : function(input, format, strict) {         var p = Date.parseFunctions;         if (p[format] == null) {             Date.createParser(format);         }         return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);     },     // private     getFormatCode : function(character) {         var f = Date.formatCodes[character];         if (f) {           f = typeof f == 'function'? f() : f;           Date.formatCodes[character] = f; // reassign function result to prevent repeated execution         }         // note: unknown characters are treated as literals         return f || ("'" + String.escape(character) + "'");     },     // private     createFormat : function(format) {         var code = [],             special = false,             ch = '';         for (var i = 0; i < format.length; ++i) {             ch = format.charAt(i);             if (!special && ch == "\") {                 special = true;             } else if (special) {                 special = false;                 code.push("'" + String.escape(ch) + "'");             } else {                 code.push(Date.getFormatCode(ch))             }         }         Date.formatFunctions[format] = new Function("return " + code.join('+'));     },     // private     createParser : function() {         var code = [             "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",                 "def = Date.defaults,",                 "results = String(input).match(Date.parseRegexes[{0}]);", // either null, or an array of matched strings             "if(results){",                 "{1}",                 "if(u != null){", // i.e. unix time is defined                     "v = new Date(u * 1000);", // give top priority to UNIX time                 "}else{",                     // create Date object representing midnight of the current day;                     // this will provide us with our date defaults                     // (note: clearTime() handles Daylight Saving Time automatically)                     "dt = (new Date()).clearTime();",                     // date calculations (note: these calculations create a dependency on Ext.num())                     "y = y >= 0? y : Ext.num(def.y, dt.getFullYear());",                     "m = m >= 0? m : Ext.num(def.m - 1, dt.getMonth());",                     "d = d >= 0? d : Ext.num(def.d, dt.getDate());",                     // time calculations (note: these calculations create a dependency on Ext.num())                     "h  = h || Ext.num(def.h, dt.getHours());",                     "i  = i || Ext.num(def.i, dt.getMinutes());",                     "s  = s || Ext.num(def.s, dt.getSeconds());",                     "ms = ms || Ext.num(def.ms, dt.getMilliseconds());",                     "if(z >= 0 && y >= 0){",                         // both the year and zero-based day of year are defined and >= 0.                         // these 2 values alone provide sufficient info to create a full date object                         // create Date object representing January 1st for the given year                         "v = new Date(y, 0, 1, h, i, s, ms);",                         // then add day of year, checking for Date "rollover" if necessary                         "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",                     "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", // check for Date "rollover"                         "v = null;", // invalid date, so return null                     "}else{",                         // plain old Date object                         "v = new Date(y, m, d, h, i, s, ms);",                     "}",                 "}",             "}",             "if(v){",                 // favour UTC offset over GMT offset                 "if(zz != null){",                     // reset to UTC, then add offset                     "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",                 "}else if(o){",                     // reset to GMT, then add offset                     "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",                 "}",             "}",             "return v;"         ].join('n');         return function(format) {             var regexNum = Date.parseRegexes.length,                 currentGroup = 1,                 calc = [],                 regex = [],                 special = false,                 ch = "";             for (var i = 0; i < format.length; ++i) {                 ch = format.charAt(i);                 if (!special && ch == "\") {                     special = true;                 } else if (special) {                     special = false;                     regex.push(String.escape(ch));                 } else {                     var obj = $f(ch, currentGroup);                     currentGroup += obj.g;                     regex.push(obj.s);                     if (obj.g && obj.c) {                         calc.push(obj.c);                     }                 }             }             Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", "i");             Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));         }     }(),     // private     parseCodes : {         /*          * Notes:          * g = {Number} calculation group (0 or 1. only group 1 contributes to date calculations.)          * c = {String} calculation method (required for group 1. null for group 0. {0} = currentGroup - position in regex result array)          * s = {String} regex pattern. all matches are stored in results[], and are accessible by the calculation mapped to 'c'          */         d: {             g:1,             c:"d = parseInt(results[{0}], 10);n",             s:"(\d{2})" // day of month with leading zeroes (01 - 31)         },         j: {             g:1,             c:"d = parseInt(results[{0}], 10);n",             s:"(\d{1,2})" // day of month without leading zeroes (1 - 31)         },         D: function() {             for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); // get localised short day names             return {                 g:0,                 c:null,                 s:"(?:" + a.join("|") +")"             }         },         l: function() {             return {                 g:0,                 c:null,                 s:"(?:" + Date.dayNames.join("|") + ")"             }         },         N: {             g:0,             c:null,             s:"[1-7]" // ISO-8601 day number (1 (monday) - 7 (sunday))         },         S: {             g:0,             c:null,             s:"(?:st|nd|rd|th)"         },         w: {             g:0,             c:null,             s:"[0-6]" // javascript day number (0 (sunday) - 6 (saturday))         },         z: {             g:1,             c:"z = parseInt(results[{0}], 10);n",             s:"(\d{1,3})" // day of the year (0 - 364 (365 in leap years))         },         W: {             g:0,             c:null,             s:"(?:\d{2})" // ISO-8601 week number (with leading zero)         },         F: function() {             return {                 g:1,                 c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);n", // get localised month number                 s:"(" + Date.monthNames.join("|") + ")"             }         },         M: function() {             for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names             return Ext.applyIf({                 s:"(" + a.join("|") + ")"             }, $f("F"));         },         m: {             g:1,             c:"m = parseInt(results[{0}], 10) - 1;n",             s:"(\d{2})" // month number with leading zeros (01 - 12)         },         n: {             g:1,             c:"m = parseInt(results[{0}], 10) - 1;n",             s:"(\d{1,2})" // month number without leading zeros (1 - 12)         },         t: {             g:0,             c:null,             s:"(?:\d{2})" // no. of days in the month (28 - 31)         },         L: {             g:0,             c:null,             s:"(?:1|0)"         },         o: function() {             return $f("Y");         },         Y: {             g:1,             c:"y = parseInt(results[{0}], 10);n",             s:"(\d{4})" // 4-digit year         },         y: {             g:1,             c:"var ty = parseInt(results[{0}], 10);n"                 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;n", // 2-digit year             s:"(\d{1,2})"         },         a: {             g:1,             c:"if (results[{0}] == 'am') {n"                 + "if (h == 12) { h = 0; }n"                 + "} else { if (h < 12) { h += 12; }}",             s:"(am|pm)"         },         A: {             g:1,             c:"if (results[{0}] == 'AM') {n"                 + "if (h == 12) { h = 0; }n"                 + "} else { if (h < 12) { h += 12; }}",             s:"(AM|PM)"         },         g: function() {             return $f("G");         },         G: {             g:1,             c:"h = parseInt(results[{0}], 10);n",             s:"(\d{1,2})" // 24-hr format of an hour without leading zeroes (0 - 23)         },         h: function() {             return $f("H");         },         H: {             g:1,             c:"h = parseInt(results[{0}], 10);n",             s:"(\d{2})" //  24-hr format of an hour with leading zeroes (00 - 23)         },         i: {             g:1,             c:"i = parseInt(results[{0}], 10);n",             s:"(\d{2})" // minutes with leading zeros (00 - 59)         },         s: {             g:1,             c:"s = parseInt(results[{0}], 10);n",             s:"(\d{2})" // seconds with leading zeros (00 - 59)         },         u: {             g:1,             c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);n",             s:"(\d+)" // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)         },         O: {             g:1,             c:[                 "o = results[{0}];",                 "var sn = o.substring(0,1),", // get + / - sign                     "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", // get hours (performs minutes-to-hour conversion also, just in case)                     "mn = o.substring(3,5) % 60;", // get minutes                 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;n" // -12hrs <= GMT offset <= 14hrs             ].join("n"),             s: "([+-]\d{4})" // GMT offset in hrs and mins         },         P: {             g:1,             c:[                 "o = results[{0}];",                 "var sn = o.substring(0,1),", // get + / - sign                     "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", // get hours (performs minutes-to-hour conversion also, just in case)                     "mn = o.substring(4,6) % 60;", // get minutes                 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;n" // -12hrs <= GMT offset <= 14hrs             ].join("n"),             s: "([+-]\d{2}:\d{2})" // GMT offset in hrs and mins (with colon separator)         },         T: {             g:0,             c:null,             s:"[A-Z]{1,4}" // timezone abbrev. may be between 1 - 4 chars         },         Z: {             g:1,             c:"zz = results[{0}] * 1;n" // -43200 <= UTC offset <= 50400                   + "zz = (-43200 <= zz && zz <= 50400)? zz : null;n",             s:"([+-]?\d{1,5})" // leading '+' sign is optional for UTC offset         },         c: function() {             var calc = [],                 arr = [                     $f("Y", 1), // year                     $f("m", 2), // month                     $f("d", 3), // day                     $f("h", 4), // hour                     $f("i", 5), // minute                     $f("s", 6), // second                     {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);n"}, // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)                     {c:[ // allow either "Z" (i.e. UTC) or "-0530" or "+08:00" (i.e. UTC offset) timezone delimiters. assumes local timezone if no timezone is specified                         "if(results[8]) {", // timezone specified                             "if(results[8] == 'Z'){",                                 "zz = 0;", // UTC                             "}else if (results[8].indexOf(':') > -1){",                                 $f("P", 8).c, // timezone offset with colon separator                             "}else{",                                 $f("O", 8).c, // timezone offset without colon separator                             "}",                         "}"                     ].join('n')}                 ];             for (var i = 0, l = arr.length; i < l; ++i) {                 calc.push(arr[i].c);             }             return {                 g:1,                 c:calc.join(""),                 s:[                     arr[0].s, // year (required)                     "(?:", "-", arr[1].s, // month (optional)                         "(?:", "-", arr[2].s, // day (optional)                             "(?:",                                 "(?:T| )?", // time delimiter -- either a "T" or a single blank space                                 arr[3].s, ":", arr[4].s,  // hour AND minute, delimited by a single colon (optional). MUST be preceded by either a "T" or a single blank space                                 "(?::", arr[5].s, ")?", // seconds (optional)                                 "(?:(?:\.|,)(\d+))?", // decimal fraction of a second (e.g. ",12345" or ".98765") (optional)                                 "(Z|(?:[-+]\d{2}(?::)?\d{2}))?", // "Z" (UTC) or "-0530" (UTC offset without colon delimiter) or "+08:00" (UTC offset with colon delimiter) (optional)                             ")?",                         ")?",                     ")?"                 ].join("")             }         },         U: {             g:1,             c:"u = parseInt(results[{0}], 10);n",             s:"(-?\d+)" // leading minus sign indicates seconds before UNIX epoch         }     } }); }()); Ext.apply(Date.prototype, {     // private     dateFormat : function(format) {         if (Date.formatFunctions[format] == null) {             Date.createFormat(format);         }         return Date.formatFunctions[format].call(this);     },     /**      * Get the timezone abbreviation of the current date (equivalent to the format specifier 'T').      *      * Note: The date string returned by the javascript Date object's toString() method varies      * between browsers (e.g. FF vs IE) and system region settings (e.g. IE in Asia vs IE in America).      * For a given date string e.g. "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)",      * getTimezone() first tries to get the timezone abbreviation from between a pair of parentheses      * (which may or may not be present), failing which it proceeds to get the timezone abbreviation      * from the GMT offset portion of the date string.      * @return {String} The abbreviated timezone name (e.g. 'CST', 'PDT', 'EDT', 'MPST' ...).      */     getTimezone : function() {         // the following list shows the differences between date strings from different browsers on a WinXP SP2 machine from an Asian locale:         //         // Opera  : "Thu, 25 Oct 2007 22:53:45 GMT+0800" -- shortest (weirdest) date string of the lot         // Safari : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone (same as FF)         // FF     : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone         // IE     : "Thu Oct 25 22:54:35 UTC+0800 2007" -- (Asian system setting) look for 3-4 letter timezone abbrev         // IE     : "Thu Oct 25 17:06:37 PDT 2007" -- (American system setting) look for 3-4 letter timezone abbrev         //         // this crazy regex attempts to guess the correct timezone abbreviation despite these differences.         // step 1: (?:((.*)) -- find timezone in parentheses         // step 2: ([A-Z]{1,4})(?:[-+][0-9]{4})?(?: -?d+)?) -- if nothing was found in step 1, find timezone from timezone offset portion of date string         // step 3: remove all non uppercase characters found in step 1 and 2         return this.toString().replace(/^.* (?:((.*))|([A-Z]{1,4})(?:[-+][0-9]{4})?(?: -?d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");     },     /**      * Get the offset from GMT of the current date (equivalent to the format specifier 'O').      * @param {Boolean} colon (optional) true to separate the hours and minutes with a colon (defaults to false).      * @return {String} The 4-character offset string prefixed with + or - (e.g. '-0600').      */     getGMTOffset : function(colon) {         return (this.getTimezoneOffset() > 0 ? "-" : "+")             + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")             + (colon ? ":" : "")             + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");     },     /**      * Get the numeric day number of the year, adjusted for leap year.      * @return {Number} 0 to 364 (365 in leap years).      */     getDayOfYear: function() {         var i = 0,             num = 0,             d = this.clone(),             m = this.getMonth();         for (i = 0, d.setMonth(0); i < m; d.setMonth(++i)) {             num += d.getDaysInMonth();         }         return num + this.getDate() - 1;     },     /**      * Get the numeric ISO-8601 week number of the year.      * (equivalent to the format specifier 'W', but without a leading zero).      * @return {Number} 1 to 53      */     getWeekOfYear : function() {         // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm         var ms1d = 864e5, // milliseconds in a day             ms7d = 7 * ms1d; // milliseconds in a week         return function() { // return a closure so constants get calculated only once             var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, // an Absolute Day Number                 AWN = Math.floor(DC3 / 7), // an Absolute Week Number                 Wyr = new Date(AWN * ms7d).getUTCFullYear();             return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;         }     }(),     /**      * Checks if the current date falls within a leap year.      * @return {Boolean} True if the current date falls within a leap year, false otherwise.      */     isLeapYear : function() {         var year = this.getFullYear();         return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));     },     /**      * Get the first day of the current month, adjusted for leap year.  The returned value      * is the numeric day index within the week (0-6) which can be used in conjunction with      * the {@link #monthNames} array to retrieve the textual day name.      * Example:      * <pre><code> var dt = new Date('1/10/2007'); document.write(Date.dayNames[dt.getFirstDayOfMonth()]); //output: 'Monday' </code></pre>      * @return {Number} The day number (0-6).      */     getFirstDayOfMonth : function() {         var day = (this.getDay() - (this.getDate() - 1)) % 7;         return (day < 0) ? (day + 7) : day;     },     /**      * Get the last day of the current month, adjusted for leap year.  The returned value      * is the numeric day index within the week (0-6) which can be used in conjunction with      * the {@link #monthNames} array to retrieve the textual day name.      * Example:      * <pre><code> var dt = new Date('1/10/2007'); document.write(Date.dayNames[dt.getLastDayOfMonth()]); //output: 'Wednesday' </code></pre>      * @return {Number} The day number (0-6).      */     getLastDayOfMonth : function() {         return this.getLastDateOfMonth().getDay();     },     /**      * Get the date of the first day of the month in which this date resides.      * @return {Date}      */     getFirstDateOfMonth : function() {         return new Date(this.getFullYear(), this.getMonth(), 1);     },     /**      * Get the date of the last day of the month in which this date resides.      * @return {Date}      */     getLastDateOfMonth : function() {         return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());     },     /**      * Get the number of days in the current month, adjusted for leap year.      * @return {Number} The number of days in the month.      */     getDaysInMonth: function() {         var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];         return function() { // return a closure for efficiency             var m = this.getMonth();             return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];         }     }(),     /**      * Get the English ordinal suffix of the current day (equivalent to the format specifier 'S').      * @return {String} 'st, 'nd', 'rd' or 'th'.      */     getSuffix : function() {         switch (this.getDate()) {             case 1:             case 21:             case 31:                 return "st";             case 2:             case 22:                 return "nd";             case 3:             case 23:                 return "rd";             default:                 return "th";         }     },     /**      * Creates and returns a new Date instance with the exact same date value as the called instance.      * Dates are copied and passed by reference, so if a copied date variable is modified later, the original      * variable will also be changed.  When the intention is to create a new variable that will not      * modify the original instance, you should create a clone.      *      * Example of correctly cloning a date:      * <pre><code> //wrong way: var orig = new Date('10/1/2006'); var copy = orig; copy.setDate(5); document.write(orig);  //returns 'Thu Oct 05 2006'! //correct way: var orig = new Date('10/1/2006'); var copy = orig.clone(); copy.setDate(5); document.write(orig);  //returns 'Thu Oct 01 2006' </code></pre>      * @return {Date} The new Date instance.      */     clone : function() {         return new Date(this.getTime());     },     /**      * Checks if the current date is affected by Daylight Saving Time (DST).      * @return {Boolean} True if the current date is affected by DST.      */     isDST : function() {         // adapted from http://extjs.com/forum/showthread.php?p=247172#post247172         // courtesy of @geoffrey.mcgill         return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();     },     /**      * Attempts to clear all time information from this Date by setting the time to midnight of the same day,      * automatically adjusting for Daylight Saving Time (DST) where applicable.      * (note: DST timezone information for the browser's host operating system is assumed to be up-to-date)      * @param {Boolean} clone true to create a clone of this date, clear the time and return it (defaults to false).      * @return {Date} this or the clone.      */     clearTime : function(clone) {         if (clone) {             return this.clone().clearTime();         }         // get current date before clearing time         var d = this.getDate();         // clear time         this.setHours(0);         this.setMinutes(0);         this.setSeconds(0);         this.setMilliseconds(0);         if (this.getDate() != d) { // account for DST (i.e. day of month changed when setting hour = 0)             // note: DST adjustments are assumed to occur in multiples of 1 hour (this is almost always the case)             // refer to http://www.timeanddate.com/time/aboutdst.html for the (rare) exceptions to this rule             // increment hour until cloned date == current date             for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));             this.setDate(d);             this.setHours(c.getHours());         }         return this;     },     /**      * Provides a convenient method for performing basic date arithmetic. This method      * does not modify the Date instance being called - it creates and returns      * a new Date instance containing the resulting date value.      *      * Examples:      * <pre><code> // Basic usage: var dt = new Date('10/29/2006').add(Date.DAY, 5); document.write(dt); //returns 'Fri Nov 03 2006 00:00:00' // Negative values will be subtracted: var dt2 = new Date('10/1/2006').add(Date.DAY, -5); document.write(dt2); //returns 'Tue Sep 26 2006 00:00:00' // You can even chain several calls together in one line: var dt3 = new Date('10/1/2006').add(Date.DAY, 5).add(Date.HOUR, 8).add(Date.MINUTE, -30); document.write(dt3); //returns 'Fri Oct 06 2006 07:30:00' </code></pre>      *      * @param {String} interval A valid date interval enum value.      * @param {Number} value The amount to add to the current date.      * @return {Date} The new Date instance.      */     add : function(interval, value) {         var d = this.clone();         if (!interval || value === 0) return d;         switch(interval.toLowerCase()) {             case Date.MILLI:                 d.setMilliseconds(this.getMilliseconds() + value);                 break;             case Date.SECOND:                 d.setSeconds(this.getSeconds() + value);                 break;             case Date.MINUTE:                 d.setMinutes(this.getMinutes() + value);                 break;             case Date.HOUR:                 d.setHours(this.getHours() + value);                 break;             case Date.DAY:                 d.setDate(this.getDate() + value);                 break;             case Date.MONTH:                 var day = this.getDate();                 if (day > 28) {                     day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());                 }                 d.setDate(day);                 d.setMonth(this.getMonth() + value);                 break;             case Date.YEAR:                 d.setFullYear(this.getFullYear() + value);                 break;         }         return d;     },     /**      * Checks if this date falls on or between the given start and end dates.      * @param {Date} start Start date      * @param {Date} end End date      * @return {Boolean} true if this date falls on or between the given start and end dates.      */     between : function(start, end) {         var t = this.getTime();         return start.getTime() <= t && t <= end.getTime();     } }); /**  * Formats a date given the supplied format string.  * @param {String} format The format string.  * @return {String} The formatted date.  * @method format  */ Date.prototype.format = Date.prototype.dateFormat; // private if (Ext.isSafari && (navigator.userAgent.match(/WebKit/(d+)/)[1] || NaN) < 420) {     Ext.apply(Date.prototype, {         _xMonth : Date.prototype.setMonth,         _xDate  : Date.prototype.setDate,         // Bug in Safari 1.3, 2.0 (WebKit build < 420)         // Date.setMonth does not work consistently if iMonth is not 0-11         setMonth : function(num) {             if (num <= -1) {                 var n = Math.ceil(-num),                     back_year = Math.ceil(n / 12),                     month = (n % 12) ? 12 - n % 12 : 0;                 this.setFullYear(this.getFullYear() - back_year);                 return this._xMonth(month);             } else {                 return this._xMonth(num);             }         },         // Bug in setDate() method (resolved in WebKit build 419.3, so to be safe we target Webkit builds < 420)         // The parameter for Date.setDate() is converted to a signed byte integer in Safari         // http://brianary.blogspot.com/2006/03/safari-date-bug.html         setDate : function(d) {             // use setTime() to workaround setDate() bug             // subtract current day of month in milliseconds, then add desired day of month in milliseconds             return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);         }     }); } /* Some basic Date tests... (requires Firebug) Date.parseDate('', 'c'); // call Date.parseDate() once to force computation of regex string so we can console.log() it console.log('Insane Regex for "c" format: %o', Date.parseCodes.c.s); // view the insane regex for the "c" format specifier // standard tests console.group('Standard Date.parseDate() Tests');     console.log('Date.parseDate("2009-01-05T11:38:56", "c")               = %o', Date.parseDate("2009-01-05T11:38:56", "c")); // assumes browser's timezone setting     console.log('Date.parseDate("2009-02-04T12:37:55.001000", "c")        = %o', Date.parseDate("2009-02-04T12:37:55.001000", "c")); // assumes browser's timezone setting     console.log('Date.parseDate("2009-03-03T13:36:54,101000Z", "c")       = %o', Date.parseDate("2009-03-03T13:36:54,101000Z", "c")); // UTC     console.log('Date.parseDate("2009-04-02T14:35:53.901000-0530", "c")   = %o', Date.parseDate("2009-04-02T14:35:53.901000-0530", "c")); // GMT-0530     console.log('Date.parseDate("2009-05-01T15:34:52,9876000+08:00", "c") = %o', Date.parseDate("2009-05-01T15:34:52,987600+08:00", "c")); // GMT+08:00 console.groupEnd(); // ISO-8601 format as specified in http://www.w3.org/TR/NOTE-datetime // -- accepts ALL 6 levels of date-time granularity console.group('ISO-8601 Granularity Test (see http://www.w3.org/TR/NOTE-datetime)');     console.log('Date.parseDate("1997", "c")                              = %o', Date.parseDate("1997", "c")); // YYYY (e.g. 1997)     console.log('Date.parseDate("1997-07", "c")                           = %o', Date.parseDate("1997-07", "c")); // YYYY-MM (e.g. 1997-07)     console.log('Date.parseDate("1997-07-16", "c")                        = %o', Date.parseDate("1997-07-16", "c")); // YYYY-MM-DD (e.g. 1997-07-16)     console.log('Date.parseDate("1997-07-16T19:20+01:00", "c")            = %o', Date.parseDate("1997-07-16T19:20+01:00", "c")); // YYYY-MM-DDThh:mmTZD (e.g. 1997-07-16T19:20+01:00)     console.log('Date.parseDate("1997-07-16T19:20:30+01:00", "c")         = %o', Date.parseDate("1997-07-16T19:20:30+01:00", "c")); // YYYY-MM-DDThh:mm:ssTZD (e.g. 1997-07-16T19:20:30+01:00)     console.log('Date.parseDate("1997-07-16T19:20:30.45+01:00", "c")      = %o', Date.parseDate("1997-07-16T19:20:30.45+01:00", "c")); // YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45+01:00)     console.log('Date.parseDate("1997-07-16 19:20:30.45+01:00", "c")      = %o', Date.parseDate("1997-07-16 19:20:30.45+01:00", "c")); // YYYY-MM-DD hh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45+01:00)     console.log('Date.parseDate("1997-13-16T19:20:30.45+01:00", "c", true)= %o', Date.parseDate("1997-13-16T19:20:30.45+01:00", "c", true)); // strict date parsing with invalid month value console.groupEnd(); //*//**  * @class Ext.util.DelayedTask  * <p> The DelayedTask class provides a convenient way to "buffer" the execution of a method,  * performing setTimeout where a new timeout cancels the old timeout. When called, the  * task will wait the specified time period before executing. If durng that time period,  * the task is called again, the original call will be cancelled. This continues so that  * the function is only called a single time for each iteration.</p>  * <p>This method is especially useful for things like detecting whether a user has finished  * typing in a text field. An example would be performing validation on a keypress. You can  * use this class to buffer the keypress events for a certain number of milliseconds, and  * perform only if they stop for that amount of time.  Usage:</p><pre><code> var task = new Ext.util.DelayedTask(function(){     alert(Ext.getDom('myInputField').value.length); }); // Wait 500ms before calling our function. If the user presses another key  // during that 500ms, it will be cancelled and we'll wait another 500ms. Ext.get('myInputField').on('keypress', function(){     task.{@link #delay}(500);  });  * </code></pre>   * <p>Note that we are using a DelayedTask here to illustrate a point. The configuration  * option <tt>buffer</tt> for {@link Ext.util.Observable#addListener addListener/on} will  * also setup a delayed task for you to buffer events.</p>   * @constructor The parameters to this constructor serve as defaults and are not required.  * @param {Function} fn (optional) The default function to timeout  * @param {Object} scope (optional) The default scope of that timeout  * @param {Array} args (optional) The default Array of arguments  */ Ext.util.DelayedTask = function(fn, scope, args){     var me = this,      id,          call = function(){      clearInterval(id);         id = null;         fn.apply(scope, args || []);     };          /**      * Cancels any pending timeout and queues a new one      * @param {Number} delay The milliseconds to delay      * @param {Function} newFn (optional) Overrides function passed to constructor      * @param {Object} newScope (optional) Overrides scope passed to constructor      * @param {Array} newArgs (optional) Overrides args passed to constructor      */     me.delay = function(delay, newFn, newScope, newArgs){         me.cancel();         fn = newFn || fn;         scope = newScope || scope;         args = newArgs || args;         id = setInterval(call, delay);     };     /**      * Cancel the last queued timeout      */     me.cancel = function(){         if(id){             clearInterval(id);             id = null;         }     }; };/**
  790.  * @class Ext.util.MixedCollection
  791.  * @extends Ext.util.Observable
  792.  * A Collection class that maintains both numeric indexes and keys and exposes events.
  793.  * @constructor
  794.  * @param {Boolean} allowFunctions True if the addAll function should add function references to the
  795.  * collection (defaults to false)
  796.  * @param {Function} keyFn A function that can accept an item of the type(s) stored in this MixedCollection
  797.  * and return the key value for that item.  This is used when available to look up the key on items that
  798.  * were passed without an explicit key parameter to a MixedCollection method.  Passing this parameter is
  799.  * equivalent to providing an implementation for the {@link #getKey} method.
  800.  */
  801. Ext.util.MixedCollection = function(allowFunctions, keyFn){
  802.     this.items = [];
  803.     this.map = {};
  804.     this.keys = [];
  805.     this.length = 0;
  806.     this.addEvents(
  807.         /**
  808.          * @event clear
  809.          * Fires when the collection is cleared.
  810.          */
  811.         "clear",
  812.         /**
  813.          * @event add
  814.          * Fires when an item is added to the collection.
  815.          * @param {Number} index The index at which the item was added.
  816.          * @param {Object} o The item added.
  817.          * @param {String} key The key associated with the added item.
  818.          */
  819.         "add",
  820.         /**
  821.          * @event replace
  822.          * Fires when an item is replaced in the collection.
  823.          * @param {String} key he key associated with the new added.
  824.          * @param {Object} old The item being replaced.
  825.          * @param {Object} new The new item.
  826.          */
  827.         "replace",
  828.         /**
  829.          * @event remove
  830.          * Fires when an item is removed from the collection.
  831.          * @param {Object} o The item being removed.
  832.          * @param {String} key (optional) The key associated with the removed item.
  833.          */
  834.         "remove",
  835.         "sort"
  836.     );
  837.     this.allowFunctions = allowFunctions === true;
  838.     if(keyFn){
  839.         this.getKey = keyFn;
  840.     }
  841.     Ext.util.MixedCollection.superclass.constructor.call(this);
  842. };
  843. Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
  844.     allowFunctions : false,
  845. /**
  846.  * Adds an item to the collection. Fires the {@link #add} event when complete.
  847.  * @param {String} key <p>The key to associate with the item, or the new item.</p>
  848.  * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key
  849.  * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection
  850.  * will be able to <i>derive</i> the key for the new item. In this case just pass the new item in
  851.  * this parameter.</p>
  852.  * @param {Object} o The item to add.
  853.  * @return {Object} The item added.
  854.  */
  855.     add: function(key, o){
  856.         if(arguments.length == 1){
  857.             o = arguments[0];
  858.             key = this.getKey(o);
  859.         }
  860.         if(typeof key != 'undefined' && key !== null){
  861.             var old = this.map[key];
  862.             if(typeof old != 'undefined'){
  863.                 return this.replace(key, o);
  864.             }
  865.             this.map[key] = o;
  866.         }
  867.         this.length++;
  868.         this.items.push(o);
  869.         this.keys.push(key);
  870.         this.fireEvent('add', this.length-1, o, key);
  871.         return o;
  872.     },
  873. /**
  874.   * MixedCollection has a generic way to fetch keys if you implement getKey.  The default implementation
  875.   * simply returns <tt style="font-weight:bold;">item.id</tt> but you can provide your own implementation
  876.   * to return a different value as in the following examples:
  877. <pre><code>
  878. // normal way
  879. var mc = new Ext.util.MixedCollection();
  880. mc.add(someEl.dom.id, someEl);
  881. mc.add(otherEl.dom.id, otherEl);
  882. //and so on
  883. // using getKey
  884. var mc = new Ext.util.MixedCollection();
  885. mc.getKey = function(el){
  886.    return el.dom.id;
  887. };
  888. mc.add(someEl);
  889. mc.add(otherEl);
  890. // or via the constructor
  891. var mc = new Ext.util.MixedCollection(false, function(el){
  892.    return el.dom.id;
  893. });
  894. mc.add(someEl);
  895. mc.add(otherEl);
  896. </code></pre>
  897.  * @param {Object} item The item for which to find the key.
  898.  * @return {Object} The key for the passed item.
  899.  */
  900.     getKey : function(o){
  901.          return o.id;
  902.     },
  903. /**
  904.  * Replaces an item in the collection. Fires the {@link #replace} event when complete.
  905.  * @param {String} key <p>The key associated with the item to replace, or the replacement item.</p>
  906.  * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key
  907.  * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection
  908.  * will be able to <i>derive</i> the key of the replacement item. If you want to replace an item
  909.  * with one having the same key value, then just pass the replacement item in this parameter.</p>
  910.  * @param o {Object} o (optional) If the first parameter passed was a key, the item to associate
  911.  * with that key.
  912.  * @return {Object}  The new item.
  913.  */
  914.     replace : function(key, o){
  915.         if(arguments.length == 1){
  916.             o = arguments[0];
  917.             key = this.getKey(o);
  918.         }
  919.         var old = this.map[key];
  920.         if(typeof key == "undefined" || key === null || typeof old == "undefined"){
  921.              return this.add(key, o);
  922.         }
  923.         var index = this.indexOfKey(key);
  924.         this.items[index] = o;
  925.         this.map[key] = o;
  926.         this.fireEvent("replace", key, old, o);
  927.         return o;
  928.     },
  929. /**
  930.  * Adds all elements of an Array or an Object to the collection.
  931.  * @param {Object/Array} objs An Object containing properties which will be added to the collection, or
  932.  * an Array of values, each of which are added to the collection.
  933.  */
  934.     addAll : function(objs){
  935.         if(arguments.length > 1 || Ext.isArray(objs)){
  936.             var args = arguments.length > 1 ? arguments : objs;
  937.             for(var i = 0, len = args.length; i < len; i++){
  938.                 this.add(args[i]);
  939.             }
  940.         }else{
  941.             for(var key in objs){
  942.                 if(this.allowFunctions || typeof objs[key] != "function"){
  943.                     this.add(key, objs[key]);
  944.                 }
  945.             }
  946.         }
  947.     },
  948. /**
  949.  * Executes the specified function once for every item in the collection, passing the following arguments:
  950.  * <div class="mdetail-params"><ul>
  951.  * <li><b>item</b> : Mixed<p class="sub-desc">The collection item</p></li>
  952.  * <li><b>index</b> : Number<p class="sub-desc">The item's index</p></li>
  953.  * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the collection</p></li>
  954.  * </ul></div>
  955.  * The function should return a boolean value. Returning false from the function will stop the iteration.
  956.  * @param {Function} fn The function to execute for each item.
  957.  * @param {Object} scope (optional) The scope in which to execute the function.
  958.  */
  959.     each : function(fn, scope){
  960.         var items = [].concat(this.items); // each safe for removal
  961.         for(var i = 0, len = items.length; i < len; i++){
  962.             if(fn.call(scope || items[i], items[i], i, len) === false){
  963.                 break;
  964.             }
  965.         }
  966.     },
  967. /**
  968.  * Executes the specified function once for every key in the collection, passing each
  969.  * key, and its associated item as the first two parameters.
  970.  * @param {Function} fn The function to execute for each item.
  971.  * @param {Object} scope (optional) The scope in which to execute the function.
  972.  */
  973.     eachKey : function(fn, scope){
  974.         for(var i = 0, len = this.keys.length; i < len; i++){
  975.             fn.call(scope || window, this.keys[i], this.items[i], i, len);
  976.         }
  977.     },
  978.     /**
  979.      * Returns the first item in the collection which elicits a true return value from the
  980.      * passed selection function.
  981.      * @param {Function} fn The selection function to execute for each item.
  982.      * @param {Object} scope (optional) The scope in which to execute the function.
  983.      * @return {Object} The first item in the collection which returned true from the selection function.
  984.      */
  985.     find : function(fn, scope){
  986.         for(var i = 0, len = this.items.length; i < len; i++){
  987.             if(fn.call(scope || window, this.items[i], this.keys[i])){
  988.                 return this.items[i];
  989.             }
  990.         }
  991.         return null;
  992.     },
  993. /**
  994.  * Inserts an item at the specified index in the collection. Fires the {@link #add} event when complete.
  995.  * @param {Number} index The index to insert the item at.
  996.  * @param {String} key The key to associate with the new item, or the item itself.
  997.  * @param {Object} o (optional) If the second parameter was a key, the new item.
  998.  * @return {Object} The item inserted.
  999.  */
  1000.     insert : function(index, key, o){
  1001.         if(arguments.length == 2){
  1002.             o = arguments[1];
  1003.             key = this.getKey(o);
  1004.         }
  1005.         if(this.containsKey(key)){
  1006.             this.suspendEvents();
  1007.             this.removeKey(key);
  1008.             this.resumeEvents();
  1009.         }
  1010.         if(index >= this.length){
  1011.             return this.add(key, o);
  1012.         }
  1013.         this.length++;
  1014.         this.items.splice(index, 0, o);
  1015.         if(typeof key != "undefined" && key !== null){
  1016.             this.map[key] = o;
  1017.         }
  1018.         this.keys.splice(index, 0, key);
  1019.         this.fireEvent("add", index, o, key);
  1020.         return o;
  1021.     },
  1022. /**
  1023.  * Remove an item from the collection.
  1024.  * @param {Object} o The item to remove.
  1025.  * @return {Object} The item removed or false if no item was removed.
  1026.  */
  1027.     remove : function(o){
  1028.         return this.removeAt(this.indexOf(o));
  1029.     },
  1030. /**
  1031.  * Remove an item from a specified index in the collection. Fires the {@link #remove} event when complete.
  1032.  * @param {Number} index The index within the collection of the item to remove.
  1033.  * @return {Object} The item removed or false if no item was removed.
  1034.  */
  1035.     removeAt : function(index){
  1036.         if(index < this.length && index >= 0){
  1037.             this.length--;
  1038.             var o = this.items[index];
  1039.             this.items.splice(index, 1);
  1040.             var key = this.keys[index];
  1041.             if(typeof key != "undefined"){
  1042.                 delete this.map[key];
  1043.             }
  1044.             this.keys.splice(index, 1);
  1045.             this.fireEvent("remove", o, key);
  1046.             return o;
  1047.         }
  1048.         return false;
  1049.     },
  1050. /**
  1051.  * Removed an item associated with the passed key fom the collection.
  1052.  * @param {String} key The key of the item to remove.
  1053.  * @return {Object} The item removed or false if no item was removed.
  1054.  */
  1055.     removeKey : function(key){
  1056.         return this.removeAt(this.indexOfKey(key));
  1057.     },
  1058. /**
  1059.  * Returns the number of items in the collection.
  1060.  * @return {Number} the number of items in the collection.
  1061.  */
  1062.     getCount : function(){
  1063.         return this.length;
  1064.     },
  1065. /**
  1066.  * Returns index within the collection of the passed Object.
  1067.  * @param {Object} o The item to find the index of.
  1068.  * @return {Number} index of the item. Returns -1 if not found.
  1069.  */
  1070.     indexOf : function(o){
  1071.         return this.items.indexOf(o);
  1072.     },
  1073. /**
  1074.  * Returns index within the collection of the passed key.
  1075.  * @param {String} key The key to find the index of.
  1076.  * @return {Number} index of the key.
  1077.  */
  1078.     indexOfKey : function(key){
  1079.         return this.keys.indexOf(key);
  1080.     },
  1081. /**
  1082.  * Returns the item associated with the passed key OR index. Key has priority over index.  This is the equivalent
  1083.  * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.
  1084.  * @param {String/Number} key The key or index of the item.
  1085.  * @return {Object} If the item is found, returns the item.  If the item was not found, returns <tt>undefined</tt>.
  1086.  * If an item was found, but is a Class, returns <tt>null</tt>.
  1087.  */
  1088.     item : function(key){
  1089.         var mk = this.map[key],
  1090.             item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
  1091.         return !Ext.isFunction(item) || this.allowFunctions ? item : null; // for prototype!
  1092.     },
  1093. /**
  1094.  * Returns the item at the specified index.
  1095.  * @param {Number} index The index of the item.
  1096.  * @return {Object} The item at the specified index.
  1097.  */
  1098.     itemAt : function(index){
  1099.         return this.items[index];
  1100.     },
  1101. /**
  1102.  * Returns the item associated with the passed key.
  1103.  * @param {String/Number} key The key of the item.
  1104.  * @return {Object} The item associated with the passed key.
  1105.  */
  1106.     key : function(key){
  1107.         return this.map[key];
  1108.     },
  1109. /**
  1110.  * Returns true if the collection contains the passed Object as an item.
  1111.  * @param {Object} o  The Object to look for in the collection.
  1112.  * @return {Boolean} True if the collection contains the Object as an item.
  1113.  */
  1114.     contains : function(o){
  1115.         return this.indexOf(o) != -1;
  1116.     },
  1117. /**
  1118.  * Returns true if the collection contains the passed Object as a key.
  1119.  * @param {String} key The key to look for in the collection.
  1120.  * @return {Boolean} True if the collection contains the Object as a key.
  1121.  */
  1122.     containsKey : function(key){
  1123.         return typeof this.map[key] != "undefined";
  1124.     },
  1125. /**
  1126.  * Removes all items from the collection.  Fires the {@link #clear} event when complete.
  1127.  */
  1128.     clear : function(){
  1129.         this.length = 0;
  1130.         this.items = [];
  1131.         this.keys = [];
  1132.         this.map = {};
  1133.         this.fireEvent("clear");
  1134.     },
  1135. /**
  1136.  * Returns the first item in the collection.
  1137.  * @return {Object} the first item in the collection..
  1138.  */
  1139.     first : function(){
  1140.         return this.items[0];
  1141.     },
  1142. /**
  1143.  * Returns the last item in the collection.
  1144.  * @return {Object} the last item in the collection..
  1145.  */
  1146.     last : function(){
  1147.         return this.items[this.length-1];
  1148.     },
  1149.     // private
  1150.     _sort : function(property, dir, fn){
  1151.         var i,
  1152.             len,
  1153.             dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1,
  1154.             c = [], k = this.keys, items = this.items;
  1155.             
  1156.         fn = fn || function(a, b){
  1157.             return a-b;
  1158.         };
  1159.         for(i = 0, len = items.length; i < len; i++){
  1160.             c[c.length] = {key: k[i], value: items[i], index: i};
  1161.         }
  1162.         c.sort(function(a, b){
  1163.             var v = fn(a[property], b[property]) * dsc;
  1164.             if(v === 0){
  1165.                 v = (a.index < b.index ? -1 : 1);
  1166.             }
  1167.             return v;
  1168.         });
  1169.         for(i = 0, len = c.length; i < len; i++){
  1170.             items[i] = c[i].value;
  1171.             k[i] = c[i].key;
  1172.         }
  1173.         this.fireEvent("sort", this);
  1174.     },
  1175.     /**
  1176.      * Sorts this collection with the passed comparison function
  1177.      * @param {String} direction (optional) "ASC" or "DESC"
  1178.      * @param {Function} fn (optional) comparison function
  1179.      */
  1180.     sort : function(dir, fn){
  1181.         this._sort("value", dir, fn);
  1182.     },
  1183.     /**
  1184.      * Sorts this collection by keys
  1185.      * @param {String} direction (optional) "ASC" or "DESC"
  1186.      * @param {Function} fn (optional) a comparison function (defaults to case insensitive string)
  1187.      */
  1188.     keySort : function(dir, fn){
  1189.         this._sort("key", dir, fn || function(a, b){
  1190.             var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
  1191.             return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
  1192.         });
  1193.     },
  1194.     /**
  1195.      * Returns a range of items in this collection
  1196.      * @param {Number} startIndex (optional) defaults to 0
  1197.      * @param {Number} endIndex (optional) default to the last item
  1198.      * @return {Array} An array of items
  1199.      */
  1200.     getRange : function(start, end){
  1201.         var items = this.items;
  1202.         if(items.length < 1){
  1203.             return [];
  1204.         }
  1205.         start = start || 0;
  1206.         end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);
  1207.         var i, r = [];
  1208.         if(start <= end){
  1209.             for(i = start; i <= end; i++) {
  1210.                 r[r.length] = items[i];
  1211.             }
  1212.         }else{
  1213.             for(i = start; i >= end; i--) {
  1214.                 r[r.length] = items[i];
  1215.             }
  1216.         }
  1217.         return r;
  1218.     },
  1219.     /**
  1220.      * Filter the <i>objects</i> in this collection by a specific property.
  1221.      * Returns a new collection that has been filtered.
  1222.      * @param {String} property A property on your objects
  1223.      * @param {String/RegExp} value Either string that the property values
  1224.      * should start with or a RegExp to test against the property
  1225.      * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning
  1226.      * @param {Boolean} caseSensitive (optional) True for case sensitive comparison (defaults to False).
  1227.      * @return {MixedCollection} The new filtered collection
  1228.      */
  1229.     filter : function(property, value, anyMatch, caseSensitive){
  1230.         if(Ext.isEmpty(value, false)){
  1231.             return this.clone();
  1232.         }
  1233.         value = this.createValueMatcher(value, anyMatch, caseSensitive);
  1234.         return this.filterBy(function(o){
  1235.             return o && value.test(o[property]);
  1236.         });
  1237.     },
  1238.     /**
  1239.      * Filter by a function. Returns a <i>new</i> collection that has been filtered.
  1240.      * The passed function will be called with each object in the collection.
  1241.      * If the function returns true, the value is included otherwise it is filtered.
  1242.      * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key)
  1243.      * @param {Object} scope (optional) The scope of the function (defaults to this)
  1244.      * @return {MixedCollection} The new filtered collection
  1245.      */
  1246.     filterBy : function(fn, scope){
  1247.         var r = new Ext.util.MixedCollection();
  1248.         r.getKey = this.getKey;
  1249.         var k = this.keys, it = this.items;
  1250.         for(var i = 0, len = it.length; i < len; i++){
  1251.             if(fn.call(scope||this, it[i], k[i])){
  1252.                 r.add(k[i], it[i]);
  1253.             }
  1254.         }
  1255.         return r;
  1256.     },
  1257.     /**
  1258.      * Finds the index of the first matching object in this collection by a specific property/value.
  1259.      * @param {String} property The name of a property on your objects.
  1260.      * @param {String/RegExp} value A string that the property values
  1261.      * should start with or a RegExp to test against the property.
  1262.      * @param {Number} start (optional) The index to start searching at (defaults to 0).
  1263.      * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning.
  1264.      * @param {Boolean} caseSensitive (optional) True for case sensitive comparison.
  1265.      * @return {Number} The matched index or -1
  1266.      */
  1267.     findIndex : function(property, value, start, anyMatch, caseSensitive){
  1268.         if(Ext.isEmpty(value, false)){
  1269.             return -1;
  1270.         }
  1271.         value = this.createValueMatcher(value, anyMatch, caseSensitive);
  1272.         return this.findIndexBy(function(o){
  1273.             return o && value.test(o[property]);
  1274.         }, null, start);
  1275.     },
  1276.     /**
  1277.      * Find the index of the first matching object in this collection by a function.
  1278.      * If the function returns <i>true</i> it is considered a match.
  1279.      * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key).
  1280.      * @param {Object} scope (optional) The scope of the function (defaults to this).
  1281.      * @param {Number} start (optional) The index to start searching at (defaults to 0).
  1282.      * @return {Number} The matched index or -1
  1283.      */
  1284.     findIndexBy : function(fn, scope, start){
  1285.         var k = this.keys, it = this.items;
  1286.         for(var i = (start||0), len = it.length; i < len; i++){
  1287.             if(fn.call(scope||this, it[i], k[i])){
  1288.                 return i;
  1289.             }
  1290.         }
  1291.         return -1;
  1292.     },
  1293.     // private
  1294.     createValueMatcher : function(value, anyMatch, caseSensitive){
  1295.         if(!value.exec){ // not a regex
  1296.             value = String(value);
  1297.             value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');
  1298.         }
  1299.         return value;
  1300.     },
  1301.     /**
  1302.      * Creates a shallow copy of this collection
  1303.      * @return {MixedCollection}
  1304.      */
  1305.     clone : function(){
  1306.         var r = new Ext.util.MixedCollection();
  1307.         var k = this.keys, it = this.items;
  1308.         for(var i = 0, len = it.length; i < len; i++){
  1309.             r.add(k[i], it[i]);
  1310.         }
  1311.         r.getKey = this.getKey;
  1312.         return r;
  1313.     }
  1314. });
  1315. /**
  1316.  * This method calls {@link #item item()}.
  1317.  * Returns the item associated with the passed key OR index. Key has priority over index.  This is the equivalent
  1318.  * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.
  1319.  * @param {String/Number} key The key or index of the item.
  1320.  * @return {Object} If the item is found, returns the item.  If the item was not found, returns <tt>undefined</tt>.
  1321.  * If an item was found, but is a Class, returns <tt>null</tt>.
  1322.  */
  1323. Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;/**  * @class Ext.util.JSON  * Modified version of Douglas Crockford"s json.js that doesn"t  * mess with the Object prototype  * http://www.json.org/js.html  * @singleton  */ Ext.util.JSON = new (function(){     var useHasOwn = !!{}.hasOwnProperty,         isNative = function() {             var useNative = null;             return function() {                 if (useNative === null) {                     useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';                 }                          return useNative;             };         }(),         pad = function(n) {             return n < 10 ? "0" + n : n;         },         doDecode = function(json){             return eval("(" + json + ')');             },         doEncode = function(o){             if(typeof o == "undefined" || o === null){                 return "null";             }else if(Ext.isArray(o)){                 return encodeArray(o);             }else if(Object.prototype.toString.apply(o) === '[object Date]'){                 return Ext.util.JSON.encodeDate(o);             }else if(typeof o == "string"){                 return encodeString(o);             }else if(typeof o == "number"){                 return isFinite(o) ? String(o) : "null";             }else if(typeof o == "boolean"){                 return String(o);             }else {                 var a = ["{"], b, i, v;                 for (i in o) {                     if(!useHasOwn || o.hasOwnProperty(i)) {                         v = o[i];                         switch (typeof v) {                         case "undefined":                         case "function":                         case "unknown":                             break;                         default:                             if(b){                                 a.push(',');                             }                             a.push(doEncode(i), ":",                                     v === null ? "null" : doEncode(v));                             b = true;                         }                     }                 }                 a.push("}");                 return a.join("");             }             },         m = {             "b": '\b',             "t": '\t',             "n": '\n',             "f": '\f',             "r": '\r',             '"' : '\"',             "\": '\\'         },         encodeString = function(s){             if (/["\x00-x1f]/.test(s)) {                 return '"' + s.replace(/([x00-x1f\"])/g, function(a, b) {                     var c = m[b];                     if(c){                         return c;                     }                     c = b.charCodeAt();                     return "\u00" +                         Math.floor(c / 16).toString(16) +                         (c % 16).toString(16);                 }) + '"';             }             return '"' + s + '"';         },         encodeArray = function(o){             var a = ["["], b, i, l = o.length, v;                 for (i = 0; i < l; i += 1) {                     v = o[i];                     switch (typeof v) {                         case "undefined":                         case "function":                         case "unknown":                             break;                         default:                             if (b) {                                 a.push(',');                             }                             a.push(v === null ? "null" : Ext.util.JSON.encode(v));                             b = true;                     }                 }                 a.push("]");                 return a.join("");         };     this.encodeDate = function(o){         return '"' + o.getFullYear() + "-" +                 pad(o.getMonth() + 1) + "-" +                 pad(o.getDate()) + "T" +                 pad(o.getHours()) + ":" +                 pad(o.getMinutes()) + ":" +                 pad(o.getSeconds()) + '"';     };     /**      * Encodes an Object, Array or other value      * @param {Mixed} o The variable to encode      * @return {String} The JSON string      */     this.encode = function() {         var ec;         return function(o) {             if (!ec) {                 // setup encoding function on first access                 ec = isNative() ? JSON.stringify : doEncode;             }             return ec(o);         };     }();     /**      * Decodes (parses) a JSON string to an object. If the JSON is invalid, this function throws a SyntaxError unless the safe option is set.      * @param {String} json The JSON string      * @return {Object} The resulting object      */     this.decode = function() {         var dc;         return function(json) {             if (!dc) {                 // setup decoding function on first access                 dc = isNative() ? JSON.parse : doDecode;             }             return dc(json);         };     }(); })(); /**  * Shorthand for {@link Ext.util.JSON#encode}  * @param {Mixed} o The variable to encode  * @return {String} The JSON string  * @member Ext  * @method encode  */ Ext.encode = Ext.util.JSON.encode; /**  * Shorthand for {@link Ext.util.JSON#decode}  * @param {String} json The JSON string  * @param {Boolean} safe (optional) Whether to return null or throw an exception if the JSON is invalid.  * @return {Object} The resulting object  * @member Ext  * @method decode  */ Ext.decode = Ext.util.JSON.decode; /**
  1324.  * @class Ext.util.Format
  1325.  * Reusable data formatting functions
  1326.  * @singleton
  1327.  */
  1328. Ext.util.Format = function(){
  1329.     var trimRe = /^s+|s+$/g;
  1330.     return {
  1331.         /**
  1332.          * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length
  1333.          * @param {String} value The string to truncate
  1334.          * @param {Number} length The maximum length to allow before truncating
  1335.          * @param {Boolean} word True to try to find a common work break
  1336.          * @return {String} The converted text
  1337.          */
  1338.         ellipsis : function(value, len, word){
  1339.             if(value && value.length > len){
  1340.                 if(word){
  1341.                     var vs = value.substr(0, len - 2);
  1342.                     var index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
  1343.                     if(index == -1 || index < (len - 15)){
  1344.                         return value.substr(0, len - 3) + "...";
  1345.                     }else{
  1346.                         return vs.substr(0, index) + "...";
  1347.                     }
  1348.                 } else{
  1349.                     return value.substr(0, len - 3) + "...";
  1350.                 }
  1351.             }
  1352.             return value;
  1353.         },
  1354.         /**
  1355.          * Checks a reference and converts it to empty string if it is undefined
  1356.          * @param {Mixed} value Reference to check
  1357.          * @return {Mixed} Empty string if converted, otherwise the original value
  1358.          */
  1359.         undef : function(value){
  1360.             return value !== undefined ? value : "";
  1361.         },
  1362.         /**
  1363.          * Checks a reference and converts it to the default value if it's empty
  1364.          * @param {Mixed} value Reference to check
  1365.          * @param {String} defaultValue The value to insert of it's undefined (defaults to "")
  1366.          * @return {String}
  1367.          */
  1368.         defaultValue : function(value, defaultValue){
  1369.             return value !== undefined && value !== '' ? value : defaultValue;
  1370.         },
  1371.         /**
  1372.          * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
  1373.          * @param {String} value The string to encode
  1374.          * @return {String} The encoded text
  1375.          */
  1376.         htmlEncode : function(value){
  1377.             return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
  1378.         },
  1379.         /**
  1380.          * Convert certain characters (&, <, >, and ') from their HTML character equivalents.
  1381.          * @param {String} value The string to decode
  1382.          * @return {String} The decoded text
  1383.          */
  1384.         htmlDecode : function(value){
  1385.             return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
  1386.         },
  1387.         /**
  1388.          * Trims any whitespace from either side of a string
  1389.          * @param {String} value The text to trim
  1390.          * @return {String} The trimmed text
  1391.          */
  1392.         trim : function(value){
  1393.             return String(value).replace(trimRe, "");
  1394.         },
  1395.         /**
  1396.          * Returns a substring from within an original string
  1397.          * @param {String} value The original text
  1398.          * @param {Number} start The start index of the substring
  1399.          * @param {Number} length The length of the substring
  1400.          * @return {String} The substring
  1401.          */
  1402.         substr : function(value, start, length){
  1403.             return String(value).substr(start, length);
  1404.         },
  1405.         /**
  1406.          * Converts a string to all lower case letters
  1407.          * @param {String} value The text to convert
  1408.          * @return {String} The converted text
  1409.          */
  1410.         lowercase : function(value){
  1411.             return String(value).toLowerCase();
  1412.         },
  1413.         /**
  1414.          * Converts a string to all upper case letters
  1415.          * @param {String} value The text to convert
  1416.          * @return {String} The converted text
  1417.          */
  1418.         uppercase : function(value){
  1419.             return String(value).toUpperCase();
  1420.         },
  1421.         /**
  1422.          * Converts the first character only of a string to upper case
  1423.          * @param {String} value The text to convert
  1424.          * @return {String} The converted text
  1425.          */
  1426.         capitalize : function(value){
  1427.             return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
  1428.         },
  1429.         // private
  1430.         call : function(value, fn){
  1431.             if(arguments.length > 2){
  1432.                 var args = Array.prototype.slice.call(arguments, 2);
  1433.                 args.unshift(value);
  1434.                 return eval(fn).apply(window, args);
  1435.             }else{
  1436.                 return eval(fn).call(window, value);
  1437.             }
  1438.         },
  1439.         /**
  1440.          * Format a number as US currency
  1441.          * @param {Number/String} value The numeric value to format
  1442.          * @return {String} The formatted currency string
  1443.          */
  1444.         usMoney : function(v){
  1445.             v = (Math.round((v-0)*100))/100;
  1446.             v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
  1447.             v = String(v);
  1448.             var ps = v.split('.');
  1449.             var whole = ps[0];
  1450.             var sub = ps[1] ? '.'+ ps[1] : '.00';
  1451.             var r = /(d+)(d{3})/;
  1452.             while (r.test(whole)) {
  1453.                 whole = whole.replace(r, '$1' + ',' + '$2');
  1454.             }
  1455.             v = whole + sub;
  1456.             if(v.charAt(0) == '-'){
  1457.                 return '-$' + v.substr(1);
  1458.             }
  1459.             return "$" +  v;
  1460.         },
  1461.         /**
  1462.          * Parse a value into a formatted date using the specified format pattern.
  1463.          * @param {String/Date} value The value to format (Strings must conform to the format expected by the javascript Date object's <a href="http://www.w3schools.com/jsref/jsref_parse.asp">parse()</a> method)
  1464.          * @param {String} format (optional) Any valid date format string (defaults to 'm/d/Y')
  1465.          * @return {String} The formatted date string
  1466.          */
  1467.         date : function(v, format){
  1468.             if(!v){
  1469.                 return "";
  1470.             }
  1471.             if(!Ext.isDate(v)){
  1472.                 v = new Date(Date.parse(v));
  1473.             }
  1474.             return v.dateFormat(format || "m/d/Y");
  1475.         },
  1476.         /**
  1477.          * Returns a date rendering function that can be reused to apply a date format multiple times efficiently
  1478.          * @param {String} format Any valid date format string
  1479.          * @return {Function} The date formatting function
  1480.          */
  1481.         dateRenderer : function(format){
  1482.             return function(v){
  1483.                 return Ext.util.Format.date(v, format);
  1484.             };
  1485.         },
  1486.         // private
  1487.         stripTagsRE : /</?[^>]+>/gi,
  1488.         
  1489.         /**
  1490.          * Strips all HTML tags
  1491.          * @param {Mixed} value The text from which to strip tags
  1492.          * @return {String} The stripped text
  1493.          */
  1494.         stripTags : function(v){
  1495.             return !v ? v : String(v).replace(this.stripTagsRE, "");
  1496.         },
  1497.         stripScriptsRe : /(?:<script.*?>)((n|r|.)*?)(?:</script>)/ig,
  1498.         /**
  1499.          * Strips all script tags
  1500.          * @param {Mixed} value The text from which to strip script tags
  1501.          * @return {String} The stripped text
  1502.          */
  1503.         stripScripts : function(v){
  1504.             return !v ? v : String(v).replace(this.stripScriptsRe, "");
  1505.         },
  1506.         /**
  1507.          * Simple format for a file size (xxx bytes, xxx KB, xxx MB)
  1508.          * @param {Number/String} size The numeric value to format
  1509.          * @return {String} The formatted file size
  1510.          */
  1511.         fileSize : function(size){
  1512.             if(size < 1024) {
  1513.                 return size + " bytes";
  1514.             } else if(size < 1048576) {
  1515.                 return (Math.round(((size*10) / 1024))/10) + " KB";
  1516.             } else {
  1517.                 return (Math.round(((size*10) / 1048576))/10) + " MB";
  1518.             }
  1519.         },
  1520.         /**
  1521.          * It does simple math for use in a template, for example:<pre><code>
  1522.          * var tpl = new Ext.Template('{value} * 10 = {value:math("* 10")}');
  1523.          * </code></pre>
  1524.          * @return {Function} A function that operates on the passed value.
  1525.          */
  1526.         math : function(){
  1527.             var fns = {};
  1528.             return function(v, a){
  1529.                 if(!fns[a]){
  1530.                     fns[a] = new Function('v', 'return v ' + a + ';');
  1531.                 }
  1532.                 return fns[a](v);
  1533.             }
  1534.         }(),
  1535.         /**
  1536.          * Rounds the passed number to the required decimal precision.
  1537.          * @param {Number/String} value The numeric value to round.
  1538.          * @param {Number} precision The number of decimal places to which to round the first parameter's value.
  1539.          * @return {Number} The rounded value.
  1540.          */
  1541.         round : function(value, precision) {
  1542.             var result = Number(value);
  1543.             if (typeof precision == 'number') {
  1544.                 precision = Math.pow(10, precision);
  1545.                 result = Math.round(value * precision) / precision;
  1546.             }
  1547.             return result;
  1548.         },
  1549.         /**
  1550.          * Formats the number according to the format string.
  1551.          * <div style="margin-left:40px">examples (123456.789):
  1552.          * <div style="margin-left:10px">
  1553.          * 0 - (123456) show only digits, no precision<br>
  1554.          * 0.00 - (123456.78) show only digits, 2 precision<br>
  1555.          * 0.0000 - (123456.7890) show only digits, 4 precision<br>
  1556.          * 0,000 - (123,456) show comma and digits, no precision<br>
  1557.          * 0,000.00 - (123,456.78) show comma and digits, 2 precision<br>
  1558.          * 0,0.00 - (123,456.78) shortcut method, show comma and digits, 2 precision<br>
  1559.          * To reverse the grouping (,) and decimal (.) for international numbers, add /i to the end.
  1560.          * For example: 0.000,00/i
  1561.          * </div></div>