~michael.nelson/ubuntu-webcatalog/1267731-import-sca-apps-error

« back to all changes in this revision

Viewing changes to src/webcatalog/static/yui/3.10.3/build/yui-base/yui-base.js

  • Committer: Tarmac
  • Author(s): Stephen Stewart
  • Date: 2013-06-26 09:19:32 UTC
  • mfrom: (184.1.4 ubuntu-global-nav)
  • Revision ID: tarmac-20130626091932-8urtuli368k8p7ds
[r=beuno,jonas-drange] add ubuntu global nav to apps.ubuntu.com

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.10.3 (build 2fb5187)
 
3
Copyright 2013 Yahoo! Inc. All rights reserved.
 
4
Licensed under the BSD License.
 
5
http://yuilibrary.com/license/
 
6
*/
 
7
 
 
8
/**
 
9
The YUI module contains the components required for building the YUI seed file.
 
10
This includes the script loading mechanism, a simple queue, and the core
 
11
utilities for the library.
 
12
 
 
13
@module yui
 
14
@main yui
 
15
@submodule yui-base
 
16
**/
 
17
 
 
18
/*jshint eqeqeq: false*/
 
19
if (typeof YUI != 'undefined') {
 
20
    YUI._YUI = YUI;
 
21
}
 
22
 
 
23
/**
 
24
The YUI global namespace object. This is the constructor for all YUI instances.
 
25
 
 
26
This is a self-instantiable factory function, meaning you don't need to precede
 
27
it with the `new` operator. You can invoke it directly like this:
 
28
 
 
29
    YUI().use('*', function (Y) {
 
30
        // Y is a new YUI instance.
 
31
    });
 
32
 
 
33
But it also works like this:
 
34
 
 
35
    var Y = YUI();
 
36
 
 
37
The `YUI` constructor accepts an optional config object, like this:
 
38
 
 
39
    YUI({
 
40
        debug: true,
 
41
        combine: false
 
42
    }).use('node', function (Y) {
 
43
        // Y.Node is ready to use.
 
44
    });
 
45
 
 
46
See the API docs for the <a href="config.html">Config</a> class for the complete
 
47
list of supported configuration properties accepted by the YUI constuctor.
 
48
 
 
49
If a global `YUI` object is already defined, the existing YUI object will not be
 
50
overwritten, to ensure that defined namespaces are preserved.
 
51
 
 
52
Each YUI instance has full custom event support, but only if the event system is
 
53
available.
 
54
 
 
55
@class YUI
 
56
@uses EventTarget
 
57
@constructor
 
58
@global
 
59
@param {Object} [config]* Zero or more optional configuration objects. Config
 
60
    values are stored in the `Y.config` property. See the
 
61
    <a href="config.html">Config</a> docs for the list of supported properties.
 
62
**/
 
63
 
 
64
    /*global YUI*/
 
65
    /*global YUI_config*/
 
66
    var YUI = function() {
 
67
        var i = 0,
 
68
            Y = this,
 
69
            args = arguments,
 
70
            l = args.length,
 
71
            instanceOf = function(o, type) {
 
72
                return (o && o.hasOwnProperty && (o instanceof type));
 
73
            },
 
74
            gconf = (typeof YUI_config !== 'undefined') && YUI_config;
 
75
 
 
76
        if (!(instanceOf(Y, YUI))) {
 
77
            Y = new YUI();
 
78
        } else {
 
79
            // set up the core environment
 
80
            Y._init();
 
81
 
 
82
            /**
 
83
            Master configuration that might span multiple contexts in a non-
 
84
            browser environment. It is applied first to all instances in all
 
85
            contexts.
 
86
 
 
87
            @example
 
88
 
 
89
                YUI.GlobalConfig = {
 
90
                    filter: 'debug'
 
91
                };
 
92
 
 
93
                YUI().use('node', function (Y) {
 
94
                    // debug files used here
 
95
                });
 
96
 
 
97
                YUI({
 
98
                    filter: 'min'
 
99
                }).use('node', function (Y) {
 
100
                    // min files used here
 
101
                });
 
102
 
 
103
            @property {Object} GlobalConfig
 
104
            @global
 
105
            @static
 
106
            **/
 
107
            if (YUI.GlobalConfig) {
 
108
                Y.applyConfig(YUI.GlobalConfig);
 
109
            }
 
110
 
 
111
            /**
 
112
            Page-level config applied to all YUI instances created on the
 
113
            current page. This is applied after `YUI.GlobalConfig` and before
 
114
            any instance-level configuration.
 
115
 
 
116
            @example
 
117
 
 
118
                // Single global var to include before YUI seed file
 
119
                YUI_config = {
 
120
                    filter: 'debug'
 
121
                };
 
122
 
 
123
                YUI().use('node', function (Y) {
 
124
                    // debug files used here
 
125
                });
 
126
 
 
127
                YUI({
 
128
                    filter: 'min'
 
129
                }).use('node', function (Y) {
 
130
                    // min files used here
 
131
                });
 
132
 
 
133
            @property {Object} YUI_config
 
134
            @global
 
135
            **/
 
136
            if (gconf) {
 
137
                Y.applyConfig(gconf);
 
138
            }
 
139
 
 
140
            // bind the specified additional modules for this instance
 
141
            if (!l) {
 
142
                Y._setup();
 
143
            }
 
144
        }
 
145
 
 
146
        if (l) {
 
147
            // Each instance can accept one or more configuration objects.
 
148
            // These are applied after YUI.GlobalConfig and YUI_Config,
 
149
            // overriding values set in those config files if there is a
 
150
            // matching property.
 
151
            for (; i < l; i++) {
 
152
                Y.applyConfig(args[i]);
 
153
            }
 
154
 
 
155
            Y._setup();
 
156
        }
 
157
 
 
158
        Y.instanceOf = instanceOf;
 
159
 
 
160
        return Y;
 
161
    };
 
162
 
 
163
(function() {
 
164
 
 
165
    var proto, prop,
 
166
        VERSION = '3.10.3',
 
167
        PERIOD = '.',
 
168
        BASE = 'http://yui.yahooapis.com/',
 
169
        /*
 
170
            These CSS class names can't be generated by
 
171
            getClassName since it is not available at the
 
172
            time they are being used.
 
173
        */
 
174
        DOC_LABEL = 'yui3-js-enabled',
 
175
        CSS_STAMP_EL = 'yui3-css-stamp',
 
176
        NOOP = function() {},
 
177
        SLICE = Array.prototype.slice,
 
178
        APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
 
179
                          'io.xdrResponse': 1,   // can call. this should
 
180
                          'SWF.eventHandler': 1 }, // be done at build time
 
181
        hasWin = (typeof window != 'undefined'),
 
182
        win = (hasWin) ? window : null,
 
183
        doc = (hasWin) ? win.document : null,
 
184
        docEl = doc && doc.documentElement,
 
185
        docClass = docEl && docEl.className,
 
186
        instances = {},
 
187
        time = new Date().getTime(),
 
188
        add = function(el, type, fn, capture) {
 
189
            if (el && el.addEventListener) {
 
190
                el.addEventListener(type, fn, capture);
 
191
            } else if (el && el.attachEvent) {
 
192
                el.attachEvent('on' + type, fn);
 
193
            }
 
194
        },
 
195
        remove = function(el, type, fn, capture) {
 
196
            if (el && el.removeEventListener) {
 
197
                // this can throw an uncaught exception in FF
 
198
                try {
 
199
                    el.removeEventListener(type, fn, capture);
 
200
                } catch (ex) {}
 
201
            } else if (el && el.detachEvent) {
 
202
                el.detachEvent('on' + type, fn);
 
203
            }
 
204
        },
 
205
        handleLoad = function() {
 
206
            YUI.Env.windowLoaded = true;
 
207
            YUI.Env.DOMReady = true;
 
208
            if (hasWin) {
 
209
                remove(window, 'load', handleLoad);
 
210
            }
 
211
        },
 
212
        getLoader = function(Y, o) {
 
213
            var loader = Y.Env._loader,
 
214
                lCore = [ 'loader-base' ],
 
215
                G_ENV = YUI.Env,
 
216
                mods = G_ENV.mods;
 
217
 
 
218
            if (loader) {
 
219
                //loader._config(Y.config);
 
220
                loader.ignoreRegistered = false;
 
221
                loader.onEnd = null;
 
222
                loader.data = null;
 
223
                loader.required = [];
 
224
                loader.loadType = null;
 
225
            } else {
 
226
                loader = new Y.Loader(Y.config);
 
227
                Y.Env._loader = loader;
 
228
            }
 
229
            if (mods && mods.loader) {
 
230
                lCore = [].concat(lCore, YUI.Env.loaderExtras);
 
231
            }
 
232
            YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
 
233
 
 
234
            return loader;
 
235
        },
 
236
 
 
237
        clobber = function(r, s) {
 
238
            for (var i in s) {
 
239
                if (s.hasOwnProperty(i)) {
 
240
                    r[i] = s[i];
 
241
                }
 
242
            }
 
243
        },
 
244
 
 
245
        ALREADY_DONE = { success: true };
 
246
 
 
247
//  Stamp the documentElement (HTML) with a class of "yui-loaded" to
 
248
//  enable styles that need to key off of JS being enabled.
 
249
if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
 
250
    if (docClass) {
 
251
        docClass += ' ';
 
252
    }
 
253
    docClass += DOC_LABEL;
 
254
    docEl.className = docClass;
 
255
}
 
256
 
 
257
if (VERSION.indexOf('@') > -1) {
 
258
    VERSION = '3.5.0'; // dev time hack for cdn test
 
259
}
 
260
 
 
261
proto = {
 
262
    /**
 
263
    Applies a new configuration object to the config of this YUI instance. This
 
264
    will merge new group/module definitions, and will also update the loader
 
265
    cache if necessary. Updating `Y.config` directly will not update the cache.
 
266
 
 
267
    @method applyConfig
 
268
    @param {Object} o the configuration object.
 
269
    @since 3.2.0
 
270
    **/
 
271
    applyConfig: function(o) {
 
272
 
 
273
        o = o || NOOP;
 
274
 
 
275
        var attr,
 
276
            name,
 
277
            // detail,
 
278
            config = this.config,
 
279
            mods = config.modules,
 
280
            groups = config.groups,
 
281
            aliases = config.aliases,
 
282
            loader = this.Env._loader;
 
283
 
 
284
        for (name in o) {
 
285
            if (o.hasOwnProperty(name)) {
 
286
                attr = o[name];
 
287
                if (mods && name == 'modules') {
 
288
                    clobber(mods, attr);
 
289
                } else if (aliases && name == 'aliases') {
 
290
                    clobber(aliases, attr);
 
291
                } else if (groups && name == 'groups') {
 
292
                    clobber(groups, attr);
 
293
                } else if (name == 'win') {
 
294
                    config[name] = (attr && attr.contentWindow) || attr;
 
295
                    config.doc = config[name] ? config[name].document : null;
 
296
                } else if (name == '_yuid') {
 
297
                    // preserve the guid
 
298
                } else {
 
299
                    config[name] = attr;
 
300
                }
 
301
            }
 
302
        }
 
303
 
 
304
        if (loader) {
 
305
            loader._config(o);
 
306
        }
 
307
 
 
308
    },
 
309
 
 
310
    /**
 
311
    Old way to apply a config to this instance (calls `applyConfig` under the
 
312
    hood).
 
313
 
 
314
    @private
 
315
    @method _config
 
316
    @param {Object} o The config to apply
 
317
    **/
 
318
    _config: function(o) {
 
319
        this.applyConfig(o);
 
320
    },
 
321
 
 
322
    /**
 
323
    Initializes this YUI instance.
 
324
 
 
325
    @private
 
326
    @method _init
 
327
    **/
 
328
    _init: function() {
 
329
        var filter, el,
 
330
            Y = this,
 
331
            G_ENV = YUI.Env,
 
332
            Env = Y.Env,
 
333
            prop;
 
334
 
 
335
        /**
 
336
        The version number of this YUI instance.
 
337
 
 
338
        This value is typically updated by a script when a YUI release is built,
 
339
        so it may not reflect the correct version number when YUI is run from
 
340
        the development source tree.
 
341
 
 
342
        @property {String} version
 
343
        **/
 
344
        Y.version = VERSION;
 
345
 
 
346
        if (!Env) {
 
347
            Y.Env = {
 
348
                core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later'],
 
349
                loaderExtras: ['loader-rollup', 'loader-yui3'],
 
350
                mods: {}, // flat module map
 
351
                versions: {}, // version module map
 
352
                base: BASE,
 
353
                cdn: BASE + VERSION + '/build/',
 
354
                // bootstrapped: false,
 
355
                _idx: 0,
 
356
                _used: {},
 
357
                _attached: {},
 
358
                _missed: [],
 
359
                _yidx: 0,
 
360
                _uidx: 0,
 
361
                _guidp: 'y',
 
362
                _loaded: {},
 
363
                // serviced: {},
 
364
                // Regex in English:
 
365
                // I'll start at the \b(simpleyui).
 
366
                // 1. Look in the test string for "simpleyui" or "yui" or
 
367
                //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
 
368
                //    can't match "foyui" or "i_heart_simpleyui". This can be anywhere in the string.
 
369
                // 2. After #1 must come a forward slash followed by the string matched in #1, so
 
370
                //    "yui-base/yui-base" or "simpleyui/simpleyui" or "yui-pants/yui-pants".
 
371
                // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
 
372
                //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
 
373
                // 4. This is followed by ".js", so "yui/yui.js", "simpleyui/simpleyui-min.js"
 
374
                // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
 
375
                //    then capture the junk between the LAST "&" and the string in 1-4.  So
 
376
                //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
 
377
                //    will capture "3.3.0/build/"
 
378
                //
 
379
                // Regex Exploded:
 
380
                // (?:\?             Find a ?
 
381
                //   (?:[^&]*&)      followed by 0..n characters followed by an &
 
382
                //   *               in fact, find as many sets of characters followed by a & as you can
 
383
                //   ([^&]*)         capture the stuff after the last & in \1
 
384
                // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
 
385
                // \b(simpleyui|     after a word break find either the string "simpleyui" or
 
386
                //    yui(?:-\w+)?   the string "yui" optionally followed by a -, then more characters
 
387
                // )                 and store the simpleyui or yui-* string in \2
 
388
                // \/\2              then comes a / followed by the simpleyui or yui-* string in \2
 
389
                // (?:-(min|debug))? optionally followed by "-min" or "-debug"
 
390
                // .js               and ending in ".js"
 
391
                _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
 
392
                parseBasePath: function(src, pattern) {
 
393
                    var match = src.match(pattern),
 
394
                        path, filter;
 
395
 
 
396
                    if (match) {
 
397
                        path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
 
398
 
 
399
                        // this is to set up the path to the loader.  The file
 
400
                        // filter for loader should match the yui include.
 
401
                        filter = match[3];
 
402
 
 
403
                        // extract correct path for mixed combo urls
 
404
                        // http://yuilibrary.com/projects/yui3/ticket/2528423
 
405
                        if (match[1]) {
 
406
                            path += '?' + match[1];
 
407
                        }
 
408
                        path = {
 
409
                            filter: filter,
 
410
                            path: path
 
411
                        };
 
412
                    }
 
413
                    return path;
 
414
                },
 
415
                getBase: G_ENV && G_ENV.getBase ||
 
416
                        function(pattern) {
 
417
                            var nodes = (doc && doc.getElementsByTagName('script')) || [],
 
418
                                path = Env.cdn, parsed,
 
419
                                i, len, src;
 
420
 
 
421
                            for (i = 0, len = nodes.length; i < len; ++i) {
 
422
                                src = nodes[i].src;
 
423
                                if (src) {
 
424
                                    parsed = Y.Env.parseBasePath(src, pattern);
 
425
                                    if (parsed) {
 
426
                                        filter = parsed.filter;
 
427
                                        path = parsed.path;
 
428
                                        break;
 
429
                                    }
 
430
                                }
 
431
                            }
 
432
 
 
433
                            // use CDN default
 
434
                            return path;
 
435
                        }
 
436
 
 
437
            };
 
438
 
 
439
            Env = Y.Env;
 
440
 
 
441
            Env._loaded[VERSION] = {};
 
442
 
 
443
            if (G_ENV && Y !== YUI) {
 
444
                Env._yidx = ++G_ENV._yidx;
 
445
                Env._guidp = ('yui_' + VERSION + '_' +
 
446
                             Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
 
447
            } else if (YUI._YUI) {
 
448
 
 
449
                G_ENV = YUI._YUI.Env;
 
450
                Env._yidx += G_ENV._yidx;
 
451
                Env._uidx += G_ENV._uidx;
 
452
 
 
453
                for (prop in G_ENV) {
 
454
                    if (!(prop in Env)) {
 
455
                        Env[prop] = G_ENV[prop];
 
456
                    }
 
457
                }
 
458
 
 
459
                delete YUI._YUI;
 
460
            }
 
461
 
 
462
            Y.id = Y.stamp(Y);
 
463
            instances[Y.id] = Y;
 
464
 
 
465
        }
 
466
 
 
467
        Y.constructor = YUI;
 
468
 
 
469
        // configuration defaults
 
470
        Y.config = Y.config || {
 
471
            bootstrap: true,
 
472
            cacheUse: true,
 
473
            debug: true,
 
474
            doc: doc,
 
475
            fetchCSS: true,
 
476
            throwFail: true,
 
477
            useBrowserConsole: true,
 
478
            useNativeES5: true,
 
479
            win: win,
 
480
            global: Function('return this')()
 
481
        };
 
482
 
 
483
        //Register the CSS stamp element
 
484
        if (doc && !doc.getElementById(CSS_STAMP_EL)) {
 
485
            el = doc.createElement('div');
 
486
            el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
 
487
            YUI.Env.cssStampEl = el.firstChild;
 
488
            if (doc.body) {
 
489
                doc.body.appendChild(YUI.Env.cssStampEl);
 
490
            } else {
 
491
                docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
 
492
            }
 
493
        } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
 
494
            YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
 
495
        }
 
496
 
 
497
        Y.config.lang = Y.config.lang || 'en-US';
 
498
 
 
499
        Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
 
500
 
 
501
        if (!filter || (!('mindebug').indexOf(filter))) {
 
502
            filter = 'min';
 
503
        }
 
504
        filter = (filter) ? '-' + filter : filter;
 
505
        Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
 
506
 
 
507
    },
 
508
 
 
509
    /**
 
510
    Finishes the instance setup. Attaches whatever YUI modules were defined
 
511
    at the time that this instance was created.
 
512
 
 
513
    @method _setup
 
514
    @private
 
515
    **/
 
516
    _setup: function() {
 
517
        var i, Y = this,
 
518
            core = [],
 
519
            mods = YUI.Env.mods,
 
520
            extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
 
521
 
 
522
        for (i = 0; i < extras.length; i++) {
 
523
            if (mods[extras[i]]) {
 
524
                core.push(extras[i]);
 
525
            }
 
526
        }
 
527
 
 
528
        Y._attach(['yui-base']);
 
529
        Y._attach(core);
 
530
 
 
531
        if (Y.Loader) {
 
532
            getLoader(Y);
 
533
        }
 
534
 
 
535
    },
 
536
 
 
537
    /**
 
538
    Executes the named method on the specified YUI instance if that method is
 
539
    whitelisted.
 
540
 
 
541
    @method applyTo
 
542
    @param {String} id YUI instance id.
 
543
    @param {String} method Name of the method to execute. For example:
 
544
        'Object.keys'.
 
545
    @param {Array} args Arguments to apply to the method.
 
546
    @return {Mixed} Return value from the applied method, or `null` if the
 
547
        specified instance was not found or the method was not whitelisted.
 
548
    **/
 
549
    applyTo: function(id, method, args) {
 
550
        if (!(method in APPLY_TO_AUTH)) {
 
551
            this.log(method + ': applyTo not allowed', 'warn', 'yui');
 
552
            return null;
 
553
        }
 
554
 
 
555
        var instance = instances[id], nest, m, i;
 
556
        if (instance) {
 
557
            nest = method.split('.');
 
558
            m = instance;
 
559
            for (i = 0; i < nest.length; i = i + 1) {
 
560
                m = m[nest[i]];
 
561
                if (!m) {
 
562
                    this.log('applyTo not found: ' + method, 'warn', 'yui');
 
563
                }
 
564
            }
 
565
            return m && m.apply(instance, args);
 
566
        }
 
567
 
 
568
        return null;
 
569
    },
 
570
 
 
571
/**
 
572
Registers a YUI module and makes it available for use in a `YUI().use()` call or
 
573
as a dependency for other modules.
 
574
 
 
575
The easiest way to create a first-class YUI module is to use
 
576
<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
 
577
tool.
 
578
 
 
579
Shifter will automatically wrap your module code in a `YUI.add()` call along
 
580
with any configuration info required for the module.
 
581
 
 
582
@example
 
583
 
 
584
    YUI.add('davglass', function (Y) {
 
585
        Y.davglass = function () {
 
586
        };
 
587
    }, '3.4.0', {
 
588
        requires: ['harley-davidson', 'mt-dew']
 
589
    });
 
590
 
 
591
@method add
 
592
@param {String} name Module name.
 
593
@param {Function} fn Function containing module code. This function will be
 
594
    executed whenever the module is attached to a specific YUI instance.
 
595
 
 
596
    @param {YUI} fn.Y The YUI instance to which this module is attached.
 
597
    @param {String} fn.name Name of the module
 
598
 
 
599
@param {String} version Module version number. This is currently used only for
 
600
    informational purposes, and is not used internally by YUI.
 
601
 
 
602
@param {Object} [config] Module config.
 
603
    @param {Array} [config.requires] Array of other module names that must be
 
604
        attached before this module can be attached.
 
605
    @param {Array} [config.optional] Array of optional module names that should
 
606
        be attached before this module is attached if they've already been
 
607
        loaded. If the `loadOptional` YUI option is `true`, optional modules
 
608
        that have not yet been loaded will be loaded just as if they were hard
 
609
        requirements.
 
610
    @param {Array} [config.use] Array of module names that are included within
 
611
        or otherwise provided by this module, and which should be attached
 
612
        automatically when this module is attached. This makes it possible to
 
613
        create "virtual rollup" modules that simply attach a collection of other
 
614
        modules or submodules.
 
615
 
 
616
@return {YUI} This YUI instance.
 
617
**/
 
618
    add: function(name, fn, version, details) {
 
619
        details = details || {};
 
620
        var env = YUI.Env,
 
621
            mod = {
 
622
                name: name,
 
623
                fn: fn,
 
624
                version: version,
 
625
                details: details
 
626
            },
 
627
            //Instance hash so we don't apply it to the same instance twice
 
628
            applied = {},
 
629
            loader, inst,
 
630
            i, versions = env.versions;
 
631
 
 
632
        env.mods[name] = mod;
 
633
        versions[version] = versions[version] || {};
 
634
        versions[version][name] = mod;
 
635
 
 
636
        for (i in instances) {
 
637
            if (instances.hasOwnProperty(i)) {
 
638
                inst = instances[i];
 
639
                if (!applied[inst.id]) {
 
640
                    applied[inst.id] = true;
 
641
                    loader = inst.Env._loader;
 
642
                    if (loader) {
 
643
                        if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) {
 
644
                            loader.addModule(details, name);
 
645
                        }
 
646
                    }
 
647
                }
 
648
            }
 
649
        }
 
650
 
 
651
        return this;
 
652
    },
 
653
 
 
654
    /**
 
655
    Executes the callback function associated with each required module,
 
656
    attaching the module to this YUI instance.
 
657
 
 
658
    @method _attach
 
659
    @param {Array} r The array of modules to attach
 
660
    @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
 
661
        is not attached.
 
662
    @private
 
663
    **/
 
