]> ToastFreeware Gitweb - philipp/winterrodeln/wradmin.git/blob - wradmin/wradmin/public/yui/yahoo/yahoo-debug.js
a4bd7f37ae91c377b25c90f28e1ab327859456cf
[philipp/winterrodeln/wradmin.git] / wradmin / wradmin / public / yui / yahoo / yahoo-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"});