]> ToastFreeware Gitweb - philipp/winterrodeln/wradmin.git/blob - wradmin/public/yui/yuiloader/yuiloader-debug.js
Start to use flask instead of pylons.
[philipp/winterrodeln/wradmin.git] / wradmin / public / yui / yuiloader / yuiloader-debug.js
1 /*
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 2.7.0
6 */
7 /**
8  * The YAHOO object is the single global object used by YUI Library.  It
9  * contains utility function for setting up namespaces, inheritance, and
10  * logging.  YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces
11  * created automatically for and used by the library.
12  * @module yahoo
13  * @title  YAHOO Global
14  */
15
16 /**
17  * YAHOO_config is not included as part of the library.  Instead it is an 
18  * object that can be defined by the implementer immediately before 
19  * including the YUI library.  The properties included in this object
20  * will be used to configure global properties needed as soon as the 
21  * library begins to load.
22  * @class YAHOO_config
23  * @static
24  */
25
26 /**
27  * A reference to a function that will be executed every time a YAHOO module
28  * is loaded.  As parameter, this function will receive the version
29  * information for the module. See <a href="YAHOO.env.html#getVersion">
30  * YAHOO.env.getVersion</a> for the description of the version data structure.
31  * @property listener
32  * @type Function
33  * @static
34  * @default undefined
35  */
36
37 /**
38  * Set to true if the library will be dynamically loaded after window.onload.
39  * Defaults to false 
40  * @property injecting
41  * @type boolean
42  * @static
43  * @default undefined
44  */
45
46 /**
47  * Instructs the yuiloader component to dynamically load yui components and
48  * their dependencies.  See the yuiloader documentation for more information
49  * about dynamic loading
50  * @property load
51  * @static
52  * @default undefined
53  * @see yuiloader
54  */
55
56 /**
57  * Forces the use of the supplied locale where applicable in the library
58  * @property locale
59  * @type string
60  * @static
61  * @default undefined
62  */
63
64 if (typeof YAHOO == "undefined" || !YAHOO) {
65     /**
66      * The YAHOO global namespace object.  If YAHOO is already defined, the
67      * existing YAHOO object will not be overwritten so that defined
68      * namespaces are preserved.
69      * @class YAHOO
70      * @static
71      */
72     var YAHOO = {};
73 }
74
75 /**
76  * Returns the namespace specified and creates it if it doesn't exist
77  * <pre>
78  * YAHOO.namespace("property.package");
79  * YAHOO.namespace("YAHOO.property.package");
80  * </pre>
81  * Either of the above would create YAHOO.property, then
82  * YAHOO.property.package
83  *
84  * Be careful when naming packages. Reserved words may work in some browsers
85  * and not others. For instance, the following will fail in Safari:
86  * <pre>
87  * YAHOO.namespace("really.long.nested.namespace");
88  * </pre>
89  * This fails because "long" is a future reserved word in ECMAScript
90  *
91  * For implementation code that uses YUI, do not create your components
92  * in the namespaces created by the library.  defined by YUI -- create 
93  * your own (YAHOO.util, YAHOO.widget, YAHOO.lang, YAHOO.env)
94  *
95  * @method namespace
96  * @static
97  * @param  {String*} arguments 1-n namespaces to create 
98  * @return {Object}  A reference to the last namespace object created
99  */
100 YAHOO.namespace = function() {
101     var a=arguments, o=null, i, j, d;
102     for (i=0; i<a.length; i=i+1) {
103         d=(""+a[i]).split(".");
104         o=YAHOO;
105
106         // YAHOO is implied, so it is ignored if it is included
107         for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
108             o[d[j]]=o[d[j]] || {};
109             o=o[d[j]];
110         }
111     }
112
113     return o;
114 };
115
116 /**
117  * Uses YAHOO.widget.Logger to output a log message, if the widget is
118  * available.
119  *
120  * @method log
121  * @static
122  * @param  {String}  msg  The message to log.
123  * @param  {String}  cat  The log category for the message.  Default
124  *                        categories are "info", "warn", "error", time".
125  *                        Custom categories can be used as well. (opt)
126  * @param  {String}  src  The source of the the message (opt)
127  * @return {Boolean}      True if the log operation was successful.
128  */
129 YAHOO.log = function(msg, cat, src) {
130     var l=YAHOO.widget.Logger;
131     if(l && l.log) {
132         return l.log(msg, cat, src);
133     } else {
134         return false;
135     }
136 };
137
138 /**
139  * Registers a module with the YAHOO object
140  * @method register
141  * @static
142  * @param {String}   name    the name of the module (event, slider, etc)
143  * @param {Function} mainClass a reference to class in the module.  This
144  *                             class will be tagged with the version info
145  *                             so that it will be possible to identify the
146  *                             version that is in use when multiple versions
147  *                             have loaded
148  * @param {Object}   data      metadata object for the module.  Currently it
149  *                             is expected to contain a "version" property
150  *                             and a "build" property at minimum.
151  */
152 YAHOO.register = function(name, mainClass, data) {
153     var mods = YAHOO.env.modules, m, v, b, ls, i;
154
155     if (!mods[name]) {
156         mods[name] = { 
157             versions:[], 
158             builds:[] 
159         };
160     }
161
162     m  = mods[name];
163     v  = data.version;
164     b  = data.build;
165     ls = YAHOO.env.listeners;
166
167     m.name = name;
168     m.version = v;
169     m.build = b;
170     m.versions.push(v);
171     m.builds.push(b);
172     m.mainClass = mainClass;
173
174     // fire the module load listeners
175     for (i=0;i<ls.length;i=i+1) {
176         ls[i](m);
177     }
178     // label the main class
179     if (mainClass) {
180         mainClass.VERSION = v;
181         mainClass.BUILD = b;
182     } else {
183         YAHOO.log("mainClass is undefined for module " + name, "warn");
184     }
185 };
186
187 /**
188  * YAHOO.env is used to keep track of what is known about the YUI library and
189  * the browsing environment
190  * @class YAHOO.env
191  * @static
192  */
193 YAHOO.env = YAHOO.env || {
194
195     /**
196      * Keeps the version info for all YUI modules that have reported themselves
197      * @property modules
198      * @type Object[]
199      */
200     modules: [],
201     
202     /**
203      * List of functions that should be executed every time a YUI module
204      * reports itself.
205      * @property listeners
206      * @type Function[]
207      */
208     listeners: []
209 };
210
211 /**
212  * Returns the version data for the specified module:
213  *      <dl>
214  *      <dt>name:</dt>      <dd>The name of the module</dd>
215  *      <dt>version:</dt>   <dd>The version in use</dd>
216  *      <dt>build:</dt>     <dd>The build number in use</dd>
217  *      <dt>versions:</dt>  <dd>All versions that were registered</dd>
218  *      <dt>builds:</dt>    <dd>All builds that were registered.</dd>
219  *      <dt>mainClass:</dt> <dd>An object that was was stamped with the
220  *                 current version and build. If 
221  *                 mainClass.VERSION != version or mainClass.BUILD != build,
222  *                 multiple versions of pieces of the library have been
223  *                 loaded, potentially causing issues.</dd>
224  *       </dl>
225  *
226  * @method getVersion
227  * @static
228  * @param {String}  name the name of the module (event, slider, etc)
229  * @return {Object} The version info
230  */
231 YAHOO.env.getVersion = function(name) {
232     return YAHOO.env.modules[name] || null;
233 };
234
235 /**
236  * Do not fork for a browser if it can be avoided.  Use feature detection when
237  * you can.  Use the user agent as a last resort.  YAHOO.env.ua stores a version
238  * number for the browser engine, 0 otherwise.  This value may or may not map
239  * to the version number of the browser using the engine.  The value is 
240  * presented as a float so that it can easily be used for boolean evaluation 
241  * as well as for looking for a particular range of versions.  Because of this, 
242  * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 
243  * reports 1.8).
244  * @class YAHOO.env.ua
245  * @static
246  */
247 YAHOO.env.ua = function() {
248     var o={
249
250         /**
251          * Internet Explorer version number or 0.  Example: 6
252          * @property ie
253          * @type float
254          */
255         ie:0,
256
257         /**
258          * Opera version number or 0.  Example: 9.2
259          * @property opera
260          * @type float
261          */
262         opera:0,
263
264         /**
265          * Gecko engine revision number.  Will evaluate to 1 if Gecko 
266          * is detected but the revision could not be found. Other browsers
267          * will be 0.  Example: 1.8
268          * <pre>
269          * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
270          * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
271          * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
272          * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
273          * </pre>
274          * @property gecko
275          * @type float
276          */
277         gecko:0,
278
279         /**
280          * AppleWebKit version.  KHTML browsers that are not WebKit browsers 
281          * will evaluate to 1, other browsers 0.  Example: 418.9.1
282          * <pre>
283          * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 
284          *                                   latest available for Mac OSX 10.3.
285          * Safari 2.0.2:         416     <-- hasOwnProperty introduced
286          * Safari 2.0.4:         418     <-- preventDefault fixed
287          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
288          *                                   different versions of webkit
289          * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
290          *                                   updated, but not updated
291          *                                   to the latest patch.
292          * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
293          *                                   and many major issues fixed).  
294          * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
295          *                                   string when hitting yahoo.com and 
296          *                                   flickr.com.
297          * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
298          *                                   from 2.x via the 10.4.11 OS patch
299          * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
300          *                                   yahoo.com user agent hack removed.
301          *                                   
302          * </pre>
303          * http://developer.apple.com/internet/safari/uamatrix.html
304          * @property webkit
305          * @type float
306          */
307         webkit: 0,
308
309         /**
310          * The mobile property will be set to a string containing any relevant
311          * user agent information when a modern mobile browser is detected.
312          * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
313          * devices with the WebKit-based browser, and Opera Mini.  
314          * @property mobile 
315          * @type string
316          */
317         mobile: null,
318
319         /**
320          * Adobe AIR version number or 0.  Only populated if webkit is detected.
321          * Example: 1.0
322          * @property air
323          * @type float
324          */
325         air: 0,
326
327         /**
328          * Google Caja version number or 0.
329          * @property caja
330          * @type float
331          */
332         caja: 0
333
334     },
335
336     ua = navigator.userAgent, 
337     
338     m;
339
340     // Modern KHTML browsers should qualify as Safari X-Grade
341     if ((/KHTML/).test(ua)) {
342         o.webkit=1;
343     }
344     // Modern WebKit browsers are at least X-Grade
345     m=ua.match(/AppleWebKit\/([^\s]*)/);
346     if (m&&m[1]) {
347         o.webkit=parseFloat(m[1]);
348
349         // Mobile browser check
350         if (/ Mobile\//.test(ua)) {
351             o.mobile = "Apple"; // iPhone or iPod Touch
352         } else {
353             m=ua.match(/NokiaN[^\/]*/);
354             if (m) {
355                 o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
356             }
357         }
358
359         m=ua.match(/AdobeAIR\/([^\s]*)/);
360         if (m) {
361             o.air = m[0]; // Adobe AIR 1.0 or better
362         }
363
364     }
365
366     if (!o.webkit) { // not webkit
367         // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
368         m=ua.match(/Opera[\s\/]([^\s]*)/);
369         if (m&&m[1]) {
370             o.opera=parseFloat(m[1]);
371             m=ua.match(/Opera Mini[^;]*/);
372             if (m) {
373                 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
374             }
375         } else { // not opera or webkit
376             m=ua.match(/MSIE\s([^;]*)/);
377             if (m&&m[1]) {
378                 o.ie=parseFloat(m[1]);
379             } else { // not opera, webkit, or ie
380                 m=ua.match(/Gecko\/([^\s]*)/);
381                 if (m) {
382                     o.gecko=1; // Gecko detected, look for revision
383                     m=ua.match(/rv:([^\s\)]*)/);
384                     if (m&&m[1]) {
385                         o.gecko=parseFloat(m[1]);
386                     }
387                 }
388             }
389         }
390     }
391
392     m=ua.match(/Caja\/([^\s]*)/);
393     if (m&&m[1]) {
394         o.caja=parseFloat(m[1]);
395     }
396     
397     return o;
398 }();
399
400 /*
401  * Initializes the global by creating the default namespaces and applying
402  * any new configuration information that is detected.  This is the setup
403  * for env.
404  * @method init
405  * @static
406  * @private
407  */
408 (function() {
409     YAHOO.namespace("util", "widget", "example");
410     /*global YAHOO_config*/
411     if ("undefined" !== typeof YAHOO_config) {
412         var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i;
413         if (l) {
414             // if YAHOO is loaded multiple times we need to check to see if
415             // this is a new config object.  If it is, add the new component
416             // load listener to the stack
417             for (i=0;i<ls.length;i=i+1) {
418                 if (ls[i]==l) {
419                     unique=false;
420                     break;
421                 }
422             }
423             if (unique) {
424                 ls.push(l);
425             }
426         }
427     }
428 })();
429 /**
430  * Provides the language utilites and extensions used by the library
431  * @class YAHOO.lang
432  */
433 YAHOO.lang = YAHOO.lang || {};
434
435 (function() {
436
437
438 var L = YAHOO.lang,
439
440     ARRAY_TOSTRING = '[object Array]',
441     FUNCTION_TOSTRING = '[object Function]',
442     OP = Object.prototype,
443
444     // ADD = ["toString", "valueOf", "hasOwnProperty"],
445     ADD = ["toString", "valueOf"],
446
447     OB = {
448
449     /**
450      * Determines wheather or not the provided object is an array.
451      * @method isArray
452      * @param {any} o The object being testing
453      * @return {boolean} the result
454      */
455     isArray: function(o) { 
456         return OP.toString.apply(o) === ARRAY_TOSTRING;
457     },
458
459     /**
460      * Determines whether or not the provided object is a boolean
461      * @method isBoolean
462      * @param {any} o The object being testing
463      * @return {boolean} the result
464      */
465     isBoolean: function(o) {
466         return typeof o === 'boolean';
467     },
468     
469     /**
470      * Determines whether or not the provided object is a function.
471      * Note: Internet Explorer thinks certain functions are objects:
472      *
473      * var obj = document.createElement("object");
474      * YAHOO.lang.isFunction(obj.getAttribute) // reports false in IE
475      *
476      * var input = document.createElement("input"); // append to body
477      * YAHOO.lang.isFunction(input.focus) // reports false in IE
478      *
479      * You will have to implement additional tests if these functions
480      * matter to you.
481      *
482      * @method isFunction
483      * @param {any} o The object being testing
484      * @return {boolean} the result
485      */
486     isFunction: function(o) {
487         return OP.toString.apply(o) === FUNCTION_TOSTRING;
488     },
489         
490     /**
491      * Determines whether or not the provided object is null
492      * @method isNull
493      * @param {any} o The object being testing
494      * @return {boolean} the result
495      */
496     isNull: function(o) {
497         return o === null;
498     },
499         
500     /**
501      * Determines whether or not the provided object is a legal number
502      * @method isNumber
503      * @param {any} o The object being testing
504      * @return {boolean} the result
505      */
506     isNumber: function(o) {
507         return typeof o === 'number' && isFinite(o);
508     },
509       
510     /**
511      * Determines whether or not the provided object is of type object
512      * or function
513      * @method isObject
514      * @param {any} o The object being testing
515      * @return {boolean} the result
516      */  
517     isObject: function(o) {
518 return (o && (typeof o === 'object' || L.isFunction(o))) || false;
519     },
520         
521     /**
522      * Determines whether or not the provided object is a string
523      * @method isString
524      * @param {any} o The object being testing
525      * @return {boolean} the result
526      */
527     isString: function(o) {
528         return typeof o === 'string';
529     },
530         
531     /**
532      * Determines whether or not the provided object is undefined
533      * @method isUndefined
534      * @param {any} o The object being testing
535      * @return {boolean} the result
536      */
537     isUndefined: function(o) {
538         return typeof o === 'undefined';
539     },
540     
541  
542     /**
543      * IE will not enumerate native functions in a derived object even if the
544      * function was overridden.  This is a workaround for specific functions 
545      * we care about on the Object prototype. 
546      * @property _IEEnumFix
547      * @param {Function} r  the object to receive the augmentation
548      * @param {Function} s  the object that supplies the properties to augment
549      * @static
550      * @private
551      */
552     _IEEnumFix: (YAHOO.env.ua.ie) ? function(r, s) {
553             var i, fname, f;
554             for (i=0;i<ADD.length;i=i+1) {
555
556                 fname = ADD[i];
557                 f = s[fname];
558
559                 if (L.isFunction(f) && f!=OP[fname]) {
560                     r[fname]=f;
561                 }
562             }
563     } : function(){},
564        
565     /**
566      * Utility to set up the prototype, constructor and superclass properties to
567      * support an inheritance strategy that can chain constructors and methods.
568      * Static members will not be inherited.
569      *
570      * @method extend
571      * @static
572      * @param {Function} subc   the object to modify
573      * @param {Function} superc the object to inherit
574      * @param {Object} overrides  additional properties/methods to add to the
575      *                              subclass prototype.  These will override the
576      *                              matching items obtained from the superclass 
577      *                              if present.
578      */
579     extend: function(subc, superc, overrides) {
580         if (!superc||!subc) {
581             throw new Error("extend failed, please check that " +
582                             "all dependencies are included.");
583         }
584         var F = function() {}, i;
585         F.prototype=superc.prototype;
586         subc.prototype=new F();
587         subc.prototype.constructor=subc;
588         subc.superclass=superc.prototype;
589         if (superc.prototype.constructor == OP.constructor) {
590             superc.prototype.constructor=superc;
591         }
592     
593         if (overrides) {
594             for (i in overrides) {
595                 if (L.hasOwnProperty(overrides, i)) {
596                     subc.prototype[i]=overrides[i];
597                 }
598             }
599
600             L._IEEnumFix(subc.prototype, overrides);
601         }
602     },
603    
604     /**
605      * Applies all properties in the supplier to the receiver if the
606      * receiver does not have these properties yet.  Optionally, one or 
607      * more methods/properties can be specified (as additional 
608      * parameters).  This option will overwrite the property if receiver 
609      * has it already.  If true is passed as the third parameter, all 
610      * properties will be applied and _will_ overwrite properties in 
611      * the receiver.
612      *
613      * @method augmentObject
614      * @static
615      * @since 2.3.0
616      * @param {Function} r  the object to receive the augmentation
617      * @param {Function} s  the object that supplies the properties to augment
618      * @param {String*|boolean}  arguments zero or more properties methods 
619      *        to augment the receiver with.  If none specified, everything
620      *        in the supplier will be used unless it would
621      *        overwrite an existing property in the receiver. If true
622      *        is specified as the third parameter, all properties will
623      *        be applied and will overwrite an existing property in
624      *        the receiver
625      */
626     augmentObject: function(r, s) {
627         if (!s||!r) {
628             throw new Error("Absorb failed, verify dependencies.");
629         }
630         var a=arguments, i, p, overrideList=a[2];
631         if (overrideList && overrideList!==true) { // only absorb the specified properties
632             for (i=2; i<a.length; i=i+1) {
633                 r[a[i]] = s[a[i]];
634             }
635         } else { // take everything, overwriting only if the third parameter is true
636             for (p in s) { 
637                 if (overrideList || !(p in r)) {
638                     r[p] = s[p];
639                 }
640             }
641             
642             L._IEEnumFix(r, s);
643         }
644     },
645  
646     /**
647      * Same as YAHOO.lang.augmentObject, except it only applies prototype properties
648      * @see YAHOO.lang.augmentObject
649      * @method augmentProto
650      * @static
651      * @param {Function} r  the object to receive the augmentation
652      * @param {Function} s  the object that supplies the properties to augment
653      * @param {String*|boolean}  arguments zero or more properties methods 
654      *        to augment the receiver with.  If none specified, everything 
655      *        in the supplier will be used unless it would overwrite an existing 
656      *        property in the receiver.  if true is specified as the third 
657      *        parameter, all properties will be applied and will overwrite an 
658      *        existing property in the receiver
659      */
660     augmentProto: function(r, s) {
661         if (!s||!r) {
662             throw new Error("Augment failed, verify dependencies.");
663         }
664         //var a=[].concat(arguments);
665         var a=[r.prototype,s.prototype], i;
666         for (i=2;i<arguments.length;i=i+1) {
667             a.push(arguments[i]);
668         }
669         L.augmentObject.apply(this, a);
670     },
671
672       
673     /**
674      * Returns a simple string representation of the object or array.
675      * Other types of objects will be returned unprocessed.  Arrays
676      * are expected to be indexed.  Use object notation for
677      * associative arrays.
678      * @method dump
679      * @since 2.3.0
680      * @param o {Object} The object to dump
681      * @param d {int} How deep to recurse child objects, default 3
682      * @return {String} the dump result
683      */
684     dump: function(o, d) {
685         var i,len,s=[],OBJ="{...}",FUN="f(){...}",
686             COMMA=', ', ARROW=' => ';
687
688         // Cast non-objects to string
689         // Skip dates because the std toString is what we want
690         // Skip HTMLElement-like objects because trying to dump 
691         // an element will cause an unhandled exception in FF 2.x
692         if (!L.isObject(o)) {
693             return o + "";
694         } else if (o instanceof Date || ("nodeType" in o && "tagName" in o)) {
695             return o;
696         } else if  (L.isFunction(o)) {
697             return FUN;
698         }
699
700         // dig into child objects the depth specifed. Default 3
701         d = (L.isNumber(d)) ? d : 3;
702
703         // arrays [1, 2, 3]
704         if (L.isArray(o)) {
705             s.push("[");
706             for (i=0,len=o.length;i<len;i=i+1) {
707                 if (L.isObject(o[i])) {
708                     s.push((d > 0) ? L.dump(o[i], d-1) : OBJ);
709                 } else {
710                     s.push(o[i]);
711                 }
712                 s.push(COMMA);
713             }
714             if (s.length > 1) {
715                 s.pop();
716             }
717             s.push("]");
718         // objects {k1 => v1, k2 => v2}
719         } else {
720             s.push("{");
721             for (i in o) {
722                 if (L.hasOwnProperty(o, i)) {
723                     s.push(i + ARROW);
724                     if (L.isObject(o[i])) {
725                         s.push((d > 0) ? L.dump(o[i], d-1) : OBJ);
726                     } else {
727                         s.push(o[i]);
728                     }
729                     s.push(COMMA);
730                 }
731             }
732             if (s.length > 1) {
733                 s.pop();
734             }
735             s.push("}");
736         }
737
738         return s.join("");
739     },
740
741     /**
742      * Does variable substitution on a string. It scans through the string 
743      * looking for expressions enclosed in { } braces. If an expression 
744      * is found, it is used a key on the object.  If there is a space in
745      * the key, the first word is used for the key and the rest is provided
746      * to an optional function to be used to programatically determine the
747      * value (the extra information might be used for this decision). If 
748      * the value for the key in the object, or what is returned from the
749      * function has a string value, number value, or object value, it is 
750      * substituted for the bracket expression and it repeats.  If this
751      * value is an object, it uses the Object's toString() if this has
752      * been overridden, otherwise it does a shallow dump of the key/value
753      * pairs.
754      * @method substitute
755      * @since 2.3.0
756      * @param s {String} The string that will be modified.
757      * @param o {Object} An object containing the replacement values
758      * @param f {Function} An optional function that can be used to
759      *                     process each match.  It receives the key,
760      *                     value, and any extra metadata included with
761      *                     the key inside of the braces.
762      * @return {String} the substituted string
763      */
764     substitute: function (s, o, f) {
765         var i, j, k, key, v, meta, saved=[], token, 
766             DUMP='dump', SPACE=' ', LBRACE='{', RBRACE='}',
767             dump;
768
769
770         for (;;) {
771             i = s.lastIndexOf(LBRACE);
772             if (i < 0) {
773                 break;
774             }
775             j = s.indexOf(RBRACE, i);
776             if (i + 1 >= j) {
777                 break;
778             }
779
780             //Extract key and meta info 
781             token = s.substring(i + 1, j);
782             key = token;
783             meta = null;
784             k = key.indexOf(SPACE);
785             if (k > -1) {
786                 meta = key.substring(k + 1);
787                 key = key.substring(0, k);
788             }
789
790             // lookup the value
791             v = o[key];
792
793             // if a substitution function was provided, execute it
794             if (f) {
795                 v = f(key, v, meta);
796             }
797
798             if (L.isObject(v)) {
799                 if (L.isArray(v)) {
800                     v = L.dump(v, parseInt(meta, 10));
801                 } else {
802                     meta = meta || "";
803
804                     // look for the keyword 'dump', if found force obj dump
805                     dump = meta.indexOf(DUMP);
806                     if (dump > -1) {
807                         meta = meta.substring(4);
808                     }
809
810                     // use the toString if it is not the Object toString 
811                     // and the 'dump' meta info was not found
812                     if (v.toString===OP.toString || dump>-1) {
813                         v = L.dump(v, parseInt(meta, 10));
814                     } else {
815                         v = v.toString();
816                     }
817                 }
818             } else if (!L.isString(v) && !L.isNumber(v)) {
819                 // This {block} has no replace string. Save it for later.
820                 v = "~-" + saved.length + "-~";
821                 saved[saved.length] = token;
822
823                 // break;
824             }
825
826             s = s.substring(0, i) + v + s.substring(j + 1);
827
828
829         }
830
831         // restore saved {block}s
832         for (i=saved.length-1; i>=0; i=i-1) {
833             s = s.replace(new RegExp("~-" + i + "-~"), "{"  + saved[i] + "}", "g");
834         }
835
836         return s;
837     },
838
839
840     /**
841      * Returns a string without any leading or trailing whitespace.  If 
842      * the input is not a string, the input will be returned untouched.
843      * @method trim
844      * @since 2.3.0
845      * @param s {string} the string to trim
846      * @return {string} the trimmed string
847      */
848     trim: function(s){
849         try {
850             return s.replace(/^\s+|\s+$/g, "");
851         } catch(e) {
852             return s;
853         }
854     },
855
856     /**
857      * Returns a new object containing all of the properties of
858      * all the supplied objects.  The properties from later objects
859      * will overwrite those in earlier objects.
860      * @method merge
861      * @since 2.3.0
862      * @param arguments {Object*} the objects to merge
863      * @return the new merged object
864      */
865     merge: function() {
866         var o={}, a=arguments, l=a.length, i;
867         for (i=0; i<l; i=i+1) {
868             L.augmentObject(o, a[i], true);
869         }
870         return o;
871     },
872
873     /**
874      * Executes the supplied function in the context of the supplied 
875      * object 'when' milliseconds later.  Executes the function a 
876      * single time unless periodic is set to true.
877      * @method later
878      * @since 2.4.0
879      * @param when {int} the number of milliseconds to wait until the fn 
880      * is executed
881      * @param o the context object
882      * @param fn {Function|String} the function to execute or the name of 
883      * the method in the 'o' object to execute
884      * @param data [Array] data that is provided to the function.  This accepts
885      * either a single item or an array.  If an array is provided, the
886      * function is executed with one parameter for each array item.  If
887      * you need to pass a single array parameter, it needs to be wrapped in
888      * an array [myarray]
889      * @param periodic {boolean} if true, executes continuously at supplied 
890      * interval until canceled
891      * @return a timer object. Call the cancel() method on this object to 
892      * stop the timer.
893      */
894     later: function(when, o, fn, data, periodic) {
895         when = when || 0; 
896         o = o || {};
897         var m=fn, d=data, f, r;
898
899         if (L.isString(fn)) {
900             m = o[fn];
901         }
902
903         if (!m) {
904             throw new TypeError("method undefined");
905         }
906
907         if (!L.isArray(d)) {
908             d = [data];
909         }
910
911         f = function() {
912             m.apply(o, d);
913         };
914
915         r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
916
917         return {
918             interval: periodic,
919             cancel: function() {
920                 if (this.interval) {
921                     clearInterval(r);
922                 } else {
923                     clearTimeout(r);
924                 }
925             }
926         };
927     },
928     
929     /**
930      * A convenience method for detecting a legitimate non-null value.
931      * Returns false for null/undefined/NaN, true for other values, 
932      * including 0/false/''
933      * @method isValue
934      * @since 2.3.0
935      * @param o {any} the item to test
936      * @return {boolean} true if it is not null/undefined/NaN || false
937      */
938     isValue: function(o) {
939         // return (o || o === false || o === 0 || o === ''); // Infinity fails
940 return (L.isObject(o) || L.isString(o) || L.isNumber(o) || L.isBoolean(o));
941     }
942
943 };
944
945 /**
946  * Determines whether or not the property was added
947  * to the object instance.  Returns false if the property is not present
948  * in the object, or was inherited from the prototype.
949  * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x.
950  * There is a discrepancy between YAHOO.lang.hasOwnProperty and
951  * Object.prototype.hasOwnProperty when the property is a primitive added to
952  * both the instance AND prototype with the same value:
953  * <pre>
954  * var A = function() {};
955  * A.prototype.foo = 'foo';
956  * var a = new A();
957  * a.foo = 'foo';
958  * alert(a.hasOwnProperty('foo')); // true
959  * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback
960  * </pre>
961  * @method hasOwnProperty
962  * @param {any} o The object being testing
963  * @param prop {string} the name of the property to test
964  * @return {boolean} the result
965  */
966 L.hasOwnProperty = (OP.hasOwnProperty) ?
967     function(o, prop) {
968         return o && o.hasOwnProperty(prop);
969     } : function(o, prop) {
970         return !L.isUndefined(o[prop]) && 
971                 o.constructor.prototype[prop] !== o[prop];
972     };
973
974 // new lang wins
975 OB.augmentObject(L, OB, true);
976
977 /*
978  * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a>
979  * @class YAHOO.util.Lang
980  */
981 YAHOO.util.Lang = L;
982  
983 /**
984  * Same as YAHOO.lang.augmentObject, except it only applies prototype 
985  * properties.  This is an alias for augmentProto.
986  * @see YAHOO.lang.augmentObject
987  * @method augment
988  * @static
989  * @param {Function} r  the object to receive the augmentation
990  * @param {Function} s  the object that supplies the properties to augment
991  * @param {String*|boolean}  arguments zero or more properties methods to 
992  *        augment the receiver with.  If none specified, everything
993  *        in the supplier will be used unless it would
994  *        overwrite an existing property in the receiver.  if true
995  *        is specified as the third parameter, all properties will
996  *        be applied and will overwrite an existing property in
997  *        the receiver
998  */
999 L.augment = L.augmentProto;
1000
1001 /**
1002  * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a>
1003  * @for YAHOO
1004  * @method augment
1005  * @static
1006  * @param {Function} r  the object to receive the augmentation
1007  * @param {Function} s  the object that supplies the properties to augment
1008  * @param {String*}  arguments zero or more properties methods to 
1009  *        augment the receiver with.  If none specified, everything
1010  *        in the supplier will be used unless it would
1011  *        overwrite an existing property in the receiver
1012  */
1013 YAHOO.augment = L.augmentProto;
1014        
1015 /**
1016  * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a>
1017  * @method extend
1018  * @static
1019  * @param {Function} subc   the object to modify
1020  * @param {Function} superc the object to inherit
1021  * @param {Object} overrides  additional properties/methods to add to the
1022  *        subclass prototype.  These will override the
1023  *        matching items obtained from the superclass if present.
1024  */
1025 YAHOO.extend = L.extend;
1026
1027 })();
1028 YAHOO.register("yahoo", YAHOO, {version: "2.7.0", build: "1799"});
1029 /**
1030  * Provides a mechanism to fetch remote resources and
1031  * insert them into a document
1032  * @module get
1033  * @requires yahoo
1034  */
1035
1036 /**
1037  * Fetches and inserts one or more script or link nodes into the document 
1038  * @namespace YAHOO.util
1039  * @class YAHOO.util.Get
1040  */
1041 YAHOO.util.Get = function() {
1042
1043     /**
1044      * hash of queues to manage multiple requests
1045      * @property queues
1046      * @private
1047      */
1048     var queues={}, 
1049         
1050     /**
1051      * queue index used to generate transaction ids
1052      * @property qidx
1053      * @type int
1054      * @private
1055      */
1056         qidx=0, 
1057         
1058     /**
1059      * node index used to generate unique node ids
1060      * @property nidx
1061      * @type int
1062      * @private
1063      */
1064         nidx=0, 
1065
1066         // ridx=0,
1067
1068         // sandboxFrame=null,
1069
1070     /**
1071      * interal property used to prevent multiple simultaneous purge 
1072      * processes
1073      * @property purging
1074      * @type boolean
1075      * @private
1076      */
1077         purging=false,
1078
1079         ua=YAHOO.env.ua, 
1080         
1081         lang=YAHOO.lang;
1082     
1083     /** 
1084      * Generates an HTML element, this is not appended to a document
1085      * @method _node
1086      * @param type {string} the type of element
1087      * @param attr {string} the attributes
1088      * @param win {Window} optional window to create the element in
1089      * @return {HTMLElement} the generated node
1090      * @private
1091      */
1092     var _node = function(type, attr, win) {
1093         var w = win || window, d=w.document, n=d.createElement(type);
1094
1095         for (var i in attr) {
1096             if (attr[i] && YAHOO.lang.hasOwnProperty(attr, i)) {
1097                 n.setAttribute(i, attr[i]);
1098             }
1099         }
1100
1101         return n;
1102     };
1103
1104     /**
1105      * Generates a link node
1106      * @method _linkNode
1107      * @param url {string} the url for the css file
1108      * @param win {Window} optional window to create the node in
1109      * @return {HTMLElement} the generated node
1110      * @private
1111      */
1112     var _linkNode = function(url, win, charset) {
1113         var c = charset || "utf-8";
1114         return _node("link", {
1115                 "id":      "yui__dyn_" + (nidx++),
1116                 "type":    "text/css",
1117                 "charset": c,
1118                 "rel":     "stylesheet",
1119                 "href":    url
1120             }, win);
1121     };
1122
1123     /**
1124      * Generates a script node
1125      * @method _scriptNode
1126      * @param url {string} the url for the script file
1127      * @param win {Window} optional window to create the node in
1128      * @return {HTMLElement} the generated node
1129      * @private
1130      */
1131     var _scriptNode = function(url, win, charset) {
1132         var c = charset || "utf-8";
1133         return _node("script", {
1134                 "id":      "yui__dyn_" + (nidx++),
1135                 "type":    "text/javascript",
1136                 "charset": c,
1137                 "src":     url
1138             }, win);
1139     };
1140
1141     /**
1142      * Returns the data payload for callback functions
1143      * @method _returnData
1144      * @private
1145      */
1146     var _returnData = function(q, msg) {
1147         return {
1148                 tId: q.tId,
1149                 win: q.win,
1150                 data: q.data,
1151                 nodes: q.nodes,
1152                 msg: msg,
1153                 purge: function() {
1154                     _purge(this.tId);
1155                 }
1156             };
1157     };
1158
1159     var _get = function(nId, tId) {
1160         var q = queues[tId],
1161             n = (lang.isString(nId)) ? q.win.document.getElementById(nId) : nId;
1162         if (!n) {
1163             _fail(tId, "target node not found: " + nId);
1164         }
1165
1166         return n;
1167     };
1168
1169     /*
1170      * The request failed, execute fail handler with whatever
1171      * was accomplished.  There isn't a failure case at the
1172      * moment unless you count aborted transactions
1173      * @method _fail
1174      * @param id {string} the id of the request
1175      * @private
1176      */
1177     var _fail = function(id, msg) {
1178         var q = queues[id];
1179         // execute failure callback
1180         if (q.onFailure) {
1181             var sc=q.scope || q.win;
1182             q.onFailure.call(sc, _returnData(q, msg));
1183         }
1184     };
1185
1186     /**
1187      * The request is complete, so executing the requester's callback
1188      * @method _finish
1189      * @param id {string} the id of the request
1190      * @private
1191      */
1192     var _finish = function(id) {
1193         var q = queues[id];
1194         q.finished = true;
1195
1196         if (q.aborted) {
1197             var msg = "transaction " + id + " was aborted";
1198             _fail(id, msg);
1199             return;
1200         }
1201
1202         // execute success callback
1203         if (q.onSuccess) {
1204             var sc=q.scope || q.win;
1205             q.onSuccess.call(sc, _returnData(q));
1206         }
1207     };
1208
1209     /**
1210      * Timeout detected
1211      * @method _timeout
1212      * @param id {string} the id of the request
1213      * @private
1214      */
1215     var _timeout = function(id) {
1216         var q = queues[id];
1217         if (q.onTimeout) {
1218             var sc=q.scope || q;
1219             q.onTimeout.call(sc, _returnData(q));
1220         }
1221     };
1222
1223     /**
1224      * Loads the next item for a given request
1225      * @method _next
1226      * @param id {string} the id of the request
1227      * @param loaded {string} the url that was just loaded, if any
1228      * @private
1229      */
1230     var _next = function(id, loaded) {
1231         var q = queues[id];
1232
1233         if (q.timer) {
1234             // Y.log('cancel timer');
1235             q.timer.cancel();
1236         }
1237
1238         if (q.aborted) {
1239             var msg = "transaction " + id + " was aborted";
1240             _fail(id, msg);
1241             return;
1242         }
1243
1244         if (loaded) {
1245             q.url.shift(); 
1246             if (q.varName) {
1247                 q.varName.shift(); 
1248             }
1249         } else {
1250             // This is the first pass: make sure the url is an array
1251             q.url = (lang.isString(q.url)) ? [q.url] : q.url;
1252             if (q.varName) {
1253                 q.varName = (lang.isString(q.varName)) ? [q.varName] : q.varName;
1254             }
1255         }
1256
1257         var w=q.win, d=w.document, h=d.getElementsByTagName("head")[0], n;
1258
1259         if (q.url.length === 0) {
1260             // Safari 2.x workaround - There is no way to know when 
1261             // a script is ready in versions of Safari prior to 3.x.
1262             // Adding an extra node reduces the problem, but doesn't
1263             // eliminate it completely because the browser executes
1264             // them asynchronously. 
1265             if (q.type === "script" && ua.webkit && ua.webkit < 420 && 
1266                     !q.finalpass && !q.varName) {
1267                 // Add another script node.  This does not guarantee that the
1268                 // scripts will execute in order, but it does appear to fix the
1269                 // problem on fast connections more effectively than using an
1270                 // arbitrary timeout.  It is possible that the browser does
1271                 // block subsequent script execution in this case for a limited
1272                 // time.
1273                 var extra = _scriptNode(null, q.win, q.charset);
1274                 extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
1275                 q.nodes.push(extra); h.appendChild(extra);
1276
1277             } else {
1278                 _finish(id);
1279             }
1280
1281             return;
1282         } 
1283
1284
1285         var url = q.url[0];
1286
1287         // if the url is undefined, this is probably a trailing comma problem in IE
1288         if (!url) {
1289             q.url.shift(); 
1290             return _next(id);
1291         }
1292
1293
1294         if (q.timeout) {
1295             // Y.log('create timer');
1296             q.timer = lang.later(q.timeout, q, _timeout, id);
1297         }
1298
1299         if (q.type === "script") {
1300             n = _scriptNode(url, w, q.charset);
1301         } else {
1302             n = _linkNode(url, w, q.charset);
1303         }
1304
1305         // track this node's load progress
1306         _track(q.type, n, id, url, w, q.url.length);
1307
1308         // add the node to the queue so we can return it to the user supplied callback
1309         q.nodes.push(n);
1310
1311         // add it to the head or insert it before 'insertBefore'
1312         if (q.insertBefore) {
1313             var s = _get(q.insertBefore, id);
1314             if (s) {
1315                 s.parentNode.insertBefore(n, s);
1316             }
1317         } else {
1318             h.appendChild(n);
1319         }
1320         
1321
1322         // FireFox does not support the onload event for link nodes, so there is
1323         // no way to make the css requests synchronous. This means that the css 
1324         // rules in multiple files could be applied out of order in this browser
1325         // if a later request returns before an earlier one.  Safari too.
1326         if ((ua.webkit || ua.gecko) && q.type === "css") {
1327             _next(id, url);
1328         }
1329     };
1330
1331     /**
1332      * Removes processed queues and corresponding nodes
1333      * @method _autoPurge
1334      * @private
1335      */
1336     var _autoPurge = function() {
1337
1338         if (purging) {
1339             return;
1340         }
1341
1342         purging = true;
1343         for (var i in queues) {
1344             var q = queues[i];
1345             if (q.autopurge && q.finished) {
1346                 _purge(q.tId);
1347                 delete queues[i];
1348             }
1349         }
1350
1351         purging = false;
1352     };
1353
1354     /**
1355      * Removes the nodes for the specified queue
1356      * @method _purge
1357      * @private
1358      */
1359     var _purge = function(tId) {
1360         var q=queues[tId];
1361         if (q) {
1362             var n=q.nodes, l=n.length, d=q.win.document, 
1363                 h=d.getElementsByTagName("head")[0];
1364
1365             if (q.insertBefore) {
1366                 var s = _get(q.insertBefore, tId);
1367                 if (s) {
1368                     h = s.parentNode;
1369                 }
1370             }
1371
1372             for (var i=0; i<l; i=i+1) {
1373                 h.removeChild(n[i]);
1374             }
1375
1376             q.nodes = [];
1377         }
1378     };
1379
1380     /**
1381      * Saves the state for the request and begins loading
1382      * the requested urls
1383      * @method queue
1384      * @param type {string} the type of node to insert
1385      * @param url {string} the url to load
1386      * @param opts the hash of options for this request
1387      * @private
1388      */
1389     var _queue = function(type, url, opts) {
1390
1391         var id = "q" + (qidx++);
1392         opts = opts || {};
1393
1394         if (qidx % YAHOO.util.Get.PURGE_THRESH === 0) {
1395             _autoPurge();
1396         }
1397
1398         queues[id] = lang.merge(opts, {
1399             tId: id,
1400             type: type,
1401             url: url,
1402             finished: false,
1403             aborted: false,
1404             nodes: []
1405         });
1406
1407         var q = queues[id];
1408         q.win = q.win || window;
1409         q.scope = q.scope || q.win;
1410         q.autopurge = ("autopurge" in q) ? q.autopurge : 
1411                       (type === "script") ? true : false;
1412
1413         lang.later(0, q, _next, id);
1414
1415         return {
1416             tId: id
1417         };
1418     };
1419
1420     /**
1421      * Detects when a node has been loaded.  In the case of
1422      * script nodes, this does not guarantee that contained
1423      * script is ready to use.
1424      * @method _track
1425      * @param type {string} the type of node to track
1426      * @param n {HTMLElement} the node to track
1427      * @param id {string} the id of the request
1428      * @param url {string} the url that is being loaded
1429      * @param win {Window} the targeted window
1430      * @param qlength the number of remaining items in the queue,
1431      * including this one
1432      * @param trackfn {Function} function to execute when finished
1433      * the default is _next
1434      * @private
1435      */
1436     var _track = function(type, n, id, url, win, qlength, trackfn) {
1437         var f = trackfn || _next;
1438
1439         // IE supports the readystatechange event for script and css nodes
1440         if (ua.ie) {
1441             n.onreadystatechange = function() {
1442                 var rs = this.readyState;
1443                 if ("loaded" === rs || "complete" === rs) {
1444                     n.onreadystatechange = null;
1445                     f(id, url);
1446                 }
1447             };
1448
1449         // webkit prior to 3.x is problemmatic
1450         } else if (ua.webkit) {
1451
1452             if (type === "script") {
1453
1454                 // Safari 3.x supports the load event for script nodes (DOM2)
1455                 if (ua.webkit >= 420) {
1456
1457                     n.addEventListener("load", function() {
1458                         f(id, url);
1459                     });
1460
1461                 // Nothing can be done with Safari < 3.x except to pause and hope
1462                 // for the best, particularly after last script is inserted. The
1463                 // scripts will always execute in the order they arrive, not
1464                 // necessarily the order in which they were inserted.  To support
1465                 // script nodes with complete reliability in these browsers, script
1466                 // nodes either need to invoke a function in the window once they
1467                 // are loaded or the implementer needs to provide a well-known
1468                 // property that the utility can poll for.
1469                 } else {
1470                     // Poll for the existence of the named variable, if it
1471                     // was supplied.
1472                     var q = queues[id];
1473                     if (q.varName) {
1474                         var freq=YAHOO.util.Get.POLL_FREQ;
1475                         q.maxattempts = YAHOO.util.Get.TIMEOUT/freq;
1476                         q.attempts = 0;
1477                         q._cache = q.varName[0].split(".");
1478                         q.timer = lang.later(freq, q, function(o) {
1479                             var a=this._cache, l=a.length, w=this.win, i;
1480                             for (i=0; i<l; i=i+1) {
1481                                 w = w[a[i]];
1482                                 if (!w) {
1483                                     // if we have exausted our attempts, give up
1484                                     this.attempts++;
1485                                     if (this.attempts++ > this.maxattempts) {
1486                                         var msg = "Over retry limit, giving up";
1487                                         q.timer.cancel();
1488                                         _fail(id, msg);
1489                                     } else {
1490                                     }
1491                                     return;
1492                                 }
1493                             }
1494                             
1495
1496                             q.timer.cancel();
1497                             f(id, url);
1498
1499                         }, null, true);
1500                     } else {
1501                         lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]);
1502                     }
1503                 }
1504             } 
1505
1506         // FireFox and Opera support onload (but not DOM2 in FF) handlers for
1507         // script nodes.  Opera, but not FF, supports the onload event for link
1508         // nodes.
1509         } else { 
1510             n.onload = function() {
1511                 f(id, url);
1512             };
1513         }
1514     };
1515
1516     return {
1517
1518         /**
1519          * The default poll freqency in ms, when needed
1520          * @property POLL_FREQ
1521          * @static
1522          * @type int
1523          * @default 10
1524          */
1525         POLL_FREQ: 10,
1526
1527         /**
1528          * The number of request required before an automatic purge.
1529          * property PURGE_THRESH
1530          * @static
1531          * @type int
1532          * @default 20
1533          */
1534         PURGE_THRESH: 20,
1535
1536         /**
1537          * The length time to poll for varName when loading a script in
1538          * Safari 2.x before the transaction fails.
1539          * property TIMEOUT
1540          * @static
1541          * @type int
1542          * @default 2000
1543          */
1544         TIMEOUT: 2000,
1545         
1546         /**
1547          * Called by the the helper for detecting script load in Safari
1548          * @method _finalize
1549          * @param id {string} the transaction id
1550          * @private
1551          */
1552         _finalize: function(id) {
1553             lang.later(0, null, _finish, id);
1554         },
1555
1556         /**
1557          * Abort a transaction
1558          * @method abort
1559          * @param {string|object} either the tId or the object returned from
1560          * script() or css()
1561          */
1562         abort: function(o) {
1563             var id = (lang.isString(o)) ? o : o.tId;
1564             var q = queues[id];
1565             if (q) {
1566                 q.aborted = true;
1567             }
1568         }, 
1569
1570         /**
1571          * Fetches and inserts one or more script nodes into the head
1572          * of the current document or the document in a specified window.
1573          *
1574          * @method script
1575          * @static
1576          * @param url {string|string[]} the url or urls to the script(s)
1577          * @param opts {object} Options: 
1578          * <dl>
1579          * <dt>onSuccess</dt>
1580          * <dd>
1581          * callback to execute when the script(s) are finished loading
1582          * The callback receives an object back with the following
1583          * data:
1584          * <dl>
1585          * <dt>win</dt>
1586          * <dd>the window the script(s) were inserted into</dd>
1587          * <dt>data</dt>
1588          * <dd>the data object passed in when the request was made</dd>
1589          * <dt>nodes</dt>
1590          * <dd>An array containing references to the nodes that were
1591          * inserted</dd>
1592          * <dt>purge</dt>
1593          * <dd>A function that, when executed, will remove the nodes
1594          * that were inserted</dd>
1595          * <dt>
1596          * </dl>
1597          * </dd>
1598          * <dt>onFailure</dt>
1599          * <dd>
1600          * callback to execute when the script load operation fails
1601          * The callback receives an object back with the following
1602          * data:
1603          * <dl>
1604          * <dt>win</dt>
1605          * <dd>the window the script(s) were inserted into</dd>
1606          * <dt>data</dt>
1607          * <dd>the data object passed in when the request was made</dd>
1608          * <dt>nodes</dt>
1609          * <dd>An array containing references to the nodes that were
1610          * inserted successfully</dd>
1611          * <dt>purge</dt>
1612          * <dd>A function that, when executed, will remove any nodes
1613          * that were inserted</dd>
1614          * <dt>
1615          * </dl>
1616          * </dd>
1617          * <dt>onTimeout</dt>
1618          * <dd>
1619          * callback to execute when a timeout occurs.
1620          * The callback receives an object back with the following
1621          * data:
1622          * <dl>
1623          * <dt>win</dt>
1624          * <dd>the window the script(s) were inserted into</dd>
1625          * <dt>data</dt>
1626          * <dd>the data object passed in when the request was made</dd>
1627          * <dt>nodes</dt>
1628          * <dd>An array containing references to the nodes that were
1629          * inserted</dd>
1630          * <dt>purge</dt>
1631          * <dd>A function that, when executed, will remove the nodes
1632          * that were inserted</dd>
1633          * <dt>
1634          * </dl>
1635          * </dd>
1636          * <dt>scope</dt>
1637          * <dd>the execution context for the callbacks</dd>
1638          * <dt>win</dt>
1639          * <dd>a window other than the one the utility occupies</dd>
1640          * <dt>autopurge</dt>
1641          * <dd>
1642          * setting to true will let the utilities cleanup routine purge 
1643          * the script once loaded
1644          * </dd>
1645          * <dt>data</dt>
1646          * <dd>
1647          * data that is supplied to the callback when the script(s) are
1648          * loaded.
1649          * </dd>
1650          * <dt>varName</dt>
1651          * <dd>
1652          * variable that should be available when a script is finished
1653          * loading.  Used to help Safari 2.x and below with script load 
1654          * detection.  The type of this property should match what was
1655          * passed into the url parameter: if loading a single url, a
1656          * string can be supplied.  If loading multiple scripts, you
1657          * must supply an array that contains the variable name for
1658          * each script.
1659          * </dd>
1660          * <dt>insertBefore</dt>
1661          * <dd>node or node id that will become the new node's nextSibling</dd>
1662          * </dl>
1663          * <dt>charset</dt>
1664          * <dd>Node charset, default utf-8</dd>
1665          * <dt>timeout</dt>
1666          * <dd>Number of milliseconds to wait before aborting and firing the timeout event</dd>
1667          * <pre>
1668          * // assumes yahoo, dom, and event are already on the page
1669          * &nbsp;&nbsp;YAHOO.util.Get.script(
1670          * &nbsp;&nbsp;["http://yui.yahooapis.com/2.3.1/build/dragdrop/dragdrop-min.js",
1671          * &nbsp;&nbsp;&nbsp;"http://yui.yahooapis.com/2.3.1/build/animation/animation-min.js"], &#123;
1672          * &nbsp;&nbsp;&nbsp;&nbsp;onSuccess: function(o) &#123;
1673          * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new YAHOO.util.DDProxy("dd1"); // also new o.reference("dd1"); would work
1674          * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.log("won't cause error because YAHOO is the scope");
1675          * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.log(o.nodes.length === 2) // true
1676          * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// o.purge(); // optionally remove the script nodes immediately
1677          * &nbsp;&nbsp;&nbsp;&nbsp;&#125;,
1678          * &nbsp;&nbsp;&nbsp;&nbsp;onFailure: function(o) &#123;
1679          * &nbsp;&nbsp;&nbsp;&nbsp;&#125;,
1680          * &nbsp;&nbsp;&nbsp;&nbsp;data: "foo",
1681          * &nbsp;&nbsp;&nbsp;&nbsp;timeout: 10000, // 10 second timeout
1682          * &nbsp;&nbsp;&nbsp;&nbsp;scope: YAHOO,
1683          * &nbsp;&nbsp;&nbsp;&nbsp;// win: otherframe // target another window/frame
1684          * &nbsp;&nbsp;&nbsp;&nbsp;autopurge: true // allow the utility to choose when to remove the nodes
1685          * &nbsp;&nbsp;&#125;);
1686          * </pre>
1687          * @return {tId: string} an object containing info about the transaction
1688          */
1689         script: function(url, opts) { return _queue("script", url, opts); },
1690
1691         /**
1692          * Fetches and inserts one or more css link nodes into the 
1693          * head of the current document or the document in a specified
1694          * window.
1695          * @method css
1696          * @static
1697          * @param url {string} the url or urls to the css file(s)
1698          * @param opts Options: 
1699          * <dl>
1700          * <dt>onSuccess</dt>
1701          * <dd>
1702          * callback to execute when the css file(s) are finished loading
1703          * The callback receives an object back with the following
1704          * data:
1705          * <dl>win</dl>
1706          * <dd>the window the link nodes(s) were inserted into</dd>
1707          * <dt>data</dt>
1708          * <dd>the data object passed in when the request was made</dd>
1709          * <dt>nodes</dt>
1710          * <dd>An array containing references to the nodes that were
1711          * inserted</dd>
1712          * <dt>purge</dt>
1713          * <dd>A function that, when executed, will remove the nodes
1714          * that were inserted</dd>
1715          * <dt>
1716          * </dl>
1717          * </dd>
1718          * <dt>scope</dt>
1719          * <dd>the execution context for the callbacks</dd>
1720          * <dt>win</dt>
1721          * <dd>a window other than the one the utility occupies</dd>
1722          * <dt>data</dt>
1723          * <dd>
1724          * data that is supplied to the callbacks when the nodes(s) are
1725          * loaded.
1726          * </dd>
1727          * <dt>insertBefore</dt>
1728          * <dd>node or node id that will become the new node's nextSibling</dd>
1729          * <dt>charset</dt>
1730          * <dd>Node charset, default utf-8</dd>
1731          * </dl>
1732          * <pre>
1733          *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
1734          * </pre>
1735          * <pre>
1736          *      YAHOO.util.Get.css(["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css",
1737          * </pre>
1738          * @return {tId: string} an object containing info about the transaction
1739          */
1740         css: function(url, opts) {
1741             return _queue("css", url, opts); 
1742         }
1743     };
1744 }();
1745
1746 YAHOO.register("get", YAHOO.util.Get, {version: "2.7.0", build: "1799"});
1747 /**
1748  * Provides dynamic loading for the YUI library.  It includes the dependency
1749  * info for the library, and will automatically pull in dependencies for
1750  * the modules requested.  It supports rollup files (such as utilities.js
1751  * and yahoo-dom-event.js), and will automatically use these when
1752  * appropriate in order to minimize the number of http connections
1753  * required to load all of the dependencies.
1754  * 
1755  * @module yuiloader
1756  * @namespace YAHOO.util
1757  */
1758
1759 /**
1760  * YUILoader provides dynamic loading for YUI.
1761  * @class YAHOO.util.YUILoader
1762  * @todo
1763  *      version management, automatic sandboxing
1764  */
1765 (function() {
1766
1767     var Y=YAHOO, util=Y.util, lang=Y.lang, env=Y.env,
1768         PROV = "_provides", SUPER = "_supersedes",
1769         REQ = "expanded", AFTER = "_after";
1770  
1771     var YUI = {
1772
1773         dupsAllowed: {'yahoo': true, 'get': true},
1774
1775         /*
1776          * The library metadata for the current release  The is the default
1777          * value for YAHOO.util.YUILoader.moduleInfo
1778          * @property YUIInfo
1779          * @static
1780          */
1781         info: {
1782
1783     // 'root': '2.5.2/build/',
1784     // 'base': 'http://yui.yahooapis.com/2.5.2/build/',
1785
1786     'root': '2.7.0/build/',
1787     'base': 'http://yui.yahooapis.com/2.7.0/build/',
1788
1789     'comboBase': 'http://yui.yahooapis.com/combo?',
1790
1791     'skin': {
1792         'defaultSkin': 'sam',
1793         'base': 'assets/skins/',
1794         'path': 'skin.css',
1795         'after': ['reset', 'fonts', 'grids', 'base'],
1796         'rollup': 3
1797     },
1798
1799     dupsAllowed: ['yahoo', 'get'],
1800
1801     'moduleInfo': {
1802
1803         'animation': {
1804             'type': 'js',
1805             'path': 'animation/animation-min.js',
1806             'requires': ['dom', 'event']
1807         },
1808
1809         'autocomplete': {
1810             'type': 'js',
1811             'path': 'autocomplete/autocomplete-min.js',
1812             'requires': ['dom', 'event', 'datasource'],
1813             'optional': ['connection', 'animation'],
1814             'skinnable': true
1815         },
1816
1817         'base': {
1818             'type': 'css',
1819             'path': 'base/base-min.css',
1820             'after': ['reset', 'fonts', 'grids']
1821         },
1822
1823         'button': {
1824             'type': 'js',
1825             'path': 'button/button-min.js',
1826             'requires': ['element'],
1827             'optional': ['menu'],
1828             'skinnable': true
1829         },
1830
1831         'calendar': {
1832             'type': 'js',
1833             'path': 'calendar/calendar-min.js',
1834             'requires': ['event', 'dom'],
1835             'skinnable': true
1836         },
1837
1838         'carousel': {
1839             'type': 'js',
1840             'path': 'carousel/carousel-min.js',
1841             'requires': ['element'],
1842             'optional': ['animation'],
1843             'skinnable': true
1844         },
1845
1846         'charts': {
1847             'type': 'js',
1848             'path': 'charts/charts-min.js',
1849             'requires': ['element', 'json', 'datasource']
1850         },
1851
1852         'colorpicker': {
1853             'type': 'js',
1854             'path': 'colorpicker/colorpicker-min.js',
1855             'requires': ['slider', 'element'],
1856             'optional': ['animation'],
1857             'skinnable': true
1858         },
1859
1860         'connection': {
1861             'type': 'js',
1862             'path': 'connection/connection-min.js',
1863             'requires': ['event']
1864         },
1865
1866         'container': {
1867             'type': 'js',
1868             'path': 'container/container-min.js',
1869             'requires': ['dom', 'event'],
1870             // button is also optional, but this creates a circular 
1871             // dependency when loadOptional is specified.  button
1872             // optionally includes menu, menu requires container.
1873             'optional': ['dragdrop', 'animation', 'connection'],
1874             'supersedes': ['containercore'],
1875             'skinnable': true
1876         },
1877
1878         'containercore': {
1879             'type': 'js',
1880             'path': 'container/container_core-min.js',
1881             'requires': ['dom', 'event'],
1882             'pkg': 'container'
1883         },
1884
1885         'cookie': {
1886             'type': 'js',
1887             'path': 'cookie/cookie-min.js',
1888             'requires': ['yahoo']
1889         },
1890
1891         'datasource': {
1892             'type': 'js',
1893             'path': 'datasource/datasource-min.js',
1894             'requires': ['event'],
1895             'optional': ['connection']
1896         },
1897
1898         'datatable': {
1899             'type': 'js',
1900             'path': 'datatable/datatable-min.js',
1901             'requires': ['element', 'datasource'],
1902             'optional': ['calendar', 'dragdrop', 'paginator'],
1903             'skinnable': true
1904         },
1905
1906         'dom': {
1907             'type': 'js',
1908             'path': 'dom/dom-min.js',
1909             'requires': ['yahoo']
1910         },
1911
1912         'dragdrop': {
1913             'type': 'js',
1914             'path': 'dragdrop/dragdrop-min.js',
1915             'requires': ['dom', 'event']
1916         },
1917
1918         'editor': {
1919             'type': 'js',
1920             'path': 'editor/editor-min.js',
1921             'requires': ['menu', 'element', 'button'],
1922             'optional': ['animation', 'dragdrop'],
1923             'supersedes': ['simpleeditor'],
1924             'skinnable': true
1925         },
1926
1927         'element': {
1928             'type': 'js',
1929             'path': 'element/element-min.js',
1930             'requires': ['dom', 'event']
1931         },
1932
1933         'event': {
1934             'type': 'js',
1935             'path': 'event/event-min.js',
1936             'requires': ['yahoo']
1937         },
1938
1939         'fonts': {
1940             'type': 'css',
1941             'path': 'fonts/fonts-min.css'
1942         },
1943
1944         'get': {
1945             'type': 'js',
1946             'path': 'get/get-min.js',
1947             'requires': ['yahoo']
1948         },
1949
1950         'grids': {
1951             'type': 'css',
1952             'path': 'grids/grids-min.css',
1953             'requires': ['fonts'],
1954             'optional': ['reset']
1955         },
1956
1957         'history': {
1958             'type': 'js',
1959             'path': 'history/history-min.js',
1960             'requires': ['event']
1961         },
1962
1963          'imagecropper': {
1964              'type': 'js',
1965              'path': 'imagecropper/imagecropper-min.js',
1966              'requires': ['dom', 'event', 'dragdrop', 'element', 'resize'],
1967              'skinnable': true
1968          },
1969
1970          'imageloader': {
1971             'type': 'js',
1972             'path': 'imageloader/imageloader-min.js',
1973             'requires': ['event', 'dom']
1974          },
1975
1976          'json': {
1977             'type': 'js',
1978             'path': 'json/json-min.js',
1979             'requires': ['yahoo']
1980          },
1981
1982          'layout': {
1983              'type': 'js',
1984              'path': 'layout/layout-min.js',
1985              'requires': ['dom', 'event', 'element'],
1986              'optional': ['animation', 'dragdrop', 'resize', 'selector'],
1987              'skinnable': true
1988          }, 
1989
1990         'logger': {
1991             'type': 'js',
1992             'path': 'logger/logger-min.js',
1993             'requires': ['event', 'dom'],
1994             'optional': ['dragdrop'],
1995             'skinnable': true
1996         },
1997
1998         'menu': {
1999             'type': 'js',
2000             'path': 'menu/menu-min.js',
2001             'requires': ['containercore'],
2002             'skinnable': true
2003         },
2004
2005         'paginator': {
2006             'type': 'js',
2007             'path': 'paginator/paginator-min.js',
2008             'requires': ['element'],
2009             'skinnable': true
2010         },
2011
2012         'profiler': {
2013             'type': 'js',
2014             'path': 'profiler/profiler-min.js',
2015             'requires': ['yahoo']
2016         },
2017
2018
2019         'profilerviewer': {
2020             'type': 'js',
2021             'path': 'profilerviewer/profilerviewer-min.js',
2022             'requires': ['profiler', 'yuiloader', 'element'],
2023             'skinnable': true
2024         },
2025
2026         'reset': {
2027             'type': 'css',
2028             'path': 'reset/reset-min.css'
2029         },
2030
2031         'reset-fonts-grids': {
2032             'type': 'css',
2033             'path': 'reset-fonts-grids/reset-fonts-grids.css',
2034             'supersedes': ['reset', 'fonts', 'grids', 'reset-fonts'],
2035             'rollup': 4
2036         },
2037
2038         'reset-fonts': {
2039             'type': 'css',
2040             'path': 'reset-fonts/reset-fonts.css',
2041             'supersedes': ['reset', 'fonts'],
2042             'rollup': 2
2043         },
2044
2045          'resize': {
2046              'type': 'js',
2047              'path': 'resize/resize-min.js',
2048              'requires': ['dom', 'event', 'dragdrop', 'element'],
2049              'optional': ['animation'],
2050              'skinnable': true
2051          },
2052
2053         'selector': {
2054             'type': 'js',
2055             'path': 'selector/selector-min.js',
2056             'requires': ['yahoo', 'dom']
2057         },
2058
2059         'simpleeditor': {
2060             'type': 'js',
2061             'path': 'editor/simpleeditor-min.js',
2062             'requires': ['element'],
2063             'optional': ['containercore', 'menu', 'button', 'animation', 'dragdrop'],
2064             'skinnable': true,
2065             'pkg': 'editor'
2066         },
2067
2068         'slider': {
2069             'type': 'js',
2070             'path': 'slider/slider-min.js',
2071             'requires': ['dragdrop'],
2072             'optional': ['animation'],
2073             'skinnable': true
2074         },
2075
2076          'stylesheet': {
2077             'type': 'js',
2078             'path': 'stylesheet/stylesheet-min.js',
2079             'requires': ['yahoo']
2080          },
2081
2082         'tabview': {
2083             'type': 'js',
2084             'path': 'tabview/tabview-min.js',
2085             'requires': ['element'],
2086             'optional': ['connection'],
2087             'skinnable': true
2088         },
2089
2090         'treeview': {
2091             'type': 'js',
2092             'path': 'treeview/treeview-min.js',
2093             'requires': ['event', 'dom'],
2094             'optional': ['json'],
2095             'skinnable': true
2096         },
2097
2098         'uploader': {
2099             'type': 'js',
2100             'path': 'uploader/uploader.js',
2101             'requires': ['element']
2102         },
2103
2104         'utilities': {
2105             'type': 'js',
2106             'path': 'utilities/utilities.js',
2107             'supersedes': ['yahoo', 'event', 'dragdrop', 'animation', 'dom', 'connection', 'element', 'yahoo-dom-event', 'get', 'yuiloader', 'yuiloader-dom-event'],
2108             'rollup': 8
2109         },
2110
2111         'yahoo': {
2112             'type': 'js',
2113             'path': 'yahoo/yahoo-min.js'
2114         },
2115
2116         'yahoo-dom-event': {
2117             'type': 'js',
2118             'path': 'yahoo-dom-event/yahoo-dom-event.js',
2119             'supersedes': ['yahoo', 'event', 'dom'],
2120             'rollup': 3
2121         },
2122
2123         'yuiloader': {
2124             'type': 'js',
2125             'path': 'yuiloader/yuiloader-min.js',
2126             'supersedes': ['yahoo', 'get']
2127         },
2128
2129         'yuiloader-dom-event': {
2130             'type': 'js',
2131             'path': 'yuiloader-dom-event/yuiloader-dom-event.js',
2132             'supersedes': ['yahoo', 'dom', 'event', 'get', 'yuiloader', 'yahoo-dom-event'],
2133             'rollup': 5
2134         },
2135
2136         'yuitest': {
2137             'type': 'js',
2138             'path': 'yuitest/yuitest-min.js',
2139             'requires': ['logger'],
2140             'skinnable': true
2141         }
2142     }
2143 }
2144  , 
2145
2146         ObjectUtil: {
2147             appendArray: function(o, a) {
2148                 if (a) {
2149                     for (var i=0; i<a.length; i=i+1) {
2150                         o[a[i]] = true;
2151                     }
2152                 }
2153             },
2154
2155             keys: function(o, ordered) {
2156                 var a=[], i;
2157                 for (i in o) {
2158                     if (lang.hasOwnProperty(o, i)) {
2159                         a.push(i);
2160                     }
2161                 }
2162
2163                 return a;
2164             }
2165         },
2166
2167         ArrayUtil: {
2168
2169             appendArray: function(a1, a2) {
2170                 Array.prototype.push.apply(a1, a2);
2171                 /*
2172                 for (var i=0; i<a2.length; i=i+1) {
2173                     a1.push(a2[i]);
2174                 }
2175                 */
2176             },
2177
2178             indexOf: function(a, val) {
2179                 for (var i=0; i<a.length; i=i+1) {
2180                     if (a[i] === val) {
2181                         return i;
2182                     }
2183                 }
2184
2185                 return -1;
2186             },
2187
2188             toObject: function(a) {
2189                 var o = {};
2190                 for (var i=0; i<a.length; i=i+1) {
2191                     o[a[i]] = true;
2192                 }
2193
2194                 return o;
2195             },
2196
2197             /*
2198              * Returns a unique array.  Does not maintain order, which is fine
2199              * for this application, and performs better than it would if it
2200              * did.
2201              */
2202             uniq: function(a) {
2203                 return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a));
2204             }
2205         }
2206     };
2207
2208     YAHOO.util.YUILoader = function(o) {
2209
2210         /**
2211          * Internal callback to handle multiple internal insert() calls
2212          * so that css is inserted prior to js
2213          * @property _internalCallback
2214          * @private
2215          */
2216         this._internalCallback = null;
2217
2218         /**
2219          * Use the YAHOO environment listener to detect script load.  This
2220          * is only switched on for Safari 2.x and below.
2221          * @property _useYahooListener
2222          * @private
2223          */
2224         this._useYahooListener = false;
2225
2226         /**
2227          * Callback that will be executed when the loader is finished
2228          * with an insert
2229          * @method onSuccess
2230          * @type function
2231          */
2232         this.onSuccess = null;
2233
2234         /**
2235          * Callback that will be executed if there is a failure
2236          * @method onFailure
2237          * @type function
2238          */
2239         this.onFailure = Y.log;
2240
2241         /**
2242          * Callback that will be executed each time a new module is loaded
2243          * @method onProgress
2244          * @type function
2245          */
2246         this.onProgress = null;
2247
2248         /**
2249          * Callback that will be executed if a timeout occurs
2250          * @method onTimeout
2251          * @type function
2252          */
2253         this.onTimeout = null;
2254
2255         /**
2256          * The execution scope for all callbacks
2257          * @property scope
2258          * @default this
2259          */
2260         this.scope = this;
2261
2262         /**
2263          * Data that is passed to all callbacks
2264          * @property data
2265          */
2266         this.data = null;
2267
2268         /**
2269          * Node reference or id where new nodes should be inserted before
2270          * @property insertBefore
2271          * @type string|HTMLElement
2272          */
2273         this.insertBefore = null;
2274
2275         /**
2276          * The charset attribute for inserted nodes
2277          * @property charset
2278          * @type string
2279          * @default utf-8
2280          */
2281         this.charset = null;
2282
2283         /**
2284          * The name of the variable in a sandbox or script node 
2285          * (for external script support in Safari 2.x and earlier)
2286          * to reference when the load is complete.  If this variable 
2287          * is not available in the specified scripts, the operation will 
2288          * fail.  
2289          * @property varName
2290          * @type string
2291          */
2292         this.varName = null;
2293
2294         /**
2295          * The base directory.
2296          * @property base
2297          * @type string
2298          * @default http://yui.yahooapis.com/[YUI VERSION]/build/
2299          */
2300         this.base = YUI.info.base;
2301
2302         /**
2303          * Base path for the combo service
2304          * @property comboBase
2305          * @type string
2306          * @default http://yui.yahooapis.com/combo?
2307          */
2308         this.comboBase = YUI.info.comboBase;
2309
2310         /**
2311          * If configured, YUI will use the the combo handler on the
2312          * Yahoo! CDN to pontentially reduce the number of http requests
2313          * required.
2314          * @property combine
2315          * @type boolean
2316          * @default false
2317          */
2318         // this.combine = (o && !('base' in o));
2319         this.combine = false;
2320
2321
2322         /**
2323          * Root path to prepend to module path for the combo
2324          * service
2325          * @property root
2326          * @type string
2327          * @default [YUI VERSION]/build/
2328          */
2329         this.root = YUI.info.root;
2330
2331         /**
2332          * Timeout value in milliseconds.  If set, this value will be used by
2333          * the get utility.  the timeout event will fire if
2334          * a timeout occurs.
2335          * @property timeout
2336          * @type int
2337          */
2338         this.timeout = 0;
2339
2340         /**
2341          * A list of modules that should not be loaded, even if
2342          * they turn up in the dependency tree
2343          * @property ignore
2344          * @type string[]
2345          */
2346         this.ignore = null;
2347
2348         /**
2349          * A list of modules that should always be loaded, even
2350          * if they have already been inserted into the page.
2351          * @property force
2352          * @type string[]
2353          */
2354         this.force = null;
2355
2356         /**
2357          * Should we allow rollups
2358          * @property allowRollup
2359          * @type boolean
2360          * @default true
2361          */
2362         this.allowRollup = true;
2363
2364         /**
2365          * A filter to apply to result urls.  This filter will modify the default
2366          * path for all modules.  The default path for the YUI library is the
2367          * minified version of the files (e.g., event-min.js).  The filter property
2368          * can be a predefined filter or a custom filter.  The valid predefined 
2369          * filters are:
2370          * <dl>
2371          *  <dt>DEBUG</dt>
2372          *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
2373          *      This option will automatically include the logger widget</dd>
2374          *  <dt>RAW</dt>
2375          *  <dd>Selects the non-minified version of the library (e.g., event.js).
2376          * </dl>
2377          * You can also define a custom filter, which must be an object literal 
2378          * containing a search expression and a replace string:
2379          * <pre>
2380          *  myFilter: &#123; 
2381          *      'searchExp': "-min\\.js", 
2382          *      'replaceStr': "-debug.js"
2383          *  &#125;
2384          * </pre>
2385          * @property filter
2386          * @type string|{searchExp: string, replaceStr: string}
2387          */
2388         this.filter = null;
2389
2390         /**
2391          * The list of requested modules
2392          * @property required
2393          * @type {string: boolean}
2394          */
2395         this.required = {};
2396
2397         /**
2398          * The library metadata
2399          * @property moduleInfo
2400          */
2401         this.moduleInfo = lang.merge(YUI.info.moduleInfo);
2402
2403         /**
2404          * List of rollup files found in the library metadata
2405          * @property rollups
2406          */
2407         this.rollups = null;
2408
2409         /**
2410          * Whether or not to load optional dependencies for 
2411          * the requested modules
2412          * @property loadOptional
2413          * @type boolean
2414          * @default false
2415          */
2416         this.loadOptional = false;
2417
2418         /**
2419          * All of the derived dependencies in sorted order, which
2420          * will be populated when either calculate() or insert()
2421          * is called
2422          * @property sorted
2423          * @type string[]
2424          */
2425         this.sorted = [];
2426
2427         /**
2428          * Set when beginning to compute the dependency tree. 
2429          * Composed of what YAHOO reports to be loaded combined
2430          * with what has been loaded by the tool
2431          * @propery loaded
2432          * @type {string: boolean}
2433          */
2434         this.loaded = {};
2435
2436         /**
2437          * Flag to indicate the dependency tree needs to be recomputed
2438          * if insert is called again.
2439          * @property dirty
2440          * @type boolean
2441          * @default true
2442          */
2443         this.dirty = true;
2444
2445         /**
2446          * List of modules inserted by the utility
2447          * @property inserted
2448          * @type {string: boolean}
2449          */
2450         this.inserted = {};
2451
2452         /**
2453          * Provides the information used to skin the skinnable components.
2454          * The following skin definition would result in 'skin1' and 'skin2'
2455          * being loaded for calendar (if calendar was requested), and
2456          * 'sam' for all other skinnable components:
2457          *
2458          *   <code>
2459          *   skin: {
2460          *
2461          *      // The default skin, which is automatically applied if not
2462          *      // overriden by a component-specific skin definition.
2463          *      // Change this in to apply a different skin globally
2464          *      defaultSkin: 'sam', 
2465          *
2466          *      // This is combined with the loader base property to get
2467          *      // the default root directory for a skin. ex:
2468          *      // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
2469          *      base: 'assets/skins/',
2470          *
2471          *      // The name of the rollup css file for the skin
2472          *      path: 'skin.css',
2473          *
2474          *      // The number of skinnable components requested that are
2475          *      // required before using the rollup file rather than the
2476          *      // individual component css files
2477          *      rollup: 3,
2478          *
2479          *      // Any component-specific overrides can be specified here,
2480          *      // making it possible to load different skins for different
2481          *      // components.  It is possible to load more than one skin
2482          *      // for a given component as well.
2483          *      overrides: {
2484          *          calendar: ['skin1', 'skin2']
2485          *      }
2486          *   }
2487          *   </code>
2488          *   @property skin
2489          */
2490
2491         var self = this;
2492
2493         env.listeners.push(function(m) {
2494             if (self._useYahooListener) {
2495                 //Y.log("YAHOO listener: " + m.name);
2496                 self.loadNext(m.name);
2497             }
2498         });
2499
2500         this.skin = lang.merge(YUI.info.skin); 
2501
2502         this._config(o);
2503
2504     };
2505
2506     Y.util.YUILoader.prototype = {
2507
2508         FILTERS: {
2509             RAW: { 
2510                 'searchExp': "-min\\.js", 
2511                 'replaceStr': ".js"
2512             },
2513             DEBUG: { 
2514                 'searchExp': "-min\\.js", 
2515                 'replaceStr': "-debug.js"
2516             }
2517         },
2518
2519         SKIN_PREFIX: "skin-",
2520
2521         _config: function(o) {
2522
2523             // apply config values
2524             if (o) {
2525                 for (var i in o) {
2526                     if (lang.hasOwnProperty(o, i)) {
2527                         if (i == "require") {
2528                             this.require(o[i]);
2529                         } else {
2530                             this[i] = o[i];
2531                         }
2532                     }
2533                 }
2534             }
2535
2536             // fix filter
2537             var f = this.filter;
2538
2539             if (lang.isString(f)) {
2540                 f = f.toUpperCase();
2541
2542                 // the logger must be available in order to use the debug
2543                 // versions of the library
2544                 if (f === "DEBUG") {
2545                     this.require("logger");
2546                 }
2547
2548                 // hack to handle a a bug where LogWriter is being instantiated
2549                 // at load time, and the loader has no way to sort above it
2550                 // at the moment.
2551                 if (!Y.widget.LogWriter) {
2552                     Y.widget.LogWriter = function() {
2553                         return Y;
2554                     };
2555                 }
2556
2557                 this.filter = this.FILTERS[f];
2558             }
2559
2560         },
2561
2562         /** Add a new module to the component metadata.         
2563          * <dl>
2564          *     <dt>name:</dt>       <dd>required, the component name</dd>
2565          *     <dt>type:</dt>       <dd>required, the component type (js or css)</dd>
2566          *     <dt>path:</dt>       <dd>required, the path to the script from "base"</dd>
2567          *     <dt>requires:</dt>   <dd>array of modules required by this component</dd>
2568          *     <dt>optional:</dt>   <dd>array of optional modules for this component</dd>
2569          *     <dt>supersedes:</dt> <dd>array of the modules this component replaces</dd>
2570          *     <dt>after:</dt>      <dd>array of modules the components which, if present, should be sorted above this one</dd>
2571          *     <dt>rollup:</dt>     <dd>the number of superseded modules required for automatic rollup</dd>
2572          *     <dt>fullpath:</dt>   <dd>If fullpath is specified, this is used instead of the configured base + path</dd>
2573          *     <dt>skinnable:</dt>  <dd>flag to determine if skin assets should automatically be pulled in</dd>
2574          * </dl>
2575          * @method addModule
2576          * @param o An object containing the module data
2577          * @return {boolean} true if the module was added, false if 
2578          * the object passed in did not provide all required attributes
2579          */
2580         addModule: function(o) {
2581
2582             if (!o || !o.name || !o.type || (!o.path && !o.fullpath)) {
2583                 return false;
2584             }
2585
2586             o.ext = ('ext' in o) ? o.ext : true;
2587             o.requires = o.requires || [];
2588
2589             this.moduleInfo[o.name] = o;
2590             this.dirty = true;
2591
2592             return true;
2593         },
2594
2595         /**
2596          * Add a requirement for one or more module
2597          * @method require
2598          * @param what {string[] | string*} the modules to load
2599          */
2600         require: function(what) {
2601             var a = (typeof what === "string") ? arguments : what;
2602             this.dirty = true;
2603             YUI.ObjectUtil.appendArray(this.required, a);
2604         },
2605
2606         /**
2607          * Adds the skin def to the module info
2608          * @method _addSkin
2609          * @param skin {string} the name of the skin
2610          * @param mod {string} the name of the module
2611          * @return {string} the module name for the skin
2612          * @private
2613          */
2614         _addSkin: function(skin, mod) {
2615
2616             // Add a module definition for the skin rollup css
2617             var name = this.formatSkin(skin), info = this.moduleInfo,
2618                 sinf = this.skin, ext = info[mod] && info[mod].ext;
2619
2620             // Y.log('ext? ' + mod + ": " + ext);
2621             if (!info[name]) {
2622                 // Y.log('adding skin ' + name);
2623                 this.addModule({
2624                     'name': name,
2625                     'type': 'css',
2626                     'path': sinf.base + skin + '/' + sinf.path,
2627                     //'supersedes': '*',
2628                     'after': sinf.after,
2629                     'rollup': sinf.rollup,
2630                     'ext': ext
2631                 });
2632             }
2633
2634             // Add a module definition for the module-specific skin css
2635             if (mod) {
2636                 name = this.formatSkin(skin, mod);
2637                 if (!info[name]) {
2638                     var mdef = info[mod], pkg = mdef.pkg || mod;
2639                     // Y.log('adding skin ' + name);
2640                     this.addModule({
2641                         'name': name,
2642                         'type': 'css',
2643                         'after': sinf.after,
2644                         'path': pkg + '/' + sinf.base + skin + '/' + mod + '.css',
2645                         'ext': ext
2646                     });
2647                 }
2648             }
2649
2650             return name;
2651         },
2652
2653         /**
2654          * Returns an object containing properties for all modules required
2655          * in order to load the requested module
2656          * @method getRequires
2657          * @param mod The module definition from moduleInfo
2658          */
2659         getRequires: function(mod) {
2660             if (!mod) {
2661                 return [];
2662             }
2663
2664             if (!this.dirty && mod.expanded) {
2665                 return mod.expanded;
2666             }
2667
2668             mod.requires=mod.requires || [];
2669             var i, d=[], r=mod.requires, o=mod.optional, info=this.moduleInfo, m;
2670             for (i=0; i<r.length; i=i+1) {
2671                 d.push(r[i]);
2672                 m = info[r[i]];
2673                 YUI.ArrayUtil.appendArray(d, this.getRequires(m));
2674
2675                 // add existing skins for skinnable modules as well.  The only
2676                 // way to do this is go through the list of required items (this
2677                 // assumes that _skin is called before getRequires is called on
2678                 // the module.
2679                 // if (m.skinnable) {
2680                 //     var req=this.required, l=req.length;
2681                 //     for (var j=0; j<l; j=j+1) {
2682                 //         // YAHOO.log('checking ' + r[j]);
2683                 //         if (req[j].indexOf(r[j]) > -1) {
2684                 //             // YAHOO.log('adding ' + r[j]);
2685                 //             d.push(req[j]);
2686                 //         }
2687                 //     }
2688                 // }
2689             }
2690
2691             if (o && this.loadOptional) {
2692                 for (i=0; i<o.length; i=i+1) {
2693                     d.push(o[i]);
2694                     YUI.ArrayUtil.appendArray(d, this.getRequires(info[o[i]]));
2695                 }
2696             }
2697
2698             mod.expanded = YUI.ArrayUtil.uniq(d);
2699
2700             return mod.expanded;
2701         },
2702
2703
2704         /**
2705          * Returns an object literal of the modules the supplied module satisfies
2706          * @method getProvides
2707          * @param name{string} The name of the module
2708          * @param notMe {string} don't add this module name, only include superseded modules
2709          * @return what this module provides
2710          */
2711         getProvides: function(name, notMe) {
2712             var addMe = !(notMe), ckey = (addMe) ? PROV : SUPER,
2713                 m = this.moduleInfo[name], o = {};
2714
2715             if (!m) {
2716                 return o;
2717             }
2718
2719             if (m[ckey]) {
2720 // Y.log('cached: ' + name + ' ' + ckey + ' ' + lang.dump(this.moduleInfo[name][ckey], 0));
2721                 return m[ckey];
2722             }
2723
2724             var s = m.supersedes, done={}, me = this;
2725
2726             // use worker to break cycles
2727             var add = function(mm) {
2728                 if (!done[mm]) {
2729                     // Y.log(name + ' provides worker trying: ' + mm);
2730                     done[mm] = true;
2731                     // we always want the return value normal behavior 
2732                     // (provides) for superseded modules.
2733                     lang.augmentObject(o, me.getProvides(mm));
2734                 } 
2735                 
2736                 // else {
2737                 // Y.log(name + ' provides worker skipping done: ' + mm);
2738                 // }
2739             };
2740
2741             // calculate superseded modules
2742             if (s) {
2743                 for (var i=0; i<s.length; i=i+1) {
2744                     add(s[i]);
2745                 }
2746             }
2747
2748             // supersedes cache
2749             m[SUPER] = o;
2750             // provides cache
2751             m[PROV] = lang.merge(o);
2752             m[PROV][name] = true;
2753
2754 // Y.log(name + " supersedes " + lang.dump(m[SUPER], 0));
2755 // Y.log(name + " provides " + lang.dump(m[PROV], 0));
2756
2757             return m[ckey];
2758         },
2759
2760
2761         /**
2762          * Calculates the dependency tree, the result is stored in the sorted 
2763          * property
2764          * @method calculate
2765          * @param o optional options object
2766          */
2767         calculate: function(o) {
2768             if (o || this.dirty) {
2769                 this._config(o);
2770                 this._setup();
2771                 this._explode();
2772                 // this._skin(); // deprecated
2773                 if (this.allowRollup) {
2774                     this._rollup();
2775                 }
2776                 this._reduce();
2777                 this._sort();
2778
2779                 // Y.log("after calculate: " + lang.dump(this.required));
2780
2781                 this.dirty = false;
2782             }
2783         },
2784
2785         /**
2786          * Investigates the current YUI configuration on the page.  By default,
2787          * modules already detected will not be loaded again unless a force
2788          * option is encountered.  Called by calculate()
2789          * @method _setup
2790          * @private
2791          */
2792         _setup: function() {
2793
2794             var info = this.moduleInfo, name, i, j;
2795
2796             // Create skin modules
2797             for (name in info) {
2798
2799                 if (lang.hasOwnProperty(info, name)) {
2800                     var m = info[name];
2801                     if (m && m.skinnable) {
2802                         // Y.log("skinning: " + name);
2803                         var o=this.skin.overrides, smod;
2804                         if (o && o[name]) {
2805                             for (i=0; i<o[name].length; i=i+1) {
2806                                 smod = this._addSkin(o[name][i], name);
2807                             }
2808                         } else {
2809                             smod = this._addSkin(this.skin.defaultSkin, name);
2810                         }
2811
2812                         m.requires.push(smod);
2813                     }
2814                 }
2815
2816             }
2817
2818             var l = lang.merge(this.inserted); // shallow clone
2819             
2820             if (!this._sandbox) {
2821                 l = lang.merge(l, env.modules);
2822             }
2823
2824             // Y.log("Already loaded stuff: " + lang.dump(l, 0));
2825
2826             // add the ignore list to the list of loaded packages
2827             if (this.ignore) {
2828                 YUI.ObjectUtil.appendArray(l, this.ignore);
2829             }
2830
2831             // remove modules on the force list from the loaded list
2832             if (this.force) {
2833                 for (i=0; i<this.force.length; i=i+1) {
2834                     if (this.force[i] in l) {
2835                         delete l[this.force[i]];
2836                     }
2837                 }
2838             }
2839
2840             // expand the list to include superseded modules
2841             for (j in l) {
2842                 // Y.log("expanding: " + j);
2843                 if (lang.hasOwnProperty(l, j)) {
2844                     lang.augmentObject(l, this.getProvides(j));
2845                 }
2846             }
2847
2848             // Y.log("loaded expanded: " + lang.dump(l, 0));
2849
2850             this.loaded = l;
2851
2852         },
2853         
2854
2855         /**
2856          * Inspects the required modules list looking for additional 
2857          * dependencies.  Expands the required list to include all 
2858          * required modules.  Called by calculate()
2859          * @method _explode
2860          * @private
2861          */
2862         _explode: function() {
2863
2864             var r=this.required, i, mod;
2865
2866             for (i in r) {
2867                 if (lang.hasOwnProperty(r, i)) {
2868                     mod = this.moduleInfo[i];
2869                     if (mod) {
2870
2871                         var req = this.getRequires(mod);
2872
2873                         if (req) {
2874                             YUI.ObjectUtil.appendArray(r, req);
2875                         }
2876                     }
2877                 }
2878             }
2879         },
2880
2881         /**
2882          * Sets up the requirements for the skin assets if any of the
2883          * requested modules are skinnable
2884          * @method _skin
2885          * @private
2886          * @deprecated skin modules are generated for all skinnable
2887          *             components during _setup(), and the components
2888          *             are configured to require the skin.
2889          */
2890         _skin: function() {
2891
2892         },
2893
2894         /**
2895          * Returns the skin module name for the specified skin name.  If a
2896          * module name is supplied, the returned skin module name is 
2897          * specific to the module passed in.
2898          * @method formatSkin
2899          * @param skin {string} the name of the skin
2900          * @param mod {string} optional: the name of a module to skin
2901          * @return {string} the full skin module name
2902          */
2903         formatSkin: function(skin, mod) {
2904             var s = this.SKIN_PREFIX + skin;
2905             if (mod) {
2906                 s = s + "-" + mod;
2907             }
2908
2909             return s;
2910         },
2911         
2912         /**
2913          * Reverses <code>formatSkin</code>, providing the skin name and
2914          * module name if the string matches the pattern for skins.
2915          * @method parseSkin
2916          * @param mod {string} the module name to parse
2917          * @return {skin: string, module: string} the parsed skin name 
2918          * and module name, or null if the supplied string does not match
2919          * the skin pattern
2920          */
2921         parseSkin: function(mod) {
2922             
2923             if (mod.indexOf(this.SKIN_PREFIX) === 0) {
2924                 var a = mod.split("-");
2925                 return {skin: a[1], module: a[2]};
2926             } 
2927
2928             return null;
2929         },
2930
2931         /**
2932          * Look for rollup packages to determine if all of the modules a
2933          * rollup supersedes are required.  If so, include the rollup to
2934          * help reduce the total number of connections required.  Called
2935          * by calculate()
2936          * @method _rollup
2937          * @private
2938          */
2939         _rollup: function() {
2940             var i, j, m, s, rollups={}, r=this.required, roll,
2941                 info = this.moduleInfo;
2942
2943             // find and cache rollup modules
2944             if (this.dirty || !this.rollups) {
2945                 for (i in info) {
2946                     if (lang.hasOwnProperty(info, i)) {
2947                         m = info[i];
2948                         //if (m && m.rollup && m.supersedes) {
2949                         if (m && m.rollup) {
2950                             rollups[i] = m;
2951                         }
2952                     }
2953                 }
2954
2955                 this.rollups = rollups;
2956             }
2957
2958             // make as many passes as needed to pick up rollup rollups
2959             for (;;) {
2960                 var rolled = false;
2961
2962                 // go through the rollup candidates
2963                 for (i in rollups) { 
2964
2965                     // there can be only one
2966                     if (!r[i] && !this.loaded[i]) {
2967                         m =info[i]; s = m.supersedes; roll=false;
2968
2969                         if (!m.rollup) {
2970                             continue;
2971                         }
2972
2973                         var skin = (m.ext) ? false : this.parseSkin(i), c = 0;
2974
2975                         // Y.log('skin? ' + i + ": " + skin);
2976                         if (skin) {
2977                             for (j in r) {
2978                                 if (lang.hasOwnProperty(r, j)) {
2979                                     if (i !== j && this.parseSkin(j)) {
2980                                         c++;
2981                                         roll = (c >= m.rollup);
2982                                         if (roll) {
2983                                             // Y.log("skin rollup " + lang.dump(r));
2984                                             break;
2985                                         }
2986                                     }
2987                                 }
2988                             }
2989
2990                         } else {
2991
2992                             // check the threshold
2993                             for (j=0;j<s.length;j=j+1) {
2994
2995                                 // if the superseded module is loaded, we can't load the rollup
2996                                 if (this.loaded[s[j]] && (!YUI.dupsAllowed[s[j]])) {
2997                                     roll = false;
2998                                     break;
2999                                 // increment the counter if this module is required.  if we are
3000                                 // beyond the rollup threshold, we will use the rollup module
3001                                 } else if (r[s[j]]) {
3002                                     c++;
3003                                     roll = (c >= m.rollup);
3004                                     if (roll) {
3005                                         // Y.log("over thresh " + c + ", " + lang.dump(r));
3006                                         break;
3007                                     }
3008                                 }
3009                             }
3010                         }
3011
3012                         if (roll) {
3013                             // Y.log("rollup: " +  i + ", " + lang.dump(this, 1));
3014                             // add the rollup
3015                             r[i] = true;
3016                             rolled = true;
3017
3018                             // expand the rollup's dependencies
3019                             this.getRequires(m);
3020                         }
3021                     }
3022                 }
3023
3024                 // if we made it here w/o rolling up something, we are done
3025                 if (!rolled) {
3026                     break;
3027                 }
3028             }
3029         },
3030
3031         /**
3032          * Remove superceded modules and loaded modules.  Called by
3033          * calculate() after we have the mega list of all dependencies
3034          * @method _reduce
3035          * @private
3036          */
3037         _reduce: function() {
3038
3039             var i, j, s, m, r=this.required;
3040             for (i in r) {
3041
3042                 // remove if already loaded
3043                 if (i in this.loaded) { 
3044                     delete r[i];
3045
3046                 // remove anything this module supersedes
3047                 } else {
3048
3049                     var skinDef = this.parseSkin(i);
3050
3051                     if (skinDef) {
3052                         //YAHOO.log("skin found in reduce: " + skinDef.skin + ", " + skinDef.module);
3053                         // the skin rollup will not have a module name
3054                         if (!skinDef.module) {
3055                             var skin_pre = this.SKIN_PREFIX + skinDef.skin;
3056                             //YAHOO.log("skin_pre: " + skin_pre);
3057                             for (j in r) {
3058
3059                                 if (lang.hasOwnProperty(r, j)) {
3060                                     m = this.moduleInfo[j];
3061                                     var ext = m && m.ext;
3062                                     if (!ext && j !== i && j.indexOf(skin_pre) > -1) {
3063                                         // Y.log ("removing component skin: " + j);
3064                                         delete r[j];
3065                                     }
3066                                 }
3067                             }
3068                         }
3069                     } else {
3070
3071                          m = this.moduleInfo[i];
3072                          s = m && m.supersedes;
3073                          if (s) {
3074                              for (j=0; j<s.length; j=j+1) {
3075                                  if (s[j] in r) {
3076                                      delete r[s[j]];
3077                                  }
3078                              }
3079                          }
3080                     }
3081                 }
3082             }
3083         },
3084
3085         _onFailure: function(msg) {
3086             YAHOO.log('Failure', 'info', 'loader');
3087
3088             var f = this.onFailure;
3089             if (f) {
3090                 f.call(this.scope, {
3091                     msg: 'failure: ' + msg,
3092                     data: this.data,
3093                     success: false
3094                 });
3095             }
3096         },
3097
3098         _onTimeout: function() {
3099             YAHOO.log('Timeout', 'info', 'loader');
3100             var f = this.onTimeout;
3101             if (f) {
3102                 f.call(this.scope, {
3103                     msg: 'timeout',
3104                     data: this.data,
3105                     success: false
3106                 });
3107             }
3108         },
3109         
3110         /**
3111          * Sorts the dependency tree.  The last step of calculate()
3112          * @method _sort
3113          * @private
3114          */
3115         _sort: function() {
3116             // create an indexed list
3117             var s=[], info=this.moduleInfo, loaded=this.loaded,
3118                 checkOptional=!this.loadOptional, me = this;
3119
3120             // returns true if b is not loaded, and is required
3121             // directly or by means of modules it supersedes.
3122             var requires = function(aa, bb) {
3123
3124                 var mm=info[aa];
3125
3126                 if (loaded[bb] || !mm) {
3127                     return false;
3128                 }
3129
3130                 var ii, 
3131                     rr = mm.expanded, 
3132                     after = mm.after, 
3133                     other = info[bb],
3134                     optional = mm.optional;
3135
3136
3137                 // check if this module requires the other directly
3138                 if (rr && YUI.ArrayUtil.indexOf(rr, bb) > -1) {
3139                     return true;
3140                 }
3141
3142                 // check if this module should be sorted after the other
3143                 if (after && YUI.ArrayUtil.indexOf(after, bb) > -1) {
3144                     return true;
3145                 }
3146
3147                 // if loadOptional is not specified, optional dependencies still
3148                 // must be sorted correctly when present.
3149                 if (checkOptional && optional && YUI.ArrayUtil.indexOf(optional, bb) > -1) {
3150                     return true;
3151                 }
3152
3153                 // check if this module requires one the other supersedes
3154                 var ss=info[bb] && info[bb].supersedes;
3155                 if (ss) {
3156                     for (ii=0; ii<ss.length; ii=ii+1) {
3157                         if (requires(aa, ss[ii])) {
3158                             return true;
3159                         }
3160                     }
3161                 }
3162
3163                 // var ss=me.getProvides(bb, true);
3164                 // if (ss) {
3165                 //     for (ii in ss) {
3166                 //         if (requires(aa, ii)) {
3167                 //             return true;
3168                 //         }
3169                 //     }
3170                 // }
3171
3172                 // external css files should be sorted below yui css
3173                 if (mm.ext && mm.type == 'css' && !other.ext && other.type == 'css') {
3174                     return true;
3175                 }
3176
3177                 return false;
3178             };
3179
3180             // get the required items out of the obj into an array so we
3181             // can sort
3182             for (var i in this.required) {
3183                 if (lang.hasOwnProperty(this.required, i)) {
3184                     s.push(i);
3185                 }
3186             }
3187
3188             // pointer to the first unsorted item
3189             var p=0; 
3190
3191             // keep going until we make a pass without moving anything
3192             for (;;) {
3193                
3194                 var l=s.length, a, b, j, k, moved=false;
3195
3196                 // start the loop after items that are already sorted
3197                 for (j=p; j<l; j=j+1) {
3198
3199                     // check the next module on the list to see if its
3200                     // dependencies have been met
3201                     a = s[j];
3202
3203                     // check everything below current item and move if we
3204                     // find a requirement for the current item
3205                     for (k=j+1; k<l; k=k+1) {
3206                         if (requires(a, s[k])) {
3207
3208                             // extract the dependency so we can move it up
3209                             b = s.splice(k, 1);
3210
3211                             // insert the dependency above the item that 
3212                             // requires it
3213                             s.splice(j, 0, b[0]);
3214
3215                             moved = true;
3216                             break;
3217                         }
3218                     }
3219
3220                     // jump out of loop if we moved something
3221                     if (moved) {
3222                         break;
3223                     // this item is sorted, move our pointer and keep going
3224                     } else {
3225                         p = p + 1;
3226                     }
3227                 }
3228
3229                 // when we make it here and moved is false, we are 
3230                 // finished sorting
3231                 if (!moved) {
3232                     break;
3233                 }
3234
3235             }
3236
3237             this.sorted = s;
3238         },
3239
3240         toString: function() {
3241             var o = {
3242                 type: "YUILoader",
3243                 base: this.base,
3244                 filter: this.filter,
3245                 required: this.required,
3246                 loaded: this.loaded,
3247                 inserted: this.inserted
3248             };
3249
3250             lang.dump(o, 1);
3251         },
3252
3253         _combine: function() {
3254
3255                 this._combining = []; 
3256
3257                 var self = this,
3258                     s=this.sorted,
3259                     len = s.length,
3260                     js = this.comboBase,
3261                     css = this.comboBase,
3262                     target, 
3263                     startLen = js.length,
3264                     i, m, type = this.loadType;
3265
3266                 YAHOO.log('type ' + type);
3267
3268                 for (i=0; i<len; i=i+1) {
3269
3270                     m = this.moduleInfo[s[i]];
3271
3272                     if (m && !m.ext && (!type || type === m.type)) {
3273
3274                         target = this.root + m.path;
3275
3276                         // if (i < len-1) {
3277                         target += '&';
3278                         // }
3279
3280                         if (m.type == 'js') {
3281                             js += target;
3282                         } else {
3283                             css += target;
3284                         }
3285
3286                         // YAHOO.log(target);
3287                         this._combining.push(s[i]);
3288                     }
3289                 }
3290
3291                 if (this._combining.length) {
3292
3293 YAHOO.log('Attempting to combine: ' + this._combining, "info", "loader");
3294
3295                     var callback=function(o) {
3296                         // YAHOO.log('Combo complete: ' + o.data, "info", "loader");
3297                         // this._combineComplete = true;
3298
3299                         var c=this._combining, len=c.length, i, m;
3300                         for (i=0; i<len; i=i+1) {
3301                             this.inserted[c[i]] = true;
3302                         }
3303
3304                         this.loadNext(o.data);
3305                     }, 
3306                     
3307                     loadScript = function() {
3308                         // YAHOO.log('combining js: ' + js);
3309                         if (js.length > startLen) {
3310                             YAHOO.util.Get.script(self._filter(js), {
3311                                 data: self._loading,
3312                                 onSuccess: callback,
3313                                 onFailure: self._onFailure,
3314                                 onTimeout: self._onTimeout,
3315                                 insertBefore: self.insertBefore,
3316                                 charset: self.charset,
3317                                 timeout: self.timeout,
3318                                 scope: self 
3319                             });
3320                         }
3321                     };
3322
3323                     // load the css first
3324                     // YAHOO.log('combining css: ' + css);
3325                     if (css.length > startLen) {
3326                         YAHOO.util.Get.css(this._filter(css), {
3327                             data: this._loading,
3328                             onSuccess: loadScript,
3329                             onFailure: this._onFailure,
3330                             onTimeout: this._onTimeout,
3331                             insertBefore: this.insertBefore,
3332                             charset: this.charset,
3333                             timeout: this.timeout,
3334                             scope: self 
3335                         });
3336                     } else {
3337                         loadScript();
3338                     }
3339
3340                     return;
3341
3342                 } else {
3343                     // this._combineComplete = true;
3344                     this.loadNext(this._loading);
3345                 }
3346         }, 
3347
3348         /**
3349          * inserts the requested modules and their dependencies.  
3350          * <code>type</code> can be "js" or "css".  Both script and 
3351          * css are inserted if type is not provided.
3352          * @method insert
3353          * @param o optional options object
3354          * @param type {string} the type of dependency to insert
3355          */
3356         insert: function(o, type) {
3357             // if (o) {
3358             //     Y.log("insert: " + lang.dump(o, 1) + ", " + type);
3359             // } else {
3360             //     Y.log("insert: " + this.toString() + ", " + type);
3361             // }
3362
3363             // build the dependency list
3364             this.calculate(o);
3365
3366
3367             // set a flag to indicate the load has started
3368             this._loading = true;
3369
3370             // flag to indicate we are done with the combo service
3371             // and any additional files will need to be loaded
3372             // individually
3373             // this._combineComplete = false;
3374
3375             // keep the loadType (js, css or undefined) cached
3376             this.loadType = type;
3377
3378             if (this.combine) {
3379                 return this._combine();
3380             }
3381
3382             if (!type) {
3383                 // Y.log("trying to load css first");
3384                 var self = this;
3385                 this._internalCallback = function() {
3386                             self._internalCallback = null;
3387                             self.insert(null, "js");
3388                         };
3389                 this.insert(null, "css");
3390                 return;
3391             }
3392
3393
3394             // start the load
3395             this.loadNext();
3396
3397         },
3398
3399         /**
3400          * Interns the script for the requested modules.  The callback is
3401          * provided a reference to the sandboxed YAHOO object.  This only
3402          * applies to the script: css can not be sandboxed; css will be
3403          * loaded into the page normally if specified.
3404          * @method sandbox
3405          * @param callback {Function} the callback to exectued when the load is
3406          *        complete.
3407          */
3408         sandbox: function(o, type) {
3409             // if (o) {
3410                 // YAHOO.log("sandbox: " + lang.dump(o, 1) + ", " + type);
3411             // } else {
3412                 // YAHOO.log("sandbox: " + this.toString() + ", " + type);
3413             // }
3414
3415             this._config(o);
3416
3417             if (!this.onSuccess) {
3418 throw new Error("You must supply an onSuccess handler for your sandbox");
3419             }
3420
3421             this._sandbox = true;
3422
3423             var self = this;
3424
3425             // take care of any css first (this can't be sandboxed)
3426             if (!type || type !== "js") {
3427                 this._internalCallback = function() {
3428                             self._internalCallback = null;
3429                             self.sandbox(null, "js");
3430                         };
3431                 this.insert(null, "css");
3432                 return;
3433             }
3434
3435             // get the connection manager if not on the page
3436             if (!util.Connect) {
3437                 // get a new loader instance to load connection.
3438                 var ld = new YAHOO.util.YUILoader();
3439                 ld.insert({
3440                     base: this.base,
3441                     filter: this.filter,
3442                     require: "connection",
3443                     insertBefore: this.insertBefore,
3444                     charset: this.charset,
3445                     onSuccess: function() {
3446                         this.sandbox(null, "js");
3447                     },
3448                     scope: this
3449                 }, "js");
3450                 return;
3451             }
3452
3453             this._scriptText = [];
3454             this._loadCount = 0;
3455             this._stopCount = this.sorted.length;
3456             this._xhr = [];
3457
3458             this.calculate();
3459
3460             var s=this.sorted, l=s.length, i, m, url;
3461
3462             for (i=0; i<l; i=i+1) {
3463                 m = this.moduleInfo[s[i]];
3464
3465                 // undefined modules cause a failure
3466                 if (!m) {
3467                     this._onFailure("undefined module " + m);
3468                     for (var j=0;j<this._xhr.length;j=j+1) {
3469                         this._xhr[j].abort();
3470                     }
3471                     return;
3472                 }
3473
3474                 // css files should be done
3475                 if (m.type !== "js") {
3476                     this._loadCount++;
3477                     continue;
3478                 }
3479
3480                 url = m.fullpath;
3481                 url = (url) ? this._filter(url) : this._url(m.path);
3482
3483                 // YAHOO.log("xhr request: " + url + ", " + i);
3484
3485                 var xhrData = {
3486
3487                     success: function(o) {
3488                         
3489                         var idx=o.argument[0], name=o.argument[2];
3490
3491                         // store the response in the position it was requested
3492                         this._scriptText[idx] = o.responseText; 
3493                         
3494                         // YAHOO.log("received: " + o.responseText.substr(0, 100) + ", " + idx);
3495                     
3496                         if (this.onProgress) {
3497                             this.onProgress.call(this.scope, {
3498                                         name: name,
3499                                         scriptText: o.responseText,
3500                                         xhrResponse: o,
3501                                         data: this.data
3502                                     });
3503                         }
3504
3505                         // only generate the sandbox once everything is loaded
3506                         this._loadCount++;
3507
3508                         if (this._loadCount >= this._stopCount) {
3509
3510                             // the variable to find
3511                             var v = this.varName || "YAHOO";
3512
3513                             // wrap the contents of the requested modules in an anonymous function
3514                             var t = "(function() {\n";
3515                         
3516                             // return the locally scoped reference.
3517                             var b = "\nreturn " + v + ";\n})();";
3518
3519                             var ref = eval(t + this._scriptText.join("\n") + b);
3520
3521                             this._pushEvents(ref);
3522
3523                             if (ref) {
3524                                 this.onSuccess.call(this.scope, {
3525                                         reference: ref,
3526                                         data: this.data
3527                                     });
3528                             } else {
3529                                 this._onFailure.call(this.varName + " reference failure");
3530                             }
3531                         }
3532                     },
3533
3534                     failure: function(o) {
3535                         this.onFailure.call(this.scope, {
3536                                 msg: "XHR failure",
3537                                 xhrResponse: o,
3538                                 data: this.data
3539                             });
3540                     },
3541
3542                     scope: this,
3543
3544                     // module index, module name, sandbox name
3545                     argument: [i, url, s[i]]
3546
3547                 };
3548
3549                 this._xhr.push(util.Connect.asyncRequest('GET', url, xhrData));
3550             }
3551         },
3552
3553         /**
3554          * Executed every time a module is loaded, and if we are in a load
3555          * cycle, we attempt to load the next script.  Public so that it
3556          * is possible to call this if using a method other than
3557          * YAHOO.register to determine when scripts are fully loaded
3558          * @method loadNext
3559          * @param mname {string} optional the name of the module that has
3560          * been loaded (which is usually why it is time to load the next
3561          * one)
3562          */
3563         loadNext: function(mname) {
3564
3565             // It is possible that this function is executed due to something
3566             // else one the page loading a YUI module.  Only react when we
3567             // are actively loading something
3568             if (!this._loading) {
3569                 return;
3570             }
3571
3572
3573             if (mname) {
3574
3575                 // if the module that was just loaded isn't what we were expecting,
3576                 // continue to wait
3577                 if (mname !== this._loading) {
3578                     return;
3579                 }
3580
3581                 // YAHOO.log("loadNext executing, just loaded " + mname);
3582
3583                 // The global handler that is called when each module is loaded
3584                 // will pass that module name to this function.  Storing this
3585                 // data to avoid loading the same module multiple times
3586                 this.inserted[mname] = true;
3587
3588                 if (this.onProgress) {
3589                     this.onProgress.call(this.scope, {
3590                             name: mname,
3591                             data: this.data
3592                         });
3593                 }
3594                 //var o = this.getProvides(mname);
3595                 //this.inserted = lang.merge(this.inserted, o);
3596             }
3597
3598             var s=this.sorted, len=s.length, i, m;
3599
3600             for (i=0; i<len; i=i+1) {
3601
3602                 // This.inserted keeps track of what the loader has loaded
3603                 if (s[i] in this.inserted) {
3604                     // YAHOO.log(s[i] + " alread loaded ");
3605                     continue;
3606                 }
3607
3608                 // Because rollups will cause multiple load notifications
3609                 // from YAHOO, loadNext may be called multiple times for
3610                 // the same module when loading a rollup.  We can safely
3611                 // skip the subsequent requests
3612                 if (s[i] === this._loading) {
3613                     // YAHOO.log("still loading " + s[i] + ", waiting");
3614                     return;
3615                 }
3616
3617                 // log("inserting " + s[i]);
3618                 m = this.moduleInfo[s[i]];
3619
3620                 if (!m) {
3621                     this.onFailure.call(this.scope, {
3622                             msg: "undefined module " + m,
3623                             data: this.data
3624                         });
3625                     return;
3626                 }
3627
3628                 // The load type is stored to offer the possibility to load
3629                 // the css separately from the script.
3630                 if (!this.loadType || this.loadType === m.type) {
3631                     this._loading = s[i];
3632                     //YAHOO.log("attempting to load " + s[i] + ", " + this.base);
3633
3634                     var fn=(m.type === "css") ? util.Get.css : util.Get.script,
3635                         url = m.fullpath,
3636                         self=this, 
3637                         c=function(o) {
3638                             self.loadNext(o.data);
3639                         };
3640
3641                         url = (url) ? this._filter(url) : this._url(m.path);
3642
3643                     // safari 2.x or lower, script, and part of YUI
3644                     if (env.ua.webkit && env.ua.webkit < 420 && m.type === "js" && 
3645                           !m.varName) {
3646                           //YUI.info.moduleInfo[s[i]]) {
3647                           //YAHOO.log("using YAHOO env " + s[i] + ", " + m.varName);
3648                         c = null;
3649                         this._useYahooListener = true;
3650                     }
3651
3652                     fn(url, {
3653                         data: s[i],
3654                         onSuccess: c,
3655                         onFailure: this._onFailure,
3656                         onTimeout: this._onTimeout,
3657                         insertBefore: this.insertBefore,
3658                         charset: this.charset,
3659                         timeout: this.timeout,
3660                         varName: m.varName,
3661                         scope: self 
3662                     });
3663
3664                     return;
3665                 }
3666             }
3667
3668             // we are finished
3669             this._loading = null;
3670
3671             // internal callback for loading css first
3672             if (this._internalCallback) {
3673                 var f = this._internalCallback;
3674                 this._internalCallback = null;
3675                 f.call(this);
3676             } else if (this.onSuccess) {
3677                 this._pushEvents();
3678                 this.onSuccess.call(this.scope, {
3679                         data: this.data
3680                     });
3681             }
3682
3683         },
3684
3685         /**
3686          * In IE, the onAvailable/onDOMReady events need help when Event is
3687          * loaded dynamically
3688          * @method _pushEvents
3689          * @param {Function} optional function reference
3690          * @private
3691          */
3692         _pushEvents: function(ref) {
3693             var r = ref || YAHOO;
3694             if (r.util && r.util.Event) {
3695                 r.util.Event._load();
3696             }
3697         },
3698
3699         /**
3700          * Applies filter
3701          * method _filter
3702          * @return {string} the filtered string
3703          * @private
3704          */
3705         _filter: function(str) {
3706             var f = this.filter;
3707             return (f) ?  str.replace(new RegExp(f.searchExp, 'g'), f.replaceStr) : str;
3708         },
3709
3710         /**
3711          * Generates the full url for a module
3712          * method _url
3713          * @param path {string} the path fragment
3714          * @return {string} the full url
3715          * @private
3716          */
3717         _url: function(path) {
3718             return this._filter((this.base || "") + path);
3719         }
3720
3721     };
3722
3723 })();
3724 YAHOO.register("yuiloader", YAHOO.util.YUILoader, {version: "2.7.0", build: "1799"});