664
    _attach: function(r, moot) {
 
665
        var i, name, mod, details, req, use, after,
 
666
            mods = YUI.Env.mods,
 
667
            aliases = YUI.Env.aliases,
 
668
            Y = this, j,
 
669
            cache = YUI.Env._renderedMods,
 
670
            loader = Y.Env._loader,
 
671
            done = Y.Env._attached,
 
672
            len = r.length, loader, def, go,
 
673
            c = [];
 
674
 
 
675
        //Check for conditional modules (in a second+ instance) and add their requirements
 
676
        //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
 
677
        for (i = 0; i < len; i++) {
 
678
            name = r[i];
 
679
            mod = mods[name];
 
680
            c.push(name);
 
681
            if (loader && loader.conditions[name]) {
 
682
                for (j in loader.conditions[name]) {
 
683
                    if (loader.conditions[name].hasOwnProperty(j)) {
 
684
                        def = loader.conditions[name][j];
 
685
                        go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
 
686
                        if (go) {
 
687
                            c.push(def.name);
 
688
                        }
 
689
                    }
 
690
                }
 
691
            }
 
692
        }
 
693
        r = c;
 
694
        len = r.length;
 
695
 
 
696
        for (i = 0; i < len; i++) {
 
697
            if (!done[r[i]]) {
 
698
                name = r[i];
 
699
                mod = mods[name];
 
700
 
 
701
                if (aliases && aliases[name] && !mod) {
 
702
                    Y._attach(aliases[name]);
 
703
                    continue;
 
704
                }
 
705
                if (!mod) {
 
706
                    if (loader && loader.moduleInfo[name]) {
 
707
                        mod = loader.moduleInfo[name];
 
708
                        moot = true;
 
709
                    }
 
710
 
 
711
 
 
712
                    //if (!loader || !loader.moduleInfo[name]) {
 
713
                    //if ((!loader || !loader.moduleInfo[name]) && !moot) {
 
714
                    if (!moot && name) {
 
715
                        if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
 
716
                            Y.Env._missed.push(name);
 
717
                            Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
 
718
                            Y.message('NOT loaded: ' + name, 'warn', 'yui');
 
719
                        }
 
720
                    }
 
721
                } else {
 
722
                    done[name] = true;
 
723
                    //Don't like this, but in case a mod was asked for once, then we fetch it
 
724
                    //We need to remove it from the missed list ^davglass
 
725
                    for (j = 0; j < Y.Env._missed.length; j++) {
 
726
                        if (Y.Env._missed[j] === name) {
 
727
                            Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
 
728
                            Y.Env._missed.splice(j, 1);
 
729
                        }
 
730
                    }
 
731
                    /*
 
732
                        If it's a temp module, we need to redo it's requirements if it's already loaded
 
733
                        since it may have been loaded by another instance and it's dependencies might
 
734
                        have been redefined inside the fetched file.
 
735
                    */
 
736
                    if (loader && cache && cache[name] && cache[name].temp) {
 
737
                        loader.getRequires(cache[name]);
 
738
                        req = [];
 
739
                        for (j in loader.moduleInfo[name].expanded_map) {
 
740
                            if (loader.moduleInfo[name].expanded_map.hasOwnProperty(j)) {
 
741
                                req.push(j);
 
742
                            }
 
743
                        }
 
744
                        Y._attach(req);
 
745
                    }
 
746
 
 
747
                    details = mod.details;
 
748
                    req = details.requires;
 
749
                    use = details.use;
 
750
                    after = details.after;
 
751
                    //Force Intl load if there is a language (Loader logic) @todo fix this shit
 
752
                    if (details.lang) {
 
753
                        req = req || [];
 
754
                        req.unshift('intl');
 
755
                    }
 
756
 
 
757
                    if (req) {
 
758
                        for (j = 0; j < req.length; j++) {
 
759
                            if (!done[req[j]]) {
 
760
                                if (!Y._attach(req)) {
 
761
                                    return false;
 
762
                                }
 
763
                                break;
 
764
                            }
 
765
                        }
 
766
                    }
 
767
 
 
768
                    if (after) {
 
769
                        for (j = 0; j < after.length; j++) {
 
770
                            if (!done[after[j]]) {
 
771
                                if (!Y._attach(after, true)) {
 
772
                                    return false;
 
773
                                }
 
774
                                break;
 
775
                            }
 
776
                        }
 
777
                    }
 
778
 
 
779
                    if (mod.fn) {
 
780
                            if (Y.config.throwFail) {
 
781
                                mod.fn(Y, name);
 
782
                            } else {
 
783
                                try {
 
784
                                    mod.fn(Y, name);
 
785
                                } catch (e) {
 
786
                                    Y.error('Attach error: ' + name, e, name);
 
787
                                return false;
 
788
                            }
 
789
                        }
 
790
                    }
 
791
 
 
792
                    if (use) {
 
793
                        for (j = 0; j < use.length; j++) {
 
794
                            if (!done[use[j]]) {
 
795
                                if (!Y._attach(use)) {
 
796
                                    return false;
 
797
                                }
 
798
                                break;
 
799
                            }
 
800
                        }
 
801
                    }
 
802
 
 
803
 
 
804
 
 
805
                }
 
806
            }
 
807
        }
 
808
 
 
809
        return true;
 
810
    },
 
811
 
 
812
    /**
 
813
    Delays the `use` callback until another event has taken place such as
 
814
    `window.onload`, `domready`, `contentready`, or `available`.
 
815
 
 
816
    @private
 
817
    @method _delayCallback
 
818
    @param {Function} cb The original `use` callback.
 
819
    @param {String|Object} until Either an event name ('load', 'domready', etc.)
 
820
        or an object containing event/args keys for contentready/available.
 
821
    @return {Function}
 
822
    **/
 
823
    _delayCallback: function(cb, until) {
 
824
 
 
825
        var Y = this,
 
826
            mod = ['event-base'];
 
827
 
 
828
        until = (Y.Lang.isObject(until) ? until : { event: until });
 
829
 
 
830
        if (until.event === 'load') {
 
831
            mod.push('event-synthetic');
 
832
        }
 
833
 
 
834
        return function() {
 
835
            var args = arguments;
 
836
            Y._use(mod, function() {
 
837
                Y.on(until.event, function() {
 
838
                    args[1].delayUntil = until.event;
 
839
                    cb.apply(Y, args);
 
840
                }, until.args);
 
841
            });
 
842
        };
 
843
    },
 
844
 
 
845
    /**
 
846
    Attaches one or more modules to this YUI instance. When this is executed,
 
847
    the requirements of the desired modules are analyzed, and one of several
 
848
    things can happen:
 
849
 
 
850
 
 
851
      * All required modules have already been loaded, and just need to be
 
852
        attached to this YUI instance. In this case, the `use()` callback will
 
853
        be executed synchronously after the modules are attached.
 
854
 
 
855
      * One or more modules have not yet been loaded, or the Get utility is not
 
856
        available, or the `bootstrap` config option is `false`. In this case,
 
857
        a warning is issued indicating that modules are missing, but all
 
858
        available modules will still be attached and the `use()` callback will
 
859
        be executed synchronously.
 
860
 
 
861
      * One or more modules are missing and the Loader is not available but the
 
862
        Get utility is, and `bootstrap` is not `false`. In this case, the Get
 
863
        utility will be used to load the Loader, and we will then proceed to
 
864
        the following state:
 
865
 
 
866
      * One or more modules are missing and the Loader is available. In this
 
867
        case, the Loader will be used to resolve the dependency tree for the
 
868
        missing modules and load them and their dependencies. When the Loader is
 
869
        finished loading modules, the `use()` callback will be executed
 
870
        asynchronously.
 
871
 
 
872
    @example
 
873
 
 
874
        // Loads and attaches dd and its dependencies.
 
875
        YUI().use('dd', function (Y) {
 
876
            // ...
 
877
        });
 
878
 
 
879
        // Loads and attaches dd and node as well as all of their dependencies.
 
880
        YUI().use(['dd', 'node'], function (Y) {
 
881
            // ...
 
882
        });
 
883
 
 
884
        // Attaches all modules that have already been loaded.
 
885
        YUI().use('*', function (Y) {
 
886
            // ...
 
887
        });
 
888
 
 
889
        // Attaches a gallery module.
 
890
        YUI().use('gallery-yql', function (Y) {
 
891
            // ...
 
892
        });
 
893
 
 
894
        // Attaches a YUI 2in3 module.
 
895
        YUI().use('yui2-datatable', function (Y) {
 
896
            // ...
 
897
        });
 
898
 
 
899
    @method use
 
900
    @param {String|Array} modules* One or more module names to attach.
 
901
    @param {Function} [callback] Callback function to be executed once all
 
902
        specified modules and their dependencies have been attached.
 
903
    @param {YUI} callback.Y The YUI instance created for this sandbox.
 
904
    @param {Object} callback.status Object containing `success`, `msg` and
 
905
        `data` properties.
 
906
    @chainable
 
907
    **/
 
908
    use: function() {
 
909
        var args = SLICE.call(arguments, 0),
 
910
            callback = args[args.length - 1],
 
911
            Y = this,
 
912
            i = 0,
 
913
            name,
 
914
            Env = Y.Env,
 
915
            provisioned = true;
 
916
 
 
917
        // The last argument supplied to use can be a load complete callback
 
918
        if (Y.Lang.isFunction(callback)) {
 
919
            args.pop();
 
920
            if (Y.config.delayUntil) {
 
921
                callback = Y._delayCallback(callback, Y.config.delayUntil);
 
922
            }
 
923
        } else {
 
924
            callback = null;
 
925
        }
 
926
        if (Y.Lang.isArray(args[0])) {
 
927
            args = args[0];
 
928
        }
 
929
 
 
930
        if (Y.config.cacheUse) {
 
931
            while ((name = args[i++])) {
 
932
                if (!Env._attached[name]) {
 
933
                    provisioned = false;
 
934
                    break;
 
935
                }
 
936
            }
 
937
 
 
938
            if (provisioned) {
 
939
                if (args.length) {
 
940
                }
 
941
                Y._notify(callback, ALREADY_DONE, args);
 
942
                return Y;
 
943
            }
 
944
        }
 
945
 
 
946
        if (Y._loading) {
 
947
            Y._useQueue = Y._useQueue || new Y.Queue();
 
948
            Y._useQueue.add([args, callback]);
 
949
        } else {
 
950
            Y._use(args, function(Y, response) {
 
951
                Y._notify(callback, response, args);
 
952
            });
 
953
        }
 
954
 
 
955
        return Y;
 
956
    },
 
957
 
 
958
    /**
 
959
    Handles Loader notifications about attachment/load errors.
 
960
 
 
961
    @method _notify
 
962
    @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
 
963
    @param {Object} response Response returned from Loader.
 
964
    @param {Array} args Arguments passed from Loader.
 
965
    @private
 
966
    **/
 
967
    _notify: function(callback, response, args) {
 
968
        if (!response.success && this.config.loadErrorFn) {
 
969
            this.config.loadErrorFn.call(this, this, callback, response, args);
 
970
        } else if (callback) {
 
971
            if (this.Env._missed && this.Env._missed.length) {
 
972
                response.msg = 'Missing modules: ' + this.Env._missed.join();
 
973
                response.success = false;
 
974
            }
 
975
            if (this.config.throwFail) {
 
976
                callback(this, response);
 
977
            } else {
 
978
                try {
 
979
                    callback(this, response);
 
980
                } catch (e) {
 
981
                    this.error('use callback error', e, args);
 
982
                }
 
983
            }
 
984
        }
 
985
    },
 
986
 
 
987
    /**
 
988
    Called from the `use` method queue to ensure that only one set of loading
 
989
    logic is performed at a time.
 
990
 
 
991
    @method _use
 
992
    @param {String} args* One or more modules to attach.
 
993
    @param {Function} [callback] Function to call once all required modules have
 
994
        been attached.
 
995
    @private
 
996
    **/
 
997
    _use: function(args, callback) {
 
998
 
 
999
        if (!this.Array) {
 
1000
            this._attach(['yui-base']);
 
1001
        }
 
1002
 
 
1003
        var len, loader, handleBoot,
 
1004
            Y = this,
 
1005
            G_ENV = YUI.Env,
 
1006
            mods = G_ENV.mods,
 
1007
            Env = Y.Env,
 
1008
            used = Env._used,
 
1009
            aliases = G_ENV.aliases,
 
1010
            queue = G_ENV._loaderQueue,
 
1011
            firstArg = args[0],
 
1012
            YArray = Y.Array,
 
1013
            config = Y.config,
 
1014
            boot = config.bootstrap,
 
1015
            missing = [],
 
1016
            i,
 
1017
            r = [],
 
1018
            ret = true,
 
1019
            fetchCSS = config.fetchCSS,
 
1020
            process = function(names, skip) {
 
1021
 
 
1022
                var i = 0, a = [], name, len, m, req, use;
 
1023
 
 
1024
                if (!names.length) {
 
1025
                    return;
 
1026
                }
 
1027
 
 
1028
                if (aliases) {
 
1029
                    len = names.length;
 
1030
                    for (i = 0; i < len; i++) {
 
1031
                        if (aliases[names[i]] && !mods[names[i]]) {
 
1032
                            a = [].concat(a, aliases[names[i]]);
 
1033
                        } else {
 
1034
                            a.push(names[i]);
 
1035
                        }
 
1036
                    }
 
1037
                    names = a;
 
1038
                }
 
1039
 
 
1040
                len = names.length;
 
1041
 
 
1042
                for (i = 0; i < len; i++) {
 
1043
                    name = names[i];
 
1044
                    if (!skip) {
 
1045
                        r.push(name);
 
1046
                    }
 
1047
 
 
1048
                    // only attach a module once
 
1049
                    if (used[name]) {
 
1050
                        continue;
 
1051
                    }
 
1052
 
 
1053
                    m = mods[name];
 
1054
                    req = null;
 
1055
                    use = null;
 
1056
 
 
1057
                    if (m) {
 
1058
                        used[name] = true;
 
1059
                        req = m.details.requires;
 
1060
                        use = m.details.use;
 
1061
                    } else {
 
1062
                        // CSS files don't register themselves, see if it has
 
1063
                        // been loaded
 
1064
                        if (!G_ENV._loaded[VERSION][name]) {
 
1065
                            missing.push(name);
 
1066
                        } else {
 
1067
                            used[name] = true; // probably css
 
1068
                        }
 
1069
                    }
 
1070
 
 
1071
                    // make sure requirements are attached
 
1072
                    if (req && req.length) {
 
1073
                        process(req);
 
1074
                    }
 
1075
 
 
1076
                    // make sure we grab the submodule dependencies too
 
1077
                    if (use && use.length) {
 
1078
                        process(use, 1);
 
1079
                    }
 
1080
                }
 
1081
 
 
1082
            },
 
1083
 
 
1084
            handleLoader = function(fromLoader) {
 
1085
                var response = fromLoader || {
 
1086
                        success: true,
 
1087
                        msg: 'not dynamic'
 
1088
                    },
 
1089
                    redo, origMissing,
 
1090
                    ret = true,
 
1091
                    data = response.data;
 
1092
 
 
1093
                Y._loading = false;
 
1094
 
 
1095
                if (data) {
 
1096
                    origMissing = missing;
 
1097
                    missing = [];
 
1098
                    r = [];
 
1099
                    process(data);
 
1100
                    redo = missing.length;
 
1101
                    if (redo) {
 
1102
                        if ([].concat(missing).sort().join() ==
 
1103
                                origMissing.sort().join()) {
 
1104
                            redo = false;
 
1105
                        }
 
1106
                    }
 
1107
                }
 
1108
 
 
1109
                if (redo && data) {
 
1110
                    Y._loading = true;
 
1111
                    Y._use(missing, function() {
 
1112
                        if (Y._attach(data)) {
 
1113
                            Y._notify(callback, response, data);
 
1114
                        }
 
1115
                    });
 
1116
                } else {
 
1117
                    if (data) {
 
1118
                        ret = Y._attach(data);
 
1119
                    }
 
1120
                    if (ret) {
 
1121
                        Y._notify(callback, response, args);
 
1122
                    }
 
1123
                }
 
1124
 
 
1125
                if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
 
1126
                    Y._use.apply(Y, Y._useQueue.next());
 
1127
                }
 
1128
 
 
1129
            };
 
1130
 
 
1131
 
 
1132
        // YUI().use('*'); // bind everything available
 
1133
        if (firstArg === '*') {
 
1134
            args = [];
 
1135
            for (i in mods) {
 
1136
                if (mods.hasOwnProperty(i)) {
 
1137
                    args.push(i);
 
1138
                }
 
1139
            }
 
1140
            ret = Y._attach(args);
 
1141
            if (ret) {
 
1142
                handleLoader();
 
1143
            }
 
1144
            return Y;
 
1145
        }
 
1146
 
 
1147
        if ((mods.loader || mods['loader-base']) && !Y.Loader) {
 
1148
            Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
 
1149
        }
 
1150
 
 
1151
 
 
1152
        // use loader to expand dependencies and sort the
 
1153
        // requirements if it is available.
 
1154
        if (boot && Y.Loader && args.length) {
 
1155
            loader = getLoader(Y);
 
1156
            loader.require(args);
 
1157
            loader.ignoreRegistered = true;
 
1158
            loader._boot = true;
 
1159
            loader.calculate(null, (fetchCSS) ? null : 'js');
 
1160
            args = loader.sorted;
 
1161
            loader._boot = false;
 
1162
        }
 
1163
 
 
1164
        process(args);
 
1165
 
 
1166
        len = missing.length;
 
1167
 
 
1168
 
 
1169
        if (len) {
 
1170
            missing = YArray.dedupe(missing);
 
1171
            len = missing.length;
 
1172
        }
 
1173
 
 
1174
 
 
1175
        // dynamic load
 
1176
        if (boot && len && Y.Loader) {
 
1177
            Y._loading = true;
 
1178
            loader = getLoader(Y);
 
1179
            loader.onEnd = handleLoader;
 
1180
            loader.context = Y;
 
1181
            loader.data = args;
 
1182
            loader.ignoreRegistered = false;
 
1183
            loader.require(missing);
 
1184
            loader.insert(null, (fetchCSS) ? null : 'js');
 
1185
 
 
1186
        } else if (boot && len && Y.Get && !Env.bootstrapped) {
 
1187
 
 
1188
            Y._loading = true;
 
1189
 
 
1190
            handleBoot = function() {
 
1191
                Y._loading = false;
 
1192
                queue.running = false;
 
1193
                Env.bootstrapped = true;
 
1194
                G_ENV._bootstrapping = false;
 
1195
                if (Y._attach(['loader'])) {
 
1196
                    Y._use(args, callback);
 
1197
                }
 
1198
            };
 
1199
 
 
1200
            if (G_ENV._bootstrapping) {
 
1201
                queue.add(handleBoot);
 
1202
            } else {
 
1203
                G_ENV._bootstrapping = true;
 
1204
                Y.Get.script(config.base + config.loaderPath, {
 
1205
                    onEnd: handleBoot
 
1206
                });
 
1207
            }
 
1208
 
 
1209
        } else {
 
1210
            ret = Y._attach(args);
 
1211
            if (ret) {
 
1212
                handleLoader();
 
1213
            }
 
1214
        }
 
1215
 
 
1216
        return Y;
 
1217
    },
 
1218
 
 
1219
 
 
1220
    /**
 
1221
    Utility method for safely creating namespaces if they don't already exist.
 
1222
    May be called statically on the YUI global object or as a method on a YUI
 
1223
    instance.
 
1224
 
 
1225
    When called statically, a namespace will be created on the YUI global
 
1226
    object:
 
1227
 
 
1228
        // Create `YUI.your.namespace.here` as nested objects, preserving any
 
1229
        // objects that already exist instead of overwriting them.
 
1230
        YUI.namespace('your.namespace.here');
 
1231
 
 
1232
    When called as a method on a YUI instance, a namespace will be created on
 
1233
    that instance:
 
1234
 
 
1235
        // Creates `Y.property.package`.
 
1236
        Y.namespace('property.package');
 
1237
 
 
1238
    Dots in the input string cause `namespace` to create nested objects for each
 
1239
    token. If any part of the requested namespace already exists, the current
 
1240
    object will be left in place and will not be overwritten. This allows
 
1241
    multiple calls to `namespace` to preserve existing namespaced properties.
 
1242
 
 
1243
    If the first token in the namespace string is "YAHOO", that token is
 
1244
    discarded. This is legacy behavior for backwards compatibility with YUI 2.
 
1245
 
 
1246
    Be careful with namespace tokens. Reserved words may work in some browsers
 
1247
    and not others. For instance, the following will fail in some browsers
 
1248
    because the supported version of JavaScript reserves the word "long":
 
1249
 
 
1250
        Y.namespace('really.long.nested.namespace');
 
1251
 
 
1252
    Note: If you pass multiple arguments to create multiple namespaces, only the
 
1253
    last one created is returned from this function.
 
1254
 
 
1255
    @method namespace
 
1256
    @param {String} namespace* One or more namespaces to create.
 
1257
    @return {Object} Reference to the last namespace object created.
 
1258
    **/
 
1259
    namespace: function() {
 
1260
        var a = arguments, o, i = 0, j, d, arg;
 
1261
 
 
1262
        for (; i < a.length; i++) {
 
1263
            o = this; //Reset base object per argument or it will get reused from the last
 
1264
            arg = a[i];
 
1265
            if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
 
1266
                d = arg.split(PERIOD);
 
1267
                for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
 
1268
                    o[d[j]] = o[d[j]] || {};
 
1269
                    o = o[d[j]];
 
1270
                }
 
1271
            } else {
 
1272
                o[arg] = o[arg] || {};
 
1273
                o = o[arg]; //Reset base object to the new object so it's returned
 
1274
            }
 
1275
        }
 
1276
        return o;
 
1277
    },
 
1278
 
 
1279
    // this is replaced if the log module is included
 
1280
    log: NOOP,
 
1281
    message: NOOP,
 
1282
    // this is replaced if the dump module is included
 
1283
    dump: function (o) { return ''+o; },
 
1284
 
 
1285
    /**
 
1286
    Reports an error.
 
1287
 
 
1288
    The reporting mechanism is controlled by the `throwFail` configuration
 
1289
    attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
 
1290
    truthy, a JS exception is thrown.
 
1291
 
 
1292
    If an `errorFn` is specified in the config it must return `true` to indicate
 
1293
    that the exception was handled and keep it from being thrown.
 
1294
 
 
1295
    @method error
 
1296
    @param {String} msg Error message.
 
1297
    @param {Error|String} [e] JavaScript error object or an error string.
 
1298
    @param {String} [src] Source of the error (such as the name of the module in
 
1299
        which the error occurred).
 
1300
    @chainable
 
1301
    **/
 
1302
    error: function(msg, e, src) {
 
1303
        //TODO Add check for window.onerror here
 
1304
 
 
1305
        var Y = this, ret;
 
1306
 
 
1307
        if (Y.config.errorFn) {
 
1308
            ret = Y.config.errorFn.apply(Y, arguments);
 
1309
        }
 
1310
 
 
1311
        if (!ret) {
 
1312
            throw (e || new Error(msg));
 
1313
        } else {
 
1314
            Y.message(msg, 'error', ''+src); // don't scrub this one
 
1315
        }
 
1316
 
 
1317
        return Y;
 
1318
    },
 
1319
 
 
1320
    /**
 
1321
    Generates an id string that is unique among all YUI instances in this
 
1322
    execution context.
 
1323
 
 
1324
    @method guid
 
1325
    @param {String} [pre] Prefix.
 
1326
    @return {String} Unique id.
 
1327
    **/
 
1328
    guid: function(pre) {
 
1329
        var id = this.Env._guidp + '_' + (++this.Env._uidx);
 
1330
        return (pre) ? (pre + id) : id;
 
1331
    },
 
1332
 
 
1333
    /**
 
1334
    Returns a unique id associated with the given object and (if *readOnly* is
 
1335
    falsy) stamps the object with that id so it can be identified in the future.
 
1336
 
 
1337
    Stamping an object involves adding a `_yuid` property to it that contains
 
1338
    the object's id. One exception to this is that in Internet Explorer, DOM
 
1339
    nodes have a `uniqueID` property that contains a browser-generated unique
 
1340
    id, which will be used instead of a YUI-generated id when available.
 
1341
 
 
1342
    @method stamp
 
1343
    @param {Object} o Object to stamp.
 
1344
    @param {Boolean} readOnly If truthy and the given object has not already
 
1345
        been stamped, the object will not be modified and `null` will be
 
1346
        returned.
 
1347
    @return {String} Object's unique id, or `null` if *readOnly* was truthy and
 
1348
        the given object was not already stamped.
 
1349
    **/
 
1350
    stamp: function(o, readOnly) {
 
1351
        var uid;
 
1352
        if (!o) {
 
1353
            return o;
 
1354
        }
 
1355
 
 
1356
        // IE generates its own unique ID for dom nodes
 
1357
        // The uniqueID property of a document node returns a new ID
 
1358
        if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
 
1359
            uid = o.uniqueID;
 
1360
        } else {
 
1361
            uid = (typeof o === 'string') ? o : o._yuid;
 
1362
        }
 
1363
 
 
1364
        if (!uid) {
 
1365
            uid = this.guid();
 
1366
            if (!readOnly) {
 
1367
                try {
 
1368
                    o._yuid = uid;
 
1369
                } catch (e) {
 
1370
                    uid = null;
 
1371
                }
 
1372
            }
 
1373
        }
 
1374
        return uid;
 
1375
    },
 
1376
 
 
1377
    /**
 
1378
    Destroys this YUI instance.
 
1379
 
 
1380
    @method destroy
 
1381
    @since 3.3.0
 
1382
    **/
 
1383
    destroy: function() {
 
1384
        var Y = this;
 
1385
        if (Y.Event) {
 
1386
            Y.Event._unload();
 
1387
        }
 
1388
        delete instances[Y.id];
 
1389
        delete Y.Env;
 
1390
        delete Y.config;
 
1391
    }
 
1392
 
 
1393
    /**
 
1394
    Safe `instanceof` wrapper that works around a memory leak in IE when the
 
1395
    object being tested is `window` or `document`.
 
1396
 
 
1397
    Unless you are testing objects that may be `window` or `document`, you
 
1398
    should use the native `instanceof` operator instead of this method.
 
1399
 
 
1400
    @method instanceOf
 
1401
    @param {Object} o Object to check.
 
1402
    @param {Object} type Class to check against.
 
1403
    @since 3.3.0
 
1404
    **/
 
1405
};
 
1406
 
 
1407
    YUI.prototype = proto;
 
1408
 
 
1409
    // inheritance utilities are not available yet
 
1410
    for (prop in proto) {
 
1411
        if (proto.hasOwnProperty(prop)) {
 
1412
            YUI[prop] = proto[prop];
 
1413
        }
 
1414
    }
 
1415
 
 
1416
    /**
 
1417
    Applies a configuration to all YUI instances in this execution context.
 
1418
 
 
1419
    The main use case for this method is in "mashups" where several third-party
 
1420
    scripts need to write to a global YUI config, but cannot share a single
 
1421
    centrally-managed config object. This way they can all call
 
1422
    `YUI.applyConfig({})` instead of overwriting the single global config.
 
1423
 
 
1424
    @example
 
1425
 
 
1426
        YUI.applyConfig({
 
1427
            modules: {
 
1428
                davglass: {
 
1429
                    fullpath: './davglass.js'
 
1430
                }
 
1431
            }
 
1432
        });
 
1433
 
 
1434
        YUI.applyConfig({
 
1435
            modules: {
 
1436
                foo: {
 
1437
                    fullpath: './foo.js'
 
1438
                }
 
1439
            }
 
1440
        });
 
1441
 
 
1442
        YUI().use('davglass', function (Y) {
 
1443
            // Module davglass will be available here.
 
1444
        });
 
1445
 
 
1446
    @method applyConfig
 
1447
    @param {Object} o Configuration object to apply.
 
1448
    @static
 
1449
    @since 3.5.0
 
1450
    **/
 
