commit extjs-2.2.1
[extjs.git] / source / adapter / ext-base.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 (function() {\r
10     var libFlyweight;\r
11 \r
12     Ext.lib.Dom = {\r
13         getViewWidth : function(full) {\r
14             return full ? this.getDocumentWidth() : this.getViewportWidth();\r
15         },\r
16 \r
17         getViewHeight : function(full) {\r
18             return full ? this.getDocumentHeight() : this.getViewportHeight();\r
19         },\r
20 \r
21         getDocumentHeight: function() {\r
22             var scrollHeight = (document.compatMode != "CSS1Compat") ? document.body.scrollHeight : document.documentElement.scrollHeight;\r
23             return Math.max(scrollHeight, this.getViewportHeight());\r
24         },\r
25 \r
26         getDocumentWidth: function() {\r
27             var scrollWidth = (document.compatMode != "CSS1Compat") ? document.body.scrollWidth : document.documentElement.scrollWidth;\r
28             return Math.max(scrollWidth, this.getViewportWidth());\r
29         },\r
30 \r
31         getViewportHeight: function(){\r
32             if(Ext.isIE){\r
33                 return Ext.isStrict ? document.documentElement.clientHeight :\r
34                          document.body.clientHeight;\r
35             }else{\r
36                 return self.innerHeight;\r
37             }\r
38         },\r
39 \r
40         getViewportWidth: function() {\r
41             if(Ext.isIE){\r
42                 return Ext.isStrict ? document.documentElement.clientWidth :\r
43                          document.body.clientWidth;\r
44             }else{\r
45                 return self.innerWidth;\r
46             }\r
47         },\r
48 \r
49         isAncestor : function(p, c) {\r
50             p = Ext.getDom(p);\r
51             c = Ext.getDom(c);\r
52             if (!p || !c) {\r
53                 return false;\r
54             }\r
55 \r
56             if (p.contains && !Ext.isSafari) {\r
57                 return p.contains(c);\r
58             } else if (p.compareDocumentPosition) {\r
59                 return !!(p.compareDocumentPosition(c) & 16);\r
60             } else {\r
61                 var parent = c.parentNode;\r
62                 while (parent) {\r
63                     if (parent == p) {\r
64                         return true;\r
65                     }\r
66                     else if (!parent.tagName || parent.tagName.toUpperCase() == "HTML") {\r
67                         return false;\r
68                     }\r
69                     parent = parent.parentNode;\r
70                 }\r
71                 return false;\r
72             }\r
73         },\r
74 \r
75         getRegion : function(el) {\r
76             return Ext.lib.Region.getRegion(el);\r
77         },\r
78 \r
79         getY : function(el) {\r
80             return this.getXY(el)[1];\r
81         },\r
82 \r
83         getX : function(el) {\r
84             return this.getXY(el)[0];\r
85         },\r
86 \r
87 \r
88         getXY : function(el) {\r
89             var p, pe, b, scroll, bd = (document.body || document.documentElement);\r
90             el = Ext.getDom(el);\r
91 \r
92             if(el == bd){\r
93                 return [0, 0];\r
94             }\r
95 \r
96             if (el.getBoundingClientRect) {\r
97                 b = el.getBoundingClientRect();\r
98                 scroll = fly(document).getScroll();\r
99                 return [b.left + scroll.left, b.top + scroll.top];\r
100             }\r
101             var x = 0, y = 0;\r
102 \r
103             p = el;\r
104 \r
105             var hasAbsolute = fly(el).getStyle("position") == "absolute";\r
106 \r
107             while (p) {\r
108 \r
109                 x += p.offsetLeft;\r
110                 y += p.offsetTop;\r
111 \r
112                 if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {\r
113                     hasAbsolute = true;\r
114                 }\r
115 \r
116                 if (Ext.isGecko) {\r
117                     pe = fly(p);\r
118 \r
119                     var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;\r
120                     var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;\r
121 \r
122 \r
123                     x += bl;\r
124                     y += bt;\r
125 \r
126 \r
127                     if (p != el && pe.getStyle('overflow') != 'visible') {\r
128                         x += bl;\r
129                         y += bt;\r
130                     }\r
131                 }\r
132                 p = p.offsetParent;\r
133             }\r
134 \r
135             if (Ext.isSafari && hasAbsolute) {\r
136                 x -= bd.offsetLeft;\r
137                 y -= bd.offsetTop;\r
138             }\r
139 \r
140             if (Ext.isGecko && !hasAbsolute) {\r
141                 var dbd = fly(bd);\r
142                 x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;\r
143                 y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;\r
144             }\r
145 \r
146             p = el.parentNode;\r
147             while (p && p != bd) {\r
148                 if (!Ext.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {\r
149                     x -= p.scrollLeft;\r
150                     y -= p.scrollTop;\r
151                 }\r
152                 p = p.parentNode;\r
153             }\r
154             return [x, y];\r
155         },\r
156 \r
157         setXY : function(el, xy) {\r
158             el = Ext.fly(el, '_setXY');\r
159             el.position();\r
160             var pts = el.translatePoints(xy);\r
161             if (xy[0] !== false) {\r
162                 el.dom.style.left = pts.left + "px";\r
163             }\r
164             if (xy[1] !== false) {\r
165                 el.dom.style.top = pts.top + "px";\r
166             }\r
167         },\r
168 \r
169         setX : function(el, x) {\r
170             this.setXY(el, [x, false]);\r
171         },\r
172 \r
173         setY : function(el, y) {\r
174             this.setXY(el, [false, y]);\r
175         }\r
176     };\r
177 \r
178 /*\r
179  * Portions of this file are based on pieces of Yahoo User Interface Library\r
180  * Copyright (c) 2007, Yahoo! Inc. All rights reserved.\r
181  * YUI licensed under the BSD License:\r
182  * http://developer.yahoo.net/yui/license.txt\r
183  */\r
184     Ext.lib.Event = function() {\r
185         var loadComplete = false;\r
186         var listeners = [];\r
187         var unloadListeners = [];\r
188         var retryCount = 0;\r
189         var onAvailStack = [];\r
190         var counter = 0;\r
191         var lastError = null;\r
192 \r
193         return {\r
194             POLL_RETRYS: 200,\r
195             POLL_INTERVAL: 20,\r
196             EL: 0,\r
197             TYPE: 1,\r
198             FN: 2,\r
199             WFN: 3,\r
200             OBJ: 3,\r
201             ADJ_SCOPE: 4,\r
202             _interval: null,\r
203 \r
204             startInterval: function() {\r
205                 if (!this._interval) {\r
206                     var self = this;\r
207                     var callback = function() {\r
208                         self._tryPreloadAttach();\r
209                     };\r
210                     this._interval = setInterval(callback, this.POLL_INTERVAL);\r
211 \r
212                 }\r
213             },\r
214 \r
215             onAvailable: function(p_id, p_fn, p_obj, p_override) {\r
216                 onAvailStack.push({ id:         p_id,\r
217                     fn:         p_fn,\r
218                     obj:        p_obj,\r
219                     override:   p_override,\r
220                     checkReady: false    });\r
221 \r
222                 retryCount = this.POLL_RETRYS;\r
223                 this.startInterval();\r
224             },\r
225 \r
226 \r
227             addListener: function(el, eventName, fn) {\r
228                 el = Ext.getDom(el);\r
229                 if (!el || !fn) {\r
230                     return false;\r
231                 }\r
232 \r
233                 if ("unload" == eventName) {\r
234                     unloadListeners[unloadListeners.length] =\r
235                     [el, eventName, fn];\r
236                     return true;\r
237                 }\r
238 \r
239                 // prevent unload errors with simple check\r
240                 var wrappedFn = function(e) {\r
241                     return typeof Ext != 'undefined' ? fn(Ext.lib.Event.getEvent(e)) : false;\r
242                 };\r
243 \r
244                 var li = [el, eventName, fn, wrappedFn];\r
245 \r
246                 var index = listeners.length;\r
247                 listeners[index] = li;\r
248 \r
249                 this.doAdd(el, eventName, wrappedFn, false);\r
250                 return true;\r
251 \r
252             },\r
253 \r
254 \r
255             removeListener: function(el, eventName, fn) {\r
256                 var i, len;\r
257 \r
258                 el = Ext.getDom(el);\r
259 \r
260                 if(!fn) {\r
261                     return this.purgeElement(el, false, eventName);\r
262                 }\r
263 \r
264 \r
265                 if ("unload" == eventName) {\r
266 \r
267                     for (i = 0,len = unloadListeners.length; i < len; i++) {\r
268                         var li = unloadListeners[i];\r
269                         if (li &&\r
270                             li[0] == el &&\r
271                             li[1] == eventName &&\r
272                             li[2] == fn) {\r
273                             unloadListeners.splice(i, 1);\r
274                             return true;\r
275                         }\r
276                     }\r
277 \r
278                     return false;\r
279                 }\r
280 \r
281                 var cacheItem = null;\r
282 \r
283 \r
284                 var index = arguments[3];\r
285 \r
286                 if ("undefined" == typeof index) {\r
287                     index = this._getCacheIndex(el, eventName, fn);\r
288                 }\r
289 \r
290                 if (index >= 0) {\r
291                     cacheItem = listeners[index];\r
292                 }\r
293 \r
294                 if (!el || !cacheItem) {\r
295                     return false;\r
296                 }\r
297 \r
298                 this.doRemove(el, eventName, cacheItem[this.WFN], false);\r
299 \r
300                 delete listeners[index][this.WFN];\r
301                 delete listeners[index][this.FN];\r
302                 listeners.splice(index, 1);\r
303 \r
304                 return true;\r
305 \r
306             },\r
307 \r
308 \r
309             getTarget: function(ev, resolveTextNode) {\r
310                 ev = ev.browserEvent || ev;\r
311                 var t = ev.target || ev.srcElement;\r
312                 return this.resolveTextNode(t);\r
313             },\r
314 \r
315 \r
316             resolveTextNode: function(node) {\r
317                 if (Ext.isSafari && node && 3 == node.nodeType) {\r
318                     return node.parentNode;\r
319                 } else {\r
320                     return node;\r
321                 }\r
322             },\r
323 \r
324 \r
325             getPageX: function(ev) {\r
326                 ev = ev.browserEvent || ev;\r
327                 var x = ev.pageX;\r
328                 if (!x && 0 !== x) {\r
329                     x = ev.clientX || 0;\r
330 \r
331                     if (Ext.isIE) {\r
332                         x += this.getScroll()[1];\r
333                     }\r
334                 }\r
335 \r
336                 return x;\r
337             },\r
338 \r
339 \r
340             getPageY: function(ev) {\r
341                 ev = ev.browserEvent || ev;\r
342                 var y = ev.pageY;\r
343                 if (!y && 0 !== y) {\r
344                     y = ev.clientY || 0;\r
345 \r
346                     if (Ext.isIE) {\r
347                         y += this.getScroll()[0];\r
348                     }\r
349                 }\r
350 \r
351 \r
352                 return y;\r
353             },\r
354 \r
355 \r
356             getXY: function(ev) {\r
357                 ev = ev.browserEvent || ev;\r
358                 return [this.getPageX(ev), this.getPageY(ev)];\r
359             },\r
360 \r
361 \r
362             getRelatedTarget: function(ev) {\r
363                 ev = ev.browserEvent || ev;\r
364                 var t = ev.relatedTarget;\r
365                 if (!t) {\r
366                     if (ev.type == "mouseout") {\r
367                         t = ev.toElement;\r
368                     } else if (ev.type == "mouseover") {\r
369                         t = ev.fromElement;\r
370                     }\r
371                 }\r
372 \r
373                 return this.resolveTextNode(t);\r
374             },\r
375 \r
376 \r
377             getTime: function(ev) {\r
378                 ev = ev.browserEvent || ev;\r
379                 if (!ev.time) {\r
380                     var t = new Date().getTime();\r
381                     try {\r
382                         ev.time = t;\r
383                     } catch(ex) {\r
384                         this.lastError = ex;\r
385                         return t;\r
386                     }\r
387                 }\r
388 \r
389                 return ev.time;\r
390             },\r
391 \r
392 \r
393             stopEvent: function(ev) {\r
394                 this.stopPropagation(ev);\r
395                 this.preventDefault(ev);\r
396             },\r
397 \r
398 \r
399             stopPropagation: function(ev) {\r
400                 ev = ev.browserEvent || ev;\r
401                 if (ev.stopPropagation) {\r
402                     ev.stopPropagation();\r
403                 } else {\r
404                     ev.cancelBubble = true;\r
405                 }\r
406             },\r
407 \r
408 \r
409             preventDefault: function(ev) {\r
410                 ev = ev.browserEvent || ev;\r
411                 if(ev.preventDefault) {\r
412                     ev.preventDefault();\r
413                 } else {\r
414                     ev.returnValue = false;\r
415                 }\r
416             },\r
417 \r
418 \r
419             getEvent: function(e) {\r
420                 var ev = e || window.event;\r
421                 if (!ev) {\r
422                     var c = this.getEvent.caller;\r
423                     while (c) {\r
424                         ev = c.arguments[0];\r
425                         if (ev && Event == ev.constructor) {\r
426                             break;\r
427                         }\r
428                         c = c.caller;\r
429                     }\r
430                 }\r
431                 return ev;\r
432             },\r
433 \r
434 \r
435             getCharCode: function(ev) {\r
436                 ev = ev.browserEvent || ev;\r
437                 return ev.charCode || ev.keyCode || 0;\r
438             },\r
439 \r
440 \r
441             _getCacheIndex: function(el, eventName, fn) {\r
442                 for (var i = 0,len = listeners.length; i < len; ++i) {\r
443                     var li = listeners[i];\r
444                     if (li &&\r
445                         li[this.FN] == fn &&\r
446                         li[this.EL] == el &&\r
447                         li[this.TYPE] == eventName) {\r
448                         return i;\r
449                     }\r
450                 }\r
451 \r
452                 return -1;\r
453             },\r
454 \r
455 \r
456             elCache: {},\r
457 \r
458 \r
459             getEl: function(id) {\r
460                 return document.getElementById(id);\r
461             },\r
462 \r
463 \r
464             clearCache: function() {\r
465             },\r
466 \r
467 \r
468             _load: function(e) {\r
469                 loadComplete = true;\r
470                 var EU = Ext.lib.Event;\r
471 \r
472 \r
473                 if (Ext.isIE) {\r
474                     EU.doRemove(window, "load", EU._load);\r
475                 }\r
476             },\r
477 \r
478 \r
479             _tryPreloadAttach: function() {\r
480 \r
481                 if (this.locked) {\r
482                     return false;\r
483                 }\r
484 \r
485                 this.locked = true;\r
486 \r
487 \r
488                 var tryAgain = !loadComplete;\r
489                 if (!tryAgain) {\r
490                     tryAgain = (retryCount > 0);\r
491                 }\r
492 \r
493 \r
494                 var notAvail = [];\r
495                 for (var i = 0,len = onAvailStack.length; i < len; ++i) {\r
496                     var item = onAvailStack[i];\r
497                     if (item) {\r
498                         var el = this.getEl(item.id);\r
499 \r
500                         if (el) {\r
501                             if (!item.checkReady ||\r
502                                 loadComplete ||\r
503                                 el.nextSibling ||\r
504                                 (document && document.body)) {\r
505 \r
506                                 var scope = el;\r
507                                 if (item.override) {\r
508                                     if (item.override === true) {\r
509                                         scope = item.obj;\r
510                                     } else {\r
511                                         scope = item.override;\r
512                                     }\r
513                                 }\r
514                                 item.fn.call(scope, item.obj);\r
515                                 onAvailStack[i] = null;\r
516                             }\r
517                         } else {\r
518                             notAvail.push(item);\r
519                         }\r
520                     }\r
521                 }\r
522 \r
523                 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;\r
524 \r
525                 if (tryAgain) {\r
526 \r
527                     this.startInterval();\r
528                 } else {\r
529                     clearInterval(this._interval);\r
530                     this._interval = null;\r
531                 }\r
532 \r
533                 this.locked = false;\r
534 \r
535                 return true;\r
536 \r
537             },\r
538 \r
539 \r
540             purgeElement: function(el, recurse, eventName) {\r
541                 var elListeners = this.getListeners(el, eventName);\r
542                 if (elListeners) {\r
543                     for (var i = 0,len = elListeners.length; i < len; ++i) {\r
544                         var l = elListeners[i];\r
545                         this.removeListener(el, l.type, l.fn);\r
546                     }\r
547                 }\r
548 \r
549                 if (recurse && el && el.childNodes) {\r
550                     for (i = 0,len = el.childNodes.length; i < len; ++i) {\r
551                         this.purgeElement(el.childNodes[i], recurse, eventName);\r
552                     }\r
553                 }\r
554             },\r
555 \r
556 \r
557             getListeners: function(el, eventName) {\r
558                 var results = [], searchLists;\r
559                 if (!eventName) {\r
560                     searchLists = [listeners, unloadListeners];\r
561                 } else if (eventName == "unload") {\r
562                     searchLists = [unloadListeners];\r
563                 } else {\r
564                     searchLists = [listeners];\r
565                 }\r
566 \r
567                 for (var j = 0; j < searchLists.length; ++j) {\r
568                     var searchList = searchLists[j];\r
569                     if (searchList && searchList.length > 0) {\r
570                         for (var i = 0,len = searchList.length; i < len; ++i) {\r
571                             var l = searchList[i];\r
572                             if (l && l[this.EL] === el &&\r
573                                 (!eventName || eventName === l[this.TYPE])) {\r
574                                 results.push({\r
575                                     type:   l[this.TYPE],\r
576                                     fn:     l[this.FN],\r
577                                     obj:    l[this.OBJ],\r
578                                     adjust: l[this.ADJ_SCOPE],\r
579                                     index:  i\r
580                                 });\r
581                             }\r
582                         }\r
583                     }\r
584                 }\r
585 \r
586                 return (results.length) ? results : null;\r
587             },\r
588 \r
589 \r
590             _unload: function(e) {\r
591 \r
592                 var EU = Ext.lib.Event, i, j, l, len, index;\r
593 \r
594                 for (i = 0,len = unloadListeners.length; i < len; ++i) {\r
595                     l = unloadListeners[i];\r
596                     if (l) {\r
597                         var scope = window;\r
598                         if (l[EU.ADJ_SCOPE]) {\r
599                             if (l[EU.ADJ_SCOPE] === true) {\r
600                                 scope = l[EU.OBJ];\r
601                             } else {\r
602                                 scope = l[EU.ADJ_SCOPE];\r
603                             }\r
604                         }\r
605                         l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ]);\r
606                         unloadListeners[i] = null;\r
607                         l = null;\r
608                         scope = null;\r
609                     }\r
610                 }\r
611 \r
612                 unloadListeners = null;\r
613 \r
614                 if (listeners && listeners.length > 0) {\r
615                     j = listeners.length;\r
616                     while (j) {\r
617                         index = j - 1;\r
618                         l = listeners[index];\r
619                         if (l) {\r
620                             EU.removeListener(l[EU.EL], l[EU.TYPE],\r
621                                     l[EU.FN], index);\r
622                         }\r
623                         j = j - 1;\r
624                     }\r
625                     l = null;\r
626 \r
627                     EU.clearCache();\r
628                 }\r
629 \r
630                 EU.doRemove(window, "unload", EU._unload);\r
631 \r
632             },\r
633 \r
634 \r
635             getScroll: function() {\r
636                 var dd = document.documentElement, db = document.body;\r
637                 if (dd && (dd.scrollTop || dd.scrollLeft)) {\r
638                     return [dd.scrollTop, dd.scrollLeft];\r
639                 } else if (db) {\r
640                     return [db.scrollTop, db.scrollLeft];\r
641                 } else {\r
642                     return [0, 0];\r
643                 }\r
644             },\r
645 \r
646 \r
647             doAdd: function () {\r
648                 if (window.addEventListener) {\r
649                     return function(el, eventName, fn, capture) {\r
650                         el.addEventListener(eventName, fn, (capture));\r
651                     };\r
652                 } else if (window.attachEvent) {\r
653                     return function(el, eventName, fn, capture) {\r
654                         el.attachEvent("on" + eventName, fn);\r
655                     };\r
656                 } else {\r
657                     return function() {\r
658                     };\r
659                 }\r
660             }(),\r
661 \r
662 \r
663             doRemove: function() {\r
664                 if (window.removeEventListener) {\r
665                     return function (el, eventName, fn, capture) {\r
666                         el.removeEventListener(eventName, fn, (capture));\r
667                     };\r
668                 } else if (window.detachEvent) {\r
669                     return function (el, eventName, fn) {\r
670                         el.detachEvent("on" + eventName, fn);\r
671                     };\r
672                 } else {\r
673                     return function() {\r
674                     };\r
675                 }\r
676             }()\r
677         };\r
678 \r
679     }();\r
680 \r
681     var E = Ext.lib.Event;\r
682     E.on = E.addListener;\r
683     E.un = E.removeListener;\r
684     if(document && document.body) {\r
685         E._load();\r
686     } else {\r
687         E.doAdd(window, "load", E._load);\r
688     }\r
689     E.doAdd(window, "unload", E._unload);\r
690     E._tryPreloadAttach();\r
691 \r
692     Ext.lib.Ajax = {\r
693         request : function(method, uri, cb, data, options) {\r
694             if(options){\r
695                 var hs = options.headers;\r
696                 if(hs){\r
697                     for(var h in hs){\r
698                         if(hs.hasOwnProperty(h)){\r
699                             this.initHeader(h, hs[h], false);\r
700                         }\r
701                     }\r
702                 }\r
703                 if(options.xmlData){\r
704                     if (!hs || !hs['Content-Type']){\r
705                         this.initHeader('Content-Type', 'text/xml', false);\r
706                     }\r
707                     method = (method ? method : (options.method ? options.method : 'POST'));\r
708                     data = options.xmlData;\r
709                 }else if(options.jsonData){\r
710                     if (!hs || !hs['Content-Type']){\r
711                         this.initHeader('Content-Type', 'application/json', false);\r
712                     }\r
713                     method = (method ? method : (options.method ? options.method : 'POST'));\r
714                     data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;\r
715                 }\r
716             }\r
717 \r
718             return this.asyncRequest(method, uri, cb, data);\r
719         },\r
720 \r
721         serializeForm : function(form) {\r
722             if(typeof form == 'string') {\r
723                 form = (document.getElementById(form) || document.forms[form]);\r
724             }\r
725 \r
726             var el, name, val, disabled, data = '', hasSubmit = false;\r
727             for (var i = 0; i < form.elements.length; i++) {\r
728                 el = form.elements[i];\r
729                 disabled = form.elements[i].disabled;\r
730                 name = form.elements[i].name;\r
731                 val = form.elements[i].value;\r
732 \r
733                 if (!disabled && name){\r
734                     switch (el.type)\r
735                             {\r
736                         case 'select-one':\r
737                         case 'select-multiple':\r
738                             for (var j = 0; j < el.options.length; j++) {\r
739                                 if (el.options[j].selected) {\r
740                                     if (Ext.isIE) {\r
741                                         data += encodeURIComponent(name) + '=' + encodeURIComponent(el.options[j].attributes['value'].specified ? el.options[j].value : el.options[j].text) + '&';\r
742                                     }\r
743                                     else {\r
744                                         data += encodeURIComponent(name) + '=' + encodeURIComponent(el.options[j].hasAttribute('value') ? el.options[j].value : el.options[j].text) + '&';\r
745                                     }\r
746                                 }\r
747                             }\r
748                             break;\r
749                         case 'radio':\r
750                         case 'checkbox':\r
751                             if (el.checked) {\r
752                                 data += encodeURIComponent(name) + '=' + encodeURIComponent(val) + '&';\r
753                             }\r
754                             break;\r
755                         case 'file':\r
756 \r
757                         case undefined:\r
758 \r
759                         case 'reset':\r
760 \r
761                         case 'button':\r
762 \r
763                             break;\r
764                         case 'submit':\r
765                             if(hasSubmit == false) {\r
766                                 data += encodeURIComponent(name) + '=' + encodeURIComponent(val) + '&';\r
767                                 hasSubmit = true;\r
768                             }\r
769                             break;\r
770                         default:\r
771                             data += encodeURIComponent(name) + '=' + encodeURIComponent(val) + '&';\r
772                             break;\r
773                     }\r
774                 }\r
775             }\r
776             data = data.substr(0, data.length - 1);\r
777             return data;\r
778         },\r
779 \r
780         headers:{},\r
781 \r
782         hasHeaders:false,\r
783 \r
784         useDefaultHeader:true,\r
785 \r
786         defaultPostHeader:'application/x-www-form-urlencoded; charset=UTF-8',\r
787 \r
788         useDefaultXhrHeader:true,\r
789 \r
790         defaultXhrHeader:'XMLHttpRequest',\r
791 \r
792         hasDefaultHeaders:true,\r
793 \r
794         defaultHeaders:{},\r
795 \r
796         poll:{},\r
797 \r
798         timeout:{},\r
799 \r
800         pollInterval:50,\r
801 \r
802         transactionId:0,\r
803 \r
804         setProgId:function(id)\r
805         {\r
806             this.activeX.unshift(id);\r
807         },\r
808 \r
809         setDefaultPostHeader:function(b)\r
810         {\r
811             this.useDefaultHeader = b;\r
812         },\r
813 \r
814         setDefaultXhrHeader:function(b)\r
815         {\r
816             this.useDefaultXhrHeader = b;\r
817         },\r
818 \r
819         setPollingInterval:function(i)\r
820         {\r
821             if (typeof i == 'number' && isFinite(i)) {\r
822                 this.pollInterval = i;\r
823             }\r
824         },\r
825 \r
826         createXhrObject:function(transactionId)\r
827         {\r
828             var obj,http;\r
829             try\r
830             {\r
831 \r
832                 http = new XMLHttpRequest();\r
833 \r
834                 obj = { conn:http, tId:transactionId };\r
835             }\r
836             catch(e)\r
837             {\r
838                 for (var i = 0; i < this.activeX.length; ++i) {\r
839                     try\r
840                     {\r
841 \r
842                         http = new ActiveXObject(this.activeX[i]);\r
843 \r
844                         obj = { conn:http, tId:transactionId };\r
845                         break;\r
846                     }\r
847                     catch(e) {\r
848                     }\r
849                 }\r
850             }\r
851             finally\r
852             {\r
853                 return obj;\r
854             }\r
855         },\r
856 \r
857         getConnectionObject:function()\r
858         {\r
859             var o;\r
860             var tId = this.transactionId;\r
861 \r
862             try\r
863             {\r
864                 o = this.createXhrObject(tId);\r
865                 if (o) {\r
866                     this.transactionId++;\r
867                 }\r
868             }\r
869             catch(e) {\r
870             }\r
871             finally\r
872             {\r
873                 return o;\r
874             }\r
875         },\r
876 \r
877         asyncRequest:function(method, uri, callback, postData)\r
878         {\r
879             var o = this.getConnectionObject();\r
880 \r
881             if (!o) {\r
882                 return null;\r
883             }\r
884             else {\r
885                 o.conn.open(method, uri, true);\r
886 \r
887                 if (this.useDefaultXhrHeader) {\r
888                     if (!this.defaultHeaders['X-Requested-With']) {\r
889                         this.initHeader('X-Requested-With', this.defaultXhrHeader, true);\r
890                     }\r
891                 }\r
892 \r
893                 if(postData && this.useDefaultHeader && (!this.hasHeaders || !this.headers['Content-Type'])){\r
894                     this.initHeader('Content-Type', this.defaultPostHeader);\r
895                 }\r
896 \r
897                  if (this.hasDefaultHeaders || this.hasHeaders) {\r
898                     this.setHeader(o);\r
899                 }\r
900 \r
901                 this.handleReadyState(o, callback);\r
902                 o.conn.send(postData || null);\r
903 \r
904                 return o;\r
905             }\r
906         },\r
907 \r
908         handleReadyState:function(o, callback)\r
909         {\r
910             var oConn = this;\r
911 \r
912             if (callback && callback.timeout) {\r
913                 this.timeout[o.tId] = window.setTimeout(function() {\r
914                     oConn.abort(o, callback, true);\r
915                 }, callback.timeout);\r
916             }\r
917 \r
918             this.poll[o.tId] = window.setInterval(\r
919                     function() {\r
920                         if (o.conn && o.conn.readyState == 4) {\r
921                             window.clearInterval(oConn.poll[o.tId]);\r
922                             delete oConn.poll[o.tId];\r
923 \r
924                             if (callback && callback.timeout) {\r
925                                 window.clearTimeout(oConn.timeout[o.tId]);\r
926                                 delete oConn.timeout[o.tId];\r
927                             }\r
928 \r
929                             oConn.handleTransactionResponse(o, callback);\r
930                         }\r
931                     }\r
932                     , this.pollInterval);\r
933         },\r
934 \r
935         handleTransactionResponse:function(o, callback, isAbort)\r
936         {\r
937 \r
938             if (!callback) {\r
939                 this.releaseObject(o);\r
940                 return;\r
941             }\r
942 \r
943             var httpStatus, responseObject;\r
944 \r
945             try\r
946             {\r
947                 if (o.conn.status !== undefined && o.conn.status != 0) {\r
948                     httpStatus = o.conn.status;\r
949                 }\r
950                 else {\r
951                     httpStatus = 13030;\r
952                 }\r
953             }\r
954             catch(e) {\r
955 \r
956 \r
957                 httpStatus = 13030;\r
958             }\r
959 \r
960             if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) {\r
961                 responseObject = this.createResponseObject(o, callback.argument);\r
962                 if (callback.success) {\r
963                     if (!callback.scope) {\r
964                         callback.success(responseObject);\r
965                     }\r
966                     else {\r
967 \r
968 \r
969                         callback.success.apply(callback.scope, [responseObject]);\r
970                     }\r
971                 }\r
972             }\r
973             else {\r
974                 switch (httpStatus) {\r
975 \r
976                     case 12002:\r
977                     case 12029:\r
978                     case 12030:\r
979                     case 12031:\r
980                     case 12152:\r
981                     case 13030:\r
982                         responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));\r
983                         if (callback.failure) {\r
984                             if (!callback.scope) {\r
985                                 callback.failure(responseObject);\r
986                             }\r
987                             else {\r
988                                 callback.failure.apply(callback.scope, [responseObject]);\r
989                             }\r
990                         }\r
991                         break;\r
992                     default:\r
993                         responseObject = this.createResponseObject(o, callback.argument);\r
994                         if (callback.failure) {\r
995                             if (!callback.scope) {\r
996                                 callback.failure(responseObject);\r
997                             }\r
998                             else {\r
999                                 callback.failure.apply(callback.scope, [responseObject]);\r
1000                             }\r
1001                         }\r
1002                 }\r
1003             }\r
1004 \r
1005             this.releaseObject(o);\r
1006             responseObject = null;\r
1007         },\r
1008 \r
1009         createResponseObject:function(o, callbackArg)\r
1010         {\r
1011             var obj = {};\r
1012             var headerObj = {};\r
1013 \r
1014             try\r
1015             {\r
1016                 var headerStr = o.conn.getAllResponseHeaders();\r
1017                 var header = headerStr.split('\n');\r
1018                 for (var i = 0; i < header.length; i++) {\r
1019                     var delimitPos = header[i].indexOf(':');\r
1020                     if (delimitPos != -1) {\r
1021                         headerObj[header[i].substring(0, delimitPos)] = header[i].substring(delimitPos + 2);\r
1022                     }\r
1023                 }\r
1024             }\r
1025             catch(e) {\r
1026             }\r
1027 \r
1028             obj.tId = o.tId;\r
1029             obj.status = o.conn.status;\r
1030             obj.statusText = o.conn.statusText;\r
1031             obj.getResponseHeader = headerObj;\r
1032             obj.getAllResponseHeaders = headerStr;\r
1033             obj.responseText = o.conn.responseText;\r
1034             obj.responseXML = o.conn.responseXML;\r
1035 \r
1036             if (typeof callbackArg !== undefined) {\r
1037                 obj.argument = callbackArg;\r
1038             }\r
1039 \r
1040             return obj;\r
1041         },\r
1042 \r
1043         createExceptionObject:function(tId, callbackArg, isAbort)\r
1044         {\r
1045             var COMM_CODE = 0;\r
1046             var COMM_ERROR = 'communication failure';\r
1047             var ABORT_CODE = -1;\r
1048             var ABORT_ERROR = 'transaction aborted';\r
1049 \r
1050             var obj = {};\r
1051 \r
1052             obj.tId = tId;\r
1053             if (isAbort) {\r
1054                 obj.status = ABORT_CODE;\r
1055                 obj.statusText = ABORT_ERROR;\r
1056             }\r
1057             else {\r
1058                 obj.status = COMM_CODE;\r
1059                 obj.statusText = COMM_ERROR;\r
1060             }\r
1061 \r
1062             if (callbackArg) {\r
1063                 obj.argument = callbackArg;\r
1064             }\r
1065 \r
1066             return obj;\r
1067         },\r
1068 \r
1069         initHeader:function(label, value, isDefault)\r
1070         {\r
1071             var headerObj = (isDefault) ? this.defaultHeaders : this.headers;\r
1072 \r
1073             if (headerObj[label] === undefined) {\r
1074                 headerObj[label] = value;\r
1075             }\r
1076             else {\r
1077 \r
1078 \r
1079                 headerObj[label] = value + "," + headerObj[label];\r
1080             }\r
1081 \r
1082             if (isDefault) {\r
1083                 this.hasDefaultHeaders = true;\r
1084             }\r
1085             else {\r
1086                 this.hasHeaders = true;\r
1087             }\r
1088         },\r
1089 \r
1090 \r
1091         setHeader:function(o)\r
1092         {\r
1093             if (this.hasDefaultHeaders) {\r
1094                 for (var prop in this.defaultHeaders) {\r
1095                     if (this.defaultHeaders.hasOwnProperty(prop)) {\r
1096                         o.conn.setRequestHeader(prop, this.defaultHeaders[prop]);\r
1097                     }\r
1098                 }\r
1099             }\r
1100 \r
1101             if (this.hasHeaders) {\r
1102                 for (var prop in this.headers) {\r
1103                     if (this.headers.hasOwnProperty(prop)) {\r
1104                         o.conn.setRequestHeader(prop, this.headers[prop]);\r
1105                     }\r
1106                 }\r
1107                 this.headers = {};\r
1108                 this.hasHeaders = false;\r
1109             }\r
1110         },\r
1111 \r
1112         resetDefaultHeaders:function() {\r
1113             delete this.defaultHeaders;\r
1114             this.defaultHeaders = {};\r
1115             this.hasDefaultHeaders = false;\r
1116         },\r
1117 \r
1118         abort:function(o, callback, isTimeout)\r
1119         {\r
1120             if (this.isCallInProgress(o)) {\r
1121                 o.conn.abort();\r
1122                 window.clearInterval(this.poll[o.tId]);\r
1123                 delete this.poll[o.tId];\r
1124                 if (isTimeout) {\r
1125                     delete this.timeout[o.tId];\r
1126                 }\r
1127 \r
1128                 this.handleTransactionResponse(o, callback, true);\r
1129 \r
1130                 return true;\r
1131             }\r
1132             else {\r
1133                 return false;\r
1134             }\r
1135         },\r
1136 \r
1137 \r
1138         isCallInProgress:function(o)\r
1139         {\r
1140 \r
1141 \r
1142             if (o.conn) {\r
1143                 return o.conn.readyState != 4 && o.conn.readyState != 0;\r
1144             }\r
1145             else {\r
1146 \r
1147                 return false;\r
1148             }\r
1149         },\r
1150 \r
1151 \r
1152         releaseObject:function(o)\r
1153         {\r
1154 \r
1155             o.conn = null;\r
1156 \r
1157             o = null;\r
1158         },\r
1159 \r
1160         activeX:[\r
1161         'MSXML2.XMLHTTP.3.0',\r
1162         'MSXML2.XMLHTTP',\r
1163         'Microsoft.XMLHTTP'\r
1164         ]\r
1165 \r
1166 \r
1167     };\r
1168 \r
1169 \r
1170     Ext.lib.Region = function(t, r, b, l) {\r
1171         this.top = t;\r
1172         this[1] = t;\r
1173         this.right = r;\r
1174         this.bottom = b;\r
1175         this.left = l;\r
1176         this[0] = l;\r
1177     };\r
1178 \r
1179     Ext.lib.Region.prototype = {\r
1180         contains : function(region) {\r
1181             return ( region.left >= this.left &&\r
1182                      region.right <= this.right &&\r
1183                      region.top >= this.top &&\r
1184                      region.bottom <= this.bottom    );\r
1185 \r
1186         },\r
1187 \r
1188         getArea : function() {\r
1189             return ( (this.bottom - this.top) * (this.right - this.left) );\r
1190         },\r
1191 \r
1192         intersect : function(region) {\r
1193             var t = Math.max(this.top, region.top);\r
1194             var r = Math.min(this.right, region.right);\r
1195             var b = Math.min(this.bottom, region.bottom);\r
1196             var l = Math.max(this.left, region.left);\r
1197 \r
1198             if (b >= t && r >= l) {\r
1199                 return new Ext.lib.Region(t, r, b, l);\r
1200             } else {\r
1201                 return null;\r
1202             }\r
1203         },\r
1204         union : function(region) {\r
1205             var t = Math.min(this.top, region.top);\r
1206             var r = Math.max(this.right, region.right);\r
1207             var b = Math.max(this.bottom, region.bottom);\r
1208             var l = Math.min(this.left, region.left);\r
1209 \r
1210             return new Ext.lib.Region(t, r, b, l);\r
1211         },\r
1212 \r
1213         constrainTo : function(r) {\r
1214             this.top = this.top.constrain(r.top, r.bottom);\r
1215             this.bottom = this.bottom.constrain(r.top, r.bottom);\r
1216             this.left = this.left.constrain(r.left, r.right);\r
1217             this.right = this.right.constrain(r.left, r.right);\r
1218             return this;\r
1219         },\r
1220 \r
1221         adjust : function(t, l, b, r) {\r
1222             this.top += t;\r
1223             this.left += l;\r
1224             this.right += r;\r
1225             this.bottom += b;\r
1226             return this;\r
1227         }\r
1228     };\r
1229 \r
1230     Ext.lib.Region.getRegion = function(el) {\r
1231         var p = Ext.lib.Dom.getXY(el);\r
1232 \r
1233         var t = p[1];\r
1234         var r = p[0] + el.offsetWidth;\r
1235         var b = p[1] + el.offsetHeight;\r
1236         var l = p[0];\r
1237 \r
1238         return new Ext.lib.Region(t, r, b, l);\r
1239     };\r
1240 \r
1241     Ext.lib.Point = function(x, y) {\r
1242         if (Ext.isArray(x)) {\r
1243             y = x[1];\r
1244             x = x[0];\r
1245         }\r
1246         this.x = this.right = this.left = this[0] = x;\r
1247         this.y = this.top = this.bottom = this[1] = y;\r
1248     };\r
1249 \r
1250     Ext.lib.Point.prototype = new Ext.lib.Region();\r
1251 \r
1252 \r
1253     Ext.lib.Anim = {\r
1254         scroll : function(el, args, duration, easing, cb, scope) {\r
1255             return this.run(el, args, duration, easing, cb, scope, Ext.lib.Scroll);\r
1256         },\r
1257 \r
1258         motion : function(el, args, duration, easing, cb, scope) {\r
1259             return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion);\r
1260         },\r
1261 \r
1262         color : function(el, args, duration, easing, cb, scope) {\r
1263             return this.run(el, args, duration, easing, cb, scope, Ext.lib.ColorAnim);\r
1264         },\r
1265 \r
1266         run : function(el, args, duration, easing, cb, scope, type) {\r
1267             type = type || Ext.lib.AnimBase;\r
1268             if (typeof easing == "string") {\r
1269                 easing = Ext.lib.Easing[easing];\r
1270             }\r
1271             var anim = new type(el, args, duration, easing);\r
1272             anim.animateX(function() {\r
1273                 Ext.callback(cb, scope);\r
1274             });\r
1275             return anim;\r
1276         }\r
1277     };\r
1278 \r
1279 \r
1280     function fly(el) {\r
1281         if (!libFlyweight) {\r
1282             libFlyweight = new Ext.Element.Flyweight();\r
1283         }\r
1284         libFlyweight.dom = el;\r
1285         return libFlyweight;\r
1286     }\r
1287 \r
1288 \r
1289     if(Ext.isIE) {\r
1290         function fnCleanUp() {\r
1291             var p = Function.prototype;\r
1292             delete p.createSequence;\r
1293             delete p.defer;\r
1294             delete p.createDelegate;\r
1295             delete p.createCallback;\r
1296             delete p.createInterceptor;\r
1297 \r
1298             window.detachEvent("onunload", fnCleanUp);\r
1299         }\r
1300         window.attachEvent("onunload", fnCleanUp);\r
1301     }\r
1302 \r
1303     Ext.lib.AnimBase = function(el, attributes, duration, method) {\r
1304         if (el) {\r
1305             this.init(el, attributes, duration, method);\r
1306         }\r
1307     };\r
1308 \r
1309     Ext.lib.AnimBase.prototype = {\r
1310 \r
1311         toString: function() {\r
1312             var el = this.getEl();\r
1313             var id = el.id || el.tagName;\r
1314             return ("Anim " + id);\r
1315         },\r
1316 \r
1317         patterns: {\r
1318             noNegatives:        /width|height|opacity|padding/i,\r
1319             offsetAttribute:  /^((width|height)|(top|left))$/,\r
1320             defaultUnit:        /width|height|top$|bottom$|left$|right$/i,\r
1321             offsetUnit:         /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i\r
1322         },\r
1323 \r
1324 \r
1325         doMethod: function(attr, start, end) {\r
1326             return this.method(this.currentFrame, start, end - start, this.totalFrames);\r
1327         },\r
1328 \r
1329 \r
1330         setAttribute: function(attr, val, unit) {\r
1331             if (this.patterns.noNegatives.test(attr)) {\r
1332                 val = (val > 0) ? val : 0;\r
1333             }\r
1334 \r
1335             Ext.fly(this.getEl(), '_anim').setStyle(attr, val + unit);\r
1336         },\r
1337 \r
1338 \r
1339         getAttribute: function(attr) {\r
1340             var el = this.getEl();\r
1341             var val = fly(el).getStyle(attr);\r
1342 \r
1343             if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {\r
1344                 return parseFloat(val);\r
1345             }\r
1346 \r
1347             var a = this.patterns.offsetAttribute.exec(attr) || [];\r
1348             var pos = !!( a[3] );\r
1349             var box = !!( a[2] );\r
1350 \r
1351 \r
1352             if (box || (fly(el).getStyle('position') == 'absolute' && pos)) {\r
1353                 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];\r
1354             } else {\r
1355                 val = 0;\r
1356             }\r
1357 \r
1358             return val;\r
1359         },\r
1360 \r
1361 \r
1362         getDefaultUnit: function(attr) {\r
1363             if (this.patterns.defaultUnit.test(attr)) {\r
1364                 return 'px';\r
1365             }\r
1366 \r
1367             return '';\r
1368         },\r
1369 \r
1370         animateX : function(callback, scope) {\r
1371             var f = function() {\r
1372                 this.onComplete.removeListener(f);\r
1373                 if (typeof callback == "function") {\r
1374                     callback.call(scope || this, this);\r
1375                 }\r
1376             };\r
1377             this.onComplete.addListener(f, this);\r
1378             this.animate();\r
1379         },\r
1380 \r
1381 \r
1382         setRuntimeAttribute: function(attr) {\r
1383             var start;\r
1384             var end;\r
1385             var attributes = this.attributes;\r
1386 \r
1387             this.runtimeAttributes[attr] = {};\r
1388 \r
1389             var isset = function(prop) {\r
1390                 return (typeof prop !== 'undefined');\r
1391             };\r
1392 \r
1393             if (!isset(attributes[attr]['to']) && !isset(attributes[attr]['by'])) {\r
1394                 return false;\r
1395             }\r
1396 \r
1397             start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);\r
1398 \r
1399 \r
1400             if (isset(attributes[attr]['to'])) {\r
1401                 end = attributes[attr]['to'];\r
1402             } else if (isset(attributes[attr]['by'])) {\r
1403                 if (start.constructor == Array) {\r
1404                     end = [];\r
1405                     for (var i = 0, len = start.length; i < len; ++i) {\r
1406                         end[i] = start[i] + attributes[attr]['by'][i];\r
1407                     }\r
1408                 } else {\r
1409                     end = start + attributes[attr]['by'];\r
1410                 }\r
1411             }\r
1412 \r
1413             this.runtimeAttributes[attr].start = start;\r
1414             this.runtimeAttributes[attr].end = end;\r
1415 \r
1416 \r
1417             this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ? attributes[attr]['unit'] : this.getDefaultUnit(attr);\r
1418         },\r
1419 \r
1420 \r
1421         init: function(el, attributes, duration, method) {\r
1422 \r
1423             var isAnimated = false;\r
1424 \r
1425 \r
1426             var startTime = null;\r
1427 \r
1428 \r
1429             var actualFrames = 0;\r
1430 \r
1431 \r
1432             el = Ext.getDom(el);\r
1433 \r
1434 \r
1435             this.attributes = attributes || {};\r
1436 \r
1437 \r
1438             this.duration = duration || 1;\r
1439 \r
1440 \r
1441             this.method = method || Ext.lib.Easing.easeNone;\r
1442 \r
1443 \r
1444             this.useSeconds = true;\r
1445 \r
1446 \r
1447             this.currentFrame = 0;\r
1448 \r
1449 \r
1450             this.totalFrames = Ext.lib.AnimMgr.fps;\r
1451 \r
1452 \r
1453             this.getEl = function() {\r
1454                 return el;\r
1455             };\r
1456 \r
1457 \r
1458             this.isAnimated = function() {\r
1459                 return isAnimated;\r
1460             };\r
1461 \r
1462 \r
1463             this.getStartTime = function() {\r
1464                 return startTime;\r
1465             };\r
1466 \r
1467             this.runtimeAttributes = {};\r
1468 \r
1469 \r
1470             this.animate = function() {\r
1471                 if (this.isAnimated()) {\r
1472                     return false;\r
1473                 }\r
1474 \r
1475                 this.currentFrame = 0;\r
1476 \r
1477                 this.totalFrames = ( this.useSeconds ) ? Math.ceil(Ext.lib.AnimMgr.fps * this.duration) : this.duration;\r
1478 \r
1479                 Ext.lib.AnimMgr.registerElement(this);\r
1480             };\r
1481 \r
1482 \r
1483             this.stop = function(finish) {\r
1484                 if (finish) {\r
1485                     this.currentFrame = this.totalFrames;\r
1486                     this._onTween.fire();\r
1487                 }\r
1488                 Ext.lib.AnimMgr.stop(this);\r
1489             };\r
1490 \r
1491             var onStart = function() {\r
1492                 this.onStart.fire();\r
1493 \r
1494                 this.runtimeAttributes = {};\r
1495                 for (var attr in this.attributes) {\r
1496                     this.setRuntimeAttribute(attr);\r
1497                 }\r
1498 \r
1499                 isAnimated = true;\r
1500                 actualFrames = 0;\r
1501                 startTime = new Date();\r
1502             };\r
1503 \r
1504 \r
1505             var onTween = function() {\r
1506                 var data = {\r
1507                     duration: new Date() - this.getStartTime(),\r
1508                     currentFrame: this.currentFrame\r
1509                 };\r
1510 \r
1511                 data.toString = function() {\r
1512                     return (\r
1513                             'duration: ' + data.duration +\r
1514                             ', currentFrame: ' + data.currentFrame\r
1515                             );\r
1516                 };\r
1517 \r
1518                 this.onTween.fire(data);\r
1519 \r
1520                 var runtimeAttributes = this.runtimeAttributes;\r
1521 \r
1522                 for (var attr in runtimeAttributes) {\r
1523                     this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);\r
1524                 }\r
1525 \r
1526                 actualFrames += 1;\r
1527             };\r
1528 \r
1529             var onComplete = function() {\r
1530                 var actual_duration = (new Date() - startTime) / 1000 ;\r
1531 \r
1532                 var data = {\r
1533                     duration: actual_duration,\r
1534                     frames: actualFrames,\r
1535                     fps: actualFrames / actual_duration\r
1536                 };\r
1537 \r
1538                 data.toString = function() {\r
1539                     return (\r
1540                             'duration: ' + data.duration +\r
1541                             ', frames: ' + data.frames +\r
1542                             ', fps: ' + data.fps\r
1543                             );\r
1544                 };\r
1545 \r
1546                 isAnimated = false;\r
1547                 actualFrames = 0;\r
1548                 this.onComplete.fire(data);\r
1549             };\r
1550 \r
1551 \r
1552             this._onStart = new Ext.util.Event(this);\r
1553             this.onStart = new Ext.util.Event(this);\r
1554             this.onTween = new Ext.util.Event(this);\r
1555             this._onTween = new Ext.util.Event(this);\r
1556             this.onComplete = new Ext.util.Event(this);\r
1557             this._onComplete = new Ext.util.Event(this);\r
1558             this._onStart.addListener(onStart);\r
1559             this._onTween.addListener(onTween);\r
1560             this._onComplete.addListener(onComplete);\r
1561         }\r
1562     };\r
1563 \r
1564 \r
1565     Ext.lib.AnimMgr = new function() {\r
1566 \r
1567         var thread = null;\r
1568 \r
1569 \r
1570         var queue = [];\r
1571 \r
1572 \r
1573         var tweenCount = 0;\r
1574 \r
1575 \r
1576         this.fps = 1000;\r
1577 \r
1578 \r
1579         this.delay = 1;\r
1580 \r
1581 \r
1582         this.registerElement = function(tween) {\r
1583             queue[queue.length] = tween;\r
1584             tweenCount += 1;\r
1585             tween._onStart.fire();\r
1586             this.start();\r
1587         };\r
1588 \r
1589 \r
1590         this.unRegister = function(tween, index) {\r
1591             tween._onComplete.fire();\r
1592             index = index || getIndex(tween);\r
1593             if (index != -1) {\r
1594                 queue.splice(index, 1);\r
1595             }\r
1596 \r
1597             tweenCount -= 1;\r
1598             if (tweenCount <= 0) {\r
1599                 this.stop();\r
1600             }\r
1601         };\r
1602 \r
1603 \r
1604         this.start = function() {\r
1605             if (thread === null) {\r
1606                 thread = setInterval(this.run, this.delay);\r
1607             }\r
1608         };\r
1609 \r
1610 \r
1611         this.stop = function(tween) {\r
1612             if (!tween) {\r
1613                 clearInterval(thread);\r
1614 \r
1615                 for (var i = 0, len = queue.length; i < len; ++i) {\r
1616                     if (queue[0].isAnimated()) {\r
1617                         this.unRegister(queue[0], 0);\r
1618                     }\r
1619                 }\r
1620 \r
1621                 queue = [];\r
1622                 thread = null;\r
1623                 tweenCount = 0;\r
1624             }\r
1625             else {\r
1626                 this.unRegister(tween);\r
1627             }\r
1628         };\r
1629 \r
1630 \r
1631         this.run = function() {\r
1632             for (var i = 0, len = queue.length; i < len; ++i) {\r
1633                 var tween = queue[i];\r
1634                 if (!tween || !tween.isAnimated()) {\r
1635                     continue;\r
1636                 }\r
1637 \r
1638                 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)\r
1639                 {\r
1640                     tween.currentFrame += 1;\r
1641 \r
1642                     if (tween.useSeconds) {\r
1643                         correctFrame(tween);\r
1644                     }\r
1645                     tween._onTween.fire();\r
1646                 }\r
1647                 else {\r
1648                     Ext.lib.AnimMgr.stop(tween, i);\r
1649                 }\r
1650             }\r
1651         };\r
1652 \r
1653         var getIndex = function(anim) {\r
1654             for (var i = 0, len = queue.length; i < len; ++i) {\r
1655                 if (queue[i] == anim) {\r
1656                     return i;\r
1657                 }\r
1658             }\r
1659             return -1;\r
1660         };\r
1661 \r
1662 \r
1663         var correctFrame = function(tween) {\r
1664             var frames = tween.totalFrames;\r
1665             var frame = tween.currentFrame;\r
1666             var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);\r
1667             var elapsed = (new Date() - tween.getStartTime());\r
1668             var tweak = 0;\r
1669 \r
1670             if (elapsed < tween.duration * 1000) {\r
1671                 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);\r
1672             } else {\r
1673                 tweak = frames - (frame + 1);\r
1674             }\r
1675             if (tweak > 0 && isFinite(tweak)) {\r
1676                 if (tween.currentFrame + tweak >= frames) {\r
1677                     tweak = frames - (frame + 1);\r
1678                 }\r
1679 \r
1680                 tween.currentFrame += tweak;\r
1681             }\r
1682         };\r
1683     };\r
1684 \r
1685     Ext.lib.Bezier = new function() {\r
1686 \r
1687         this.getPosition = function(points, t) {\r
1688             var n = points.length;\r
1689             var tmp = [];\r
1690 \r
1691             for (var i = 0; i < n; ++i) {\r
1692                 tmp[i] = [points[i][0], points[i][1]];\r
1693             }\r
1694 \r
1695             for (var j = 1; j < n; ++j) {\r
1696                 for (i = 0; i < n - j; ++i) {\r
1697                     tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];\r
1698                     tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];\r
1699                 }\r
1700             }\r
1701 \r
1702             return [ tmp[0][0], tmp[0][1] ];\r
1703 \r
1704         };\r
1705     };\r
1706     (function() {\r
1707 \r
1708         Ext.lib.ColorAnim = function(el, attributes, duration, method) {\r
1709             Ext.lib.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);\r
1710         };\r
1711 \r
1712         Ext.extend(Ext.lib.ColorAnim, Ext.lib.AnimBase);\r
1713 \r
1714 \r
1715         var Y = Ext.lib;\r
1716         var superclass = Y.ColorAnim.superclass;\r
1717         var proto = Y.ColorAnim.prototype;\r
1718 \r
1719         proto.toString = function() {\r
1720             var el = this.getEl();\r
1721             var id = el.id || el.tagName;\r
1722             return ("ColorAnim " + id);\r
1723         };\r
1724 \r
1725         proto.patterns.color = /color$/i;\r
1726         proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;\r
1727         proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;\r
1728         proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;\r
1729         proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/;\r
1730 \r
1731 \r
1732         proto.parseColor = function(s) {\r
1733             if (s.length == 3) {\r
1734                 return s;\r
1735             }\r
1736 \r
1737             var c = this.patterns.hex.exec(s);\r
1738             if (c && c.length == 4) {\r
1739                 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];\r
1740             }\r
1741 \r
1742             c = this.patterns.rgb.exec(s);\r
1743             if (c && c.length == 4) {\r
1744                 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];\r
1745             }\r
1746 \r
1747             c = this.patterns.hex3.exec(s);\r
1748             if (c && c.length == 4) {\r
1749                 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];\r
1750             }\r
1751 \r
1752             return null;\r
1753         };\r
1754 \r
1755         proto.getAttribute = function(attr) {\r
1756             var el = this.getEl();\r
1757             if (this.patterns.color.test(attr)) {\r
1758                 var val = fly(el).getStyle(attr);\r
1759 \r
1760                 if (this.patterns.transparent.test(val)) {\r
1761                     var parent = el.parentNode;\r
1762                     val = fly(parent).getStyle(attr);\r
1763 \r
1764                     while (parent && this.patterns.transparent.test(val)) {\r
1765                         parent = parent.parentNode;\r
1766                         val = fly(parent).getStyle(attr);\r
1767                         if (parent.tagName.toUpperCase() == 'HTML') {\r
1768                             val = '#fff';\r
1769                         }\r
1770                     }\r
1771                 }\r
1772             } else {\r
1773                 val = superclass.getAttribute.call(this, attr);\r
1774             }\r
1775 \r
1776             return val;\r
1777         };\r
1778 \r
1779         proto.doMethod = function(attr, start, end) {\r
1780             var val;\r
1781 \r
1782             if (this.patterns.color.test(attr)) {\r
1783                 val = [];\r
1784                 for (var i = 0, len = start.length; i < len; ++i) {\r
1785                     val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);\r
1786                 }\r
1787 \r
1788                 val = 'rgb(' + Math.floor(val[0]) + ',' + Math.floor(val[1]) + ',' + Math.floor(val[2]) + ')';\r
1789             }\r
1790             else {\r
1791                 val = superclass.doMethod.call(this, attr, start, end);\r
1792             }\r
1793 \r
1794             return val;\r
1795         };\r
1796 \r
1797         proto.setRuntimeAttribute = function(attr) {\r
1798             superclass.setRuntimeAttribute.call(this, attr);\r
1799 \r
1800             if (this.patterns.color.test(attr)) {\r
1801                 var attributes = this.attributes;\r
1802                 var start = this.parseColor(this.runtimeAttributes[attr].start);\r
1803                 var end = this.parseColor(this.runtimeAttributes[attr].end);\r
1804 \r
1805                 if (typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined') {\r
1806                     end = this.parseColor(attributes[attr].by);\r
1807 \r
1808                     for (var i = 0, len = start.length; i < len; ++i) {\r
1809                         end[i] = start[i] + end[i];\r
1810                     }\r
1811                 }\r
1812 \r
1813                 this.runtimeAttributes[attr].start = start;\r
1814                 this.runtimeAttributes[attr].end = end;\r
1815             }\r
1816         };\r
1817     })();\r
1818 \r
1819 \r
1820     Ext.lib.Easing = {\r
1821 \r
1822 \r
1823         easeNone: function (t, b, c, d) {\r
1824             return c * t / d + b;\r
1825         },\r
1826 \r
1827 \r
1828         easeIn: function (t, b, c, d) {\r
1829             return c * (t /= d) * t + b;\r
1830         },\r
1831 \r
1832 \r
1833         easeOut: function (t, b, c, d) {\r
1834             return -c * (t /= d) * (t - 2) + b;\r
1835         },\r
1836 \r
1837 \r
1838         easeBoth: function (t, b, c, d) {\r
1839             if ((t /= d / 2) < 1) {\r
1840                 return c / 2 * t * t + b;\r
1841             }\r
1842 \r
1843             return -c / 2 * ((--t) * (t - 2) - 1) + b;\r
1844         },\r
1845 \r
1846 \r
1847         easeInStrong: function (t, b, c, d) {\r
1848             return c * (t /= d) * t * t * t + b;\r
1849         },\r
1850 \r
1851 \r
1852         easeOutStrong: function (t, b, c, d) {\r
1853             return -c * ((t = t / d - 1) * t * t * t - 1) + b;\r
1854         },\r
1855 \r
1856 \r
1857         easeBothStrong: function (t, b, c, d) {\r
1858             if ((t /= d / 2) < 1) {\r
1859                 return c / 2 * t * t * t * t + b;\r
1860             }\r
1861 \r
1862             return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\r
1863         },\r
1864 \r
1865 \r
1866 \r
1867         elasticIn: function (t, b, c, d, a, p) {\r
1868             if (t == 0) {\r
1869                 return b;\r
1870             }\r
1871             if ((t /= d) == 1) {\r
1872                 return b + c;\r
1873             }\r
1874             if (!p) {\r
1875                 p = d * .3;\r
1876             }\r
1877 \r
1878             if (!a || a < Math.abs(c)) {\r
1879                 a = c;\r
1880                 var s = p / 4;\r
1881             }\r
1882             else {\r
1883                 var s = p / (2 * Math.PI) * Math.asin(c / a);\r
1884             }\r
1885 \r
1886             return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;\r
1887         },\r
1888 \r
1889 \r
1890         elasticOut: function (t, b, c, d, a, p) {\r
1891             if (t == 0) {\r
1892                 return b;\r
1893             }\r
1894             if ((t /= d) == 1) {\r
1895                 return b + c;\r
1896             }\r
1897             if (!p) {\r
1898                 p = d * .3;\r
1899             }\r
1900 \r
1901             if (!a || a < Math.abs(c)) {\r
1902                 a = c;\r
1903                 var s = p / 4;\r
1904             }\r
1905             else {\r
1906                 var s = p / (2 * Math.PI) * Math.asin(c / a);\r
1907             }\r
1908 \r
1909             return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;\r
1910         },\r
1911 \r
1912 \r
1913         elasticBoth: function (t, b, c, d, a, p) {\r
1914             if (t == 0) {\r
1915                 return b;\r
1916             }\r
1917 \r
1918             if ((t /= d / 2) == 2) {\r
1919                 return b + c;\r
1920             }\r
1921 \r
1922             if (!p) {\r
1923                 p = d * (.3 * 1.5);\r
1924             }\r
1925 \r
1926             if (!a || a < Math.abs(c)) {\r
1927                 a = c;\r
1928                 var s = p / 4;\r
1929             }\r
1930             else {\r
1931                 var s = p / (2 * Math.PI) * Math.asin(c / a);\r
1932             }\r
1933 \r
1934             if (t < 1) {\r
1935                 return -.5 * (a * Math.pow(2, 10 * (t -= 1)) *\r
1936                               Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;\r
1937             }\r
1938             return a * Math.pow(2, -10 * (t -= 1)) *\r
1939                    Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;\r
1940         },\r
1941 \r
1942 \r
1943 \r
1944         backIn: function (t, b, c, d, s) {\r
1945             if (typeof s == 'undefined') {\r
1946                 s = 1.70158;\r
1947             }\r
1948             return c * (t /= d) * t * ((s + 1) * t - s) + b;\r
1949         },\r
1950 \r
1951 \r
1952         backOut: function (t, b, c, d, s) {\r
1953             if (typeof s == 'undefined') {\r
1954                 s = 1.70158;\r
1955             }\r
1956             return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\r
1957         },\r
1958 \r
1959 \r
1960         backBoth: function (t, b, c, d, s) {\r
1961             if (typeof s == 'undefined') {\r
1962                 s = 1.70158;\r
1963             }\r
1964 \r
1965             if ((t /= d / 2 ) < 1) {\r
1966                 return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\r
1967             }\r
1968             return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\r
1969         },\r
1970 \r
1971 \r
1972         bounceIn: function (t, b, c, d) {\r
1973             return c - Ext.lib.Easing.bounceOut(d - t, 0, c, d) + b;\r
1974         },\r
1975 \r
1976 \r
1977         bounceOut: function (t, b, c, d) {\r
1978             if ((t /= d) < (1 / 2.75)) {\r
1979                 return c * (7.5625 * t * t) + b;\r
1980             } else if (t < (2 / 2.75)) {\r
1981                 return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;\r
1982             } else if (t < (2.5 / 2.75)) {\r
1983                 return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;\r
1984             }\r
1985             return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;\r
1986         },\r
1987 \r
1988 \r
1989         bounceBoth: function (t, b, c, d) {\r
1990             if (t < d / 2) {\r
1991                 return Ext.lib.Easing.bounceIn(t * 2, 0, c, d) * .5 + b;\r
1992             }\r
1993             return Ext.lib.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;\r
1994         }\r
1995     };\r
1996 \r
1997     (function() {\r
1998         Ext.lib.Motion = function(el, attributes, duration, method) {\r
1999             if (el) {\r
2000                 Ext.lib.Motion.superclass.constructor.call(this, el, attributes, duration, method);\r
2001             }\r
2002         };\r
2003 \r
2004         Ext.extend(Ext.lib.Motion, Ext.lib.ColorAnim);\r
2005 \r
2006 \r
2007         var Y = Ext.lib;\r
2008         var superclass = Y.Motion.superclass;\r
2009         var proto = Y.Motion.prototype;\r
2010 \r
2011         proto.toString = function() {\r
2012             var el = this.getEl();\r
2013             var id = el.id || el.tagName;\r
2014             return ("Motion " + id);\r
2015         };\r
2016 \r
2017         proto.patterns.points = /^points$/i;\r
2018 \r
2019         proto.setAttribute = function(attr, val, unit) {\r
2020             if (this.patterns.points.test(attr)) {\r
2021                 unit = unit || 'px';\r
2022                 superclass.setAttribute.call(this, 'left', val[0], unit);\r
2023                 superclass.setAttribute.call(this, 'top', val[1], unit);\r
2024             } else {\r
2025                 superclass.setAttribute.call(this, attr, val, unit);\r
2026             }\r
2027         };\r
2028 \r
2029         proto.getAttribute = function(attr) {\r
2030             if (this.patterns.points.test(attr)) {\r
2031                 var val = [\r
2032                         superclass.getAttribute.call(this, 'left'),\r
2033                         superclass.getAttribute.call(this, 'top')\r
2034                         ];\r
2035             } else {\r
2036                 val = superclass.getAttribute.call(this, attr);\r
2037             }\r
2038 \r
2039             return val;\r
2040         };\r
2041 \r
2042         proto.doMethod = function(attr, start, end) {\r
2043             var val = null;\r
2044 \r
2045             if (this.patterns.points.test(attr)) {\r
2046                 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;\r
2047                 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);\r
2048             } else {\r
2049                 val = superclass.doMethod.call(this, attr, start, end);\r
2050             }\r
2051             return val;\r
2052         };\r
2053 \r
2054         proto.setRuntimeAttribute = function(attr) {\r
2055             if (this.patterns.points.test(attr)) {\r
2056                 var el = this.getEl();\r
2057                 var attributes = this.attributes;\r
2058                 var start;\r
2059                 var control = attributes['points']['control'] || [];\r
2060                 var end;\r
2061                 var i, len;\r
2062 \r
2063                 if (control.length > 0 && !Ext.isArray(control[0])) {\r
2064                     control = [control];\r
2065                 } else {\r
2066                     var tmp = [];\r
2067                     for (i = 0,len = control.length; i < len; ++i) {\r
2068                         tmp[i] = control[i];\r
2069                     }\r
2070                     control = tmp;\r
2071                 }\r
2072 \r
2073                 Ext.fly(el, '_anim').position();\r
2074 \r
2075                 if (isset(attributes['points']['from'])) {\r
2076                     Ext.lib.Dom.setXY(el, attributes['points']['from']);\r
2077                 }\r
2078                 else {\r
2079                     Ext.lib.Dom.setXY(el, Ext.lib.Dom.getXY(el));\r
2080                 }\r
2081 \r
2082                 start = this.getAttribute('points');\r
2083 \r
2084 \r
2085                 if (isset(attributes['points']['to'])) {\r
2086                     end = translateValues.call(this, attributes['points']['to'], start);\r
2087 \r
2088                     var pageXY = Ext.lib.Dom.getXY(this.getEl());\r
2089                     for (i = 0,len = control.length; i < len; ++i) {\r
2090                         control[i] = translateValues.call(this, control[i], start);\r
2091                     }\r
2092 \r
2093 \r
2094                 } else if (isset(attributes['points']['by'])) {\r
2095                     end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];\r
2096 \r
2097                     for (i = 0,len = control.length; i < len; ++i) {\r
2098                         control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];\r
2099                     }\r
2100                 }\r
2101 \r
2102                 this.runtimeAttributes[attr] = [start];\r
2103 \r
2104                 if (control.length > 0) {\r
2105                     this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);\r
2106                 }\r
2107 \r
2108                 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;\r
2109             }\r
2110             else {\r
2111                 superclass.setRuntimeAttribute.call(this, attr);\r
2112             }\r
2113         };\r
2114 \r
2115         var translateValues = function(val, start) {\r
2116             var pageXY = Ext.lib.Dom.getXY(this.getEl());\r
2117             val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];\r
2118 \r
2119             return val;\r
2120         };\r
2121 \r
2122         var isset = function(prop) {\r
2123             return (typeof prop !== 'undefined');\r
2124         };\r
2125     })();\r
2126 \r
2127 \r
2128     (function() {\r
2129         Ext.lib.Scroll = function(el, attributes, duration, method) {\r
2130             if (el) {\r
2131                 Ext.lib.Scroll.superclass.constructor.call(this, el, attributes, duration, method);\r
2132             }\r
2133         };\r
2134 \r
2135         Ext.extend(Ext.lib.Scroll, Ext.lib.ColorAnim);\r
2136 \r
2137 \r
2138         var Y = Ext.lib;\r
2139         var superclass = Y.Scroll.superclass;\r
2140         var proto = Y.Scroll.prototype;\r
2141 \r
2142         proto.toString = function() {\r
2143             var el = this.getEl();\r
2144             var id = el.id || el.tagName;\r
2145             return ("Scroll " + id);\r
2146         };\r
2147 \r
2148         proto.doMethod = function(attr, start, end) {\r
2149             var val = null;\r
2150 \r
2151             if (attr == 'scroll') {\r
2152                 val = [\r
2153                         this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),\r
2154                         this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)\r
2155                         ];\r
2156 \r
2157             } else {\r
2158                 val = superclass.doMethod.call(this, attr, start, end);\r
2159             }\r
2160             return val;\r
2161         };\r
2162 \r
2163         proto.getAttribute = function(attr) {\r
2164             var val = null;\r
2165             var el = this.getEl();\r
2166 \r
2167             if (attr == 'scroll') {\r
2168                 val = [ el.scrollLeft, el.scrollTop ];\r
2169             } else {\r
2170                 val = superclass.getAttribute.call(this, attr);\r
2171             }\r
2172 \r
2173             return val;\r
2174         };\r
2175 \r
2176         proto.setAttribute = function(attr, val, unit) {\r
2177             var el = this.getEl();\r
2178 \r
2179             if (attr == 'scroll') {\r
2180                 el.scrollLeft = val[0];\r
2181                 el.scrollTop = val[1];\r
2182             } else {\r
2183                 superclass.setAttribute.call(this, attr, val, unit);\r
2184             }\r
2185         };\r
2186     })();\r
2187 \r
2188 \r
2189 })();