1451
    YUI.applyConfig = function(o) {
 
1452
        if (!o) {
 
1453
            return;
 
1454
        }
 
1455
        //If there is a GlobalConfig, apply it first to set the defaults
 
1456
        if (YUI.GlobalConfig) {
 
1457
            this.prototype.applyConfig.call(this, YUI.GlobalConfig);
 
1458
        }
 
1459
        //Apply this config to it
 
1460
        this.prototype.applyConfig.call(this, o);
 
1461
        //Reset GlobalConfig to the combined config
 
1462
        YUI.GlobalConfig = this.config;
 
1463
    };
 
1464
 
 
1465
    // set up the environment
 
1466
    YUI._init();
 
1467
 
 
1468
    if (hasWin) {
 
1469
        // add a window load event at load time so we can capture
 
1470
        // the case where it fires before dynamic loading is
 
1471
        // complete.
 
1472
        add(window, 'load', handleLoad);
 
1473
    } else {
 
1474
        handleLoad();
 
1475
    }
 
1476
 
 
1477
    YUI.Env.add = add;
 
1478
    YUI.Env.remove = remove;
 
1479
 
 
1480
    /*global exports*/
 
1481
    // Support the CommonJS method for exporting our single global
 
1482
    if (typeof exports == 'object') {
 
1483
        exports.YUI = YUI;
 
1484
        /**
 
1485
        * Set a method to be called when `Get.script` is called in Node.js
 
1486
        * `Get` will open the file, then pass it's content and it's path
 
1487
        * to this method before attaching it. Commonly used for code coverage
 
1488
        * instrumentation. <strong>Calling this multiple times will only
 
1489
        * attach the last hook method</strong>. This method is only
 
1490
        * available in Node.js.
 
1491
        * @method setLoadHook
 
1492
        * @static
 
1493
        * @param {Function} fn The function to set
 
1494
        * @param {String} fn.data The content of the file
 
1495
        * @param {String} fn.path The file path of the file
 
1496
        */
 
1497
        YUI.setLoadHook = function(fn) {
 
1498
            YUI._getLoadHook = fn;
 
1499
        };
 
1500
        /**
 
1501
        * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
 
1502
        * @method _getLoadHook
 
1503
        * @private
 
1504
        * @param {String} data The content of the file
 
1505
        * @param {String} path The file path of the file
 
1506
        */
 
1507
        YUI._getLoadHook = null;
 
1508
    }
 
1509
 
 
1510
}());
 
1511
 
 
1512
 
 
1513
/**
 
1514
Config object that contains all of the configuration options for
 
1515
this `YUI` instance.
 
1516
 
 
1517
This object is supplied by the implementer when instantiating YUI. Some
 
1518
properties have default values if they are not supplied by the implementer.
 
1519
 
 
1520
This object should not be updated directly because some values are cached. Use
 
1521
`applyConfig()` to update the config object on a YUI instance that has already
 
1522
been configured.
 
1523
 
 
1524
@class config
 
1525
@static
 
1526
**/
 
1527
 
 
1528
/**
 
1529
If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
 
1530
if they're needed to load additional dependencies and aren't already available.
 
1531
 
 
1532
Setting this to `false` will prevent YUI from automatically loading the Loader
 
1533
and module metadata, so you will need to manually ensure that they're available
 
1534
or handle dependency resolution yourself.
 
1535
 
 
1536
@property {Boolean} bootstrap
 
1537
@default true
 
1538
**/
 
1539
 
 
1540
/**
 
1541
 
 
1542
@property {Object} aliases
 
1543
**/
 
1544
 
 
1545
/**
 
1546
A hash of module group definitions.
 
1547
 
 
1548
For each group you can specify a list of modules and the base path and
 
1549
combo spec to use when dynamically loading the modules.
 
1550
 
 
1551
@example
 
1552
 
 
1553
    groups: {
 
1554
        yui2: {
 
1555
            // specify whether or not this group has a combo service
 
1556
            combine: true,
 
1557
 
 
1558
            // The comboSeperator to use with this group's combo handler
 
1559
            comboSep: ';',
 
1560
 
 
1561
            // The maxURLLength for this server
 
1562
            maxURLLength: 500,
 
1563
 
 
1564
            // the base path for non-combo paths
 
1565
            base: 'http://yui.yahooapis.com/2.8.0r4/build/',
 
1566
 
 
1567
            // the path to the combo service
 
1568
            comboBase: 'http://yui.yahooapis.com/combo?',
 
1569
 
 
1570
            // a fragment to prepend to the path attribute when
 
1571
            // when building combo urls
 
1572
            root: '2.8.0r4/build/',
 
1573
 
 
1574
            // the module definitions
 
1575
            modules:  {
 
1576
                yui2_yde: {
 
1577
                    path: "yahoo-dom-event/yahoo-dom-event.js"
 
1578
                },
 
1579
                yui2_anim: {
 
1580
                    path: "animation/animation.js",
 
1581
                    requires: ['yui2_yde']
 
1582
                }
 
1583
            }
 
1584
        }
 
1585
    }
 
1586
 
 
1587
@property {Object} groups
 
1588
**/
 
1589
 
 
1590
/**
 
1591
Path to the Loader JS file, relative to the `base` path.
 
1592
 
 
1593
This is used to dynamically bootstrap the Loader when it's needed and isn't yet
 
1594
available.
 
1595
 
 
1596
@property {String} loaderPath
 
1597
@default "loader/loader-min.js"
 
1598
**/
 
1599
 
 
1600
/**
 
1601
If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
 
1602
`false` to prevent YUI from loading any CSS, or set it to the string `"force"`
 
1603
to force CSS dependencies to be loaded even if their associated JS modules are
 
1604
already loaded.
 
1605
 
 
1606
@property {Boolean|String} fetchCSS
 
1607
@default true
 
1608
**/
 
1609
 
 
1610
/**
 
1611
Default gallery version used to build gallery module urls.
 
1612
 
 
1613
@property {String} gallery
 
1614
@since 3.1.0
 
1615
**/
 
1616
 
 
1617
/**
 
1618
Default YUI 2 version used to build YUI 2 module urls.
 
1619
 
 
1620
This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
 
1621
`2in3` config for pulling different revisions of the wrapped YUI 2 modules.
 
1622
 
 
1623
@property {String} yui2
 
1624
@default "2.9.0"
 
1625
@since 3.1.0
 
1626
**/
 
1627
 
 
1628
/**
 
1629
Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
 
1630
 
 
1631
@property {String} 2in3
 
1632
@default "4"
 
1633
@since 3.1.0
 
1634
**/
 
1635
 
 
1636
/**
 
1637
Alternate console log function that should be used in environments without a
 
1638
supported native console. This function is executed with the YUI instance as its
 
1639
`this` object.
 
1640
 
 
1641
@property {Function} logFn
 
1642
@since 3.1.0
 
1643
**/
 
1644
 
 
1645
/**
 
1646
The minimum log level to log messages for. Log levels are defined
 
1647
incrementally. Messages greater than or equal to the level specified will
 
1648
be shown. All others will be discarded. The order of log levels in
 
1649
increasing priority is:
 
1650
 
 
1651
    debug
 
1652
    info
 
1653
    warn
 
1654
    error
 
1655
 
 
1656
@property {String} logLevel
 
1657
@default 'debug'
 
1658
@since 3.10.0
 
1659
**/
 
1660
 
 
1661
/**
 
1662
Callback to execute when `Y.error()` is called. It receives the error message
 
1663
and a JavaScript error object if one was provided.
 
1664
 
 
1665
This function is executed with the YUI instance as its `this` object.
 
1666
 
 
1667
Returning `true` from this function will prevent an exception from being thrown.
 
1668
 
 
1669
@property {Function} errorFn
 
1670
@param {String} errorFn.msg Error message
 
1671
@param {Object} [errorFn.err] Error object (if one was provided).
 
1672
@since 3.2.0
 
1673
**/
 
1674
 
 
1675
/**
 
1676
A callback to execute when Loader fails to load one or more resources.
 
1677
 
 
1678
This could be because of a script load failure. It could also be because a
 
1679
module fails to register itself when the `requireRegistration` config is `true`.
 
1680
 
 
1681
If this function is defined, the `use()` callback will only be called when the
 
1682
loader succeeds. Otherwise, `use()` will always executes unless there was a
 
1683
JavaScript error when attaching a module.
 
1684
 
 
1685
@property {Function} loadErrorFn
 
1686
@since 3.3.0
 
1687
**/
 
1688
 
 
1689
/**
 
1690
If `true`, Loader will expect all loaded scripts to be first-class YUI modules
 
1691
that register themselves with the YUI global, and will trigger a failure if a
 
1692
loaded script does not register a YUI module.
 
1693
 
 
1694
@property {Boolean} requireRegistration
 
1695
@default false
 
1696
@since 3.3.0
 
1697
**/
 
1698
 
 
1699
/**
 
1700
Cache serviced use() requests.
 
1701
 
 
1702
@property {Boolean} cacheUse
 
1703
@default true
 
1704
@since 3.3.0
 
1705
@deprecated No longer used.
 
1706
**/
 
1707
 
 
1708
/**
 
1709
Whether or not YUI should use native ES5 functionality when available for
 
1710
features like `Y.Array.each()`, `Y.Object()`, etc.
 
1711
 
 
1712
When `false`, YUI will always use its own fallback implementations instead of
 
1713
relying on ES5 functionality, even when ES5 functionality is available.
 
1714
 
 
1715
@property {Boolean} useNativeES5
 
1716
@default true
 
1717
@since 3.5.0
 
1718
**/
 
1719
 
 
1720
/**
 
1721
 * Leverage native JSON stringify if the browser has a native
 
1722
 * implementation.  In general, this is a good idea.  See the Known Issues
 
1723
 * section in the JSON user guide for caveats.  The default value is true
 
1724
 * for browsers with native JSON support.
 
1725
 *
 
1726
 * @property useNativeJSONStringify
 
1727
 * @type Boolean
 
1728
 * @default true
 
1729
 * @since 3.8.0
 
1730
 */
 
1731
 
 
1732
 /**
 
1733
 * Leverage native JSON parse if the browser has a native implementation.
 
1734
 * In general, this is a good idea.  See the Known Issues section in the
 
1735
 * JSON user guide for caveats.  The default value is true for browsers with
 
1736
 * native JSON support.
 
1737
 *
 
1738
 * @property useNativeJSONParse
 
1739
 * @type Boolean
 
1740
 * @default true
 
1741
 * @since 3.8.0
 
1742
 */
 
1743
 
 
1744
/**
 
1745
Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
 
1746
 
 
1747
@property {Object|String} delayUntil
 
1748
@since 3.6.0
 
1749
@example
 
1750
 
 
1751
You can use `load` or `domready` strings by default:
 
1752
 
 
1753
    YUI({
 
1754
        delayUntil: 'domready'
 
1755
    }, function (Y) {
 
1756
        // This will not execute until 'domeready' occurs.
 
1757
    });
 
1758
 
 
1759
Or you can delay until a node is available (with `available` or `contentready`):
 
1760
 
 
1761
    YUI({
 
1762
        delayUntil: {
 
1763
            event: 'available',
 
1764
            args : '#foo'
 
1765
        }
 
1766
    }, function (Y) {
 
1767
        // This will not execute until a node matching the selector "#foo" is
 
1768
        // available in the DOM.
 
1769
    });
 
1770
 
 
1771
**/
 
1772
YUI.add('yui-base', function (Y, NAME) {
 
1773
 
 
1774
/*
 
1775
 * YUI stub
 
1776
 * @module yui
 
1777
 * @submodule yui-base
 
1778
 */
 
1779
/**
 
1780
 * The YUI module contains the components required for building the YUI
 
1781
 * seed file.  This includes the script loading mechanism, a simple queue,
 
1782
 * and the core utilities for the library.
 
1783
 * @module yui
 
1784
 * @submodule yui-base
 
1785
 */
 
1786
 
 
1787
/**
 
1788
 * Provides core language utilites and extensions used throughout YUI.
 
1789
 *
 
1790
 * @class Lang
 
1791
 * @static
 
1792
 */
 
1793
 
 
1794
var L = Y.Lang || (Y.Lang = {}),
 
1795
 
 
1796
STRING_PROTO = String.prototype,
 
1797
TOSTRING     = Object.prototype.toString,
 
1798
 
 
1799
TYPES = {
 
1800
    'undefined'        : 'undefined',
 
1801
    'number'           : 'number',
 
1802
    'boolean'          : 'boolean',
 
1803
    'string'           : 'string',
 
1804
    '[object Function]': 'function',
 
1805
    '[object RegExp]'  : 'regexp',
 
1806
    '[object Array]'   : 'array',
 
1807
    '[object Date]'    : 'date',
 
1808
    '[object Error]'   : 'error'
 
1809
},
 
1810
 
 
1811
SUBREGEX        = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
 
1812
TRIMREGEX       = /^\s+|\s+$/g,
 
1813
NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i;
 
1814
 
 
1815
// -- Protected Methods --------------------------------------------------------
 
1816
 
 
1817
/**
 
1818
Returns `true` if the given function appears to be implemented in native code,
 
1819
`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
 
1820
if the `useNativeES5` YUI config option is set to `false`.
 
1821
 
 
1822
This isn't guaranteed to be 100% accurate and won't work for anything other than
 
1823
functions, but it can be useful for determining whether a function like
 
1824
`Array.prototype.forEach` is native or a JS shim provided by another library.
 
1825
 
 
1826
There's a great article by @kangax discussing certain flaws with this technique:
 
1827
<http://perfectionkills.com/detecting-built-in-host-methods/>
 
1828
 
 
1829
While his points are valid, it's still possible to benefit from this function
 
1830
as long as it's used carefully and sparingly, and in such a way that false
 
1831
negatives have minimal consequences. It's used internally to avoid using
 
1832
potentially broken non-native ES5 shims that have been added to the page by
 
1833
other libraries.
 
1834
 
 
1835
@method _isNative
 
1836
@param {Function} fn Function to test.
 
1837
@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
 
1838
@static
 
1839
@protected
 
1840
@since 3.5.0
 
1841
**/
 
1842
L._isNative = function (fn) {
 
1843
    return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
 
1844
};
 
1845
 
 
1846
// -- Public Methods -----------------------------------------------------------
 
1847
 
 
1848
/**
 
1849
 * Determines whether or not the provided item is an array.
 
1850
 *
 
1851
 * Returns `false` for array-like collections such as the function `arguments`
 
1852
 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
 
1853
 * test for an array-like collection.
 
1854
 *
 
1855
 * @method isArray
 
1856
 * @param o The object to test.
 
1857
 * @return {boolean} true if o is an array.
 
1858
 * @static
 
1859
 */
 
1860
L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
 
1861
    return L.type(o) === 'array';
 
1862
};
 
1863
 
 
1864
/**
 
1865
 * Determines whether or not the provided item is a boolean.
 
1866
 * @method isBoolean
 
1867
 * @static
 
1868
 * @param o The object to test.
 
1869
 * @return {boolean} true if o is a boolean.
 
1870
 */
 
1871
L.isBoolean = function(o) {
 
1872
    return typeof o === 'boolean';
 
1873
};
 
1874
 
 
1875
/**
 
1876
 * Determines whether or not the supplied item is a date instance.
 
1877
 * @method isDate
 
1878
 * @static
 
1879
 * @param o The object to test.
 
1880
 * @return {boolean} true if o is a date.
 
1881
 */
 
1882
L.isDate = function(o) {
 
1883
    return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
 
1884
};
 
1885
 
 
1886
/**
 
1887
 * <p>
 
1888
 * Determines whether or not the provided item is a function.
 
1889
 * Note: Internet Explorer thinks certain functions are objects:
 
1890
 * </p>
 
1891
 *
 
1892
 * <pre>
 
1893
 * var obj = document.createElement("object");
 
1894
 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
 
1895
 * &nbsp;
 
1896
 * var input = document.createElement("input"); // append to body
 
1897
 * Y.Lang.isFunction(input.focus) // reports false in IE
 
1898
 * </pre>
 
1899
 *
 
1900
 * <p>
 
1901
 * You will have to implement additional tests if these functions
 
1902
 * matter to you.
 
1903
 * </p>
 
1904
 *
 
1905
 * @method isFunction
 
1906
 * @static
 
1907
 * @param o The object to test.
 
1908
 * @return {boolean} true if o is a function.
 
1909
 */
 
1910
L.isFunction = function(o) {
 
1911
    return L.type(o) === 'function';
 
1912
};
 
1913
 
 
1914
/**
 
1915
 * Determines whether or not the provided item is null.
 
1916
 * @method isNull
 
1917
 * @static
 
1918
 * @param o The object to test.
 
1919
 * @return {boolean} true if o is null.
 
1920
 */
 
1921
L.isNull = function(o) {
 
1922
    return o === null;
 
1923
};
 
1924
 
 
1925
/**
 
1926
 * Determines whether or not the provided item is a legal number.
 
1927
 * @method isNumber
 
1928
 * @static
 
1929
 * @param o The object to test.
 
1930
 * @return {boolean} true if o is a number.
 
1931
 */
 
1932
L.isNumber = function(o) {
 
1933
    return typeof o === 'number' && isFinite(o);
 
1934
};
 
1935
 
 
1936
/**
 
1937
 * Determines whether or not the provided item is of type object
 
1938
 * or function. Note that arrays are also objects, so
 
1939
 * <code>Y.Lang.isObject([]) === true</code>.
 
1940
 * @method isObject
 
1941
 * @static
 
1942
 * @param o The object to test.
 
1943
 * @param failfn {boolean} fail if the input is a function.
 
1944
 * @return {boolean} true if o is an object.
 
1945
 * @see isPlainObject
 
1946
 */
 
1947
L.isObject = function(o, failfn) {
 
1948
    var t = typeof o;
 
1949
    return (o && (t === 'object' ||
 
1950
        (!failfn && (t === 'function' || L.isFunction(o))))) || false;
 
1951
};
 
1952
 
 
1953
/**
 
1954
 * Determines whether or not the provided item is a string.
 
1955
 * @method isString
 
1956
 * @static
 
1957
 * @param o The object to test.
 
1958
 * @return {boolean} true if o is a string.
 
1959
 */
 
1960
L.isString = function(o) {
 
1961
    return typeof o === 'string';
 
1962
};
 
1963
 
 
1964
/**
 
1965
 * Determines whether or not the provided item is undefined.
 
1966
 * @method isUndefined
 
1967
 * @static
 
1968
 * @param o The object to test.
 
1969
 * @return {boolean} true if o is undefined.
 
1970
 */
 
1971
L.isUndefined = function(o) {
 
1972
    return typeof o === 'undefined';
 
1973
};
 
1974
 
 
1975
/**
 
1976
 * A convenience method for detecting a legitimate non-null value.
 
1977
 * Returns false for null/undefined/NaN, true for other values,
 
1978
 * including 0/false/''
 
1979
 * @method isValue
 
1980
 * @static
 
1981
 * @param o The item to test.
 
1982
 * @return {boolean} true if it is not null/undefined/NaN || false.
 
1983
 */
 
1984
L.isValue = function(o) {
 
1985
    var t = L.type(o);
 
1986
 
 
1987
    switch (t) {
 
1988
        case 'number':
 
1989
            return isFinite(o);
 
1990
 
 
1991
        case 'null': // fallthru
 
1992
        case 'undefined':
 
1993
            return false;
 
1994
 
 
1995
        default:
 
1996
            return !!t;
 
1997
    }
 
1998
};
 
1999
 
 
2000
/**
 
2001
 * Returns the current time in milliseconds.
 
2002
 *
 
2003
 * @method now
 
2004
 * @return {Number} Current time in milliseconds.
 
2005
 * @static
 
2006
 * @since 3.3.0
 
2007
 */
 
2008
L.now = Date.now || function () {
 
2009
    return new Date().getTime();
 
2010
};
 
2011
 
 
2012
/**
 
2013
 * Lightweight version of <code>Y.substitute</code>. Uses the same template
 
2014
 * structure as <code>Y.substitute</code>, but doesn't support recursion,
 
2015
 * auto-object coersion, or formats.
 
2016
 * @method sub
 
2017
 * @param {string} s String to be modified.
 
2018
 * @param {object} o Object containing replacement values.
 
2019
 * @return {string} the substitute result.
 
2020
 * @static
 
2021
 * @since 3.2.0
 
2022
 */
 
2023
L.sub = function(s, o) {
 
2024
    return s.replace ? s.replace(SUBREGEX, function (match, key) {
 
2025
        return L.isUndefined(o[key]) ? match : o[key];
 
2026
    }) : s;
 
2027
};
 
2028
 
 
2029
/**
 
2030
 * Returns a string without any leading or trailing whitespace.  If
 
2031
 * the input is not a string, the input will be returned untouched.
 
2032
 * @method trim
 
2033
 * @static
 
2034
 * @param s {string} the string to trim.
 
2035
 * @return {string} the trimmed string.
 
2036
 */
 
2037
L.trim = STRING_PROTO.trim ? function(s) {
 
2038
    return s && s.trim ? s.trim() : s;
 
2039
} : function (s) {
 
2040
    try {
 
2041
        return s.replace(TRIMREGEX, '');
 
2042
    } catch (e) {
 
2043
        return s;
 
2044
    }
 
2045
};
 
2046
 
 
2047
/**
 
2048
 * Returns a string without any leading whitespace.
 
2049
 * @method trimLeft
 
2050
 * @static
 
2051
 * @param s {string} the string to trim.
 
2052
 * @return {string} the trimmed string.
 
2053
 */
 
2054
L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
 
2055
    return s.trimLeft();
 
2056
} : function (s) {
 
2057
    return s.replace(/^\s+/, '');
 
2058
};
 
2059
 
 
2060
/**
 
2061
 * Returns a string without any trailing whitespace.
 
2062
 * @method trimRight
 
2063
 * @static
 
2064
 * @param s {string} the string to trim.
 
2065
 * @return {string} the trimmed string.
 
2066
 */
 
2067
L.trimRight = STRING_PROTO.trimRight ? function (s) {
 
2068
    return s.trimRight();
 
2069
} : function (s) {
 
2070
    return s.replace(/\s+$/, '');
 
2071
};
 
2072
 
 
2073
/**
 
2074
Returns one of the following strings, representing the type of the item passed
 
2075
in:
 
2076
 
 
2077
 * "array"
 
2078
 * "boolean"
 
2079
 * "date"
 
2080
 * "error"
 
2081
 * "function"
 
2082
 * "null"
 
2083
 * "number"
 
2084
 * "object"
 
2085
 * "regexp"
 
2086
 * "string"
 
2087
 * "undefined"
 
2088
 
 
2089
Known issues:
 
2090
 
 
2091
 * `typeof HTMLElementCollection` returns function in Safari, but
 
2092
    `Y.Lang.type()` reports "object", which could be a good thing --
 
2093
    but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
 
2094
 
 
2095
@method type
 
2096
@param o the item to test.
 
2097
@return {string} the detected type.
 
2098
@static
 
2099
**/
 
2100
L.type = function(o) {
 
2101
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
 
2102
};
 
2103
/**
 
2104
@module yui
 
2105
@submodule yui-base
 
2106
*/
 
2107
 
 
2108
var Lang   = Y.Lang,
 
2109
    Native = Array.prototype,
 
2110
 
 
2111
    hasOwn = Object.prototype.hasOwnProperty;
 
2112
 
 
2113
/**
 
2114
Provides utility methods for working with arrays. Additional array helpers can
 
2115
be found in the `collection` and `array-extras` modules.
 
2116
 
 
2117
`Y.Array(thing)` returns a native array created from _thing_. Depending on
 
2118
_thing_'s type, one of the following will happen:
 
2119
 
 
2120
  * Arrays are returned unmodified unless a non-zero _startIndex_ is
 
2121
    specified.
 
2122
  * Array-like collections (see `Array.test()`) are converted to arrays.
 
2123
  * For everything else, a new array is created with _thing_ as the sole
 
2124
    item.
 
2125
 
 
2126
Note: elements that are also collections, such as `<form>` and `<select>`
 
2127
elements, are not automatically converted to arrays. To force a conversion,
 
2128
pass `true` as the value of the _force_ parameter.
 
2129
 
 
2130
@class Array
 
2131
@constructor
 
2132
@param {Any} thing The thing to arrayify.
 
2133
@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
 
2134
  collection, a subset of items starting at the specified index will be
 
2135
  returned.
 
2136
@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
 
2137
  array-like collection no matter what.
 
2138
@return {Array} A native array created from _thing_, according to the rules
 
2139
  described above.
 
2140
**/
 
2141
function YArray(thing, startIndex, force) {
 
2142
    var len, result;
 
2143
 
 
2144
    /*jshint expr: true*/
 
2145
    startIndex || (startIndex = 0);
 
2146
 
 
2147
    if (force || YArray.test(thing)) {
 
2148
        // IE throws when trying to slice HTMLElement collections.
 
2149
        try {
 
2150
            return Native.slice.call(thing, startIndex);
 
2151
        } catch (ex) {
 
2152
            result = [];
 
2153
 
 
2154
            for (len = thing.length; startIndex < len; ++startIndex) {
 
2155
                result.push(thing[startIndex]);
 
2156
            }
 
2157
 
 
2158
            return result;
 
2159
        }
 
2160
    }
 
2161
 
 
2162
    return [thing];
 
2163
}
 
2164
 
 
2165
Y.Array = YArray;
 
2166
 
 
2167
/**
 
2168
Dedupes an array of strings, returning an array that's guaranteed to contain
 
2169
only one copy of a given string.
 
2170
 
 
2171
This method differs from `Array.unique()` in that it's optimized for use only
 
2172
with strings, whereas `unique` may be used with other types (but is slower).
 
2173
Using `dedupe()` with non-string values may result in unexpected behavior.
 
2174
 
 
2175
@method dedupe
 
2176
@param {String[]} array Array of strings to dedupe.
 
2177
@return {Array} Deduped copy of _array_.
 
2178
@static
 
2179
@since 3.4.0
 
2180
**/
 
2181
YArray.dedupe = function (array) {
 
2182
    var hash    = {},
 
2183
        results = [],
 
2184
        i, item, len;
 
2185
 
 
2186
    for (i = 0, len = array.length; i < len; ++i) {
 
2187
        item = array[i];
 
2188
 
 
2189
        if (!hasOwn.call(hash, item)) {
 
2190
            hash[item] = 1;
 
2191
            results.push(item);
 
2192
        }
 
2193
    }
 
2194
 
 
2195
    return results;
 
2196
};
 
2197
 
 
2198
/**
 
2199
Executes the supplied function on each item in the array. This method wraps
 
2200
the native ES5 `Array.forEach()` method if available.
 
2201
 
 
2202
@method each
 
2203
@param {Array} array Array to iterate.
 
2204
@param {Function} fn Function to execute on each item in the array. The function
 
2205
  will receive the following arguments:
 
2206
    @param {Any} fn.item Current array item.
 
2207
    @param {Number} fn.index Current array index.
 
2208
    @param {Array} fn.array Array being iterated.
 
2209
@param {Object} [thisObj] `this` object to use when calling _fn_.
 
2210
@return {YUI} The YUI instance.
 
2211
@static
 
2212
**/
 
2213
YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
 
2214
    Native.forEach.call(array || [], fn, thisObj || Y);
 
2215
    return Y;
 
2216
} : function (array, fn, thisObj) {
 
2217
    for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
 
2218
        if (i in array) {
 
2219
            fn.call(thisObj || Y, array[i], i, array);
 
2220
        }
 
2221
    }
 
2222
 
 
2223
    return Y;
 
2224
};
 
2225
 
 
2226
/**
 
2227
Alias for `each()`.
 
2228
 
 
2229
@method forEach
 
2230
@static
 
2231
**/
 
2232
 
 
2233
/**
 
2234
Returns an object using the first array as keys and the second as values. If
 
2235
the second array is not provided, or if it doesn't contain the same number of
 
2236
values as the first array, then `true` will be used in place of the missing
 
2237
values.
 
2238
 
 
2239
@example
 
2240
 
 
2241
    Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
 
2242
    // => {a: 'foo', b: 'bar', c: true}
 
2243
 
 
2244
@method hash
 
2245
@param {String[]} keys Array of strings to use as keys.
 
2246
@param {Array} [values] Array to use as values.
 
2247
@return {Object} Hash using the first array as keys and the second as values.
 
2248
@static
 
2249
**/
 
2250
YArray.hash = function (keys, values) {
 
2251
    var hash = {},
 
2252
        vlen = (values && values.length) || 0,
 
2253
        i, len;
 
2254
 
 
2255
    for (i = 0, len = keys.length; i < len; ++i) {
 
2256
        if (i in keys) {
 
2257
            hash[keys[i]] = vlen > i && i in values ? values[i] : true;
 
2258
        }
 
2259
    }
 
2260
 
 
2261
    return hash;
 
2262
};
 
2263
 
 
2264
/**
 
2265
Returns the index of the first item in the array that's equal (using a strict
 
2266
equality check) to the specified _value_, or `-1` if the value isn't found.
 
2267
 
 
2268
This method wraps the native ES5 `Array.indexOf()` method if available.
 
2269
 
 
2270
@method indexOf
 
2271
@param {Array} array Array to search.
 
2272
@param {Any} value Value to search for.
 
2273
@param {Number} [from=0] The index at which to begin the search.
 
2274
@return {Number} Index of the item strictly equal to _value_, or `-1` if not
 
2275
    found.
 
2276
@static
 
2277
**/
 
2278
YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
 
2279
    return Native.indexOf.call(array, value, from);
 
2280
} : function (array, value, from) {
 
2281
    // http://es5.github.com/#x15.4.4.14
 
2282
    var len = array.length;
 
2283
 
 
2284
    from = +from || 0;
 
2285
    from = (from > 0 || -1) * Math.floor(Math.abs(from));
 
2286
 
 
2287
    if (from < 0) {
 
2288
        from += len;
 
2289
 
 
2290
        if (from < 0) {
 
2291
            from = 0;
 
2292
        }
 
2293
    }
 
2294
 
 
2295
    for (; from < len; ++from) {
 
2296
        if (from in array && array[from] === value) {
 
2297
            return from;
 
2298
        }
 
2299
    }
 
2300
 
 
2301
    return -1;
 
2302
};
 
2303
 
 
2304
/**
 
2305
Numeric sort convenience function.
 
2306
 
 
2307
The native `Array.prototype.sort()` function converts values to strings and
 
2308
sorts them in lexicographic order, which is unsuitable for sorting numeric
 
2309
values. Provide `Array.numericSort` as a custom sort function when you want
 
2310
to sort values in numeric order.
 
2311
 
 
2312
@example
 
2313
 
 
2314
    [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
 
2315
    // => [4, 8, 15, 16, 23, 42]
 
2316
 
 
2317
@method numericSort
 
2318
@param {Number} a First value to compare.
 
2319
@param {Number} b Second value to compare.
 
2320
@return {Number} Difference between _a_ and _b_.
 
2321
@static
 
2322
**/
 
2323
YArray.numericSort = function (a, b) {
 
2324
    return a - b;
 
2325
};
 
2326
 
 
2327
/**
 
2328
Executes the supplied function on each item in the array. Returning a truthy
 
2329
value from the function will stop the processing of remaining items.
 
2330
 
 
2331
@method some
 
2332
@param {Array} array Array to iterate over.
 
2333
@param {Function} fn Function to execute on each item. The function will receive
 
2334
  the following arguments:
 
2335
    @param {Any} fn.value Current array item.
 
2336
    @param {Number} fn.index Current array index.
 
2337
    @param {Array} fn.array Array being iterated over.
 
2338
@param {Object} [thisObj] `this` object to use when calling _fn_.
 
2339
@return {Boolean} `true` if the function returns a truthy value on any of the
 
2340
  items in the array; `false` otherwise.
 
2341
@static
 
2342
**/
 
2343
YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
 
2344
    return Native.some.call(array, fn, thisObj);
 
2345
} : function (array, fn, thisObj) {
 
2346
    for (var i = 0, len = array.length; i < len; ++i) {
 
2347
        if (i in array && fn.call(thisObj, array[i], i, array)) {
 
2348
            return true;
 
2349
        }
 
2350
    }
 
2351
 
 
2352
    return false;
 
2353
};
 
2354
 
 
2355
/**
 
2356
Evaluates _obj_ to determine if it's an array, an array-like collection, or
 
2357
something else. This is useful when working with the function `arguments`
 
2358
collection and `HTMLElement` collections.
 
2359
 
 
2360
Note: This implementation doesn't consider elements that are also
 
2361
collections, such as `<form>` and `<select>`, to be array-like.
 
2362
 
 
2363
@method test
 
2364
@param {Object} obj Object to test.
 
2365
@return {Number} A number indicating the results of the test:
 
2366
 
 
2367
  * 0: Neither an array nor an array-like collection.
 
2368
  * 1: Real array.
 
2369
  * 2: Array-like collection.
 
2370
 
 
2371
@static
 
2372
**/
 
2373
YArray.test = function (obj) {
 
2374
    var result = 0;
 
2375
 
 
2376
    if (Lang.isArray(obj)) {
 
2377
        result = 1;
 
2378
    } else if (Lang.isObject(obj)) {
 
2379
        try {
 
2380
            // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
 
2381
            // or functions without apply/call (Safari
 
2382
            // HTMLElementCollection bug).
 
2383
            if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
 
2384
                result = 2;
 
2385
            }
 
2386
        } catch (ex) {}
 
2387
    }
 
2388
 
 
2389
    return result;
 
2390
};
 
2391
/**
 
2392
 * The YUI module contains the components required for building the YUI
 
2393
 * seed file.  This includes the script loading mechanism, a simple queue,
 
2394
 * and the core utilities for the library.
 
2395
 * @module yui
 
2396
 * @submodule yui-base
 
2397
 */
 
2398
 
 
2399
/**
 
2400
 * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
 
2401
 * removed using next().
 
2402
 *
 
2403
 * @class Queue
 
2404
 * @constructor
 
2405
 * @param {MIXED} item* 0..n items to seed the queue.
 
2406
 */
 
2407
function Queue() {
 
2408
    this._init();
 
2409
    this.add.apply(this, arguments);
 
2410
}
 
2411
 
 
2412
Queue.prototype = {
 
2413
    /**
 
2414
     * Initialize the queue
 
2415
     *
 
2416
     * @method _init
 
2417
     * @protected
 
2418
     */
 
2419
    _init: function() {
 
2420
        /**
 
2421
         * The collection of enqueued items
 
2422
         *
 
2423
         * @property _q
 
2424
         * @type Array
 
2425
         * @protected
 
2426
         */
 
2427
        this._q = [];
 
2428
    },
 
2429
 
 
2430
    /**
 
2431
     * Get the next item in the queue. FIFO support
 
2432
     *
 
2433
     * @method next
 
2434
     * @return {MIXED} the next item in the queue.
 
2435
     */
 
2436
    next: function() {
 
2437
        return this._q.shift();
 
2438
    },
 
2439
 
 
2440
    /**
 
2441
     * Get the last in the queue. LIFO support.
 
2442
     *
 
2443
     * @method last
 
2444
     * @return {MIXED} the last item in the queue.
 
2445
     */
 
2446
    last: function() {
 
2447
        return this._q.pop();
 
2448
    },
 
2449
 
 
2450
    /**
 
2451
     * Add 0..n items to the end of the queue.
 
2452
     *
 
2453
     * @method add
 
2454
     * @param {MIXED} item* 0..n items.
 
2455
     * @return {object} this queue.
 
2456
     */
 
2457
    add: function() {
 
2458
        this._q.push.apply(this._q, arguments);
 
2459
 
 
2460
        return this;
 
2461
    },
 
2462
 
 
2463
    /**
 
2464
     * Returns the current number of queued items.
 
2465
     *
 
2466
     * @method size
 
2467
     * @return {Number} The size.
 
2468
     */
 
2469
    size: function() {
 
2470
        return this._q.length;
 
2471
    }
 
2472
};
 
2473
 
 
2474
Y.Queue = Queue;
 
2475
 
 
2476
YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
 
2477
 
 
2478
/**
 
2479
The YUI module contains the components required for building the YUI seed file.
 
2480
This includes the script loading mechanism, a simple queue, and the core
 
2481
utilities for the library.
 
2482
 
 
2483
@module yui
 
2484
@submodule yui-base
 
2485
**/
 
2486
 
 
2487
var CACHED_DELIMITER = '__',
 
2488
 
 
2489
    hasOwn   = Object.prototype.hasOwnProperty,
 
2490
    isObject = Y.Lang.isObject;
 
2491
 
 
2492
/**
 
2493
Returns a wrapper for a function which caches the return value of that function,
 
2494
keyed off of the combined string representation of the argument values provided
 
2495
when the wrapper is called.
 
2496
 
 
2497
Calling this function again with the same arguments will return the cached value
 
2498
rather than executing the wrapped function.
 
2499
 
 
2500
Note that since the cache is keyed off of the string representation of arguments
 
2501
passed to the wrapper function, arguments that aren't strings and don't provide
 
2502
a meaningful `toString()` method may result in unexpected caching behavior. For
 
2503
example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
 
2504
string `[object Object]` when used as a cache key.
 
2505
 
 
2506
@method cached
 
2507
@param {Function} source The function to memoize.
 
2508
@param {Object} [cache={}] Object in which to store cached values. You may seed
 
2509
  this object with pre-existing cached values if desired.
 
2510
@param {any} [refetch] If supplied, this value is compared with the cached value
 
2511
  using a `==` comparison. If the values are equal, the wrapped function is
 
2512
  executed again even though a cached value exists.
 
2513
@return {Function} Wrapped function.
 
2514
@for YUI
 
2515
**/
 
2516
Y.cached = function (source, cache, refetch) {
 
2517
    /*jshint expr: true*/
 
2518
    cache || (cache = {});
 
2519
 
 
2520
    return function (arg) {
 
2521
        var key = arguments.length > 1 ?
 
2522
                Array.prototype.join.call(arguments, CACHED_DELIMITER) :
 
2523
                String(arg);
 
2524
        
 
2525
        /*jshint eqeqeq: false*/
 
2526
        if (!(key in cache) || (refetch && cache[key] == refetch)) {
 
2527
            cache[key] = source.apply(source, arguments);
 
2528
        }
 
2529
 
 
2530
        return cache[key];
 
2531
    };
 
2532
};
 
2533
 
 
2534
/**
 
2535
Returns the `location` object from the window/frame in which this YUI instance
 
2536
operates, or `undefined` when executing in a non-browser environment
 
2537
(e.g. Node.js).
 
2538
 
 
2539
It is _not_ recommended to hold references to the `window.location` object
 
2540
outside of the scope of a function in which its properties are being accessed or
 
2541
its methods are being called. This is because of a nasty bug/issue that exists
 
2542
in both Safari and MobileSafari browsers:
 
2543
[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
 
2544
 
 
2545
@method getLocation
 
2546
@return {location} The `location` object from the window/frame in which this YUI
 
2547
    instance operates.
 
2548
@since 3.5.0
 
2549
**/
 
2550
Y.getLocation = function () {
 
2551
    // It is safer to look this up every time because yui-base is attached to a
 
2552
    // YUI instance before a user's config is applied; i.e. `Y.config.win` does
 
2553
    // not point the correct window object when this file is loaded.
 
2554
    var win = Y.config.win;
 
2555
 
 
2556
    // It is not safe to hold a reference to the `location` object outside the
 
2557
    // scope in which it is being used. The WebKit engine used in Safari and
 
2558
    // MobileSafari will "disconnect" the `location` object from the `window`
 
2559
    // when a page is restored from back/forward history cache.
 
2560
    return win && win.location;
 
2561
};
 
2562
 
 
2563
/**
 
2564
Returns a new object containing all of the properties of all the supplied
 
2565
objects. The properties from later objects will overwrite those in earlier
 
2566
objects.
 
2567
 
 
2568
Passing in a single object will create a shallow copy of it. For a deep copy,
 
2569
use `clone()`.
 
2570
 
 
2571
@method merge
 
2572
@param {Object} objects* One or more objects to merge.
 
2573
@return {Object} A new merged object.
 
2574
**/
 
2575
Y.merge = function () {
 
2576
    var i      = 0,
 
2577
        len    = arguments.length,
 
2578
        result = {},
 
2579
        key,
 
2580
        obj;
 
2581
 
 
2582
    for (; i < len; ++i) {
 
2583
        obj = arguments[i];
 
2584
 
 
2585
        for (key in obj) {
 
2586
            if (hasOwn.call(obj, key)) {
 
2587
                result[key] = obj[key];
 
2588
            }
 
2589
        }
 
2590
    }
 
2591
 
 
2592
    return result;
 
2593
};
 
2594
 
 
2595
/**
 
2596
Mixes _supplier_'s properties into _receiver_.
 
2597
 
 
2598
Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
 
2599
shadowed unless the _overwrite_ parameter is `true`, and will not be merged
 
2600
unless the _merge_ parameter is `true`.
 
2601
 
 
2602
In the default mode (0), only properties the supplier owns are copied (prototype
 
2603
properties are not copied). The following copying modes are available:
 
2604
 
 
2605
  * `0`: _Default_. Object to object.
 
2606
  * `1`: Prototype to prototype.
 
2607
  * `2`: Prototype to prototype and object to object.
 
2608
  * `3`: Prototype to object.
 
2609
  * `4`: Object to prototype.
 
2610
 
 
2611
@method mix
 
2612
@param {Function|Object} receiver The object or function to receive the mixed
 
2613
  properties.
 
2614
@param {Function|Object} supplier The object or function supplying the
 
2615
  properties to be mixed.
 
2616
@param {Boolean} [overwrite=false] If `true`, properties that already exist
 
2617
  on the receiver will be overwritten with properties from the supplier.
 
2618
@param {String[]} [whitelist] An array of property names to copy. If
 
2619
  specified, only the whitelisted properties will be copied, and all others
 
2620
  will be ignored.
 
2621
@param {Number} [mode=0] Mix mode to use. See above for available modes.
 
2622
@param {Boolean} [merge=false] If `true`, objects and arrays that already
 
2623
  exist on the receiver will have the corresponding object/array from the
 
2624
  supplier merged into them, rather than being skipped or overwritten. When
 
2625
  both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
 
2626
@return {Function|Object|YUI} The receiver, or the YUI instance if the
 
2627
  specified receiver is falsy.
 
2628
**/
 
2629
Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
 
2630
    var alwaysOverwrite, exists, from, i, key, len, to;
 
2631
 
 
2632
    // If no supplier is given, we return the receiver. If no receiver is given,
 
2633
    // we return Y. Returning Y doesn't make much sense to me, but it's
 
2634
    // grandfathered in for backcompat reasons.
 
2635
    if (!receiver || !supplier) {
 
2636
        return receiver || Y;
 
2637
    }
 
2638
 
 
2639
    if (mode) {
 
2640
        // In mode 2 (prototype to prototype and object to object), we recurse
 
2641
        // once to do the proto to proto mix. The object to object mix will be
 
2642
        // handled later on.
 
2643
        if (mode === 2) {
 
2644
            Y.mix(receiver.prototype, supplier.prototype, overwrite,
 
2645
                    whitelist, 0, merge);
 
2646
        }
 
2647
 
 
2648
        // Depending on which mode is specified, we may be copying from or to
 
2649
        // the prototypes of the supplier and receiver.
 
2650
        from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
 
2651
        to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
 
2652
 
 
2653
        // If either the supplier or receiver doesn't actually have a
 
2654
        // prototype property, then we could end up with an undefined `from`
 
2655
        // or `to`. If that happens, we abort and return the receiver.
 
2656
        if (!from || !to) {
 
2657
            return receiver;
 
2658
        }
 
2659
    } else {
 
2660
        from = supplier;
 
2661
        to   = receiver;
 
2662
    }
 
2663
 
 
2664
    // If `overwrite` is truthy and `merge` is falsy, then we can skip a
 
2665
    // property existence check on each iteration and save some time.
 
2666
    alwaysOverwrite = overwrite && !merge;
 
2667
 
 
2668
    if (whitelist) {
 
2669
        for (i = 0, len = whitelist.length; i < len; ++i) {
 
2670
            key = whitelist[i];
 
2671
 
 
2672
            // We call `Object.prototype.hasOwnProperty` instead of calling
 
2673
            // `hasOwnProperty` on the object itself, since the object's
 
2674
            // `hasOwnProperty` method may have been overridden or removed.
 
2675
            // Also, some native objects don't implement a `hasOwnProperty`
 
2676
            // method.
 
2677
            if (!hasOwn.call(from, key)) {
 
2678
                continue;
 
2679
            }
 
2680
 
 
2681
            // The `key in to` check here is (sadly) intentional for backwards
 
2682
            // compatibility reasons. It prevents undesired shadowing of
 
2683
            // prototype members on `to`.
 
2684
            exists = alwaysOverwrite ? false : key in to;
 
2685
 
 
2686
            if (merge && exists && isObject(to[key], true)
 
2687
                    && isObject(from[key], true)) {
 
2688
                // If we're in merge mode, and the key is present on both
 
2689
                // objects, and the value on both objects is either an object or
 
2690
                // an array (but not a function), then we recurse to merge the
 
2691
                // `from` value into the `to` value instead of overwriting it.
 
2692
                //
 
2693
                // Note: It's intentional that the whitelist isn't passed to the
 
2694
                // recursive call here. This is legacy behavior that lots of
 
2695
                // code still depends on.
 
2696
                Y.mix(to[key], from[key], overwrite, null, 0, merge);
 
2697
            } else if (overwrite || !exists) {
 
2698
                // We're not in merge mode, so we'll only copy the `from` value
 
2699
                // to the `to` value if we're in overwrite mode or if the
 
2700
                // current key doesn't exist on the `to` object.
 
2701
                to[key] = from[key];
 
2702
            }
 
2703
        }
 
2704
    } else {
 
2705
        for (key in from) {
 
2706
            // The code duplication here is for runtime performance reasons.
 
2707
            // Combining whitelist and non-whitelist operations into a single
 
2708
            // loop or breaking the shared logic out into a function both result
 
2709
            // in worse performance, and Y.mix is critical enough that the byte
 
2710
            // tradeoff is worth it.
 
2711
            if (!hasOwn.call(from, key)) {
 
2712
                continue;
 
2713
            }
 
2714
 
 
2715
            // The `key in to` check here is (sadly) intentional for backwards
 
2716
            // compatibility reasons. It prevents undesired shadowing of
 
2717
            // prototype members on `to`.
 
2718
            exists = alwaysOverwrite ? false : key in to;
 
2719
 
 
2720
            if (merge && exists && isObject(to[key], true)
 
2721
                    && isObject(from[key], true)) {
 
2722
                Y.mix(to[key], from[key], overwrite, null, 0, merge);
 
2723
            } else if (overwrite || !exists) {
 
2724
                to[key] = from[key];
 
2725
            }
 
2726
        }
 
2727
 
 
2728
        // If this is an IE browser with the JScript enumeration bug, force
 
2729
        // enumeration of the buggy properties by making a recursive call with
 
2730
        // the buggy properties as the whitelist.
 
2731
        if (Y.Object._hasEnumBug) {
 
2732
            Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
 
2733
        }
 
2734
    }
 
2735
 
 
2736
    return receiver;
 
2737
};
 
2738
/**
 
2739
 * The YUI module contains the components required for building the YUI
 
2740
 * seed file.  This includes the script loading mechanism, a simple queue,
 
2741
 * and the core utilities for the library.
 
2742
 * @module yui
 
2743
 * @submodule yui-base
 
2744
 */
 
2745
 
 
2746
/**
 
2747
 * Adds utilities to the YUI instance for working with objects.
 
2748
 *
 
2749
 * @class Object
 
2750
 */
 
2751
 
 
2752
var Lang   = Y.Lang,
 
2753
    hasOwn = Object.prototype.hasOwnProperty,
 
2754
 
 
2755
    UNDEFINED, // <-- Note the comma. We're still declaring vars.
 
2756
 
 
2757
/**
 
2758
 * Returns a new object that uses _obj_ as its prototype. This method wraps the
 
2759
 * native ES5 `Object.create()` method if available, but doesn't currently
 
2760
 * pass through `Object.create()`'s second argument (properties) in order to
 
2761
 * ensure compatibility with older browsers.
 
2762
 *
 
2763
 * @method ()
 
2764
 * @param {Object} obj Prototype object.
 
2765
 * @return {Object} New object using _obj_ as its prototype.
 
2766
 * @static
 
2767
 */
 
2768
O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
 
2769
    // We currently wrap the native Object.create instead of simply aliasing it
 
2770
    // to ensure consistency with our fallback shim, which currently doesn't
 
2771
    // support Object.create()'s second argument (properties). Once we have a
 
2772
    // safe fallback for the properties arg, we can stop wrapping
 
2773
    // Object.create().
 
2774
    return Object.create(obj);
 
2775
} : (function () {
 
2776
    // Reusable constructor function for the Object.create() shim.
 
2777
    function F() {}
 
2778
 
 
2779
    // The actual shim.
 
2780
    return function (obj) {
 
2781
        F.prototype = obj;
 
2782
        return new F();
 
2783
    };
 
2784
}()),
 
2785
 
 
2786
/**
 
2787
 * Property names that IE doesn't enumerate in for..in loops, even when they
 
2788
 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
 
2789
 * manually enumerate these properties.
 
2790
 *
 
2791
 * @property _forceEnum
 
2792
 * @type String[]
 
2793
 * @protected
 
2794
 * @static
 
2795
 */
 
2796
forceEnum = O._forceEnum = [
 
2797
    'hasOwnProperty',
 
2798
    'isPrototypeOf',
 
2799
    'propertyIsEnumerable',
 
2800
    'toString',
 
2801
    'toLocaleString',
 
2802
    'valueOf'
 
2803
],
 
2804
 
 
2805
/**
 
2806
 * `true` if this browser has the JScript enumeration bug that prevents
 
2807
 * enumeration of the properties named in the `_forceEnum` array, `false`
 
2808
 * otherwise.
 
2809
 *
 
2810
 * See:
 
2811
 *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
 
2812
 *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
 
2813
 *
 
2814
 * @property _hasEnumBug
 
2815
 * @type Boolean
 
2816
 * @protected
 
2817
 * @static
 
2818
 */
 
2819
hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
 
2820
 
 
2821
/**
 
2822
 * `true` if this browser incorrectly considers the `prototype` property of
 
2823
 * functions to be enumerable. Currently known to affect Opera 11.50.
 
2824
 *
 
2825
 * @property _hasProtoEnumBug
 
2826
 * @type Boolean
 
2827
 * @protected
 
2828
 * @static
 
2829
 */
 
2830
hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
 
2831
 
 
2832
/**
 
2833
 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
 
2834
 * exists only on _obj_'s prototype. This is essentially a safer version of
 
2835
 * `obj.hasOwnProperty()`.
 
2836
 *
 
2837
 * @method owns
 
2838
 * @param {Object} obj Object to test.
 
2839
 * @param {String} key Property name to look for.
 
2840
 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
 
2841
 * @static
 
2842
 */
 
2843
owns = O.owns = function (obj, key) {
 
2844
    return !!obj && hasOwn.call(obj, key);
 
2845
}; // <-- End of var declarations.
 
2846
 
 
2847
/**
 
2848
 * Alias for `owns()`.
 
2849
 *
 
2850
 * @method hasKey
 
2851
 * @param {Object} obj Object to test.
 
2852
 * @param {String} key Property name to look for.
 
2853
 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
 
2854
 * @static
 
2855
 */
 
2856
O.hasKey = owns;
 
2857
 
 
2858
/**
 
2859
 * Returns an array containing the object's enumerable keys. Does not include
 
2860
 * prototype keys or non-enumerable keys.
 
2861
 *
 
2862
 * Note that keys are returned in enumeration order (that is, in the same order
 
2863
 * that they would be enumerated by a `for-in` loop), which may not be the same
 
2864
 * as the order in which they were defined.
 
2865
 *
 
2866
 * This method is an alias for the native ES5 `Object.keys()` method if
 
2867
 * available.
 
2868
 *
 
2869
 * @example
 
2870
 *
 
2871
 *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
 
2872
 *     // => ['a', 'b', 'c']
 
2873
 *
 
2874
 * @method keys
 
2875
 * @param {Object} obj An object.
 
2876
 * @return {String[]} Array of keys.
 
2877
 * @static
 
2878
 */
 
2879
O.keys = Lang._isNative(Object.keys) ? Object.keys : function (obj) {
 
2880
    if (!Lang.isObject(obj)) {
 
2881
        throw new TypeError('Object.keys called on a non-object');
 
2882
    }
 
2883
 
 
2884
    var keys = [],
 
2885
        i, key, len;
 
2886
 
 
2887
    if (hasProtoEnumBug && typeof obj === 'function') {
 
2888
        for (key in obj) {
 
2889
            if (owns(obj, key) && key !== 'prototype') {
 
2890
                keys.push(key);
 
2891
            }
 
2892
        }
 
2893
    } else {
 
2894
        for (key in obj) {
 
2895
            if (owns(obj, key)) {
 
2896
                keys.push(key);
 
2897
            }
 
2898
        }
 
2899
    }
 
2900
 
 
2901
    if (hasEnumBug) {
 
2902
        for (i = 0, len = forceEnum.length; i < len; ++i) {
 
2903
            key = forceEnum[i];
 
2904
 
 
2905
            if (owns(obj, key)) {
 
2906
                keys.push(key);
 
2907
            }
 
2908
        }
 
2909
    }
 
2910
 
 
2911
    return keys;
 
2912
};
 
2913
 
 
2914
/**
 
2915
 * Returns an array containing the values of the object's enumerable keys.
 
2916
 *
 
2917
 * Note that values are returned in enumeration order (that is, in the same
 
2918
 * order that they would be enumerated by a `for-in` loop), which may not be the
 
2919
 * same as the order in which they were defined.
 
2920
 *
 
2921
 * @example
 
2922
 *
 
2923
 *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
 
2924
 *     // => ['foo', 'bar', 'baz']
 
2925
 *
 
2926
 * @method values
 
2927
 * @param {Object} obj An object.
 
2928
 * @return {Array} Array of values.
 
2929
 * @static
 
2930
 */
 
2931
O.values = function (obj) {
 
2932
    var keys   = O.keys(obj),
 
2933
        i      = 0,
 
2934
        len    = keys.length,
 
2935
        values = [];
 
2936
 
 
2937
    for (; i < len; ++i) {
 
2938
        values.push(obj[keys[i]]);
 
2939
    }
 
2940
 
 
2941
    return values;
 
2942
};
 
2943
 
 
2944
/**
 
2945
 * Returns the number of enumerable keys owned by an object.
 
2946
 *
 
2947
 * @method size
 
2948
 * @param {Object} obj An object.
 
2949
 * @return {Number} The object's size.
 
2950
 * @static
 
2951
 */
 
2952
O.size = function (obj) {
 
2953
    try {
 
2954
        return O.keys(obj).length;
 
2955
    } catch (ex) {
 
2956
        return 0; // Legacy behavior for non-objects.
 
2957
    }
 
2958
};
 
2959
 
 
2960
/**
 
2961
 * Returns `true` if the object owns an enumerable property with the specified
 
2962
 * value.
 
2963
 *
 
2964
 * @method hasValue
 
2965
 * @param {Object} obj An object.
 
2966
 * @param {any} value The value to search for.
 
2967
 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
 
2968
 * @static
 
2969
 */
 
2970
O.hasValue = function (obj, value) {
 
2971
    return Y.Array.indexOf(O.values(obj), value) > -1;
 
2972
};
 
2973
 
 
2974
/**
 
2975
 * Executes a function on each enumerable property in _obj_. The function
 
2976
 * receives the value, the key, and the object itself as parameters (in that
 
2977
 * order).
 
2978
 *
 
2979
 * By default, only properties owned by _obj_ are enumerated. To include
 
2980
 * prototype properties, set the _proto_ parameter to `true`.
 
2981
 *
 
2982
 * @method each
 
2983
 * @param {Object} obj Object to enumerate.
 
2984
 * @param {Function} fn Function to execute on each enumerable property.
 
2985
 *   @param {mixed} fn.value Value of the current property.
 
2986
 *   @param {String} fn.key Key of the current property.
 
2987
 *   @param {Object} fn.obj Object being enumerated.
 
2988
 * @param {Object} [thisObj] `this` object to use when calling _fn_.
 
2989
 * @param {Boolean} [proto=false] Include prototype properties.
 
2990
 * @return {YUI} the YUI instance.
 
2991
 * @chainable
 
2992
 * @static
 
2993
 */
 
2994
O.each = function (obj, fn, thisObj, proto) {
 
2995
    var key;
 
2996
 
 
2997
    for (key in obj) {
 
2998
        if (proto || owns(obj, key)) {
 
2999
            fn.call(thisObj || Y, obj[key], key, obj);
 
3000
        }
 
3001
    }
 
3002
 
 
3003
    return Y;
 
3004
};
 
3005
 
 
3006
/**
 
3007
 * Executes a function on each enumerable property in _obj_, but halts if the
 
3008
 * function returns a truthy value. The function receives the value, the key,
 
3009
 * and the object itself as paramters (in that order).
 
3010
 *
 
3011
 * By default, only properties owned by _obj_ are enumerated. To include
 
3012
 * prototype properties, set the _proto_ parameter to `true`.
 
3013
 *
 
3014
 * @method some
 
3015
 * @param {Object} obj Object to enumerate.
 
3016
 * @param {Function} fn Function to execute on each enumerable property.
 
3017
 *   @param {mixed} fn.value Value of the current property.
 
3018
 *   @param {String} fn.key Key of the current property.
 
3019
 *   @param {Object} fn.obj Object being enumerated.
 
3020
 * @param {Object} [thisObj] `this` object to use when calling _fn_.
 
3021
 * @param {Boolean} [proto=false] Include prototype properties.
 
3022
 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
 
3023
 *   `false` otherwise.
 
3024
 * @static
 
3025
 */
 
3026
O.some = function (obj, fn, thisObj, proto) {
 
3027
    var key;
 
3028
 
 
3029
    for (key in obj) {
 
3030
        if (proto || owns(obj, key)) {
 
3031
            if (fn.call(thisObj || Y, obj[key], key, obj)) {
 
3032
                return true;
 
3033
            }
 
3034
        }
 
3035
    }
 
3036
 
 
3037
    return false;
 
3038
};
 
3039
 
 
3040
/**
 
3041
 * Retrieves the sub value at the provided path,
 
3042
 * from the value object provided.
 
3043
 *
 
3044
 * @method getValue
 
3045
 * @static
 
3046
 * @param o The object from which to extract the property value.
 
3047
 * @param path {Array} A path array, specifying the object traversal path
 
3048
 * from which to obtain the sub value.
 
3049
 * @return {Any} The value stored in the path, undefined if not found,
 
3050
 * undefined if the source is not an object.  Returns the source object
 
3051
 * if an empty path is provided.
 
3052
 */
 
3053
O.getValue = function(o, path) {
 
3054
    if (!Lang.isObject(o)) {
 
3055
        return UNDEFINED;
 
3056
    }
 
3057
 
 
3058
    var i,
 
3059
        p = Y.Array(path),
 
3060
        l = p.length;
 
3061
 
 
3062
    for (i = 0; o !== UNDEFINED && i < l; i++) {
 
3063
        o = o[p[i]];
 
3064
    }
 
3065
 
 
3066
    return o;
 
3067
};
 
3068
 
 
3069
/**
 
3070
 * Sets the sub-attribute value at the provided path on the
 
3071
 * value object.  Returns the modified value object, or
 
3072
 * undefined if the path is invalid.
 
3073
 *
 
3074
 * @method setValue
 
3075
 * @static
 
3076
 * @param o             The object on which to set the sub value.
 
3077
 * @param path {Array}  A path array, specifying the object traversal path
 
3078
 *                      at which to set the sub value.
 
3079
 * @param val {Any}     The new value for the sub-attribute.
 
3080
 * @return {Object}     The modified object, with the new sub value set, or
 
3081
 *                      undefined, if the path was invalid.
 
3082
 */
 
3083
O.setValue = function(o, path, val) {
 
3084
    var i,
 
3085
        p = Y.Array(path),
 
3086
        leafIdx = p.length - 1,
 
3087
        ref = o;
 
3088
 
 
3089
    if (leafIdx >= 0) {
 
3090
        for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
 
3091
            ref = ref[p[i]];
 
3092
        }
 
3093
 
 
3094
        if (ref !== UNDEFINED) {
 
3095
            ref[p[i]] = val;
 
3096
        } else {
 
3097
            return UNDEFINED;
 
3098
        }
 
3099
    }
 
3100
 
 
3101
    return o;
 
3102
};
 
3103
 
 
3104
/**
 
3105
 * Returns `true` if the object has no enumerable properties of its own.
 
3106
 *
 
3107
 * @method isEmpty
 
3108
 * @param {Object} obj An object.
 
3109
 * @return {Boolean} `true` if the object is empty.
 
3110
 * @static
 
3111
 * @since 3.2.0
 
3112
 */
 
3113
O.isEmpty = function (obj) {
 
3114
    return !O.keys(Object(obj)).length;
 
3115
};
 
3116
/**
 
3117
 * The YUI module contains the components required for building the YUI seed
 
3118
 * file.  This includes the script loading mechanism, a simple queue, and the
 
3119
 * core utilities for the library.
 
3120
 * @module yui
 
3121
 * @submodule yui-base
 
3122
 */
 
3123
 
 
3124
/**
 
3125
 * YUI user agent detection.
 
3126
 * Do not fork for a browser if it can be avoided.  Use feature detection when
 
3127
 * you can.  Use the user agent as a last resort.  For all fields listed
 
3128
 * as @type float, UA stores a version number for the browser engine,
 
3129
 * 0 otherwise.  This value may or may not map to the version number of
 
3130
 * the browser using the engine.  The value is presented as a float so
 
3131
 * that it can easily be used for boolean evaluation as well as for
 
3132
 * looking for a particular range of versions.  Because of this,
 
3133
 * some of the granularity of the version info may be lost.  The fields that
 
3134
 * are @type string default to null.  The API docs list the values that
 
3135
 * these fields can have.
 
3136
 * @class UA
 
3137
 * @static
 
3138
 */
 
3139
 
 
3140
/**
 
3141
* Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
 
3142
* to populate `Y.UA`.
 
3143
*
 
3144
* @static
 
3145
* @method parseUA
 
3146
* @param {String} [subUA=navigator.userAgent] UA string to parse
 
3147
* @return {Object} The Y.UA object
 
3148
*/
 
3149
YUI.Env.parseUA = function(subUA) {
 
3150
 
 
3151
    var numberify = function(s) {
 
3152
            var c = 0;
 
3153
            return parseFloat(s.replace(/\./g, function() {
 
3154
                return (c++ === 1) ? '' : '.';
 
3155
            }));
 
3156
        },
 
3157
 
 
3158
        win = Y.config.win,
 
3159
 
 
3160
        nav = win && win.navigator,
 
3161
 
 
3162
        o = {
 
3163
 
 
3164
        /**
 
3165
         * Internet Explorer version number or 0.  Example: 6
 
3166
         * @property ie
 
3167
         * @type float
 
3168
         * @static
 
3169
         */
 
3170
        ie: 0,
 
3171
 
 
3172
        /**
 
3173
         * Opera version number or 0.  Example: 9.2
 
3174
         * @property opera
 
3175
         * @type float
 
3176
         * @static
 
3177
         */
 
3178
        opera: 0,
 
3179
 
 
3180
        /**
 
3181
         * Gecko engine revision number.  Will evaluate to 1 if Gecko
 
3182
         * is detected but the revision could not be found. Other browsers
 
3183
         * will be 0.  Example: 1.8
 
3184
         * <pre>
 
3185
         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
 
3186
         * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
 
3187
         * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
 
3188
         * Firefox 3.0   <-- 1.9
 
3189
         * Firefox 3.5   <-- 1.91
 
3190
         * </pre>
 
3191
         * @property gecko
 
3192
         * @type float
 
3193
         * @static
 
3194
         */
 
3195
        gecko: 0,
 
3196
 
 
3197
        /**
 
3198
         * AppleWebKit version.  KHTML browsers that are not WebKit browsers
 
3199
         * will evaluate to 1, other browsers 0.  Example: 418.9
 
3200
         * <pre>
 
3201
         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
 
3202
         *                                   latest available for Mac OSX 10.3.
 
3203
         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
 
3204
         * Safari 2.0.4:         418     <-- preventDefault fixed
 
3205
         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
 
3206
         *                                   different versions of webkit
 
3207
         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
 
3208
         *                                   updated, but not updated
 
3209
         *                                   to the latest patch.
 
3210
         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
 
3211
         * SVG and many major issues fixed).
 
3212
         * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
 
3213
         * update from 2.x via the 10.4.11 OS patch.
 
3214
         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
 
3215
         *                                   yahoo.com user agent hack removed.
 
3216
         * </pre>
 
3217
         * http://en.wikipedia.org/wiki/Safari_version_history
 
3218
         * @property webkit
 
3219
         * @type float
 
3220
         * @static
 
3221
         */
 
3222
        webkit: 0,
 
3223
 
 
3224
        /**
 
3225
         * Safari will be detected as webkit, but this property will also
 
3226
         * be populated with the Safari version number
 
3227
         * @property safari
 
3228
         * @type float
 
3229
         * @static
 
3230
         */
 
3231
        safari: 0,
 
3232
 
 
3233
        /**
 
3234
         * Chrome will be detected as webkit, but this property will also
 
3235
         * be populated with the Chrome version number
 
3236
         * @property chrome
 
3237
         * @type float
 
3238
         * @static
 
3239
         */
 
3240
        chrome: 0,
 
3241
 
 
3242
        /**
 
3243
         * The mobile property will be set to a string containing any relevant
 
3244
         * user agent information when a modern mobile browser is detected.
 
3245
         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
 
3246
         * devices with the WebKit-based browser, and Opera Mini.
 
3247
         * @property mobile
 
3248
         * @type string
 
3249
         * @default null
 
3250
         * @static
 
3251
         */
 
3252
        mobile: null,
 
3253
 
 
3254
        /**
 
3255
         * Adobe AIR version number or 0.  Only populated if webkit is detected.
 
3256
         * Example: 1.0
 
3257
         * @property air
 
3258
         * @type float
 
3259
         */
 
3260
        air: 0,
 
3261
        /**
 
3262
         * PhantomJS version number or 0.  Only populated if webkit is detected.
 
3263
         * Example: 1.0
 
3264
         * @property phantomjs
 
3265
         * @type float
 
3266
         */
 
3267
        phantomjs: 0,
 
3268
        /**
 
3269
         * Detects Apple iPad's OS version
 
3270
         * @property ipad
 
3271
         * @type float
 
3272
         * @static
 
3273
         */
 
3274
        ipad: 0,
 
3275
        /**
 
3276
         * Detects Apple iPhone's OS version
 
3277
         * @property iphone
 
3278
         * @type float
 
3279
         * @static
 
3280
         */
 
3281
        iphone: 0,
 
3282
        /**
 
3283
         * Detects Apples iPod's OS version
 
3284
         * @property ipod
 
3285
         * @type float
 
3286
         * @static
 
3287
         */
 
3288
        ipod: 0,
 
3289
        /**
 
3290
         * General truthy check for iPad, iPhone or iPod
 
3291
         * @property ios
 
3292
         * @type Boolean
 
3293
         * @default null
 
3294
         * @static
 
3295
         */
 
3296
        ios: null,
 
3297
        /**
 
3298
         * Detects Googles Android OS version
 
3299
         * @property android
 
3300
         * @type float
 
3301
         * @static
 
3302
         */
 
3303
        android: 0,
 
3304
        /**
 
3305
         * Detects Kindle Silk
 
3306
         * @property silk
 
3307
         * @type float
 
3308
         * @static
 
3309
         */
 
3310
        silk: 0,
 
3311
        /**
 
3312
         * Detects Kindle Silk Acceleration
 
3313
         * @property accel
 
3314
         * @type Boolean
 
3315
         * @static
 
3316
         */
 
3317
        accel: false,
 
3318
        /**
 
3319
         * Detects Palms WebOS version
 
3320
         * @property webos
 
3321
         * @type float
 
3322
         * @static
 
3323
         */
 
3324
        webos: 0,
 
3325
 
 
3326
        /**
 
3327
         * Google Caja version number or 0.
 
3328
         * @property caja
 
3329
         * @type float
 
3330
         */
 
3331
        caja: nav && nav.cajaVersion,
 
3332
 
 
3333
        /**
 
3334
         * Set to true if the page appears to be in SSL
 
3335
         * @property secure
 
3336
         * @type boolean
 
3337
         * @static
 
3338
         */
 
3339
        secure: false,
 
3340
 
 
3341
        /**
 
3342
         * The operating system.  Currently only detecting windows or macintosh
 
3343
         * @property os
 
3344
         * @type string
 
3345
         * @default null
 
3346
         * @static
 
3347
         */
 
3348
        os: null,
 
3349
 
 
3350
        /**
 
3351
         * The Nodejs Version
 
3352
         * @property nodejs
 
3353
         * @type float
 
3354
         * @default 0
 
3355
         * @static
 
3356
         */
 
3357
        nodejs: 0,
 
3358
        /**
 
3359
        * Window8/IE10 Application host environment
 
3360
        * @property winjs
 
3361
        * @type Boolean
 
3362
        * @static
 
3363
        */
 
3364
        winjs: !!((typeof Windows !== "undefined") && Windows.System),
 
3365
        /**
 
3366
        * Are touch/msPointer events available on this device
 
3367
        * @property touchEnabled
 
3368
        * @type Boolean
 
3369
        * @static
 
3370
        */
 
3371
        touchEnabled: false
 
3372
    },
 
3373
 
 
3374
    ua = subUA || nav && nav.userAgent,
 
3375
 
 
3376
    loc = win && win.location,
 
3377
 
 
3378
    href = loc && loc.href,
 
3379
 
 
3380
    m;
 
3381
 
 
3382
    /**
 
3383
    * The User Agent string that was parsed
 
3384
    * @property userAgent
 
3385
    * @type String
 
3386
    * @static
 
3387
    */
 
3388
    o.userAgent = ua;
 
3389
 
 
3390
 
 
3391
    o.secure = href && (href.toLowerCase().indexOf('https') === 0);
 
3392
 
 
3393
    if (ua) {
 
3394
 
 
3395
        if ((/windows|win32/i).test(ua)) {
 
3396
            o.os = 'windows';
 
3397
        } else if ((/macintosh|mac_powerpc/i).test(ua)) {
 
3398
            o.os = 'macintosh';
 
3399
        } else if ((/android/i).test(ua)) {
 
3400
            o.os = 'android';
 
3401
        } else if ((/symbos/i).test(ua)) {
 
3402
            o.os = 'symbos';
 
3403
        } else if ((/linux/i).test(ua)) {
 
3404
            o.os = 'linux';
 
3405
        } else if ((/rhino/i).test(ua)) {
 
3406
            o.os = 'rhino';
 
3407
        }
 
3408
 
 
3409
        // Modern KHTML browsers should qualify as Safari X-Grade
 
3410
        if ((/KHTML/).test(ua)) {
 
3411
            o.webkit = 1;
 
3412
        }
 
3413
        if ((/IEMobile|XBLWP7/).test(ua)) {
 
3414
            o.mobile = 'windows';
 
3415
        }
 
3416
        if ((/Fennec/).test(ua)) {
 
3417
            o.mobile = 'gecko';
 
3418
        }
 
3419
        // Modern WebKit browsers are at least X-Grade
 
3420
        m = ua.match(/AppleWebKit\/([^\s]*)/);
 
3421
        if (m && m[1]) {
 
3422
            o.webkit = numberify(m[1]);
 
3423
            o.safari = o.webkit;
 
3424
 
 
3425
            if (/PhantomJS/.test(ua)) {
 
3426
                m = ua.match(/PhantomJS\/([^\s]*)/);
 
3427
                if (m && m[1]) {
 
3428
                    o.phantomjs = numberify(m[1]);
 
3429
                }
 
3430
            }
 
3431
 
 
3432
            // Mobile browser check
 
3433
            if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
 
3434
                o.mobile = 'Apple'; // iPhone or iPod Touch
 
3435
 
 
3436
                m = ua.match(/OS ([^\s]*)/);
 
3437
                if (m && m[1]) {
 
3438
                    m = numberify(m[1].replace('_', '.'));
 
3439
                }
 
3440
                o.ios = m;
 
3441
                o.os = 'ios';
 
3442
                o.ipad = o.ipod = o.iphone = 0;
 
3443
 
 
3444
                m = ua.match(/iPad|iPod|iPhone/);
 
3445
                if (m && m[0]) {
 
3446
                    o[m[0].toLowerCase()] = o.ios;
 
3447
                }
 
3448
            } else {
 
3449
                m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
 
3450
                if (m) {
 
3451
                    // Nokia N-series, webOS, ex: NokiaN95
 
3452
                    o.mobile = m[0];
 
3453
                }
 
3454
                if (/webOS/.test(ua)) {
 
3455
                    o.mobile = 'WebOS';
 
3456
                    m = ua.match(/webOS\/([^\s]*);/);
 
3457
                    if (m && m[1]) {
 
3458
                        o.webos = numberify(m[1]);
 
3459
                    }
 
3460
                }
 
3461
                if (/ Android/.test(ua)) {
 
3462
                    if (/Mobile/.test(ua)) {
 
3463
                        o.mobile = 'Android';
 
3464
                    }
 
3465
                    m = ua.match(/Android ([^\s]*);/);
 
3466
                    if (m && m[1]) {
 
3467
                        o.android = numberify(m[1]);
 
3468
                    }
 
3469
 
 
3470
                }
 
3471
                if (/Silk/.test(ua)) {
 
3472
                    m = ua.match(/Silk\/([^\s]*)\)/);
 
3473
                    if (m && m[1]) {
 
3474
                        o.silk = numberify(m[1]);
 
3475
                    }
 
3476
                    if (!o.android) {
 
3477
                        o.android = 2.34; //Hack for desktop mode in Kindle
 
3478
                        o.os = 'Android';
 
3479
                    }
 
3480
                    if (/Accelerated=true/.test(ua)) {
 
3481
                        o.accel = true;
 
3482
                    }
 
3483
                }
 
3484
            }
 
3485
 
 
3486
            m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
 
3487
            if (m && m[1] && m[2]) {
 
3488
                o.chrome = numberify(m[2]); // Chrome
 
3489
                o.safari = 0; //Reset safari back to 0
 
3490
                if (m[1] === 'CrMo') {
 
3491
                    o.mobile = 'chrome';
 
3492
                }
 
3493
            } else {
 
3494
                m = ua.match(/AdobeAIR\/([^\s]*)/);
 
3495
                if (m) {
 
3496
                    o.air = m[0]; // Adobe AIR 1.0 or better
 
3497
                }
 
3498
            }
 
3499
        }
 
3500
 
 
3501
        if (!o.webkit) { // not webkit
 
3502
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
 
3503
            if (/Opera/.test(ua)) {
 
3504
                m = ua.match(/Opera[\s\/]([^\s]*)/);
 
3505
                if (m && m[1]) {
 
3506
                    o.opera = numberify(m[1]);
 
3507
                }
 
3508
                m = ua.match(/Version\/([^\s]*)/);
 
3509
                if (m && m[1]) {
 
3510
                    o.opera = numberify(m[1]); // opera 10+
 
3511
                }
 
3512
 
 
3513
                if (/Opera Mobi/.test(ua)) {
 
3514
                    o.mobile = 'opera';
 
3515
                    m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
 
3516
                    if (m && m[1]) {
 
3517
                        o.opera = numberify(m[1]);
 
3518
                    }
 
3519
                }
 
3520
                m = ua.match(/Opera Mini[^;]*/);
 
3521
 
 
3522
                if (m) {
 
3523
                    o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
 
3524
                }
 
3525
            } else { // not opera or webkit
 
3526
                m = ua.match(/MSIE\s([^;]*)/);
 
3527
                if (m && m[1]) {
 
3528
                    o.ie = numberify(m[1]);
 
3529
                } else { // not opera, webkit, or ie
 
3530
                    m = ua.match(/Gecko\/([^\s]*)/);
 
3531
                    if (m) {
 
3532
                        o.gecko = 1; // Gecko detected, look for revision
 
3533
                        m = ua.match(/rv:([^\s\)]*)/);
 
3534
                        if (m && m[1]) {
 
3535
                            o.gecko = numberify(m[1]);
 
3536
                            if (/Mobile|Tablet/.test(ua)) {
 
3537
                                o.mobile = "ffos";
 
3538
                            }
 
3539
                        }
 
3540
                    }
 
3541
                }
 
3542
            }
 
3543
        }
 
3544
    }
 
3545
 
 
3546
    //Check for known properties to tell if touch events are enabled on this device or if
 
3547
    //the number of MSPointer touchpoints on this device is greater than 0.
 
3548
    if (win && nav && !(o.chrome && o.chrome < 6)) {
 
3549
        o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
 
3550
    }
 
3551
 
 
3552
    //It was a parsed UA, do not assign the global value.
 
3553
    if (!subUA) {
 
3554
 
 
3555
        if (typeof process === 'object') {
 
3556
 
 
3557
            if (process.versions && process.versions.node) {
 
3558
                //NodeJS
 
3559
                o.os = process.platform;
 
3560
                o.nodejs = numberify(process.versions.node);
 
3561
            }
 
3562
        }
 
3563
 
 
3564
        YUI.Env.UA = o;
 
3565
 
 
3566
    }
 
3567
 
 
3568
    return o;
 
3569
};
 
3570
 
 
3571
 
 
3572
Y.UA = YUI.Env.UA || YUI.Env.parseUA();
 
3573
 
 
3574
/**
 
3575
Performs a simple comparison between two version numbers, accounting for
 
3576
standard versioning logic such as the fact that "535.8" is a lower version than
 
3577
"535.24", even though a simple numerical comparison would indicate that it's
 
3578
greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
 
3579
considered equivalent.
 
3580
 
 
3581
Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
 
3582
1 if _a_ is higher than _b_.
 
3583
 
 
3584
Versions may be numbers or strings containing numbers and dots. For example,
 
3585
both `535` and `"535.8.10"` are acceptable. A version string containing
 
3586
non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
 
3587
 
 
3588
@method compareVersions
 
3589
@param {Number|String} a First version number to compare.
 
3590
@param {Number|String} b Second version number to compare.
 
3591
@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
 
3592
    higher than _b_.
 
3593
**/
 
3594
Y.UA.compareVersions = function (a, b) {
 
3595
    var aPart, aParts, bPart, bParts, i, len;
 
3596
 
 
3597
    if (a === b) {
 
3598
        return 0;
 
3599
    }
 
3600
 
 
3601
    aParts = (a + '').split('.');
 
3602
    bParts = (b + '').split('.');
 
3603
 
 
3604
    for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
 
3605
        aPart = parseInt(aParts[i], 10);
 
3606
        bPart = parseInt(bParts[i], 10);
 
3607
 
 
3608
        /*jshint expr: true*/
 
3609
        isNaN(aPart) && (aPart = 0);
 
3610
        isNaN(bPart) && (bPart = 0);
 
3611
 
 
3612
        if (aPart < bPart) {
 
3613
            return -1;
 
3614
        }
 
3615
 
 
3616
        if (aPart > bPart) {
 
3617
            return 1;
 
3618
        }
 
3619
    }
 
3620
 
 
3621
    return 0;
 
3622
};
 
3623
YUI.Env.aliases = {
 
3624
    "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
 
3625
    "anim-shape-transform": ["anim-shape"],
 
3626
    "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","router","view","view-node-map"],
 
3627
    "attribute": ["attribute-base","attribute-complex"],
 
3628
    "attribute-events": ["attribute-observable"],
 
3629
    "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
 
3630
    "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
 
3631
    "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
 
3632
    "base": ["base-base","base-pluginhost","base-build"],
 
3633
    "cache": ["cache-base","cache-offline","cache-plugin"],
 
3634
    "charts": ["charts-base"],
 
3635
    "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
 
3636
    "color": ["color-base","color-hsl","color-harmony"],
 
3637
    "controller": ["router"],
 
3638
    "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
 
3639
    "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
 
3640
    "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
 
3641
    "datatype": ["datatype-date","datatype-number","datatype-xml"],
 
3642
    "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
 
3643
    "datatype-number": ["datatype-number-parse","datatype-number-format"],
 
3644
    "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
 
3645
    "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
 
3646
    "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
 
3647
    "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
 
3648
    "event": ["event-base","event-delegate","event-synthetic","event-mousewheel","event-mouseenter","event-key","event-focus","event-resize","event-hover","event-outside","event-touch","event-move","event-flick","event-valuechange","event-tap"],
 
3649
    "event-custom": ["event-custom-base","event-custom-complex"],
 
3650
    "event-gestures": ["event-flick","event-move"],
 
3651
    "handlebars": ["handlebars-compiler"],
 
3652
    "highlight": ["highlight-base","highlight-accentfold"],
 
3653
    "history": ["history-base","history-hash","history-hash-ie","history-html5"],
 
3654
    "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
 
3655
    "json": ["json-parse","json-stringify"],
 
3656
    "loader": ["loader-base","loader-rollup","loader-yui3"],
 
3657
    "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
 
3658
    "pluginhost": ["pluginhost-base","pluginhost-config"],
 
3659
    "querystring": ["querystring-parse","querystring-stringify"],
 
3660
    "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
 
3661
    "resize": ["resize-base","resize-proxy","resize-constrain"],
 
3662
    "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
 
3663
    "template": ["template-base","template-micro"],
 
3664
    "text": ["text-accentfold","text-wordbreak"],
 
3665
    "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
 
3666
};
 
3667
 
 
3668
 
 
3669
}, '3.10.3', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});
 
3670
YUI.add('get', function (Y, NAME) {
 
3671
 
 
3672
/*jslint boss:true, expr:true, laxbreak: true */
 
3673
 
 
3674
/**
 
3675
Provides dynamic loading of remote JavaScript and CSS resources.
 
3676
 
 
3677
@module get
 
3678
@class Get
 
3679
@static
 
3680
**/
 
3681
 
 
3682
var Lang = Y.Lang,
 
3683
 
 
3684
    CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
 
3685
 
 
3686
    Get, Transaction;
 
3687
 
 
3688
Y.Get = Get = {
 
3689
    // -- Public Properties ----------------------------------------------------
 
3690
 
 
3691
    /**
 
3692
    Default options for CSS requests. Options specified here will override
 
3693
    global defaults for CSS requests.
 
3694
 
 
3695
    See the `options` property for all available options.
 
3696
 
 
3697
    @property cssOptions
 
3698
    @type Object
 
3699
    @static
 
3700
    @since 3.5.0
 
3701
    **/
 
3702
    cssOptions: {
 
3703
        attributes: {
 
3704
            rel: 'stylesheet'
 
3705
        },
 
3706
 
 
3707
        doc         : Y.config.linkDoc || Y.config.doc,
 
3708
        pollInterval: 50
 
3709
    },
 
3710
 
 
3711
    /**
 
3712
    Default options for JS requests. Options specified here will override global
 
3713
    defaults for JS requests.
 
3714
 
 
3715
    See the `options` property for all available options.
 
3716
 
 
3717
    @property jsOptions
 
3718
    @type Object
 
3719
    @static
 
3720
    @since 3.5.0
 
3721
    **/
 
3722
    jsOptions: {
 
3723
        autopurge: true,
 
3724
        doc      : Y.config.scriptDoc || Y.config.doc
 
3725
    },
 
3726
 
 
3727
    /**
 
3728
    Default options to use for all requests.
 
3729
 
 
3730
    Note that while all available options are documented here for ease of
 
3731
    discovery, some options (like callback functions) only make sense at the
 
3732
    transaction level.
 
3733
 
 
3734
    Callback functions specified via the options object or the `options`
 
3735
    parameter of the `css()`, `js()`, or `load()` methods will receive the
 
3736
    transaction object as a parameter. See `Y.Get.Transaction` for details on
 
3737
    the properties and methods available on transactions.
 
3738
 
 
3739
    @static
 
3740
    @since 3.5.0
 
3741
    @property {Object} options
 
3742
 
 
3743
    @property {Boolean} [options.async=false] Whether or not to load scripts
 
3744
        asynchronously, meaning they're requested in parallel and execution
 
3745
        order is not guaranteed. Has no effect on CSS, since CSS is always
 
3746
        loaded asynchronously.
 
3747
 
 
3748
    @property {Object} [options.attributes] HTML attribute name/value pairs that
 
3749
        should be added to inserted nodes. By default, the `charset` attribute
 
3750
        will be set to "utf-8" and nodes will be given an auto-generated `id`
 
3751
        attribute, but you can override these with your own values if desired.
 
3752
 
 
3753
    @property {Boolean} [options.autopurge] Whether or not to automatically
 
3754
        purge inserted nodes after the purge threshold is reached. This is
 
3755
        `true` by default for JavaScript, but `false` for CSS since purging a
 
3756
        CSS node will also remove any styling applied by the referenced file.
 
3757
 
 
3758
    @property {Object} [options.context] `this` object to use when calling
 
3759
        callback functions. Defaults to the transaction object.
 
3760
 
 
3761
    @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
 
3762
        callbacks.
 
3763
 
 
3764
    @property {Document} [options.doc] Document into which nodes should be
 
3765
        inserted. By default, the current document is used.
 
3766
 
 
3767
    @property {HTMLElement|String} [options.insertBefore] HTML element or id
 
3768
        string of an element before which all generated nodes should be
 
3769
        inserted. If not specified, Get will automatically determine the best
 
3770
        place to insert nodes for maximum compatibility.
 
3771
 
 
3772
    @property {Function} [options.onEnd] Callback to execute after a transaction
 
3773
        is complete, regardless of whether it succeeded or failed.
 
3774
 
 
3775
    @property {Function} [options.onFailure] Callback to execute after a
 
3776
        transaction fails, times out, or is aborted.
 
3777
 
 
3778
    @property {Function} [options.onProgress] Callback to execute after each
 
3779
        individual request in a transaction either succeeds or fails.
 
3780
 
 
3781
    @property {Function} [options.onSuccess] Callback to execute after a
 
3782
        transaction completes successfully with no errors. Note that in browsers
 
3783
        that don't support the `error` event on CSS `<link>` nodes, a failed CSS
 
3784
        request may still be reported as a success because in these browsers
 
3785
        it can be difficult or impossible to distinguish between success and
 
3786
        failure for CSS resources.
 
3787
 
 
3788
    @property {Function} [options.onTimeout] Callback to execute after a
 
3789
        transaction times out.
 
3790
 
 
3791
    @property {Number} [options.pollInterval=50] Polling interval (in
 
3792
        milliseconds) for detecting CSS load completion in browsers that don't
 
3793
        support the `load` event on `<link>` nodes. This isn't used for
 
3794
        JavaScript.
 
3795
 
 
3796
    @property {Number} [options.purgethreshold=20] Number of nodes to insert
 
3797
        before triggering an automatic purge when `autopurge` is `true`.
 
3798
 
 
3799
    @property {Number} [options.timeout] Number of milliseconds to wait before
 
3800
        aborting a transaction. When a timeout occurs, the `onTimeout` callback
 
3801
        is called, followed by `onFailure` and finally `onEnd`. By default,
 
3802
        there is no timeout.
 
3803
 
 
3804
    @property {String} [options.type] Resource type ("css" or "js"). This option
 
3805
        is set automatically by the `css()` and `js()` functions and will be
 
3806
        ignored there, but may be useful when using the `load()` function. If
 
3807
        not specified, the type will be inferred from the URL, defaulting to
 
3808
        "js" if the URL doesn't contain a recognizable file extension.
 
3809
    **/
 
3810
    options: {
 
3811
        attributes: {
 
3812
            charset: 'utf-8'
 
3813
        },
 
3814
 
 
3815
        purgethreshold: 20
 
3816
    },
 
3817
 
 
3818
    // -- Protected Properties -------------------------------------------------
 
3819
 
 
3820
    /**
 
3821
    Regex that matches a CSS URL. Used to guess the file type when it's not
 
3822
    specified.
 
3823
 
 
3824
    @property REGEX_CSS
 
3825
    @type RegExp
 
3826
    @final
 
3827
    @protected
 
3828
    @static
 
3829
    @since 3.5.0
 
3830
    **/
 
3831
    REGEX_CSS: /\.css(?:[?;].*)?$/i,
 
3832
 
 
3833
    /**
 
3834
    Regex that matches a JS URL. Used to guess the file type when it's not
 
3835
    specified.
 
3836
 
 
3837
    @property REGEX_JS
 
3838
    @type RegExp
 
3839
    @final
 
3840
    @protected
 
3841
    @static
 
3842
    @since 3.5.0
 
3843
    **/
 
3844
    REGEX_JS : /\.js(?:[?;].*)?$/i,
 
3845
 
 
3846
    /**
 
3847
    Contains information about the current environment, such as what script and
 
3848
    link injection features it supports.
 
3849
 
 
3850
    This object is created and populated the first time the `_getEnv()` method
 
3851
    is called.
 
3852
 
 
3853
    @property _env
 
3854
    @type Object
 
3855
    @protected
 
3856
    @static
 
3857
    @since 3.5.0
 
3858
    **/
 
3859
 
 
3860
    /**
 
3861
    Mapping of document _yuid strings to <head> or <base> node references so we
 
3862
    don't have to look the node up each time we want to insert a request node.
 
3863
 
 
3864
    @property _insertCache
 
3865
    @type Object
 
3866
    @protected
 
3867
    @static
 
3868
    @since 3.5.0
 
3869
    **/
 
3870
    _insertCache: {},
 
3871
 
 
3872
    /**
 
3873
    Information about the currently pending transaction, if any.
 
3874
 
 
3875
    This is actually an object with two properties: `callback`, containing the
 
3876
    optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
 
3877
    containing the actual transaction instance.
 
3878
 
 
3879
    @property _pending
 
3880
    @type Object
 
3881
    @protected
 
3882
    @static
 
3883
    @since 3.5.0
 
3884
    **/
 
3885
    _pending: null,
 
3886
 
 
3887
    /**
 
3888
    HTML nodes eligible to be purged next time autopurge is triggered.
 
3889
 
 
3890
    @property _purgeNodes
 
3891
    @type HTMLElement[]
 
3892
    @protected
 
3893
    @static
 
3894
    @since 3.5.0
 
3895
    **/
 
3896
    _purgeNodes: [],
 
3897
 
 
3898
    /**
 
3899
    Queued transactions and associated callbacks.
 
3900
 
 
3901
    @property _queue
 
3902
    @type Object[]
 
3903
    @protected
 
3904
    @static
 
3905
    @since 3.5.0
 
3906
    **/
 
3907
    _queue: [],
 
3908
 
 
3909
    // -- Public Methods -------------------------------------------------------
 
3910
 
 
3911
    /**
 
3912
    Aborts the specified transaction.
 
3913
 
 
3914
    This will cause the transaction's `onFailure` callback to be called and
 
3915
    will prevent any new script and link nodes from being added to the document,
 
3916
    but any resources that have already been requested will continue loading
 
3917
    (there's no safe way to prevent this, unfortunately).
 
3918
 
 
3919
    *Note:* This method is deprecated as of 3.5.0, and will be removed in a
 
3920
    future version of YUI. Use the transaction-level `abort()` method instead.
 
3921
 
 
3922
    @method abort
 
3923
    @param {Get.Transaction} transaction Transaction to abort.
 
3924
    @deprecated Use the `abort()` method on the transaction instead.
 
3925
    @static
 
3926
    **/
 
3927
    abort: function (transaction) {
 
3928
        var i, id, item, len, pending;
 
3929
 
 
3930
 
 
3931
        if (!transaction.abort) {
 
3932
            id          = transaction;
 
3933
            pending     = this._pending;
 
3934
            transaction = null;
 
3935
 
 
3936
            if (pending && pending.transaction.id === id) {
 
3937
                transaction   = pending.transaction;
 
3938
                this._pending = null;
 
3939
            } else {
 
3940
                for (i = 0, len = this._queue.length; i < len; ++i) {
 
3941
                    item = this._queue[i].transaction;
 
3942
 
 
3943
                    if (item.id === id) {
 
3944
                        transaction = item;
 
3945
                        this._queue.splice(i, 1);
 
3946
                        break;
 
3947
                    }
 
3948
                }
 
3949
            }
 
3950
        }
 
3951
 
 
3952
        transaction && transaction.abort();
 
3953
    },
 
3954
 
 
3955
    /**
 
3956
    Loads one or more CSS files.
 
3957
 
 
3958
    The _urls_ parameter may be provided as a URL string, a request object,
 
3959
    or an array of URL strings and/or request objects.
 
3960
 
 
3961
    A request object is just an object that contains a `url` property and zero
 
3962
    or more options that should apply specifically to that request.
 
3963
    Request-specific options take priority over transaction-level options and
 
3964
    default options.
 
3965
 
 
3966
    URLs may be relative or absolute, and do not have to have the same origin
 
3967
    as the current page.
 
3968
 
 
3969
    The `options` parameter may be omitted completely and a callback passed in
 
3970
    its place, if desired.
 
3971
 
 
3972
    @example
 
3973
 
 
3974
        // Load a single CSS file and log a message on completion.
 
3975
        Y.Get.css('foo.css', function (err) {
 
3976
            if (err) {
 
3977
            } else {
 
3978
            }
 
3979
        });
 
3980
 
 
3981
        // Load multiple CSS files and log a message when all have finished
 
3982
        // loading.
 
3983
        var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
 
3984
 
 
3985
        Y.Get.css(urls, function (err) {
 
3986
            if (err) {
 
3987
            } else {
 
3988
            }
 
3989
        });
 
3990
 
 
3991
        // Specify transaction-level options, which will apply to all requests
 
3992
        // within the transaction.
 
3993
        Y.Get.css(urls, {
 
3994
            attributes: {'class': 'my-css'},
 
3995
            timeout   : 5000
 
3996
        });
 
3997
 
 
3998
        // Specify per-request options, which override transaction-level and
 
3999
        // default options.
 
4000
        Y.Get.css([
 
4001
            {url: 'foo.css', attributes: {id: 'foo'}},
 
4002
            {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
 
4003
        ]);
 
4004
 
 
4005
    @method css
 
4006
    @param {String|Object|Array} urls URL string, request object, or array
 
4007
        of URLs and/or request objects to load.
 
4008
    @param {Object} [options] Options for this transaction. See the
 
4009
        `Y.Get.options` property for a complete list of available options.
 
4010
    @param {Function} [callback] Callback function to be called on completion.
 
4011
        This is a general callback and will be called before any more granular
 
4012
        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
 
4013
        object.
 
4014
 
 
4015
        @param {Array|null} callback.err Array of errors that occurred during
 
4016
            the transaction, or `null` on success.
 
4017
        @param {Get.Transaction} callback.transaction Transaction object.
 
4018
 
 
4019
    @return {Get.Transaction} Transaction object.
 
4020
    @static
 
4021
    **/
 
4022
    css: function (urls, options, callback) {
 
4023
        return this._load('css', urls, options, callback);
 
4024
    },
 
4025
 
 
4026
    /**
 
4027
    Loads one or more JavaScript resources.
 
4028
 
 
4029
    The _urls_ parameter may be provided as a URL string, a request object,
 
4030
    or an array of URL strings and/or request objects.
 
4031
 
 
4032
    A request object is just an object that contains a `url` property and zero
 
4033
    or more options that should apply specifically to that request.
 
4034
    Request-specific options take priority over transaction-level options and
 
4035
    default options.
 
4036
 
 
4037
    URLs may be relative or absolute, and do not have to have the same origin
 
4038
    as the current page.
 
4039
 
 
4040
    The `options` parameter may be omitted completely and a callback passed in
 
4041
    its place, if desired.
 
4042
 
 
4043
    Scripts will be executed in the order they're specified unless the `async`
 
4044
    option is `true`, in which case they'll be loaded in parallel and executed
 
4045
    in whatever order they finish loading.
 
4046
 
 
4047
    @example
 
4048
 
 
4049
        // Load a single JS file and log a message on completion.
 
4050
        Y.Get.js('foo.js', function (err) {
 
4051
            if (err) {
 
4052
            } else {
 
4053
            }
 
4054
        });
 
4055
 
 
4056
        // Load multiple JS files, execute them in order, and log a message when
 
4057
        // all have finished loading.
 
4058
        var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
 
4059
 
 
4060
        Y.Get.js(urls, function (err) {
 
4061
            if (err) {
 
4062
            } else {
 
4063
            }
 
4064
        });
 
4065
 
 
4066
        // Specify transaction-level options, which will apply to all requests
 
4067
        // within the transaction.
 
4068
        Y.Get.js(urls, {
 
4069
            attributes: {'class': 'my-js'},
 
4070
            timeout   : 5000
 
4071
        });
 
4072
 
 
4073
        // Specify per-request options, which override transaction-level and
 
4074
        // default options.
 
4075
        Y.Get.js([
 
4076
            {url: 'foo.js', attributes: {id: 'foo'}},
 
4077
            {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
 
4078
        ]);
 
4079
 
 
4080
    @method js
 
4081
    @param {String|Object|Array} urls URL string, request object, or array
 
4082
        of URLs and/or request objects to load.
 
4083
    @param {Object} [options] Options for this transaction. See the
 
4084
        `Y.Get.options` property for a complete list of available options.
 
4085
    @param {Function} [callback] Callback function to be called on completion.
 
4086
        This is a general callback and will be called before any more granular
 
4087
        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
 
4088
        object.
 
4089
 
 
4090
        @param {Array|null} callback.err Array of errors that occurred during
 
4091
            the transaction, or `null` on success.
 
4092
        @param {Get.Transaction} callback.transaction Transaction object.
 
4093
 
 
4094
    @return {Get.Transaction} Transaction object.
 
4095
    @since 3.5.0
 
4096
    @static
 
4097
    **/
 
4098
    js: function (urls, options, callback) {
 
4099
        return this._load('js', urls, options, callback);
 
4100
    },
 
4101
 
 
4102
    /**
 
4103
    Loads one or more CSS and/or JavaScript resources in the same transaction.
 
4104
 
 
4105
    Use this method when you want to load both CSS and JavaScript in a single
 
4106
    transaction and be notified when all requested URLs have finished loading,
 
4107
    regardless of type.
 
4108
 
 
4109
    Behavior and options are the same as for the `css()` and `js()` methods. If
 
4110
    a resource type isn't specified in per-request options or transaction-level
 
4111
    options, Get will guess the file type based on the URL's extension (`.css`
 
4112
    or `.js`, with or without a following query string). If the file type can't
 
4113
    be guessed from the URL, a warning will be logged and Get will assume the
 
4114
    URL is a JavaScript resource.
 
4115
 
 
4116
    @example
 
4117
 
 
4118
        // Load both CSS and JS files in a single transaction, and log a message
 
4119
        // when all files have finished loading.
 
4120
        Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
 
4121
            if (err) {
 
4122
            } else {
 
4123
            }
 
4124
        });
 
4125
 
 
4126
    @method load
 
4127
    @param {String|Object|Array} urls URL string, request object, or array
 
4128
        of URLs and/or request objects to load.
 
4129
    @param {Object} [options] Options for this transaction. See the
 
4130
        `Y.Get.options` property for a complete list of available options.
 
4131
    @param {Function} [callback] Callback function to be called on completion.
 
4132
        This is a general callback and will be called before any more granular
 
4133
        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
 
4134
        object.
 
4135
 
 
4136
        @param {Array|null} err Array of errors that occurred during the
 
4137
            transaction, or `null` on success.
 
4138
        @param {Get.Transaction} Transaction object.
 
4139
 
 
4140
    @return {Get.Transaction} Transaction object.
 
4141
    @since 3.5.0
 
4142
    @static
 
4143
    **/
 
4144
    load: function (urls, options, callback) {
 
4145
        return this._load(null, urls, options, callback);
 
4146
    },
 
4147
 
 
4148
    // -- Protected Methods ----------------------------------------------------
 
4149
 
 
4150
    /**
 
4151
    Triggers an automatic purge if the purge threshold has been reached.
 
4152
 
 
4153
    @method _autoPurge
 
4154
    @param {Number} threshold Purge threshold to use, in milliseconds.
 
4155
    @protected
 
4156
    @since 3.5.0
 
4157
    @static
 
4158
    **/
 
4159
    _autoPurge: function (threshold) {
 
4160
        if (threshold && this._purgeNodes.length >= threshold) {
 
4161
            this._purge(this._purgeNodes);
 
4162
        }
 
4163
    },
 
4164
 
 
4165
    /**
 
4166
    Populates the `_env` property with information about the current
 
4167
    environment.
 
4168
 
 
4169
    @method _getEnv
 
4170
    @return {Object} Environment information.
 
4171
    @protected
 
4172
    @since 3.5.0
 
4173
    @static
 
4174
    **/
 
4175
    _getEnv: function () {
 
4176
        var doc = Y.config.doc,
 
4177
            ua  = Y.UA;
 
4178
 
 
4179
        // Note: some of these checks require browser sniffs since it's not
 
4180
        // feasible to load test files on every pageview just to perform a
 
4181
        // feature test. I'm sorry if this makes you sad.
 
4182
        return (this._env = {
 
4183
 
 
4184
            // True if this is a browser that supports disabling async mode on
 
4185
            // dynamically created script nodes. See
 
4186
            // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
 
4187
 
 
4188
            // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
 
4189
            // because it is async by default, and allows you to disable async by setting it to false
 
4190
            async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
 
4191
 
 
4192
            // True if this browser fires an event when a dynamically injected
 
4193
            // link node fails to load. This is currently true for Firefox 9+
 
4194
            // and WebKit 535.24+
 
4195
            cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
 
4196
 
 
4197
            // True if this browser fires an event when a dynamically injected
 
4198
            // link node finishes loading. This is currently true for IE, Opera,
 
4199
            // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
 
4200
            // DOM 0 "onload" event, but not "load". All versions of IE fire
 
4201
            // "onload".
 
4202
            // davglass: Seems that Chrome on Android needs this to be false.
 
4203
            cssLoad: (
 
4204
                    (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
 
4205
                    ua.compareVersions(ua.webkit, 535.24) >= 0
 
4206
                ) && !(ua.chrome && ua.chrome <= 18),
 
4207
 
 
4208
            // True if this browser preserves script execution order while
 
4209
            // loading scripts in parallel as long as the script node's `async`
 
4210
            // attribute is set to false to explicitly disable async execution.
 
4211
            preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
 
4212
        });
 
4213
    },
 
4214
 
 
4215
    _getTransaction: function (urls, options) {
 
4216
        var requests = [],
 
4217
            i, len, req, url;
 
4218
 
 
4219
        if (!Lang.isArray(urls)) {
 
4220
            urls = [urls];
 
4221
        }
 
4222
 
 
4223
        options = Y.merge(this.options, options);
 
4224
 
 
4225
        // Clone the attributes object so we don't end up modifying it by ref.
 
4226
        options.attributes = Y.merge(this.options.attributes,
 
4227
                options.attributes);
 
4228
 
 
4229
        for (i = 0, len = urls.length; i < len; ++i) {
 
4230
            url = urls[i];
 
4231
            req = {attributes: {}};
 
4232
 
 
4233
            // If `url` is a string, we create a URL object for it, then mix in
 
4234
            // global options and request-specific options. If it's an object
 
4235
            // with a "url" property, we assume it's a request object containing
 
4236
            // URL-specific options.
 
4237
            if (typeof url === 'string') {
 
4238
                req.url = url;
 
4239
            } else if (url.url) {
 
4240
                // URL-specific options override both global defaults and
 
4241
                // request-specific options.
 
4242
                Y.mix(req, url, false, null, 0, true);
 
4243
                url = url.url; // Make url a string so we can use it later.
 
4244
            } else {
 
4245
                continue;
 
4246
            }
 
4247
 
 
4248
            Y.mix(req, options, false, null, 0, true);
 
4249
 
 
4250
            // If we didn't get an explicit type for this URL either in the
 
4251
            // request options or the URL-specific options, try to determine
 
4252
            // one from the file extension.
 
4253
            if (!req.type) {
 
4254
                if (this.REGEX_CSS.test(url)) {
 
4255
                    req.type = 'css';
 
4256
                } else {
 
4257
                    if (!this.REGEX_JS.test(url)) {
 
4258
                    }
 
4259
 
 
4260
                    req.type = 'js';
 
4261
                }
 
4262
            }
 
4263
 
 
4264
            // Mix in type-specific default options, but don't overwrite any
 
4265
            // options that have already been set.
 
4266
            Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
 
4267
                false, null, 0, true);
 
4268
 
 
4269
            // Give the node an id attribute if it doesn't already have one.
 
4270
            req.attributes.id || (req.attributes.id = Y.guid());
 
4271
 
 
4272
            // Backcompat for <3.5.0 behavior.
 
4273
            if (req.win) {
 
4274
                req.doc = req.win.document;
 
4275
            } else {
 
4276
                req.win = req.doc.defaultView || req.doc.parentWindow;
 
4277
            }
 
4278
 
 
4279
            if (req.charset) {
 
4280
                req.attributes.charset = req.charset;
 
4281
            }
 
4282
 
 
4283
            requests.push(req);
 
4284
        }
 
4285
 
 
4286
        return new Transaction(requests, options);
 
4287
    },
 
4288
 
 
4289
    _load: function (type, urls, options, callback) {
 
4290
        var transaction;
 
4291
 
 
4292
        // Allow callback as third param.
 
4293
        if (typeof options === 'function') {
 
4294
            callback = options;
 
4295
            options  = {};
 
4296
        }
 
4297
 
 
4298
        options || (options = {});
 
4299
        options.type = type;
 
4300
 
 
4301
        options._onFinish = Get._onTransactionFinish;
 
4302
 
 
4303
        if (!this._env) {
 
4304
            this._getEnv();
 
4305
        }
 
4306
 
 
4307
        transaction = this._getTransaction(urls, options);
 
4308
 
 
4309
        this._queue.push({
 
4310
            callback   : callback,
 
4311
            transaction: transaction
 
4312
        });
 
4313
 
 
4314
        this._next();
 
4315
 
 
4316
        return transaction;
 
4317
    },
 
4318
 
 
4319
    _onTransactionFinish : function() {
 
4320
        Get._pending = null;
 
4321
        Get._next();
 
4322
    },
 
4323
 
 
4324
    _next: function () {
 
4325
        var item;
 
4326
 
 
4327
        if (this._pending) {
 
4328
            return;
 
4329
        }
 
4330
 
 
4331
        item = this._queue.shift();
 
4332
 
 
4333
        if (item) {
 
4334
            this._pending = item;
 
4335
            item.transaction.execute(item.callback);
 
4336
        }
 
4337
    },
 
4338
 
 
4339
    _purge: function (nodes) {
 
4340
        var purgeNodes    = this._purgeNodes,
 
4341
            isTransaction = nodes !== purgeNodes,
 
4342
            index, node;
 
4343
 
 
4344
        while (node = nodes.pop()) { // assignment
 
4345
            // Don't purge nodes that haven't finished loading (or errored out),
 
4346
            // since this can hang the transaction.
 
4347
            if (!node._yuiget_finished) {
 
4348
                continue;
 
4349
            }
 
4350
 
 
4351
            node.parentNode && node.parentNode.removeChild(node);
 
4352
 
 
4353
            // If this is a transaction-level purge and this node also exists in
 
4354
            // the Get-level _purgeNodes array, we need to remove it from
 
4355
            // _purgeNodes to avoid creating a memory leak. The indexOf lookup
 
4356
            // sucks, but until we get WeakMaps, this is the least troublesome
 
4357
            // way to do this (we can't just hold onto node ids because they may
 
4358
            // not be in the same document).
 
4359
            if (isTransaction) {
 
4360
                index = Y.Array.indexOf(purgeNodes, node);
 
4361
 
 
4362
                if (index > -1) {
 
4363
                    purgeNodes.splice(index, 1);
 
4364
                }
 
4365
            }
 
4366
        }
 
4367
    }
 
4368
};
 
4369
 
 
4370
/**
 
4371
Alias for `js()`.
 
4372
 
 
4373
@method script
 
4374
@static
 
4375
**/
 
4376
Get.script = Get.js;
 
4377
 
 
4378
/**
 
4379
Represents a Get transaction, which may contain requests for one or more JS or
 
4380
CSS files.
 
4381
 
 
4382
This class should not be instantiated manually. Instances will be created and
 
4383
returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
 
4384
 
 
4385
@class Get.Transaction
 
4386
@constructor
 
4387
@since 3.5.0
 
4388
**/
 
4389
Get.Transaction = Transaction = function (requests, options) {
 
4390
    var self = this;
 
4391
 
 
4392
    self.id       = Transaction._lastId += 1;
 
4393
    self.data     = options.data;
 
4394
    self.errors   = [];
 
4395
    self.nodes    = [];
 
4396
    self.options  = options;
 
4397
    self.requests = requests;
 
4398
 
 
4399
    self._callbacks = []; // callbacks to call after execution finishes
 
4400
    self._queue     = [];
 
4401
    self._reqsWaiting   = 0;
 
4402
 
 
4403
    // Deprecated pre-3.5.0 properties.
 
4404
    self.tId = self.id; // Use `id` instead.
 
4405
    self.win = options.win || Y.config.win;
 
4406
};
 
4407
 
 
4408
/**
 
4409
Arbitrary data object associated with this transaction.
 
4410
 
 
4411
This object comes from the options passed to `Get.css()`, `Get.js()`, or
 
4412
`Get.load()`, and will be `undefined` if no data object was specified.
 
4413
 
 
4414
@property {Object} data
 
4415
**/
 
4416
 
 
4417
/**
 
4418
Array of errors that have occurred during this transaction, if any.
 
4419
 
 
4420
@since 3.5.0
 
4421
@property {Object[]} errors
 
4422
@property {String} errors.error Error message.
 
4423
@property {Object} errors.request Request object related to the error.
 
4424
**/
 
4425
 
 
4426
/**
 
4427
Numeric id for this transaction, unique among all transactions within the same
 
4428
YUI sandbox in the current pageview.
 
4429
 
 
4430
@property {Number} id
 
4431
@since 3.5.0
 
4432
**/
 
4433
 
 
4434
/**
 
4435
HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
 
4436
during the current transaction.
 
4437
 
 
4438
@property {HTMLElement[]} nodes
 
4439
**/
 
4440
 
 
4441
/**
 
4442
Options associated with this transaction.
 
4443
 
 
4444
See `Get.options` for the full list of available options.
 
4445
 
 
4446
@property {Object} options
 
4447
@since 3.5.0
 
4448
**/
 
4449
 
 
4450
/**
 
4451
Request objects contained in this transaction. Each request object represents
 
4452
one CSS or JS URL that will be (or has been) requested and loaded into the page.
 
4453
 
 
4454
@property {Object} requests
 
4455
@since 3.5.0
 
4456
**/
 
4457
 
 
4458
/**
 
4459
Id of the most recent transaction.
 
4460
 
 
4461
@property _lastId
 
4462
@type Number
 
4463
@protected
 
4464
@static
 
4465
**/
 
4466
Transaction._lastId = 0;
 
4467
 
 
4468
Transaction.prototype = {
 
4469
    // -- Public Properties ----------------------------------------------------
 
4470
 
 
4471
    /**
 
4472
    Current state of this transaction. One of "new", "executing", or "done".
 
4473
 
 
4474
    @property _state
 
4475
    @type String
 
4476
    @protected
 
4477
    **/
 
4478
    _state: 'new', // "new", "executing", or "done"
 
4479
 
 
4480
    // -- Public Methods -------------------------------------------------------
 
4481
 
 
4482
    /**
 
4483
    Aborts this transaction.
 
4484
 
 
4485
    This will cause the transaction's `onFailure` callback to be called and
 
4486
    will prevent any new script and link nodes from being added to the document,
 
4487
    but any resources that have already been requested will continue loading
 
4488
    (there's no safe way to prevent this, unfortunately).
 
4489
 
 
4490
    @method abort
 
4491
    @param {String} [msg="Aborted."] Optional message to use in the `errors`
 
4492
        array describing why the transaction was aborted.
 
4493
    **/
 
4494
    abort: function (msg) {
 
4495
        this._pending    = null;
 
4496
        this._pendingCSS = null;
 
4497
        this._pollTimer  = clearTimeout(this._pollTimer);
 
4498
        this._queue      = [];
 
4499
        this._reqsWaiting    = 0;
 
4500
 
 
4501
        this.errors.push({error: msg || 'Aborted'});
 
4502
        this._finish();
 
4503
    },
 
4504
 
 
4505
    /**
 
4506
    Begins execting the transaction.
 
4507
 
 
4508
    There's usually no reason to call this manually, since Get will call it
 
4509
    automatically when other pending transactions have finished. If you really
 
4510
    want to execute your transaction before Get does, you can, but be aware that
 
4511
    this transaction's scripts may end up executing before the scripts in other
 
4512
    pending transactions.
 
4513
 
 
4514
    If the transaction is already executing, the specified callback (if any)
 
4515
    will be queued and called after execution finishes. If the transaction has
 
4516
    already finished, the callback will be called immediately (the transaction
 
4517
    will not be executed again).
 
4518
 
 
4519
    @method execute
 
4520
    @param {Function} callback Callback function to execute after all requests
 
4521
        in the transaction are complete, or after the transaction is aborted.
 
4522
    **/
 
4523
    execute: function (callback) {
 
4524
        var self     = this,
 
4525
            requests = self.requests,
 
4526
            state    = self._state,
 
4527
            i, len, queue, req;
 
4528
 
 
4529
        if (state === 'done') {
 
4530
            callback && callback(self.errors.length ? self.errors : null, self);
 
4531
            return;
 
4532
        } else {
 
4533
            callback && self._callbacks.push(callback);
 
4534
 
 
4535
            if (state === 'executing') {
 
4536
                return;
 
4537
            }
 
4538
        }
 
4539
 
 
4540
        self._state = 'executing';
 
4541
        self._queue = queue = [];
 
4542
 
 
4543
        if (self.options.timeout) {
 
4544
            self._timeout = setTimeout(function () {
 
4545
                self.abort('Timeout');
 
4546
            }, self.options.timeout);
 
4547
        }
 
4548
 
 
4549
        self._reqsWaiting = requests.length;
 
4550
 
 
4551
        for (i = 0, len = requests.length; i < len; ++i) {
 
4552
            req = requests[i];
 
4553
 
 
4554
            if (req.async || req.type === 'css') {
 
4555
                // No need to queue CSS or fully async JS.
 
4556
                self._insert(req);
 
4557
            } else {
 
4558
                queue.push(req);
 
4559
            }
 
4560
        }
 
4561
 
 
4562
        self._next();
 
4563
    },
 
4564
 
 
4565
    /**
 
4566
    Manually purges any `<script>` or `<link>` nodes this transaction has
 
4567
    created.
 
4568
 
 
4569
    Be careful when purging a transaction that contains CSS requests, since
 
4570
    removing `<link>` nodes will also remove any styles they applied.
 
4571
 
 
4572
    @method purge
 
4573
    **/
 
4574
    purge: function () {
 
4575
        Get._purge(this.nodes);
 
4576
    },
 
4577
 
 
4578
    // -- Protected Methods ----------------------------------------------------
 
4579
    _createNode: function (name, attrs, doc) {
 
4580
        var node = doc.createElement(name),
 
4581
            attr, testEl;
 
4582
 
 
4583
        if (!CUSTOM_ATTRS) {
 
4584
            // IE6 and IE7 expect property names rather than attribute names for
 
4585
            // certain attributes. Rather than sniffing, we do a quick feature
 
4586
            // test the first time _createNode() runs to determine whether we
 
4587
            // need to provide a workaround.
 
4588
            testEl = doc.createElement('div');
 
4589
            testEl.setAttribute('class', 'a');
 
4590
 
 
4591
            CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
 
4592
                'for'  : 'htmlFor',
 
4593
                'class': 'className'
 
4594
            };
 
4595
        }
 
4596
 
 
4597
        for (attr in attrs) {
 
4598
            if (attrs.hasOwnProperty(attr)) {
 
4599
                node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
 
4600
            }
 
4601
        }
 
4602
 
 
4603
        return node;
 
4604
    },
 
4605
 
 
4606
    _finish: function () {
 
4607
        var errors  = this.errors.length ? this.errors : null,
 
4608
            options = this.options,
 
4609
            thisObj = options.context || this,
 
4610
            data, i, len;
 
4611
 
 
4612
        if (this._state === 'done') {
 
4613
            return;
 
4614
        }
 
4615
 
 
4616
        this._state = 'done';
 
4617
 
 
4618
        for (i = 0, len = this._callbacks.length; i < len; ++i) {
 
4619
            this._callbacks[i].call(thisObj, errors, this);
 
4620
        }
 
4621
 
 
4622
        data = this._getEventData();
 
4623
 
 
4624
        if (errors) {
 
4625
            if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
 
4626
                options.onTimeout.call(thisObj, data);
 
4627
            }
 
4628
 
 
4629
            if (options.onFailure) {
 
4630
                options.onFailure.call(thisObj, data);
 
4631
            }
 
4632
        } else if (options.onSuccess) {
 
4633
            options.onSuccess.call(thisObj, data);
 
4634
        }
 
4635
 
 
4636
        if (options.onEnd) {
 
4637
            options.onEnd.call(thisObj, data);
 
4638
        }
 
4639
 
 
4640
        if (options._onFinish) {
 
4641
            options._onFinish();
 
4642
        }
 
4643
    },
 
4644
 
 
4645
    _getEventData: function (req) {
 
4646
        if (req) {
 
4647
            // This merge is necessary for backcompat. I hate it.
 
4648
            return Y.merge(this, {
 
4649
                abort  : this.abort, // have to copy these because the prototype isn't preserved
 
4650
                purge  : this.purge,
 
4651
                request: req,
 
4652
                url    : req.url,
 
4653
                win    : req.win
 
4654
            });
 
4655
        } else {
 
4656
            return this;
 
4657
        }
 
4658
    },
 
4659
 
 
4660
    _getInsertBefore: function (req) {
 
4661
        var doc = req.doc,
 
4662
            el  = req.insertBefore,
 
4663
            cache, docStamp;
 
4664
 
 
4665
        if (el) {
 
4666
            return typeof el === 'string' ? doc.getElementById(el) : el;
 
4667
        }
 
4668
 
 
4669
        cache    = Get._insertCache;
 
4670
        docStamp = Y.stamp(doc);
 
4671
 
 
4672
        if ((el = cache[docStamp])) { // assignment
 
4673
            return el;
 
4674
        }
 
4675
 
 
4676
        // Inserting before a <base> tag apparently works around an IE bug
 
4677
        // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
 
4678
        // bug that is, exactly. Better safe than sorry?
 
4679
        if ((el = doc.getElementsByTagName('base')[0])) { // assignment
 
4680
            return (cache[docStamp] = el);
 
4681
        }
 
4682
 
 
4683
        // Look for a <head> element.
 
4684
        el = doc.head || doc.getElementsByTagName('head')[0];
 
4685
 
 
4686
        if (el) {
 
4687
            // Create a marker node at the end of <head> to use as an insertion
 
4688
            // point. Inserting before this node will ensure that all our CSS
 
4689
            // gets inserted in the correct order, to maintain style precedence.
 
4690
            el.appendChild(doc.createTextNode(''));
 
4691
            return (cache[docStamp] = el.lastChild);
 
4692
        }
 
4693
 
 
4694
        // If all else fails, just insert before the first script node on the
 
4695
        // page, which is virtually guaranteed to exist.
 
4696
        return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
 
4697
    },
 
4698
 
 
4699
    _insert: function (req) {
 
4700
        var env          = Get._env,
 
4701
            insertBefore = this._getInsertBefore(req),
 
4702
            isScript     = req.type === 'js',
 
4703
            node         = req.node,
 
4704
            self         = this,
 
4705
            ua           = Y.UA,
 
4706
            cssTimeout, nodeType;
 
4707
 
 
4708
        if (!node) {
 
4709
            if (isScript) {
 
4710
                nodeType = 'script';
 
4711
            } else if (!env.cssLoad && ua.gecko) {
 
4712
                nodeType = 'style';
 
4713
            } else {
 
4714
                nodeType = 'link';
 
4715
            }
 
4716
 
 
4717
            node = req.node = this._createNode(nodeType, req.attributes,
 
4718
                req.doc);
 
4719
        }
 
4720
 
 
4721
        function onError() {
 
4722
            self._progress('Failed to load ' + req.url, req);
 
4723
        }
 
4724
 
 
4725
        function onLoad() {
 
4726
            if (cssTimeout) {
 
4727
                clearTimeout(cssTimeout);
 
4728
            }
 
4729
 
 
4730
            self._progress(null, req);
 
4731
        }
 
4732
 
 
4733
        // Deal with script asynchronicity.
 
4734
        if (isScript) {
 
4735
            node.setAttribute('src', req.url);
 
4736
 
 
4737
            if (req.async) {
 
4738
                // Explicitly indicate that we want the browser to execute this
 
4739
                // script asynchronously. This is necessary for older browsers
 
4740
                // like Firefox <4.
 
4741
                node.async = true;
 
4742
            } else {
 
4743
                if (env.async) {
 
4744
                    // This browser treats injected scripts as async by default
 
4745
                    // (standard HTML5 behavior) but asynchronous loading isn't
 
4746
                    // desired, so tell the browser not to mark this script as
 
4747
                    // async.
 
4748
                    node.async = false;
 
4749
                }
 
4750
 
 
4751
                // If this browser doesn't preserve script execution order based
 
4752
                // on insertion order, we'll need to avoid inserting other
 
4753
                // scripts until this one finishes loading.
 
4754
                if (!env.preservesScriptOrder) {
 
4755
                    this._pending = req;
 
4756
                }
 
4757
            }
 
4758
        } else {
 
4759
            if (!env.cssLoad && ua.gecko) {
 
4760
                // In Firefox <9, we can import the requested URL into a <style>
 
4761
                // node and poll for the existence of node.sheet.cssRules. This
 
4762
                // gives us a reliable way to determine CSS load completion that
 
4763
                // also works for cross-domain stylesheets.
 
4764
                //
 
4765
                // Props to Zach Leatherman for calling my attention to this
 
4766
                // technique.
 
4767
                node.innerHTML = (req.attributes.charset ?
 
4768
                    '@charset "' + req.attributes.charset + '";' : '') +
 
4769
                    '@import "' + req.url + '";';
 
4770
            } else {
 
4771
                node.setAttribute('href', req.url);
 
4772
            }
 
4773
        }
 
4774
 
 
4775
        // Inject the node.
 
4776
        if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
 
4777
            // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
 
4778
            node.onreadystatechange = function () {
 
4779
                if (/loaded|complete/.test(node.readyState)) {
 
4780
                    node.onreadystatechange = null;
 
4781
                    onLoad();
 
4782
                }
 
4783
            };
 
4784
        } else if (!isScript && !env.cssLoad) {
 
4785
            // CSS on Firefox <9 or WebKit.
 
4786
            this._poll(req);
 
4787
        } else {
 
4788
            // Script or CSS on everything else. Using DOM 0 events because that
 
4789
            // evens the playing field with older IEs.
 
4790
 
 
4791
            if (ua.ie >= 10) {
 
4792
 
 
4793
                // We currently need to introduce a timeout for IE10, since it
 
4794
                // calls onerror/onload synchronously for 304s - messing up existing
 
4795
                // program flow.
 
4796
 
 
4797
                // Remove this block if the following bug gets fixed by GA
 
4798
                /*jshint maxlen: 1500 */
 
4799
                // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
 
4800
                node.onerror = function() { setTimeout(onError, 0); };
 
4801
                node.onload  = function() { setTimeout(onLoad, 0); };
 
4802
            } else {
 
4803
                node.onerror = onError;
 
4804
                node.onload  = onLoad;
 
4805
            }
 
4806
 
 
4807
            // If this browser doesn't fire an event when CSS fails to load,
 
4808
            // fail after a timeout to avoid blocking the transaction queue.
 
4809
            if (!env.cssFail && !isScript) {
 
4810
                cssTimeout = setTimeout(onError, req.timeout || 3000);
 
4811
            }
 
4812
        }
 
4813
 
 
4814
        this.nodes.push(node);
 
4815
        insertBefore.parentNode.insertBefore(node, insertBefore);
 
4816
    },
 
4817
 
 
4818
    _next: function () {
 
4819
        if (this._pending) {
 
4820
            return;
 
4821
        }
 
4822
 
 
4823
        // If there are requests in the queue, insert the next queued request.
 
4824
        // Otherwise, if we're waiting on already-inserted requests to finish,
 
4825
        // wait longer. If there are no queued requests and we're not waiting
 
4826
        // for anything to load, then we're done!
 
4827
        if (this._queue.length) {
 
4828
            this._insert(this._queue.shift());
 
4829
        } else if (!this._reqsWaiting) {
 
4830
            this._finish();
 
4831
        }
 
4832
    },
 
4833
 
 
4834
    _poll: function (newReq) {
 
4835
        var self       = this,
 
4836
            pendingCSS = self._pendingCSS,
 
4837
            isWebKit   = Y.UA.webkit,
 
4838
            i, hasRules, j, nodeHref, req, sheets;
 
4839
 
 
4840
        if (newReq) {
 
4841
            pendingCSS || (pendingCSS = self._pendingCSS = []);
 
4842
            pendingCSS.push(newReq);
 
4843
 
 
4844
            if (self._pollTimer) {
 
4845
                // A poll timeout is already pending, so no need to create a
 
4846
                // new one.
 
4847
                return;
 
4848
            }
 
4849
        }
 
4850
 
 
4851
        self._pollTimer = null;
 
4852
 
 
4853
        // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
 
4854
        // will still be treated as a success. There's no good workaround for
 
4855
        // this.
 
4856
 
 
4857
        for (i = 0; i < pendingCSS.length; ++i) {
 
4858
            req = pendingCSS[i];
 
4859
 
 
4860
            if (isWebKit) {
 
4861
                // Look for a stylesheet matching the pending URL.
 
4862
                sheets   = req.doc.styleSheets;
 
4863
                j        = sheets.length;
 
4864
                nodeHref = req.node.href;
 
4865
 
 
4866
                while (--j >= 0) {
 
4867
                    if (sheets[j].href === nodeHref) {
 
4868
                        pendingCSS.splice(i, 1);
 
4869
                        i -= 1;
 
4870
                        self._progress(null, req);
 
4871
                        break;
 
4872
                    }
 
4873
                }
 
4874
            } else {
 
4875
                // Many thanks to Zach Leatherman for calling my attention to
 
4876
                // the @import-based cross-domain technique used here, and to
 
4877
                // Oleg Slobodskoi for an earlier same-domain implementation.
 
4878
                //
 
4879
                // See Zach's blog for more details:
 
4880
                // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
 
4881
                try {
 
4882
                    // We don't really need to store this value since we never
 
4883
                    // use it again, but if we don't store it, Closure Compiler
 
4884
                    // assumes the code is useless and removes it.
 
4885
                    hasRules = !!req.node.sheet.cssRules;
 
4886
 
 
4887
                    // If we get here, the stylesheet has loaded.
 
4888
                    pendingCSS.splice(i, 1);
 
4889
                    i -= 1;
 
4890
                    self._progress(null, req);
 
4891
                } catch (ex) {
 
4892
                    // An exception means the stylesheet is still loading.
 
4893
                }
 
4894
            }
 
4895
        }
 
4896
 
 
4897
        if (pendingCSS.length) {
 
4898
            self._pollTimer = setTimeout(function () {
 
4899
                self._poll.call(self);
 
4900
            }, self.options.pollInterval);
 
4901
        }
 
4902
    },
 
4903
 
 
4904
    _progress: function (err, req) {
 
4905
        var options = this.options;
 
4906
 
 
4907
        if (err) {
 
4908
            req.error = err;
 
4909
 
 
4910
            this.errors.push({
 
4911
                error  : err,
 
4912
                request: req
 
4913
            });
 
4914
 
 
4915
        }
 
4916
 
 
4917
        req.node._yuiget_finished = req.finished = true;
 
4918
 
 
4919
        if (options.onProgress) {
 
4920
            options.onProgress.call(options.context || this,
 
4921
                this._getEventData(req));
 
4922
        }
 
4923
 
 
4924
        if (req.autopurge) {
 
4925
            // Pre-3.5.0 Get always excludes the most recent node from an
 
4926
            // autopurge. I find this odd, but I'm keeping that behavior for
 
4927
            // the sake of backcompat.
 
4928
            Get._autoPurge(this.options.purgethreshold);
 
4929
            Get._purgeNodes.push(req.node);
 
4930
        }
 
4931
 
 
4932
        if (this._pending === req) {
 
4933
            this._pending = null;
 
4934
        }
 
4935
 
 
4936
        this._reqsWaiting -= 1;
 
4937
 
 
4938
        this._next();
 
4939
    }
 
4940
};
 
4941
 
 
4942
 
 
4943
}, '3.10.3', {"requires": ["yui-base"]});
 
4944
YUI.add('features', function (Y, NAME) {
 
4945
 
 
4946
var feature_tests = {};
 
4947
 
 
4948
/**
 
4949
Contains the core of YUI's feature test architecture.
 
4950
@module features
 
4951
*/
 
4952
 
 
4953
/**
 
4954
* Feature detection
 
4955
* @class Features
 
4956
* @static
 
4957
*/
 
4958
 
 
4959
Y.mix(Y.namespace('Features'), {
 
4960
 
 
4961
    /**
 
4962
    * Object hash of all registered feature tests
 
4963
    * @property tests
 
4964
    * @type Object
 
4965
    */
 
4966
    tests: feature_tests,
 
4967
 
 
4968
    /**
 
4969
    * Add a test to the system
 
4970
    *
 
4971
    *   ```
 
4972
    *   Y.Features.add("load", "1", {});
 
4973
    *   ```
 
4974
    *
 
4975
    * @method add
 
4976
    * @param {String} cat The category, right now only 'load' is supported
 
4977
    * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
 
4978
    * @param {Object} o Object containing test properties
 
4979
    * @param {String} o.name The name of the test
 
4980
    * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
 
4981
    * @param {String} o.trigger The module that triggers this test.
 
4982
    */
 
4983
    add: function(cat, name, o) {
 
4984
        feature_tests[cat] = feature_tests[cat] || {};
 
4985
        feature_tests[cat][name] = o;
 
4986
    },
 
4987
    /**
 
4988
    * Execute all tests of a given category and return the serialized results
 
4989
    *
 
4990
    *   ```
 
4991
    *   caps=1:1;2:1;3:0
 
4992
    *   ```
 
4993
    * @method all
 
4994
    * @param {String} cat The category to execute
 
4995
    * @param {Array} args The arguments to pass to the test function
 
4996
    * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
 
4997
    */
 
4998
    all: function(cat, args) {
 
4999
        var cat_o = feature_tests[cat],
 
5000
            // results = {};
 
5001
            result = [];
 
5002
        if (cat_o) {
 
5003
            Y.Object.each(cat_o, function(v, k) {
 
5004
                result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
 
5005
            });
 
5006
        }
 
5007
 
 
5008
        return (result.length) ? result.join(';') : '';
 
5009
    },
 
5010
    /**
 
5011
    * Run a sepecific test and return a Boolean response.
 
5012
    *
 
5013
    *   ```
 
5014
    *   Y.Features.test("load", "1");
 
5015
    *   ```
 
5016
    *
 
5017
    * @method test
 
5018
    * @param {String} cat The category of the test to run
 
5019
    * @param {String} name The name of the test to run
 
5020
    * @param {Array} args The arguments to pass to the test function
 
5021
    * @return {Boolean} True or false if the test passed/failed.
 
5022
    */
 
5023
    test: function(cat, name, args) {
 
5024
        args = args || [];
 
5025
        var result, ua, test,
 
5026
            cat_o = feature_tests[cat],
 
5027
            feature = cat_o && cat_o[name];
 
5028
 
 
5029
        if (!feature) {
 
5030
        } else {
 
5031
 
 
5032
            result = feature.result;
 
5033
 
 
5034
            if (Y.Lang.isUndefined(result)) {
 
5035
 
 
5036
                ua = feature.ua;
 
5037
                if (ua) {
 
5038
                    result = (Y.UA[ua]);
 
5039
                }
 
5040
 
 
5041
                test = feature.test;
 
5042
                if (test && ((!ua) || result)) {
 
5043
                    result = test.apply(Y, args);
 
5044
                }
 
5045
 
 
5046
                feature.result = result;
 
5047
            }
 
5048
        }
 
5049
 
 
5050
        return result;
 
5051
    }
 
5052
});
 
5053
 
 
5054
// Y.Features.add("load", "1", {});
 
5055
// Y.Features.test("load", "1");
 
5056
// caps=1:1;2:0;3:1;
 
5057
 
 
5058
/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
 
5059
/*jshint maxlen:900, eqeqeq: false */
 
5060
var add = Y.Features.add;
 
5061
// app-transitions-native
 
5062
add('load', '0', {
 
5063
    "name": "app-transitions-native",
 
5064
    "test": function (Y) {
 
5065
    var doc  = Y.config.doc,
 
5066
        node = doc ? doc.documentElement : null;
 
5067
 
 
5068
    if (node && node.style) {
 
5069
        return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
 
5070
    }
 
5071
 
 
5072
    return false;
 
5073
},
 
5074
    "trigger": "app-transitions"
 
5075
});
 
5076
// autocomplete-list-keys
 
5077
add('load', '1', {
 
5078
    "name": "autocomplete-list-keys",
 
5079
    "test": function (Y) {
 
5080
    // Only add keyboard support to autocomplete-list if this doesn't appear to
 
5081
    // be an iOS or Android-based mobile device.
 
5082
    //
 
5083
    // There's currently no feasible way to actually detect whether a device has
 
5084
    // a hardware keyboard, so this sniff will have to do. It can easily be
 
5085
    // overridden by manually loading the autocomplete-list-keys module.
 
5086
    //
 
5087
    // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
 
5088
    // doesn't fire the keyboard events used by AutoCompleteList, so there's
 
5089
    // no point loading the -keys module even when a bluetooth keyboard may be
 
5090
    // available.
 
5091
    return !(Y.UA.ios || Y.UA.android);
 
5092
},
 
5093
    "trigger": "autocomplete-list"
 
5094
});
 
5095
// dd-gestures
 
5096
add('load', '2', {
 
5097
    "name": "dd-gestures",
 
5098
    "trigger": "dd-drag",
 
5099
    "ua": "touchEnabled"
 
5100
});
 
5101
// dom-style-ie
 
5102
add('load', '3', {
 
5103
    "name": "dom-style-ie",
 
5104
    "test": function (Y) {
 
5105
 
 
5106
    var testFeature = Y.Features.test,
 
5107
        addFeature = Y.Features.add,
 
5108
        WINDOW = Y.config.win,
 
5109
        DOCUMENT = Y.config.doc,
 
5110
        DOCUMENT_ELEMENT = 'documentElement',
 
5111
        ret = false;
 
5112
 
 
5113
    addFeature('style', 'computedStyle', {
 
5114
        test: function() {
 
5115
            return WINDOW && 'getComputedStyle' in WINDOW;
 
5116
        }
 
5117
    });
 
5118
 
 
5119
    addFeature('style', 'opacity', {
 
5120
        test: function() {
 
5121
            return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
 
5122
        }
 
5123
    });
 
5124
 
 
5125
    ret =  (!testFeature('style', 'opacity') &&
 
5126
            !testFeature('style', 'computedStyle'));
 
5127
 
 
5128
    return ret;
 
5129
},
 
5130
    "trigger": "dom-style"
 
5131
});
 
5132
// editor-para-ie
 
5133
add('load', '4', {
 
5134
    "name": "editor-para-ie",
 
5135
    "trigger": "editor-para",
 
5136
    "ua": "ie",
 
5137
    "when": "instead"
 
5138
});
 
5139
// event-base-ie
 
5140
add('load', '5', {
 
5141
    "name": "event-base-ie",
 
5142
    "test": function(Y) {
 
5143
    var imp = Y.config.doc && Y.config.doc.implementation;
 
5144
    return (imp && (!imp.hasFeature('Events', '2.0')));
 
5145
},
 
5146
    "trigger": "node-base"
 
5147
});
 
5148
// graphics-canvas
 
5149
add('load', '6', {
 
5150
    "name": "graphics-canvas",
 
5151
    "test": function(Y) {
 
5152
    var DOCUMENT = Y.config.doc,
 
5153
        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
 
5154
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
 
5155
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
 
5156
    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
 
5157
},
 
5158
    "trigger": "graphics"
 
5159
});
 
5160
// graphics-canvas-default
 
5161
add('load', '7', {
 
5162
    "name": "graphics-canvas-default",
 
5163
    "test": function(Y) {
 
5164
    var DOCUMENT = Y.config.doc,
 
5165
        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
 
5166
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
 
5167
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
 
5168
    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
 
5169
},
 
5170
    "trigger": "graphics"
 
5171
});
 
5172
// graphics-svg
 
5173
add('load', '8', {
 
5174
    "name": "graphics-svg",
 
5175
    "test": function(Y) {
 
5176
    var DOCUMENT = Y.config.doc,
 
5177
        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
 
5178
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
 
5179
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
 
5180
    
 
5181
    return svg && (useSVG || !canvas);
 
5182
},
 
5183
    "trigger": "graphics"
 
5184
});
 
5185
// graphics-svg-default
 
5186
add('load', '9', {
 
5187
    "name": "graphics-svg-default",
 
5188
    "test": function(Y) {
 
5189
    var DOCUMENT = Y.config.doc,
 
5190
        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
 
5191
                canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
 
5192
        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
 
5193
    
 
5194
    return svg && (useSVG || !canvas);
 
5195
},
 
5196
    "trigger": "graphics"
 
5197
});
 
5198
// graphics-vml
 
5199
add('load', '10', {
 
5200
    "name": "graphics-vml",
 
5201
    "test": function(Y) {
 
5202
    var DOCUMENT = Y.config.doc,
 
5203
                canvas = DOCUMENT && DOCUMENT.createElement("canvas");
 
5204
    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
 
5205
},
 
5206
    "trigger": "graphics"
 
5207
});
 
5208
// graphics-vml-default
 
5209
add('load', '11', {
 
5210
    "name": "graphics-vml-default",
 
5211
    "test": function(Y) {
 
5212
    var DOCUMENT = Y.config.doc,
 
5213
                canvas = DOCUMENT && DOCUMENT.createElement("canvas");
 
5214
    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
 
5215
},
 
5216
    "trigger": "graphics"
 
5217
});
 
5218
// history-hash-ie
 
5219
add('load', '12', {
 
5220
    "name": "history-hash-ie",
 
5221
    "test": function (Y) {
 
5222
    var docMode = Y.config.doc && Y.config.doc.documentMode;
 
5223
 
 
5224
    return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
 
5225
            !docMode || docMode < 8);
 
5226
},
 
5227
    "trigger": "history-hash"
 
5228
});
 
5229
// io-nodejs
 
5230
add('load', '13', {
 
5231
    "name": "io-nodejs",
 
5232
    "trigger": "io-base",
 
5233
    "ua": "nodejs"
 
5234
});
 
5235
// json-parse-shim
 
5236
add('load', '14', {
 
5237
    "name": "json-parse-shim",
 
5238
    "test": function (Y) {
 
5239
    var _JSON = Y.config.global.JSON,
 
5240
        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
 
5241
        nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
 
5242
 
 
5243
    function workingNative( k, v ) {
 
5244
        return k === "ok" ? true : v;
 
5245
    }
 
5246
    
 
5247
    // Double check basic functionality.  This is mainly to catch early broken
 
5248
    // implementations of the JSON API in Firefox 3.1 beta1 and beta2
 
5249
    if ( nativeSupport ) {
 
5250
        try {
 
5251
            nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
 
5252
        }
 
5253
        catch ( e ) {
 
5254
            nativeSupport = false;
 
5255
        }
 
5256
    }
 
5257
 
 
5258
    return !nativeSupport;
 
5259
},
 
5260
    "trigger": "json-parse"
 
5261
});
 
5262
// json-stringify-shim
 
5263
add('load', '15', {
 
5264
    "name": "json-stringify-shim",
 
5265
    "test": function (Y) {
 
5266
    var _JSON = Y.config.global.JSON,
 
5267
        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
 
5268
        nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
 
5269
 
 
5270
    // Double check basic native functionality.  This is primarily to catch broken
 
5271
    // early JSON API implementations in Firefox 3.1 beta1 and beta2.
 
5272
    if ( nativeSupport ) {
 
5273
        try {
 
5274
            nativeSupport = ( '0' === Native.stringify(0) );
 
5275
        } catch ( e ) {
 
5276
            nativeSupport = false;
 
5277
        }
 
5278
    }
 
5279
 
 
5280
 
 
5281
    return !nativeSupport;
 
5282
},
 
5283
    "trigger": "json-stringify"
 
5284
});
 
5285
// scrollview-base-ie
 
5286
add('load', '16', {
 
5287
    "name": "scrollview-base-ie",
 
5288
    "trigger": "scrollview-base",
 
5289
    "ua": "ie"
 
5290
});
 
5291
// selector-css2
 
5292
add('load', '17', {
 
5293
    "name": "selector-css2",
 
5294
    "test": function (Y) {
 
5295
    var DOCUMENT = Y.config.doc,
 
5296
        ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
 
5297
 
 
5298
    return ret;
 
5299
},
 
5300
    "trigger": "selector"
 
5301
});
 
5302
// transition-timer
 
5303
add('load', '18', {
 
5304
    "name": "transition-timer",
 
5305
    "test": function (Y) {
 
5306
    var DOCUMENT = Y.config.doc,
 
5307
        node = (DOCUMENT) ? DOCUMENT.documentElement: null,
 
5308
        ret = true;
 
5309
 
 
5310
    if (node && node.style) {
 
5311
        ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
 
5312
    }
 
5313
 
 
5314
    return ret;
 
5315
},
 
5316
    "trigger": "transition"
 
5317
});
 
5318
// widget-base-ie
 
5319
add('load', '19', {
 
5320
    "name": "widget-base-ie",
 
5321
    "trigger": "widget-base",
 
5322
    "ua": "ie"
 
5323
});
 
5324
// yql-jsonp
 
5325
add('load', '20', {
 
5326
    "name": "yql-jsonp",
 
5327
    "test": function (Y) {
 
5328
    /* Only load the JSONP module when not in nodejs or winjs
 
5329
    TODO Make the winjs module a CORS module
 
5330
    */
 
5331
    return (!Y.UA.nodejs && !Y.UA.winjs);
 
5332
},
 
5333
    "trigger": "yql",
 
5334
    "when": "after"
 
5335
});
 
5336
// yql-nodejs
 
5337
add('load', '21', {
 
5338
    "name": "yql-nodejs",
 
5339
    "trigger": "yql",
 
5340
    "ua": "nodejs",
 
5341
    "when": "after"
 
5342
});
 
5343
// yql-winjs
 
5344
add('load', '22', {
 
5345
    "name": "yql-winjs",
 
5346
    "trigger": "yql",
 
5347
    "ua": "winjs",
 
5348
    "when": "after"
 
5349
});
 
5350
 
 
5351
}, '3.10.3', {"requires": ["yui-base"]});
 
5352
YUI.add('intl-base', function (Y, NAME) {
 
5353
 
 
5354
/**
 
5355
 * The Intl utility provides a central location for managing sets of
 
5356
 * localized resources (strings and formatting patterns).
 
5357
 *
 
5358
 * @class Intl
 
5359
 * @uses EventTarget
 
5360
 * @static
 
5361
 */
 
5362
 
 
5363
var SPLIT_REGEX = /[, ]/;
 
5364
 
 
5365
Y.mix(Y.namespace('Intl'), {
 
5366
 
 
5367
 /**
 
5368
    * Returns the language among those available that
 
5369
    * best matches the preferred language list, using the Lookup
 
5370
    * algorithm of BCP 47.
 
5371
    * If none of the available languages meets the user's preferences,
 
5372
    * then "" is returned.
 
5373
    * Extended language ranges are not supported.
 
5374
    *
 
5375
    * @method lookupBestLang
 
5376
    * @param {String[] | String} preferredLanguages The list of preferred
 
5377
    * languages in descending preference order, represented as BCP 47
 
5378
    * language tags. A string array or a comma-separated list.
 
5379
    * @param {String[]} availableLanguages The list of languages
 
5380
    * that the application supports, represented as BCP 47 language
 
5381
    * tags.
 
5382
    *
 
5383
    * @return {String} The available language that best matches the
 
5384
    * preferred language list, or "".
 
5385
    * @since 3.1.0
 
5386
    */
 
5387
    lookupBestLang: function(preferredLanguages, availableLanguages) {
 
5388
 
 
5389
        var i, language, result, index;
 
5390
 
 
5391
        // check whether the list of available languages contains language;
 
5392
        // if so return it
 
5393
        function scan(language) {
 
5394
            var i;
 
5395
            for (i = 0; i < availableLanguages.length; i += 1) {
 
5396
                if (language.toLowerCase() ===
 
5397
                            availableLanguages[i].toLowerCase()) {
 
5398
                    return availableLanguages[i];
 
5399
                }
 
5400
            }
 
5401
        }
 
5402
 
 
5403
        if (Y.Lang.isString(preferredLanguages)) {
 
5404
            preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
 
5405
        }
 
5406
 
 
5407
        for (i = 0; i < preferredLanguages.length; i += 1) {
 
5408
            language = preferredLanguages[i];
 
5409
            if (!language || language === '*') {
 
5410
                continue;
 
5411
            }
 
5412
            // check the fallback sequence for one language
 
5413
            while (language.length > 0) {
 
5414
                result = scan(language);
 
5415
                if (result) {
 
5416
                    return result;
 
5417
                } else {
 
5418
                    index = language.lastIndexOf('-');
 
5419
                    if (index >= 0) {
 
5420
                        language = language.substring(0, index);
 
5421
                        // one-character subtags get cut along with the
 
5422
                        // following subtag
 
5423
                        if (index >= 2 && language.charAt(index - 2) === '-') {
 
5424
                            language = language.substring(0, index - 2);
 
5425
                        }
 
5426
                    } else {
 
5427
                        // nothing available for this language
 
5428
                        break;
 
5429
                    }
 
5430
                }
 
5431
            }
 
5432
        }
 
5433
 
 
5434
        return '';
 
5435
    }
 
5436
});
 
5437
 
 
5438
 
 
5439
}, '3.10.3', {"requires": ["yui-base"]});
 
5440
YUI.add('yui-log', function (Y, NAME) {
 
5441
 
 
5442
/**
 
5443
 * Provides console log capability and exposes a custom event for
 
5444
 * console implementations. This module is a `core` YUI module,
 
5445
 * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
 
5446
 *
 
5447
 * @module yui
 
5448
 * @submodule yui-log
 
5449
 */
 
5450
 
 
5451
var INSTANCE = Y,
 
5452
    LOGEVENT = 'yui:log',
 
5453
    UNDEFINED = 'undefined',
 
5454
    LEVELS = { debug: 1,
 
5455
               info: 2,
 
5456
               warn: 4,
 
5457
               error: 8 };
 
5458
 
 
5459
/**
 
5460
 * If the 'debug' config is true, a 'yui:log' event will be
 
5461
 * dispatched, which the Console widget and anything else
 
5462
 * can consume.  If the 'useBrowserConsole' config is true, it will
 
5463
 * write to the browser console if available.  YUI-specific log
 
5464
 * messages will only be present in the -debug versions of the
 
5465
 * JS files.  The build system is supposed to remove log statements
 
5466
 * from the raw and minified versions of the files.
 
5467
 *
 
5468
 * @method log
 
5469
 * @for YUI
 
5470
 * @param  {String}  msg  The message to log.
 
5471
 * @param  {String}  cat  The log category for the message.  Default
 
5472
 *                        categories are "info", "warn", "error", time".
 
5473
 *                        Custom categories can be used as well. (opt).
 
5474
 * @param  {String}  src  The source of the the message (opt).
 
5475
 * @param  {boolean} silent If true, the log event won't fire.
 
5476
 * @return {YUI}      YUI instance.
 
5477
 */
 
5478
INSTANCE.log = function(msg, cat, src, silent) {
 
5479
    var bail, excl, incl, m, f, minlevel,
 
5480
        Y = INSTANCE,
 
5481
        c = Y.config,
 
5482
        publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
 
5483
    // suppress log message if the config is off or the event stack
 
5484
    // or the event call stack contains a consumer of the yui:log event
 
5485
    if (c.debug) {
 
5486
        // apply source filters
 
5487
        src = src || "";
 
5488
        if (typeof src !== "undefined") {
 
5489
            excl = c.logExclude;
 
5490
            incl = c.logInclude;
 
5491
            if (incl && !(src in incl)) {
 
5492
                bail = 1;
 
5493
            } else if (incl && (src in incl)) {
 
5494
                bail = !incl[src];
 
5495
            } else if (excl && (src in excl)) {
 
5496
                bail = excl[src];
 
5497
            }
 
5498
 
 
5499
            // Determine the current minlevel as defined in configuration
 
5500
            Y.config.logLevel = Y.config.logLevel || 'debug';
 
5501
            minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
 
5502
 
 
5503
            if (cat in LEVELS && LEVELS[cat] < minlevel) {
 
5504
                // Skip this message if the we don't meet the defined minlevel
 
5505
                bail = 1;
 
5506
            }
 
5507
        }
 
5508
        if (!bail) {
 
5509
            if (c.useBrowserConsole) {
 
5510
                m = (src) ? src + ': ' + msg : msg;
 
5511
                if (Y.Lang.isFunction(c.logFn)) {
 
5512
                    c.logFn.call(Y, msg, cat, src);
 
5513
                } else if (typeof console !== UNDEFINED && console.log) {
 
5514
                    f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
 
5515
                    console[f](m);
 
5516
                } else if (typeof opera !== UNDEFINED) {
 
5517
                    opera.postError(m);
 
5518
                }
 
5519
            }
 
5520
 
 
5521
            if (publisher && !silent) {
 
5522
 
 
5523
                if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
 
5524
                    publisher.publish(LOGEVENT, {
 
5525
                        broadcast: 2
 
5526
                    });
 
5527
                }
 
5528
 
 
5529
                publisher.fire(LOGEVENT, {
 
5530
                    msg: msg,
 
5531
                    cat: cat,
 
5532
                    src: src
 
5533
                });
 
5534
            }
 
5535
        }
 
5536
    }
 
5537
 
 
5538
    return Y;
 
5539
};
 
5540
 
 
5541
/**
 
5542
 * Write a system message.  This message will be preserved in the
 
5543
 * minified and raw versions of the YUI files, unlike log statements.
 
5544
 * @method message
 
5545
 * @for YUI
 
5546
 * @param  {String}  msg  The message to log.
 
5547
 * @param  {String}  cat  The log category for the message.  Default
 
5548
 *                        categories are "info", "warn", "error", time".
 
5549
 *                        Custom categories can be used as well. (opt).
 
5550
 * @param  {String}  src  The source of the the message (opt).
 
5551
 * @param  {boolean} silent If true, the log event won't fire.
 
5552
 * @return {YUI}      YUI instance.
 
5553
 */
 
5554
INSTANCE.message = function() {
 
5555
    return INSTANCE.log.apply(INSTANCE, arguments);
 
5556
};
 
5557
 
 
5558
 
 
5559
}, '3.10.3', {"requires": ["yui-base"]});
 
5560
YUI.add('yui-later', function (Y, NAME) {
 
5561
 
 
5562
/**
 
5563
 * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
 
5564
 * <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
 
5565
 *
 
5566
 * @module yui
 
5567
 * @submodule yui-later
 
5568
 */
 
5569
 
 
5570
var NO_ARGS = [];
 
5571
 
 
5572
/**
 
5573
 * Executes the supplied function in the context of the supplied
 
5574
 * object 'when' milliseconds later.  Executes the function a
 
5575
 * single time unless periodic is set to true.
 
5576
 * @for YUI
 
5577
 * @method later
 
5578
 * @param when {int} the number of milliseconds to wait until the fn
 
5579
 * is executed.
 
5580
 * @param o the context object.
 
5581
 * @param fn {Function|String} the function to execute or the name of
 
5582
 * the method in the 'o' object to execute.
 
5583
 * @param data [Array] data that is provided to the function.  This
 
5584
 * accepts either a single item or an array.  If an array is provided,
 
5585
 * the function is executed with one parameter for each array item.
 
5586
 * If you need to pass a single array parameter, it needs to be wrapped
 
5587
 * in an array [myarray].
 
5588
 *
 
5589
 * Note: native methods in IE may not have the call and apply methods.
 
5590
 * In this case, it will work, but you are limited to four arguments.
 
5591
 *
 
5592
 * @param periodic {boolean} if true, executes continuously at supplied
 
5593
 * interval until canceled.
 
5594
 * @return {object} a timer object. Call the cancel() method on this
 
5595
 * object to stop the timer.
 
5596
 */
 
5597
Y.later = function(when, o, fn, data, periodic) {
 
5598
    when = when || 0;
 
5599
    data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
 
5600
    o = o || Y.config.win || Y;
 
5601
 
 
5602
    var cancelled = false,
 
5603
        method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
 
5604
        wrapper = function() {
 
5605
            // IE 8- may execute a setInterval callback one last time
 
5606
            // after clearInterval was called, so in order to preserve
 
5607
            // the cancel() === no more runny-run, we have to jump through
 
5608
            // an extra hoop.
 
5609
            if (!cancelled) {
 
5610
                if (!method.apply) {
 
5611
                    method(data[0], data[1], data[2], data[3]);
 
5612
                } else {
 
5613
                    method.apply(o, data || NO_ARGS);
 
5614
                }
 
5615
            }
 
5616
        },
 
5617
        id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
 
5618
 
 
5619
    return {
 
5620
        id: id,
 
5621
        interval: periodic,
 
5622
        cancel: function() {
 
5623
            cancelled = true;
 
5624
            if (this.interval) {
 
5625
                clearInterval(id);
 
5626
            } else {
 
5627
                clearTimeout(id);
 
5628
            }
 
5629
        }
 
5630
    };
 
5631
};
 
5632
 
 
5633
Y.Lang.later = Y.later;
 
5634
 
 
5635
 
 
5636
 
 
5637
}, '3.10.3', {"requires": ["yui-base"]});
 
5638
YUI.add('yui', function (Y, NAME) {}, '3.10.3', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});