PageSourceSearch

https://www.provincia.terni.it/portal/combo?browserId=chrome&minif…/aui/event-key/event-key.js

js provincia.terni.it collected 2026-10-02 12:10:51 UTC 838,001 bytes, 27,501 lines download raw bytes

1/**
2The YUI module contains the components required for building the YUI seed file.
3This includes the script loading mechanism, a simple queue, and the core
4utilities for the library.
5
6@module yui
7@main yui
8@submodule yui-base
9**/
10
11/*jshint eqeqeq: false*/
12if (typeof YUI != 'undefined') {
13    YUI._YUI = YUI;
14}
15
16/**
17The YUI global namespace object. This is the constructor for all YUI instances.
18
19This is a self-instantiable factory function, meaning you don't need to precede
20it with the `new` operator. You can invoke it directly like this:
21
22    YUI().use('*', function (Y) {
23        // Y is a new YUI instance.
24    });
25
26But it also works like this:
27
28    var Y = YUI();
29
30The `YUI` constructor accepts an optional config object, like this:
31
32    YUI({
33        debug: true,
34        combine: false
35    }).use('node', function (Y) {
36        // Y.Node is ready to use.
37    });
38
39See the API docs for the <a href="config.html">Config</a> class for the complete
40list of supported configuration properties accepted by the YUI constuctor.
41
42If a global `YUI` object is already defined, the existing YUI object will not be
43overwritten, to ensure that defined namespaces are preserved.
44
45Each YUI instance has full custom event support, but only if the event system is
46available.
47
48@class YUI
49@uses EventTarget
50@constructor
51@global
52@param {Object} [config]* Zero or more optional configuration objects. Config
53    values are stored in the `Y.config` property. See the
54    <a href="config.html">Config</a> docs for the list of supported properties.
55**/
56
57    /*global YUI*/
58    /*global YUI_config*/
59    var YUI = function() {
60        var i = 0,
61            Y = this,
62            args = arguments,
63            l = args.length,
64            instanceOf = function(o, type) {
65                return (o && o.hasOwnProperty && (o instanceof type));
66            },
67            gconf = (typeof YUI_config !== 'undefined') && YUI_config;
68
69        if (!(instanceOf(Y, YUI))) {
70            Y = new YUI();
71        } else {
72            // set up the core environment
73            Y._init();
74
75            /**
76            Master configuration that might span multiple contexts in a non-
77            browser environment. It is applied first to all instances in all
78            contexts.
79
80            @example
81
82                YUI.GlobalConfig = {
83                    filter: 'debug'
84                };
85
86                YUI().use('node', function (Y) {
87                    // debug files used here
88                });
89
90                YUI({
91                    filter: 'min'
92                }).use('node', function (Y) {
93                    // min files used here
94                });
95
96            @property {Object} GlobalConfig
97            @global
98            @static
99            **/
100            if (YUI.GlobalConfig) {
101                Y.applyConfig(YUI.GlobalConfig);
102            }
103
104            /**
105            Page-level config applied to all YUI instances created on the
106            current page. This is applied after `YUI.GlobalConfig` and before
107            any instance-level configuration.
108
109            @example
110
111                // Single global var to include before YUI seed file
112                YUI_config = {
113                    filter: 'debug'
114                };
115
116                YUI().use('node', function (Y) {
117                    // debug files used here
118                });
119
120                YUI({
121                    filter: 'min'
122                }).use('node', function (Y) {
123                    // min files used here
124                });
125
126            @property {Object} YUI_config
127            @global
128            **/
129            if (gconf) {
130                Y.applyConfig(gconf);
131            }
132
133            // bind the specified additional modules for this instance
134            if (!l) {
135                Y._afterConfig();
136                Y._setup();
137            }
138        }
139
140        if (l) {
141            // Each instance can accept one or more configuration objects.
142            // These are applied after YUI.GlobalConfig and YUI_Config,
143            // overriding values set in those config files if there is a
144            // matching property.
145            for (; i < l; i++) {
146                Y.applyConfig(args[i]);
147            }
148
149            Y._afterConfig();
150            Y._setup();
151        }
152
153        Y.instanceOf = instanceOf;
154
155        return Y;
156    };
157
158(function() {
159
160    var proto, prop,
161        VERSION = 'patched-v3.18.1',
162        PERIOD = '.',
163        BASE = 'http://yui.yahooapis.com/',
164        /*
165            These CSS class names can't be generated by
166            getClassName since it is not available at the
167            time they are being used.
168        */
169        DOC_LABEL = 'yui3-js-enabled',
170        CSS_STAMP_EL = 'yui3-css-stamp',
171        NOOP = function() {},
172        SLICE = Array.prototype.slice,
173        APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
174                          'io.xdrResponse': 1,   // can call. this should
175                          'SWF.eventHandler': 1 }, // be done at build time
176        hasWin = (typeof window != 'undefined'),
177        win = (hasWin) ? window : null,
178        doc = (hasWin) ? win.document : null,
179        docEl = doc && doc.documentElement,
180        docClass = docEl && docEl.className,
181        instances = {},
182        time = new Date().getTime(),
183        add = function(el, type, fn, capture) {
184            if (el && el.addEventListener) {
185                el.addEventListener(type, fn, capture);
186            } else if (el && el.attachEvent) {
187                el.attachEvent('on' + type, fn);
188            }
189        },
190        remove = function(el, type, fn, capture) {
191            if (el && el.removeEventListener) {
192                // this can throw an uncaught exception in FF
193                try {
194                    el.removeEventListener(type, fn, capture);
195                } catch (ex) {}
196            } else if (el && el.detachEvent) {
197                el.detachEvent('on' + type, fn);
198            }
199        },
200        handleReady = function() {
201            YUI.Env.DOMReady = true;
202            if (hasWin) {
203                remove(doc, 'DOMContentLoaded', handleReady);
204            }
205            if (doc && doc.body && YUI.Env.cssStampEl && (!doc.body.contains(YUI.Env.cssStampEl))) {
206                doc.body.appendChild(YUI.Env.cssStampEl);
207            }
208        },
209        handleLoad = function() {
210            YUI.Env.windowLoaded = true;
211            YUI.Env.DOMReady = true;
212            if (hasWin) {
213                remove(window, 'load', handleLoad);
214            }
215        },
216        getLoader = function(Y, o) {
217            var loader = Y.Env._loader,
218                lCore = [ 'loader-base' ],
219                G_ENV = YUI.Env,
220                mods = G_ENV.mods;
221
222            if (loader) {
223                //loader._config(Y.config);
224                loader.ignoreRegistered = false;
225                loader.onEnd = null;
226                loader.data = null;
227                loader.required = [];
228                loader.loadType = null;
229            } else {
230                loader = new Y.Loader(Y.config);
231                Y.Env._loader = loader;
232            }
233            if (mods && mods.loader) {
234                lCore = [].concat(lCore, YUI.Env.loaderExtras);
235            }
236            YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
237
238            return loader;
239        },
240
241        clobber = function(r, s) {
242            for (var i in s) {
243                if (s.hasOwnProperty(i)) {
244                    r[i] = s[i];
245                }
246            }
247        },
248
249        ALREADY_DONE = { success: true };
250
251//  Stamp the documentElement (HTML) with a class of "yui-loaded" to
252//  enable styles that need to key off of JS being enabled.
253if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
254    if (docClass) {
255        docClass += ' ';
256    }
257    docClass += DOC_LABEL;
258    docEl.className = docClass;
259}
260
261if (VERSION.indexOf('@') > -1) {
262    VERSION = '3.5.0'; // dev time hack for cdn test
263}
264
265proto = {
266    /**
267    Applies a new configuration object to the config of this YUI instance. This
268    will merge new group/module definitions, and will also update the loader
269    cache if necessary. Updating `Y.config` directly will not update the cache.
270
271    @method applyConfig
272    @param {Object} o the configuration object.
273    @since 3.2.0
274    **/
275    applyConfig: function(o) {
276
277        o = o || NOOP;
278
279        var attr,
280            name,
281            // detail,
282            config = this.config,
283            mods = config.modules,
284            groups = config.groups,
285            aliases = config.aliases,
286            loader = this.Env._loader;
287
288        for (name in o) {
289            if (o.hasOwnProperty(name)) {
290                attr = o[name];
291                if (mods && name == 'modules') {
292                    clobber(mods, attr);
293                } else if (aliases && name == 'aliases') {
294                    clobber(aliases, attr);
295                } else if (groups && name == 'groups') {
296                    clobber(groups, attr);
297                } else if (name == 'win') {
298                    config[name] = (attr && attr.contentWindow) || attr;
299                    config.doc = config[name] ? config[name].document : null;
300                } else if (name == '_yuid') {
301                    // preserve the guid
302                } else {
303                    config[name] = attr;
304                }
305            }
306        }
307
308        if (loader) {
309            loader._config(o);
310        }
311
312    },
313
314    /**
315    Old way to apply a config to this instance (calls `applyConfig` under the
316    hood).
317
318    @private
319    @method _config
320    @param {Object} o The config to apply
321    **/
322    _config: function(o) {
323        this.applyConfig(o);
324    },
325
326    /**
327    Initializes this YUI instance.
328
329    @private
330    @method _init
331    **/
332    _init: function() {
333        var filter, el,
334            Y = this,
335            G_ENV = YUI.Env,
336            Env = Y.Env,
337            prop;
338
339        /**
340        The version number of this YUI instance.
341
342        This value is typically updated by a script when a YUI release is built,
343        so it may not reflect the correct version number when YUI is run from
344        the development source tree.
345
346        @property {String} version
347        **/
348        Y.version = VERSION;
349
350        if (!Env) {
351            Y.Env = {
352                core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'],
353                loaderExtras: ['loader-rollup', 'loader-yui3'],
354                mods: {}, // flat module map
355                versions: {}, // version module map
356                base: BASE,
357                cdn: BASE + VERSION + '/',
358                // bootstrapped: false,
359                _idx: 0,
360                _used: {},
361                _attached: {},
362                _exported: {},
363                _missed: [],
364                _yidx: 0,
365                _uidx: 0,
366                _guidp: 'y',
367                _loaded: {},
368                // serviced: {},
369                // Regex in English:
370                // I'll start at the \b(yui).
371                // 1. Look in the test string for "yui" or
372                //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
373                //    can't match "foyui" or "i_heart_yui". This can be anywhere in the string.
374                // 2. After #1 must come a forward slash followed by the string matched in #1, so
375                //    "yui-base/yui-base" or "yui-pants/yui-pants".
376                // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
377                //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
378                // 4. This is followed by ".js", so "yui/yui.js".
379                // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
380                //    then capture the junk between the LAST "&" and the string in 1-4.  So
381                //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
382                //    will capture "3.3.0/build/"
383                //
384                // Regex Exploded:
385                // (?:\?             Find a ?
386                //   (?:[^&]*&)      followed by 0..n characters followed by an &
387                //   *               in fact, find as many sets of characters followed by a & as you can
388                //   ([^&]*)         capture the stuff after the last & in \1
389                // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
390                // \b(               after a word break find either the string
391                //    yui(?:-\w+)?   "yui" optionally followed by a -, then more characters
392                // )                 and store the yui-* string in \2
393                // \/\2              then comes a / followed by the yui-* string in \2
394                // (?:-(min|debug))? optionally followed by "-min" or "-debug"
395                // .js               and ending in ".js"
396                _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(aui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
397                parseBasePath: function(src, pattern) {
398                    var match = src.match(pattern),
399                        path, filter;
400
401                    if (match) {
402                        path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
403
404                        // this is to set up the path to the loader.  The file
405                        // filter for loader should match the yui include.
406                        filter = match[3];
407
408                        // extract correct path for mixed combo urls
409                        // http://yuilibrary.com/projects/yui3/ticket/2528423
410                        if (match[1]) {
411                            path += '?' + match[1];
412                        }
413                        path = {
414                            filter: filter,
415                            path: path
416                        };
417                    }
418                    return path;
419                },
420                getBase: G_ENV && G_ENV.getBase ||
421                        function(pattern) {
422                            var nodes = (doc && doc.getElementsByTagName('script')) || [],
423                                path = Env.cdn, parsed,
424                                i, len, src;
425
426                            for (i = 0, len = nodes.length; i < len; ++i) {
427                                src = nodes[i].src;
428                                if (src) {
429                                    parsed = Y.Env.parseBasePath(src, pattern);
430                                    if (parsed) {
431                                        filter = parsed.filter;
432                                        path = parsed.path;
433                                        break;
434                                    }
435                                }
436                            }
437
438                            // use CDN default
439                            return path;
440                        }
441
442            };
443
444            Env = Y.Env;
445
446            Env._loaded[VERSION] = {};
447
448            if (G_ENV && Y !== YUI) {
449                Env._yidx = ++G_ENV._yidx;
450                Env._guidp = ('yui_' + VERSION + '_' +
451                             Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
452            } else if (YUI._YUI) {
453
454                G_ENV = YUI._YUI.Env;
455                Env._yidx += G_ENV._yidx;
456                Env._uidx += G_ENV._uidx;
457
458                for (prop in G_ENV) {
459                    if (!(prop in Env)) {
460                        Env[prop] = G_ENV[prop];
461                    }
462                }
463
464                delete YUI._YUI;
465            }
466
467            Y.id = Y.stamp(Y);
468            instances[Y.id] = Y;
469
470        }
471
472        Y.constructor = YUI;
473
474        // configuration defaults
475        Y.config = Y.config || {
476            bootstrap: true,
477            cacheUse: true,
478            debug: true,
479            doc: doc,
480            fetchCSS: true,
481            throwFail: true,
482            useBrowserConsole: true,
483            useNativeES5: true,
484            win: win
485        };
486
487        //Register the CSS stamp element
488        if (doc && !doc.getElementById(CSS_STAMP_EL)) {
489            el = doc.createElement('div');
490            el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
491            YUI.Env.cssStampEl = el.firstChild;
492            if (doc.body) {
493                doc.body.appendChild(YUI.Env.cssStampEl);
494            } else {
495                docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
496            }
497        } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
498            YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
499        }
500
501        Y.config.lang = Y.config.lang || 'en-US';
502
503        Y.config.base = YUI.config.base ||
504                (YUI.config.defaultBase && YUI.config.root && YUI.config.defaultBase + YUI.config.root) ||
505                Y.Env.getBase(Y.Env._BASE_RE);
506
507        if (!filter || (!('mindebug').indexOf(filter))) {
508            filter = 'min';
509        }
510        filter = (filter) ? '-' + filter : filter;
511        Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
512
513    },
514
515    /**
516    This method is called after all other configuration has been applied to
517    the YUI instance.
518
519    @method _afterConfig
520    @private
521    **/
522    _afterConfig: function () {
523        var Y = this;
524
525        // We need to set up Y.config.global after the rest of the configuration
526        // so that setting it in user configuration prevents the library from
527        // using eval(). This is critical for Content Security Policy enabled
528        // sites and other environments like Chrome extensions
529        if (!Y.config.hasOwnProperty('global')) {
530            Y.config.global = Function('return this')();
531        }
532    },
533
534    /**
535    Finishes the instance setup. Attaches whatever YUI modules were defined
536    at the time that this instance was created.
537
538    @method _setup
539    @private
540    **/
541    _setup: function() {
542        var i, Y = this,
543            core = [],
544            mods = YUI.Env.mods,
545            extendedCore = Y.config.extendedCore || [],
546            extras = Y.config.core || [].concat(YUI.Env.core).concat(extendedCore); //Clone it..
547
548        for (i = 0; i < extras.length; i++) {
549            if (mods[extras[i]]) {
550                core.push(extras[i]);
551            }
552        }
553
554        Y._attach(['yui-base']);
555        Y._attach(core);
556
557        if (Y.Loader) {
558            getLoader(Y);
559        }
560
561    },
562
563    /**
564    Executes the named method on the specified YUI instance if that method is
565    whitelisted.
566
567    @method applyTo
568    @param {String} id YUI instance id.
569    @param {String} method Name of the method to execute. For example:
570        'Object.keys'.
571    @param {Array} args Arguments to apply to the method.
572    @return {Mixed} Return value from the applied method, or `null` if the
573        specified instance was not found or the method was not whitelisted.
574    **/
575    applyTo: function(id, method, args) {
576        if (!(method in APPLY_TO_AUTH)) {
577            this.log(method + ': applyTo not allowed', 'warn', 'yui');
578            return null;
579        }
580
581        var instance = instances[id], nest, m, i;
582        if (instance) {
583            nest = method.split('.');
584            m = instance;
585            for (i = 0; i < nest.length; i = i + 1) {
586                m = m[nest[i]];
587                if (!m) {
588                    this.log('applyTo not found: ' + method, 'warn', 'yui');
589                }
590            }
591            return m && m.apply(instance, args);
592        }
593
594        return null;
595    },
596
597/**
598Registers a YUI module and makes it available for use in a `YUI().use()` call or
599as a dependency for other modules.
600
601The easiest way to create a first-class YUI module is to use
602<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
603tool.
604
605Shifter will automatically wrap your module code in a `YUI.add()` call along
606with any configuration info required for the module.
607
608@example
609
610    YUI.add('davglass', function (Y) {
611        Y.davglass = function () {
612        };
613    }, '3.4.0', {
614        requires: ['harley-davidson', 'mt-dew']
615    });
616
617@method add
618@param {String} name Module name.
619@param {Function} fn Function containing module code. This function will be
620    executed whenever the module is attached to a specific YUI instance.
621
622    @param {YUI} fn.Y The YUI instance to which this module is attached.
623    @param {String} fn.name Name of the module
624
625@param {String} version Module version number. This is currently used only for
626    informational purposes, and is not used internally by YUI.
627
628@param {Object} [details] Module config.
629    @param {Array} [details.requires] Array of other module names that must be
630        attached before this module can be attached.
631    @param {Array} [details.optional] Array of optional module names that should
632        be attached before this module is attached if they've already been
633        loaded. If the `loadOptional` YUI option is `true`, optional modules
634        that have not yet been loaded will be loaded just as if they were hard
635        requirements.
636    @param {Array} [details.use] Array of module names that are included within
637        or otherwise provided by this module, and which should be attached
638        automatically when this module is attached. This makes it possible to
639        create "virtual rollup" modules that simply attach a collection of other
640        modules or submodules.
641
642@return {YUI} This YUI instance.
643**/
644    add: function(name, fn, version, details) {
645        details = details || {};
646        var env = YUI.Env,
647            mod = {
648                name: name,
649                fn: fn,
650                version: version,
651                details: details
652            },
653            //Instance hash so we don't apply it to the same instance twice
654            applied = {},
655            loader, inst, modInfo,
656            i, versions = env.versions;
657
658        env.mods[name] = mod;
659        versions[version] = versions[version] || {};
660        versions[version][name] = mod;
661
662        for (i in instances) {
663            if (instances.hasOwnProperty(i)) {
664                inst = instances[i];
665                if (!applied[inst.id]) {
666                    applied[inst.id] = true;
667                    loader = inst.Env._loader;
668                    if (loader) {
669                        modInfo = loader.getModuleInfo(name);
670                        if (!modInfo || modInfo.temp) {
671                            loader.addModule(details, name);
672                        }
673                    }
674                }
675            }
676        }
677
678        return this;
679    },
680
681    /**
682    Executes the callback function associated with each required module,
683    attaching the module to this YUI instance.
684
685    @method _attach
686    @param {Array} r The array of modules to attach
687    @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
688        is not attached.
689    @private
690    **/
691    _attach: function(r, moot) {
692        var i, name, mod, details, req, use, after,
693            mods = YUI.Env.mods,
694            aliases = YUI.Env.aliases,
695            Y = this, j,
696            cache = YUI.Env._renderedMods,
697            loader = Y.Env._loader,
698            done = Y.Env._attached,
699            exported = Y.Env._exported,
700            len = r.length, loader, def, go,
701            c = [],
702            modArgs, esCompat, reqlen, modInfo,
703            condition,
704            __exports__, __imports__;
705
706        //Check for conditional modules (in a second+ instance) and add their requirements
707        //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
708        for (i = 0; i < len; i++) {
709            name = r[i];
710            mod = mods[name];
711            c.push(name);
712            if (loader && loader.conditions[name]) {
713                for (j in loader.conditions[name]) {
714                    if (loader.conditions[name].hasOwnProperty(j)) {
715                        def = loader.conditions[name][j];
716                        go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
717                        if (go) {
718                            c.push(def.name);
719                        }
720                    }
721                }
722            }
723        }
724        r = c;
725        len = r.length;
726
727        for (i = 0; i < len; i++) {
728            if (!done[r[i]]) {
729                name = r[i];
730                mod = mods[name];
731
732                if (aliases && aliases[name] && !mod) {
733                    Y._attach(aliases[name]);
734                    continue;
735                }
736                if (!mod) {
737                    modInfo = loader && loader.getModuleInfo(name);
738                    if (modInfo) {
739                        mod = modInfo;
740                        moot = true;
741                    }
742
743
744                    //if (!loader || !loader.moduleInfo[name]) {
745                    //if ((!loader || !loader.moduleInfo[name]) && !moot) {
746                    if (!moot && name) {
747                        if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
748                            Y.Env._missed.push(name);
749                            Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
750                            Y.message('NOT loaded: ' + name, 'warn', 'yui');
751                        }
752                    }
753                } else {
754                    done[name] = true;
755                    //Don't like this, but in case a mod was asked for once, then we fetch it
756                    //We need to remove it from the missed list ^davglass
757                    for (j = 0; j < Y.Env._missed.length; j++) {
758                        if (Y.Env._missed[j] === name) {
759                            Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
760                            Y.Env._missed.splice(j, 1);
761                        }
762                    }
763
764                    // Optional dependencies normally work by modifying the
765                    // dependency list of a module. If the dependency's test
766                    // passes it is added to the list. If not, it's not loaded.
767                    // This following check ensures that optional dependencies
768                    // are not attached when they were already loaded into the
769                    // page (when bundling for example)
770                    if (loader && !loader._canBeAttached(name)) {
771                        return true;
772                    }
773
774                    /*
775                        If it's a temp module, we need to redo it's requirements if it's already loaded
776                        since it may have been loaded by another instance and it's dependencies might
777                        have been redefined inside the fetched file.
778                    */
779                    if (loader && cache && cache[name] && cache[name].temp) {
780                        loader.getRequires(cache[name]);
781                        req = [];
782                        modInfo = loader.getModuleInfo(name);
783                        for (j in modInfo.expanded_map) {
784                            if (modInfo.expanded_map.hasOwnProperty(j)) {
785                                req.push(j);
786                            }
787                        }
788                        Y._attach(req);
789                    }
790
791                    details = mod.details;
792                    req = details.requires;
793                    esCompat = details.es;
794                    use = details.use;
795                    after = details.after;
796                    //Force Intl load if there is a language (Loader logic) @todo fix this shit
797                    if (details.lang) {
798                        req = req || [];
799                        req.unshift('intl');
800                    }
801
802                    if (req) {
803                        reqlen = req.length;
804                        for (j = 0; j < reqlen; j++) {
805                            if (!done[req[j]]) {
806                                if (!Y._attach(req)) {
807                                    return false;
808                                }
809                                break;
810                            }
811                        }
812                    }
813
814                    if (after) {
815                        for (j = 0; j < after.length; j++) {
816                            if (!done[after[j]]) {
817                                if (!Y._attach(after, true)) {
818                                    return false;
819                                }
820                                break;
821                            }
822                        }
823                    }
824
825                    if (mod.fn) {
826                        modArgs = [Y, name];
827                        if (esCompat) {
828                            __imports__ = {};
829                            __exports__ = {};
830                            // passing `exports` and `imports` onto the module function
831                            modArgs.push(__imports__, __exports__);
832                            if (req) {
833                                reqlen = req.length;
834                                for (j = 0; j < reqlen; j++) {
835                                    __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y;
836                                }
837                            }
838                        }
839                        if (Y.config.throwFail) {
840                            __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
841                        } else {
842                            try {
843                                __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
844                            } catch (e) {
845                                Y.error('Attach error: ' + name, e, name);
846                                return false;
847                            }
848                        }
849                        if (esCompat) {
850                            // store the `exports` in case others `es` modules requires it
851                            exported[name] = __exports__;
852
853                            // If an ES module is conditionally loaded and set
854                            // to be used "instead" another module, replace the
855                            // trigger module's content with the conditionally
856                            // loaded one so the values returned by require()
857                            // still makes sense
858                            condition = mod.details.condition;
859                            if (condition && condition.when === 'instead') {
860                                exported[condition.trigger] = __exports__;
861                            }
862                        }
863                    }
864
865                    if (use) {
866                        for (j = 0; j < use.length; j++) {
867                            if (!done[use[j]]) {
868                                if (!Y._attach(use)) {
869                                    return false;
870                                }
871                                break;
872                            }
873                        }
874                    }
875
876
877
878                }
879            }
880        }
881
882        return true;
883    },
884
885    /**
886    Delays the `use` callback until another event has taken place such as
887    `window.onload`, `domready`, `contentready`, or `available`.
888
889    @private
890    @method _delayCallback
891    @param {Function} cb The original `use` callback.
892    @param {String|Object} until Either an event name ('load', 'domready', etc.)
893        or an object containing event/args keys for contentready/available.
894    @return {Function}
895    **/
896    _delayCallback: function(cb, until) {
897
898        var Y = this,
899            mod = ['event-base'];
900
901        until = (Y.Lang.isObject(until) ? until : { event: until });
902
903        if (until.event === 'load') {
904            mod.push('event-synthetic');
905        }
906
907        return function() {
908            var args = arguments;
909            Y._use(mod, function() {
910                Y.on(until.event, function() {
911                    args[1].delayUntil = until.event;
912                    cb.apply(Y, args);
913                }, until.args);
914            });
915        };
916    },
917
918    /**
919    Attaches one or more modules to this YUI instance. When this is executed,
920    the requirements of the desired modules are analyzed, and one of several
921    things can happen:
922
923
924      * All required modules have already been loaded, and just need to be
925        attached to this YUI instance. In this case, the `use()` callback will
926        be executed synchronously after the modules are attached.
927
928      * One or more modules have not yet been loaded, or the Get utility is not
929        available, or the `bootstrap` config option is `false`. In this case,
930        a warning is issued indicating that modules are missing, but all
931        available modules will still be attached and the `use()` callback will
932        be executed synchronously.
933
934      * One or more modules are missing and the Loader is not available but the
935        Get utility is, and `bootstrap` is not `false`. In this case, the Get
936        utility will be used to load the Loader, and we will then proceed to
937        the following state:
938
939      * One or more modules are missing and the Loader is available. In this
940        case, the Loader will be used to resolve the dependency tree for the
941        missing modules and load them and their dependencies. When the Loader is
942        finished loading modules, the `use()` callback will be executed
943        asynchronously.
944
945    @example
946
947        // Loads and attaches dd and its dependencies.
948        YUI().use('dd', function (Y) {
949            // ...
950        });
951
952        // Loads and attaches dd and node as well as all of their dependencies.
953        YUI().use(['dd', 'node'], function (Y) {
954            // ...
955        });
956
957        // Attaches all modules that have already been loaded.
958        YUI().use('*', function (Y) {
959            // ...
960        });
961
962        // Attaches a gallery module.
963        YUI().use('gallery-yql', function (Y) {
964            // ...
965        });
966
967        // Attaches a YUI 2in3 module.
968        YUI().use('yui2-datatable', function (Y) {
969            // ...
970        });
971
972    @method use
973    @param {String|Array} modules* One or more module names to attach.
974    @param {Function} [callback] Callback function to be executed once all
975        specified modules and their dependencies have been attached.
976    @param {YUI} callback.Y The YUI instance created for this sandbox.
977    @param {Object} callback.status Object containing `success`, `msg` and
978        `data` properties.
979    @chainable
980    **/
981    use: function() {
982        var args = SLICE.call(arguments, 0),
983            callback = args[args.length - 1],
984            Y = this,
985            i = 0,
986            name,
987            Env = Y.Env,
988            provisioned = true;
989
990        // The last argument supplied to use can be a load complete callback
991        if (Y.Lang.isFunction(callback)) {
992            args.pop();
993            if (Y.config.delayUntil) {
994                callback = Y._delayCallback(callback, Y.config.delayUntil);
995            }
996        } else {
997            callback = null;
998        }
999        if (Y.Lang.isArray(args[0])) {
1000            args = args[0];
1001        }
1002
1003        if (Y.config.cacheUse) {
1004            while ((name = args[i++])) {
1005                if (!Env._attached[name]) {
1006                    provisioned = false;
1007                    break;
1008                }
1009            }
1010
1011            if (provisioned) {
1012                if (args.length) {
1013                }
1014                Y._notify(callback, ALREADY_DONE, args);
1015                return Y;
1016            }
1017        }
1018
1019        if (Y._loading) {
1020            Y._useQueue = Y._useQueue || new Y.Queue();
1021            Y._useQueue.add([args, callback]);
1022        } else {
1023            Y._use(args, function(Y, response) {
1024                Y._notify(callback, response, args);
1025            });
1026        }
1027
1028        return Y;
1029    },
1030
1031    /**
1032    Sugar for loading both legacy and ES6-based YUI modules.
1033
1034    @method require
1035    @param {String} [modules*] List of module names to import or a single
1036        module name.
1037    @param {Function} callback Callback that gets called once all the modules
1038        were loaded. Each parameter of the callback is the export value of the
1039        corresponding module in the list. If the module is a legacy YUI module,
1040        the YUI instance is used instead of the module exports.
1041    @example
1042    ```
1043    YUI().require(['es6-set'], function (Y, imports) {
1044        var Set = imports.Set,
1045            set = new Set();
1046    });
1047    ```
1048    **/
1049    require: function () {
1050        var args = SLICE.call(arguments),
1051            callback;
1052
1053        if (typeof args[args.length - 1] === 'function') {
1054            callback = args.pop();
1055
1056            // only add the callback if one was provided
1057            // YUI().require('foo'); is valid
1058            args.push(function (Y) {
1059                var i, length = args.length,
1060                    exported = Y.Env._exported,
1061                    __imports__ = {};
1062
1063                // Get only the imports requested as arguments
1064                for (i = 0; i < length; i++) {
1065                    if (exported.hasOwnProperty(args[i])) {
1066                        __imports__[args[i]] = exported[args[i]];
1067                    }
1068                }
1069
1070                // Using `undefined` because:
1071                // - Using `Y.config.global` would force the value of `this` to be
1072                //   the global object even in strict mode
1073                // - Using `Y` goes against the goal of moving away from a shared
1074                //   object and start thinking in terms of imported and exported
1075                //   objects
1076                callback.call(undefined, Y, __imports__);
1077            });
1078        }
1079        // Do not return the Y object. This makes it hard to follow this
1080        // traditional pattern:
1081        //   var Y = YUI().use(...);
1082        // This is a good idea in the light of ES6 modules, to avoid working
1083        // in the global scope.
1084        // This also leaves the door open for returning a promise, once the
1085        // YUI loader is based on the ES6 loader which uses
1086        // loader.import(...).then(...)
1087        this.use.apply(this, args);
1088    },
1089
1090    /**
1091    Handles Loader notifications about attachment/load errors.
1092
1093    @method _notify
1094    @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
1095    @param {Object} response Response returned from Loader.
1096    @param {Array} args Arguments passed from Loader.
1097    @private
1098    **/
1099    _notify: function(callback, response, args) {
1100        if (!response.success && this.config.loadErrorFn) {
1101            this.config.loadErrorFn.call(this, this, callback, response, args);
1102        } else if (callback) {
1103            if (this.Env._missed && this.Env._missed.length) {
1104                response.msg = 'Missing modules: ' + this.Env._missed.join();
1105                response.success = false;
1106            }
1107            if (this.config.throwFail) {
1108                callback(this, response);
1109            } else {
1110                try {
1111                    callback(this, response);
1112                } catch (e) {
1113                    this.error('use callback error', e, args);
1114                }
1115            }
1116        }
1117    },
1118
1119    /**
1120    Called from the `use` method queue to ensure that only one set of loading
1121    logic is performed at a time.
1122
1123    @method _use
1124    @param {String} args* One or more modules to attach.
1125    @param {Function} [callback] Function to call once all required modules have
1126        been attached.
1127    @private
1128    **/
1129    _use: function(args, callback) {
1130
1131        if (!this.Array) {
1132            this._attach(['yui-base']);
1133        }
1134
1135        var len, loader, handleBoot,
1136            Y = this,
1137            G_ENV = YUI.Env,
1138            mods = G_ENV.mods,
1139            Env = Y.Env,
1140            used = Env._used,
1141            aliases = G_ENV.aliases,
1142            queue = G_ENV._loaderQueue,
1143            firstArg = args[0],
1144            YArray = Y.Array,
1145            config = Y.config,
1146            boot = config.bootstrap,
1147            missing = [],
1148            i,
1149            r = [],
1150            ret = true,
1151            fetchCSS = config.fetchCSS,
1152            process = function(names, skip) {
1153
1154                var i = 0, a = [], name, len, m, req, use;
1155
1156                if (!names.length) {
1157                    return;
1158                }
1159
1160                if (aliases) {
1161                    len = names.length;
1162                    for (i = 0; i < len; i++) {
1163                        if (aliases[names[i]] && !mods[names[i]]) {
1164                            a = [].concat(a, aliases[names[i]]);
1165                        } else {
1166                            a.push(names[i]);
1167                        }
1168                    }
1169                    names = a;
1170                }
1171
1172                len = names.length;
1173
1174                for (i = 0; i < len; i++) {
1175                    name = names[i];
1176                    if (!skip) {
1177                        r.push(name);
1178                    }
1179
1180                    // only attach a module once
1181                    if (used[name]) {
1182                        continue;
1183                    }
1184
1185                    m = mods[name];
1186                    req = null;
1187                    use = null;
1188
1189                    if (m) {
1190                        used[name] = true;
1191                        req = m.details.requires;
1192                        use = m.details.use;
1193                    } else {
1194                        // CSS files don't register themselves, see if it has
1195                        // been loaded
1196                        if (!G_ENV._loaded[VERSION][name]) {
1197                            missing.push(name);
1198                        } else {
1199                            used[name] = true; // probably css
1200                        }
1201                    }
1202
1203                    // make sure requirements are attached
1204                    if (req && req.length) {
1205                        process(req);
1206                    }
1207
1208                    // make sure we grab the submodule dependencies too
1209                    if (use && use.length) {
1210                        process(use, 1);
1211                    }
1212                }
1213
1214            },
1215
1216            handleLoader = function(fromLoader) {
1217                var response = fromLoader || {
1218                        success: true,
1219                        msg: 'not dynamic'
1220                    },
1221                    redo, origMissing,
1222                    ret = true,
1223                    data = response.data;
1224
1225                Y._loading = false;
1226
1227                if (data) {
1228                    origMissing = missing;
1229                    missing = [];
1230                    r = [];
1231                    process(data);
1232                    redo = missing.length;
1233                    if (redo) {
1234                        if ([].concat(missing).sort().join() ==
1235                                origMissing.sort().join()) {
1236                            redo = false;
1237                        }
1238                    }
1239                }
1240
1241                if (redo && data) {
1242                    Y._loading = true;
1243                    Y._use(missing, function() {
1244                        if (Y._attach(data)) {
1245                            Y._notify(callback, response, data);
1246                        }
1247                    });
1248                } else {
1249                    if (data) {
1250                        ret = Y._attach(data);
1251                    }
1252                    if (ret) {
1253                        Y._notify(callback, response, args);
1254                    }
1255                }
1256
1257                if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1258                    Y._use.apply(Y, Y._useQueue.next());
1259                }
1260
1261            };
1262
1263
1264        // YUI().use('*'); // bind everything available
1265        if (firstArg === '*') {
1266            args = [];
1267            for (i in mods) {
1268                if (mods.hasOwnProperty(i)) {
1269                    args.push(i);
1270                }
1271            }
1272            ret = Y._attach(args);
1273            if (ret) {
1274                handleLoader();
1275            }
1276            return Y;
1277        }
1278
1279        if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1280            Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1281        }
1282
1283
1284        // use loader to expand dependencies and sort the
1285        // requirements if it is available.
1286        if (boot && Y.Loader && args.length) {
1287            loader = getLoader(Y);
1288            loader.require(args);
1289            loader.ignoreRegistered = true;
1290            loader._boot = true;
1291            loader.calculate(null, (fetchCSS) ? null : 'js');
1292            args = loader.sorted;
1293            loader._boot = false;
1294        }
1295
1296        process(args);
1297
1298        len = missing.length;
1299
1300
1301        if (len) {
1302            missing = YArray.dedupe(missing);
1303            len = missing.length;
1304        }
1305
1306
1307        // dynamic load
1308        if (boot && len && Y.Loader) {
1309            Y._loading = true;
1310            loader = getLoader(Y);
1311            loader.onEnd = handleLoader;
1312            loader.context = Y;
1313            loader.data = args;
1314            loader.ignoreRegistered = false;
1315            loader.require(missing);
1316            loader.insert(null, (fetchCSS) ? null : 'js');
1317
1318        } else if (boot && len && Y.Get && !Env.bootstrapped) {
1319
1320            Y._loading = true;
1321
1322            handleBoot = function() {
1323                Y._loading = false;
1324                queue.running = false;
1325                Env.bootstrapped = true;
1326                G_ENV._bootstrapping = false;
1327                if (Y._attach(['loader'])) {
1328                    Y._use(args, callback);
1329                }
1330            };
1331
1332            if (G_ENV._bootstrapping) {
1333                queue.add(handleBoot);
1334            } else {
1335                G_ENV._bootstrapping = true;
1336                Y.Get.script(config.base + config.loaderPath, {
1337                    onEnd: handleBoot
1338                });
1339            }
1340
1341        } else {
1342            ret = Y._attach(args);
1343            if (ret) {
1344                handleLoader();
1345            }
1346        }
1347
1348        return Y;
1349    },
1350
1351
1352    /**
1353    Utility method for safely creating namespaces if they don't already exist.
1354    May be called statically on the YUI global object or as a method on a YUI
1355    instance.
1356
1357    When called statically, a namespace will be created on the YUI global
1358    object:
1359
1360        // Create `YUI.your.namespace.here` as nested objects, preserving any
1361        // objects that already exist instead of overwriting them.
1362        YUI.namespace('your.namespace.here');
1363
1364    When called as a method on a YUI instance, a namespace will be created on
1365    that instance:
1366
1367        // Creates `Y.property.package`.
1368        Y.namespace('property.package');
1369
1370    Dots in the input string cause `namespace` to create nested objects for each
1371    token. If any part of the requested namespace already exists, the current
1372    object will be left in place and will not be overwritten. This allows
1373    multiple calls to `namespace` to preserve existing namespaced properties.
1374
1375    If the first token in the namespace string is "YAHOO", that token is
1376    discarded. This is legacy behavior for backwards compatibility with YUI 2.
1377
1378    Be careful with namespace tokens. Reserved words may work in some browsers
1379    and not others. For instance, the following will fail in some browsers
1380    because the supported version of JavaScript reserves the word "long":
1381
1382        Y.namespace('really.long.nested.namespace');
1383
1384    Note: If you pass multiple arguments to create multiple namespaces, only the
1385    last one created is returned from this function.
1386
1387    @method namespace
1388    @param {String} namespace* One or more namespaces to create.
1389    @return {Object} Reference to the last namespace object created.
1390    **/
1391    namespace: function() {
1392        var a = arguments, o, i = 0, j, d, arg;
1393
1394        for (; i < a.length; i++) {
1395            o = this; //Reset base object per argument or it will get reused from the last
1396            arg = a[i];
1397            if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1398                d = arg.split(PERIOD);
1399                for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1400                    o[d[j]] = o[d[j]] || {};
1401                    o = o[d[j]];
1402                }
1403            } else {
1404                o[arg] = o[arg] || {};
1405                o = o[arg]; //Reset base object to the new object so it's returned
1406            }
1407        }
1408        return o;
1409    },
1410
1411    // this is replaced if the log module is included
1412    log: NOOP,
1413    message: NOOP,
1414    // this is replaced if the dump module is included
1415    dump: function (o) { return ''+o; },
1416
1417    /**
1418    Reports an error.
1419
1420    The reporting mechanism is controlled by the `throwFail` configuration
1421    attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1422    truthy, a JS exception is thrown.
1423
1424    If an `errorFn` is specified in the config it must return `true` to indicate
1425    that the exception was handled and keep it from being thrown.
1426
1427    @method error
1428    @param {String} msg Error message.
1429    @param {Error|String} [e] JavaScript error object or an error string.
1430    @param {String} [src] Source of the error (such as the name of the module in
1431        which the error occurred).
1432    @chainable
1433    **/
1434    error: function(msg, e, src) {
1435        //TODO Add check for window.onerror here
1436
1437        var Y = this, ret;
1438
1439        if (Y.config.errorFn) {
1440            ret = Y.config.errorFn.apply(Y, arguments);
1441        }
1442
1443        if (!ret) {
1444            throw (e || new Error(msg));
1445        } else {
1446            Y.message(msg, 'error', ''+src); // don't scrub this one
1447        }
1448
1449        return Y;
1450    },
1451
1452    /**
1453    Generates an id string that is unique among all YUI instances in this
1454    execution context.
1455
1456    @method guid
1457    @param {String} [pre] Prefix.
1458    @return {String} Unique id.
1459    **/
1460    guid: function(pre) {
1461        var id = this.Env._guidp + '_' + (++this.Env._uidx);
1462        return (pre) ? (pre + id) : id;
1463    },
1464
1465    /**
1466    Returns a unique id associated with the given object and (if *readOnly* is
1467    falsy) stamps the object with that id so it can be identified in the future.
1468
1469    Stamping an object involves adding a `_yuid` property to it that contains
1470    the object's id. One exception to this is that in Internet Explorer, DOM
1471    nodes have a `uniqueID` property that contains a browser-generated unique
1472    id, which will be used instead of a YUI-generated id when available.
1473
1474    @method stamp
1475    @param {Object} o Object to stamp.
1476    @param {Boolean} readOnly If truthy and the given object has not already
1477        been stamped, the object will not be modified and `null` will be
1478        returned.
1479    @return {String} Object's unique id, or `null` if *readOnly* was truthy and
1480        the given object was not already stamped.
1481    **/
1482    stamp: function(o, readOnly) {
1483        var uid;
1484        if (!o) {
1485            return o;
1486        }
1487
1488        // IE generates its own unique ID for dom nodes
1489        // The uniqueID property of a document node returns a new ID
1490        if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1491            uid = o.uniqueID;
1492        } else {
1493            uid = (typeof o === 'string') ? o : o._yuid;
1494        }
1495
1496        if (!uid) {
1497            uid = this.guid();
1498            if (!readOnly) {
1499                try {
1500                    o._yuid = uid;
1501                } catch (e) {
1502                    uid = null;
1503                }
1504            }
1505        }
1506        return uid;
1507    },
1508
1509    /**
1510    Destroys this YUI instance.
1511
1512    @method destroy
1513    @since 3.3.0
1514    **/
1515    destroy: function() {
1516        var Y = this;
1517        if (Y.Event) {
1518            Y.Event._unload();
1519        }
1520        delete instances[Y.id];
1521        delete Y.Env;
1522        delete Y.config;
1523    }
1524
1525    /**
1526    Safe `instanceof` wrapper that works around a memory leak in IE when the
1527    object being tested is `window` or `document`.
1528
1529    Unless you are testing objects that may be `window` or `document`, you
1530    should use the native `instanceof` operator instead of this method.
1531
1532    @method instanceOf
1533    @param {Object} o Object to check.
1534    @param {Object} type Class to check against.
1535    @since 3.3.0
1536    **/
1537};
1538
1539    YUI.prototype = proto;
1540
1541    // inheritance utilities are not available yet
1542    for (prop in proto) {
1543        if (proto.hasOwnProperty(prop)) {
1544            YUI[prop] = proto[prop];
1545        }
1546    }
1547
1548    /**
1549    Applies a configuration to all YUI instances in this execution context.
1550
1551    The main use case for this method is in "mashups" where several third-party
1552    scripts need to write to a global YUI config, but cannot share a single
1553    centrally-managed config object. This way they can all call
1554    `YUI.applyConfig({})` instead of overwriting the single global config.
1555
1556    @example
1557
1558        YUI.applyConfig({
1559            modules: {
1560                davglass: {
1561                    fullpath: './davglass.js'
1562                }
1563            }
1564        });
1565
1566        YUI.applyConfig({
1567            modules: {
1568                foo: {
1569                    fullpath: './foo.js'
1570                }
1571            }
1572        });
1573
1574        YUI().use('davglass', function (Y) {
1575            // Module davglass will be available here.
1576        });
1577
1578    @method applyConfig
1579    @param {Object} o Configuration object to apply.
1580    @static
1581    @since 3.5.0
1582    **/
1583    YUI.applyConfig = function(o) {
1584        if (!o) {
1585            return;
1586        }
1587        //If there is a GlobalConfig, apply it first to set the defaults
1588        if (YUI.GlobalConfig) {
1589            this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1590        }
1591        //Apply this config to it
1592        this.prototype.applyConfig.call(this, o);
1593        //Reset GlobalConfig to the combined config
1594        YUI.GlobalConfig = this.config;
1595    };
1596
1597    // set up the environment
1598    YUI._init();
1599
1600    if (hasWin) {
1601        add(doc, 'DOMContentLoaded', handleReady);
1602
1603        // add a window load event at load time so we can capture
1604        // the case where it fires before dynamic loading is
1605        // complete.
1606        add(window, 'load', handleLoad);
1607    } else {
1608        handleReady();
1609        handleLoad();
1610    }
1611
1612    YUI.Env.add = add;
1613    YUI.Env.remove = remove;
1614
1615    /*global exports*/
1616    // Support the CommonJS method for exporting our single global
1617    if (typeof exports == 'object') {
1618        exports.YUI = YUI;
1619        /**
1620        * Set a method to be called when `Get.script` is called in Node.js
1621        * `Get` will open the file, then pass it's content and it's path
1622        * to this method before attaching it. Commonly used for code coverage
1623        * instrumentation. <strong>Calling this multiple times will only
1624        * attach the last hook method</strong>. This method is only
1625        * available in Node.js.
1626        * @method setLoadHook
1627        * @static
1628        * @param {Function} fn The function to set
1629        * @param {String} fn.data The content of the file
1630        * @param {String} fn.path The file path of the file
1631        */
1632        YUI.setLoadHook = function(fn) {
1633            YUI._getLoadHook = fn;
1634        };
1635        /**
1636        * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1637        * @method _getLoadHook
1638        * @private
1639        * @param {String} data The content of the file
1640        * @param {String} path The file path of the file
1641        */
1642        YUI._getLoadHook = null;
1643    }
1644
1645    YUI.Env[VERSION] = {};
1646}());
1647
1648
1649/**
1650Config object that contains all of the configuration options for
1651this `YUI` instance.
1652
1653This object is supplied by the implementer when instantiating YUI. Some
1654properties have default values if they are not supplied by the implementer.
1655
1656This object should not be updated directly because some values are cached. Use
1657`applyConfig()` to update the config object on a YUI instance that has already
1658been configured.
1659
1660@class config
1661@static
1662**/
1663
1664/**
1665If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1666if they're needed to load additional dependencies and aren't already available.
1667
1668Setting this to `false` will prevent YUI from automatically loading the Loader
1669and module metadata, so you will need to manually ensure that they're available
1670or handle dependency resolution yourself.
1671
1672@property {Boolean} bootstrap
1673@default true
1674**/
1675
1676/**
1677
1678@property {Object} filters
1679**/
1680
1681/**
1682If `true`, YUI will use a combo handler to load multiple modules in as few
1683requests as possible.
1684
1685The YUI CDN (which YUI uses by default) supports combo handling, but other
1686servers may not. If the server from which you're loading YUI does not support
1687combo handling, set this to `false`.
1688
1689Providing a value for the `base` config property will cause `combine` to default
1690to `false` instead of `true`.
1691
1692@property {Boolean} combine
1693@default true
1694*/
1695
1696/**
1697Array of module names that should never be dynamically loaded.
1698
1699@property {String[]} ignore
1700**/
1701
1702/**
1703Array of module names that should always be loaded when required, even if
1704already present on the page.
1705
1706@property {String[]} force
1707**/
1708
1709/**
1710DOM element or id that should be used as the insertion point for dynamically
1711added `<script>` and `<link>` nodes.
1712
1713@property {HTMLElement|String} insertBefore
1714**/
1715
1716/**
1717Object hash containing attributes to add to dynamically added `<script>` nodes.
1718
1719@property {Object} jsAttributes
1720**/
1721
1722/**
1723Object hash containing attributes to add to dynamically added `<link>` nodes.
1724
1725@property {Object} cssAttributes
1726**/
1727
1728/**
1729Timeout in milliseconds before a dynamic JS or CSS request will be considered a
1730failure. If not set, no timeout will be enforced.
1731
1732@property {Number} timeout
1733**/
1734
1735/**
1736A hash of module definitions to add to the list of available YUI modules. These
1737modules can then be dynamically loaded via the `use()` method.
1738
1739This is a hash in which keys are module names and values are objects containing
1740module metadata.
1741
1742See `Loader.addModule()` for the supported module metadata fields. Also see
1743`groups`, which provides a way to configure the base and combo spec for a set of
1744modules.
1745
1746@example
1747
1748    modules: {
1749        mymod1: {
1750            requires: ['node'],
1751            fullpath: '/mymod1/mymod1.js'
1752        },
1753
1754        mymod2: {
1755            requires: ['mymod1'],
1756            fullpath: '/mymod2/mymod2.js'
1757        },
1758
1759        mymod3: '/js/mymod3.js',
1760        mycssmod: '/css/mycssmod.css'
1761    }
1762
1763@property {Object} modules
1764**/
1765
1766/**
1767Aliases are dynamic groups of modules that can be used as shortcuts.
1768
1769@example
1770
1771    YUI({
1772        aliases: {
1773            davglass: [ 'node', 'yql', 'dd' ],
1774            mine: [ 'davglass', 'autocomplete']
1775        }
1776    }).use('mine', function (Y) {
1777        // Node, YQL, DD & AutoComplete available here.
1778    });
1779
1780@property {Object} aliases
1781**/
1782
1783/**
1784A hash of module group definitions.
1785
1786For each group you can specify a list of modules and the base path and
1787combo spec to use when dynamically loading the modules.
1788
1789@example
1790
1791    groups: {
1792        yui2: {
1793            // specify whether or not this group has a combo service
1794            combine: true,
1795
1796            // The comboSeperator to use with this group's combo handler
1797            comboSep: ';',
1798
1799            // The maxURLLength for this server
1800            maxURLLength: 500,
1801
1802            // the base path for non-combo paths
1803            base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1804
1805            // the path to the combo service
1806            comboBase: 'http://yui.yahooapis.com/combo?',
1807
1808            // a fragment to prepend to the path attribute when
1809            // when building combo urls
1810            root: '2.8.0r4/build/',
1811
1812            // the module definitions
1813            modules:  {
1814                yui2_yde: {
1815                    path: "yahoo-dom-event/yahoo-dom-event.js"
1816                },
1817                yui2_anim: {
1818                    path: "animation/animation.js",
1819                    requires: ['yui2_yde']
1820                }
1821            }
1822        }
1823    }
1824
1825@property {Object} groups
1826**/
1827
1828/**
1829Path to the Loader JS file, relative to the `base` path.
1830
1831This is used to dynamically bootstrap the Loader when it's needed and isn't yet
1832available.
1833
1834@property {String} loaderPath
1835@default "loader/loader-min.js"
1836**/
1837
1838/**
1839If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
1840`false` to prevent YUI from loading any CSS, or set it to the string `"force"`
1841to force CSS dependencies to be loaded even if their associated JS modules are
1842already loaded.
1843
1844@property {Boolean|String} fetchCSS
1845@default true
1846**/
1847
1848/**
1849Default gallery version used to build gallery module urls.
1850
1851@property {String} gallery
1852@since 3.1.0
1853**/
1854
1855/**
1856Default YUI 2 version used to build YUI 2 module urls.
1857
1858This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
1859`2in3` config for pulling different revisions of the wrapped YUI 2 modules.
1860
1861@property {String} yui2
1862@default "2.9.0"
1863@since 3.1.0
1864**/
1865
1866/**
1867Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
1868
1869@property {String} 2in3
1870@default "4"
1871@since 3.1.0
1872**/
1873
1874/**
1875Alternate console log function that should be used in environments without a
1876supported native console. This function is executed with the YUI instance as its
1877`this` object.
1878
1879@property {Function} logFn
1880@since 3.1.0
1881**/
1882
1883/**
1884The minimum log level to log messages for. Log levels are defined
1885incrementally. Messages greater than or equal to the level specified will
1886be shown. All others will be discarded. The order of log levels in
1887increasing priority is:
1888
1889    debug
1890    info
1891    warn
1892    error
1893
1894@property {String} logLevel
1895@default 'debug'
1896@since 3.10.0
1897**/
1898
1899/**
1900Callback to execute when `Y.error()` is called. It receives the error message
1901and a JavaScript error object if one was provided.
1902
1903This function is executed with the YUI instance as its `this` object.
1904
1905Returning `true` from this function will prevent an exception from being thrown.
1906
1907@property {Function} errorFn
1908@param {String} errorFn.msg Error message
1909@param {Object} [errorFn.err] Error object (if one was provided).
1910@since 3.2.0
1911**/
1912
1913/**
1914A callback to execute when Loader fails to load one or more resources.
1915
1916This could be because of a script load failure. It could also be because a
1917module fails to register itself when the `requireRegistration` config is `true`.
1918
1919If this function is defined, the `use()` callback will only be called when the
1920loader succeeds. Otherwise, `use()` will always executes unless there was a
1921JavaScript error when attaching a module.
1922
1923@property {Function} loadErrorFn
1924@since 3.3.0
1925**/
1926
1927/**
1928If `true`, Loader will expect all loaded scripts to be first-class YUI modules
1929that register themselves with the YUI global, and will trigger a failure if a
1930loaded script does not register a YUI module.
1931
1932@property {Boolean} requireRegistration
1933@default false
1934@since 3.3.0
1935**/
1936
1937/**
1938Cache serviced use() requests.
1939
1940@property {Boolean} cacheUse
1941@default true
1942@since 3.3.0
1943@deprecated No longer used.
1944**/
1945
1946/**
1947Whether or not YUI should use native ES5 functionality when available for
1948features like `Y.Array.each()`, `Y.Object()`, etc.
1949
1950When `false`, YUI will always use its own fallback implementations instead of
1951relying on ES5 functionality, even when ES5 functionality is available.
1952
1953@property {Boolean} useNativeES5
1954@default true
1955@since 3.5.0
1956**/
1957
1958/**
1959 * Leverage native JSON stringify if the browser has a native
1960 * implementation.  In general, this is a good idea.  See the Known Issues
1961 * section in the JSON user guide for caveats.  The default value is true
1962 * for browsers with native JSON support.
1963 *
1964 * @property useNativeJSONStringify
1965 * @type Boolean
1966 * @default true
1967 * @since 3.8.0
1968 */
1969
1970 /**
1971 * Leverage native JSON parse if the browser has a native implementation.
1972 * In general, this is a good idea.  See the Known Issues section in the
1973 * JSON user guide for caveats.  The default value is true for browsers with
1974 * native JSON support.
1975 *
1976 * @property useNativeJSONParse
1977 * @type Boolean
1978 * @default true
1979 * @since 3.8.0
1980 */
1981
1982/**
1983Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
1984
1985@property {Object|String} delayUntil
1986@since 3.6.0
1987@example
1988
1989You can use `load` or `domready` strings by default:
1990
1991    YUI({
1992        delayUntil: 'domready'
1993    }, function (Y) {
1994        // This will not execute until 'domeready' occurs.
1995    });
1996
1997Or you can delay until a node is available (with `available` or `contentready`):
1998
1999    YUI({
2000        delayUntil: {
2001            event: 'available',
2002            args : '#foo'
2003        }
2004    }, function (Y) {
2005        // This will not execute until a node matching the selector "#foo" is
2006        // available in the DOM.
2007    });
2008
2009**/
2010YUI.add('yui-base', function (Y, NAME) {
2011
2012/*
2013 * YUI stub
2014 * @module yui
2015 * @submodule yui-base
2016 */
2017/**
2018 * The YUI module contains the components required for building the YUI
2019 * seed file.  This includes the script loading mechanism, a simple queue,
2020 * and the core utilities for the library.
2021 * @module yui
2022 * @submodule yui-base
2023 */
2024
2025/**
2026 * Provides core language utilites and extensions used throughout YUI.
2027 *
2028 * @class Lang
2029 * @static
2030 */
2031
2032var L = Y.Lang || (Y.Lang = {}),
2033
2034STRING_PROTO = String.prototype,
2035TOSTRING     = Object.prototype.toString,
2036
2037TYPES = {
2038    'undefined'        : 'undefined',
2039    'number'           : 'number',
2040    'boolean'          : 'boolean',
2041    'string'           : 'string',
2042    '[object Function]': 'function',
2043    '[object RegExp]'  : 'regexp',
2044    '[object Array]'   : 'array',
2045    '[object Date]'    : 'date',
2046    '[object Error]'   : 'error'
2047},
2048
2049SUBREGEX         = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
2050
2051WHITESPACE       = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF",
2052WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+",
2053TRIM_LEFT_REGEX  = new RegExp("^" + WHITESPACE_CLASS),
2054TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"),
2055TRIMREGEX        = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"),
2056
2057NATIVE_FN_REGEX  = /\{\s*\[(?:native code|function)\]\s*\}/i;
2058
2059// -- Protected Methods --------------------------------------------------------
2060
2061/**
2062Returns `true` if the given function appears to be implemented in native code,
2063`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
2064if the `useNativeES5` YUI config option is set to `false`.
2065
2066This isn't guaranteed to be 100% accurate and won't work for anything other than
2067functions, but it can be useful for determining whether a function like
2068`Array.prototype.forEach` is native or a JS shim provided by another library.
2069
2070There's a great article by @kangax discussing certain flaws with this technique:
2071<http://perfectionkills.com/detecting-built-in-host-methods/>
2072
2073While his points are valid, it's still possible to benefit from this function
2074as long as it's used carefully and sparingly, and in such a way that false
2075negatives have minimal consequences. It's used internally to avoid using
2076potentially broken non-native ES5 shims that have been added to the page b
2076y
2077other libraries.
2078
2079@method _isNative
2080@param {Function} fn Function to test.
2081@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
2082@static
2083@protected
2084@since 3.5.0
2085**/
2086L._isNative = function (fn) {
2087    return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
2088};
2089
2090// -- Public Methods -----------------------------------------------------------
2091
2092/**
2093 * Determines whether or not the provided item is an array.
2094 *
2095 * Returns `false` for array-like collections such as the function `arguments`
2096 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
2097 * test for an array-like collection.
2098 *
2099 * @method isArray
2100 * @param o The object to test.
2101 * @return {boolean} true if o is an array.
2102 * @static
2103 */
2104L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
2105    return L.type(o) === 'array';
2106};
2107
2108/**
2109 * Determines whether or not the provided item is a boolean.
2110 * @method isBoolean
2111 * @static
2112 * @param o The object to test.
2113 * @return {boolean} true if o is a boolean.
2114 */
2115L.isBoolean = function(o) {
2116    return typeof o === 'boolean';
2117};
2118
2119/**
2120 * Determines whether or not the supplied item is a date instance.
2121 * @method isDate
2122 * @static
2123 * @param o The object to test.
2124 * @return {boolean} true if o is a date.
2125 */
2126L.isDate = function(o) {
2127    return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
2128};
2129
2130/**
2131 * <p>
2132 * Determines whether or not the provided item is a function.
2133 * Note: Internet Explorer thinks certain functions are objects:
2134 * </p>
2135 *
2136 * <pre>
2137 * var obj = document.createElement("object");
2138 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
2139 * &nbsp;
2140 * var input = document.createElement("input"); // append to body
2141 * Y.Lang.isFunction(input.focus) // reports false in IE
2142 * </pre>
2143 *
2144 * <p>
2145 * You will have to implement additional tests if these functions
2146 * matter to you.
2147 * </p>
2148 *
2149 * @method isFunction
2150 * @static
2151 * @param o The object to test.
2152 * @return {boolean} true if o is a function.
2153 */
2154L.isFunction = function(o) {
2155    return L.type(o) === 'function';
2156};
2157
2158/**
2159 * Determines whether or not the provided item is null.
2160 * @method isNull
2161 * @static
2162 * @param o The object to test.
2163 * @return {boolean} true if o is null.
2164 */
2165L.isNull = function(o) {
2166    return o === null;
2167};
2168
2169/**
2170 * Determines whether or not the provided item is a legal number.
2171 * @method isNumber
2172 * @static
2173 * @param o The object to test.
2174 * @return {boolean} true if o is a number.
2175 */
2176L.isNumber = function(o) {
2177    return typeof o === 'number' && isFinite(o);
2178};
2179
2180/**
2181 * Determines whether or not the provided item is of type object
2182 * or function. Note that arrays are also objects, so
2183 * <code>Y.Lang.isObject([]) === true</code>.
2184 * @method isObject
2185 * @static
2186 * @param o The object to test.
2187 * @param failfn {boolean} fail if the input is a function.
2188 * @return {boolean} true if o is an object.
2189 * @see isPlainObject
2190 */
2191L.isObject = function(o, failfn) {
2192    var t = typeof o;
2193    return (o && (t === 'object' ||
2194        (!failfn && (t === 'function' || L.isFunction(o))))) || false;
2195};
2196
2197/**
2198 * Determines whether or not the provided value is a regexp.
2199 * @method isRegExp
2200 * @static
2201 * @param value The value or object to test.
2202 * @return {boolean} true if value is a regexp.
2203 */
2204L.isRegExp = function(value) {
2205    return L.type(value) === 'regexp';
2206};
2207
2208/**
2209 * Determines whether or not the provided item is a string.
2210 * @method isString
2211 * @static
2212 * @param o The object to test.
2213 * @return {boolean} true if o is a string.
2214 */
2215L.isString = function(o) {
2216    return typeof o === 'string';
2217};
2218
2219/**
2220 * Determines whether or not the provided item is undefined.
2221 * @method isUndefined
2222 * @static
2223 * @param o The object to test.
2224 * @return {boolean} true if o is undefined.
2225 */
2226L.isUndefined = function(o) {
2227    return typeof o === 'undefined';
2228};
2229
2230/**
2231 * A convenience method for detecting a legitimate non-null value.
2232 * Returns false for null/undefined/NaN, true for other values,
2233 * including 0/false/''
2234 * @method isValue
2235 * @static
2236 * @param o The item to test.
2237 * @return {boolean} true if it is not null/undefined/NaN || false.
2238 */
2239L.isValue = function(o) {
2240    var t = L.type(o);
2241
2242    switch (t) {
2243        case 'number':
2244            return isFinite(o);
2245
2246        case 'null': // fallthru
2247        case 'undefined':
2248            return false;
2249
2250        default:
2251            return !!t;
2252    }
2253};
2254
2255/**
2256 * Returns the current time in milliseconds.
2257 *
2258 * @method now
2259 * @return {Number} Current time in milliseconds.
2260 * @static
2261 * @since 3.3.0
2262 */
2263L.now = Date.now || function () {
2264    return new Date().getTime();
2265};
2266
2267/**
2268 * Performs `{placeholder}` substitution on a string. The object passed as the
2269 * second parameter provides values to replace the `{placeholder}`s.
2270 * `{placeholder}` token names must match property names of the object. For example,
2271 *
2272 *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });`
2273 *
2274 * `{placeholder}` tokens that are undefined on the object map will be left
2275 * in tact (leaving unsightly `{placeholder}`'s in the output string).
2276 *
2277 * @method sub
2278 * @param {string} s String to be modified.
2279 * @param {object} o Object containing replacement values.
2280 * @return {string} the substitute result.
2281 * @static
2282 * @since 3.2.0
2283 */
2284L.sub = function(s, o) {
2285
2286    /**
2287    Finds the value of `key` in given object.
2288    If the key has a 'dot' notation e.g. 'foo.bar.baz', the function will
2289    try to resolve this path if it doesn't exist as a property
2290    @example
2291        value({ 'a.b': 1, a: { b: 2 } }, 'a.b'); // 1
2292        value({ a: { b: 2 } }          , 'a.b'); // 2
2293    @param {Object} obj A key/value pairs object
2294    @param {String} key
2295    @return {Any}
2296    @private
2297    **/
2298    function value(obj, key) {
2299
2300        var subkey;
2301
2302        if ( typeof obj[key] !== 'undefined' ) {
2303            return obj[key];
2304        }
2305
2306        key    = key.split('.');         // given 'a.b.c'
2307        subkey = key.slice(1).join('.'); // 'b.c'
2308        key    = key[0];                 // 'a'
2309
2310        // special case for null as typeof returns object and we don't want that.
2311        if ( subkey && typeof obj[key] === 'object' && obj[key] !== null ) {
2312            return value(obj[key], subkey);
2313        }
2314    }
2315
2316    return s.replace ? s.replace(SUBREGEX, function (match, key) {
2317        var val = key.indexOf('.')>-1 ? value(o, key) : o[key];
2318        return typeof val === 'undefined' ? match : val;
2319    }) : s;
2320};
2321
2322/**
2323 * Returns a string without any leading or trailing whitespace.  If
2324 * the input is not a string, the input will be returned untouched.
2325 * @method trim
2326 * @static
2327 * @param s {string} the string to trim.
2328 * @return {string} the trimmed string.
2329 */
2330L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) {
2331    return s && s.trim ? s.trim() : s;
2332} : function (s) {
2333    try {
2334        return s.replace(TRIMREGEX, '');
2335    } catch (e) {
2336        return s;
2337    }
2338};
2339
2340/**
2341 * Returns a string without any leading whitespace.
2342 * @method trimLeft
2343 * @static
2344 * @param s {string} the string to trim.
2345 * @return {string} the trimmed string.
2346 */
2347L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) {
2348    return s.trimLeft();
2349} : function (s) {
2350    return s.replace(TRIM_LEFT_REGEX, '');
2351};
2352
2353/**
2354 * Returns a string without any trailing whitespace.
2355 * @method trimRight
2356 * @static
2357 * @param s {string} the string to trim.
2358 * @return {string} the trimmed string.
2359 */
2360L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) {
2361    return s.trimRight();
2362} : function (s) {
2363    return s.replace(TRIM_RIGHT_REGEX, '');
2364};
2365
2366/**
2367Returns one of the following strings, representing the type of the item passed
2368in:
2369
2370 * "array"
2371 * "boolean"
2372 * "date"
2373 * "error"
2374 * "function"
2375 * "null"
2376 * "number"
2377 * "object"
2378 * "regexp"
2379 * "string"
2380 * "undefined"
2381
2382Known issues:
2383
2384 * `typeof HTMLElementCollection` returns function in Safari, but
2385    `Y.Lang.type()` reports "object", which could be a good thing --
2386    but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2387
2388@method type
2389@param o the item to test.
2390@return {string} the detected type.
2391@static
2392**/
2393L.type = function(o) {
2394    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2395};
2396/**
2397@module yui
2398@submodule yui-base
2399*/
2400
2401var Lang   = Y.Lang,
2402    Native = Array.prototype,
2403
2404    hasOwn = Object.prototype.hasOwnProperty;
2405
2406/**
2407Provides utility methods for working with arrays. Additional array helpers can
2408be found in the `collection` and `array-extras` modules.
2409
2410`Y.Array(thing)` returns a native array created from _thing_. Depending on
2411_thing_'s type, one of the following will happen:
2412
2413  * Arrays are returned unmodified unless a non-zero _startIndex_ is
2414    specified.
2415  * Array-like collections (see `Array.test()`) are converted to arrays.
2416  * For everything else, a new array is created with _thing_ as the sole
2417    item.
2418
2419Note: elements that are also collections, such as `<form>` and `<select>`
2420elements, are not automatically converted to arrays. To force a conversion,
2421pass `true` as the value of the _force_ parameter.
2422
2423@class Array
2424@constructor
2425@param {Any} thing The thing to arrayify.
2426@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2427  collection, a subset of items starting at the specified index will be
2428  returned.
2429@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2430  array-like collection no matter what.
2431@return {Array} A native array created from _thing_, according to the rules
2432  described above.
2433**/
2434function YArray(thing, startIndex, force) {
2435    var len, result;
2436
2437    /*jshint expr: true*/
2438    startIndex || (startIndex = 0);
2439
2440    if (force || YArray.test(thing)) {
2441        // IE throws when trying to slice HTMLElement collections.
2442        try {
2443            return Native.slice.call(thing, startIndex);
2444        } catch (ex) {
2445            result = [];
2446
2447            for (len = thing.length; startIndex < len; ++startIndex) {
2448                result.push(thing[startIndex]);
2449            }
2450
2451            return result;
2452        }
2453    }
2454
2455    return [thing];
2456}
2457
2458Y.Array = YArray;
2459
2460/**
2461Dedupes an array of strings, returning an array that's guaranteed to contain
2462only one copy of a given string.
2463
2464This method differs from `Array.unique()` in that it's optimized for use only
2465with arrays consisting entirely of strings or entirely of numbers, whereas
2466`unique` may be used with other value types (but is slower).
2467
2468Using `dedupe()` with values other than strings or numbers, or with arrays
2469containing a mix of strings and numbers, may result in unexpected behavior.
2470
2471@method dedupe
2472@param {String[]|Number[]} array Array of strings or numbers to dedupe.
2473@return {Array} Copy of _array_ containing no duplicate values.
2474@static
2475@since 3.4.0
2476**/
2477YArray.dedupe = Lang._isNative(Object.create) ? function (array) {
2478    var hash    = Object.create(null),
2479        results = [],
2480        i, item, len;
2481
2482    for (i = 0, len = array.length; i < len; ++i) {
2483        item = array[i];
2484
2485        if (!hash[item]) {
2486            hash[item] = 1;
2487            results.push(item);
2488        }
2489    }
2490
2491    return results;
2492} : function (array) {
2493    var hash    = {},
2494        results = [],
2495        i, item, len;
2496
2497    for (i = 0, len = array.length; i < len; ++i) {
2498        item = array[i];
2499
2500        if (!hasOwn.call(hash, item)) {
2501            hash[item] = 1;
2502            results.push(item);
2503        }
2504    }
2505
2506    return results;
2507};
2508
2509/**
2510Executes the supplied function on each item in the array. This method wraps
2511the native ES5 `Array.forEach()` method if available.
2512
2513@method each
2514@param {Array} array Array to iterate.
2515@param {Function} fn Function to execute on each item in the array. The function
2516  will receive the following arguments:
2517    @param {Any} fn.item Current array item.
2518    @param {Number} fn.index Current array index.
2519    @param {Array} fn.array Array being iterated.
2520@param {Object} [thisObj] `this` object to use when calling _fn_.
2521@return {YUI} The YUI instance.
2522@static
2523**/
2524YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2525    Native.forEach.call(array || [], fn, thisObj || Y);
2526    return Y;
2527} : function (array, fn, thisObj) {
2528    for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2529        if (i in array) {
2530            fn.call(thisObj || Y, array[i], i, array);
2531        }
2532    }
2533
2534    return Y;
2535};
2536
2537/**
2538Alias for `each()`.
2539
2540@method forEach
2541@static
2542**/
2543
2544/**
2545Returns an object using the first array as keys and the second as values. If
2546the second array is not provided, or if it doesn't contain the same number of
2547values as the first array, then `true` will be used in place of the missing
2548values.
2549
2550@example
2551
2552    Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2553    // => {a: 'foo', b: 'bar', c: true}
2554
2555@method hash
2556@param {String[]} keys Array of strings to use as keys.
2557@param {Array} [values] Array to use as values.
2558@return {Object} Hash using the first array as keys and the second as values.
2559@static
2560**/
2561YArray.hash = function (keys, values) {
2562    var hash = {},
2563        vlen = (values && values.length) || 0,
2564        i, len;
2565
2566    for (i = 0, len = keys.length; i < len; ++i) {
2567        if (i in keys) {
2568            hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2569        }
2570    }
2571
2572    return hash;
2573};
2574
2575/**
2576Returns the index of the first item in the array that's equal (using a strict
2577equality check) to the specified _value_, or `-1` if the value isn't found.
2578
2579This method wraps the native ES5 `Array.indexOf()` method if available.
2580
2581@method indexOf
2582@param {Array} array Array to search.
2583@param {Any} value Value to search for.
2584@param {Number} [from=0] The index at which to begin the search.
2585@return {Number} Index of the item strictly equal to _value_, or `-1` if not
2586    found.
2587@static
2588**/
2589YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2590    return Native.indexOf.call(array, value, from);
2591} : function (array, value, from) {
2592    // http://es5.github.com/#x15.4.4.14
2593    var len = array.length;
2594
2595    from = +from || 0;
2596    from = (from > 0 || -1) * Math.floor(Math.abs(from));
2597
2598    if (from < 0) {
2599        from += len;
2600
2601        if (from < 0) {
2602            from = 0;
2603        }
2604    }
2605
2606    for (; from < len; ++from) {
2607        if (from in array && array[from] === value) {
2608            return from;
2609        }
2610    }
2611
2612    return -1;
2613};
2614
2615/**
2616Numeric sort convenience function.
2617
2618The native `Array.prototype.sort()` function converts values to strings and
2619sorts them in lexicographic order, which is unsuitable for sorting numeric
2620values. Provide `Array.numericSort` as a custom sort function when you want
2621to sort values in numeric order.
2622
2623@example
2624
2625    [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2626    // => [4, 8, 15, 16, 23, 42]
2627
2628@method numericSort
2629@param {Number} a First value to compare.
2630@param {Number} b Second value to compare.
2631@return {Number} Difference between _a_ and _b_.
2632@static
2633**/
2634YArray.numericSort = function (a, b) {
2635    return a - b;
2636};
2637
2638/**
2639Executes the supplied function on each item in the array. Returning a truthy
2640value from the function will stop the processing of remaining items.
2641
2642@method some
2643@param {Array} array Array to iterate over.
2644@param {Function} fn Function to execute on each item. The function will receive
2645  the following arguments:
2646    @param {Any} fn.value Current array item.
2647    @param {Number} fn.index Current array index.
2648    @param {Array} fn.array Array being iterated over.
2649@param {Object} [thisObj] `this` object to use when calling _fn_.
2650@return {Boolean} `true` if the function returns a truthy value on any of the
2651  items in the array; `false` otherwise.
2652@static
2653**/
2654YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2655    return Native.some.call(array, fn, thisObj);
2656} : function (array, fn, thisObj) {
2657    for (var i = 0, len = array.length; i < len; ++i) {
2658        if (i in array && fn.call(thisObj, array[i], i, array)) {
2659            return true;
2660        }
2661    }
2662
2663    return false;
2664};
2665
2666/**
2667Evaluates _obj_ to determine if it's an array, an array-like collection, or
2668something else. This is useful when working with the function `arguments`
2669collection and `HTMLElement` collections.
2670
2671Note: This implementation doesn't consider elements that are also
2672collections, such as `<form>` and `<select>`, to be array-like.
2673
2674@method test
2675@param {Object} obj Object to test.
2676@return {Number} A number indicating the results of the test:
2677
2678  * 0: Neither an array nor an array-like collection.
2679  * 1: Real array.
2680  * 2: Array-like collection.
2681
2682@static
2683**/
2684YArray.test = function (obj) {
2685    var result = 0;
2686
2687    if (Lang.isArray(obj)) {
2688        result = 1;
2689    } else if (Lang.isObject(obj)) {
2690        try {
2691            // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2692            // or functions without apply/call (Safari
2693            // HTMLElementCollection bug).
2694            if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2695                result = 2;
2696            }
2697        } catch (ex) {}
2698    }
2699
2700    return result;
2701};
2702/**
2703 * The YUI module contains the components required for building the YUI
2704 * seed file.  This includes the script loading mechanism, a simple queue,
2705 * and the core utilities for the library.
2706 * @module yui
2707 * @submodule yui-base
2708 */
2709
2710/**
2711 * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
2712 * removed using next().
2713 *
2714 * @class Queue
2715 * @constructor
2716 * @param {MIXED} item* 0..n items to seed the queue.
2717 */
2718function Queue() {
2719    this._init();
2720    this.add.apply(this, arguments);
2721}
2722
2723Queue.prototype = {
2724    /**
2725     * Initialize the queue
2726     *
2727     * @method _init
2728     * @protected
2729     */
2730    _init: function() {
2731        /**
2732         * The collection of enqueued items
2733         *
2734         * @property _q
2735         * @type Array
2736         * @protected
2737         */
2738        this._q = [];
2739    },
2740
2741    /**
2742     * Get the next item in the queue. FIFO support
2743     *
2744     * @method next
2745     * @return {MIXED} the next item in the queue.
2746     */
2747    next: function() {
2748        return this._q.shift();
2749    },
2750
2751    /**
2752     * Get the last in the queue. LIFO support.
2753     *
2754     * @method last
2755     * @return {MIXED} the last item in the queue.
2756     */
2757    last: function() {
2758        return this._q.pop();
2759    },
2760
2761    /**
2762     * Add 0..n items to the end of the queue.
2763     *
2764     * @method add
2765     * @param {MIXED} item* 0..n items.
2766     * @return {object} this queue.
2767     */
2768    add: function() {
2769        this._q.push.apply(this._q, arguments);
2770
2771        return this;
2772    },
2773
2774    /**
2775     * Returns the current number of queued items.
2776     *
2777     * @method size
2778     * @return {Number} The size.
2779     */
2780    size: function() {
2781        return this._q.length;
2782    }
2783};
2784
2785Y.Queue = Queue;
2786
2787YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2788
2789/**
2790The YUI module contains the components required for building the YUI seed file.
2791This includes the script loading mechanism, a simple queue, and the core
2792utilities for the library.
2793
2794@module yui
2795@submodule yui-base
2796**/
2797
2798var CACHED_DELIMITER = '__',
2799
2800    hasOwn   = Object.prototype.hasOwnProperty,
2801    isObject = Y.Lang.isObject;
2802
2803/**
2804Returns a wrapper for a function which caches the return value of that function,
2805keyed off of the combined string representation of the argument values provided
2806when the wrapper is called.
2807
2808Calling this function again with the same arguments will return the cached value
2809rather than executing the wrapped function.
2810
2811Note that since the cache is keyed off of the string representation of arguments
2812passed to the wrapper function, arguments that aren't strings and don't provide
2813a meaningful `toString()` method may result in unexpected caching behavior. For
2814example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2815string `[object Object]` when used as a cache key.
2816
2817@method cached
2818@param {Function} source The function to memoize.
2819@param {Object} [cache={}] Object in which to store cached values. You may seed
2820  this object with pre-existing cached values if desired.
2821@param {any} [refetch] If supplied, this value is compared with the cached value
2822  using a `==` comparison. If the values are equal, the wrapped function is
2823  executed again even though a cached value exists.
2824@return {Function} Wrapped function.
2825@for YUI
2826**/
2827Y.cached = function (source, cache, refetch) {
2828    /*jshint expr: true*/
2829    cache || (cache = {});
2830
2831    return function (arg) {
2832        var key = arguments.length > 1 ?
2833                Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2834                String(arg);
2835
2836        /*jshint eqeqeq: false*/
2837        if (!(key in cache) || (refetch && cache[key] == refetch)) {
2838            cache[key] = source.apply(source, arguments);
2839        }
2840
2841        return cache[key];
2842    };
2843};
2844
2845/**
2846Returns the `location` object from the window/frame in which this YUI instance
2847operates, or `undefined` when executing in a non-browser environment
2848(e.g. Node.js).
2849
2850It is _not_ recommended to hold references to the `window.location` object
2851outside of the scope of a function in which its properties are being accessed or
2852its methods are being called. This is because of a nasty bug/issue that exists
2853in both Safari and MobileSafari browsers:
2854[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
2855
2856@method getLocation
2857@return {location} The `location` object from the window/frame in which this YUI
2858    instance operates.
2859@since 3.5.0
2860**/
2861Y.getLocation = function () {
2862    // It is safer to look this up every time because yui-base is attached to a
2863    // YUI instance before a user's config is applied; i.e. `Y.config.win` does
2864    // not point the correct window object when this file is loaded.
2865    var win = Y.config.win;
2866
2867    // It is not safe to hold a reference to the `location` object outside the
2868    // scope in which it is being used. The WebKit engine used in Safari and
2869    // MobileSafari will "disconnect" the `location` object from the `window`
2870    // when a page is restored from back/forward history cache.
2871    return win && win.location;
2872};
2873
2874/**
2875Returns a new object containing all of the properties of all the supplied
2876objects. The properties from later objects will overwrite those in earlier
2877objects.
2878
2879Passing in a single object will create a shallow copy of it. For a deep copy,
2880use `clone()`.
2881
2882@method merge
2883@param {Object} objects* One or more objects to merge.
2884@return {Object} A new merged object.
2885**/
2886Y.merge = function () {
2887    var i      = 0,
2888        len    = arguments.length,
2889        result = {},
2890        key,
2891        obj;
2892
2893    for (; i < len; ++i) {
2894        obj = arguments[i];
2895
2896        for (key in obj) {
2897            if (hasOwn.call(obj, key)) {
2898                result[key] = obj[key];
2899            }
2900        }
2901    }
2902
2903    return result;
2904};
2905
2906/**
2907Mixes _supplier_'s properties into _receiver_.
2908
2909Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2910shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2911unless the _merge_ parameter is `true`.
2912
2913In the default mode (0), only properties the supplier owns are copied (prototype
2914properties are not copied). The following copying modes are available:
2915
2916  * `0`: _Default_. Object to object.
2917  * `1`: Prototype to prototype.
2918  * `2`: Prototype to prototype and object to object.
2919  * `3`: Prototype to object.
2920  * `4`: Object to prototype.
2921
2922@method mix
2923@param {Function|Object} receiver The object or function to receive the mixed
2924  properties.
2925@param {Function|Object} supplier The object or function supplying the
2926  properties to be mixed.
2927@param {Boolean} [overwrite=false] If `true`, properties that already exist
2928  on the receiver will be overwritten with properties from the supplier.
2929@param {String[]} [whitelist] An array of property names to copy. If
2930  specified, only the whitelisted properties will be copied, and all others
2931  will be ignored.
2932@param {Number} [mode=0] Mix mode to use. See above for available modes.
2933@param {Boolean} [merge=false] If `true`, objects and arrays that already
2934  exist on the receiver will have the corresponding object/array from the
2935  supplier merged into them, rather than being skipped or overwritten. When
2936  both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2937@return {Function|Object|YUI} The receiver, or the YUI instance if the
2938  specified receiver is falsy.
2939**/
2940Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2941    var alwaysOverwrite, exists, from, i, key, len, to;
2942
2943    // If no supplier is given, we return the receiver. If no receiver is given,
2944    // we return Y. Returning Y doesn't make much sense to me, but it's
2945    // grandfathered in for backcompat reasons.
2946    if (!receiver || !supplier) {
2947        return receiver || Y;
2948    }
2949
2950    if (mode) {
2951        // In mode 2 (prototype to prototype and object to object), we recurse
2952        // once to do the proto to proto mix. The object to object mix will be
2953        // handled later on.
2954        if (mode === 2) {
2955            Y.mix(receiver.prototype, supplier.prototype, overwrite,
2956                    whitelist, 0, merge);
2957        }
2958
2959        // Depending on which mode is specified, we may be copying from or to
2960        // the prototypes of the supplier and receiver.
2961        from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
2962        to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
2963
2964        // If either the supplier or receiver doesn't actually have a
2965        // prototype property, then we could end up with an undefined `from`
2966        // or `to`. If that happens, we abort and return the receiver.
2967        if (!from || !to) {
2968            return receiver;
2969        }
2970    } else {
2971        from = supplier;
2972        to   = receiver;
2973    }
2974
2975    // If `overwrite` is truthy and `merge` is falsy, then we can skip a
2976    // property existence check on each iteration and save some time.
2977    alwaysOverwrite = overwrite && !merge;
2978
2979    if (whitelist) {
2980        for (i = 0, len = whitelist.length; i < len; ++i) {
2981            key = whitelist[i];
2982
2983            // We call `Object.prototype.hasOwnProperty` instead of calling
2984            // `hasOwnProperty` on the object itself, since the object's
2985            // `hasOwnProperty` method may have been overridden or removed.
2986            // Also, some native objects don't implement a `hasOwnProperty`
2987            // method.
2988            if (!hasOwn.call(from, key)) {
2989                continue;
2990            }
2991
2992            // The `key in to` check here is (sadly) intentional for backwards
2993            // compatibility reasons. It prevents undesired shadowing of
2994            // prototype members on `to`.
2995            exists = alwaysOverwrite ? false : key in to;
2996
2997            if (merge && exists && isObject(to[key], true)
2998                    && isObject(from[key], true)) {
2999                // If we're in merge mode, and the key is present on both
3000                // objects, and the value on both objects is either an object or
3001                // an array (but not a function), then we recurse to merge the
3002                // `from` value into the `to` value instead of overwriting it.
3003                //
3004                // Note: It's intentional that the whitelist isn't passed to the
3005                // recursive call here. This is legacy behavior that lots of
3006                // code still depends on.
3007                Y.mix(to[key], from[key], overwrite, null, 0, merge);
3008            } else if (overwrite || !exists) {
3009                // We're not in merge mode, so we'll only copy the `from` value
3010                // to the `to` value if we're in overwrite mode or if the
3011                // current key doesn't exist on the `to` object.
3012                to[key] = from[key];
3013            }
3014        }
3015    } else {
3016        for (key in from) {
3017            // The code duplication here is for runtime performance reasons.
3018            // Combining whitelist and non-whitelist operations into a single
3019            // loop or breaking the shared logic out into a function both result
3020            // in worse performance, and Y.mix is critical enough that the byte
3021            // tradeoff is worth it.
3022            if (!hasOwn.call(from, key)) {
3023                continue;
3024            }
3025
3026            // The `key in to` check here is (sadly) intentional for backwards
3027            // compatibility reasons. It prevents undesired shadowing of
3028            // prototype members on `to`.
3029            exists = alwaysOverwrite ? false : key in to;
3030
3031            if (merge && exists && isObject(to[key], true)
3032                    && isObject(from[key], true)) {
3033                Y.mix(to[key], from[key], overwrite, null, 0, merge);
3034            } else if (overwrite || !exists) {
3035                to[key] = from[key];
3036            }
3037        }
3038
3039        // If this is an IE browser with the JScript enumeration bug, force
3040        // enumeration of the buggy properties by making a recursive call with
3041        // the buggy properties as the whitelist.
3042        if (Y.Object._hasEnumBug) {
3043            Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
3044        }
3045    }
3046
3047    return receiver;
3048};
3049/**
3050 * The YUI module contains the components required for building the YUI
3051 * seed file.  This includes the script loading mechanism, a simple queue,
3052 * and the core utilities for the library.
3053 * @module yui
3054 * @submodule yui-base
3055 */
3056
3057/**
3058 * Adds utilities to the YUI instance for working with objects.
3059 *
3060 * @class Object
3061 */
3062
3063var Lang   = Y.Lang,
3064    hasOwn = Object.prototype.hasOwnProperty,
3065
3066    UNDEFINED, // <-- Note the comma. We're still declaring vars.
3067
3068/**
3069 * Returns a new object that uses _obj_ as its prototype. This method wraps the
3070 * native ES5 `Object.create()` method if available, but doesn't currently
3071 * pass through `Object.create()`'s second argument (properties) in order to
3072 * ensure compatibility with older browsers.
3073 *
3074 * @method ()
3075 * @param {Object} obj Prototype object.
3076 * @return {Object} New object using _obj_ as its prototype.
3077 * @static
3078 */
3079O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
3080    // We currently wrap the native Object.create instead of simply aliasing it
3081    // to ensure consistency with our fallback shim, which currently doesn't
3082    // support Object.create()'s second argument (properties). Once we have a
3083    // safe fallback for the properties arg, we can stop wrapping
3084    // Object.create().
3085    return Object.create(obj);
3086} : (function () {
3087    // Reusable constructor function for the Object.create() shim.
3088    function F() {}
3089
3090    // The actual shim.
3091    return function (obj) {
3092        F.prototype = obj;
3093        return new F();
3094    };
3095}()),
3096
3097/**
3098 * Property names that IE doesn't enumerate in for..in loops, even when they
3099 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
3100 * manually enumerate these properties.
3101 *
3102 * @property _forceEnum
3103 * @type String[]
3104 * @protected
3105 * @static
3106 */
3107forceEnum = O._forceEnum = [
3108    'hasOwnProperty',
3109    'isPrototypeOf',
3110    'propertyIsEnumerable',
3111    'toString',
3112    'toLocaleString',
3113    'valueOf'
3114],
3115
3116/**
3117 * `true` if this browser has the JScript enumeration bug that prevents
3118 * enumeration of the properties named in the `_forceEnum` array, `false`
3119 * otherwise.
3120 *
3121 * See:
3122 *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
3123 *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
3124 *
3125 * @property _hasEnumBug
3126 * @type Boolean
3127 * @protected
3128 * @static
3129 */
3130hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
3131
3132/**
3133 * `true` if this browser incorrectly considers the `prototype` property of
3134 * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x.
3135 *
3136 * @property _hasProtoEnumBug
3137 * @type Boolean
3138 * @protected
3139 * @static
3140 */
3141hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
3142
3143/**
3144 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
3145 * exists only on _obj_'s prototype. This is essentially a safer version of
3146 * `obj.hasOwnProperty()`.
3147 *
3148 * @method owns
3149 * @param {Object} obj Object to test.
3150 * @param {String} key Property name to look for.
3151 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3152 * @static
3153 */
3154owns = O.owns = function (obj, key) {
3155    return !!obj && hasOwn.call(obj, key);
3156}; // <-- End of var declarations.
3157
3158/**
3159 * Alias for `owns()`.
3160 *
3161 * @method hasKey
3162 * @param {Object} obj Object to test.
3163 * @param {String} key Property name to look for.
3164 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3165 * @static
3166 */
3167O.hasKey = owns;
3168
3169/**
3170 * Returns an array containing the object's enumerable keys. Does not include
3171 * prototype keys or non-enumerable keys.
3172 *
3173 * Note that keys are returned in enumeration order (that is, in the same order
3174 * that they would be enumerated by a `for-in` loop), which may not be the same
3175 * as the order in which they were defined.
3176 *
3177 * This method is an alias for the native ES5 `Object.keys()` method if
3178 * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of
3179 * `Object.keys()` have an inconsistency as they consider `prototype` to be
3180 * enumerable, so a non-native shim is used to rectify the difference.
3181 *
3182 * @example
3183 *
3184 *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
3185 *     // => ['a', 'b', 'c']
3186 *
3187 * @method keys
3188 * @param {Object} obj An object.
3189 * @return {String[]} Array of keys.
3190 * @static
3191 */
3192O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) {
3193    if (!Lang.isObject(obj)) {
3194        throw new TypeError('Object.keys called on a non-object');
3195    }
3196
3197    var keys = [],
3198        i, key, len;
3199
3200    if (hasProtoEnumBug && typeof obj === 'function') {
3201        for (key in obj) {
3202            if (owns(obj, key) && key !== 'prototype') {
3203                keys.push(key);
3204            }
3205        }
3206    } else {
3207        for (key in obj) {
3208            if (owns(obj, key)) {
3209                keys.push(key);
3210            }
3211        }
3212    }
3213
3214    if (hasEnumBug) {
3215        for (i = 0, len = forceEnum.length; i < len; ++i) {
3216            key = forceEnum[i];
3217
3218            if (owns(obj, key)) {
3219                keys.push(key);
3220            }
3221        }
3222    }
3223
3224    return keys;
3225};
3226
3227/**
3228 * Returns an array containing the values of the object's enumerable keys.
3229 *
3230 * Note that values are returned in enumeration order (that is, in the same
3231 * order that they would be enumerated by a `for-in` loop), which may not be the
3232 * same as the order in which they were defined.
3233 *
3234 * @example
3235 *
3236 *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
3237 *     // => ['foo', 'bar', 'baz']
3238 *
3239 * @method values
3240 * @param {Object} obj An object.
3241 * @return {Array} Array of values.
3242 * @static
3243 */
3244O.values = function (obj) {
3245    var keys   = O.keys(obj),
3246        i      = 0,
3247        len    = keys.length,
3248        values = [];
3249
3250    for (; i < len; ++i) {
3251        values.push(obj[keys[i]]);
3252    }
3253
3254    return values;
3255};
3256
3257/**
3258 * Returns the number of enumerable keys owned by an object.
3259 *
3260 * @method size
3261 * @param {Object} obj An object.
3262 * @return {Number} The object's size.
3263 * @static
3264 */
3265O.size = function (obj) {
3266    try {
3267        return O.keys(obj).length;
3268    } catch (ex) {
3269        return 0; // Legacy behavior for non-objects.
3270    }
3271};
3272
3273/**
3274 * Returns `true` if the object owns an enumerable property with the specified
3275 * value.
3276 *
3277 * @method hasValue
3278 * @param {Object} obj An object.
3279 * @param {any} value The value to search for.
3280 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
3281 * @static
3282 */
3283O.hasValue = function (obj, value) {
3284    return Y.Array.indexOf(O.values(obj), value) > -1;
3285};
3286
3287/**
3288 * Executes a function on each enumerable property in _obj_. The function
3289 * receives the value, the key, and the object itself as parameters (in that
3290 * order).
3291 *
3292 * By default, only properties owned by _obj_ are enumerated. To include
3293 * prototype properties, set the _proto_ parameter to `true`.
3294 *
3295 * @method each
3296 * @param {Object} obj Object to enumerate.
3297 * @param {Function} fn Function to execute on each enumerable property.
3298 *   @param {mixed} fn.value Value of the current property.
3299 *   @param {String} fn.key Key of the current property.
3300 *   @param {Object} fn.obj Object being enumerated.
3301 * @param {Object} [thisObj] `this` object to use when calling _fn_.
3302 * @param {Boolean} [proto=false] Include prototype properties.
3303 * @return {YUI} the YUI instance.
3304 * @chainable
3305 * @static
3306 */
3307O.each = function (obj, fn, thisObj, proto) {
3308    var key;
3309
3310    for (key in obj) {
3311        if (proto || owns(obj, key)) {
3312            fn.call(thisObj || Y, obj[key], key, obj);
3313        }
3314    }
3315
3316    return Y;
3317};
3318
3319/**
3320 * Executes a function on each enumerable property in _obj_, but halts if the
3321 * function returns a truthy value. The function receives the value, the key,
3322 * and the object itself as paramters (in that order).
3323 *
3324 * By default, only properties owned by _obj_ are enumerated. To include
3325 * prototype properties, set the _proto_ parameter to `true`.
3326 *
3327 * @method some
3328 * @param {Object} obj Object to enumerate.
3329 * @param {Function} fn Function to execute on each enumerable property.
3330 *   @param {mixed} fn.value Value of the current property.
3331 *   @param {String} fn.key Key of the current property.
3332 *   @param {Object} fn.obj Object being enumerated.
3333 * @param {Object} [thisObj] `this` object to use when calling _fn_.
3334 * @param {Boolean} [proto=false] Include prototype properties.
3335 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3336 *   `false` otherwise.
3337 * @static
3338 */
3339O.some = function (obj, fn, thisObj, proto) {
3340    var key;
3341
3342    for (key in obj) {
3343        if (proto || owns(obj, key)) {
3344            if (fn.call(thisObj || Y, obj[key], key, obj)) {
3345                return true;
3346            }
3347        }
3348    }
3349
3350    return false;
3351};
3352
3353/**
3354 * Retrieves the sub value at the provided path,
3355 * from the value object provided.
3356 *
3357 * @method getValue
3358 * @static
3359 * @param o The object from which to extract the property value.
3360 * @param path {Array} A path array, specifying the object traversal path
3361 * from which to obtain the sub value.
3362 * @return {Any} The value stored in the path, undefined if not found,
3363 * undefined if the source is not an object.  Returns the source object
3364 * if an empty path is provided.
3365 */
3366O.getValue = function(o, path) {
3367    if (!Lang.isObject(o)) {
3368        return UNDEFINED;
3369    }
3370
3371    var i,
3372        p = Y.Array(path),
3373        l = p.length;
3374
3375    for (i = 0; o !== UNDEFINED && i < l; i++) {
3376        o = o[p[i]];
3377    }
3378
3379    return o;
3380};
3381
3382/**
3383 * Sets the sub-attribute value at the provided path on the
3384 * value object.  Returns the modified value object, or
3385 * undefined if the path is invalid.
3386 *
3387 * @method setValue
3388 * @static
3389 * @param o             The object on which to set the sub value.
3390 * @param path {Array}  A path array, specifying the object traversal path
3391 *                      at which to set the sub value.
3392 * @param val {Any}     The new value for the sub-attribute.
3393 * @return {Object}     The modified object, with the new sub value set, or
3394 *                      undefined, if the path was invalid.
3395 */
3396O.setValue = function(o, path, val) {
3397    var i,
3398        p = Y.Array(path),
3399        leafIdx = p.length - 1,
3400        ref = o;
3401
3402    if (leafIdx >= 0) {
3403        for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3404            ref = ref[p[i]];
3405        }
3406
3407        if (ref !== UNDEFINED) {
3408            ref[p[i]] = val;
3409        } else {
3410            return UNDEFINED;
3411        }
3412    }
3413
3414    return o;
3415};
3416
3417/**
3418 * Returns `true` if the object has no enumerable properties of its own.
3419 *
3420 * @method isEmpty
3421 * @param {Object} obj An object.
3422 * @return {Boolean} `true` if the object is empty.
3423 * @static
3424 * @since 3.2.0
3425 */
3426O.isEmpty = function (obj) {
3427    return !O.keys(Object(obj)).length;
3428};
3429/**
3430 * The YUI module contains the components required for building the YUI seed
3431 * file.  This includes the script loading mechanism, a simple queue, and the
3432 * core utilities for the library.
3433 * @module yui
3434 * @submodule yui-base
3435 */
3436
3437/**
3438 * YUI user agent detection.
3439 * Do not fork for a browser if it can be avoided.  Use feature detection when
3440 * you can.  Use the user agent as a last resort.  For all fields listed
3441 * as @type float, UA stores a version number for the browser engine,
3442 * 0 otherwise.  This value may or may not map to the version number of
3443 * the browser using the engine.  The value is presented as a float so
3444 * that it can easily be used for boolean evaluation as well as for
3445 * looking for a particular range of versions.  Because of this,
3446 * some of the granularity of the version info may be lost.  The fields that
3447 * are @type string default to null.  The API docs list the values that
3448 * these fields can have.
3449 * @class UA
3450 * @static
3451 */
3452
3453/**
3454* Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
3455* to populate `Y.UA`.
3456*
3457* @static
3458* @method parseUA
3459* @param {String} [subUA=navigator.userAgent] UA string to parse
3460* @return {Object} The Y.UA object
3461*/
3462YUI.Env.parseUA = function(subUA) {
3463
3464    var numberify = function(s) {
3465            var c = 0;
3466            return parseFloat(s.replace(/\./g, function() {
3467                return (c++ === 1) ? '' : '.';
3468            }));
3469        },
3470
3471        win = Y.config.win,
3472
3473        nav = win && win.navigator,
3474
3475        o = {
3476
3477        /**
3478         * Internet Explorer version number or 0.  Example: 6
3479         * @property ie
3480         * @type float
3481         * @static
3482         */
3483        ie: 0,
3484
3485        /**
3486         * Opera version number or 0.  Example: 9.2
3487         * @property opera
3488         * @type float
3489         * @static
3490         */
3491        opera: 0,
3492
3493        /**
3494         * Gecko engine revision number.  Will evaluate to 1 if Gecko
3495         * is detected but the revision could not be found. Other browsers
3496         * will be 0.  Example: 1.8
3497         * <pre>
3498         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
3499         * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3500         * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3501         * Firefox 3.0   <-- 1.9
3502         * Firefox 3.5   <-- 1.91
3503         * </pre>
3504         * @property gecko
3505         * @type float
3506         * @static
3507         */
3508        gecko: 0,
3509
3510        /**
3511         * AppleWebKit version.  KHTML browsers that are not WebKit browsers
3512         * will evaluate to 1, other browsers 0.  Example: 418.9
3513         * <pre>
3514         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3515         *                                   latest available for Mac OSX 10.3.
3516         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
3517         * Safari 2.0.4:         418     <-- preventDefault fixed
3518         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3519         *                                   different versions of webkit
3520         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
3521         *                                   updated, but not updated
3522         *                                   to the latest patch.
3523         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
3524         * SVG and many major issues fixed).
3525         * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
3526         * update from 2.x via the 10.4.11 OS patch.
3527         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
3528         *                                   yahoo.com user agent hack removed.
3529         * </pre>
3530         * http://en.wikipedia.org/wiki/Safari_version_history
3531         * @property webkit
3532         * @type float
3533         * @static
3534         */
3535        webkit: 0,
3536
3537        /**
3538         * Safari will be detected as webkit, but this property will also
3539         * be populated with the Safari version number
3540         * @property safari
3541         * @type float
3542         * @static
3543         */
3544        safari: 0,
3545
3546        /**
3547         * Chrome will be detected as webkit, but this property will also
3548         * be populated with the Chrome version number
3549         * @property chrome
3550         * @type float
3551         * @static
3552         */
3553        chrome: 0,
3554
3555        /**
3556         * The mobile property will be set to a string containing any relevant
3557         * user agent information when a modern mobile browser is detected.
3558         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3559         * devices with the WebKit-based browser, and Opera Mini.
3560         * @property mobile
3561         * @type string
3562         * @default null
3563         * @static
3564         */
3565        mobile: null,
3566
3567        /**
3568         * Adobe AIR version number or 0.  Only populated if webkit is detected.
3569         * Example: 1.0
3570         * @property air
3571         * @type float
3572         */
3573        air: 0,
3574        /**
3575         * PhantomJS version number or 0.  Only populated if webkit is detected.
3576         * Example: 1.0
3577         * @property phantomjs
3578         * @type float
3579         */
3580        phantomjs: 0,
3581        /**
3582         * Detects Apple iPad's OS version
3583         * @property ipad
3584         * @type float
3585         * @static
3586         */
3587        ipad: 0,
3588        /**
3589         * Detects Apple iPhone's OS version
3590         * @property iphone
3591         * @type float
3592         * @static
3593         */
3594        iphone: 0,
3595        /**
3596         * Detects Apples iPod's OS version
3597         * @property ipod
3598         * @type float
3599         * @static
3600         */
3601        ipod: 0,
3602        /**
3603         * General truthy check for iPad, iPhone or iPod
3604         * @property ios
3605         * @type Boolean
3606         * @default null
3607         * @static
3608         */
3609        ios: null,
3610        /**
3611         * Detects Googles Android OS version
3612         * @property android
3613         * @type float
3614         * @static
3615         */
3616        android: 0,
3617        /**
3618         * Detects Kindle Silk
3619         * @property silk
3620         * @type float
3621         * @static
3622         */
3623        silk: 0,
3624        /**
3625         * Detects Ubuntu version
3626         * @property ubuntu
3627         * @type float
3628         * @static
3629         */
3630        ubuntu: 0,
3631        /**
3632         * Detects Kindle Silk Acceleration
3633         * @property accel
3634         * @type Boolean
3635         * @static
3636         */
3637        accel: false,
3638        /**
3639         * Detects Palms WebOS version
3640         * @property webos
3641         * @type float
3642         * @static
3643         */
3644        webos: 0,
3645
3646        /**
3647         * Google Caja version number or 0.
3648         * @property caja
3649         * @type float
3650         */
3651        caja: nav && nav.cajaVersion,
3652
3653        /**
3654         * Set to true if the page appears to be in SSL
3655         * @property secure
3656         * @type boolean
3657         * @static
3658         */
3659        secure: false,
3660
3661        /**
3662         * The operating system.
3663         *
3664         * Possible values are `windows`, `macintosh`, `android`, `symbos`, `linux`, `rhino` and `ios`.
3665         *
3666         * @property os
3667         * @type string
3668         * @default null
3669         * @static
3670         */
3671        os: null,
3672
3673        /**
3674         * The Nodejs Version
3675         * @property nodejs
3676         * @type float
3677         * @default 0
3678         * @static
3679         */
3680        nodejs: 0,
3681        /**
3682        * Window8/IE10 Application host environment
3683        * @property winjs
3684        * @type Boolean
3685        * @static
3686        */
3687        winjs: !!((typeof Windows !== "undefined") && Windows.System),
3688        /**
3689        * Are touch/msPointer events available on this device
3690        * @property touchEnabled
3691        * @type Boolean
3692        * @static
3693        */
3694        touchEnabled: false
3695    },
3696
3697    ua = subUA || nav && nav.userAgent,
3698
3699    loc = win && win.location,
3700
3701    href = loc && loc.href,
3702
3703    m;
3704
3705    /**
3706    * The User Agent string that was parsed
3707    * @property userAgent
3708    * @type String
3709    * @static
3710    */
3711    o.userAgent = ua;
3712
3713
3714    o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3715
3716    if (ua) {
3717
3718        if ((/windows|win32/i).test(ua)) {
3719            o.os = 'windows';
3720        } else if ((/macintosh|mac_powerpc/i).test(ua)) {
3721            o.os = 'macintosh';
3722        } else if ((/android/i).test(ua)) {
3723            o.os = 'android';
3724        } else if ((/symbos/i).test(ua)) {
3725            o.os = 'symbos';
3726        } else if ((/linux/i).test(ua)) {
3727            o.os = 'linux';
3728        } else if ((/rhino/i).test(ua)) {
3729            o.os = 'rhino';
3730        }
3731
3732        // Modern KHTML browsers should qualify as Safari X-Grade
3733        if ((/KHTML/).test(ua)) {
3734            o.webkit = 1;
3735        }
3736        if ((/IEMobile|XBLWP7/).test(ua)) {
3737            o.mobile = 'windows';
3738        }
3739        if ((/Fennec/).test(ua)) {
3740            o.mobile = 'gecko';
3741        }
3742        // Modern WebKit browsers are at least X-Grade
3743        m = ua.match(/AppleWebKit\/([^\s]*)/);
3744        if (m && m[1]) {
3745            o.webkit = numberify(m[1]);
3746            o.safari = o.webkit;
3747
3748            if (/PhantomJS/.test(ua)) {
3749                m = ua.match(/PhantomJS\/([^\s]*)/);
3750                if (m && m[1]) {
3751                    o.phantomjs = numberify(m[1]);
3752                }
3753            }
3754
3755            // Mobile browser check
3756            if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3757                o.mobile = 'Apple'; // iPhone or iPod Touch
3758
3759                m = ua.match(/OS ([^\s]*)/);
3760                if (m && m[1]) {
3761                    m = numberify(m[1].replace('_', '.'));
3762                }
3763                o.ios = m;
3764                o.os = 'ios';
3765                o.ipad = o.ipod = o.iphone = 0;
3766
3767                m = ua.match(/iPad|iPod|iPhone/);
3768                if (m && m[0]) {
3769                    o[m[0].toLowerCase()] = o.ios;
3770                }
3771            } else {
3772                m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3773                if (m) {
3774                    // Nokia N-series, webOS, ex: NokiaN95
3775                    o.mobile = m[0];
3776                }
3777                if (/webOS/.test(ua)) {
3778                    o.mobile = 'WebOS';
3779                    m = ua.match(/webOS\/([^\s]*);/);
3780                    if (m && m[1]) {
3781                        o.webos = numberify(m[1]);
3782                    }
3783                }
3784                if (/ Android/.test(ua)) {
3785                    o.mobile = 'Android';
3786                    m = ua.match(/Android ([^\s]*);/);
3787                    if (m && m[1]) {
3788                        o.android = numberify(m[1]);
3789                    }
3790
3791                }
3792                if (/Silk/.test(ua)) {
3793                    m = ua.match(/Silk\/([^\s]*)/);
3794                    if (m && m[1]) {
3795                        o.silk = numberify(m[1]);
3796                    }
3797                    if (!o.android) {
3798                        o.android = 2.34; //Hack for desktop mode in Kindle
3799                        o.os = 'Android';
3800                    }
3801                    if (/Accelerated=true/.test(ua)) {
3802                        o.accel = true;
3803                    }
3804                }
3805            }
3806
3807            m = ua.match(/OPR\/(\d+\.\d+)/);
3808
3809            if (m && m[1]) {
3810                // Opera 15+ with Blink (pretends to be both Chrome and Safari)
3811                o.opera = numberify(m[1]);
3812            } else {
3813                m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
3814
3815                if (m && m[1] && m[2]) {
3816                    o.chrome = numberify(m[2]); // Chrome
3817                    o.safari = 0; //Reset safari back to 0
3818                    if (m[1] === 'CrMo') {
3819                        o.mobile = 'chrome';
3820                    }
3821                } else {
3822                    m = ua.match(/AdobeAIR\/([^\s]*)/);
3823                    if (m) {
3824                        o.air = m[0]; // Adobe AIR 1.0 or better
3825                    }
3826                }
3827            }
3828        }
3829
3830        m = ua.match(/Ubuntu\ (\d+\.\d+)/);
3831        if (m && m[1]) {
3832
3833            o.os = 'linux';
3834            o.ubuntu = numberify(m[1]);
3835
3836            m = ua.match(/\ WebKit\/([^\s]*)/);
3837            if (m && m[1]) {
3838                o.webkit = numberify(m[1]);
3839            }
3840            m = ua.match(/\ Chromium\/([^\s]*)/);
3841            if (m && m[1]) {
3842                o.chrome = numberify(m[1]);
3843            }
3844            if (/ Mobile$/.test(ua)) {
3845                o.mobile = 'Ubuntu';
3846            }
3847        }
3848
3849        if (!o.webkit) { // not webkit
3850// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3851            if (/Opera/.test(ua)) {
3852                m = ua.match(/Opera[\s\/]([^\s]*)/);
3853                if (m && m[1]) {
3854                    o.opera = numberify(m[1]);
3855                }
3856                m = ua.match(/Version\/([^\s]*)/);
3857                if (m && m[1]) {
3858                    o.opera = numberify(m[1]); // opera 10+
3859                }
3860
3861                if (/Opera Mobi/.test(ua)) {
3862                    o.mobile = 'opera';
3863                    m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
3864                    if (m && m[1]) {
3865                        o.opera = numberify(m[1]);
3866                    }
3867                }
3868                m = ua.match(/Opera Mini[^;]*/);
3869
3870                if (m) {
3871                    o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3872                }
3873            } else { // not opera or webkit
3874                m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);
3875
3876                if (m && (m[1] || m[2])) {
3877                    o.ie = numberify(m[1] || m[2]);
3878                } else { // not opera, webkit, or ie
3879                    m = ua.match(/Gecko\/([^\s]*)/);
3880
3881                    if (m) {
3882                        o.gecko = 1; // Gecko detected, look for revision
3883                        m = ua.match(/rv:([^\s\)]*)/);
3884                        if (m && m[1]) {
3885                            o.gecko = numberify(m[1]);
3886                            if (/Mobile|Tablet/.test(ua)) {
3887                                o.mobile = "ffos";
3888                            }
3889                        }
3890                    }
3891                }
3892            }
3893        }
3894    }
3895
3896    //Check for known properties to tell if touch events are enabled on this device or if
3897    //the number of MSPointer touchpoints on this device is greater than 0.
3898    if (win && nav && !(o.chrome && o.chrome < 6)) {
3899        o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
3900    }
3901
3902    //It was a parsed UA, do not assign the global value.
3903    if (!subUA) {
3904
3905        if (typeof process === 'object') {
3906
3907            if (process.versions && process.versions.node) {
3908                //NodeJS
3909                o.os = process.platform;
3910                o.nodejs = numberify(process.versions.node);
3911            }
3912        }
3913
3914        YUI.Env.UA = o;
3915
3916    }
3917
3918    return o;
3919};
3920
3921
3922Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3923
3924/**
3925Performs a simple comparison between two version numbers, accounting for
3926standard versioning logic such as the fact that "535.8" is a lower version than
3927"535.24", even though a simple numerical comparison would indicate that it's
3928greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
3929considered equivalent.
3930
3931Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
39321 if _a_ is higher than _b_.
3933
3934Versions may be numbers or strings containing numbers and dots. For example,
3935both `535` and `"535.8.10"` are acceptable. A version string containing
3936non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
3937
3938@method compareVersions
3939@param {Number|String} a First version number to compare.
3940@param {Number|String} b Second version number to compare.
3941@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
3942    higher than _b_.
3943**/
3944Y.UA.compareVersions = function (a, b) {
3945    var aPart, aParts, bPart, bParts, i, len;
3946
3947    if (a === b) {
3948        return 0;
3949    }
3950
3951    aParts = (a + '').split('.');
3952    bParts = (b + '').split('.');
3953
3954    for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
3955        aPart = parseInt(aParts[i], 10);
3956        bPart = parseInt(bParts[i], 10);
3957
3958        /*jshint expr: true*/
3959        isNaN(aPart) && (aPart = 0);
3960        isNaN(bPart) && (bPart = 0);
3961
3962        if (aPart < bPart) {
3963            return -1;
3964        }
3965
3966        if (aPart > bPart) {
3967            return 1;
3968        }
3969    }
3970
3971    return 0;
3972};
3973YUI.Env.aliases = {
3974    "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
3975    "anim-shape-transform": ["anim-shape"],
3976    "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"],
3977    "attribute": ["attribute-base","attribute-complex"],
3978    "attribute-events": ["attribute-observable"],
3979    "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
3980    "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
3981    "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
3982    "base": ["base-base","base-pluginhost","base-build"],
3983    "cache": ["cache-base","cache-offline","cache-plugin"],
3984    "charts": ["charts-base"],
3985    "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
3986    "color": ["color-base","color-hsl","color-harmony"],
3987    "controller": ["router"],
3988    "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
3989    "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
3990    "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
3991    "datatype": ["datatype-date","datatype-number","datatype-xml"],
3992    "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
3993    "datatype-number": ["datatype-number-parse","datatype-number-format"],
3994    "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
3995    "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
3996    "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
3997    "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
3998    "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"],
3999    "event-custom": ["event-custom-base","event-custom-complex"],
4000    "event-gestures": ["event-flick","event-move"],
4001    "handlebars": ["handlebars-compiler"],
4002    "highlight": ["highlight-base","highlight-accentfold"],
4003    "history": ["history-base","history-hash","history-html5"],
4004    "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
4005    "json": ["json-parse","json-stringify"],
4006    "loader": ["loader-base","loader-rollup","loader-yui3"],
4007    "loader-pathogen-encoder": ["loader-base","loader-rollup","loader-yui3","loader-pathogen-combo
4007handler"],
4008    "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
4009    "pluginhost": ["pluginhost-base","pluginhost-config"],
4010    "querystring": ["querystring-parse","querystring-stringify"],
4011    "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
4012    "resize": ["resize-base","resize-proxy","resize-constrain"],
4013    "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
4014    "template": ["template-base","template-micro"],
4015    "text": ["text-accentfold","text-wordbreak"],
4016    "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
4017};
4018
4019
4020}, 'patched-v3.18.1', {
4021    "use": [
4022        "yui-base",
4023        "get",
4024        "features",
4025        "intl-base",
4026        "yui-log",
4027        "yui-later",
4028        "loader-base",
4029        "loader-rollup",
4030        "loader-yui3"
4031    ]
4032});
4033YUI.add('get', function (Y, NAME) {
4034
4035/*jslint boss:true, expr:true, laxbreak: true */
4036
4037/**
4038Provides dynamic loading of remote JavaScript and CSS resources.
4039
4040@module get
4041@class Get
4042@static
4043**/
4044
4045var Lang = Y.Lang,
4046
4047    CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
4048
4049    Get, Transaction;
4050
4051Y.Get = Get = {
4052    // -- Public Properties ----------------------------------------------------
4053
4054    /**
4055    Default options for CSS requests. Options specified here will override
4056    global defaults for CSS requests.
4057
4058    See the `options` property for all available options.
4059
4060    @property cssOptions
4061    @type Object
4062    @static
4063    @since 3.5.0
4064    **/
4065    cssOptions: {
4066        attributes: {
4067            rel: 'stylesheet'
4068        },
4069
4070        doc         : Y.config.linkDoc || Y.config.doc,
4071        pollInterval: 50
4072    },
4073
4074    /**
4075    Default options for JS requests. Options specified here will override global
4076    defaults for JS requests.
4077
4078    See the `options` property for all available options.
4079
4080    @property jsOptions
4081    @type Object
4082    @static
4083    @since 3.5.0
4084    **/
4085    jsOptions: {
4086        autopurge: true,
4087        doc      : Y.config.scriptDoc || Y.config.doc
4088    },
4089
4090    /**
4091    Default options to use for all requests.
4092
4093    Note that while all available options are documented here for ease of
4094    discovery, some options (like callback functions) only make sense at the
4095    transaction level.
4096
4097    Callback functions specified via the options object or the `options`
4098    parameter of the `css()`, `js()`, or `load()` methods will receive the
4099    transaction object as a parameter. See `Y.Get.Transaction` for details on
4100    the properties and methods available on transactions.
4101
4102    @static
4103    @since 3.5.0
4104    @property {Object} options
4105
4106    @property {Boolean} [options.async=false] Whether or not to load scripts
4107        asynchronously, meaning they're requested in parallel and execution
4108        order is not guaranteed. Has no effect on CSS, since CSS is always
4109        loaded asynchronously.
4110
4111    @property {Object} [options.attributes] HTML attribute name/value pairs that
4112        should be added to inserted nodes. By default, the `charset` attribute
4113        will be set to "utf-8" and nodes will be given an auto-generated `id`
4114        attribute, but you can override these with your own values if desired.
4115
4116    @property {Boolean} [options.autopurge] Whether or not to automatically
4117        purge inserted nodes after the purge threshold is reached. This is
4118        `true` by default for JavaScript, but `false` for CSS since purging a
4119        CSS node will also remove any styling applied by the referenced file.
4120
4121    @property {Object} [options.context] `this` object to use when calling
4122        callback functions. Defaults to the transaction object.
4123
4124    @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
4125        callbacks.
4126
4127    @property {Document} [options.doc] Document into which nodes should be
4128        inserted. By default, the current document is used.
4129
4130    @property {HTMLElement|String} [options.insertBefore] HTML element or id
4131        string of an element before which all generated nodes should be
4132        inserted. If not specified, Get will automatically determine the best
4133        place to insert nodes for maximum compatibility.
4134
4135    @property {Function} [options.onEnd] Callback to execute after a transaction
4136        is complete, regardless of whether it succeeded or failed.
4137
4138    @property {Function} [options.onFailure] Callback to execute after a
4139        transaction fails, times out, or is aborted.
4140
4141    @property {Function} [options.onProgress] Callback to execute after each
4142        individual request in a transaction either succeeds or fails.
4143
4144    @property {Function} [options.onSuccess] Callback to execute after a
4145        transaction completes successfully with no errors. Note that in browsers
4146        that don't support the `error` event on CSS `<link>` nodes, a failed CSS
4147        request may still be reported as a success because in these browsers
4148        it can be difficult or impossible to distinguish between success and
4149        failure for CSS resources.
4150
4151    @property {Function} [options.onTimeout] Callback to execute after a
4152        transaction times out.
4153
4154    @property {Number} [options.pollInterval=50] Polling interval (in
4155        milliseconds) for detecting CSS load completion in browsers that don't
4156        support the `load` event on `<link>` nodes. This isn't used for
4157        JavaScript.
4158
4159    @property {Number} [options.purgethreshold=20] Number of nodes to insert
4160        before triggering an automatic purge when `autopurge` is `true`.
4161
4162    @property {Number} [options.timeout] Number of milliseconds to wait before
4163        aborting a transaction. When a timeout occurs, the `onTimeout` callback
4164        is called, followed by `onFailure` and finally `onEnd`. By default,
4165        there is no timeout.
4166
4167    @property {String} [options.type] Resource type ("css" or "js"). This option
4168        is set automatically by the `css()` and `js()` functions and will be
4169        ignored there, but may be useful when using the `load()` function. If
4170        not specified, the type will be inferred from the URL, defaulting to
4171        "js" if the URL doesn't contain a recognizable file extension.
4172    **/
4173    options: {
4174        attributes: {
4175            charset: 'utf-8'
4176        },
4177
4178        purgethreshold: 20
4179    },
4180
4181    // -- Protected Properties -------------------------------------------------
4182
4183    /**
4184    Regex that matches a CSS URL. Used to guess the file type when it's not
4185    specified.
4186
4187    @property REGEX_CSS
4188    @type RegExp
4189    @final
4190    @protected
4191    @static
4192    @since 3.5.0
4193    **/
4194    REGEX_CSS: /\.css(?:[?;].*)?$/i,
4195
4196    /**
4197    Regex that matches a JS URL. Used to guess the file type when it's not
4198    specified.
4199
4200    @property REGEX_JS
4201    @type RegExp
4202    @final
4203    @protected
4204    @static
4205    @since 3.5.0
4206    **/
4207    REGEX_JS : /\.js(?:[?;].*)?$/i,
4208
4209    /**
4210    Contains information about the current environment, such as what script and
4211    link injection features it supports.
4212
4213    This object is created and populated the first time the `_getEnv()` method
4214    is called.
4215
4216    @property _env
4217    @type Object
4218    @protected
4219    @static
4220    @since 3.5.0
4221    **/
4222
4223    /**
4224    Mapping of document _yuid strings to <head> or <base> node references so we
4225    don't have to look the node up each time we want to insert a request node.
4226
4227    @property _insertCache
4228    @type Object
4229    @protected
4230    @static
4231    @since 3.5.0
4232    **/
4233    _insertCache: {},
4234
4235    /**
4236    Information about the currently pending transaction, if any.
4237
4238    This is actually an object with two properties: `callback`, containing the
4239    optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
4240    containing the actual transaction instance.
4241
4242    @property _pending
4243    @type Object
4244    @protected
4245    @static
4246    @since 3.5.0
4247    **/
4248    _pending: null,
4249
4250    /**
4251    HTML nodes eligible to be purged next time autopurge is triggered.
4252
4253    @property _purgeNodes
4254    @type HTMLElement[]
4255    @protected
4256    @static
4257    @since 3.5.0
4258    **/
4259    _purgeNodes: [],
4260
4261    /**
4262    Queued transactions and associated callbacks.
4263
4264    @property _queue
4265    @type Object[]
4266    @protected
4267    @static
4268    @since 3.5.0
4269    **/
4270    _queue: [],
4271
4272    // -- Public Methods -------------------------------------------------------
4273
4274    /**
4275    Aborts the specified transaction.
4276
4277    This will cause the transaction's `onFailure` callback to be called and
4278    will prevent any new script and link nodes from being added to the document,
4279    but any resources that have already been requested will continue loading
4280    (there's no safe way to prevent this, unfortunately).
4281
4282    *Note:* This method is deprecated as of 3.5.0, and will be removed in a
4283    future version of YUI. Use the transaction-level `abort()` method instead.
4284
4285    @method abort
4286    @param {Get.Transaction} transaction Transaction to abort.
4287    @deprecated Use the `abort()` method on the transaction instead.
4288    @static
4289    **/
4290    abort: function (transaction) {
4291        var i, id, item, len, pending;
4292
4293
4294        if (!transaction.abort) {
4295            id          = transaction;
4296            pending     = this._pending;
4297            transaction = null;
4298
4299            if (pending && pending.transaction.id === id) {
4300                transaction   = pending.transaction;
4301                this._pending = null;
4302            } else {
4303                for (i = 0, len = this._queue.length; i < len; ++i) {
4304                    item = this._queue[i].transaction;
4305
4306                    if (item.id === id) {
4307                        transaction = item;
4308                        this._queue.splice(i, 1);
4309                        break;
4310                    }
4311                }
4312            }
4313        }
4314
4315        transaction && transaction.abort();
4316    },
4317
4318    /**
4319    Loads one or more CSS files.
4320
4321    The _urls_ parameter may be provided as a URL string, a request object,
4322    or an array of URL strings and/or request objects.
4323
4324    A request object is just an object that contains a `url` property and zero
4325    or more options that should apply specifically to that request.
4326    Request-specific options take priority over transaction-level options and
4327    default options.
4328
4329    URLs may be relative or absolute, and do not have to have the same origin
4330    as the current page.
4331
4332    The `options` parameter may be omitted completely and a callback passed in
4333    its place, if desired.
4334
4335    @example
4336
4337        // Load a single CSS file and log a message on completion.
4338        Y.Get.css('foo.css', function (err) {
4339            if (err) {
4340            } else {
4341            }
4342        });
4343
4344        // Load multiple CSS files and log a message when all have finished
4345        // loading.
4346        var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
4347
4348        Y.Get.css(urls, function (err) {
4349            if (err) {
4350            } else {
4351            }
4352        });
4353
4354        // Specify transaction-level options, which will apply to all requests
4355        // within the transaction.
4356        Y.Get.css(urls, {
4357            attributes: {'class': 'my-css'},
4358            timeout   : 5000
4359        });
4360
4361        // Specify per-request options, which override transaction-level and
4362        // default options.
4363        Y.Get.css([
4364            {url: 'foo.css', attributes: {id: 'foo'}},
4365            {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4366        ]);
4367
4368    @method css
4369    @param {String|Object|Array}
4369 urls URL string, request object, or array
4370        of URLs and/or request objects to load.
4371    @param {Object} [options] Options for this transaction. See the
4372        `Y.Get.options` property for a complete list of available options.
4373    @param {Function} [callback] Callback function to be called on completion.
4374        This is a general callback and will be called before any more granular
4375        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4376        object.
4377
4378        @param {Array|null} callback.err Array of errors that occurred during
4379            the transaction, or `null` on success.
4380        @param {Get.Transaction} callback.transaction Transaction object.
4381
4382    @return {Get.Transaction} Transaction object.
4383    @static
4384    **/
4385    css: function (urls, options, callback) {
4386        return this._load('css', urls, options, callback);
4387    },
4388
4389    /**
4390    Loads one or more JavaScript resources.
4391
4392    The _urls_ parameter may be provided as a URL string, a request object,
4393    or an array of URL strings and/or request objects.
4394
4395    A request object is just an object that contains a `url` property and zero
4396    or more options that should apply specifically to that request.
4397    Request-specific options take priority over transaction-level options and
4398    default options.
4399
4400    URLs may be relative or absolute, and do not have to have the same origin
4401    as the current page.
4402
4403    The `options` parameter may be omitted completely and a callback passed in
4404    its place, if desired.
4405
4406    Scripts will be executed in the order they're specified unless the `async`
4407    option is `true`, in which case they'll be loaded in parallel and executed
4408    in whatever order they finish loading.
4409
4410    @example
4411
4412        // Load a single JS file and log a message on completion.
4413        Y.Get.js('foo.js', function (err) {
4414            if (err) {
4415            } else {
4416            }
4417        });
4418
4419        // Load multiple JS files, execute them in order, and log a message when
4420        // all have finished loading.
4421        var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4422
4423        Y.Get.js(urls, function (err) {
4424            if (err) {
4425            } else {
4426            }
4427        });
4428
4429        // Specify transaction-level options, which will apply to all requests
4430        // within the transaction.
4431        Y.Get.js(urls, {
4432            attributes: {'class': 'my-js'},
4433            timeout   : 5000
4434        });
4435
4436        // Specify per-request options, which override transaction-level and
4437        // default options.
4438        Y.Get.js([
4439            {url: 'foo.js', attributes: {id: 'foo'}},
4440            {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4441        ]);
4442
4443    @method js
4444    @param {String|Object|Array} urls URL string, request object, or array
4445        of URLs and/or request objects to load.
4446    @param {Object} [options] Options for this transaction. See the
4447        `Y.Get.options` property for a complete list of available options.
4448    @param {Function} [callback] Callback function to be called on completion.
4449        This is a general callback and will be called before any more granular
4450        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4451        object.
4452
4453        @param {Array|null} callback.err Array of errors that occurred during
4454            the transaction, or `null` on success.
4455        @param {Get.Transaction} callback.transaction Transaction object.
4456
4457    @return {Get.Transaction} Transaction object.
4458    @since 3.5.0
4459    @static
4460    **/
4461    js: function (urls, options, callback) {
4462        return this._load('js', urls, options, callback);
4463    },
4464
4465    /**
4466    Loads one or more CSS and/or JavaScript resources in the same transaction.
4467
4468    Use this method when you want to load both CSS and JavaScript in a single
4469    transaction and be notified when all requested URLs have finished loading,
4470    regardless of type.
4471
4472    Behavior and options are the same as for the `css()` and `js()` methods. If
4473    a resource type isn't specified in per-request options or transaction-level
4474    options, Get will guess the file type based on the URL's extension (`.css`
4475    or `.js`, with or without a following query string). If the file type can't
4476    be guessed from the URL, a warning will be logged and Get will assume the
4477    URL is a JavaScript resource.
4478
4479    @example
4480
4481        // Load both CSS and JS files in a single transaction, and log a message
4482        // when all files have finished loading.
4483        Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4484            if (err) {
4485            } else {
4486            }
4487        });
4488
4489    @method load
4490    @param {String|Object|Array}
4490 urls URL string, request object, or array
4491        of URLs and/or request objects to load.
4492    @param {Object} [options] Options for this transaction. See the
4493        `Y.Get.options` property for a complete list of available options.
4494    @param {Function} [callback] Callback function to be called on completion.
4495        This is a general callback and will be called before any more granular
4496        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4497        object.
4498
4499        @param {Array|null} err Array of errors that occurred during the
4500            transaction, or `null` on success.
4501        @param {Get.Transaction} Transaction object.
4502
4503    @return {Get.Transaction} Transaction object.
4504    @since 3.5.0
4505    @static
4506    **/
4507    load: function (urls, options, callback) {
4508        return this._load(null, urls, options, callback);
4509    },
4510
4511    // -- Protected Methods ----------------------------------------------------
4512
4513    /**
4514    Triggers an automatic purge if the purge threshold has been reached.
4515
4516    @method _autoPurge
4517    @param {Number} threshold Purge threshold to use, in milliseconds.
4518    @protected
4519    @since 3.5.0
4520    @static
4521    **/
4522    _autoPurge: function (threshold) {
4523        if (threshold && this._purgeNodes.length >= threshold) {
4524            this._purge(this._purgeNodes);
4525        }
4526    },
4527
4528    /**
4529    Populates the `_env` property with information about the current
4530    environment.
4531
4532    @method _getEnv
4533    @return {Object} Environment information.
4534    @protected
4535    @since 3.5.0
4536    @static
4537    **/
4538    _getEnv: function () {
4539        var doc = Y.config.doc,
4540            ua  = Y.UA;
4541
4542        // Note: some of these checks require browser sniffs since it's not
4543        // feasible to load test files on every pageview just to perform a
4544        // feature test. I'm sorry if this makes you sad.
4545        return (this._env = {
4546
4547            // True if this is a browser that supports disabling async mode on
4548            // dynamically created script nodes. See
4549            // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4550
4551            // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4552            // because it is async by default, and allows you to disable async by setting it to false
4553            async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4554
4555            // True if this browser fires an event when a dynamically injected
4556            // link node fails to load. This is currently true for Firefox 9+
4557            // and WebKit 535.24+
4558            cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4559
4560            // True if this browser fires an event when a dynamically injected
4561            // link node finishes loading. This is currently true for IE, Opera,
4562            // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4563            // DOM 0 "onload" event, but not "load". All versions of IE fire
4564            // "onload".
4565            // davglass: Seems that Chrome on Android needs this to be false.
4566            cssLoad: (
4567                    (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4568                    ua.compareVersions(ua.webkit, 535.24) >= 0
4569                ) && !(ua.chrome && ua.chrome <= 18),
4570
4571            // True if this browser preserves script execution order while
4572            // loading scripts in parallel as long as the script node's `async`
4573            // attribute is set to false to explicitly disable async execution.
4574            preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4575        });
4576    },
4577
4578    _getTransaction: function (urls, options) {
4579        var requests = [],
4580            i, len, req, url;
4581
4582        if (!Lang.isArray(urls)) {
4583            urls = [urls];
4584        }
4585
4586        options = Y.merge(this.options, options);
4587
4588        // Clone the attributes object so we don't end up modifying it by ref.
4589        options.attributes = Y.merge(this.options.attributes,
4590                options.attributes);
4591
4592        for (i = 0, len = urls.length; i < len; ++i) {
4593            url = urls[i];
4594            req = {attributes: {}};
4595
4596            // If `url` is a string, we create a URL object for it, then mix in
4597            // global options and request-specific options. If it's an object
4598            // with a "url" property, we assume it's a request object c
4598ontaining
4599            // URL-specific options.
4600            if (typeof url === 'string') {
4601                req.url = url;
4602            } else if (url.url) {
4603                // URL-specific options override both global defaults and
4604                // request-specific options.
4605                Y.mix(req, url, false, null, 0, true);
4606                url = url.url; // Make url a string so we can use it later.
4607            } else {
4608                continue;
4609            }
4610
4611            Y.mix(req, options, false, null, 0, true);
4612
4613            // If we didn't get an explicit type for this URL either in the
4614            // request options or the URL-specific options, try to determine
4615            // one from the file extension.
4616            if (!req.type) {
4617                if (this.REGEX_CSS.test(url)) {
4618                    req.type = 'css';
4619                } else {
4620                    if (!this.REGEX_JS.test(url)) {
4621                    }
4622
4623                    req.type = 'js';
4624                }
4625            }
4626
4627            // Mix in type-specific default options, but don't overwrite any
4628            // options that have already been set.
4629            Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4630                false, null, 0, true);
4631
4632            // Give the node an id attribute if it doesn't already have one.
4633            req.attributes.id || (req.attributes.id = Y.guid());
4634
4635            // Backcompat for <3.5.0 behavior.
4636            if (req.win) {
4637                req.doc = req.win.document;
4638            } else {
4639                req.win = req.doc.defaultView || req.doc.parentWindow;
4640            }
4641
4642            if (req.charset) {
4643                req.attributes.charset = req.charset;
4644            }
4645
4646            requests.push(req);
4647        }
4648
4649        return new Transaction(requests, options);
4650    },
4651
4652    _load: function (type, urls, options, callback) {
4653        var transaction;
4654
4655        // Allow callback as third param.
4656        if (typeof options === 'function') {
4657            callback = options;
4658            options  = {};
4659        }
4660
4661        options || (options = {});
4662        options.type = type;
4663
4664        options._onFinish = Get._onTransactionFinish;
4665
4666        if (!this._env) {
4667            this._getEnv();
4668        }
4669
4670        transaction = this._getTransaction(urls, options);
4671
4672        this._queue.push({
4673            callback   : callback,
4674            transaction: transaction
4675        });
4676
4677        this._next();
4678
4679        return transaction;
4680    },
4681
4682    _onTransactionFinish : function() {
4683        Get._pending = null;
4684        Get._next();
4685    },
4686
4687    _next: function () {
4688        var item;
4689
4690        if (this._pending) {
4691            return;
4692        }
4693
4694        item = this._queue.shift();
4695
4696        if (item) {
4697            this._pending = item;
4698            item.transaction.execute(item.callback);
4699        }
4700    },
4701
4702    _purge: function (nodes) {
4703        var purgeNodes    = this._purgeNodes,
4704            isTransaction = nodes !== purgeNodes,
4705            index, node;
4706
4707        while (node = nodes.pop()) { // assignment
4708            // Don't purge nodes that haven't finished loading (or errored out),
4709            // since this can hang the transaction.
4710            if (!node._yuiget_finished) {
4711                continue;
4712            }
4713
4714            node.parentNode && node.parentNode.removeChild(node);
4715
4716            // If this is a transaction-level purge and this node also exists in
4717            // the Get-level _purgeNodes array, we need to remove it from
4718            // _purgeNodes to avoid creating a memory leak. The indexOf lookup
4719            // sucks, but until we get WeakMaps, this is the least troublesome
4720            // way to do this (we can't just hold onto node ids because they may
4721            // not be in the same document).
4722            if (isTransaction) {
4723                index = Y.Array.indexOf(purgeNodes, node);
4724
4725                if (index > -1) {
4726                    purgeNodes.splice(index, 1);
4727                }
4728            }
4729        }
4730    }
4731};
4732
4733/**
4734Alias for `js()`.
4735
4736@method script
4737@static
4738**/
4739Get.script = Get.js;
4740
4741/**
4742Represents a Get transaction, which may contain requests for one or more JS or
4743CSS files.
4744
4745This class should not be instantiated manually. Instances will be created and
4746returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4747
4748@class Get.Transaction
4749@constructor
4750@since 3.5.0
4751**/
4752Get.Transaction = Transaction = function (requests, options) {
4753    var self = this;
4754
4755    self.id       = Transaction._lastId += 1;
4756    self.data     = options.data;
4757    self.errors   = [];
4758    self.nodes    = [];
4759    self.options  = options;
4760    self.requests = requests;
4761
4762    self._callbacks = []; // callbacks to call after execution finishes
4763    self._queue     = [];
4764    self._reqsWaiting   = 0;
4765
4766    // Deprecated pre-3.5.0 properties.
4767    self.tId = self.id; // Use `id` instead.
4768    self.win = options.win || Y.config.win;
4769};
4770
4771/**
4772Arbitrary data object associated with this transaction.
4773
4774This object comes from the options passed to `Get.css()`, `Get.js()`, or
4775`Get.load()`, and will be `undefined` if no data object was specified.
4776
4777@property {Object} data
4778**/
4779
4780/**
4781Array of errors that have occurred during this transaction, if any. Each error
4782object has the following properties:
4783`errors.error`: Error message.
4784`errors.request`: Request object related to the error.
4785
4786@since 3.5.0
4787@property {Object[]} errors
4788**/
4789
4790/**
4791Numeric id for this transaction, unique among all transactions within the same
4792YUI sandbox in the current pageview.
4793
4794@property {Number} id
4795@since 3.5.0
4796**/
4797
4798/**
4799HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
4800during the current transaction.
4801
4802@property {HTMLElement[]} nodes
4803**/
4804
4805/**
4806Options associated with this transaction.
4807
4808See `Get.options` for the full list of available options.
4809
4810@property {Object} options
4811@since 3.5.0
4812**/
4813
4814/**
4815Request objects contained in this transaction. Each request object represents
4816one CSS or JS URL that will be (or has been) requested and loaded into the page.
4817
4818@property {Object} requests
4819@since 3.5.0
4820**/
4821
4822/**
4823Id of the most recent transaction.
4824
4825@property _lastId
4826@type Number
4827@protected
4828@static
4829**/
4830Transaction._lastId = 0;
4831
4832Transaction.prototype = {
4833    // -- Public Properties ----------------------------------------------------
4834
4835    /**
4836    Current state of this transaction. One of "new", "executing", or "done".
4837
4838    @property _state
4839    @type String
4840    @protected
4841    **/
4842    _state: 'new', // "new", "executing", or "done"
4843
4844    // -- Public Methods -------------------------------------------------------
4845
4846    /**
4847    Aborts this transaction.
4848
4849    This will cause the transaction's `onFailure` callback to be called and
4850    will prevent any new script and link nodes from being added to the document,
4851    but any resources that have already been requested will continue loading
4852    (there's no safe way to prevent this, unfortunately).
4853
4854    @method abort
4855    @param {String} [msg="Aborted."] Optional message to use in the `errors`
4856        array describing why the transaction was aborted.
4857    **/
4858    abort: function (msg) {
4859        this._pending    = null;
4860        this._pendingCSS = null;
4861        this._pollTimer  = clearTimeout(this._pollTimer);
4862        this._queue      = [];
4863        this._reqsWaiting    = 0;
4864
4865        this.errors.push({error: msg || 'Aborted'});
4866        this._finish();
4867    },
4868
4869    /**
4870    Begins execting the transaction.
4871
4872    There's usually no reason to call this manually, since Get will call it
4873    automatically when other pending transactions have finished. If you really
4874    want to execute your transaction before Get does, you can, but be aware that
4875    this transaction's scripts may end up executing before the scripts in other
4876    pending transactions.
4877
4878    If the transaction is already executing, the specified callback (if any)
4879    will be queued and called after execution finishes. If the transaction has
4880    already finished, the callback will be called immediately (the transaction
4881    will not be executed again).
4882
4883    @method execute
4884    @param {Function} callback Callback function to execute after all requests
4885        in the transaction are complete, or after the transaction is aborted.
4886    **/
4887    execute: function (callback) {
4888        var self     = this,
4889            requests = self.requests,
4890            state    = self._state,
4891            i, len, queue, req;
4892
4893        if (state === 'done') {
4894            callback && callback(self.errors.length ? self.errors : null, self);
4895            return;
4896        } else {
4897            callback && self._callbacks.push(callback);
4898
4899            if (state === 'executing') {
4900                return;
4901            }
4902        }
4903
4904        self._state = 'executing';
4905        self._queue = queue = [];
4906
4907        if (self.options.timeout) {
4908            self._timeout = setTimeout(function () {
4909                self.abort('Timeout');
4910            }, self.options.timeout);
4911        }
4912
4913        self._reqsWaiting = requests.length;
4914
4915        for (i = 0, len = requests.length; i < len; ++i) {
4916            req = requests[i];
4917
4918            if (req.async || req.type === 'css') {
4919                // No need to queue CSS or fully async JS.
4920                self._insert(req);
4921            } else {
4922                queue.push(req);
4923            }
4924        }
4925
4926        self._next();
4927    },
4928
4929    /**
4930    Manually purges any `<script>` or `<link>` nodes this transaction has
4931    created.
4932
4933    Be careful when purging a transaction that contains CSS requests, since
4934    removing `<link>` nodes will also remove any styles they applied.
4935
4936    @method purge
4937    **/
4938    purge: function () {
4939        Get._purge(this.nodes);
4940    },
4941
4942    // -- Protected Methods ----------------------------------------------------
4943    _createNode: function (name, attrs, doc) {
4944        var node = doc.createElement(name),
4945            attr, testEl;
4946
4947        if (!CUSTOM_ATTRS) {
4948            // IE6 and IE7 expect property names rather than attribute names for
4949            // certain attributes. Rather than sniffing, we do a quick feature
4950            // test the first time _createNode() runs to determine whether we
4951            // need to provide a workaround.
4952            testEl = doc.createElement('div');
4953            testEl.setAttribute('class', 'a');
4954
4955            CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
4956                'for'  : 'htmlFor',
4957                'class': 'className'
4958            };
4959        }
4960
4961        for (attr in attrs) {
4962            if (attrs.hasOwnProperty(attr)) {
4963                node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
4964            }
4965        }
4966
4967        return node;
4968    },
4969
4970    _finish: function () {
4971        var errors  = this.errors.length ? this.errors : null,
4972            options = this.options,
4973            thisObj = options.context || this,
4974            data, i, len;
4975
4976        if (this._state === 'done') {
4977            return;
4978        }
4979
4980        this._state = 'done';
4981
4982        for (i = 0, len = this._callbacks.length; i < len; ++i) {
4983            this._callbacks[i].call(thisObj, errors, this);
4984        }
4985
4986        data = this._getEventData();
4987
4988        if (errors) {
4989            if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
4990                options.onTimeout.call(thisObj, data);
4991            }
4992
4993            if (options.onFailure) {
4994                options.onFailure.call(thisObj, data);
4995            }
4996        } else if (options.onSuccess) {
4997            options.onSuccess.call(thisObj, data);
4998        }
4999
5000        if (options.onEnd) {
5001            options.onEnd.call(thisObj, data);
5002        }
5003
5004        if (options._onFinish) {
5005            options._onFinish();
5006        }
5007    },
5008
5009    _getEventData: function (req) {
5010        if (req) {
5011            // This merge is necessary for backcompat. I hate it.
5012            return Y.merge(this, {
5013                abort  : this.abort, // have to copy these because the prototype isn't preserved
5014                purge  : this.purge,
5015                request: req,
5016                url    : req.url,
5017                win    : req.win
5018            });
5019        } else {
5020            return this;
5021        }
5022    },
5023
5024    _getInsertBefore: function (req) {
5025        var doc = req.doc,
5026            el  = req.insertBefore,
5027            cache, docStamp;
5028
5029        if (el) {
5030            return typeof el === 'string' ? doc.getElementById(el) : el;
5031        }
5032
5033        cache    = Get._insertCache;
5034        docStamp = Y.stamp(doc);
5035
5036        if ((el = cache[docStamp])) { // assignment
5037            return el;
5038        }
5039
5040        // Inserting before a <base> tag apparently works around an IE bug
5041        // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
5042        // bug that is, exactly. Better safe than sorry?
5043        if ((el = doc.getElementsByTagName('base')[0])) { // assignment
5044            return (cache[docStamp] = el);
5045        }
5046
5047        // Look for a <head> element.
5048        el = doc.head || doc.getElementsByTagName('head')[0];
5049
5050        if (el) {
5051            // Create a marker node at the end of <head> to use as an insertion
5052            // point. Inserting before this node will ensure that all our CSS
5053            // gets inserted in the correct order, to maintain style precedence.
5054            el.appendChild(doc.createTextNode(''));
5055            return (cache[docStamp] = el.lastChild);
5056        }
5057
5058        // If all else fails, just insert before the first script node on the
5059        // page, which is virtually guaranteed to exist.
5060        return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
5061    },
5062
5063    _insert: function (req) {
5064        var env          = Get._env,
5065            insertBefore = this._getInsertBefore(req),
5066            isScript     = req.type === 'js',
5067            node         = req.node,
5068            self         = this,
5069            ua           = Y.UA,
5070            cssTimeout, nodeType;
5071
5072        if (!node) {
5073            if (isScript) {
5074                nodeType = 'script';
5075            } else if (!env.cssLoad && ua.gecko) {
5076                nodeType = 'style';
5077            } else {
5078                nodeType = 'link';
5079                delete req.attributes['charset'];
5080            }
5081
5082            node = req.node = this._createNode(nodeType, req.attributes,
5083                req.doc);
5084        }
5085
5086        function onError() {
5087            self._progress('Failed to load ' + req.url, req);
5088        }
5089
5090        function onLoad() {
5091            if (cssTimeout) {
5092                clearTimeout(cssTimeout);
5093            }
5094
5095            self._progress(null, req);
5096        }
5097
5098        // Deal with script asynchronicity.
5099        if (isScript) {
5100            node.setAttribute('src', req.url);
5101
5102            if (req.async) {
5103                // Explicitly indicate that we want the browser to execute this
5104                // script asynchronously. This is necessary for older browsers
5105                // like Firefox <4.
5106                node.async = true;
5107            } else {
5108                if (env.async) {
5109                    // This browser treats injected scripts as async by default
5110                    // (standard HTML5 behavior) but asynchronous loading isn't
5111                    // desired, so tell the browser not to mark this script as
5112                    // async.
5113                    node.async = false;
5114                }
5115
5116                // If this browser doesn't preserve script execution order based
5117                // on insertion order, we'll need to avoid inserting other
5118                // scripts until this one finishes loading.
5119                if (!env.preservesScriptOrder) {
5120                    this._pending = req;
5121                }
5122            }
5123        } else {
5124            if (!env.cssLoad && ua.gecko) {
5125                // In Firefox <9, we can import the requested URL into a <style>
5126                // node and poll for the existence of node.sheet.cssRules. This
5127                // gives us a reliable way to determine CSS load completion that
5128                // also works for cross-domain stylesheets.
5129                //
5130                // Props to Zach Leatherman for calling my attention to this
5131                // technique.
5132                node.innerHTML = (req.attributes.charset ?
5133                    '@charset "' + req.attributes.charset + '";' : '') +
5134                    '@import "' + req.url + '";';
5135            } else {
5136                node.setAttribute('href', req.url);
5137            }
5138        }
5139
5140        // Inject the node.
5141        if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
5142            // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
5143            node.onreadystatechange = function () {
5144                if (/loaded|complete/.test(node.readyState)) {
5145                    node.onreadystatechange = null;
5146                    onLoad();
5147                }
5148            };
5149        } else if (!isScript && !env.cssLoad) {
5150            // CSS on Firefox <9 or WebKit.
5151            this._poll(req);
5152        } else {
5153            // Script or CSS on everything else. Using DOM 0 events because that
5154            // evens the playing field with older IEs.
5155
5156            if (ua.ie >= 10) {
5157
5158                // We currently need to introduce a timeout for IE10, since it
5159                // calls onerror/onload synchronously for 304s - messing up existing
5160                // program flow.
5161
5162                // Remove this block if the following bug gets fixed by GA
5163                /*jshint maxlen: 1500 */
5164                // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
5165                node.onerror = function() { setTimeout(onError, 0); };
5166                node.onload  = function() { setTimeout(onLoad, 0); };
5167            } else {
5168                node.onerror = onError;
5169                node.onload  = onLoad;
5170            }
5171
5172            // If this browser doesn't fire an event when CSS fails to load,
5173            // fail after a timeout to avoid blocking the transaction queue.
5174            if (!env.cssFail && !isScript) {
5175                cssTimeout = setTimeout(onError, req.timeout || 3000);
5176            }
5177        }
5178
5179        this.nodes.push(node);
5180        insertBefore.parentNode.insertBefore(node, insertBefore);
5181    },
5182
5183    _next: function () {
5184        if (this._pending) {
5185            return;
5186        }
5187
5188        // If there are requests in the queue, insert the next queued request.
5189        // Otherwise, if we're waiting on already-inserted requests to finish,
5190        // wait longer. If there are no queued requests and we're not waiting
5191        // for anything to load, then we're done!
5192        if (this._queue.length) {
5193            this._insert(this._queue.shift());
5194        } else if (!this._reqsWaiting) {
5195            this._finish();
5196        }
5197    },
5198
5199    _poll: function (newReq) {
5200        var self       = this,
5201            pendingCSS = self._pendingCSS,
5202            isWebKit   = Y.UA.webkit,
5203            i, hasRules, j, nodeHref, req, sheets;
5204
5205        if (newReq) {
5206            pendingCSS || (pendingCSS = self._pendingCSS = []);
5207            pendingCSS.push(newReq);
5208
5209            if (self._pollTimer) {
5210                // A poll timeout is already pending, so no need to create a
5211                // new one.
5212                return;
5213            }
5214        }
5215
5216        self._pollTimer = null;
5217
5218        // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
5219        // will still be treated as a success. There's no good workaround for
5220        // this.
5221
5222        for (i = 0; i < pendingCSS.length; ++i) {
5223            req = pendingCSS[i];
5224
5225            if (isWebKit) {
5226                // Look for a stylesheet matching the pending URL.
5227                sheets   = req.doc.styleSheets;
5228                j        = sheets.length;
5229                nodeHref = req.node.href;
5230
5231                while (--j >= 0) {
5232                    if (sheets[j].href === nodeHref) {
5233                        pendingCSS.splice(i, 1);
5234                        i -= 1;
5235                        self._progress(null, req);
5236                        break;
5237                    }
5238                }
5239            } else {
5240                // Many thanks to Zach Leatherman for calling my attention to
5241                // the @import-based cross-domain technique used here, and to
5242                // Oleg Slobodskoi for an earlier same-domain implementation.
5243                //
5244                // See Zach's blog for more details:
5245                // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
5246                try {
5247                    // We don't really need to store this value since we never
5248                    // use it again, but if we don't store it, Closure Compiler
5249                    // assumes the code is useless and removes it.
5250                    hasRules = !!req.node.sheet.cssRules;
5251
5252                    // If we get here, the stylesheet has loaded.
5253                    pendingCSS.splice(i, 1);
5254                    i -= 1;
5255                    self._progress(null, req);
5256                } catch (ex) {
5257                    // An exception means the stylesheet is still loading.
5258                }
5259            }
5260        }
5261
5262        if (pendingCSS.length) {
5263            self._pollTimer = setTimeout(function () {
5264                self._poll.call(self);
5265            }, self.options.pollInterval);
5266        }
5267    },
5268
5269    _progress: function (err, req) {
5270        var options = this.options;
5271
5272        if (err) {
5273            req.error = err;
5274
5275            this.errors.push({
5276                error  : err,
5277                request: req
5278            });
5279
5280        }
5281
5282        req.node._yuiget_finished = req.finished = true;
5283
5284        if (options.onProgress) {
5285            options.onProgress.call(options.context || this,
5286                this._getEventData(req));
5287        }
5288
5289        if (req.autopurge) {
5290            // Pre-3.5.0 Get always excludes the most recent node from an
5291            // autopurge. I find this odd, but I'm keeping that behavior for
5292            // the sake of backcompat.
5293            Get._autoPurge(this.options.purgethreshold);
5294            Get._purgeNodes.push(req.node);
5295        }
5296
5297        if (this._pending === req) {
5298            this._pending = null;
5299        }
5300
5301        this._reqsWaiting -= 1;
5302
5303        this._next();
5304    }
5305};
5306
5307
5308}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5309YUI.add('features', function (Y, NAME) {
5310
5311var feature_tests = {};
5312
5313/**
5314Contains the core of YUI's feature test architecture.
5315@module features
5316*/
5317
5318/**
5319* Feature detection
5320* @class Features
5321* @static
5322*/
5323
5324Y.mix(Y.namespace('Features'), {
5325
5326    /**
5327    * Object hash of all registered feature tests
5328    * @property tests
5329    * @type Object
5330    */
5331    tests: feature_tests,
5332
5333    /**
5334    * Add a test to the system
5335    *
5336    *   ```
5337    *   Y.Features.add("load", "1", {});
5338    *   ```
5339    *
5340    * @method add
5341    * @param {String} cat The category, right now only 'load' is supported
5342    * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
5343    * @param {Object} o Object containing test properties
5344    * @param {String} o.name The name of the test
5345    * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
5346    * @param {String} o.trigger The module that triggers this test.
5347    */
5348    add: function(cat, name, o) {
5349        feature_tests[cat] = feature_tests[cat] || {};
5350        feature_tests[cat][name] = o;
5351    },
5352    /**
5353    * Execute all tests of a given category and return the serialized results
5354    *
5355    *   ```
5356    *   caps=1:1;2:1;3:0
5357    *   ```
5358    * @method all
5359    * @param {String} cat The category to execute
5360    * @param {Array} args The arguments to pass to the test function
5361    * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
5362    */
5363    all: function(cat, args) {
5364        var cat_o = feature_tests[cat],
5365            // results = {};
5366            result = [];
5367        if (cat_o) {
5368            Y.Object.each(cat_o, function(v, k) {
5369                result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
5370            });
5371        }
5372
5373        return (result.length) ? result.join(';') : '';
5374    },
5375    /**
5376    * Run a specific test and return a Boolean response.
5377    *
5378    *   ```
5379    *   Y.Features.test("load", "1");
5380    *   ```
5381    *
5382    * @method test
5383    * @param {String} cat The category of the test to run
5384    * @param {String} name The name of the test to run
5385    * @param {Array} args The arguments to pass to the test function
5386    * @return {Boolean} True or false if the test passed/failed.
5387    */
5388    test: function(cat, name, args) {
5389        args = args || [];
5390        var result, ua, test,
5391            cat_o = feature_tests[cat],
5392            feature = cat_o && cat_o[name];
5393
5394        if (!feature) {
5395        } else {
5396
5397            result = feature.result;
5398
5399            if (Y.Lang.isUndefined(result)) {
5400
5401                ua = feature.ua;
5402                if (ua) {
5403                    result = (Y.UA[ua]);
5404                }
5405
5406                test = feature.test;
5407                if (test && ((!ua) || result)) {
5408                    result = test.apply(Y, args);
5409                }
5410
5411                feature.result = result;
5412            }
5413        }
5414
5415        return result;
5416    }
5417});
5418
5419// Y.Features.add("load", "1", {});
5420// Y.Features.test("load", "1");
5421// caps=1:1;2:0;3:1;
5422
5423/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
5424/*jshint maxlen:900, eqeqeq: false */
5425var add = Y.Features.add;
5426// app-transitions-native
5427add('load', '0', {
5428    "name": "app-transitions-native",
5429    "test": function (Y) {
5430    var doc  = Y.config.doc,
5431        node = doc ? doc.documentElement : null;
5432
5433    if (node && node.style) {
5434        return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5435    }
5436
5437    return false;
5438},
5439    "trigger": "app-transitions"
5440});
5441// autocomplete-list-keys
5442add('load', '1', {
5443    "name": "autocomplete-list-keys",
5444    "test": function (Y) {
5445    // Only add keyboard support to autocomplete-list if this doesn't appear to
5446    // be an iOS or Android-based mobile device.
5447    //
5448    // There's currently no feasible way to actually detect whether a device has
5449    // a hardware keyboard, so this sniff will have to do. It can easily be
5450    // overridden by manually loading the autocomplete-list-keys module.
5451    //
5452    // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5453    // doesn't fire the keyboard events used by AutoCompleteList, so there's
5454    // no point loading the -keys module even when a bluetooth keyboard may be
5455    // available.
5456    return !(Y.UA.ios || Y.UA.android);
5457},
5458    "trigger": "autocomplete-list"
5459});
5460// dd-gestures
5461add('load', '2', {
5462    "name": "dd-gestures",
5463    "trigger": "dd-drag",
5464    "ua": "touchEnabled"
5465});
5466// dom-style-ie
5467add('load', '3', {
5468    "name": "dom-style-ie",
5469    "test": function (Y) {
5470
5471    var testFeature = Y.Features.test,
5472        addFeature = Y.Features.add,
5473        WINDOW = Y.config.win,
5474        DOCUMENT = Y.config.doc,
5475        DOCUMENT_ELEMENT = 'documentElement',
5476        ret = false;
5477
5478    addFeature('style', 'computedStyle', {
5479        test: function() {
5480            return WINDOW && 'getComputedStyle' in WINDOW;
5481        }
5482    });
5483
5484    addFeature('style', 'opacity', {
5485        test: function() {
5486            return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5487        }
5488    });
5489
5490    ret =  (!testFeature('style', 'opacity') &&
5491            !testFeature('style', 'computedStyle'));
5492
5493    return ret;
5494},
5495    "trigger": "dom-style"
5496});
5497// editor-para-ie
5498add('load', '4', {
5499    "name": "editor-para-ie",
5500    "trigger": "editor-para",
5501    "ua": "ie",
5502    "when": "instead"
5503});
5504// event-base-ie
5505add('load', '5', {
5506    "name": "event-base-ie",
5507    "test": function(Y) {
5508    var imp = Y.config.doc && Y.config.doc.implementation;
5509    return (imp && (!imp.hasFeature('Events', '2.0')));
5510},
5511    "trigger": "node-base"
5512});
5513// graphics-canvas
5514add('load', '6', {
5515    "name": "graphics-canvas",
5516    "test": function(Y) {
5517    var DOCUMENT = Y.config.doc,
5518        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5519		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5520        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5521    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5522},
5523    "trigger": "graphics"
5524});
5525// graphics-canvas-default
5526add('load', '7', {
5527    "name": "graphics-canvas-default",
5528    "test": function(Y) {
5529    var DOCUMENT = Y.config.doc,
5530        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5531		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5532        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5533    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5534},
5535    "trigger": "graphics"
5536});
5537// graphics-svg
5538add('load', '8', {
5539    "name": "graphics-svg",
5540    "test": function(Y) {
5541    var DOCUMENT = Y.config.doc,
5542        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5543		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5544        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5545
5546    return svg && (useSVG || !canvas);
5547},
5548    "trigger": "graphics"
5549});
5550// graphics-svg-default
5551add('load', '9', {
5552    "name": "graphics-svg-default",
5553    "test": function(Y) {
5554    var DOCUMENT = Y.config.doc,
5555        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5556		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5557        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5558
5559    return svg && (useSVG || !canvas);
5560},
5561    "trigger": "graphics"
5562});
5563// graphics-vml
5564add('load', '10', {
5565    "name": "graphics-vml",
5566    "test": function(Y) {
5567    var DOCUMENT = Y.config.doc,
5568		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5569    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5570},
5571    "trigger": "graphics"
5572});
5573// graphics-vml-default
5574add('load', '11', {
5575    "name": "graphics-vml-default",
5576    "test": function(Y) {
5577    var DOCUMENT = Y.config.doc,
5578		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5579    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5580},
5581    "trigger": "graphics"
5582});
5583// history-hash-ie
5584add('load', '12', {
5585    "name": "history-hash-ie",
5586    "test": function (Y) {
5587    var docMode = Y.config.doc && Y.config.doc.documentMode;
5588
5589    return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5590            !docMode || docMode < 8);
5591},
5592    "trigger": "history-hash"
5593});
5594// io-nodejs
5595add('load', '13', {
5596    "name": "io-nodejs",
5597    "trigger": "io-base",
5598    "ua": "nodejs"
5599});
5600// json-parse-shim
5601add('load', '14', {
5602    "name": "json-parse-shim",
5603    "test": function (Y) {
5604    var _JSON = Y.config.global.JSON,
5605        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5606        nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5607
5608    function workingNative( k, v ) {
5609        return k === "ok" ? true : v;
5610    }
5611
5612    // Double check basic functionality.  This is mainly to catch early broken
5613    // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5614    if ( nativeSupport ) {
5615        try {
5616            nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5617        }
5618        catch ( e ) {
5619            nativeSupport = false;
5620        }
5621    }
5622
5623    return !nativeSupport;
5624},
5625    "trigger": "json-parse"
5626});
5627// json-stringify-shim
5628add('load', '15', {
5629    "name": "json-stringify-shim",
5630    "test": function (Y) {
5631    var _JSON = Y.config.global.JSON,
5632        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5633        nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5634
5635    // Double check basic native functionality.  This is primarily to catch broken
5636    // early JSON API implementations in Firefox 3.1 beta1 and beta2.
5637    if ( nativeSupport ) {
5638        try {
5639            nativeSupport = ( '0' === Native.stringify(0) );
5640        } catch ( e ) {
5641            nativeSupport = false;
5642        }
5643    }
5644
5645
5646    return !nativeSupport;
5647},
5648    "trigger": "json-stringify"
5649});
5650// scrollview-base-ie
5651add('load', '16', {
5652    "name": "scrollview-base-ie",
5653    "trigger": "scrollview-base",
5654    "ua": "ie"
5655});
5656// selector-css2
5657add('load', '17', {
5658    "name": "selector-css2",
5659    "test": function (Y) {
5660    var DOCUMENT = Y.config.doc,
5661        ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5662
5663    return ret;
5664},
5665    "trigger": "selector"
5666});
5667// transition-timer
5668add('load', '18', {
5669    "name": "transition-timer",
5670    "test": function (Y) {
5671    var DOCUMENT = Y.config.doc,
5672        node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5673        ret = true;
5674
5675    if (node && node.style) {
5676        ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5677    }
5678
5679    return ret;
5680},
5681    "trigger": "transition"
5682});
5683// widget-base-ie
5684add('load', '19', {
5685    "name": "widget-base-ie",
5686    "trigger": "widget-base",
5687    "ua": "ie"
5688});
5689// yql-jsonp
5690add('load', '20', {
5691    "name": "yql-jsonp",
5692    "test": function (Y) {
5693    /* Only load the JSONP module when not in nodejs or winjs
5694    TODO Make the winjs module a CORS module
5695    */
5696    return (!Y.UA.nodejs && !Y.UA.winjs);
5697},
5698    "trigger": "yql"
5699});
5700// yql-nodejs
5701add('load', '21', {
5702    "name": "yql-nodejs",
5703    "trigger": "yql",
5704    "ua": "nodejs"
5705});
5706// yql-winjs
5707add('load', '22', {
5708    "name": "yql-winjs",
5709    "trigger": "yql",
5710    "ua": "winjs"
5711});
5712
5713}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5714YUI.add('intl-base', function (Y, NAME) {
5715
5716/**
5717 * The Intl utility provides a central location for managing sets of
5718 * localized resources (strings and formatting patterns).
5719 *
5720 * @class Intl
5721 * @uses EventTarget
5722 * @static
5723 */
5724
5725var SPLIT_REGEX = /[, ]/;
5726
5727Y.mix(Y.namespace('Intl'), {
5728
5729 /**
5730    * Returns the language among those available that
5731    * best matches the preferred language list, using the Lookup
5732    * algorithm of BCP 47.
5733    * If none of the available languages meets the user's preferences,
5734    * then "" is returned.
5735    * Extended language ranges are not supported.
5736    *
5737    * @method lookupBestLang
5738    * @param {String[] | String} preferredLanguages The list of preferred
5739    * languages in descending preference order, represented as BCP 47
5740    * language tags. A string array or a comma-separated list.
5741    * @param {String[]} availableLanguages The list of languages
5742    * that the application supports, represented as BCP 47 language
5743    * tags.
5744    *
5745    * @return {String} The available language that best matches the
5746    * preferred language list, or "".
5747    * @since 3.1.0
5748    */
5749    lookupBestLang: function(preferredLanguages, availableLanguages) {
5750
5751        var i, language, result, index;
5752
5753        // check whether the list of available languages contains language;
5754        // if so return it
5755        function scan(language) {
5756            var i;
5757            for (i = 0; i < availableLanguages.length; i += 1) {
5758                if (language.toLowerCase() ===
5759                            availableLanguages[i].toLowerCase()) {
5760                    return availableLanguages[i];
5761                }
5762            }
5763        }
5764
5765        if (Y.Lang.isString(preferredLanguages)) {
5766            preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5767        }
5768
5769        for (i = 0; i < preferredLanguages.length; i += 1) {
5770            language = preferredLanguages[i];
5771            if (!language || language === '*') {
5772                continue;
5773            }
5774            // check the fallback sequence for one language
5775            while (language.length > 0) {
5776                result = scan(language);
5777                if (result) {
5778                    return result;
5779                } else {
5780                    index = language.lastIndexOf('-');
5781                    if (index >= 0) {
5782                        language = language.substring(0, index);
5783                        // one-character subtags get cut along with the
5784                        // following subtag
5785                        if (index >= 2 && language.charAt(index - 2) === '-') {
5786                            language = language.substring(0, index - 2);
5787                        }
5788                    } else {
5789                        // nothing available for this language
5790                        break;
5791                    }
5792                }
5793            }
5794        }
5795
5796        return '';
5797    }
5798});
5799
5800
5801}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5802YUI.add('yui-log', function (Y, NAME) {
5803
5804/**
5805 * Provides console log capability and exposes a custom event for
5806 * console implementations. This module is a `core` YUI module,
5807 * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
5808 *
5809 * @module yui
5810 * @submodule yui-log
5811 */
5812
5813var INSTANCE = Y,
5814    LOGEVENT = 'yui:log',
5815    UNDEFINED = 'undefined',
5816    LEVELS = { debug: 1,
5817               info: 2,
5818               warn: 4,
5819               error: 8 };
5820
5821/**
5822 * If the 'debug' config is true, a 'yui:log' event will be
5823 * dispatched, which the Console widget and anything else
5824 * can consume.  If the 'useBrowserConsole' config is true, it will
5825 * write to the browser console if available.  YUI-specific log
5826 * messages will only be present in the -debug versions of the
5827 * JS files.  The build system is supposed to remove log statements
5828 * from the raw and minified versions of the files.
5829 *
5830 * @method log
5831 * @for YUI
5832 * @param  {String}  msg  The message to log.
5833 * @param  {String}  cat  The log category for the message.  Default
5834 *                        categories are "info", "warn", "error", "debug".
5835 *                        Custom categories can be used as well. (opt).
5836 * @param  {String}  src  The source of the the message (opt).
5837 * @param  {boolean} silent If true, the log event won't fire.
5838 * @return {YUI}      YUI instance.
5839 */
5840INSTANCE.log = function(msg, cat, src, silent) {
5841    var bail, excl, incl, m, f, minlevel,
5842        Y = INSTANCE,
5843        c = Y.config,
5844        publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
5845    // suppress log message if the config is off or the event stack
5846    // or the event call stack contains a consumer of the yui:log event
5847    if (c.debug) {
5848        // apply source filters
5849        src = src || "";
5850        if (typeof src !== "undefined") {
5851            excl = c.logExclude;
5852            incl = c.logInclude;
5853            if (incl && !(src in incl)) {
5854                bail = 1;
5855            } else if (incl && (src in incl)) {
5856                bail = !incl[src];
5857            } else if (excl && (src in excl)) {
5858                bail = excl[src];
5859            }
5860
5861            // Set a default category of info if the category was not defined.
5862            if ((typeof cat === 'undefined')) {
5863                cat = 'info';
5864            }
5865
5866            // Determine the current minlevel as defined in configuration
5867            Y.config.logLevel = Y.config.logLevel || 'debug';
5868            minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
5869
5870            if (cat in LEVELS && LEVELS[cat] < minlevel) {
5871                // Skip this message if the we don't meet the defined minlevel
5872                bail = 1;
5873            }
5874        }
5875        if (!bail) {
5876            if (c.useBrowserConsole) {
5877                m = (src) ? src + ': ' + msg : msg;
5878                if (Y.Lang.isFunction(c.logFn)) {
5879                    c.logFn.call(Y, msg, cat, src);
5880                } else if (typeof console !== UNDEFINED && console.log) {
5881                    f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
5882                    console[f](m);
5883                } else if (typeof opera !== UNDEFINED) {
5884                    opera.postError(m);
5885                }
5886            }
5887
5888            if (publisher && !silent) {
5889
5890                if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
5891                    publisher.publish(LOGEVENT, {
5892                        broadcast: 2
5893                    });
5894                }
5895
5896                publisher.fire(LOGEVENT, {
5897                    msg: msg,
5898                    cat: cat,
5899                    src: src
5900                });
5901            }
5902        }
5903    }
5904
5905    return Y;
5906};
5907
5908/**
5909 * Write a system message.  This message will be preserved in the
5910 * minified and raw versions of the YUI files, unlike log statements.
5911 * @method message
5912 * @for YUI
5913 * @param  {String}  msg  The message to log.
5914 * @param  {String}  cat  The log category for the message.  Default
5915 *                        categories are "info", "warn", "error", "debug".
5916 *                        Custom categories can be used as well. (opt).
5917 * @param  {String}  src  The source of the the message (opt).
5918 * @param  {boolean} silent If true, the log event won't fire.
5919 * @return {YUI}      YUI instance.
5920 */
5921INSTANCE.message = function() {
5922    return INSTANCE.log.apply(INSTANCE, arguments);
5923};
5924
5925
5926}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5927YUI.add('yui-later', function (Y, NAME) {
5928
5929/**
5930 * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
5931 * <a href="../classes/YUI.html#method_later">
5931it's documentation is located under the YUI class</a>.
5932 *
5933 * @module yui
5934 * @submodule yui-later
5935 */
5936
5937var NO_ARGS = [];
5938
5939/**
5940 * Executes the supplied function in the context of the supplied
5941 * object 'when' milliseconds later.  Executes the function a
5942 * single time unless periodic is set to true.
5943 * @for YUI
5944 * @method later
5945 * @param when {Number} the number of milliseconds to wait until the fn
5946 * is executed.
5947 * @param o the context object.
5948 * @param fn {Function|String} the function to execute or the name of
5949 * the method in the 'o' object to execute.
5950 * @param data [Array] data that is provided to the function.  This
5951 * accepts either a single item or an array.  If an array is provided,
5952 * the function is executed with one parameter for each array item.
5953 * If you need to pass a single array parameter, it needs to be wrapped
5954 * in an array [myarray].
5955 *
5956 * Note: native methods in IE may not have the call and apply methods.
5957 * In this case, it will work, but you are limited to four arguments.
5958 *
5959 * @param periodic {boolean} if true, executes continuously at supplied
5960 * interval until canceled.
5961 * @return {object} a timer object. Call the cancel() method on this
5962 * object to stop the timer.
5963 */
5964Y.later = function(when, o, fn, data, periodic) {
5965    when = when || 0;
5966    data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
5967    o = o || Y.config.win || Y;
5968
5969    var cancelled = false,
5970        method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
5971        wrapper = function() {
5972            // IE 8- may execute a setInterval callback one last time
5973            // after clearInterval was called, so in order to preserve
5974            // the cancel() === no more runny-run, we have to jump through
5975            // an extra hoop.
5976            if (!cancelled) {
5977                if (!method.apply) {
5978                    method(data[0], data[1], data[2], data[3]);
5979                } else {
5980                    method.apply(o, data || NO_ARGS);
5981                }
5982            }
5983        },
5984        id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
5985
5986    return {
5987        id: id,
5988        interval: periodic,
5989        cancel: function() {
5990            cancelled = true;
5991            if (this.interval) {
5992                clearInterval(id);
5993            } else {
5994                clearTimeout(id);
5995            }
5996        }
5997    };
5998};
5999
6000Y.Lang.later = Y.later;
6001
6002
6003
6004}, 'patched-v3.18.1', {"requires": ["yui-base"]});
6005YUI.add('loader-base', function (Y, NAME) {
6006
6007/**
6008 * The YUI loader core
6009 * @module loader
6010 * @submodule loader-base
6011 */
6012
6013(function() {
6014    var VERSION = Y.version,
6015        BUILD = '/build/',
6016        ROOT = VERSION + '/',
6017        CDN_BASE = Y.Env.base,
6018        GALLERY_VERSION = 'gallery-2014.06.04-21-38',
6019        TNT = '2in3',
6020        TNT_VERSION = '4',
6021        YUI2_VERSION = '2.9.0',
6022        COMBO_BASE = CDN_BASE + 'combo?',
6023        META = {
6024            version: VERSION,
6025            root: ROOT,
6026            base: Y.Env.base,
6027            comboBase: COMBO_BASE,
6028            skin: {
6029                defaultSkin: 'sam',
6030                base: 'assets/skins/',
6031                path: 'skin.css',
6032                after: [
6033                    'cssreset',
6034                    'cssfonts',
6035                    'cssgrids',
6036                    'cssbase',
6037                    'cssreset-context',
6038                    'cssfonts-context'
6039                ]
6040            },
6041            groups: {},
6042            patterns: {}
6043        },
6044        groups = META.groups,
6045        yui2Update = function(tnt, yui2, config) {
6046            var root = TNT + '.' +
6047                    (tnt || TNT_VERSION) + '/' +
6048                    (yui2 || YUI2_VERSION) + BUILD,
6049                base = (config && config.base) ? config.base : CDN_BASE,
6050                combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6051
6052            groups.yui2.base = base + root;
6053            groups.yui2.root = root;
6054            groups.yui2.comboBase = combo;
6055        },
6056        galleryUpdate = function(tag, config) {
6057            var root = (tag || GALLERY_VERSION) + BUILD,
6058                base = (config && config.base) ? config.base : CDN_BASE,
6059                combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6060
6061            groups.gallery.base = base + root;
6062            groups.gallery.root = root;
6063            groups.gallery.comboBase = combo;
6064        };
6065
6066
6067    groups[VERSION] = {};
6068
6069    groups.gallery = {
6070        ext: false,
6071        combine: true,
6072        comboBase: COMBO_BASE,
6073        update: galleryUpdate,
6074        patterns: {
6075            'gallery-': {},
6076            'lang/gallery-': {},
6077            'gallerycss-': {
6078                type: 'css'
6079            }
6080        }
6081    };
6082
6083    groups.yui2 = {
6084        combine: true,
6085        ext: false,
6086        comboBase: COMBO_BASE,
6087        update: yui2Update,
6088        patterns: {
6089            'yui2-': {
6090                configFn: function(me) {
6091                    if (/-skin|reset|fonts|grids|base/.test(me.name)) {
6092                        me.type = 'css';
6093                        me.path = me.path.replace(/\.js/, '.css');
6094                        // this makes skins in builds earlier than
6095                        // 2.6.0 work as long as combine is false
6096                        me.path = me.path.replace(/\/yui2-skin/,
6097                                            '/assets/skins/sam/yui2-skin');
6098                    }
6099                }
6100            }
6101        }
6102    };
6103
6104    galleryUpdate();
6105    yui2Update();
6106
6107    if (YUI.Env[VERSION]) {
6108        Y.mix(META, YUI.Env[VERSION], false, [
6109            'modules',
6110            'groups',
6111            'skin'
6112        ], 0, true);
6113    }
6114
6115    YUI.Env[VERSION] = META;
6116}());
6117/*jslint forin: true, maxlen: 350 */
6118
6119/**
6120 * Loader dynamically loads script and css files.  It includes the dependency
6121 * information for the version of the library in use, and will automatically pull in
6122 * dependencies for the modules requested. It can also load the
6123 * files from the Yahoo! CDN, and it can utilize the combo service provided on
6124 * this network to reduce the number of http connections required to download
6125 * YUI files.
6126 *
6127 * @module loader
6128 * @main loader
6129 * @submodule loader-base
6130 */
6131
6132var NOT_FOUND = {},
6133    NO_REQUIREMENTS = [],
6134    MAX_URL_LENGTH = 1024,
6135    GLOBAL_ENV = YUI.Env,
6136    GLOBAL_LOADED = GLOBAL_ENV._loaded,
6137    CSS = 'css',
6138    JS = 'js',
6139    INTL = 'intl',
6140    DEFAULT_SKIN = 'sam',
6141    VERSION = Y.version,
6142    ROOT_LANG = '',
6143    YObject = Y.Object,
6144    oeach = YObject.each,
6145    yArray = Y.Array,
6146    _queue = GLOBAL_ENV._loaderQueue,
6147    META = GLOBAL_ENV[VERSION],
6148    SKIN_PREFIX = 'skin-',
6149    L = Y.Lang,
6150    ON_PAGE = GLOBAL_ENV.mods,
6151    modulekey,
6152    _path = function(dir, file, type, nomin) {
6153        var path = dir + '/' + file;
6154        if (!nomin) {
6155            path += '-min';
6156        }
6157        path += '.' + (type || CSS);
6158
6159        return path;
6160    };
6161
6162
6163    if (!YUI.Env._cssLoaded) {
6164        YUI.Env._cssLoaded = {};
6165    }
6166
6167
6168/**
6169 * The component metadata is stored in Y.Env.meta.
6170 * Part of the loader module.
6171 * @property meta
6172 * @for YUI
6173 */
6174Y.Env.meta = META;
6175
6176/**
6177 * Loader dynamically loads script and css files.  It includes the dependency
6178 * info for the version of the library in use, and will automatically pull in
6179 * dependencies for the modules requested. It can load the
6180 * files from the Yahoo! CDN, and it can utilize the combo service provided on
6181 * this network to reduce the number of http connections required to download
6182 * YUI files. You can also specify an external, custom combo service to host
6183 * your modules as well.
6184
6185        var Y = YUI();
6186        var loader = new Y.Loader({
6187            filter: 'debug',
6188            base: '../../',
6189            root: 'build/',
6190            combine: true,
6191            require: ['node', 'dd', 'console']
6192        });
6193        var out = loader.resolve(true);
6194
6195 * If the Loader needs to be patched before it is used for the first time, it
6196 * should be done through the `doBeforeLoader` hook. Simply make the patch
6197 * available via configuration before YUI is loaded:
6198
6199        YUI_config = YUI_config || {};
6200        YUI_config.doBeforeLoader = function (config) {
6201            var resolve = this.context.Loader.prototype.resolve;
6202            this.context.Loader.prototype.resolve = function () {
6203                // do something here
6204                return resolve.apply(this, arguments);
6205            };
6206        };
6207
6208 * @constructor
6209 * @class Loader
6210 * @param {Object} config an optional set of configuration options.
6211 * @param {String} config.base The base dir which to fetch this module from
6212 * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?`
6213 * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/`
6214 * @param {String|Object} config.filter A filter to apply to result urls. <a href="#property_filter">See filter property</a>
6215 * @param {Object} config.filters Per-component filter specification.  If specified for a given component, this overrides the filter config.
6216 * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies
6217 * @param {Boolean} [config.async=true] Fetch files in async
6218 * @param {Array} config.ignore: A list of modules that should never be dynamically loaded
6219 * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page
6220 * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes
6221 * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes
6222 * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes
6223 * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes.  If not set, there is no timeout
6224 * @param {Object} config.context Execution context for all callbacks
6225 * @param {Function} config.onSuccess Callback for the 'success' event
6226 * @param {Function} config.onFailure Callback for the 'failure' event
6227 * @param {Function} config.onTimeout Callback for the 'timeout' event
6228 * @param {Function} config.onProgress Callback executed each time a script or css file is loaded
6229 * @param {Object} config.modules A list of module definitions.  See <a href="#method_addModule">Loader.addModule</a> for the supported module metadata
6230 * @param {Object} config.groups A list of group definitions.  Each group can contain specific definitions for `base`, `comboBase`, `combine`, and accepts a list of `modules`.
6231 * @param {String} config.2in3 The version of the YUI 2 in 3 wrapper to use.  The intrinsic support for YUI 2 modules in YUI 3 relies on versions of the YUI 2 components inside YUI 3 module wrappers.  These wrappers change over time to accomodate the issues that arise from running YUI 2 in a YUI 3 sandbox.
6232 * @param {String} config.yui2 When using the 2in3 project, you can select the version of YUI 2 to use.  V
6232alid values are `2.2.2`, `2.3.1`, `2.4.1`, `2.5.2`, `2.6.0`, `2.7.0`, `2.8.0`, `2.8.1` and `2.9.0` [default] -- plus all versions of YUI 2 going forward.
6233 * @param {Function} config.doBeforeLoader An optional hook that allows for the patching of the loader instance. The `Y` instance is available as `this.context` and the only argument to the function is the Loader configuration object.
6234 */
6235Y.Loader = function(o) {
6236
6237    var self = this;
6238
6239    //Catch no config passed.
6240    o = o || {};
6241
6242    modulekey = META.md5;
6243
6244    /**
6245     * Internal callback to handle multiple internal insert() calls
6246     * so that css is inserted prior to js
6247     * @property _internalCallback
6248     * @private
6249     */
6250    // self._internalCallback = null;
6251
6252    /**
6253     * Callback that will be executed when the loader is finished
6254     * with an insert
6255     * @method onSuccess
6256     * @type function
6257     */
6258    // self.onSuccess = null;
6259
6260    /**
6261     * Callback that will be executed if there is a failure
6262     * @method onFailure
6263     * @type function
6264     */
6265    // self.onFailure = null;
6266
6267    /**
6268     * Callback executed each time a script or css file is loaded
6269     * @method onProgress
6270     * @type function
6271     */
6272    // self.onProgress = null;
6273
6274    /**
6275     * Callback that will be executed if a timeout occurs
6276     * @method onTimeout
6277     * @type function
6278     */
6279    // self.onTimeout = null;
6280
6281    /**
6282     * The execution context for all callbacks
6283     * @property context
6284     * @default {YUI} the YUI instance
6285     */
6286    self.context = Y;
6287
6288    // Hook that allows the patching of loader
6289    if (o.doBeforeLoader) {
6290        o.doBeforeLoader.apply(self, arguments);
6291    }
6292
6293    /**
6294     * Data that is passed to all callbacks
6295     * @property data
6296     */
6297    // self.data = null;
6298
6299    /**
6300     * Node reference or id where new nodes should be inserted before
6301     * @property insertBefore
6302     * @type string|HTMLElement
6303     */
6304    // self.insertBefore = null;
6305
6306    /**
6307     * The charset attribute for inserted nodes
6308     * @property charset
6309     * @type string
6310     * @deprecated , use cssAttributes or jsAttributes.
6311     */
6312    // self.charset = null;
6313
6314    /**
6315     * An object literal containing attributes to add to link nodes
6316     * @property cssAttributes
6317     * @type object
6318     */
6319    // self.cssAttributes = null;
6320
6321    /**
6322     * An object literal containing attributes to add to script nodes
6323     * @property jsAttributes
6324     * @type object
6325     */
6326    // self.jsAttributes = null;
6327
6328    /**
6329     * The base directory.
6330     * @property base
6331     * @type string
6332     * @default http://yui.yahooapis.com/[YUI VERSION]/build/
6333     */
6334    self.base = Y.Env.meta.base + Y.Env.meta.root;
6335
6336    /**
6337     * Base path for the combo service
6338     * @property comboBase
6339     * @type string
6340     * @default http://yui.yahooapis.com/combo?
6341     */
6342    self.comboBase = Y.Env.meta.comboBase;
6343
6344    /*
6345     * Base path for language packs.
6346     */
6347    // self.langBase = Y.Env.meta.langBase;
6348    // self.lang = "";
6349
6350    /**
6351     * If configured, the loader will attempt to use the combo
6352     * service for YUI resources and configured external resources.
6353     * @property combine
6354     * @type boolean
6355     * @default true if a base dir isn't in the config
6356     */
6357    self.combine = o.base &&
6358        (o.base.indexOf(self.comboBase.substr(0, 20)) > -1);
6359
6360    /**
6361    * The default seperator to use between files in a combo URL
6362    * @property comboSep
6363    * @type {String}
6364    * @default Ampersand
6365    */
6366    self.comboSep = '&';
6367    /**
6368     * Max url length for combo urls.  The default is 1024. This is the URL
6369     * limit for the Yahoo! hosted combo servers.  If consuming
6370     * a different combo service that has a different URL limit
6371     * it is possible to override this default by supplying
6372     * the maxURLLength config option.  The config option will
6373     * only take effect if lower than the default.
6374     *
6375     * @property maxURLLength
6376     * @type int
6377     */
6378    self.maxURLLength = MAX_URL_LENGTH;
6379
6380    /**
6381     * Ignore modules registered on the YUI global
6382     * @property ignoreRegistered
6383     * @default false
6384     */
6385    self.ignoreRegistered = o.ignoreRegistered;
6386
6387    /**
6388     * Root path to prepend to module path for the combo
6389     * service
6390     * @property root
6391     * @type string
6392     * @default [YUI VERSION]/build/
6393     */
6394    self.root = Y.Env.meta.root;
6395
6396    /**
6397     * Timeout value in milliseconds.  If set, self value will be used by
6398     * the get utility.  the timeout event will fire if
6399     * a timeout occurs.
6400     * @property timeout
6401     * @type int
6402     */
6403    self.timeout = 0;
6404
6405    /**
6406     * A list of modules that should not be loaded, even if
6407     * they turn up in the dependency tree
6408     * @property ignore
6409     * @type string[]
6410     */
6411    // self.ignore = null;
6412
6413    /**
6414     * A list of modules that should always be loaded, even
6415     * if they have already been inserted into the page.
6416     * @property force
6417     * @type string[]
6418     */
6419    // self.force = null;
6420
6421    self.forceMap = {};
6422
6423    /**
6424     * Should we allow rollups
6425     * @property allowRollup
6426     * @type boolean
6427     * @default false
6428     */
6429    self.allowRollup = false;
6430
6431    /**
6432     * A filter to apply to result urls.  This filter will modify the default
6433     * path for all modules.  The default path for the YUI library is the
6434     * minified version of the files (e.g., event-min.js).  The filter property
6435     * can be a predefined filter or a custom filter.  The valid predefined
6436     * filters are:
6437     * <dl>
6438     *  <dt>DEBUG</dt>
6439     *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
6440     *      This option will automatically include the Logger widget</dd>
6441     *  <dt>RAW</dt>
6442     *  <dd>Selects the non-minified version of the library (e.g., event.js).
6443     *  </dd>
6444     * </dl>
6445     * You can also define a custom filter, which must be an object literal
6446     * containing a search expression and a replace string:
6447     *
6448     *      myFilter: {
6449     *          'searchExp': "-min\\.js",
6450     *          'replaceStr': "-debug.js"
6451     *      }
6452     *
6453     * @property filter
6454     * @type string| {searchExp: string, replaceStr: string}
6455     */
6456    // self.filter = null;
6457
6458    /**
6459     * per-component filter specification.  If specified for a given
6460     * component, this overrides the filter config.
6461     * @property filters
6462     * @type object
6463     */
6464    self.filters = {};
6465
6466    /**
6467     * The list of requested modules
6468     * @property required
6469     * @type {string: boolean}
6470     */
6471    self.required = {};
6472
6473    /**
6474     * If a module name is predefined when requested, it is checked againsts
6475     * the patterns provided in this property.  If there is a match, the
6476     * module is added with the default configuration.
6477     *
6478     * At the moment only supporting module prefixes, but anticipate
6479     * supporting at least regular expressions.
6480     * @property patterns
6481     * @type Object
6482     */
6483    // self.patterns = Y.merge(Y.Env.meta.patterns);
6484    self.patterns = {};
6485
6486    /**
6487     * Internal loader instance metadata. Use accessor `getModuleInfo()` instead.
6488     */
6489    self.moduleInfo = {};
6490
6491    self.groups = Y.merge(Y.Env.meta.groups);
6492
6493    /**
6494     * Provides the information used to skin the skinnable components.
6495     * The following skin definition would result in 'skin1' and 'skin2'
6496     * being loaded for calendar (if calendar was requested), and
6497     * 'sam' for all other skinnable components:
6498     *
6499     *      skin: {
6500     *          // The default skin, which is automatically applied if not
6501     *          // overriden by a component-specific skin definition.
6502     *          // Change this in to apply a different skin globally
6503     *          defaultSkin: 'sam',
6504     *
6505     *          // This is combined with the loader base property to get
6506     *          // the default root directory for a skin. ex:
6507     *          // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
6508     *          base: 'assets/skins/',
6509     *
6510     *          // Any component-specific overrides can be specified here,
6511     *          // making it possible to load different skins for different
6512     *          // components.  It is possible to load more than one skin
6513     *          // for a given component as well.
6514     *          overrides: {
6515     *              calendar: ['skin1', 'skin2']
6516     *          }
6517     *      }
6518     * @property skin
6519     * @type {Object}
6520     */
6521    self.skin = Y.merge(Y.Env.meta.skin);
6522
6523    /*
6524     * Map of conditional modules
6525     * @since 3.2.0
6526     */
6527    self.conditions = {};
6528
6529    // map of modules with a hash of modules that meet the requirement
6530    // self.provides = {};
6531
6532    self.config = o;
6533    self._internal = true;
6534
6535    self._populateConditionsCache();
6536
6537    /**
6538     * Set when beginning to compute the dependency tree.
6539     * Composed of what YUI reports to be loaded combined
6540     * with what has been loaded by any instance on the page
6541     * with the version number specified in the metadata.
6542     * @property loaded
6543     * @type {string: boolean}
6544     */
6545    self.loaded = GLOBAL_LOADED[VERSION];
6546
6547
6548    /**
6549    * Should Loader fetch scripts in `async`, defaults to `true`
6550    * @property async
6551    */
6552
6553    self.async = true;
6554
6555    self._inspectPage();
6556
6557    self._internal = false;
6558
6559    self._config(o);
6560
6561    self.forceMap = (self.force) ? Y.Array.hash(self.force) : {};
6562
6563    self.testresults = null;
6564
6565    if (Y.config.tests) {
6566        self.testresults = Y.config.tests;
6567    }
6568
6569    /**
6570     * List of rollup files found in the library metadata
6571     * @property rollups
6572     */
6573    // self.rollups = null;
6574
6575    /**
6576     * Whether or not to load optional dependencies for
6577     * the requested modules
6578     * @property loadOptional
6579     * @type boolean
6580     * @default false
6581     */
6582    // self.loadOptional = false;
6583
6584    /**
6585     * All of the derived dependencies in sorted order, which
6586     * will be populated when either calculate() or insert()
6587     * is called
6588     * @property sorted
6589     * @type string[]
6590     */
6591    self.sorted = [];
6592
6593    /*
6594     * A list of modules to attach to the YUI instance when complete.
6595     * If not supplied, the sorted list of dependencies are applied.
6596     * @property attaching
6597     */
6598    // self.attaching = null;
6599
6600    /**
6601     * Flag to indicate the dependency tree needs to be recomputed
6602     * if insert is called again.
6603     * @property dirty
6604     * @type boolean
6605     * @default true
6606     */
6607    self.dirty = true;
6608
6609    /**
6610     * List of modules inserted by the utility
6611     * @property inserted
6612     * @type {string: boolean}
6613     */
6614    self.inserted = {};
6615
6616    /**
6617     * List of skipped modules during insert() because the module
6618     * was not defined
6619     * @property skipped
6620     */
6621    self.skipped = {};
6622
6623    // Y.on('yui:load', self.loadNext, self);
6624
6625    self.tested = {};
6626
6627    /*
6628     * Cached sorted calculate results
6629     * @property results
6630     * @since 3.2.0
6631     */
6632    //self.results = {};
6633
6634    if (self.ignoreRegistered) {
6635        //Clear inpage already processed modules.
6636        self._resetModules();
6637    }
6638
6639};
6640
6641Y.Loader.prototype = {
6642    /**
6643    * Gets the module info from the local moduleInfo hash, or from the
6644    * default metadata and populate the local moduleInfo hash.
6645    * @method getModuleInfo
6646    * @param {string} name of the module
6647    * @public
6648    */
6649    getModuleInfo: function(name) {
6650
6651        var m = this.moduleInfo[name],
6652            rawMetaModules, globalRenderedMods, internal, v;
6653
6654        if (m) {
6655            return m;
6656        }
6657
6658        rawMetaModules = META.modules;
6659        globalRenderedMods = GLOBAL_ENV._renderedMods;
6660        internal = this._internal;
6661
6662        /*
6663        The logic here is:
6664
6665        - if the `moduleInfo[name]` is avilable,
6666          then short circuit
6667        - otherwise, if the module is in the globalCache (cross Y instance),
6668          then port it from the global registry into `moduleInfo[name]`
6669        - otherwise, if the module has raw metadata (from meta modules)
6670          then add it to the global registry and to `moduleInfo[name]`
6671
6672        */
6673        if (globalRenderedMods && globalRenderedMods.hasOwnProperty(name) && !this.ignoreRegistered) {
6674            this.moduleInfo[name] = Y.merge(globalRenderedMods[name]);
6675        } else {
6676            if (rawMetaModules.hasOwnProperty(name)) {
6677                this._internal = true; // making sure that modules from raw data are marked as internal
6678                v = this.addModule(rawMetaModules[name], name);
6679                // Inspect the page for the CSS module and mark it as loaded.
6680                if (v && v.type === CSS) {
6681                    if (this.isCSSLoaded(v.name, true)) {
6682                        this.loaded[v.name] = true;
6683                    }
6684                }
6685                this._internal = internal;
6686            }
6687        }
6688        return this.moduleInfo[name];
6689    },
6690    /**
6691    * Expand the names that are aliases to other modules.
6692    * @method _expandAliases
6693    * @param {string[]} list a module name or a list of names to be expanded
6694    * @private
6695    * @return {array}
6696    */
6697    _expandAliases: function(list) {
6698        var expanded = [],
6699            aliases = YUI.Env.aliases,
6700            i, name;
6701        list = Y.Array(list);
6702        for (i = 0; i < list.length; i += 1) {
6703            name = list[i];
6704            expanded.push.apply(expanded, aliases[name] ? aliases[name] : [name]);
6705        }
6706        return expanded;
6707    },
6708    /**
6709    * Populate the conditions cache from raw modules, this is necessary
6710    * because no other module will require a conditional module, instead
6711    * the condition has to be executed and then the module is analyzed
6712    * to be included in the final requirement list. Without this cache
6713    * conditional modules will be simply ignored.
6714    * @method _populateConditionsCache
6715    * @private
6716    */
6717    _populateConditionsCache: function() {
6718        var rawMetaModules = META.modules,
6719            cache = GLOBAL_ENV._conditions,
6720            i, j, t, trigger;
6721
6722        // if we have conditions in cache and cache is enabled
6723        // we should port them to this loader instance
6724        if (cache && !this.ignoreRegistered) {
6725            for (i in cache) {
6726                if (cache.hasOwnProperty(i)) {
6727                    this.conditions[i] = Y.merge(cache[i]);
6728                }
6729            }
6730        } else {
6731            for (i in rawMetaModules) {
6732                if (rawMetaModules.hasOwnProperty(i) && rawMetaModules[i].condition) {
6733                    t = this._expandAliases(rawMetaModules[i].condition.trigger);
6734                    for (j = 0; j < t.length; j += 1) {
6735                        trigger = t[j];
6736                        this.conditions[trigger] = this.conditions[trigger] || {};
6737                        this.conditions[trigger][rawMetaModules[i].name || i] = rawMetaModules[i].condition;
6738                    }
6739                }
6740            }
6741            GLOBAL_ENV._conditions = this.conditions;
6742        }
6743    },
6744    /**
6745    * Reset modules in the module cache to a pre-processed state so additional
6746    * computations with a different skin or language will work as expected.
6747    * @method _resetModules
6748    * @private
6749    */
6750    _resetModules: function() {
6751        var self = this, i, o,
6752            mod, name, details;
6753        for (i in self.moduleInfo) {
6754            if (self.moduleInfo.hasOwnProperty(i) && self.moduleInfo[i]) {
6755                mod = self.moduleInfo[i];
6756                name = mod.name;
6757                details  = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null);
6758
6759                if (details) {
6760                    self.moduleInfo[name]._reset = true;
6761                    self.moduleInfo[name].requires = details.requires || [];
6762                    self.moduleInfo[name].optional = details.optional || [];
6763                    self.moduleInfo[name].supersedes = details.supercedes || [];
6764                }
6765
6766                if (mod.defaults) {
6767                    for (o in mod.defaults) {
6768                        if (mod.defaults.hasOwnProperty(o)) {
6769                            if (mod[o]) {
6770                                mod[o] = mod.defaults[o];
6771                            }
6772                        }
6773                    }
6774                }
6775                mod.langCache = undefined;
6776                mod.skinCache = undefined;
6777                if (mod.skinnable) {
6778                    self._addSkin(self.skin.defaultSkin, mod.name);
6779                }
6780            }
6781        }
6782    },
6783    /**
6784    Regex that matches a CSS URL. Used to guess the file type when it's not
6785    specified.
6786
6787    @property REGEX_CSS
6788    @type RegExp
6789    @final
6790    @protected
6791    @since 3.5.0
6792    **/
6793    REGEX_CSS: /\.css(?:[?;].*)?$/i,
6794
6795    /**
6796    * Default filters for raw and debug
6797    * @property FILTER_DEFS
6798    * @type Object
6799    * @final
6800    * @protected
6801    */
6802    FILTER_DEFS: {
6803        RAW: {
6804            'searchExp': '-min\\.js',
6805            'replaceStr': '.js'
6806        },
6807        DEBUG: {
6808            'searchExp': '-min\\.js',
6809            'replaceStr': '-debug.js'
6810        },
6811        COVERAGE: {
6812            'searchExp': '-min\\.js',
6813            'replaceStr': '-coverage.js'
6814        }
6815    },
6816    /*
6817    * Check the pages meta-data and cache the result.
6818    * @method _inspectPage
6819    * @private
6820    */
6821    _inspectPage: function() {
6822        var self = this, v, m, req, mr, i;
6823
6824        for (i in ON_PAGE) {
6825            if (ON_PAGE.hasOwnProperty(i)) {
6826                v = ON_PAGE[i];
6827                if (v.details) {
6828                    m = self.getModuleInfo(v.name);
6829                    req = v.details.requires;
6830                    mr = m && m.requires;
6831
6832                   if (m) {
6833                       if (!m._inspected && req && mr.length !== req.length) {
6834                           // console.log('deleting ' + m.name);
6835                           delete m.expanded;
6836                       }
6837                   } else {
6838                       m = self.addModule(v.details, i);
6839                   }
6840                   m._inspected = true;
6841               }
6842            }
6843        }
6844    },
6845    /*
6846    * returns true if b is not loaded, and is required directly or by means of modules it supersedes.
6847    * @private
6848    * @method _requires
6849    * @param {String} mod1 The first module to compare
6850    * @param {String} mod2 The second module to compare
6851    */
6852   _requires: function(mod1, mod2) {
6853
6854        var i, rm, after_map, s,
6855            m = this.getModuleInfo(mod1),
6856            other = this.getModuleInfo(mod2);
6857
6858        if (!m || !other) {
6859            return false;
6860        }
6861
6862        rm = m.expanded_map;
6863        after_map = m.after_map;
6864
6865        // check if this module should be sorted after the other
6866        // do this first to short circut circular deps
6867        if (after_map && (mod2 in after_map)) {
6868            return true;
6869        }
6870
6871        after_map = other.after_map;
6872
6873        // and vis-versa
6874        if (after_map && (mod1 in after_map)) {
6875            return false;
6876        }
6877
6878        // check if this module requires one the other supersedes
6879        s = other.supersedes;
6880        if (s) {
6881            for (i = 0; i < s.length; i++) {
6882                if (this._requires(mod1, s[i])) {
6883                    return true;
6884                }
6885            }
6886        }
6887
6888        s = m.supersedes;
6889        if (s) {
6890            for (i = 0; i < s.length; i++) {
6891                if (this._requires(mod2, s[i])) {
6892                    return false;
6893                }
6894            }
6895        }
6896
6897        // check if this module requires the other directly
6898        // if (r && yArray.indexOf(r, mod2) > -1) {
6899        if (rm && (mod2 in rm)) {
6900            return true;
6901        }
6902
6903        // external css files should be sorted below yui css
6904        if (m.ext && m.type === CSS && !other.ext && other.type === CSS) {
6905            return true;
6906        }
6907
6908        return false;
6909    },
6910    /**
6911    * Apply a new config to the Loader instance
6912    * @method _config
6913    * @private
6914    * @param {Object} o The new configuration
6915    */
6916    _config: function(o) {
6917        var i, j, val, a, f, group, groupName, self = this,
6918            mods = [], mod, modInfo;
6919        // apply config values
6920        if (o) {
6921            for (i in o) {
6922                if (o.hasOwnProperty(i)) {
6923                    val = o[i];
6924                    //TODO This should be a case
6925                    if (i === 'require') {
6926                        self.require(val);
6927                    } else if (i === 'skin') {
6928                        //If the config.skin is a string, format to the expected object
6929                        if (typeof val === 'string') {
6930                            self.skin.defaultSkin = o.skin;
6931                            val = {
6932                                defaultSkin: val
6933                            };
6934                        }
6935
6936                        Y.mix(self.skin, val, true);
6937                    } else if (i === 'groups') {
6938                        for (j in val) {
6939                            if (val.hasOwnProperty(j)) {
6940                                groupName = j;
6941                                group = val[j];
6942                                self.addGroup(group, groupName);
6943                                if (group.aliases) {
6944                                    for (a in group.aliases) {
6945                                        if (group.aliases.hasOwnProperty(a)) {
6946                                            self.addAlias(group.aliases[a], a);
6947                                        }
6948                                    }
6949                                }
6950                            }
6951                        }
6952
6953                    } else if (i === 'modules') {
6954                        // add a hash of module definitions
6955                        for (j in val) {
6956                            if (val.hasOwnProperty(j)) {
6957                                self.addModule(val[j], j);
6958                            }
6959                        }
6960                    } else if (i === 'aliases') {
6961                        for (j in val) {
6962                            if (val.hasOwnProperty(j)) {
6963                                self.addAlias(val[j], j);
6964                            }
6965                        }
6966                    } else if (i === 'gallery') {
6967                        if (this.groups.gallery.update) {
6968                            this.groups.gallery.update(val, o);
6969                        }
6970                    } else if (i === 'yui2' || i === '2in3') {
6971                        if (this.groups.yui2.update) {
6972                            this.groups.yui2.update(o['2in3'], o.yui2, o);
6973                        }
6974                    } else {
6975                        self[i] = val;
6976                    }
6977                }
6978            }
6979        }
6980
6981        // fix filter
6982        f = self.filter;
6983
6984        if (L.isString(f)) {
6985            f = f.toUpperCase();
6986            self.filterName = f;
6987            self.filter = self.FILTER_DEFS[f];
6988            if (f === 'DEBUG') {
6989                self.require('yui-log', 'dump');
6990            }
6991        }
6992
6993        if (self.filterName && self.coverage) {
6994            if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) {
6995                for (i = 0; i < self.coverage.length; i++) {
6996                    mod = self.coverage[i];
6997                    modInfo = self.getModuleInfo(mod);
6998                    if (modInfo && modInfo.use) {
6999                        mods = mods.concat(modInfo.use);
7000                    } else {
7001                        mods.push(mod);
7002                    }
7003                }
7004                self.filters = self.filters || {};
7005                Y.Array.each(mods, function(mod) {
7006                    self.filters[mod] = self.FILTER_DEFS.COVERAGE;
7007                });
7008                self.filterName = 'RAW';
7009                self.filter = self.FILTER_DEFS[self.filterName];
7010            }
7011        }
7012
7013    },
7014
7015    /**
7016     * Returns the skin module name for the specified skin name.  If a
7017     * module name is supplied, the returned skin module name is
7018     * specific to the module passed in.
7019     * @method formatSkin
7020     * @param {string} skin the name of the skin.
7021     * @param {string} mod optional: the name of a module to skin.
7022     * @return {string} the full skin module name.
7023     */
7024    formatSkin: function(skin, mod) {
7025        var s = SKIN_PREFIX + skin;
7026        if (mod) {
7027            s = s + '-' + mod;
7028        }
7029
7030        return s;
7031    },
7032
7033    /**
7034     * Adds the skin def to the module info
7035     * @method _addSkin
7036     * @param {string} skin the name of the skin.
7037     * @param {string} mod the name of the module.
7038     * @param {string} parent parent module if this is a skin of a
7039     * submodule or plugin.
7040     * @return {string} the module name for the skin.
7041     * @private
7042     */
7043    _addSkin: function(skin, mod, parent) {
7044        var pkg, name, nmod,
7045            sinf = this.skin,
7046            mdef = mod && this.getModuleInfo(mod),
7047            ext = mdef && mdef.ext;
7048
7049        // Add a module definition for the module-specific skin css
7050        if (mod) {
7051            name = this.formatSkin(skin, mod);
7052            if (!this.getModuleInfo(name)) {
7053                pkg = mdef.pkg || mod;
7054                nmod = {
7055                    skin: true,
7056                    name: name,
7057                    group: mdef.group,
7058                    type: 'css',
7059                    after: sinf.after,
7060                    path: (parent || pkg) + '/' + sinf.base + skin +
7061                          '/' + mod + '.css',
7062                    ext: ext
7063                };
7064                if (mdef.base) {
7065                    nmod.base = mdef.base;
7066                }
7067                if (mdef.configFn) {
7068                    nmod.configFn = mdef.configFn;
7069                }
7070                this.addModule(nmod, name);
7071
7072            }
7073        }
7074
7075        return name;
7076    },
7077    /**
7078    * Adds an alias module to the system
7079    * @method addAlias
7080    * @param {Array} use An array of modules that makes up this alias
7081    * @param {String} name The name of the alias
7082    * @example
7083    *       var loader = new Y.Loader({});
7084    *       loader.addAlias([ 'node', 'yql' ], 'davglass');
7085    *       loader.require(['davglass']);
7086    *       var out = loader.resolve(true);
7087    *
7088    *       //out.js will contain Node and YQL modules
7089    */
7090    addAlias: function(use, name) {
7091        YUI.Env.aliases[name] = use;
7092        this.addModule({
7093            name: name,
7094            use: use
7095        });
7096    },
7097    /**
7098     * Add a new module group
7099     * @method addGroup
7100     * @param {Object} config An object containing the group configuration data
7101     * @param {String} config.name required, the group name
7102     * @param {String} config.base The base directory for this module group
7103     * @param {String} config.root The root path to add to each combo resource path
7104     * @param {Boolean} config.combine Should the request be combined
7105     * @param {String} config.comboBase Combo service base path
7106     * @param {Object} config.modules The group of modules
7107     * @param {String} name the group name.
7108     * @example
7109     *      var loader = new Y.Loader({});
7110     *      loader.addGroup({
7111     *          name: 'davglass',
7112     *          combine: true,
7113     *          comboBase: '/combo?',
7114     *          root: '',
7115     *          modules: {
7116     *              //Module List here
7117     *          }
7118     *      }, 'davglass');
7119     */
7120    addGroup: function(o, name) {
7121        var mods = o.modules,
7122            self = this,
7123            defaultBase = o.defaultBase || Y.config.defaultBase,
7124            i, v;
7125
7126        name = name || o.name;
7127        o.name = name;
7128        self.groups[name] = o;
7129
7130        if (!o.base && defaultBase && o.root) {
7131            o.base = defaultBase + o.root;
7132        }
7133
7134        if (o.patterns) {
7135            for (i in o.patterns) {
7136                if (o.patterns.hasOwnProperty(i)) {
7137                    o.patterns[i].group = name;
7138                    self.patterns[i] = o.patterns[i];
7139                }
7140            }
7141        }
7142
7143        if (mods) {
7144            for (i in mods) {
7145                if (mods.hasOwnProperty(i)) {
7146                    v = mods[i];
7147                    if (typeof v === 'string') {
7148                        v = { name: i, fullpath: v };
7149                    }
7150                    v.group = name;
7151                    self.addModule(v, i);
7152                }
7153            }
7154        }
7155    },
7156
7157    /**
7158     * Add a new module to the component metadata.
7159     * @method addModule
7160     * @param {Object}
7160 config An object containing the module data.
7161     * @param {String} config.name Required, the component name
7162     * @param {String} config.type Required, the component type (js or css)
7163     * @param {String} config.path Required, the path to the script from `base`
7164     * @param {Array} config.requires Array of modules required by this component
7165     * @param {Array} [config.optional] Array of optional modules for this component
7166     * @param {Array} [config.supersedes] Array of the modules this component replaces
7167     * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one
7168     * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array
7169     * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup
7170     * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path`
7171     * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in
7172     * @param {Object} [config.submodules] Hash of submodules
7173     * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration.
7174     * @param {Array} [config.lang] Array of BCP 47 language tags of languages for which this module has localized resource bundles, e.g., `["en-GB", "zh-Hans-CN"]`
7175     * @param {Object} [config.condition] Specifies that the module should be loaded automatically if a condition is met. This is an object with up to four fields:
7176     * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load
7177     * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded.
7178     * @param {String} [config.condition.ua] The UA name of <a href="UA.html">Y.UA</a> object that returns true when the module is to be loaded. e.g., `"ie"`, `"nodejs"`.
7179     * @param {String} [config.condition.when] Specifies the load order of the conditional module
7180     *  with regard to the position of the trigger module.
7181     *  This should be one of three values: `before`, `after`, or `instead`.  The default is `after`.
7182     * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()`
7183     * @param {Function} [config.configFn] A function to exectute when configuring this module
7184     * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config.
7185     * @param {String[]} [config.optionalRequires] List of dependencies that
7186        may optionally be loaded by this loader. This is targeted mostly at
7187        polyfills, since they should not be in the list of requires because
7188        polyfills are assumed to be available in the global scope.
7189     * @param {Function} [config.test] Test to be called when this module is
7190        added as an optional dependency of another module. If the test function
7191        returns `false`, the module will be ignored and will not be attached to
7192        this YUI instance.
7193     * @param {String} [name] The module name, required if not in the module data.
7194     * @return {Object} the module definition or null if the object passed in did not provide all required attributes.
7195     */
7196    addModule: function(o, name) {
7197        name = name || o.name;
7198
7199        if (typeof o === 'string') {
7200            o = { name: name, fullpath: o };
7201        }
7202
7203
7204        var subs, i, l, t, sup, s, smod, plugins, plug,
7205            j, langs, packName, supName, flatSup, flatLang, lang, ret,
7206            overrides, skinname, when, g, p,
7207            modInfo = this.moduleInfo[name],
7208            conditions = this.conditions, trigger;
7209
7210        //Only merge this data if the temp flag is set
7211        //from an earlier pass from a pattern or else
7212        //an override module (YUI_config) can not be used to
7213        //replace a default module.
7214        if (modInfo && modInfo.temp) {
7215            //This catches temp modules loaded via a pattern
7216            // The module will be added twice, once from the pattern and
7217            // Once from the actual add call, this ensures that properties
7218            // that were added to the module the first time around (group: gallery)
7219            // are also added the second time around too.
7220            o = Y.merge(modInfo, o);
7221        }
7222
7223        o.name = name;
7224
7225        if (!o || !o.name) {
7226            return null;
7227        }
7228
7229        if (!o.type) {
7230            //Always assume it's javascript unless the CSS pattern is matched.
7231            o.type = JS;
7232            p = o.path || o.fullpath;
7233            if (p && this.REGEX_CSS.test(p)) {
7234                o.type = CSS;
7235            }
7236        }
7237
7238        if (!o.path && !o.fullpath) {
7239            o.path = _path(name, name, o.type);
7240        }
7241        o.supersedes = o.supersedes || o.use;
7242
7243        o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true;
7244
7245        // Handle submodule logic
7246        subs = o.submodules;
7247
7248        this.moduleInfo[name] = o;
7249
7250        o.requires = o.requires || [];
7251
7252        /*
7253        Only allowing the cascade of requires information, since
7254        optional and supersedes are far more fine grained than
7255        a blanket requires is.
7256        */
7257        if (this.requires) {
7258            for (i = 0; i < this.requires.length; i++) {
7259                o.requires.push(this.requires[i]);
7260            }
7261        }
7262        if (o.group && this.groups && this.groups[o.group]) {
7263            g = this.groups[o.group];
7264            if (g.requires) {
7265                for (i = 0; i < g.requires.length; i++) {
7266                    o.requires.push(g.requires[i]);
7267                }
7268            }
7269        }
7270
7271
7272        if (!o.defaults) {
7273            o.defaults = {
7274                requires: o.requires ? [].concat(o.requires) : null,
7275                supersedes: o.supersedes ? [].concat(o.supersedes) : null,
7276                optional: o.optional ? [].concat(o.optional) : null
7277            };
7278        }
7279
7280        if (o.skinnable && o.ext && o.temp) {
7281            skinname = this._addSkin(this.skin.defaultSkin, name);
7282            o.requires.unshift(skinname);
7283        }
7284
7285        if (o.requires.length) {
7286            o.requires = this.filterRequires(o.requires) || [];
7287        }
7288
7289        if (!o.langPack && o.lang) {
7290            // Setup root package by default as a fallback
7291            // for languages that are not defined
7292            packName = this.getLangPackName(ROOT_LANG, name);
7293            smod = this.getModuleInfo(packName);
7294
7295            if (!smod) {
7296                this._addLangPack(null, o, packName);
7297            }
7298
7299            langs = yArray(o.lang);
7300
7301            for (j = 0; j < langs.length; j++) {
7302                lang = langs[j];
7303                packName = this.getLangPackName(lang, name);
7304                smod = this.getModuleInfo(packName);
7305                if (!smod) {
7306                    smod = this._addLangPack(lang, o, packName);
7307                }
7308            }
7309        }
7310
7311
7312        if (subs) {
7313            sup = o.supersedes || [];
7314            l = 0;
7315
7316            for (i in subs) {
7317                if (subs.hasOwnProperty(i)) {
7318                    s = subs[i];
7319
7320                    s.path = s.path || _path(name, i, o.type);
7321                    s.pkg = name;
7322                    s.group = o.group;
7323
7324                    if (s.supersedes) {
7325                        sup = sup.concat(s.supersedes);
7326                    }
7327
7328                    smod = this.addModule(s, i);
7329                    sup.push(i);
7330
7331                    if (smod.skinnable) {
7332                        o.skinnable = true;
7333                        overrides = this.skin.overrides;
7334                        if (overrides && overrides[i]) {
7335                            for (j = 0; j < overrides[i].length; j++) {
7336                                skinname = this._addSkin(overrides[i][j],
7337                                         i, name);
7338                                sup.push(skinname);
7339                            }
7340                        }
7341                        skinname = this._addSkin(this.skin.defaultSkin,
7342                                        i, name);
7343                        sup.push(skinname);
7344                    }
7345
7346                    // looks like we are expected to work out the metadata
7347                    // for the parent module language packs from what is
7348                    // specified in the child modules.
7349                    if (s.lang && s.lang.length) {
7350                        // Setup root package by default as a fallback
7351                        // for languages that are not defined
7352                        packName = this.getLangPackName(ROOT_LANG, name);
7353                        smod = this.getModuleInfo(packName);
7354
7355                        if (!smod) {
7356                            this._addLangPack(null, o, packName);
7357                        }
7358
7359                        langs = yArray(s.lang);
7360
7361                        for (j = 0; j < langs.length; j++) {
7362                            lang = langs[j];
7363                            packName = this.getLangPackName(lang, name);
7364                            supName = this.getLangPackName(lang, i);
7365                            smod = this.getModuleInfo(packName);
7366
7367                            if (!smod) {
7368                                smod = this._addLangPack(lang, o, packName);
7369                            }
7370
7371                            flatSup = flatSup || yArray.hash(smod.supersedes);
7372
7373                            if (!(supName in flatSup)) {
7374                                smod.supersedes.push(supName);
7375                            }
7376
7377                            o.lang = o.lang || [];
7378
7379                            flatLang = flatLang || yArray.hash(o.lang);
7380
7381                            if (!(lang in flatLang)) {
7382                                o.lang.push(lang);
7383                            }
7384
7385// Add rollup file, need to add to supersedes list too
7386
7387                            // default packages
7388                            packName = this.getLangPackName(ROOT_LANG, name);
7389                            supName = this.getLangPackName(ROOT_LANG, i);
7390
7391                            smod = this.getModuleInfo(packName);
7392
7393                            if (!smod) {
7394                                smod = this._addLangPack(lang, o, packName);
7395                            }
7396
7397                            if (!(supName in flatSup)) {
7398                                smod.supersedes.push(supName);
7399                            }
7400
7401// Add rollup file, need to add to supersedes list too
7402
7403                        }
7404                    }
7405
7406                    l++;
7407                }
7408            }
7409            //o.supersedes = YObject.keys(yArray.hash(sup));
7410            o.supersedes = yArray.dedupe(sup);
7411            if (this.allowRollup) {
7412                o.rollup = (l < 4) ? l : Math.min(l - 1, 4);
7413            }
7414        }
7415
7416        plugins = o.plugins;
7417        if (plugins) {
7418            for (i in plugins) {
7419                if (plugins.hasOwnProperty(i)) {
7420                    plug = plugins[i];
7421                    plug.pkg = name;
7422                    plug.path = plug.path || _path(name, i, o.type);
7423                    plug.requires = plug.requires || [];
7424                    plug.group = o.group;
7425                    this.addModule(plug, i);
7426                    if (o.skinnable) {
7427                        this._addSkin(this.skin.defaultSkin, i, name);
7428                    }
7429
7430                }
7431            }
7432        }
7433
7434        if (o.condition) {
7435            t = this._expandAliases(o.condition.trigger);
7436            for (i = 0; i < t.length; i++) {
7437                trigger = t[i];
7438                when = o.condition.when;
7439                conditions[trigger] = conditions[trigger] || {};
7440                conditions[trigger][name] = o.condition;
7441                // the 'when' attribute can be 'before', 'after', or 'instead'
7442                // the default is after.
7443                if (when && when !== 'after') {
7444                    if (when === 'instead') { // replace the trigger
7445                        o.supersedes = o.supersedes || [];
7446                        o.supersedes.push(trigger);
7447                    }
7448                    // before the trigger
7449                        // the trigger requires the conditional mod,
7450                        // so it should appear before the conditional
7451                        // mod if we do not intersede.
7452                } else { // after the trigger
7453                    o.after = o.after || [];
7454                    o.after.push(trigger);
7455                }
7456            }
7457        }
7458
7459        if (o.supersedes) {
7460            o.supersedes = this.filterRequires(o.supersedes);
7461        }
7462
7463        if (o.after) {
7464            o.after = this.filterRequires(o.after);
7465            o.after_map = yArray.hash(o.after);
7466        }
7467
7468        // this.dirty = true;
7469
7470        if (o.configFn) {
7471            ret = o.configFn(o);
7472            if (ret === false) {
7473                delete this.moduleInfo[name];
7474                delete GLOBAL_ENV._renderedMods[name];
7475                o = null;
7476            }
7477        }
7478        //Add to global cache
7479        if (o) {
7480            if (!GLOBAL_ENV._renderedMods) {
7481                GLOBAL_ENV._renderedMods = {};
7482            }
7483            GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o);
7484            GLOBAL_ENV._conditions = conditions;
7485        }
7486
7487        return o;
7488    },
7489
7490    /**
7491     * Add a requirement for one or more module
7492     * @method require
7493     * @param {string[] | string*} what the modules to load.
7494     */
7495    require: function(what) {
7496        var a = (typeof what === 'string') ? yArray(arguments) : what;
7497        this.dirty = true;
7498        this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a)));
7499
7500        this._explodeRollups();
7501    },
7502    /**
7503    * Grab all the items that were asked for, check to see if the Loader
7504    * meta-data contains a "use" array. If it doesm remove the asked item and replace it with
7505    * the content of the "use".
7506    * This will make asking for: "dd"
7507    * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin"
7508    * @private
7509    * @method _explodeRollups
7510    */
7511    _explodeRollups: function() {
7512        var self = this, m, m2, i, a, v, len, len2,
7513        r = self.required;
7514
7515        if (!self.allowRollup) {
7516            for (i in r) {
7517                if (r.hasOwnProperty(i)) {
7518                    m = self.getModule(i);
7519                    if (m && m.use) {
7520                        len = m.use.length;
7521                        for (a = 0; a < len; a++) {
7522                            m2 = self.getModule(m.use[a]);
7523                            if (m2 && m2.use) {
7524                                len2 = m2.use.length;
7525                                for (v = 0; v < len2; v++) {
7526                                    r[m2.use[v]] = true;
7527                                }
7528                            } else {
7529                                r[m.use[a]] = true;
7530                            }
7531                        }
7532                    }
7533                }
7534            }
7535            self.required = r;
7536        }
7537
7538    },
7539    /**
7540    * Explodes the required array to remove aliases and replace them with real modules
7541    * @method filterRequires
7542    * @param {Array} r The original requires array
7543    * @return {Array} The new array of exploded requirements
7544    */
7545    filterRequires: function(r) {
7546        if (r) {
7547            if (!Y.Lang.isArray(r)) {
7548                r = [r];
7549            }
7550            r = Y.Array(r);
7551            var c = [], i, mod, o, m;
7552
7553            for (i = 0; i < r.length; i++) {
7554                mod = this.getModule(r[i]);
7555                if (mod && mod.use) {
7556                    for (o = 0; o < mod.use.length; o++) {
7557                        //Must walk the other modules in case a module is a rollup of rollups (datatype)
7558                        m = this.getModule(mod.use[o]);
7559                        if (m && m.use && (m.name !== mod.name)) {
7560                            c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use)));
7561                        } else {
7562                            c.push(mod.use[o]);
7563                        }
7564                    }
7565                } else {
7566                    c.push(r[i]);
7567                }
7568            }
7569            r = c;
7570        }
7571        return r;
7572    },
7573
7574    /**
7575    Returns `true` if the module can be attached to the YUI instance. Runs
7576    the module's test if there is one and caches its result.
7577
7578    @method _canBeAttached
7579    @param {String} module Name of the module to check.
7580    @return {Boolean} Result of the module's test if it has one, or `true`.
7581    **/
7582    _canBeAttached: function (m) {
7583        m = this.getModule(m);
7584        if (m && m.test) {
7585            if (!m.hasOwnProperty('_testResult')) {
7586                m._testResult = m.test(Y);
7587            }
7588            return m._testResult;
7589        }
7590        // return `true` for modules not registered as Loader will know what
7591        // to do with them later on
7592        return true;
7593    },
7594
7595    /**
7596     * Returns an object containing properties for all modules required
7597     * in order to load the requested module
7598     * @method getRequires
7599     * @param {object}  mod The module definition from moduleInfo.
7600     * @return {array} the expanded requirement list.
7601     */
7602    getRequires: function(mod) {
7603
7604        if (!mod) {
7605            //console.log('returning no reqs for ' + mod.name);
7606            return NO_REQUIREMENTS;
7607        }
7608
7609        if (mod._parsed) {
7610            //console.log('returning requires for ' + mod.name, mod.requires);
7611            return mod.expanded || NO_REQUIREMENTS;
7612        }
7613
7614        //TODO add modue cache here out of scope..
7615
7616        var i, m, j, length, add, packName, lang, testresults = this.testresults,
7617            name = mod.name, cond,
7618            adddef = ON_PAGE[name] && ON_PAGE[name].details,
7619            optReqs = mod.optionalRequires,
7620            d, go, def,
7621            r, old_mod,
7622            o, skinmod, skindef, skinpar, skinname,
7623            intl = mod.lang || mod.intl,
7624            ftests = Y.Features && Y.Features.tests.load,
7625            hash, reparse;
7626
7627        // console.log(name);
7628
7629        // pattern match leaves module stub that needs to be filled out
7630        if (mod.temp && adddef) {
7631            old_mod = mod;
7632            mod = this.addModule(adddef, name);
7633            mod.group = old_mod.group;
7634            mod.pkg = old_mod.pkg;
7635            delete mod.expanded;
7636        }
7637
7638        // console.log('cache: ' + mod.langCache + ' == ' + this.lang);
7639
7640        //If a skin or a lang is different, reparse..
7641        reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin));
7642
7643        if (mod.expanded && !reparse) {
7644            return mod.expanded;
7645        }
7646
7647        // Optional dependencies are dependencies that may or may not be
7648        // available.
7649        // This feature was designed specifically to be used when transpiling
7650        // ES6 modules, in order to use polyfills and regular scripts that define
7651        // global variables without having to import them since they should be
7652        // available in the global scope.
7653        if (optReqs) {
7654            for (i = 0, length = optReqs.length; i < length; i++) {
7655                if (this._canBeAttached(optReqs[i])) {
7656                    mod.requires.push(optReqs[i]);
7657                }
7658            }
7659        }
7660
7661        d = [];
7662        hash = {};
7663        r = this.filterRequires(mod.requires);
7664        if (mod.lang) {
7665            //If a module has a lang attribute, auto add the intl requirement.
7666            d.unshift('intl');
7667            r.unshift('intl');
7668            intl = true;
7669        }
7670        o = this.filterRequires(mod.optional);
7671
7672
7673        mod._parsed = true;
7674        mod.langCache = this.lang;
7675        mod.skinCache = this.skin.defaultSkin;
7676
7677        for (i = 0; i < r.length; i++) {
7678            if (!hash[r[i]]) {
7679                d.push(r[i]);
7680                hash[r[i]] = true;
7681                m = this.getModule(r[i]);
7682                if (m) {
7683                    add = this.getRequires(m);
7684                    intl = intl || (m.expanded_map &&
7685                        (INTL in m.expanded_map));
7686                    for (j = 0; j < add.length; j++) {
7687                        d.push(add[j]);
7688                    }
7689                }
7690            }
7691        }
7692
7693        // get the requirements from superseded modules, if any
7694        r = this.filterRequires(mod.supersedes);
7695        if (r) {
7696            for (i = 0; i < r.length; i++) {
7697                if (!hash[r[i]]) {
7698                    // if this module has submodules, the requirements list is
7699                    // expanded to include the submodules.  This is so we can
7700                    // prevent dups when a submodule is already loaded and the
7701                    // parent is requested.
7702                    if (mod.submodules) {
7703                        d.push(r[i]);
7704                    }
7705
7706                    hash[r[i]] = true;
7707                    m = this.getModule(r[i]);
7708
7709                    if (m) {
7710                        add = this.getRequires(m);
7711                        intl = intl || (m.expanded_map &&
7712                            (INTL in m.expanded_map));
7713                        for (j = 0; j < add.length; j++) {
7714                            d.push(add[j]);
7715                        }
7716                    }
7717                }
7718            }
7719        }
7720
7721        if (o && this.loadOptional) {
7722            for (i = 0; i < o.length; i++) {
7723                if (!hash[o[i]]) {
7724                    d.push(o[i]);
7725                    hash[o[i]] = true;
7726                    m = this.getModuleInfo(o[i]);
7727                    if (m) {
7728                        add = this.getRequires(m);
7729                        intl = intl || (m.expanded_map &&
7730                            (INTL in m.expanded_map));
7731                        for (j = 0; j < add.length; j++) {
7732                            d.push(add[j]);
7733                        }
7734                    }
7735                }
7736            }
7737        }
7738
7739        cond = this.conditions[name];
7740
7741        if (cond) {
7742            //Set the module to not parsed since we have conditionals and this could change the dependency tree.
7743            mod._parsed = false;
7744            if (testresults && ftests) {
7745                oeach(testresults, function(result, id) {
7746                    var condmod = ftests[id].name;
7747                    if (!hash[condmod] && ftests[id].trigger === name) {
7748                        if (result && ftests[id]) {
7749                            hash[condmod] = true;
7750                            d.push(condmod);
7751                        }
7752                    }
7753                });
7754            } else {
7755                for (i in cond) {
7756                    if (cond.hasOwnProperty(i)) {
7757                        if (!hash[i]) {
7758                            def = cond[i];
7759                            //first see if they've specfied a ua check
7760                            //then see if they've got a test fn & if it returns true
7761                            //otherwise just having a condition block is enough
7762                            go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) ||
7763                                        (def.test && def.test(Y, r)));
7764
7765                            if (go) {
7766                                hash[i] = true;
7767                                d.push(i);
7768                                m = this.getModule(i);
7769                                if (m) {
7770                                    add = this.getRequires(m);
7771                                    for (j = 0; j < add.length; j++) {
7772                                        d.push(add[j]);
7773                                    }
7774
7775                                }
7776                            }
7777                        }
7778                    }
7779                }
7780            }
7781        }
7782
7783        // Create skin modules
7784        if (mod.skinnable) {
7785            skindef = this.skin.overrides;
7786            for (i in YUI.Env.aliases) {
7787                if (YUI.Env.aliases.hasOwnProperty(i)) {
7788                    if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) {
7789                        skinpar = i;
7790                    }
7791                }
7792            }
7793            if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) {
7794                skinname = name;
7795                if (skindef[skinpar]) {
7796                    skinname = skinpar;
7797                }
7798                for (i = 0; i < skindef[skinname].length; i++) {
7799                    skinmod = this._addSkin(skindef[skinname][i], name);
7800                    if (!this.isCSSLoaded(skinmod, this._boot)) {
7801                        d.push(skinmod);
7802                    }
7803                }
7804            } else {
7805                skinmod = this._addSkin(this.skin.defaultSkin, name);
7806                if (!this.isCSSLoaded(skinmod, this._boot)) {
7807                    d.push(skinmod);
7808                }
7809            }
7810        }
7811
7812        mod._parsed = false;
7813
7814        if (intl) {
7815
7816            if (mod.lang && !mod.langPack && Y.Intl) {
7817                lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang);
7818                packName = this.getLangPackName(lang, name);
7819                if (packName) {
7820                    d.unshift(packName);
7821                }
7822            }
7823            d.unshift(INTL);
7824        }
7825
7826        mod.expanded_map = yArray.hash(d);
7827
7828        mod.expanded = YObject.keys(mod.expanded_map);
7829
7830        return mod.expanded;
7831    },
7832    /**
7833    * Check to see if named css module is already loaded on the page
7834    * @method isCSSLoaded
7835    * @param {String} name The name of the css file
7836    * @param {Boolean} skip To skip the short-circuit for ignoreRegister
7837    * @return Boolean
7838    */
7839    isCSSLoaded: function(name, skip) {
7840        //TODO - Make this call a batching call with name being an array
7841        if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) {
7842            return false;
7843        }
7844        var el = YUI.Env.cssStampEl,
7845            ret = false,
7846            mod = YUI.Env._cssLoaded[name],
7847            style = el.currentStyle; //IE
7848
7849
7850        if (mod !== undefined) {
7851            return mod;
7852        }
7853
7854        //Add the classname to the element
7855        el.className = name;
7856
7857        if (!style) {
7858            style = Y.config.doc.defaultView.getComputedStyle(el, null);
7859        }
7860
7861        if (style && style.display === 'none') {
7862            ret = true;
7863        }
7864
7865
7866        el.className = ''; //Reset the classname to ''
7867
7868        YUI.Env._cssLoaded[name] = ret;
7869
7870        return ret;
7871    },
7872
7873    /**
7874     * Returns a hash of module names the supplied module satisfies.
7875     * @method getProvides
7876     * @param {string} name The name of the module.
7877     * @return {object} what this module provides.
7878     */
7879    getProvides: function(name) {
7880        var m = this.getModule(name), o, s;
7881            // supmap = this.provides;
7882
7883        if (!m) {
7884            return NOT_FOUND;
7885        }
7886
7887        if (m && !m.provides) {
7888            o = {};
7889            s = m.supersedes;
7890
7891            if (s) {
7892                yArray.each(s, function(v) {
7893                    Y.mix(o, this.getProvides(v));
7894                }, this);
7895            }
7896
7897            o[name] = true;
7898            m.provides = o;
7899
7900        }
7901
7902        return m.provides;
7903    },
7904
7905    /**
7906     * Calculates the dependency tree, the result is stored in the sorted
7907     * property.
7908     * @method calculate
7909     * @param {object} o optional options object.
7910     * @param {string} type optional argument to prune modules.
7911     */
7912    calculate: function(o, type) {
7913        if (o || type || this.dirty) {
7914
7915            if (o) {
7916                this._config(o);
7917            }
7918
7919            if (!this._init) {
7920                this._setup();
7921            }
7922
7923            this._explode();
7924
7925            if (this.allowRollup) {
7926                this._rollup();
7927            } else {
7928                this._explodeRollups();
7929            }
7930            this._reduce();
7931            this._sort();
7932        }
7933    },
7934    /**
7935    * Creates a "psuedo" package for languages provided in the lang array
7936    * @method _addLangPack
7937    * @private
7938    * @param {String} lang The language to create
7939    * @param {Object} m The module definition to create the language pack around
7940    * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US)
7941    * @return {Object} The module definition
7942    */
7943    _addLangPack: function(lang, m, packName) {
7944        var name = m.name,
7945            packPath, conf,
7946            existing = this.getModuleInfo(packName);
7947
7948        if (!existing) {
7949
7950            packPath = _path((m.pkg || name), packName, JS, true);
7951
7952            conf = {
7953                path: packPath,
7954                intl: true,
7955                langPack: true,
7956                ext: m.ext,
7957                group: m.group,
7958                supersedes: []
7959            };
7960            if (m.root) {
7961                conf.root = m.root;
7962            }
7963            if (m.base) {
7964                conf.base = m.base;
7965            }
7966
7967            if (m.configFn) {
7968                conf.configFn = m.configFn;
7969            }
7970
7971            this.addModule(conf, packName);
7972
7973            if (lang) {
7974                Y.Env.lang = Y.Env.lang || {};
7975                Y.Env.lang[lang] = Y.Env.lang[lang] || {};
7976                Y.Env.lang[lang][name] = true;
7977            }
7978        }
7979
7980        return this.getModuleInfo(packName);
7981    },
7982
7983    /**
7984     * Investigates the current YUI configuration on the page.  By default,
7985     * modules already detected will not be loaded again unless a force
7986     * option is encountered.  Called by calculate()
7987     * @method _setup
7988     * @private
7989     */
7990    _setup: function() {
7991        var info = this.moduleInfo, name, i, j, m, l,
7992            packName;
7993
7994        for (name in info) {
7995            if (info.hasOwnProperty(name)) {
7996                m = info[name];
7997                if (m) {
7998
7999                    // remove dups
8000                    //m.requires = YObject.keys(yArray.hash(m.requires));
8001                    m.requires = yArray.dedupe(m.requires);
8002
8003                    // Create lang pack modules
8004                    //if (m.lang && m.lang.length) {
8005                    if (m.lang) {
8006                        // Setup root package if the module has lang defined,
8007                        // it needs to provide a root language pack
8008                        packName = this.getLangPackName(ROOT_LANG, name);
8009                        this._addLangPack(null, m, packName);
8010                    }
8011
8012                }
8013            }
8014        }
8015
8016
8017        //l = Y.merge(this.inserted);
8018        l = {};
8019
8020        // available modules
8021        if (!this.ignoreRegistered) {
8022            Y.mix(l, GLOBAL_ENV.mods);
8023        }
8024
8025        // add the ignore list to the list of loaded packages
8026        if (this.ignore) {
8027            Y.mix(l, yArray.hash(this.ignore));
8028        }
8029
8030        // expand the list to include superseded modules
8031        for (j in l) {
8032            if (l.hasOwnProperty(j)) {
8033                Y.mix(l, this.getProvides(j));
8034            }
8035        }
8036
8037        // remove modules on the force list from the loaded list
8038        if (this.force) {
8039            for (i = 0; i < this.force.length; i++) {
8040                if (this.force[i] in l) {
8041                    delete l[this.force[i]];
8042                }
8043            }
8044        }
8045
8046        Y.mix(this.loaded, l);
8047
8048        this._init = true;
8049    },
8050
8051    /**
8052     * Builds a module name for a language pack
8053     * @method getLangPackName
8054     * @param {string} lang the language code.
8055     * @param {string} mname the module to build it for.
8056     * @return {string} the language pack module name.
8057     */
8058    getLangPackName: function(lang, mname) {
8059        return ('lang/' + mname + ((lang) ? '_' + lang : ''));
8060    },
8061    /**
8062     * Inspects the required modules list looking for additional
8063     * dependencies.  Expands the required list to include all
8064     * required modules.  Called by calculate()
8065     * @method _explode
8066     * @private
8067     */
8068    _explode: function() {
8069        //TODO Move done out of scope
8070        var r = this.required, m, reqs, done = {},
8071            self = this, name, expound;
8072
8073        // the setup phase is over, all modules have been created
8074        self.dirty = false;
8075
8076        self._explodeRollups();
8077        r = self.required;
8078
8079        for (name in r) {
8080            if (r.hasOwnProperty(name)) {
8081                if (!done[name]) {
8082                    done[name] = true;
8083                    m = self.getModule(name);
8084                    if (m) {
8085                        expound = m.expound;
8086
8087                        if (expound) {
8088                            r[expound] = self.getModule(expound);
8089                            reqs = self.getRequires(r[expound]);
8090                            Y.mix(r, yArray.hash(reqs));
8091                        }
8092
8093                        reqs = self.getRequires(m);
8094                        Y.mix(r, yArray.hash(reqs));
8095                    }
8096                }
8097            }
8098        }
8099
8100    },
8101    /**
8102    * The default method used to test a module against a pattern
8103    * @method _patternTest
8104    * @private
8105    * @param {String} mname The module being tested
8106    * @param {String} pname The pattern to match
8107    */
8108    _patternTest: function(mname, pname) {
8109        return (mname.indexOf(pname) > -1);
8110    },
8111    /**
8112    * Get's the loader meta data for the requested module
8113    * @method getModule
8114    * @param {String} mname The module name to get
8115    * @return {Object} The module metadata
8116    */
8117    getModule: function(mname) {
8118        //TODO: Remove name check - it's a quick hack to fix pattern WIP
8119        if (!mname) {
8120            return null;
8121        }
8122
8123        var p, found, pname,
8124            m = this.getModuleInfo(mname),
8125            patterns = this.patterns;
8126
8127        // check the patterns library to see if we should automatically add
8128        // the module with defaults
8129        if (!m || (m && m.ext)) {
8130            for (pname in patterns) {
8131                if (patterns.hasOwnProperty(pname)) {
8132                    p = patterns[pname];
8133
8134                    //There is no test method, create a default one that tests
8135                    // the pattern against the mod name
8136                    if (!p.test) {
8137                        p.test = this._patternTest;
8138                    }
8139
8140                    if (p.test(mname, pname)) {
8141                        // use the metadata supplied for the pattern
8142                        // as the module definition.
8143                        found = p;
8144                        break;
8145                    }
8146                }
8147            }
8148        }
8149
8150        if (!m) {
8151            if (found) {
8152                if (p.action) {
8153                    p.action.call(this, mname, pname);
8154                } else {
8155                    // ext true or false?
8156                    m = this.addModule(Y.merge(found, {
8157                        test: void 0,
8158                        temp: true
8159                    }), mname);
8160                    if (m && found.configFn) {
8161                        m.configFn = found.configFn;
8162                    }
8163                }
8164            }
8165        } else {
8166            if (found && m && found.configFn && !m.configFn) {
8167                m.configFn = found.configFn;
8168                m.configFn(m);
8169            }
8170        }
8171
8172        return m;
8173    },
8174
8175    // impl in rollup submodule
8176    _rollup: function() { },
8177
8178    /**
8179     * Remove superceded modules and loaded modules.  Called by
8180     * calculate() after we have the mega list of all dependencies
8181     * @method _reduce
8182     * @return {object} the reduced dependency hash.
8183     * @private
8184     */
8185    _reduce: function(r) {
8186
8187        r = r || this.required;
8188
8189        var i, j, s, m, type = this.loadType,
8190        ignore = this.ignore ? yArray.hash(this.ignore) : false;
8191
8192        for (i in r) {
8193            if (r.hasOwnProperty(i)) {
8194                m = this.getModule(i);
8195                // remove if already loaded
8196                if (((this.loaded[i] || ON_PAGE[i]) &&
8197                        !this.forceMap[i] && !this.ignoreRegistered) ||
8198                        (type && m && m.type !== type)) {
8199                    delete r[i];
8200                }
8201                if (ignore && ignore[i]) {
8202                    delete r[i];
8203                }
8204                // remove anything this module supersedes
8205                s = m && m.supersedes;
8206                if (s) {
8207                    for (j = 0; j < s.length; j++) {
8208                        if (s[j] in r) {
8209                            delete r[s[j]];
8210                        }
8211                    }
8212                }
8213            }
8214        }
8215
8216        return r;
8217    },
8218    /**
8219    * Handles the queue when a module has been loaded for all cases
8220    * @method _finish
8221    * @private
8222    * @param {String} msg The message from Loader
8223    * @param {Boolean} success A boolean denoting success or failure
8224    */
8225    _finish: function(msg, success) {
8226
8227        _queue.running = false;
8228
8229        var onEnd = this.onEnd;
8230        if (onEnd) {
8231            onEnd.call(this.context, {
8232                msg: msg,
8233                data: this.data,
8234                success: success
8235            });
8236        }
8237        this._continue();
8238    },
8239    /**
8240    * The default Loader onSuccess handler, calls this.onSuccess with a payload
8241    * @method _onSuccess
8242    * @private
8243    */
8244    _onSuccess: function() {
8245        var self = this, skipped = Y.merge(self.skipped), fn,
8246            failed = [], rreg = self.requireRegistration,
8247            success, msg, i, mod;
8248
8249        for (i in skipped) {
8250            if (skipped.hasOwnProperty(i)) {
8251                delete self.inserted[i];
8252            }
8253        }
8254
8255        self.skipped = {};
8256
8257        for (i in self.inserted) {
8258            if (self.inserted.hasOwnProperty(i)) {
8259                mod = self.getModule(i);
8260                if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) {
8261                    failed.push(i);
8262                } else {
8263                    Y.mix(self.loaded, self.getProvides(i));
8264                }
8265            }
8266        }
8267
8268        fn = self.onSuccess;
8269        msg = (failed.length) ? 'notregistered' : 'success';
8270        success = !(failed.length);
8271        if (fn) {
8272            fn.call(self.context, {
8273                msg: msg,
8274                data: self.data,
8275                success: success,
8276                failed: failed,
8277                skipped: skipped
8278            });
8279        }
8280        self._finish(msg, success);
8281    },
8282    /**
8283    * The default Loader onProgress handler, calls this.onProgress with a payload
8284    * @method _onProgress
8285    * @private
8286    */
8287    _onProgress: function(e) {
8288        var self = this, i;
8289        //set the internal cache to what just came in.
8290        if (e.data && e.data.length) {
8291            for (i = 0; i < e.data.length; i++) {
8292                e.data[i] = self.getModule(e.data[i].name);
8293            }
8294        }
8295        if (self.onProgress) {
8296            self.onProgress.call(self.context, {
8297                name: e.url,
8298                data: e.data
8299            });
8300        }
8301    },
8302    /**
8303    * The default Loader onFailure handler, calls this.onFailure with a payload
8304    * @method _onFailure
8305    * @private
8306    */
8307    _onFailure: function(o) {
8308        var f = this.onFailure, msg = [], i = 0, len = o.errors.length;
8309
8310        for (i; i < len; i++) {
8311            msg.push(o.errors[i].error);
8312        }
8313
8314        msg = msg.join(',');
8315
8316
8317        if (f) {
8318            f.call(this.context, {
8319                msg: msg,
8320                data: this.data,
8321                success: false
8322            });
8323        }
8324
8325        this._finish(msg, false);
8326
8327    },
8328
8329    /**
8330    * The default Loader onTimeout handler, calls this.onTimeout with a payload
8331    * @method _onTimeout
8332    * @param {Get.Transaction} transaction The Transaction object from `Y.Get`
8333    * @private
8334    */
8335    _onTimeout: function(transaction) {
8336        var f = this.onTimeout;
8337        if (f) {
8338            f.call(this.context, {
8339                msg: 'timeout',
8340                data: this.data,
8341                success: false,
8342                transaction: transaction
8343            });
8344        }
8345    },
8346
8347    /**
8348     * Sorts the dependency tree.  The last step of calculate()
8349     * @method _sort
8350     * @private
8351     */
8352    _sort: function() {
8353        var name,
8354
8355            // Object containing module names.
8356            required = this.required,
8357
8358            // Keep track of whether we've visited a module.
8359            visited = {};
8360
8361        // Will contain modules names, in the correct order,
8362        // according to dependencies.
8363        this.sorted = [];
8364
8365        for (name in required) {
8366            if (!visited[name] && required.hasOwnProperty(name)) {
8367                this._visit(name, visited);
8368            }
8369        }
8370    },
8371
8372    /**
8373     * Recursively visits the dependencies of the module name
8374     * passed in, and appends each module name to the `sorted` property.
8375     * @param {String} name The name of a module.
8376     * @param {Object} visited Keeps track of whether a module was visited.
8377     * @method _visit
8378     * @private
8379     */
8380    _visit: function (name, visited) {
8381        var required, condition, moduleInfo, dependency, dependencies,
8382            trigger, isAfter, i, l;
8383
8384        visited[name] = true;
8385        required = this.required;
8386        moduleInfo = this.moduleInfo[name];
8387        condition = this.conditions[name] || {};
8388
8389        if (moduleInfo) {
8390            // Recurse on each dependency of this module,
8391            // figuring out its dependencies, and so on.
8392            dependencies = moduleInfo.expanded || moduleInfo.requires;
8393
8394            for (i = 0, l = dependencies.length; i < l; ++i) {
8395                dependency = dependencies[i];
8396                trigger = condition[dependency];
8397
8398                // We cannot process this dependency yet if it must
8399                // appear after our current module.
8400                isAfter = trigger && (!trigger.when || trigger.when === "after");
8401
8402                // Is this module name in the required list of modules,
8403                // and have we not already visited it?
8404                if (required[dependency] && !visited[dependency] && !isAfter) {
8405                    this._visit(dependency, visited);
8406                }
8407            }
8408        }
8409
8410        this.sorted.push(name);
8411    },
8412
8413    /**
8414    * Handles the actual insertion of script/link tags
8415    * @method _insert
8416    * @private
8417    * @param {Object} source The YUI instance the request came from
8418    * @param {Object} o The metadata to include
8419    * @param {String} type JS or CSS
8420    * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta
8421    */
8422    _insert: function(source, o, type, skipcalc) {
8423
8424
8425        // restore the state at the time of the request
8426        if (source) {
8427            this._config(source);
8428        }
8429
8430        // build the dependency list
8431        // don't include type so we can process CSS and script in
8432        // one pass when the type is not specified.
8433
8434        var modules = this.resolve(!skipcalc),
8435            self = this, comp = 0, actions = 0,
8436            mods = {}, deps, complete;
8437
8438        self._refetch = [];
8439
8440        if (type) {
8441            //Filter out the opposite type and reset the array so the checks later work
8442            modules[((type === JS) ? CSS : JS)] = [];
8443        }
8444        if (!self.fetchCSS) {
8445            modules.css = [];
8446        }
8447        if (modules.js.length) {
8448            comp++;
8449        }
8450        if (modules.css.length) {
8451            comp++;
8452        }
8453
8454        //console.log('Resolved Modules: ', modules);
8455
8456        complete = function(d) {
8457            actions++;
8458            var errs = {}, i = 0, o = 0, u = '', fn,
8459                modName, resMods;
8460
8461            if (d && d.errors) {
8462                for (i = 0; i < d.errors.length; i++) {
8463                    if (d.errors[i].request) {
8464                        u = d.errors[i].request.url;
8465                    } else {
8466                        u = d.errors[i];
8467                    }
8468                    errs[u] = u;
8469                }
8470            }
8471
8472            if (d && d.data && d.data.length && (d.type === 'success')) {
8473                for (i = 0; i < d.data.length; i++) {
8474                    self.inserted[d.data[i].name] = true;
8475                    //If the external module has a skin or a lang, reprocess it
8476                    if (d.data[i].lang || d.data[i].skinnable) {
8477                        delete self.inserted[d.data[i].name];
8478                        self._refetch.push(d.data[i].name);
8479                    }
8480                }
8481            }
8482
8483            if (actions === comp) {
8484                self._loading = null;
8485                if (self._refetch.length) {
8486                    //Get the deps for the new meta-data and reprocess
8487                    for (i = 0; i < self._refetch.length; i++) {
8488                        deps = self.getRequires(self.getModule(self._refetch[i]));
8489                        for (o = 0; o < deps.length; o++) {
8490                            if (!self.inserted[deps[o]]) {
8491                                //We wouldn't be to this point without the module being here
8492                                mods[deps[o]] = deps[o];
8493                            }
8494                        }
8495                    }
8496                    mods = Y.Object.keys(mods);
8497                    if (mods.length) {
8498                        self.require(mods);
8499                        resMods = self.resolve(true);
8500                        if (resMods.cssMods.length) {
8501                            for (i=0; i <  resMods.cssMods.length; i++) {
8502                                modName = resMods.cssMods[i].name;
8503                                delete YUI.Env._cssLoaded[modName];
8504                                if (self.isCSSLoaded(modName)) {
8505                                    self.inserted[modName] = true;
8506                                    delete self.required[modName];
8507                                }
8508                            }
8509                            self.sorted = [];
8510                            self._sort();
8511                        }
8512                        d = null; //bail
8513                        self._insert(); //insert the new deps
8514                    }
8515                }
8516                if (d && d.fn) {
8517                    fn = d.fn;
8518                    delete d.fn;
8519                    fn.call(self, d);
8520                }
8521            }
8522        };
8523
8524        this._loading = true;
8525
8526        if (!modules.js.length && !modules.css.length) {
8527            actions = -1;
8528            complete({
8529                fn: self._onSuccess
8530            });
8531            return;
8532        }
8533
8534
8535        if (modules.css.length) { //Load CSS first
8536            Y.Get.css(modules.css, {
8537                data: modules.cssMods,
8538                attributes: self.cssAttributes,
8539                insertBefore: self.insertBefore,
8540                charset: self.charset,
8541                timeout: self.timeout,
8542                context: self,
8543                onProgress: function(e) {
8544                    self._onProgress.call(self, e);
8545                },
8546                onTimeout: function(d) {
8547                    self._onTimeout.call(self, d);
8548                },
8549                onSuccess: function(d) {
8550                    d.type = 'success';
8551                    d.fn = self._onSuccess;
8552                    complete.call(self, d);
8553                },
8554                onFailure: function(d) {
8555                    d.type = 'failure';
8556                    d.fn = self._onFailure;
8557                    complete.call(self, d);
8558                }
8559            });
8560        }
8561
8562        if (modules.js.length) {
8563            Y.Get.js(modules.js, {
8564                data: modules.jsMods,
8565                insertBefore: self.insertBefore,
8566                attributes: self.jsAttributes,
8567                charset: self.charset,
8568                timeout: self.timeout,
8569                autopurge: false,
8570                context: self,
8571                async: self.async,
8572                onProgress: function(e) {
8573                    self._onProgress.call(self, e);
8574                },
8575                onTimeout: function(d) {
8576                    self._onTimeout.call(self, d);
8577                },
8578                onSuccess: function(d) {
8579                    d.type = 'success';
8580                    d.fn = self._onSuccess;
8581                    complete.call(self, d);
8582                },
8583                onFailure: function(d) {
8584                    d.type = 'failure';
8585                    d.fn = self._onFailure;
8586                    complete.call(self, d);
8587                }
8588            });
8589        }
8590    },
8591    /**
8592    * Once a loader operation is completely finished, process any additional queued items.
8593    * @method _continue
8594    * @private
8595    */
8596    _continue: function() {
8597        if (!(_queue.running) && _queue.size() > 0) {
8598            _queue.running = true;
8599            _queue.next()();
8600        }
8601    },
8602
8603    /**
8604     * inserts the requested modules and their dependencies.
8605     * <code>type</code> can be "js" or "css".  Both script and
8606     * css are inserted if type is not provided.
8607     * @method insert
8608     * @param {object} o optional options object.
8609     * @param {string} type the type of dependency to insert.
8610     */
8611    insert: function(o, type, skipsort) {
8612        var self = this, copy = Y.merge(this);
8613        delete copy.require;
8614        delete copy.dirty;
8615        _queue.add(function() {
8616            self._insert(copy, o, type, skipsort);
8617        });
8618        this._continue();
8619    },
8620
8621    /**
8622     * Executed every time a module is loaded, and if we are in a load
8623     * cycle, we attempt to load the next script.  Public so that it
8624     * is possible to call this if using a method other than
8625     * Y.register to determine when scripts are fully loaded
8626     * @method loadNext
8627     * @deprecated
8628     * @param {string} mname optional the name of the module that has
8629     * been loaded (which is usually why it is time to load the next
8630     * one).
8631     */
8632    loadNext: function() {
8633        return;
8634    },
8635
8636    /**
8637     * Apply filter defined for this instance to a url/path
8638     * @method _filter
8639     * @param {string} u the string to filter.
8640     * @param {string} name the name of the module, if we are processing
8641     * a single module as opposed to a combined url.
8642     * @return {string} the filtered string.
8643     * @private
8644     */
8645    _filter: function(u, name, group) {
8646        var f = this.filter,
8647            hasFilter = name && (name in this.filters),
8648            modFilter = hasFilter && this.filters[name],
8649            groupName = group || (this.getModuleInfo(name) || {}).group || null;
8650
8651        if (groupName && this.groups[groupName] && this.groups[groupName].filter) {
8652            modFilter = this.groups[groupName].filter;
8653            hasFilter = true;
8654        }
8655
8656        if (u) {
8657            if (hasFilter) {
8658                f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter;
8659            }
8660            if (f) {
8661                u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr);
8662            }
8663        }
8664        return u;
8665    },
8666
8667    /**
8668     * Generates the full url for a module
8669     * @method _url
8670     * @param {string} path the path fragment.
8671     * @param {String} name The name of the module
8672     * @param {String} [base] The base url to use. Defaults to self.base
8673     * @return {string} the full url.
8674     * @private
8675     */
8676    _url: function(path, name, base) {
8677        return this._filter((base || this.base || '') + path, name);
8678    },
8679    /**
8680    * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules.
8681    * @method resolve
8682    * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else
8683    * @param {Array} [sorted=loader.sorted] An override for the loader.sorted array
8684    * @return {Object} Object hash (js and css) of two arrays of file lists
8685    * @example This method can be used as an off-line dep calculator
8686    *
8687    *        var Y = YUI();
8688    *        var loader = new Y.Loader({
8689    *            filter: 'debug',
8690    *            base: '../../',
8691    *            root: 'build/',
8692    *            combine: true,
8693    *            require: ['node', 'dd', 'console']
8694    *        });
8695    *        var out = loader.resolve(true);
8696    *
8697    */
8698    resolve: function(calc, sorted) {
8699        var self     = this,
8700            resolved = { js: [], jsMods: [], css: [], cssMods: [] },
8701            addSingle,
8702            usePathogen = Y.config.comboLoader && Y.config.customComboBase;
8703
8704        if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) {
8705            self._resetModules();
8706        }
8707
8708        if (calc) {
8709            self.calculate();
8710        }
8711        sorted = sorted || self.sorted;
8712
8713        addSingle = function(mod) {
8714            if (mod) {
8715                var group = (mod.group && self.groups[mod.group]) || NOT_FOUND,
8716                    url;
8717
8718                //Always assume it's async
8719                if (group.async === false) {
8720                    mod.async = group.async;
8721                }
8722
8723                url = (mod.fullpath) ? self._filter(mod.fullpath, mod.name) :
8724                      self._url(mod.path, mod.name, group.base || mod.base);
8725
8726                if (mod.attributes || mod.async === false) {
8727                    url = {
8728                        url: url,
8729                        async: mod.async
8730                    };
8731                    if (mod.attributes) {
8732                        url.attributes = mod.attributes;
8733                    }
8734                }
8735                resolved[mod.type].push(url);
8736                resolved[mod.type + 'Mods'].push(mod);
8737            } else {
8738            }
8739
8740        };
8741
8742        /*jslint vars: true */
8743        var inserted     = (self.ignoreRegistered) ? {}
8743 : self.inserted,
8744            comboSources,
8745            maxURLLength,
8746            comboMeta,
8747            comboBase,
8748            comboSep,
8749            group,
8750            mod,
8751            len,
8752            i,
8753            hasComboModule = false;
8754
8755        /*jslint vars: false */
8756
8757        for (i = 0, len = sorted.length; i < len; i++) {
8758            mod = self.getModule(sorted[i]);
8759            if (!mod || inserted[mod.name]) {
8760                continue;
8761            }
8762
8763            group = self.groups[mod.group];
8764
8765            comboBase = self.comboBase;
8766
8767            if (group) {
8768                if (!group.combine || mod.fullpath) {
8769                    //This is not a combo module, skip it and load it singly later.
8770                    addSingle(mod);
8771                    continue;
8772                }
8773                mod.combine = true;
8774
8775                if (typeof group.root === 'string') {
8776                    mod.root = group.root;
8777                }
8778
8779                comboBase    = group.comboBase || comboBase;
8780                comboSep     = group.comboSep;
8781                maxURLLength = group.maxURLLength;
8782            } else {
8783                if (!self.combine) {
8784                    //This is not a combo module, skip it and load it singly later.
8785                    addSingle(mod);
8786                    continue;
8787                }
8788            }
8789
8790            if (!mod.combine && mod.ext) {
8791                addSingle(mod);
8792                continue;
8793            }
8794            hasComboModule = true;
8795            comboSources = comboSources || {};
8796            comboSources[comboBase] = comboSources[comboBase] ||
8797                { js: [], jsMods: [], css: [], cssMods: [] };
8798
8799            comboMeta               = comboSources[comboBase];
8800            comboMeta.group         = mod.group;
8801            comboMeta.comboSep      = comboSep || self.comboSep;
8802            comboMeta.maxURLLength  = maxURLLength || self.maxURLLength;
8803
8804            comboMeta[mod.type + 'Mods'].push(mod);
8805            if (mod.type === JS || mod.type === CSS) {
8806                resolved[mod.type + 'Mods'].push(mod);
8807            }
8808        }
8809        //only encode if we have something to encode
8810        if (hasComboModule) {
8811            if (usePathogen) {
8812                resolved = this._pathogenEncodeComboSources(resolved);
8813            } else {
8814                resolved = this._encodeComboSources(resolved, comboSources);
8815            }
8816        }
8817        return resolved;
8818    },
8819
8820    /**
8821     * Encodes combo sources and appends them to an object hash of arrays from `loader.resolve`.
8822     *
8823     * @method _encodeComboSources
8824     * @param {Object} resolved The object hash of arrays in which to attach the encoded combo sources.
8825     * @param {Object} comboSources An object containing relevant data about modules.
8826     * @return Object
8827     * @private
8828     */
8829    _encodeComboSources: function(resolved, comboSources) {
8830        var fragSubset,
8831            modules,
8832            tmpBase,
8833            baseLen,
8834            frags,
8835            frag,
8836            type,
8837            mod,
8838            maxURLLength,
8839            comboBase,
8840            comboMeta,
8841            comboSep,
8842            i,
8843            len,
8844            self = this;
8845
8846        for (comboBase in comboSources) {
8847            if (comboSources.hasOwnProperty(comboBase)) {
8848                comboMeta    = comboSources[comboBase];
8849                comboSep     = comboMeta.comboSep;
8850                maxURLLength = comboMeta.maxURLLength;
8851                for (type in comboMeta) {
8852                    if (type === JS || type === CSS) {
8853                        modules = comboMeta[type + 'Mods'];
8854                        frags = [];
8855                        for (i = 0, len = modules.length; i < len; i += 1) {
8856                            mod = modules[i];
8857                            frag = ((typeof mod.root === 'string') ? mod.root : self.root) + (mod.path || mod.fullpath);
8858                            frags.push(
8859                                self._filter(frag, mod.name)
8860                            );
8861                        }
8862                        tmpBase = comboBase + frags.join(comboSep);
8863                        baseLen = tmpBase.length;
8864                        if (maxURLLength <= comboBase.length) {
8865                            maxURLLength = MAX_URL_LENGTH;
8866                        }
8867
8868                        if (frags.length) {
8869                            if (baseLen > maxURLLength) {
8870                                fragSubset = [];
8871                                for (i = 0, len = frags.length; i < len; i++) {
8872                                    fragSubset.push(frags[i]);
8873                                    tmpBase = comboBase + fragSubset.join(comboSep);
8874
8875                                    if (tmpBase.length > maxURLLength) {
8876                                        frag = fragSubset.pop();
8877                                        tmpBase = comboBase + fragSubset.join(comboSep);
8878                                        resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8879                                        fragSubset = [];
8880                                        if (frag) {
8881                                            fragSubset.push(frag);
8882                                        }
8883                                    }
8884                                }
8885                                if (fragSubset.length) {
8886                                    tmpBase = comboBase + fragSubset.join(comboSep);
8887                                    resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8888                                }
8889                            } else {
8890                                resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8891                            }
8892                        }
8893                    }
8894                }
8895            }
8896        }
8897        return resolved;
8898    },
8899
8900    /**
8901    Shortcut to calculate, resolve and load all modules.
8902
8903        var loader = new Y.Loader({
8904            ignoreRegistered: true,
8905            modules: {
8906                mod: {
8907                    path: 'mod.js'
8908                }
8909            },
8910            requires: [ 'mod' ]
8911        });
8912        loader.load(function() {
8913            console.log('All modules have loaded..');
8914        });
8915
8916
8917    @method load
8918    @param {Function} cb Executed after all load operations are complete
8919    */
8920    load: function(cb) {
8921        if (!cb) {
8922            return;
8923        }
8924        var self = this,
8925            out = self.resolve(true);
8926
8927        self.data = out;
8928
8929        self.onEnd = function() {
8930            cb.apply(self.context || self, arguments);
8931        };
8932
8933        self.insert();
8934    }
8935};
8936
8937
8938}, 'patched-v3.18.1', {"requires": ["get", "features"]});
8939YUI.add('loader-rollup', function (Y, NAME) {
8940
8941/**
8942 * Optional automatic rollup logic for reducing http connections
8943 * when not using a combo service.
8944 * @module loader
8945 * @submodule rollup
8946 */
8947
8948/**
8949 * Look for rollup packages to determine if all of the modules a
8950 * rollup supersedes are required.  If so, include the rollup to
8951 * help reduce the total number of connections required.  Called
8952 * by calculate().  This is an optional feature, and requires the
8953 * appropriate submodule to function.
8954 * @method _rollup
8955 * @for Loader
8956 * @private
8957 */
8958Y.Loader.prototype._rollup = function() {
8959    var i, j, m, s, r = this.required, roll,
8960        info = this.moduleInfo, rolled, c, smod;
8961
8962    // find and cache rollup modules
8963    if (this.dirty || !this.rollups) {
8964        this.rollups = {};
8965        for (i in info) {
8966            if (info.hasOwnProperty(i)) {
8967                m = this.getModule(i);
8968                // if (m && m.rollup && m.supersedes) {
8969                if (m && m.rollup) {
8970                    this.rollups[i] = m;
8971                }
8972            }
8973        }
8974    }
8975
8976    // make as many passes as needed to pick up rollup rollups
8977    for (;;) {
8978        rolled = false;
8979
8980        // go through the rollup candidates
8981        for (i in this.rollups) {
8982            if (this.rollups.hasOwnProperty(i)) {
8983                // there can be only one, unless forced
8984                if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) {
8985                    m = this.getModule(i);
8986                    s = m.supersedes || [];
8987                    roll = false;
8988
8989                    // @TODO remove continue
8990                    if (!m.rollup) {
8991                        continue;
8992                    }
8993
8994                    c = 0;
8995
8996                    // check the threshold
8997                    for (j = 0; j < s.length; j++) {
8998                        smod = info[s[j]];
8999
9000                        // if the superseded module is loaded, we can't
9001                        // load the rollup unless it has been forced.
9002                        if (this.loaded[s[j]] && !this.forceMap[s[j]]) {
9003                            roll = false;
9004                            break;
9005                        // increment the counter if this module is required.
9006                        // if we are beyond the rollup threshold, we will
9007                        // use the rollup module
9008                        } else if (r[s[j]] && m.type === smod.type) {
9009                            c++;
9010                            roll = (c >= m.rollup);
9011                            if (roll) {
9012                                break;
9013                            }
9014                        }
9015                    }
9016
9017                    if (roll) {
9018                        // add the rollup
9019                        r[i] = true;
9020                        rolled = true;
9021
9022                        // expand the rollup's dependencies
9023                        this.getRequires(m);
9024                    }
9025                }
9026            }
9027        }
9028
9029        // if we made it here w/o rolling up something, we are done
9030        if (!rolled) {
9031            break;
9032        }
9033    }
9034};
9035
9036
9037}, 'patched-v3.18.1', {"requires": ["loader-base"]});
9038YUI.add('loader-yui3', function (Y, NAME) {
9039
9040/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
9041
9042/*jshint maxlen:900, eqeqeq: false */
9043
9044/**
9045 * YUI 3 module metadata
9046 * @module loader
9047 * @submodule loader-yui3
9048 */
9049YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
9050Y.mix(YUI.Env[Y.version].modules, {
9051    "align-plugin": {
9052        "requires": [
9053            "node-screen",
9054            "node-pluginhost"
9055        ]
9056    },
9057    "anim": {
9058        "use": [
9059            "anim-base",
9060            "anim-color",
9061            "anim-curve",
9062            "anim-easing",
9063            "anim-node-plugin",
9064            "anim-scroll",
9065            "anim-xy"
9066        ]
9067    },
9068    "anim-base": {
9069        "requires": [
9070            "base-base",
9071            "node-style",
9072            "color-base"
9073        ]
9074    },
9075    "anim-color": {
9076        "requires": [
9077            "anim-base"
9078        ]
9079    },
9080    "anim-curve": {
9081        "requires": [
9082            "anim-xy"
9083        ]
9084    },
9085    "anim-easing": {
9086        "requires": [
9087            "anim-base"
9088        ]
9089    },
9090    "anim-node-plugin": {
9091        "requires": [
9092            "node-pluginhost",
9093            "anim-base"
9094        ]
9095    },
9096    "anim-scroll": {
9097        "requires": [
9098            "anim-base"
9099        ]
9100    },
9101    "anim-shape": {
9102        "requires": [
9103            "anim-base",
9104            "anim-easing",
9105            "anim-color",
9106            "matrix"
9107        ]
9108    },
9109    "anim-shape-transform": {
9110        "use": [
9111            "anim-shape"
9112        ]
9113    },
9114    "anim-xy": {
9115        "requires": [
9116            "anim-base",
9117            "node-screen"
9118        ]
9119    },
9120    "app": {
9121        "use": [
9122            "app-base",
9123            "app-content",
9124            "app-transitions",
9125            "lazy-model-list",
9126            "model",
9127            "model-list",
9128            "model-sync-rest",
9129            "model-sync-local",
9130            "router",
9131            "view",
9132            "view-node-map"
9133        ]
9134    },
9135    "app-base": {
9136        "requires": [
9137            "classnamemanager",
9138            "pjax-base",
9139            "router",
9140            "view"
9141        ]
9142    },
9143    "app-content": {
9144        "requires": [
9145            "app-base",
9146            "pjax-content"
9147        ]
9148    },
9149    "app-transitions": {
9150        "requires": [
9151            "app-base"
9152        ]
9153    },
9154    "app-transitions-css": {
9155        "type": "css"
9156    },
9157    "app-transitions-native": {
9158        "condition": {
9159            "name": "app-transitions-native",
9160            "test": function (Y) {
9161    var doc  = Y.config.doc,
9162        node = doc ? doc.documentElement : null;
9163
9164    if (node && node.style) {
9165        return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
9166    }
9167
9168    return false;
9169},
9170            "trigger": "app-transitions"
9171        },
9172        "requires": [
9173            "app-transitions",
9174            "app-transitions-css",
9175            "parallel",
9176            "transition"
9177        ]
9178    },
9179    "array-extras": {
9180        "requires": [
9181            "yui-base"
9182        ]
9183    },
9184    "array-invoke": {
9185        "requires": [
9186            "yui-base"
9187        ]
9188    },
9189    "arraylist": {
9190        "requires": [
9191            "yui-base"
9192        ]
9193    },
9194    "arraylist-add": {
9195        "requires": [
9196            "arraylist"
9197        ]
9198    },
9199    "arraylist-filter": {
9200        "requires": [
9201            "arraylist"
9202        ]
9203    },
9204    "arraysort": {
9205        "requires": [
9206            "yui-base"
9207        ]
9208    },
9209    "async-queue": {
9210        "requires": [
9211            "event-custom"
9212        ]
9213    },
9214    "attribute": {
9215        "use": [
9216            "attribute-base",
9217            "attribute-complex"
9218        ]
9219    },
9220    "attribute-base": {
9221        "requires": [
9222            "attribute-core",
9223            "attribute-observable",
9224            "attribute-extras"
9225        ]
9226    },
9227    "attribute-complex": {
9228        "requires": [
9229            "attribute-base"
9230        ]
9231    },
9232    "attribute-core": {
9233        "requires": [
9234            "oop"
9235        ]
9236    },
9237    "attribute-events": {
9238        "use": [
9239            "attribute-observable"
9240        ]
9241    },
9242    "attribute-extras": {
9243        "requires": [
9244            "oop"
9245        ]
9246    },
9247    "attribute-observable": {
9248        "requires": [
9249            "event-custom"
9250        ]
9251    },
9252    "autocomplete": {
9253        "use": [
9254            "autocomplete-base",
9255            "autocomplete-sources",
9256            "autocomplete-list",
9257            "autocomplete-plugin"
9258        ]
9259    },
9260    "autocomplete-base": {
9261        "optional": [
9262            "autocomplete-sources"
9263        ],
9264        "requires": [
9265            "array-extras",
9266            "base-build",
9267            "escape",
9268            "event-valuechange",
9269            "node-base"
9270        ]
9271    },
9272    "autocomplete-filters": {
9273        "requires": [
9274            "array-extras",
9275            "text-wordbreak"
9276        ]
9277    },
9278    "autocomplete-filters-accentfold": {
9279        "requires": [
9280            "array-extras",
9281            "text-accentfold",
9282            "text-wordbreak"
9283        ]
9284    },
9285    "autocomplete-highlighters": {
9286        "requires": [
9287            "array-extras",
9288            "highlight-base"
9289        ]
9290    },
9291    "autocomplete-highlighters-accentfold": {
9292        "requires": [
9293            "array-extras",
9294            "highlight-accentfold"
9295        ]
9296    },
9297    "autocomplete-list": {
9298        "after": [
9299            "autocomplete-sources"
9300        ],
9301        "lang": [
9302            "en",
9303            "es",
9304            "hu",
9305            "it"
9306        ],
9307        "requires": [
9308            "autocomplete-base",
9309            "event-resize",
9310            "node-screen",
9311            "selector-css3",
9312            "shim-plugin",
9313            "widget",
9314            "widget-position",
9315            "widget-position-align"
9316        ],
9317        "skinnable": true
9318    },
9319    "autocomplete-list-keys": {
9320        "condition": {
9321            "name": "autocomplete-list-keys",
9322            "test": function (Y) {
9323    // Only add keyboard support to autocomplete-list if this doesn't appear to
9324    // be an iOS or Android-based mobile device.
9325    //
9326    // There's currently no feasible way to actually detect whether a device has
9327    // a hardware keyboard, so this sniff will have to do. It can easily be
9328    // overridden by manually loading the autocomplete-list-keys module.
9329    //
9330    // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
9331    // doesn't fire the keyboard events used by AutoCompleteList, so there's
9332    // no point loading the -keys module even when a bluetooth keyboard may be
9333    // available.
9334    return !(Y.UA.ios || Y.UA.android);
9335},
9336            "trigger": "autocomplete-list"
9337        },
9338        "requires": [
9339            "autocomplete-list",
9340            "base-build"
9341        ]
9342    },
9343    "autocomplete-plugin": {
9344        "requires": [
9345            "autocomplete-list",
9346            "node-pluginhost"
9347        ]
9348    },
9349    "autocomplete-sources": {
9350        "optional": [
9351            "io-base",
9352            "json-parse",
9353            "jsonp",
9354            "yql"
9355        ],
9356        "requires": [
9357            "autocomplete-base"
9358        ]
9359    },
9360    "axes": {
9361        "use": [
9362            "axis-numeric",
9363            "axis-category",
9364            "axis-time",
9365            "axis-stacked"
9366        ]
9367    },
9368    "axes-base": {
9369        "use": [
9370            "axis-numeric-base",
9371            "axis-category-base",
9372            "axis-time-base",
9373            "axis-stacked-base"
9374        ]
9375    },
9376    "axis": {
9377        "requires": [
9378            "dom",
9379            "widget",
9380            "widget-position",
9381            "widget-stack",
9382            "graphics",
9383            "axis-base"
9384        ]
9385    },
9386    "axis-base": {
9387        "requires": [
9388            "classnamemanager",
9389            "datatype-number",
9390            "datatype-date",
9391            "base",
9392            "event-custom"
9393        ]
9394    },
9395    "axis-category": {
9396        "requires": [
9397            "axis",
9398            "axis-category-base"
9399        ]
9400    },
9401    "axis-category-base": {
9402        "requires": [
9403            "axis-base"
9404        ]
9405    },
9406    "axis-numeric": {
9407        "requires": [
9408            "axis",
9409            "axis-numeric-base"
9410        ]
9411    },
9412    "axis-numeric-base": {
9413        "requires": [
9414            "axis-base"
9415        ]
9416    },
9417    "axis-stacked": {
9418        "requires": [
9419            "axis-numeric",
9420            "axis-stacked-base"
9421        ]
9422    },
9423    "axis-stacked-base": {
9424        "requires": [
9425            "axis-numeric-base"
9426        ]
9427    },
9428    "axis-time": {
9429        "requires": [
9430            "axis",
9431            "axis-time-base"
9432        ]
9433    },
9434    "axis-time-base": {
9435        "requires": [
9436            "axis-base"
9437        ]
9438    },
9439    "base": {
9440        "use": [
9441            "base-base",
9442            "base-pluginhost",
9443            "base-build"
9444        ]
9445    },
9446    "base-base": {
9447        "requires": [
9448            "attribute-base",
9449            "base-core",
9450            "base-observable"
9451        ]
9452    },
9453    "base-build": {
9454        "requires": [
9455            "base-base"
9456        ]
9457    },
9458    "base-core": {
9459        "requires": [
9460            "attribute-core"
9461        ]
9462    },
9463    "base-observable": {
9464        "requires": [
9465            "attribute-observable",
9466            "base-core"
9467        ]
9468    },
9469    "base-pluginhost": {
9470        "requires": [
9471            "base-base",
9472            "pluginhost"
9473        ]
9474    },
9475    "button": {
9476        "requires": [
9477            "button-core",
9478            "cssbutton",
9479            "widget"
9480        ]
9481    },
9482    "button-core": {
9483        "requires": [
9484            "attribute-core",
9485            "classnamemanager",
9486            "node-base",
9487            "escape"
9488        ]
9489    },
9490    "button-group": {
9491        "requires": [
9492            "button-plugin",
9493            "cssbutton",
9494            "widget"
9495        ]
9496    },
9497    "button-plugin": {
9498        "requires": [
9499            "button-core",
9500            "cssbutton",
9501            "node-pluginhost"
9502        ]
9503    },
9504    "cache": {
9505        "use": [
9506            "cache-base",
9507            "cache-offline",
9508            "cache-plugin"
9509        ]
9510    },
9511    "cache-base": {
9512        "requires": [
9513            "base"
9514        ]
9515    },
9516    "cache-offline": {
9517        "requires": [
9518            "cache-base",
9519            "json"
9520        ]
9521    },
9522    "cache-plugin": {
9523        "requires": [
9524            "plugin",
9525            "cache-base"
9526        ]
9527    },
9528    "calendar": {
9529        "requires": [
9530            "calendar-base",
9531            "calendarnavigator"
9532        ],
9533        "skinnable": true
9534    },
9535    "calendar-base": {
9536        "lang": [
9537            "ca",
9538            "ca-ES",
9539            "de",
9540            "en",
9541            "es",
9542            "es-AR",
9543            "eu-ES",
9544            "fr",
9545            "hu",
9546            "it",
9547            "ja",
9548            "nb-NO",
9549            "nl",
9550            "pt-BR",
9551            "ru",
9552            "zh-Hans",
9553            "zh-Hans-CN",
9554            "zh-Hant",
9555            "zh-Hant-HK",
9556            "zh-HANT-TW"
9557        ],
9558        "requires": [
9559            "widget",
9560            "datatype-date",
9561            "datatype-date-math",
9562            "cssgrids"
9563        ],
9564        "skinnable": true
9565    },
9566    "calendarnavigator": {
9567        "lang": [
9568            "en",
9569            "es",
9570            "es-AR",
9571            "eu-ES"
9572        ],
9573        "requires": [
9574            "plugin",
9575            "classnamemanager",
9576            "datatype-date",
9577            "node"
9578        ],
9579        "skinnable": true
9580    },
9581    "charts": {
9582        "use": [
9583            "charts-base"
9584        ]
9585    },
9586    "charts-base": {
9587        "requires": [
9588            "dom",
9589            "event-mouseenter",
9590            "event-touch",
9591            "graphics-group",
9592            "axes",
9593            "series-pie",
9594            "series-line",
9595            "series-marker",
9596            "series-area",
9597            "series-spline",
9598            "series-column",
9599            "series-bar",
9600            "series-areaspline",
9601            "series-combo",
9602            "series-combospline",
9603            "series-line-stacked",
9604            "series-marker-stacked",
9605            "series-area-stacked",
9606            "series-spline-stacked",
9607            "series-column-stacked",
9608            "series-bar-stacked",
9609            "series-areaspline-stacked",
9610            "series-combo-stacked",
9611            "series-combospline-stacked"
9612        ]
9613    },
9614    "charts-legend": {
9615        "requires": [
9616            "charts-base"
9617        ]
9618    },
9619    "classnamemanager": {
9620        "requires": [
9621            "yui-base"
9622        ]
9623    },
9624    "clickable-rail": {
9625        "requires": [
9626            "slider-base"
9627        ]
9628    },
9629    "collection": {
9630        "use": [
9631            "array-extras",
9632            "arraylist",
9633            "arraylist-add",
9634            "arraylist-filter",
9635            "array-invoke"
9636        ]
9637    },
9638    "color": {
9639        "use": [
9640            "color-base",
9641            "color-hsl",
9642            "color-harmony"
9643        ]
9644    },
9645    "color-base": {
9646        "requires": [
9647            "yui-base"
9648        ]
9649    },
9650    "color-harmony": {
9651        "requires": [
9652            "color-hsl"
9653        ]
9654    },
9655    "color-hsl": {
9656        "requires": [
9657            "color-base"
9658        ]
9659    },
9660    "color-hsv": {
9661        "requires": [
9662            "color-base"
9663        ]
9664    },
9665    "console": {
9666        "lang": [
9667            "en",
9668            "es",
9669            "hu",
9670            "it",
9671            "ja"
9672        ],
9673        "requires": [
9674            "yui-log",
9675            "widget"
9676        ],
9677        "skinnable": true
9678    },
9679    "console-filters": {
9680        "requires": [
9681            "plugin",
9682            "console"
9683        ],
9684        "skinnable": true
9685    },
9686    "content-editable": {
9687        "requires": [
9688            "node-base",
9689            "editor-selection",
9690            "stylesheet",
9691            "plugin"
9692        ]
9693    },
9694    "controller": {
9695        "use": [
9696            "router"
9697        ]
9698    },
9699    "cookie": {
9700        "requires": [
9701            "yui-base"
9702        ]
9703    },
9704    "createlink-base": {
9705        "requires": [
9706            "editor-base"
9707        ]
9708    },
9709    "cssbase": {
9710        "after": [
9711            "cssreset",
9712            "cssfonts",
9713            "cssgrids",
9714            "cssreset-context",
9715            "cssfonts-context",
9716            "cssgrids-context"
9717        ],
9718        "type": "css"
9719    },
9720    "cssbase-context": {
9721        "after": [
9722            "cssreset",
9723            "cssfonts",
9724            "cssgrids",
9725            "cssreset-context",
9726            "cssfonts-context",
9727            "cssgrids-context"
9728        ],
9729        "type": "css"
9730    },
9731    "cssbutton": {
9732        "type": "css"
9733    },
9734    "cssfonts": {
9735        "type": "css"
9736    },
9737    "cssfonts-context": {
9738        "type": "css"
9739    },
9740    "cssgrids": {
9741        "optional": [
9742            "cssnormalize"
9743        ],
9744        "type": "css"
9745    },
9746    "cssgrids-base": {
9747        "optional": [
9748            "cssnormalize"
9749        ],
9750        "type": "css"
9751    },
9752    "cssgrids-responsive": {
9753        "optional": [
9754            "cssnormalize"
9755        ],
9756        "requires": [
9757            "cssgrids",
9758            "cssgrids-responsive-base"
9759        ],
9760        "type": "css"
9761    },
9762    "cssgrids-units": {
9763        "optional": [
9764            "cssnormalize"
9765        ],
9766        "requires": [
9767            "cssgrids-base"
9768        ],
9769        "type": "css"
9770    },
9771    "cssnormalize": {
9772        "type": "css"
9773    },
9774    "cssnormalize-context": {
9775        "type": "css"
9776    },
9777    "cssreset": {
9778        "type": "css"
9779    },
9780    "cssreset-context": {
9781        "type": "css"
9782    },
9783    "dataschema": {
9784        "use": [
9785            "dataschema-base",
9786            "dataschema-json",
9787            "dataschema-xml",
9788            "dataschema-array",
9789            "dataschema-text"
9790        ]
9791    },
9792    "dataschema-array": {
9793        "requires": [
9794            "dataschema-base"
9795        ]
9796    },
9797    "dataschema-base": {
9798        "requires": [
9799            "base"
9800        ]
9801    },
9802    "dataschema-json": {
9803        "requires": [
9804            "dataschema-base",
9805            "json"
9806        ]
9807    },
9808    "dataschema-text": {
9809        "requires": [
9810            "dataschema-base"
9811        ]
9812    },
9813    "dataschema-xml": {
9814        "requires": [
9815            "dataschema-base"
9816        ]
9817    },
9818    "datasource": {
9819        "use": [
9820            "datasource-local",
9821            "datasource-io",
9822            "datasource-get",
9823            "datasource-function",
9824            "datasource-cache",
9825            "datasource-jsonschema",
9826            "datasource-xmlschema",
9827            "datasource-arrayschema",
9828            "datasource-textschema",
9829            "datasource-polling"
9830        ]
9831    },
9832    "datasource-arrayschema": {
9833        "requires": [
9834            "datasource-local",
9835            "plugin",
9836            "dataschema-array"
9837        ]
9838    },
9839    "datasource-cache": {
9840        "requires": [
9841            "datasource-local",
9842            "plugin",
9843            "cache-base"
9844        ]
9845    },
9846    "datasource-function": {
9847        "requires": [
9848            "datasource-local"
9849        ]
9850    },
9851    "datasource-get": {
9852        "requires": [
9853            "datasource-local",
9854            "get"
9855        ]
9856    },
9857    "datasource-io": {
9858        "requires": [
9859            "datasource-local",
9860            "io-base"
9861        ]
9862    },
9863    "datasource-jsonschema": {
9864        "requires": [
9865            "datasource-local",
9866            "plugin",
9867            "dataschema-json"
9868        ]
9869    },
9870    "datasource-local": {
9871        "requires": [
9872            "base"
9873        ]
9874    },
9875    "datasource-polling": {
9876        "requires": [
9877            "datasource-local"
9878        ]
9879    },
9880    "datasource-textschema": {
9881        "requires": [
9882            "datasource-local",
9883            "plugin",
9884            "dataschema-text"
9885        ]
9886    },
9887    "datasource-xmlschema": {
9888        "requires": [
9889            "datasource-local",
9890            "plugin",
9891            "datatype-xml",
9892            "dataschema-xml"
9893        ]
9894    },
9895    "datatable": {
9896        "use": [
9897            "datatable-core",
9898            "datatable-table",
9899            "datatable-head",
9900            "datatable-body",
9901            "datatable-base",
9902            "datatable-column-widths",
9903            "datatable-message",
9904            "datatable-mutable",
9905            "datatable-sort",
9906            "datatable-datasource"
9907        ]
9908    },
9909    "datatable-base": {
9910        "requires": [
9911            "datatable-core",
9912            "datatable-table",
9913            "datatable-head",
9914            "datatable-body",
9915            "base-build",
9916            "widget"
9917        ],
9918        "skinnable": true
9919    },
9920    "datatable-body": {
9921        "requires": [
9922            "datatable-core",
9923            "view",
9924            "classnamemanager"
9925        ]
9926    },
9927    "datatable-column-widths": {
9928        "requires": [
9929            "datatable-base"
9930        ]
9931    },
9932    "datatable-core": {
9933        "requires": [
9934            "escape",
9935            "model-list",
9936            "node-event-delegate"
9937        ]
9938    },
9939    "datatable-datasource": {
9940        "requires": [
9941            "datatable-base",
9942            "plugin",
9943            "datasource-local"
9944        ]
9945    },
9946    "datatable-foot": {
9947        "requires": [
9948            "datatable-core",
9949            "vi
9949ew"
9950        ]
9951    },
9952    "datatable-formatters": {
9953        "requires": [
9954            "datatable-body",
9955            "datatype-number-format",
9956            "datatype-date-format",
9957            "escape"
9958        ]
9959    },
9960    "datatable-head": {
9961        "requires": [
9962            "datatable-core",
9963            "view",
9964            "classnamemanager"
9965        ]
9966    },
9967    "datatable-highlight": {
9968        "requires": [
9969            "datatable-base",
9970            "event-hover"
9971        ],
9972        "skinnable": true
9973    },
9974    "datatable-keynav": {
9975        "requires": [
9976            "datatable-base"
9977        ]
9978    },
9979    "datatable-message": {
9980        "lang": [
9981            "en",
9982            "fr",
9983            "es",
9984            "hu",
9985            "it"
9986        ],
9987        "requires": [
9988            "datatable-base"
9989        ],
9990        "skinnable": true
9991    },
9992    "datatable-mutable": {
9993        "requires": [
9994            "datatable-base"
9995        ]
9996    },
9997    "datatable-paginator": {
9998        "lang": [
9999            "en",
10000            "fr"
10001        ],
10002        "requires": [
10003            "model",
10004            "view",
10005            "paginator-core",
10006            "datatable-foot",
10007            "datatable-paginator-templates"
10008        ],
10009        "skinnable": true
10010    },
10011    "datatable-paginator-templates": {
10012        "requires": [
10013            "template"
10014        ]
10015    },
10016    "datatable-scroll": {
10017        "requires": [
10018            "datatable-base",
10019            "datatable-column-widths",
10020            "dom-screen"
10021        ],
10022        "skinnable": true
10023    },
10024    "datatable-sort": {
10025        "lang": [
10026            "en",
10027            "fr",
10028            "es",
10029            "hu"
10030        ],
10031        "requires": [
10032            "datatable-base"
10033        ],
10034        "skinnable": true
10035    },
10036    "datatable-table": {
10037        "requires": [
10038            "datatable-core",
10039            "datatable-head",
10040            "datatable-body",
10041            "view",
10042            "classnamemanager"
10043        ]
10044    },
10045    "datatype": {
10046        "use": [
10047            "datatype-date",
10048            "datatype-number",
10049            "datatype-xml"
10050        ]
10051    },
10052    "datatype-date": {
10053        "use": [
10054            "datatype-date-parse",
10055            "datatype-date-format",
10056            "datatype-date-math"
10057        ]
10058    },
10059    "datatype-date-format": {
10060        "lang": [
10061            "ar",
10062            "ar-JO",
10063            "ca",
10064            "ca-ES",
10065            "da",
10066            "da-DK",
10067            "de",
10068            "de-AT",
10069            "de-DE",
10070            "el",
10071            "el-GR",
10072            "en",
10073            "en-AU",
10074            "en-CA",
10075            "en-GB",
10076            "en-IE",
10077            "en-IN",
10078            "en-JO",
10079            "en-MY",
10080            "en-NZ",
10081            "en-PH",
10082            "en-SG",
10083            "en-US",
10084            "es",
10085            "es-AR",
10086            "es-BO",
10087            "es-CL",
10088            "es-CO",
10089            "es-EC",
10090            "es-ES",
10091            "es-MX",
10092            "es-PE",
10093            "es-PY",
10094            "es-US",
10095            "es-UY",
10096            "es-VE",
10097            "fi",
10098            "fi-FI",
10099            "fr",
10100            "fr-BE",
10101            "fr-CA",
10102            "fr-FR",
10103            "hi",
10104            "hi-IN",
10105            "hu",
10106            "id",
10107            "id-ID",
10108            "it",
10109            "it-IT",
10110            "ja",
10111            "ja-JP",
10112            "ko",
10113            "ko-KR",
10114            "ms",
10115            "ms-MY",
10116            "nb",
10117            "nb-NO",
10118            "nl",
10119            "nl-BE",
10120            "nl-NL",
10121            "pl",
10122            "pl-PL",
10123            "pt",
10124            "pt-BR",
10125            "ro",
10126            "ro-RO",
10127            "ru",
10128            "ru-RU",
10129            "sv",
10130            "sv-SE",
10131            "th",
10132            "th-TH",
10133            "tr",
10134            "tr-TR",
10135            "vi",
10136            "vi-VN",
10137            "zh-Hans",
10138            "zh-Hans-CN",
10139            "zh-Hant",
10140            "zh-Hant-HK",
10141            "zh-Hant-TW"
10142        ]
10143    },
10144    "datatype-date-math": {
10145        "requires": [
10146            "yui-base"
10147        ]
10148    },
10149    "datatype-date-parse": {},
10150    "datatype-number": {
10151        "use": [
10152            "datatype-number-parse",
10153            "datatype-number-format"
10154        ]
10155    },
10156    "datatype-number-format": {},
10157    "datatype-number-parse": {
10158        "requires": [
10159            "escape"
10160        ]
10161    },
10162    "datatype-xml": {
10163        "use": [
10164            "datatype-xml-parse",
10165            "datatype-xml-format"
10166        ]
10167    },
10168    "datatype-xml-format": {},
10169    "datatype-xml-parse": {},
10170    "dd": {
10171        "use": [
10172            "dd-ddm-base",
10173            "dd-ddm",
10174            "dd-ddm-drop",
10175            "dd-drag",
10176            "dd-proxy",
10177            "dd-constrain",
10178            "dd-drop",
10179            "dd-scroll",
10180            "dd-delegate"
10181        ]
10182    },
10183    "dd-constrain": {
10184        "requires": [
10185            "dd-drag"
10186        ]
10187    },
10188    "dd-ddm": {
10189        "requires": [
10190            "dd-ddm-base",
10191            "event-resize"
10192        ]
10193    },
10194    "dd-ddm-base": {
10195        "requires": [
10196            "node",
10197            "base",
10198            "yui-throttle",
10199            "classnamemanager"
10200        ]
10201    },
10202    "dd-ddm-drop": {
10203        "requires": [
10204            "dd-ddm"
10205        ]
10206    },
10207    "dd-delegate": {
10208        "requires": [
10209            "dd-drag",
10210            "dd-drop-plugin",
10211            "event-mouseenter"
10212        ]
10213    },
10214    "dd-drag": {
10215        "requires": [
10216            "dd-ddm-base",
10217            "selector-css2"
10218        ]
10219    },
10220    "dd-drop": {
10221        "requires": [
10222            "dd-drag",
10223            "dd-ddm-drop"
10224        ]
10225    },
10226    "dd-drop-plugin": {
10227        "requires": [
10228            "dd-drop"
10229        ]
10230    },
10231    "dd-gestures": {
10232        "condition": {
10233            "name": "dd-gestures",
10234            "trigger": "dd-drag",
10235            "ua": "touchEnabled"
10236        },
10237        "requires": [
10238            "dd-drag",
10239            "event-synthetic",
10240            "event-gestures"
10241        ]
10242    },
10243    "dd-plugin": {
10244        "optional": [
10245            "dd-constrain",
10246            "dd-proxy"
10247        ],
10248        "requires": [
10249            "dd-drag"
10250        ]
10251    },
10252    "dd-proxy": {
10253        "requires": [
10254            "dd-drag"
10255        ]
10256    },
10257    "dd-scroll": {
10258        "requires": [
10259            "dd-drag"
10260        ]
10261    },
10262    "dial": {
10263        "lang": [
10264            "en",
10265            "es",
10266            "hu"
10267        ],
10268        "requires": [
10269            "widget",
10270            "dd-drag",
10271            "event-mouseenter",
10272            "event-move",
10273            "event-key",
10274            "transition",
10275            "intl"
10276        ],
10277        "skinnable": true
10278    },
10279    "dom": {
10280        "use": [
10281            "dom-base",
10282            "dom-screen",
10283            "dom-style",
10284            "selector-native",
10285            "selector"
10286        ]
10287    },
10288    "dom-base": {
10289        "requires": [
10290            "dom-core"
10291        ]
10292    },
10293    "dom-core": {
10294        "requires": [
10295            "oop",
10296            "features"
10297        ]
10298    },
10299    "dom-screen": {
10300        "requires": [
10301            "dom-base",
10302            "dom-style"
10303        ]
10304    },
10305    "dom-style": {
10306        "requires": [
10307            "dom-base"
10308        ]
10309    },
10310    "dom-style-ie": {
10311        "condition": {
10312            "name": "dom-style-ie",
10313            "test": function (Y) {
10314
10315    var testFeature = Y.Features.test,
10316        addFeature = Y.Features.add,
10317        WINDOW = Y.config.win,
10318        DOCUMENT = Y.config.doc,
10319        DOCUMENT_ELEMENT = 'documentElement',
10320        ret = false;
10321
10322    addFeature('style', 'computedStyle', {
10323        test: function() {
10324            return WINDOW && 'getComputedStyle' in WINDOW;
10325        }
10326    });
10327
10328    addFeature('style', 'opacity', {
10329        test: function() {
10330            return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
10331        }
10332    });
10333
10334    ret =  (!testFeature('style', 'opacity') &&
10335            !testFeature('style', 'computedStyle'));
10336
10337    return ret;
10338},
10339            "trigger": "dom-style"
10340        },
10341        "requires": [
10342            "dom-style",
10343            "color-base"
10344        ]
10345    },
10346    "dump": {
10347        "requires": [
10348            "yui-base"
10349        ]
10350    },
10351    "editor": {
10352        "use": [
10353            "frame",
10354            "editor-selection",
10355            "exec-command",
10356            "editor-base",
10357            "editor-para",
10358            "editor-br",
10359            "editor-bidi",
10360            "editor-tab",
10361            "createlink-base"
10362        ]
10363    },
10364    "editor-base": {
10365        "requires": [
10366            "base",
10367            "frame",
10368            "node",
10369            "exec-command",
10370            "editor-selection"
10371        ]
10372    },
10373    "editor-bidi": {
10374        "requires": [
10375            "editor-base"
10376        ]
10377    },
10378    "editor-br": {
10379        "requires": [
10380            "editor-base"
10381        ]
10382    },
10383    "editor-inline": {
10384        "requires": [
10385            "editor-base",
10386            "content-editable"
10387        ]
10388    },
10389    "editor-lists": {
10390        "requires": [
10391            "editor-base"
10392        ]
10393    },
10394    "editor-para": {
10395        "requires": [
10396            "editor-para-base"
10397        ]
10398    },
10399    "editor-para-base": {
10400        "requires": [
10401            "editor-base"
10402        ]
10403    },
10404    "editor-para-ie": {
10405        "condition": {
10406            "name": "editor-para-ie",
10407            "trigger": "editor-para",
10408            "ua": "ie",
10409            "when": "instead"
10410        },
10411        "requires": [
10412            "editor-para-base"
10413        ]
10414    },
10415    "editor-selection": {
10416        "requires": [
10417            "node"
10418        ]
10419    },
10420    "editor-tab": {
10421        "requires": [
10422            "editor-base"
10423        ]
10424    },
10425    "escape": {
10426        "requires": [
10427            "yui-base"
10428        ]
10429    },
10430    "event": {
10431        "after": [
10432            "node-base"
10433        ],
10434        "use": [
10435            "event-base",
10436            "event-delegate",
10437            "event-synthetic",
10438            "event-mousewheel",
10439            "event-mouseenter",
10440            "event-key",
10441            "event-focus",
10442            "event-resize",
10443            "event-hover",
10444            "event-outside",
10445            "event-touch",
10446            "event-move",
10447            "event-flick",
10448            "event-valuechange",
10449            "event-tap"
10450        ]
10451    },
10452    "event-base": {
10453        "after": [
10454            "node-base"
10455        ],
10456        "requires": [
10457            "event-custom-base"
10458        ]
10459    },
10460    "event-base-ie": {
10461        "after": [
10462            "event-base"
10463        ],
10464        "condition": {
10465            "name": "event-base-ie",
10466            "test": function(Y) {
10467    var imp = Y.config.doc && Y.config.doc.implementation;
10468    return (imp && (!imp.hasFeature('Events', '2.0')));
10469},
10470            "trigger": "node-base"
10471        },
10472        "requires": [
10473            "node-base"
10474        ]
10475    },
10476    "event-contextmenu": {
10477        "requires": [
10478            "event-synthetic",
10479            "dom-screen"
10480        ]
10481    },
10482    "event-custom": {
10483        "use": [
10484            "event-custom-base",
10485            "event-custom-complex"
10486        ]
10487    },
10488    "event-custom-base": {
10489        "requires": [
10490            "oop"
10491        ]
10492    },
10493    "event-custom-complex": {
10494        "requires": [
10495            "event-custom-base"
10496        ]
10497    },
10498    "event-delegate": {
10499        "requires": [
10500            "node-base"
10501        ]
10502    },
10503    "event-flick": {
10504        "requires": [
10505            "node-base",
10506            "event-touch",
10507            "event-synthetic"
10508        ]
10509    },
10510    "event-focus": {
10511        "requires": [
10512            "event-synthetic"
10513        ]
10514    },
10515    "event-gestures": {
10516        "use": [
10517            "event-flick",
10518            "event-move"
10519        ]
10520    },
10521    "event-hover": {
10522        "requires": [
10523            "event-mouseenter"
10524        ]
10525    },
10526    "event-key": {
10527        "requires": [
10528            "event-synthetic"
10529        ]
10530    },
10531    "event-mouseenter": {
10532        "requires": [
10533            "event-synthetic"
10534        ]
10535    },
10536    "event-mousewheel": {
10537        "requires": [
10538            "node-base"
10539        ]
10540    },
10541    "event-move": {
10542        "requires": [
10543            "node-base",
10544            "event-touch",
10545            "event-synthetic"
10546        ]
10547    },
10548    "event-outside": {
10549        "requires": [
10550            "event-synthetic"
10551        ]
10552    },
10553    "event-resize": {
10554        "requires": [
10555            "node-base",
10556            "event-synthetic"
10557        ]
10558    },
10559    "event-simulate": {
10560        "requires": [
10561            "event-base"
10562        ]
10563    },
10564    "event-synthetic": {
10565        "requires": [
10566            "node-base",
10567            "event-custom-complex"
10568        ]
10569    },
10570    "event-tap": {
10571        "requires": [
10572            "node-base",
10573            "event-base",
10574            "event-touch",
10575            "event-synthetic"
10576        ]
10577    },
10578    "event-touch": {
10579        "requires": [
10580            "node-base"
10581        ]
10582    },
10583    "event-valuechange": {
10584        "requires": [
10585            "event-focus",
10586            "event-synthetic"
10587        ]
10588    },
10589    "exec-command": {
10590        "requires": [
10591            "frame"
10592        ]
10593    },
10594    "features": {
10595        "requires": [
10596            "yui-base"
10597        ]
10598    },
10599    "file": {
10600        "requires": [
10601            "file-flash",
10602            "file-html5"
10603        ]
10604    },
10605    "file-flash": {
10606        "requires": [
10607            "base"
10608        ]
10609    },
10610    "file-html5": {
10611        "requires": [
10612            "base"
10613        ]
10614    },
10615    "frame": {
10616        "requires": [
10617            "base",
10618            "node",
10619            "plugin",
10620            "selector-css3",
10621            "yui-throttle"
10622        ]
10623    },
10624    "gesture-simulate": {
10625        "requires": [
10626            "async-queue",
10627            "event-simulate",
10628            "node-screen"
10629        ]
10630    },
10631    "get": {
10632        "requires": [
10633            "yui-base"
10634        ]
10635    },
10636    "graphics": {
10637        "requires": [
10638            "node",
10639            "event-custom",
10640            "pluginhost",
10641            "matrix",
10642            "classnamemanager"
10643        ]
10644    },
10645    "graphics-canvas": {
10646        "condition": {
10647            "name": "graphics-canvas",
10648            "test": function(Y) {
10649    var DOCUMENT = Y.config.doc,
10650        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10651		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10652        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10653    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10654},
10655            "trigger": "graphics"
10656        },
10657        "requires": [
10658            "graphics",
10659            "color-base"
10660        ]
10661    },
10662    "graphics-canvas-default": {
10663        "condition": {
10664            "name": "graphics-canvas-default",
10665            "test": function(Y) {
10666    var DOCUMENT = Y.config.doc,
10667        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10668		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10669        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10670    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10671},
10672            "trigger": "graphics"
10673        }
10674    },
10675    "graphics-group": {
10676        "requires": [
10677            "graphics"
10678        ]
10679    },
10680    "graphics-svg": {
10681        "condition": {
10682            "name": "graphics-svg",
10683            "test": function(Y) {
10684    var DOCUMENT = Y.config.doc,
10685        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10686		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10687        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10688
10689    return svg && (useSVG || !canvas);
10690},
10691            "trigger": "graphics"
10692        },
10693        "requires": [
10694            "graphics"
10695        ]
10696    },
10697    "graphics-svg-default": {
10698        "condition": {
10699            "name": "graphics-svg-default",
10700            "test": function(Y) {
10701    var DOCUMENT = Y.config.doc,
10702        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10703		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10704        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10705
10706    return svg && (useSVG || !canvas);
10707},
10708            "trigger": "graphics"
10709        }
10710    },
10711    "graphics-vml": {
10712        "condition": {
10713            "name": "graphics-vml",
10714            "test": function(Y) {
10715    var DOCUMENT = Y.config.doc,
10716		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10717    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10718},
10719            "trigger": "graphics"
10720        },
10721        "requires": [
10722            "graphics",
10723            "color-base"
10724        ]
10725    },
10726    "graphics-vml-default": {
10727        "condition": {
10728            "name": "graphics-vml-default",
10729            "test": function(Y) {
10730    var DOCUMENT = Y.config.doc,
10731		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10732    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10733},
10734            "trigger": "graphics"
10735        }
10736    },
10737    "handlebars": {
10738        "use": [
10739            "handlebars-compiler"
10740        ]
10741    },
10742    "handlebars-base": {
10743        "requires": []
10744    },
10745    "handlebars-compiler": {
10746        "requires": [
10747            "handlebars-base"
10748        ]
10749    },
10750    "highlight": {
10751        "use": [
10752            "highlight-base",
10753            "highlight-accentfold"
10754        ]
10755    },
10756    "highlight-accentfold": {
10757        "requires": [
10758            "highlight-base",
10759            "text-accentfold"
10760        ]
10761    },
10762    "highlight-base": {
10763        "requires": [
10764            "array-extras",
10765            "classnamemanager",
10766            "escape",
10767            "text-wordbreak"
10768        ]
10769    },
10770    "history": {
10771        "use": [
10772            "history-base",
10773            "history-hash",
10774            "history-html5"
10775        ]
10776    },
10777    "history-base": {
10778        "requires": [
10779            "event-custom-complex"
10780        ]
10781    },
10782    "history-hash": {
10783        "after": [
10784            "history-html5"
10785        ],
10786        "requires": [
10787            "event-synthetic",
10788            "history-base",
10789            "yui-later"
10790        ]
10791    },
10792    "history-hash-ie": {
10793        "condition": {
10794            "name": "history-hash-ie",
10795            "test": function (Y) {
10796    var docMode = Y.config.doc && Y.config.doc.documentMode;
10797
10798    return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
10799            !docMode || docMode < 8);
10800},
10801            "trigger": "history-hash"
10802        },
10803        "requires": [
10804            "history-hash",
10805            "node-base"
10806        ]
10807    },
10808    "history-html5": {
10809        "optional": [
10810            "json"
10811        ],
10812        "requires": [
10813            "event-base",
10814            "history-base",
10815            "node-base"
10816        ]
10817    },
10818    "imageloader": {
10819        "requires": [
10820            "base-base",
10821            "node-style",
10822            "node-screen"
10823        ]
10824    },
10825    "intl": {
10826        "requires": [
10827            "intl-base",
10828            "event-custom"
10829        ]
10830    },
10831    "intl-base": {
10832        "requires": [
10833            "yui-base"
10834        ]
10835    },
10836    "io": {
10837        "use": [
10838            "io-base",
10839            "io-xdr",
10840            "io-form",
10841            "io-upload-iframe",
10842            "io-queue"
10843        ]
10844    },
10845    "io-base": {
10846        "requires": [
10847            "event-custom-base",
10848            "querystring-stringify-simple"
10849        ]
10850    },
10851    "io-form": {
10852        "requires": [
10853            "io-base",
10854            "node-base"
10855        ]
10856    },
10857    "io-nodejs": {
10858        "condition": {
10859            "name": "io-nodejs",
10860            "trigger": "io-base",
10861            "ua": "nodejs"
10862        },
10863        "requires": [
10864            "io-base"
10865        ]
10866    },
10867    "io-queue": {
10868        "requires": [
10869            "io-base",
10870            "queue-promote"
10871        ]
10872    },
10873    "io-upload-iframe": {
10874        "requires": [
10875            "io-base",
10876            "node-base"
10877        ]
10878    },
10879    "io-xdr": {
10880        "requires": [
10881            "io-base",
10882            "datatype-xml-parse"
10883        ]
10884    },
10885    "json": {
10886        "use": [
10887            "json-parse",
10888            "json-stringify"
10889        ]
10890    },
10891    "json-parse": {
10892        "requires": [
10893            "yui-base"
10894        ]
10895    },
10896    "json-parse-shim": {
10897        "condition": {
10898            "name": "json-parse-shim",
10899            "test": function (Y) {
10900    var _JSON = Y.config.global.JSON,
10901        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
10902        nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
10903
10904    function workingNative( k, v ) {
10905        return k === "ok" ? true : v;
10906    }
10907
10908    // Double check basic functionality.  This is mainly to catch early broken
10909    // implementations of the JSON API in Firefox 3.1 beta1 and beta2
10910    if ( nativeSupport ) {
10911        try {
10912            nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
10913        }
10914        catch ( e ) {
10915            nativeSupport = false;
10916        }
10917    }
10918
10919    return !nativeSupport;
10920},
10921            "trigger": "json-parse"
10922        },
10923        "requires": [
10924            "json-parse"
10925        ]
10926    },
10927    "json-stringify": {
10928        "requires": [
10929            "yui-base"
10930        ]
10931    },
10932    "json-stringify-shim": {
10933        "condition": {
10934            "name": "json-stringify-shim",
10935            "test": function (Y) {
10936    var _JSON = Y.config.global.JSON,
10937        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
10938        nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
10939
10940    // Double check basic native functionality.  This is primarily to catch broken
10941    // early JSON API implementations in Firefox 3.1 beta1 and beta2.
10942    if ( nativeSupport ) {
10943        try {
10944            nativeSupport = ( '0' === Native.stringify(0) );
10945        } catch ( e ) {
10946            nativeSupport = false;
10947        }
10948    }
10949
10950
10951    return !nativeSupport;
10952},
10953            "trigger": "json-stringify"
10954        },
10955        "requires": [
10956            "json-stringify"
10957        ]
10958    },
10959    "jsonp": {
10960        "requires": [
10961            "get",
10962            "oop"
10963        ]
10964    },
10965    "jsonp-url": {
10966        "requires": [
10967            "jsonp"
10968        ]
10969    },
10970    "lazy-model-list": {
10971        "requires": [
10972            "model-list"
10973        ]
10974    },
10975    "loader": {
10976        "use": [
10977            "loader-base",
10978            "loader-rollup",
10979            "loader-yui3"
10980        ]
10981    },
10982    "loader-base": {
10983        "requires": [
10984            "get",
10985            "features"
10986        ]
10987    },
10988    "loader-pathogen-combohandler": {},
10989    "loader-pathogen-encoder": {
10990        "use": [
10991            "loader-base",
10992            "loader-rollup",
10993            "loader-yui3",
10994            "loader-pathogen-combohandler"
10995        ]
10996    },
10997    "loader-rollup": {
10998        "requires": [
10999            "loader-base"
11000        ]
11001    },
11002    "loader-yui3": {
11003        "requires": [
11004            "loader-base"
11005        ]
11006    },
11007    "matrix": {
11008        "requires": [
11009            "yui-base"
11010        ]
11011    },
11012    "model": {
11013        "requires": [
11014            "base-build",
11015            "escape",
11016            "json-parse"
11017        ]
11018    },
11019    "model-list": {
11020        "requires": [
11021            "array-extras",
11022            "array-invoke",
11023            "arraylist",
11024            "base-build",
11025            "escape",
11026            "json-parse",
11027            "model"
11028        ]
11029    },
11030    "model-sync-local": {
11031        "requires": [
11032            "model",
11033            "json-stringify"
11034        ]
11035    },
11036    "model-sync-rest": {
11037        "requires": [
11038            "model",
11039            "io-base",
11040            "json-stringify"
11041        ]
11042    },
11043    "node": {
11044        "use": [
11045            "node-base",
11046            "node-event-delegate",
11047            "node-pluginhost",
11048            "node-screen",
11049            "node-style"
11050        ]
11051    },
11052    "node-base": {
11053        "requires": [
11054            "event-base",
11055            "node-core",
11056            "dom-base",
11057            "dom-style"
11058        ]
11059    },
11060    "node-core": {
11061        "requires": [
11062            "dom-core",
11063            "selector"
11064        ]
11065    },
11066    "node-event-delegate": {
11067        "requires": [
11068            "node-base",
11069            "event-delegate"
11070        ]
11071    },
11072    "node-event-html5": {
11073        "requires": [
11074            "node-base"
11075        ]
11076    },
11077    "node-event-simulate": {
11078        "requires": [
11079            "node-base",
11080            "event-simulate",
11081            "gesture-simulate"
11082        ]
11083    },
11084    "node-flick": {
11085        "requires": [
11086            "classnamemanager",
11087            "transition",
11088            "event-flick",
11089            "plugin"
11090        ],
11091        "skinnable": true
11092    },
11093    "node-focusmanager": {
11094        "requires": [
11095            "attribute",
11096            "node",
11097            "plugin",
11098            "node-event-simulate",
11099            "event-key",
11100            "event-focus"
11101        ]
11102    },
11103    "node-load": {
11104        "requires": [
11105            "node-base",
11106            "io-base"
11107        ]
11108    },
11109    "node-menunav": {
11110        "requires": [
11111            "node",
11112            "classnamemanager",
11113            "plugin",
11114            "node-focusmanager"
11115        ],
11116        "skinnable": true
11117    },
11118    "node-pluginhost": {
11119        "requires": [
11120            "node-base",
11121            "pluginhost"
11122        ]
11123    },
11124    "node-screen": {
11125        "requires": [
11126            "dom-screen",
11127            "node-base"
11128        ]
11129    },
11130    "node-scroll-info": {
11131        "requires": [
11132            "array-extras",
11133            "base-build",
11134            "event-resize",
11135            "node-pluginhost",
11136            "plugin",
11137            "selector"
11138        ]
11139    },
11140    "node-style": {
11141        "requires": [
11142            "dom-style",
11143            "node-base"
11144        ]
11145    },
11146    "oop": {
11147        "requires": [
11148            "yui-base"
11149        ]
11150    },
11151    "overlay": {
11152        "requires": [
11153            "widget",
11154            "widget-stdmod",
11155            "widget-position",
11156            "widget-position-align",
11157            "widget-stack",
11158            "widget-position-constrain"
11159        ],
11160        "skinnable": true
11161    },
11162    "paginator": {
11163        "requires": [
11164            "paginator-core"
11165        ]
11166    },
11167    "paginator-core": {
11168        "requires": [
11169            "base"
11170        ]
11171    },
11172    "paginator-url": {
11173        "requires": [
11174            "paginator"
11175        ]
11176    },
11177    "panel": {
11178        "requires": [
11179            "widget",
11180            "widget-autohide",
11181            "widget-buttons",
11182            "widget-modality",
11183            "widget-position",
11184            "widget-position-align",
11185            "widget-position-constrain",
11186            "widget-stack",
11187            "widget-stdmod"
11188        ],
11189        "skinnable": true
11190    },
11191    "parallel": {
11192        "requires": [
11193            "yui-base"
11194        ]
11195    },
11196    "pjax": {
11197        "requires": [
11198            "pjax-base",
11199            "pjax-content"
11200        ]
11201    },
11202    "pjax-base": {
11203        "requires": [
11204            "classnamemanager",
11205            "node-event-delegate",
11206            "router"
11207        ]
11208    },
11209    "pjax-content": {
11210        "requires": [
11211            "io-base",
11212            "node-base",
11213            "router"
11214        ]
11215    },
11216    "pjax-plugin": {
11217        "requires": [
11218            "node-pluginhost",
11219            "pjax",
11220            "plugin"
11221        ]
11222    },
11223    "plugin": {
11224        "requires": [
11225            "base-base"
11226        ]
11227    },
11228    "pluginhost": {
11229        "use": [
11230            "pluginhost-base",
11231            "pluginhost-config"
11232        ]
11233    },
11234    "pluginhost-base": {
11235        "requires": [
11236            "yui-base"
11237        ]
11238    },
11239    "pluginhost-config": {
11240        "requires": [
11241            "pluginhost-base"
11242        ]
11243    },
11244    "promise": {
11245        "requires": [
11246            "timers"
11247        ]
11248    },
11249    "querystring": {
11250        "use": [
11251            "querystring-parse",
11252            "querystring-stringify"
11253        ]
11254    },
11255    "querystring-parse": {
11256        "requires": [
11257            "yui-base",
11258            "array-extras"
11259        ]
11260    },
11261    "querystring-parse-simple": {
11262        "requires": [
11263            "yui-base"
11264        ]
11265    },
11266    "querystring-stringify": {
11267        "requires": [
11268            "yui-base"
11269        ]
11270    },
11271    "querystring-stringify-simple": {
11272        "requires": [
11273            "yui-base"
11274        ]
11275    },
11276    "queue-promote": {
11277        "requires": [
11278            "yui-base"
11279        ]
11280    },
11281    "range-slider": {
11282        "requires": [
11283            "slider-base",
11284            "slider-value-range",
11285            "clickable-rail"
11286        ]
11287    },
11288    "recordset": {
11289        "use": [
11290            "recordset-base",
11291            "recordset-sort",
11292            "recordset-filter",
11293            "recordset-indexer"
11294        ]
11295    },
11296    "recordset-base": {
11297        "requires": [
11298            "base",
11299            "arraylist"
11300        ]
11301    },
11302    "recordset-filter": {
11303        "requires": [
11304            "recordset-base",
11305            "array-extras",
11306            "plugin"
11307        ]
11308    },
11309    "recordset-indexer": {
11310        "requires": [
11311            "recordset-base",
11312            "plugin"
11313        ]
11314    },
11315    "recordset-sort": {
11316        "requires": [
11317            "arraysort",
11318            "recordset-base",
11319            "plugin"
11320        ]
11321    },
11322    "resize": {
11323        "use": [
11324            "resize-base",
11325            "resize-proxy",
11326            "resize-constrain"
11327        ]
11328    },
11329    "resize-base": {
11330        "requires": [
11331            "base",
11332            "widget",
11333            "event",
11334            "oop",
11335            "dd-drag",
11336            "dd-delegate",
11337            "dd-drop"
11338        ],
11339        "skinnable": true
11340    },
11341    "resize-constrain": {
11342        "requires": [
11343            "plugin",
11344            "resize-base"
11345        ]
11346    },
11347    "resize-plugin": {
11348        "optional": [
11349            "resize-constrain"
11350        ],
11351        "requires": [
11352            "resize-base",
11353            "plugin"
11354        ]
11355    },
11356    "resize-proxy": {
11357        "requires": [
11358            "plugin",
11359            "resize-base"
11360        ]
11361    },
11362    "router": {
11363        "optional": [
11364            "querystring-parse"
11365        ],
11366        "requires": [
11367            "array-extras",
11368            "base-build",
11369            "history"
11370        ]
11371    },
11372    "scrollview": {
11373        "requires": [
11374            "scrollview-base",
11375            "scrollview-scrollbars"
11376        ]
11377    },
11378    "scrollview-base": {
11379        "requires": [
11380            "widget",
11381            "event-gestures",
11382            "event-mousewheel",
11383            "transition"
11384        ],
11385        "skinnable": true
11386    },
11387    "scrollview-base-ie": {
11388        "condition": {
11389            "name": "scrollview-base-ie",
11390            "trigger": "scrollview-base",
11391            "ua": "ie"
11392        },
11393        "requires": [
11394            "scrollview-base"
11395        ]
11396    },
11397    "scrollview-list": {
11398        "requires": [
11399            "plugin",
11400            "classnamemanager"
11401        ],
11402        "skinnable": true
11403    },
11404    "scrollview-paginator": {
11405        "requires": [
11406            "plugin",
11407            "classnamemanager"
11408        ]
11409    },
11410    "scrollview-scrollbars": {
11411        "requires": [
11412            "classnamemanager",
11413            "transition",
11414            "plugin"
11415        ],
11416        "skinnable": true
11417    },
11418    "selector": {
11419        "requires": [
11420            "selector-native"
11421        ]
11422    },
11423    "selector-css2": {
11424        "condition": {
11425            "name": "selector-css2",
11426            "test": function (Y) {
11427    var DOCUMENT = Y.config.doc,
11428        ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
11429
11430    return ret;
11431},
11432            "trigger": "selector"
11433        },
11434        "requires": [
11435            "selector-native"
11436        ]
11437    },
11438    "selector-css3": {
11439        "requires": [
11440            "selector-native",
11441            "selector-css2"
11442        ]
11443    },
11444    "selector-native": {
11445        "requires": [
11446            "dom-base"
11447        ]
11448    },
11449    "series-area": {
11450        "requires": [
11451            "series-cartesian",
11452            "series-fill-util"
11453        ]
11454    },
11455    "series-area-stacked": {
11456        "requires": [
11457            "series-stacked",
11458            "series-area"
11459        ]
11460    },
11461    "series-areaspline": {
11462        "requires": [
11463            "series-area",
11464            "series-curve-util"
11465        ]
11466    },
11467    "series-areaspline-stacked": {
11468        "requires": [
11469            "series-stacked",
11470            "series-areaspline"
11471        ]
11472    },
11473    "series-bar": {
11474        "requires": [
11475            "series-marker",
11476            "series-histogram-base"
11477        ]
11478    },
11479    "series-bar-stacked": {
11480        "requires": [
11481            "series-stacked",
11482            "series-bar"
11483        ]
11484    },
11485    "series-base": {
11486        "requires": [
11487            "graphics",
11488            "axis-base"
11489        ]
11490    },
11491    "series-candlestick": {
11492        "requires": [
11493            "series-range"
11494        ]
11495    },
11496    "series-cartesian": {
11497        "requires": [
11498            "series-base"
11499        ]
11500    },
11501    "series-column": {
11502        "requires": [
11503            "series-marker",
11504            "series-histogram-base"
11505        ]
11506    },
11507    "series-column-stacked": {
11508        "requires": [
11509            "series-stacked",
11510            "series-column"
11511        ]
11512    },
11513    "series-combo": {
11514        "requires": [
11515            "series-cartesian",
11516            "series-line-util",
11517            "series-plot-util",
11518            "series-fill-util"
11519        ]
11520    },
11521    "series-combo-stacked": {
11522        "requires": [
11523            "series-stacked",
11524            "series-combo"
11525        ]
11526    },
11527    "series-combospline": {
11528        "requires": [
11529            "series-combo",
11530            "series-curve-util"
11531        ]
11532    },
11533    "series-combospline-stacked": {
11534        "requires": [
11535            "series-combo-stacked",
11536            "series-curve-util"
11537        ]
11538    },
11539    "series-curve-util": {},
11540    "series-fill-util": {},
11541    "series-histogram-base": {
11542        "requires": [
11543            "series-cartesian",
11544            "series-plot-util"
11545        ]
11546    },
11547    "series-line": {
11548        "requires": [
11549            "series-cartesian",
11550            "series-line-util"
11551        ]
11552    },
11553    "series-line-stacked": {
11554        "requires": [
11555            "series-stacked",
11556            "series-line"
11557        ]
11558    },
11559    "series-line-util": {},
11560    "series-marker": {
11561        "requires": [
11562            "series-cartesian",
11563            "series-plot-util"
11564        ]
11565    },
11566    "series-marker-stacked": {
11567        "requires": [
11568            "series-stacked",
11569            "series-marker"
11570        ]
11571    },
11572    "series-ohlc": {
11573        "requires": [
11574            "series-range"
11575        ]
11576    },
11577    "series-pie": {
11578        "requires": [
11579            "series-base",
11580            "series-plot-util"
11581        ]
11582    },
11583    "series-plot-util": {},
11584    "series-range": {
11585        "requires": [
11586            "series-cartesian"
11587        ]
11588    },
11589    "series-spline": {
11590        "requires": [
11591            "series-line",
11592            "series-curve-util"
11593        ]
11594    },
11595    "series-spline-stacked": {
11596        "requires": [
11597            "series-stacked",
11598            "series-spline"
11599        ]
11600    },
11601    "series-stacked": {
11602        "requires": [
11603            "axis-stacked"
11604        ]
11605    },
11606    "shim-plugin": {
11607        "requires": [
11608            "node-style",
11609            "node-pluginhost"
11610        ]
11611    },
11612    "slider": {
11613        "use": [
11614            "slider-base",
11615            "slider-value-range",
11616            "clickable-rail",
11617            "range-slider"
11618        ]
11619    },
11620    "slider-base": {
11621        "requires": [
11622            "widget",
11623            "dd-constrain",
11624            "event-key"
11625        ],
11626        "skinnable": true
11627    },
11628    "slider-value-range": {
11629        "requires": [
11630            "slider-base"
11631        ]
11632    },
11633    "sortable": {
11634        "requires": [
11635            "dd-delegate",
11636            "dd-drop-plugin",
11637            "dd-proxy"
11638        ]
11639    },
11640    "sortable-scroll": {
11641        "requires": [
11642            "dd-scroll",
11643            "sortable"
11644        ]
11645    },
11646    "stylesheet": {
11647        "requires": [
11648            "yui-base"
11649        ]
11650    },
11651    "substitute": {
11652        "optional": [
11653            "dump"
11654        ],
11655        "requires": [
11656            "yui-base"
11657        ]
11658    },
11659    "swf": {
11660        "requires": [
11661            "event-custom",
11662            "node",
11663            "swfdetect",
11664            "escape"
11665        ]
11666    },
11667    "swfdetect": {
11668        "requires": [
11669            "yui-base"
11670        ]
11671    },
11672    "tabview": {
11673        "requires": [
11674            "widget",
11675            "widget-parent",
11676            "widget-child",
11677            "tabview-base",
11678            "node-pluginhost",
11679            "node-focusmanager"
11680        ],
11681        "skinnable": true
11682    },
11683    "tabview-base": {
11684        "requires": [
11685            "node-event-delegate",
11686            "classnamemanager"
11687        ]
11688    },
11689    "tabview-plugin": {
11690        "requires": [
11691            "tabview-base"
11692        ]
11693    },
11694    "template": {
11695        "use": [
11696            "template-base",
11697            "template-micro"
11698        ]
11699    },
11700    "template-base": {
11701        "requires": [
11702            "yui-base"
11703        ]
11704    },
11705    "template-micro": {
11706        "requires": [
11707            "escape"
11708        ]
11709    },
11710    "test": {
11711        "requires": [
11712            "event-simulate",
11713            "event-custom",
11714            "json-stringify"
11715        ]
11716    },
11717  
11717  "test-console": {
11718        "requires": [
11719            "console-filters",
11720            "test",
11721            "array-extras"
11722        ],
11723        "skinnable": true
11724    },
11725    "text": {
11726        "use": [
11727            "text-accentfold",
11728            "text-wordbreak"
11729        ]
11730    },
11731    "text-accentfold": {
11732        "requires": [
11733            "array-extras",
11734            "text-data-accentfold"
11735        ]
11736    },
11737    "text-data-accentfold": {
11738        "requires": [
11739            "yui-base"
11740        ]
11741    },
11742    "text-data-wordbreak": {
11743        "requires": [
11744            "yui-base"
11745        ]
11746    },
11747    "text-wordbreak": {
11748        "requires": [
11749            "array-extras",
11750            "text-data-wordbreak"
11751        ]
11752    },
11753    "timers": {
11754        "requires": [
11755            "yui-base"
11756        ]
11757    },
11758    "transition": {
11759        "requires": [
11760            "node-style"
11761        ]
11762    },
11763    "transition-timer": {
11764        "condition": {
11765            "name": "transition-timer",
11766            "test": function (Y) {
11767    var DOCUMENT = Y.config.doc,
11768        node = (DOCUMENT) ? DOCUMENT.documentElement: null,
11769        ret = true;
11770
11771    if (node && node.style) {
11772        ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
11773    }
11774
11775    return ret;
11776},
11777            "trigger": "transition"
11778        },
11779        "requires": [
11780            "transition"
11781        ]
11782    },
11783    "tree": {
11784        "requires": [
11785            "base-build",
11786            "tree-node"
11787        ]
11788    },
11789    "tree-labelable": {
11790        "requires": [
11791            "tree"
11792        ]
11793    },
11794    "tree-lazy": {
11795        "requires": [
11796            "base-pluginhost",
11797            "plugin",
11798            "tree"
11799        ]
11800    },
11801    "tree-node": {},
11802    "tree-openable": {
11803        "requires": [
11804            "tree"
11805        ]
11806    },
11807    "tree-selectable": {
11808        "requires": [
11809            "tree"
11810        ]
11811    },
11812    "tree-sortable": {
11813        "requires": [
11814            "tree"
11815        ]
11816    },
11817    "uploader": {
11818        "requires": [
11819            "uploader-html5",
11820            "uploader-flash"
11821        ]
11822    },
11823    "uploader-flash": {
11824        "requires": [
11825            "swfdetect",
11826            "escape",
11827            "widget",
11828            "base",
11829            "cssbutton",
11830            "node",
11831            "event-custom",
11832            "uploader-queue"
11833        ]
11834    },
11835    "uploader-html5": {
11836        "requires": [
11837            "widget",
11838            "node-event-simulate",
11839            "file-html5",
11840            "uploader-queue"
11841        ]
11842    },
11843    "uploader-queue": {
11844        "requires": [
11845            "base"
11846        ]
11847    },
11848    "view": {
11849        "requires": [
11850            "base-build",
11851            "node-event-delegate"
11852        ]
11853    },
11854    "view-node-map": {
11855        "requires": [
11856            "view"
11857        ]
11858    },
11859    "widget": {
11860        "use": [
11861            "widget-base",
11862            "widget-htmlparser",
11863            "widget-skin",
11864            "widget-uievents"
11865        ]
11866    },
11867    "widget-anim": {
11868        "requires": [
11869            "anim-base",
11870            "plugin",
11871            "widget"
11872        ]
11873    },
11874    "widget-autohide": {
11875        "requires": [
11876            "base-build",
11877            "event-key",
11878            "event-outside",
11879            "widget"
11880        ]
11881    },
11882    "widget-base": {
11883        "requires": [
11884            "attribute",
11885            "base-base",
11886            "base-pluginhost",
11887            "classnamemanager",
11888            "event-focus",
11889            "node-base",
11890            "node-style"
11891        ],
11892        "skinnable": true
11893    },
11894    "widget-base-ie": {
11895        "condition": {
11896            "name": "widget-base-ie",
11897            "trigger": "widget-base",
11898            "ua": "ie"
11899        },
11900        "requires": [
11901            "widget-base"
11902        ]
11903    },
11904    "widget-buttons": {
11905        "requires": [
11906            "button-plugin",
11907            "cssbutton",
11908            "widget-stdmod"
11909        ]
11910    },
11911    "widget-child": {
11912        "requires": [
11913            "base-build",
11914            "widget"
11915        ]
11916    },
11917    "widget-htmlparser": {
11918        "requires": [
11919            "widget-base"
11920        ]
11921    },
11922    "widget-modality": {
11923        "requires": [
11924            "base-build",
11925            "event-outside",
11926            "widget"
11927        ],
11928        "skinnable": true
11929    },
11930    "widget-parent": {
11931        "requires": [
11932            "arraylist",
11933            "base-build",
11934            "widget"
11935        ]
11936    },
11937    "widget-position": {
11938        "requires": [
11939            "base-build",
11940            "node-screen",
11941            "widget"
11942        ]
11943    },
11944    "widget-position-align": {
11945        "requires": [
11946            "widget-position"
11947        ]
11948    },
11949    "widget-position-constrain": {
11950        "requires": [
11951            "widget-position"
11952        ]
11953    },
11954    "widget-skin": {
11955        "requires": [
11956            "widget-base"
11957        ]
11958    },
11959    "widget-stack": {
11960        "requires": [
11961            "base-build",
11962            "widget"
11963        ],
11964        "skinnable": true
11965    },
11966    "widget-stdmod": {
11967        "requires": [
11968            "base-build",
11969            "widget"
11970        ]
11971    },
11972    "widget-uievents": {
11973        "requires": [
11974            "node-event-delegate",
11975            "widget-base"
11976        ]
11977    },
11978    "yql": {
11979        "requires": [
11980            "oop"
11981        ]
11982    },
11983    "yql-jsonp": {
11984        "condition": {
11985            "name": "yql-jsonp",
11986            "test": function (Y) {
11987    /* Only load the JSONP module when not in nodejs or winjs
11988    TODO Make the winjs module a CORS module
11989    */
11990    return (!Y.UA.nodejs && !Y.UA.winjs);
11991},
11992            "trigger": "yql"
11993        },
11994        "requires": [
11995            "yql",
11996            "jsonp",
11997            "jsonp-url"
11998        ]
11999    },
12000    "yql-nodejs": {
12001        "condition": {
12002            "name": "yql-nodejs",
12003            "trigger": "yql",
12004            "ua": "nodejs"
12005        },
12006        "requires": [
12007            "yql"
12008        ]
12009    },
12010    "yql-winjs": {
12011        "condition": {
12012            "name": "yql-winjs",
12013            "trigger": "yql",
12014            "ua": "winjs"
12015        },
12016        "requires": [
12017            "yql"
12018        ]
12019    },
12020    "yui": {},
12021    "yui-base": {},
12022    "yui-later": {
12023        "requires": [
12024            "yui-base"
12025        ]
12026    },
12027    "yui-log": {
12028        "requires": [
12029            "yui-base"
12030        ]
12031    },
12032    "yui-throttle": {
12033        "requires": [
12034            "yui-base"
12035        ]
12036    }
12037});
12038YUI.Env[Y.version].md5 = '95eb05a1b097773b5af03e0680e7dda4';
12039
12040
12041}, 'patched-v3.18.1', {"requires": ["loader-base"]});
12042YUI.add('yui', function (Y, NAME) {}, 'patched-v3.18.1', {
12043    "use": [
12044        "yui-base",
12045        "get",
12046        "features",
12047        "intl-base",
12048        "yui-log",
12049        "yui-later",
12050        "loader-base",
12051        "loader-rollup",
12052        "loader-yui3"
12053    ]
12054});
12055YUI.add('aui-base-core', function (A, NAME) {
12056
12057var Y = A;
12058YUI.Env.aliases = YUI.Env.aliases || {};
12059Y.mix(YUI.Env.aliases, {
12060    "aui-autosize": ["aui-autosize-iframe"],
12061    "aui-base": ["oop","yui-throttle","aui-classnamemanager","aui-debounce","aui-base-core","aui-base-lang","aui-node-base"],
12062    "aui-base-deprecated": ["aui-base","aui-node","aui-component","aui-delayed-task-deprecated","aui-selector","aui-event-base"],
12063    "aui-button": ["aui-button-core"],
12064    "aui-collection": ["aui-map","aui-set","aui-linkedset"],
12065    "aui-color-picker-deprecated": ["aui-color-picker-base-deprecated","aui-color-picker-grid-plugin-deprecated"],
12066    "aui-datasource-control-deprecated": ["aui-datasource-control-base-deprecated","aui-input-text-control-deprecated"],
12067    "aui-datatable": ["aui-datatable-edit","aui-datatable-highlight","aui-datatable-selection","aui-datatable-property-list"],
12068    "aui-datatable-edit": ["datatable-base","calendar","overlay","sortable","aui-datatype","aui-toolbar","aui-form-validator","aui-datatable-base-cell-editor","aui-datatable-base-options-cell-editor","aui-datatable-cell-editor-support","aui-datatable-core","aui-datatable-checkbox-cell-editor","aui-datatable-date-cell-editor","aui-datatable-dropdown-cell-editor","aui-datatable-radio-cell-editor","aui-datatable-text-cell-editor","aui-datatable-text-area-cell-editor"],
12069    "aui-datepicker-deprecated": ["aui-datepicker-base-deprecated","aui-datepicker-select-deprecated"],
12070    "aui-event": ["aui-event-base"],
12071    "aui-form-deprecated": ["aui-form-base-deprecated","aui-form-combobox-deprecated","aui-form-field-deprecated","aui-form-select-deprecated","aui-form-textarea-deprecated","aui-form-textfield-deprecated"],
12072    "aui-io": ["aui-io-request"],
12073    "aui-io-deprecated": ["aui-io-request","aui-io-plugin-deprecated"],
12074    "aui-node": ["aui-node-base"],
12075    "aui-overlay-deprecated": ["aui-overlay-base-deprecated","aui-overlay-context-deprecated","aui-overlay-context-panel-deprecated","aui-overlay-manager-deprecated","aui-overlay-mask-deprecated"],
12076    "aui-rating": ["aui-rating-base","aui-rating-thumb"],
12077    "aui-resize-deprecated": ["aui-resize-base-deprecated","aui-resize-constrain-deprecated"],
12078    "aui-scheduler": ["event-gestures","aui-scheduler-base","aui-scheduler-event-recorder","aui-scheduler-view-agenda","aui-scheduler-view-day","aui-scheduler-view-month","aui-scheduler-view-table-dd","aui-scheduler-view-table","aui-scheduler-view-week","aui-viewport"],
12079    "aui-search": ["aui-search-tst"],
12080    "aui-sortable": ["aui-sortable-layout","aui-sortable-list"],
12081    "aui-surface": ["aui-surface-app","aui-surface-screen"],
12082    "aui-toggler": ["aui-toggler-base","aui-toggler-delegate"],
12083    "aui-tooltip": ["aui-tooltip-base","aui-tooltip-delegate"],
12084    "aui-tpl-snippets-deprecated": ["aui-tpl-snippets-base-deprecated","aui-tpl-snippets-checkbox-deprecated","aui-tpl-snippets-input-deprecated","aui-tpl-snippets-select-deprecated","aui-tpl-snippets-textarea-deprecated"],
12085    "aui-tree": ["aui-tree-data","aui-tree-io","aui-tree-node","aui-tree-paginator","aui-tree-view"],
12086    "aui-widget": ["aui-widget-cssclass","aui-widget-toolbars"],
12087    "aui-widget-core": ["aui-widget-cssclass"]
12088});
12089/* This file is auto-generated by (yogi loader --yes --mix --js js/aui-loader.js --json js/aui-loader.json --start ../) */
12090
12091/*jshint maxlen:900, eqeqeq: false */
12092
12093/**
12094 * YUI 3 module metadata
12095 * @module loader
12096 * @submodule loader-yui3
12097 */
12098YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
12099Y.mix(YUI.Env[Y.version].modules, {
12100    "aui-ace-autocomplete-base": {
12101        "requires": [
12102            "aui-ace-editor"
12103        ]
12104    },
12105    "aui-ace-autocomplete-freemarker": {
12106        "requires": [
12107            "aui-ace-autocomplete-templateprocessor"
12108        ]
12109    },
12110    "aui-ace-autocomplete-list": {
12111        "requires": [
12112            "aui-ace-autocomplete-base",
12113            "overlay",
12114            "widget-autohide"
12115        ],
12116        "skinnable": true
12117    },
12118    "aui-ace-autocomplete-plugin": {
12119        "requires": [
12120            "aui-ace-autocomplete-list",
12121            "plugin"
12122        ]
12123    },
12124    "aui-ace-autocomplete-templateprocessor": {
12125        "requires": [
12126            "aui-ace-autocomplete-base"
12127        ]
12128    },
12129    "aui-ace-autocomplete-velocity": {
12130        "requires": [
12131            "aui-ace-autocomplete-templateprocessor"
12132        ]
12133    },
12134    "aui-ace-editor": {
12135        "requires": [
12136            "aui-node",
12137            "aui-component"
12138        ]
12139    },
12140    "aui-affix": {
12141        "requires": [
12142            "base",
12143            "node-screen",
12144            "aui-node"
12145        ]
12146    },
12147    "aui-alert": {
12148        "requires": [
12149            "aui-aria",
12150            "aui-classnamemanager",
12151            "aui-widget-cssclass",
12152            "aui-widget-transition",
12153            "timers",
12154            "widget",
12155            "widget-stdmod"
12156        ],
12157        "skinnable": true
12158    },
12159    "aui-aria": {
12160        "requires": [
12161            "plugin",
12162            "aui-component"
12163        ]
12164    },
12165    "aui-aria-table-sortable": {
12166        "requires": [
12167            "aui-aria"
12168        ]
12169    },
12170    "aui-arraysort": {
12171        "requires": [
12172            "arraysort"
12173        ]
12174    },
12175    "aui-audio": {
12176        "requires": [
12177            "aui-aria",
12178            "aui-node",
12179            "aui-component",
12180            "node-event-html5",
12181            "querystring-stringify-simple"
12182        ],
12183        "skinnable": true
12184    },
12185    "aui-autocomplete-deprecated": {
12186        "requires": [
12187            "aui-base-deprecated",
12188            "aui-overlay-base-deprecated",
12189            "datasource",
12190            "dataschema",
12191            "aui-form-combobox-deprecated"
12192        ],
12193        "skinnable": true
12194    },
12195    "aui-autosize": {
12196        "use": [
12197            "aui-autosize-iframe"
12198        ]
12199    },
12200    "aui-autosize-deprecated": {
12201        "requires": [
12202            "event-valuechange",
12203            "plugin",
12204            "aui-base-deprecated"
12205        ],
12206        "skinnable": true
12207    },
12208    "aui-autosize-iframe": {
12209        "requires": [
12210            "plugin",
12211            "aui-component",
12212            "aui-timer",
12213            "aui-node-base"
12214        ]
12215    },
12216    "aui-base": {
12217        "use": [
12218            "oop",
12219            "yui-throttle",
12220            "aui-classnamemanager",
12221            "aui-debounce",
12222            "aui-base-core",
12223            "aui-base-lang",
12224            "aui-node-base"
12225        ]
12226    },
12227    "aui-base-core": {},
12228    "aui-base-deprecated": {
12229        "use": [
12230            "aui-base",
12231            "aui-node",
12232            "aui-component",
12233            "aui-delayed-task-deprecated",
12234            "aui-selector",
12235            "aui-event-base"
12236        ]
12237    },
12238    "aui-base-html5-shiv": {
12239        "condition": {
12240            "name": "aui-base-html5-shiv",
12241            "trigger": "node-base",
12242            "ua": "ie"
12243        }
12244    },
12245    "aui-base-lang": {},
12246    "aui-boolean-data-editor": {
12247        "requires": [
12248            "aui-button-switch",
12249            "aui-data-editor"
12250        ]
12251    },
12252    "aui-button": {
12253        "use": [
12254            "aui-button-core"
12255        ]
12256    },
12257    "aui-button-core": {
12258        "requires": [
12259            "button",
12260            "button-group",
12261            "button-plugin",
12262            "aui-component",
12263            "aui-widget-cssclass",
12264            "aui-widget-toggle"
12265        ],
12266        "skinnable": true
12267    },
12268    "aui-button-item-deprecated": {
12269        "requires": [
12270            "aui-base-deprecated",
12271            "aui-state-interaction-deprecated",
12272            "widget-child"
12273        ],
12274        "skinnable": true
12275    },
12276    "aui-button-search-cancel": {
12277        "requires": [
12278            "array-invoke",
12279            "base",
12280            "base-build",
12281            "event-focus",
12282            "event-move",
12283            "event-resize",
12284            "node-screen",
12285            "node-event-delegate",
12286            "aui-node-base",
12287            "aui-classnamemanager",
12288            "aui-event-input"
12289        ]
12290    },
12291    "aui-button-switch": {
12292        "requires": [
12293            "aui-node-base",
12294            "base-build",
12295            "event-key",
12296            "transition",
12297            "widget"
12298        ],
12299        "skinnable": true
12300    },
12301    "aui-carousel": {
12302        "requires": [
12303            "anim",
12304            "aui-event",
12305            "aui-image-viewer-base",
12306            "aui-image-viewer-slideshow",
12307            "node-event-delegate",
12308            "node-focusmanager"
12309        ],
12310        "skinnable": true
12311    },
12312    "aui-carousel-mobile-touch": {
12313        "condition": {
12314            "name": "aui-carousel-mobile-touch",
12315            "test": function(A) {
12316    return A.UA.mobile && A.UA.touchEnabled;
12317},
12318            "trigger": "aui-carousel"
12319        },
12320        "requires": [
12321            "base-build",
12322            "aui-carousel"
12323        ]
12324    },
12325    "aui-carousel-swipe": {
12326        "condition": {
12327            "name": "aui-carousel-swipe",
12328            "trigger": "aui-carousel",
12329            "ua": "touchEnabled"
12330        },
12331        "requires": [
12332            "aui-carousel",
12333            "aui-widget-swipe",
12334            "base-build"
12335        ],
12336        "skinnable": true
12337    },
12338    "aui-char-counter": {
12339        "requires": [
12340            "aui-aria",
12341            "aui-node",
12342            "aui-event-input",
12343            "aui-component"
12344        ]
12345    },
12346    "aui-chart-deprecated": {
12347        "requires": [
12348            "datasource",
12349            "json",
12350            "aui-swf-deprecated"
12351        ]
12352    },
12353    "aui-classnamemanager": {
12354        "requires": [
12355            "classnamemanager"
12356        ]
12357    },
12358    "aui-collection": {
12359        "use": [
12360            "aui-map",
12361            "aui-set",
12362            "aui-linkedset"
12363        ]
12364    },
12365    "aui-color-palette": {
12366        "requires": [
12367            "array-extras",
12368            "aui-palette",
12369            "color-base",
12370            "node-core",
12371            "aui-widget-cssclass",
12372            "aui-widget-toggle"
12373        ],
12374        "skinnable": true
12375    },
12376    "aui-color-picker-base": {
12377        "requires": [
12378            "aui-color-palette",
12379            "aui-hsva-palette-modal",
12380            "event-outside"
12381        ],
12382        "skinnable": true
12383    },
12384    "aui-color-picker-base-deprecated": {
12385        "requires": [
12386            "dd-drag",
12387            "panel",
12388            "slider",
12389            "aui-button-item-deprecated",
12390            "aui-color-util-deprecated",
12391            "aui-form-base-deprecated",
12392            "aui-overlay-context-deprecated"
12393        ],
12394        "skinnable": true
12395    },
12396    "aui-color-picker-deprecated": {
12397        "use": [
12398            "aui-color-picker-base-deprecated",
12399            "aui-color-picker-grid-plugin-deprecated"
12400        ]
12401    },
12402    "aui-color-picker-grid-plugin-deprecated": {
12403        "requires": [
12404            "plugin",
12405            "aui-color-picker-base-deprecated"
12406        ],
12407        "skinnable": true
12408    },
12409    "aui-color-picker-popover": {
12410        "requires": [
12411            "aui-color-picker-base",
12412            "aui-popover",
12413            "aui-widget-cssclass",
12414            "aui-widget-toggle"
12415        ],
12416        "skinnable": true
12417    },
12418    "aui-color-util-deprecated": {
12419        "requires": []
12420    },
12421    "aui-component": {
12422        "requires": [
12423            "aui-classnamemanager",
12424            "aui-widget-cssclass",
12425            "aui-widget-toggle",
12426            "base-build",
12427            "widget-base"
12428        ]
12429    },
12430    "aui-css": {
12431        "type": "css"
12432    },
12433    "aui-data-editor": {
12434        "requires": [
12435            "aui-classnamemanager",
12436            "base-build",
12437            "node-base"
12438        ],
12439        "skinnable": true
12440    },
12441    "aui-data-set-deprecated": {
12442        "requires": [
12443            "oop",
12444            "collection",
12445            "base"
12446        ]
12447    },
12448    "aui-datasource-control-base-deprecated": {
12449        "requires": [
12450            "datasource",
12451            "dataschema",
12452            "aui-base-deprecated"
12453        ]
12454    },
12455    "aui-datasource-control-deprecated": {
12456        "use": [
12457            "aui-datasource-control-base-deprecated",
12458            "aui-input-text-control-deprecated"
12459        ]
12460    },
12461    "aui-datatable": {
12462        "use": [
12463            "aui-datatable-edit",
12464            "aui-datatable-highlight",
12465            "aui-datatable-selection",
12466            "aui-datatable-property-list"
12467        ]
12468    },
12469    "aui-datatable-base-cell-editor": {
12470        "requires": [
12471            "datatable-base",
12472            "overlay"
12473        ],
12474        "skinnable": true
12475    },
12476    "aui-datatable-base-options-cell-editor": {
12477        "requires": [
12478            "aui-datatable-base-cell-editor",
12479            "escape"
12480        ],
12481        "skinnable": true
12482    },
12483    "aui-datatable-body": {
12484        "requires": [
12485            "aui-classnamemanager",
12486            "datatable-base",
12487            "event-key",
12488            "aui-event-base"
12489        ]
12490    },
12491    "aui-datatable-cell-editor-support": {
12492        "requires": [
12493            "datatable-base"
12494        ]
12495    },
12496    "aui-datatable-checkbox-cell-editor": {
12497        "requires": [
12498            "aui-datatable-base-options-cell-editor"
12499        ]
12500    },
12501    "aui-datatable-core": {
12502        "requires": [
12503            "aui-datatable-body",
12504            "datatable-base",
12505            "event-key",
12506            "aui-event-base"
12507        ],
12508        "skinnable": true
12509    },
12510    "aui-datatable-date-cell-editor": {
12511        "requires": [
12512            "aui-datatable-base-options-cell-editor"
12513        ]
12514    },
12515    "aui-datatable-dropdown-cell-editor": {
12516        "requires": [
12517            "aui-datatable-base-options-cell-editor"
12518        ]
12519    },
12520    "aui-datatable-edit": {
12521        "use": [
12522            "datatable-base",
12523            "calendar",
12524            "overlay",
12525            "sortable",
12526            "aui-datatype",
12527            "aui-toolbar",
12528            "aui-form-validator",
12529            "aui-datatable-base-cell-editor",
12530            "aui-datatable-base-options-cell-editor",
12531            "aui-datatable-cell-editor-support",
12532            "aui-datatable-core",
12533            "aui-datatable-checkbox-cell-editor",
12534            "aui-datatable-date-cell-editor",
12535            "aui-datatable-dropdown-cell-editor",
12536            "aui-datatable-radio-cell-editor",
12537            "aui-datatable-text-cell-editor",
12538            "aui-datatable-text-area-cell-editor"
12539        ]
12540    },
12541    "aui-datatable-highlight": {
12542        "requires": [
12543            "aui-datatable-selection"
12544        ],
12545        "skinnable": true
12546    },
12547    "aui-datatable-property-list": {
12548        "requires": [
12549            "datatable-scroll",
12550            "datatable-sort",
12551            "aui-datatable-core",
12552            "aui-datatable-edit",
12553            "aui-datatable-highlight",
12554            "aui-datatable-selection",
12555            "aui-widget-cssclass",
12556            "aui-widget-toggle"
12557        ],
12558        "skinnable": true
12559    },
12560    "aui-datatable-radio-cell-editor": {
12561        "requires": [
12562            "aui-datatable-base-options-cell-editor"
12563        ]
12564    },
12565    "aui-datatable-selection": {
12566        "requires": [
12567            "aui-datatable-core"
12568        ],
12569        "skinnable": true
12570    },
12571    "aui-datatable-text-area-cell-editor": {
12572        "requires": [
12573            "aui-datatable-base-options-cell-editor"
12574        ]
12575    },
12576    "aui-datatable-text-cell-editor": {
12577        "requires": [
12578            "aui-datatable-base-options-cell-editor"
12579        ]
12580    },
12581    "aui-datatype": {
12582        "requires": [
12583            "datatype",
12584            "aui-datatype-date-parse"
12585        ]
12586    },
12587    "aui-datatype-date-parse": {
12588        "requires": [
12589            "aui-base-lang",
12590            "datatype-date-format",
12591            "datatype-date-parse",
12592            "intl"
12593        ]
12594    },
12595    "aui-datepicker": {
12596        "requires": [
12597            "aui-aria",
12598            "aui-datepicker-delegate",
12599            "aui-datepicker-popover",
12600            "base",
12601            "base-build",
12602            "calendar"
12603        ],
12604        "skinnable": true
12605    },
12606    "aui-datepicker-base-deprecated": {
12607        "requires": [
12608            "calendar",
12609            "aui-datatype",
12610            "aui-overlay-context-deprecated"
12611        ],
12612        "skinnable": true
12613    },
12614    "aui-datepicker-delegate": {
12615        "requires": [
12616            "aui-datatype-date-parse",
12617            "aui-event-input",
12618            "event-focus",
12619            "node-event-delegate"
12620        ]
12621    },
12622    "aui-datepicker-deprecated": {
12623        "skinnable": true,
12624        "use": [
12625            "aui-datepicker-base-deprecated",
12626            "aui-datepicker-select-deprecated"
12627        ]
12628    },
12629    "aui-datepicker-native": {
12630        "requires": [
12631            "aui-datepicker-delegate",
12632            "aui-node-base",
12633            "base",
12634            "base-build"
12635        ]
12636    },
12637    "aui-datepicker-popover": {
12638        "requires": [
12639            "aui-classnamemanager",
12640            "aui-popover"
12641        ]
12642    },
12643    "aui-datepicker-select-deprecated": {
12644        "requires": [
12645            "aui-datepicker-base-deprecated",
12646            "aui-button-item-deprecated"
12647        ],
12648        "skinnable": true
12649    },
12650    "aui-debounce": {},
12651    "aui-delayed-task-deprecated": {
12652        "requires": [
12653            "yui-base"
12654        ]
12655    },
12656    "aui-diagram-builder": {
12657        "requires": [
12658            "aui-aria",
12659            "aui-map",
12660            "aui-property-builder",
12661            "aui-diagram-builder-connector",
12662            "aui-property-builder-settings",
12663            "aui-diagram-node-condition",
12664            "aui-diagram-node-end",
12665            "aui-diagram-node-fork",
12666            "aui-diagram-node-join",
12667            "aui-diagram-node-start",
12668            "aui-diagram-node-state",
12669            "aui-diagram-node-task",
12670            "overlay"
12671        ],
12672        "skinnable": true
12673    },
12674    "aui-diagram-builder-connector": {
12675        "requires": [
12676            "arraylist-add",
12677            "arraylist-filter",
12678            "escape",
12679            "json",
12680            "graphics",
12681            "dd"
12682        ],
12683        "skinnable": true
12684    },
12685    "aui-diagram-node": {
12686        "requires": [
12687            "aui-aria",
12688            "aui-diagram-node-manager-base",
12689            "escape",
12690            "overlay"
12691        ]
12692    },
12693    "aui-diagram-node-condition": {
12694        "requires": [
12695            "aui-diagram-node-state"
12696        ]
12697    },
12698    "aui-diagram-node-end": {
12699        "requires": [
12700            "aui-diagram-node-state"
12701        ]
12702    },
12703    "aui-diagram-node-fork": {
12704        "requires": [
12705            "aui-diagram-node-state"
12706        ]
12707    },
12708    "aui-diagram-node-join": {
12709        "requires": [
12710            "aui-diagram-node-state"
12711        ]
12712    },
12713    "aui-diagram-node-manager-base": {
12714        "requires": [
12715            "base"
12716        ]
12717    },
12718    "aui-diagram-node-start": {
12719        "requires": [
12720            "aui-diagram-node-state"
12721        ]
12722    },
12723    "aui-diagram-node-state": {
12724        "requires": [
12725            "aui-diagram-node"
12726        ]
12727    },
12728    "aui-diagram-node-task": {
12729        "requires": [
12730            "aui-diagram-node-state"
12731        ]
12732    },
12733    "aui-dialog-iframe-deprecated": {
12734        "requires": [
12735            "plugin",
12736            "array-invoke",
12737            "aui-base-deprecated",
12738            "aui-loading-mask-deprecated"
12739        ],
12740        "skinnable": true
12741    },
12742    "aui-dropdown": {
12743        "requires": [
12744            "event-delegate",
12745            "event-key",
12746            "event-outside",
12747            "node-focusmanager",
12748            "widget",
12749            "widget-stack",
12750            "aui-classnamemanager",
12751            "aui-node",
12752            "aui-widget-cssclass",
12753            "aui-widget-toggle",
12754            "aui-widget-trigger"
12755        ],
12756        "skinnable": true
12757    },
12758    "aui-editable-deprecated": {
12759        "requires": [
12760            "aui-base-deprecated",
12761            "aui-form-combobox-deprecated",
12762            "escape",
12763            "event-resize"
12764        ],
12765        "skinnable": true
12766    },
12767    "aui-event": {
12768        "use": [
12769            "aui-event-base"
12770        ]
12771    },
12772    "aui-event-base": {
12773        "requires": [
12774            "event-base"
12775        ]
12776    },
12777    "aui-event-delegate-change": {
12778        "condition": {
12779            "name": "aui-event-delegate-change",
12780            "trigger": "event-base-ie",
12781            "ua": "ie"
12782        },
12783        "requires": [
12784            "aui-event-base",
12785            "event-delegate",
12786            "event-synthetic"
12787        ]
12788    },
12789    "aui-event-delegate-submit": {
12790        "condition": {
12791            "name": "aui-event-delegate-submit",
12792            "trigger": "event-base-ie",
12793            "ua": "ie"
12794        },
12795        "requires": [
12796            "aui-event-base",
12797            "event-delegate",
12798            "event-synthetic"
12799        ]
12800    },
12801    "aui-event-input": {
12802        "condition": {
12803            "name": "aui-event-input",
12804            "test": function(A) {
12805    var supportsDOMEvent = A.supportsDOMEvent,
12806        testFeature = A.Features.test,
12807        addFeature = A.Features.add;
12808
12809    if (testFeature('event', 'input') === undefined) {
12810        addFeature('event', 'input', {
12811            test: function() {
12812                return supportsDOMEvent(document.createElement('textarea'), 'input') && (!A.UA.ie || A.UA.ie > 9);
12813            }
12814        });
12815    }
12816
12817    return !testFeature('event', 'input');
12818},
12819            "trigger": "aui-event-base"
12820        },
12821        "requires": [
12822            "aui-event-base",
12823            "event-delegate",
12824            "event-synthetic",
12825            "timers"
12826        ]
12827    },
12828    "aui-form-base-deprecated": {
12829        "requires": [
12830            "io-form",
12831            "querystring-parse",
12832            "aui-base-deprecated",
12833            "aui-data-set-deprecated",
12834            "aui-form-field-deprecated"
12835        ]
12836    },
12837    "aui-form-builder": {
12838        "requires": [
12839            "aui-modal",
12840            "aui-layout",
12841            "aui-form-builder-field-list",
12842            "aui-form-builder-field-toolbar",
12843            "aui-form-builder-field-type",
12844            "aui-form-builder-field-types",
12845            "aui-form-builder-layout-builder",
12846            "aui-form-builder-page-manager",
12847            "aui-form-builder-settings-modal",
12848            "event-focus",
12849            "event-tap"
12850        ],
12851        "skinnable": true
12852    },
12853    "aui-form-builder-available-field-deprecated": {
12854        "requires": [
12855            "aui-property-builder-available-field"
12856        ]
12857    },
12858    "aui-form-builder-deprecated": {
12859        "requires": [
12860            "aui-button",
12861            "aui-collection",
12862            "aui-form-builder-available-field-deprecated",
12863            "aui-form-builder-field-deprecated",
12864            "aui-form-builder-field-button-deprecated",
12865            "aui-form-builder-field-checkbox-deprecated",
12866            "aui-form-builder-field-fieldset-deprecated",
12867            "aui-form-builder-field-file-upload-deprecated",
12868            "aui-form-builder-field-multiple-choice-deprecated",
12869            "aui-form-builder-field-radio-deprecated",
12870            "aui-form-builder-field-select-deprecated",
12871            "aui-form-builder-field-text-deprecated",
12872            "aui-form-builder-field-textarea-deprecated",
12873            "aui-property-builder",
12874            "aui-property-builder-settings",
12875            "aui-sortable-list",
12876            "aui-tabview",
12877            "aui-tooltip-base",
12878            "escape",
12879            "transition"
12880        ],
12881        "skinnable": true
12882    },
12883    "aui-form-builder-field-base": {
12884        "requires": [
12885            "aui-classnamemanager",
12886            "aui-node-base",
12887            "aui-text-data-editor",
12888            "aui-toggler",
12889            "base",
12890            "node-base"
12891        ],
12892        "skinnable": true
12893    },
12894    "aui-form-builder-field-button-deprecated": {
12895        "requires": [
12896            "aui-form-builder-field-deprecated"
12897        ]
12898    },
12899    "aui-form-builder-field-checkbox-deprecated": {
12900        "requires": [
12901            "aui-form-builder-field-deprecated"
12902        ]
12903    },
12904    "aui-form-builder-field-choice": {
12905        "requires": [
12906            "aui-boolean-data-editor",
12907            "aui-options-data-editor",
12908            "aui-tabs-data-editor",
12909            "aui-form-builder-field-base",
12910            "aui-form-field-choice"
12911        ]
12912    },
12913    "aui-form-builder-field-deprecated": {
12914        "requires": [
12915            "panel",
12916            "aui-datatype",
12917            "aui-datatable-edit",
12918            "aui-property-builder-field-support"
12919        ],
12920        "skinnable": true
12921    },
12922    "aui-form-builder-field-fieldset-deprecated": {
12923        "requires": [
12924            "aui-form-builder-field-deprecated"
12925        ]
12926    },
12927    "aui-form-builder-field-file-upload-deprecated": {
12928        "requires": [
12929            "aui-form-builder-field-deprecated"
12930        ]
12931    },
12932    "aui-form-builder-field-list": {
12933        "requires": [
12934            "aui-form-builder-field-type",
12935            "aui-form-builder-field-types",
12936            "aui-form-builder-layout-builder"
12937        ],
12938        "skinnable": true
12939    },
12940    "aui-form-builder-field-multiple-choice-deprecated": {
12941        "requires": [
12942            "aui-form-builder-field-deprecated"
12943        ]
12944    },
12945    "aui-form-builder-field-radio-deprecated": {
12946        "requires": [
12947            "aui-form-builder-field-deprecated"
12948        ]
12949    },
12950    "aui-form-builder-field-select-deprecated": {
12951        "requires": [
12952            "aui-form-builder-field-deprecated"
12953        ]
12954    },
12955    "aui-form-builder-field-sentence": {
12956        "requires": [
12957            "aui-form-builder-field-base",
12958            "aui-form-field"
12959        ]
12960    },
12961    "aui-form-builder-field-text": {
12962        "requires": [
12963            "aui-boolean-data-editor",
12964            "aui-radio-group-data-editor",
12965            "aui-form-builder-field-base",
12966            "aui-form-field-text"
12967        ]
12968    },
12969    "aui-form-builder-field-text-deprecated": {
12970        "requires": [
12971            "aui-form-builder-field-deprecated"
12972        ]
12973    },
12974    "aui-form-builder-field-textarea-deprecated": {
12975        "requires": [
12976            "aui-form-builder-field-deprecated"
12977        ]
12978    },
12979    "aui-form-builder-field-toolbar": {
12980        "requires": [
12981            "aui-classnamemanager",
12982            "base",
12983            "node-base"
12984        ],
12985        "skinnable": true
12986    },
12987    "aui-form-builder-field-type": {
12988        "requires": [
12989            "base",
12990            "node-base"
12991        ],
12992        "skinnable": true
12993    },
12994    "aui-form-builder-field-types": {
12995        "requires": [
12996            "aui-classnamemanager",
12997            "aui-form-builder-field-types-modal",
12998            "base",
12999            "node-base"
13000        ],
13001        "skinnable": true
13002    },
13003    "aui-form-builder-field-types-modal": {
13004        "requires": [
13005            "aui-modal"
13006        ],
13007        "skinnable": true
13008    },
13009    "aui-form-builder-layout-builder": {
13010        "requires": [
13011            "aui-classnamemanager",
13012            "aui-layout-builder",
13013            "aui-modal",
13014            "base",
13015            "node-base"
13016        ],
13017        "skinnable": true
13018    },
13019    "aui-form-builder-page-manager": {
13020        "requires": [
13021            "aui-pagination",
13022            "aui-popover",
13023            "aui-tabview",
13024            "base",
13025            "event-valuechange",
13026            "node-base"
13027        ],
13028        "skinnable": true
13029    },
13030    "aui-form-builder-settings-modal": {
13031        "requires": [
13032            "aui-classnamemanager",
13033            "aui-modal",
13034            "base",
13035            "node-base"
13036        ],
13037        "skinnable": true
13038    },
13039    "aui-form-combobox-deprecated": {
13040        "requires": [
13041            "aui-form-textarea-deprecated",
13042            "aui-toolbar"
13043        ],
13044        "skinnable": true
13045    },
13046    "aui-form-deprecated": {
13047        "use": [
13048            "aui-form-base-deprecated",
13049            "aui-form-combobox-deprecated",
13050            "aui-form-field-deprecated",
13051            "aui-form-select-deprecated",
13052            "aui-form-textarea-deprecated",
13053            "aui-form-textfield-deprecated"
13054        ]
13055    },
13056    "aui-form-field": {
13057        "requires": [
13058            "aui-classnamemanager",
13059            "aui-node-base",
13060            "base-build"
13061        ],
13062        "skinnable": true
13063    },
13064    "aui-form-field-choice": {
13065        "requires": [
13066            "aui-form-field-required"
13067        ],
13068        "skinnable": true
13069    },
13070    "aui-form-field-deprecated": {
13071        "requires": [
13072            "aui-base-deprecated",
13073            "aui-component"
13074        ]
13075    },
13076    "aui-form-field-required": {
13077        "requires": [
13078            "aui-form-field"
13079        ]
13080    },
13081    "aui-form-field-text": {
13082        "requires": [
13083            "aui-form-field-required"
13084        ],
13085        "skinnable": true
13086    },
13087    "aui-form-select-deprecated": {
13088        "requires": [
13089            "aui-form-field-deprecated"
13090        ]
13091    },
13092    "aui-form-textarea-deprecated": {
13093        "requires": [
13094            "node-pluginhost",
13095            "aui-autosize-deprecated",
13096            "aui-form-textfield-deprecated"
13097        ]
13098    },
13099    "aui-form-textfield-deprecated": {
13100        "requires": [
13101            "aui-form-field-deprecated"
13102        ]
13103    },
13104    "aui-form-validator": {
13105        "requires": [
13106            "escape",
13107            "selector-css3",
13108            "node-event-delegate",
13109            "aui-node",
13110            "aui-component",
13111            "aui-event-input"
13112        ]
13113    },
13114    "aui-hsv-palette": {
13115        "requires": [
13116            "aui-classnamemanager",
13117            "aui-widget-cssclass",
13118            "aui-widget-toggle",
13119            "aui-event-input",
13120            "base-build",
13121            "clickable-rail",
13122            "color-hsv",
13123            "dd-constrain",
13124            "slider",
13125            "widget"
13126        ],
13127        "skinnable": true
13128    },
13129    "aui-hsva-palette": {
13130        "requires": [
13131            "aui-hsv-palette"
13132        ],
13133        "skinnable": true
13134    },
13135    "aui-hsva-palette-modal": {
13136        "requires": [
13137            "aui-hsva-palette",
13138            "aui-modal"
13139        ],
13140        "skinnable": true
13141    },
13142    "aui-image-cropper": {
13143        "requires": [
13144            "resize-base",
13145            "resize-constrain",
13146            "dd-constrain",
13147            "aui-node-base",
13148            "aui-component"
13149        ],
13150        "skinnable": true
13151    },
13152    "aui-image-viewer": {
13153        "requires": [
13154            "widget",
13155            "widget-modality",
13156            "widget-position",
13157            "widget-position-align",
13158            "widget-position-constrain",
13159            "widget-stack",
13160            "widget-stdmod",
13161            "aui-event",
13162            "aui-image-viewer-base",
13163            "aui-image-viewer-multiple",
13164            "aui-image-viewer-slideshow",
13165            "aui-node-base",
13166            "aui-widget-cssclass",
13167            "aui-widget-toggle"
13168        ],
13169        "skinnable": true
13170    },
13171    "aui-image-viewer-base": {
13172        "requires": [
13173            "anim",
13174            "aui-aria",
13175            "aui-classnamemanager",
13176            "aui-node",
13177            "aui-widget-responsive",
13178            "base-build",
13179            "imageloader",
13180            "node-base",
13181            "widget",
13182            "widget-stack"
13183        ],
13184        "skinnable": true
13185    },
13186    "aui-image-viewer-media": {
13187        "requires": [
13188            "plugin",
13189            "aui-component",
13190            "aui-image-viewer"
13191        ]
13192    },
13193    "aui-image-viewer-multiple": {
13194        "requires": [
13195            "base-build",
13196            "node-base",
13197            "aui-classnamemanager",
13198            "aui-image-viewer-base"
13199        ],
13200        "skinnable": true
13201    },
13202    "aui-image-viewer-multiple-swipe": {
13203        "condition": {
13204            "name": "aui-image-viewer-multiple-swipe",
13205            "trigger": "aui-image-viewer-multiple",
13206            "ua": "touchEnabled"
13207        },
13208        "requires": [
13209            "aui-image-viewer-multiple",
13210            "aui-image-viewer-swipe"
13211        ]
13212    },
13213    "aui-image-viewer-slideshow": {
13214        "requires": [
13215            "node",
13216            "aui-classnamemanager"
13217        ]
13218    },
13219    "aui-image-viewer-swipe": {
13220        "condition": {
13221            "name": "aui-image-viewer-swipe",
13222            "trigger": "aui-image-viewer-base",
13223            "ua": "touchEnabled"
13224        },
13225        "requires": [
13226            "event-resize",
13227            "aui-image-viewer-base",
13228            "aui-widget-swipe"
13229        ]
13230    },
13231    "aui-input-text-control-deprecated": {
13232        "requires": [
13233            "aui-base-deprecated",
13234            "aui-datasource-control-base-deprecated",
13235            "aui-form-combobox-deprecated"
13236        ]
13237    },
13238    "aui-io": {
13239        "use": [
13240            "aui-io-request"
13241        ]
13242    },
13243    "aui-io-deprecated": {
13244        "use": [
13245            "aui-io-request",
13246            "aui-io-plugin-deprecated"
13247        ]
13248    },
13249    "aui-io-plugin-deprecated": {
13250        "requires": [
13251            "aui-overlay-base-deprecated",
13252            "aui-parse-content",
13253            "aui-io-request",
13254            "aui-loading-mask-deprecated"
13255        ]
13256    },
13257    "aui-io-request": {
13258        "requires": [
13259            "io-base",
13260            "json",
13261            "plugin",
13262            "querystring-stringify",
13263            "aui-component"
13264        ]
13265    },
13266    "aui-io-request-deprecated": {
13267        "requires": [
13268            "io-base",
13269            "json",
13270            "plugin",
13271            "querystring-stringify",
13272            "aui-base-deprecated"
13273        ]
13274    },
13275    "aui-layout": {
13276        "requires": [
13277            "aui-layout-col",
13278            "aui-layout-row",
13279            "aui-node-base",
13280            "base-build",
13281            "datatype-number-parse",
13282            "event-resize"
13283        ]
13284    },
13285    "aui-layout-builder": {
13286        "requires": [
13287            "aui-classnamemanager",
13288            "aui-layout",
13289            "aui-layout-builder-add-col",
13290            "aui-layout-builder-add-row",
13291            "aui-layout-builder-move",
13292            "aui-layout-builder-remove-row",
13293            "aui-layout-builder-resize-col",
13294            "aui-node-base",
13295            "base-build",
13296            "node-event-delegate",
13297            "node-screen",
13298            "node-style"
13299        ]
13300    },
13301    "aui-layout-builder-add-col": {
13302        "requires": [
13303            "event-key",
13304            "node-base"
13305        ],
13306        "skinnable": true
13307    },
13308    "aui-layout-builder-add-row": {
13309        "requires": [
13310            "aui-node-base",
13311            "base-build",
13312            "node-scroll-info"
13313        ],
13314        "skinnable": true
13315    },
13316    "aui-layout-builder-move": {
13317        "requires": [
13318            "aui-node-base",
13319            "base-build"
13320        ],
13321        "skinnable": true
13322    },
13323    "aui-layout-builder-remove-row": {
13324        "requires": [
13325            "aui-node-base",
13326            "base-build"
13327        ],
13328        "skinnable": true
13329    },
13330    "aui-layout-builder-resize-col": {
13331        "requires": [
13332            "dd-constrain",
13333            "dd-delegate",
13334            "dd-drop-plugin",
13335            "dd-proxy",
13336            "event-mouseenter",
13337            "node-base"
13338        ],
13339        "skinnable": true
13340    },
13341    "aui-layout-col": {
13342        "requires": [
13343            "aui-classnamemanager",
13344            "aui-node-base",
13345            "base-build"
13346        ],
13347        "skinnable": true
13348    },
13349    "aui-layout-row": {
13350        "requires": [
13351            "array-invoke",
13352            "aui-node-base",
13353            "base-build"
13354        ],
13355        "skinnable": true
13356    },
13357    "aui-linkedset": {
13358        "requires": [
13359            "aui-set"
13360        ]
13361    },
13362    "aui-live-search-deprecated": {
13363        "requires": [
13364            "aui-base-deprecated"
13365        ]
13366    },
13367    "aui-loading-mask-deprecated": {
13368        "requires": [
13369            "plugin",
13370            "aui-overlay-mask-deprecated"
13371        ],
13372        "skinnable": true
13373    },
13374    "aui-map": {
13375        "requires": [
13376            "base-build"
13377        ]
13378    },
13379    "aui-menu": {
13380        "requires": [
13381            "base-build",
13382            "event-mouseenter",
13383            "event-resize",
13384            "widget",
13385            "widget-position",
13386            "widget-position-align",
13387            "widget-position-constrain",
13388            "widget-stack",
13389            "aui-classnamemanager",
13390            "aui-debounce",
13391            "aui-dropdown",
13392            "aui-menu-item"
13393        ],
13394        "skinnable": true
13395    },
13396    "aui-menu-item": {
13397        "requires": [
13398            "base-build",
13399            "node-base",
13400            "aui-classnamemanager",
13401            "aui-node",
13402            "aui-widget-shortcut"
13403        ]
13404    },
13405    "aui-messaging": {
13406        "requires": [
13407            "querystring",
13408            "aui-timer"
13409        ]
13410    },
13411    "aui-modal": {
13412        "requires": [
13413            "widget",
13414            "widget-autohide",
13415            "widget-buttons",
13416            "widget-modality",
13417            "widget-position",
13418            "widget-position-align",
13419            "widget-position-constrain",
13420            "widget-stack",
13421            "widget-stdmod",
13422            "dd-plugin",
13423            "dd-constrain",
13424            "timers",
13425            "aui-classnamemanager",
13426            "aui-widget-cssclass",
13427            "aui-widget-toggle",
13428            "aui-widget-toolbars"
13429        ],
13430        "skinnable": true
13431    },
13432    "aui-modal-resize": {
13433        "condition": {
13434            "name": "aui-modal-resize",
13435            "test": function(A) {
13436    return !A.UA.mobile;
13437},
13438            "trigger": "aui-modal"
13439        },
13440        "requires": [
13441            "aui-modal",
13442            "resize-plugin"
13443        ]
13444    },
13445    "aui-node": {
13446        "use": [
13447            "aui-node-base"
13448        ]
13449    },
13450    "aui-node-accessible": {
13451        "requires": [
13452            "aui-node-base",
13453            "event-custom-base"
13454        ]
13455    },
13456    "aui-node-base": {
13457        "requires": [
13458            "array-extras",
13459            "aui-base-lang",
13460            "aui-classnamemanager",
13461            "aui-debounce",
13462            "node"
13463        ]
13464    },
13465    "aui-node-html5": {
13466        "condition": {
13467            "name": "aui-node-html5",
13468            "trigger": "aui-node",
13469            "ua": "ie"
13470        },
13471        "requires": [
13472            "collection",
13473            "aui-node-base"
13474        ]
13475    },
13476    "aui-options-data-editor": {
13477        "requires": [
13478            "aui-data-editor",
13479            "dd-constrain",
13480            "dd-delegate",
13481            "dd-drop-plugin",
13482            "dd-proxy",
13483            "event-valuechange",
13484            "node-event-delegate"
13485        ],
13486        "skinnable": true
13487    },
13488    "aui-overlay-base-deprecated": {
13489        "requires": [
13490            "widget-position",
13491            "widget-stack",
13492            "widget-position-align",
13493            "widget-position-constrain",
13494            "widget-stdmod",
13495            "aui-component"
13496        ]
13497    },
13498    "aui-overlay-context-deprecated": {
13499        "requires": [
13500            "aui-overlay-manager-deprecated",
13501            "aui-delayed-task-deprecated",
13502            "aui-aria"
13503        ]
13504    },
13505    "aui-overlay-context-panel-deprecated": {
13506        "requires": [
13507            "anim",
13508            "aui-overlay-context-deprecated"
13509        ],
13510        "skinnable": true
13511    },
13512    "aui-overlay-deprecated": {
13513        "use": [
13514            "aui-overlay-base-deprecated",
13515            "aui-overlay-context-deprecated",
13516            "aui-overlay-context-panel-deprecated",
13517            "aui-overlay-manager-deprecated",
13518            "aui-overlay-mask-deprecated"
13519        ]
13520    },
13521    "aui-overlay-manager-deprecated": {
13522        "requires": [
13523            "overlay",
13524            "plugin",
13525            "aui-base-deprecated",
13526            "aui-overlay-base-deprecated"
13527        ]
13528    },
13529    "aui-overlay-mask-deprecated": {
13530        "requires": [
13531            "event-resize",
13532            "aui-base-deprecated",
13533            "aui-overlay-base-deprecated"
13534        ],
13535        "skinnable": true
13536    },
13537    "aui-pagination": {
13538        "requires": [
13539            "node-event-delegate",
13540            "aui-node",
13541            "aui-component",
13542            "widget-htmlparser"
13543        ],
13544        "skinnable": true
13545    },
13546    "aui-palette": {
13547        "requires": [
13548            "base-build",
13549            "event-hover",
13550            "widget",
13551            "aui-classnamemanager",
13552            "aui-base",
13553            "aui-widget-cssclass",
13554            "aui-widget-toggle"
13555        ],
13556        "skinnable": true
13557    },
13558    "aui-parse-content": {
13559        "requires": [
13560            "async-queue",
13561            "plugin",
13562            "io-base",
13563            "aui-component",
13564            "aui-node-base"
13565        ]
13566    },
13567    "aui-popover": {
13568        "requires": [
13569            "event-resize",
13570            "widget",
13571            "widget-autohide",
13572            "widget-buttons",
13573            "widget-modality",
13574            "widget-position",
13575            "widget-position-align",
13576            "widget-position-constrain",
13577            "widget-stack",
13578            "widget-stdmod",
13579            "aui-classnamemanager",
13580            "aui-widget-cssclass",
13581            "aui-widget-toggle",
13582            "aui-widget-toolbars",
13583            "aui-widget-transition",
13584            "aui-widget-trigger",
13585            "aui-widget-position-align-suggestion",
13586            "aui-component",
13587            "aui-node-base"
13588        ],
13589        "skinnable": true
13590    },
13591    "aui-progressbar": {
13592        "requires": [
13593            "aui-node",
13594            "aui-component",
13595            "aui-aria"
13596        ],
13597        "skinnable": true
13598    },
13599    "aui-promise": {
13600        "requires": [
13601            "array-invoke",
13602            "promise",
13603            "oop"
13604        ]
13605    },
13606    "aui-property-builder": {
13607        "requires": [
13608            "dd",
13609            "collection",
13610            "aui-property-builder-available-field",
13611            "aui-property-builder-field-support",
13612            "aui-property-builder-settings",
13613            "aui-tabview"
13614        ],
13615        "skinnable": true
13616    },
13617    "aui-property-builder-available-field": {
13618        "requires": [
13619            "base",
13620            "aui-component",
13621            "aui-node"
13622        ]
13623    },
13624    "aui-property-builder-field-support": {},
13625    "aui-property-builder-settings": {
13626        "requires": [
13627            "aui-tabview",
13628            "aui-datatable-property-list"
13629        ]
13630    },
13631    "aui-radio-group-data-editor": {
13632        "requires": [
13633            "aui-data-editor",
13634            "node-event-delegate"
13635        ],
13636        "skinnable": true
13637    },
13638    "aui-rating": {
13639        "use": [
13640            "aui-rating-base",
13641            "aui-rating-thumb"
13642        ]
13643    },
13644    "aui-rating-base": {
13645        "requires": [
13646            "aui-component",
13647            "aui-node-base",
13648            "widget-htmlparser",
13649            "widget-uievents"
13650        ],
13651        "skinnable": true
13652    },
13653    "aui-rating-thumb": {
13654        "requires": [
13655            "aui-rating-base"
13656        ]
13657    },
13658    "aui-resize-base-deprecated": {
13659        "requires": [
13660            "dd-drag",
13661            "dd-delegate",
13662            "dd-drop",
13663            "aui-base-deprecated"
13664        ],
13665        "skinnable": true
13666    },
13667    "aui-resize-constrain-deprecated": {
13668        "requires": [
13669            "dd-constrain",
13670            "plugin",
13671            "aui-resize-base-deprecated"
13672        ]
13673    },
13674    "aui-resize-deprecated": {
13675        "skinnable": true,
13676        "use": [
13677            "aui-resize-base-deprecated",
13678            "aui-resize-constrain-deprecated"
13679        ]
13680    },
13681    "aui-scale-data-editor": {
13682        "requires": [
13683            "aui-classnamemanager",
13684            "aui-data-editor",
13685            "event-valuechange"
13686        ]
13687    },
13688    "aui-scheduler": {
13689        "use": [
13690            "event-gestures",
13691            "aui-scheduler-base",
13692            "aui-scheduler-event-recorder",
13693            "aui-scheduler-view-agenda",
13694            "aui-scheduler-view-day",
13695            "aui-scheduler-view-month",
13696            "aui-scheduler-view-table-dd",
13697            "aui-scheduler-view-table",
13698            "aui-scheduler-view-week",
13699            "aui-viewport"
13700        ]
13701    },
13702    "aui-scheduler-base": {
13703        "requires": [
13704            "model",
13705            "model-list",
13706            "widget-stdmod",
13707            "color-hsl",
13708            "aui-event-base",
13709            "aui-node-base",
13710            "aui-component",
13711            "aui-datatype",
13712            "aui-button",
13713            "node-focusmanager"
13714        ],
13715        "skinnable": true
13716    },
13717    "aui-scheduler-event-recorder": {
13718        "requires": [
13719            "querystring",
13720            "io-form",
13721            "overlay",
13722            "aui-scheduler-base",
13723            "aui-popover"
13724        ],
13725        "skinnable": true
13726    },
13727    "aui-scheduler-touch": {
13728        "condition": {
13729            "name": "aui-scheduler-touch",
13730            "trigger": "aui-scheduler",
13731            "ua": "touchEnabled"
13732        },
13733        "requires": [
13734            "base-build",
13735            "aui-scheduler"
13736        ],
13737        "skinnable": true
13738    },
13739    "aui-scheduler-view-agenda": {
13740        "requires": [
13741            "aui-scheduler-base"
13742        ],
13743        "skinnable": true
13744    },
13745    "aui-scheduler-view-day": {
13746        "requires": [
13747            "dd-drag",
13748            "dd-delegate",
13749            "dd-drop",
13750            "dd-constrain",
13751            "aui-scheduler-view-table"
13752        ],
13753        "skinnable": true
13754    },
13755    "aui-scheduler-view-month": {
13756        "requires": [
13757            "aui-scheduler-view-table"
13758        ],
13759        "skinnable": true
13760    },
13761    "aui-scheduler-view-table": {
13762        "requires": [
13763            "overlay",
13764            "aui-scheduler-base"
13765        ],
13766        "skinnable": true
13767    },
13768    "aui-scheduler-view-table-dd": {
13769        "requires": [
13770            "dd-drag",
13771            "dd-delegate",
13772            "dd-drop",
13773            "aui-scheduler-view-table"
13774        ]
13775    },
13776    "aui-scheduler-view-week": {
13777        "requires": [
13778            "aui-scheduler-view-day"
13779        ],
13780        "skinnable": true
13781    },
13782    "aui-scroller-deprecated": {
13783        "requires": [
13784            "event-mouseenter",
13785            "aui-base-deprecated",
13786            "aui-simple-anim-deprecated"
13787        ],
13788        "skinnable": true
13789    },
13790    "aui-scrollspy": {
13791        "requires": [
13792            "base-build",
13793            "node-screen",
13794            "aui-classnamemanager"
13795        ]
13796    },
13797    "aui-search": {
13798        "use": [
13799            "aui-search-tst"
13800        ]
13801    },
13802    "aui-search-tst": {
13803        "requires": [
13804            "aui-component"
13805        ]
13806    },
13807    "aui-selector": {
13808        "requires": [
13809            "selector-css3",
13810            "aui-classnamemanager"
13811        ]
13812    },
13813    "aui-set": {
13814        "requires": [
13815            "aui-map"
13816        ]
13817    },
13818    "aui-simple-anim-deprecated": {
13819        "requires": [
13820            "aui-base-deprecated"
13821        ]
13822    },
13823    "aui-skin-deprecated": {
13824        "type": "css"
13825    },
13826    "aui-sortable": {
13827        "use": [
13828            "aui-sortable-layout",
13829            "aui-sortable-list"
13830        ]
13831    },
13832    "aui-sortable-layout": {
13833        "requires": [
13834            "dd-delegate",
13835            "dd-drag",
13836            "dd-drop",
13837            "dd-proxy",
13838            "aui-node",
13839            "aui-component"
13840        ],
13841        "skinnable": true
13842    },
13843    "aui-sortable-list": {
13844        "requires": [
13845            "dd-drag",
13846            "dd-drop",
13847            "dd-proxy",
13848            "dd-scroll",
13849            "aui-node",
13850            "aui-component"
13851        ]
13852    },
13853    "aui-state-interaction-deprecated": {
13854        "requires": [
13855            "aui-base-deprecated",
13856            "plugin"
13857        ]
13858    },
13859    "aui-surface": {
13860        "use": [
13861            "aui-surface-app",
13862            "aui-surface-screen"
13863        ]
13864    },
13865    "aui-surface-app": {
13866        "requires": [
13867            "event-delegate",
13868            "node-event-html5",
13869            "aui-surface-base",
13870            "aui-surface-screen",
13871            "aui-surface-screen-route"
13872        ]
13873    },
13874    "aui-surface-base": {
13875        "requires": [
13876            "base-build",
13877            "node-style",
13878            "timers",
13879            "aui-debounce",
13880            "aui-promise",
13881            "aui-parse-content"
13882        ]
13883    },
13884    "aui-surface-screen": {
13885        "requires": [
13886            "base-build"
13887        ]
13888    },
13889    "aui-surface-screen-html": {
13890        "requires": [
13891            "aui-base",
13892            "aui-io-request",
13893            "aui-promise",
13894         
13894   "aui-surface-screen",
13895            "aui-url"
13896        ]
13897    },
13898    "aui-surface-screen-route": {
13899        "requires": [
13900            "base-build"
13901        ]
13902    },
13903    "aui-swf-deprecated": {
13904        "requires": [
13905            "querystring-parse-simple",
13906            "querystring-stringify-simple",
13907            "aui-base-deprecated"
13908        ]
13909    },
13910    "aui-tabs-data-editor": {
13911        "requires": [
13912            "aui-data-editor",
13913            "aui-tabview"
13914        ]
13915    },
13916    "aui-tabview": {
13917        "requires": [
13918            "selector-css3",
13919            "tabview",
13920            "aui-component",
13921            "aui-widget-css"
13922        ],
13923        "skinnable": true
13924    },
13925    "aui-template-deprecated": {
13926        "requires": [
13927            "aui-base-deprecated"
13928        ]
13929    },
13930    "aui-text-data-editor": {
13931        "requires": [
13932            "aui-data-editor",
13933            "event-valuechange"
13934        ],
13935        "skinnable": true
13936    },
13937    "aui-text-data-unicode": {
13938        "requires": [
13939            "text"
13940        ]
13941    },
13942    "aui-text-unicode": {
13943        "requires": [
13944            "aui-text-data-unicode"
13945        ]
13946    },
13947    "aui-textboxlist-deprecated": {
13948        "requires": [
13949            "anim-node-plugin",
13950            "aui-autocomplete-deprecated",
13951            "aui-button-item-deprecated",
13952            "aui-data-set-deprecated",
13953            "escape",
13954            "node-focusmanager"
13955        ],
13956        "skinnable": true
13957    },
13958    "aui-timepicker": {
13959        "requires": [
13960            "autocomplete",
13961            "aui-datepicker-delegate",
13962            "aui-datepicker-popover"
13963        ],
13964        "skinnable": true
13965    },
13966    "aui-timepicker-native": {
13967        "requires": [
13968            "base",
13969            "base-build",
13970            "aui-node-base",
13971            "aui-datepicker-delegate",
13972            "aui-datepicker-native"
13973        ]
13974    },
13975    "aui-timer": {
13976        "requires": [
13977            "oop"
13978        ]
13979    },
13980    "aui-toggler": {
13981        "use": [
13982            "aui-toggler-base",
13983            "aui-toggler-delegate"
13984        ]
13985    },
13986    "aui-toggler-accessibility": {
13987        "requires": [
13988            "aui-toggler-base"
13989        ]
13990    },
13991    "aui-toggler-base": {
13992        "requires": [
13993            "transition",
13994            "aui-selector",
13995            "aui-event-base",
13996            "aui-node",
13997            "aui-component",
13998            "event-tap"
13999        ],
14000        "skinnable": true
14001    },
14002    "aui-toggler-delegate": {
14003        "requires": [
14004            "array-invoke",
14005            "node-event-delegate",
14006            "aui-toggler-base"
14007        ]
14008    },
14009    "aui-toolbar": {
14010        "requires": [
14011            "arraylist",
14012            "arraylist-add",
14013            "aui-component",
14014            "aui-button-core"
14015        ]
14016    },
14017    "aui-tooltip": {
14018        "use": [
14019            "aui-tooltip-base",
14020            "aui-tooltip-delegate"
14021        ]
14022    },
14023    "aui-tooltip-base": {
14024        "requires": [
14025            "aui-aria",
14026            "aui-classnamemanager",
14027            "aui-component",
14028            "aui-debounce",
14029            "aui-node-base",
14030            "aui-widget-cssclass",
14031            "aui-widget-toggle",
14032            "aui-widget-transition",
14033            "aui-widget-trigger",
14034            "aui-widget-position-align-suggestion",
14035            "event-hover",
14036            "event-resize",
14037            "escape",
14038            "widget",
14039            "widget-autohide",
14040            "widget-position",
14041            "widget-position-align",
14042            "widget-position-constrain",
14043            "widget-stack",
14044            "widget-stdmod"
14045        ],
14046        "skinnable": true
14047    },
14048    "aui-tooltip-delegate": {
14049        "requires": [
14050            "aui-tooltip-base",
14051            "node-event-delegate"
14052        ]
14053    },
14054    "aui-tooltip-deprecated": {
14055        "requires": [
14056            "aui-overlay-context-panel-deprecated"
14057        ],
14058        "skinnable": true
14059    },
14060    "aui-tpl-snippets-base-deprecated": {
14061        "requires": [
14062            "aui-template-deprecated"
14063        ]
14064    },
14065    "aui-tpl-snippets-checkbox-deprecated": {
14066        "requires": [
14067            "aui-tpl-snippets-base-deprecated"
14068        ]
14069    },
14070    "aui-tpl-snippets-deprecated": {
14071        "use": [
14072            "aui-tpl-snippets-base-deprecated",
14073            "aui-tpl-snippets-checkbox-deprecated",
14074            "aui-tpl-snippets-input-deprecated",
14075            "aui-tpl-snippets-select-deprecated",
14076            "aui-tpl-snippets-textarea-deprecated"
14077        ]
14078    },
14079    "aui-tpl-snippets-input-deprecated": {
14080        "requires": [
14081            "aui-tpl-snippets-base-deprecated"
14082        ]
14083    },
14084    "aui-tpl-snippets-select-deprecated": {
14085        "requires": [
14086            "aui-tpl-snippets-base-deprecated"
14087        ]
14088    },
14089    "aui-tpl-snippets-textarea-deprecated": {
14090        "requires": [
14091            "aui-tpl-snippets-base-deprecated"
14092        ]
14093    },
14094    "aui-tree": {
14095        "use": [
14096            "aui-tree-data",
14097            "aui-tree-io",
14098            "aui-tree-node",
14099            "aui-tree-paginator",
14100            "aui-tree-view"
14101        ]
14102    },
14103    "aui-tree-data": {
14104        "requires": [
14105            "aui-base-core",
14106            "aui-base-lang",
14107            "aui-node-base",
14108            "aui-timer",
14109            "aui-component"
14110        ]
14111    },
14112    "aui-tree-io": {
14113        "requires": [
14114            "aui-component",
14115            "aui-io"
14116        ]
14117    },
14118    "aui-tree-node": {
14119        "requires": [
14120            "json",
14121            "querystring-stringify",
14122            "aui-tree-data",
14123            "aui-tree-io",
14124            "aui-tree-paginator",
14125            "event-key"
14126        ]
14127    },
14128    "aui-tree-paginator": {
14129        "requires": [
14130            "yui-base"
14131        ]
14132    },
14133    "aui-tree-view": {
14134        "requires": [
14135            "dd-delegate",
14136            "dd-proxy",
14137            "widget",
14138            "aui-tree-node",
14139            "aui-tree-paginator",
14140            "aui-tree-io"
14141        ],
14142        "skinnable": true
14143    },
14144    "aui-undo-redo": {
14145        "requires": [
14146            "aui-base",
14147            "base",
14148            "base-build",
14149            "event-key",
14150            "promise"
14151        ]
14152    },
14153    "aui-url": {
14154        "requires": [
14155            "oop",
14156            "querystring-parse",
14157            "querystring-stringify"
14158        ]
14159    },
14160    "aui-video": {
14161        "requires": [
14162            "event-resize",
14163            "node-event-html5",
14164            "querystring-stringify-simple",
14165            "aui-aria",
14166            "aui-node",
14167            "aui-component",
14168            "aui-debounce"
14169        ],
14170        "skinnable": true
14171    },
14172    "aui-viewport": {
14173        "requires": [
14174            "aui-node",
14175            "aui-component"
14176        ]
14177    },
14178    "aui-widget": {
14179        "use": [
14180            "aui-widget-cssclass",
14181            "aui-widget-toolbars"
14182        ]
14183    },
14184    "aui-widget-core": {
14185        "use": [
14186            "aui-widget-cssclass"
14187        ]
14188    },
14189    "aui-widget-cssclass": {
14190        "requires": [
14191            "widget-base"
14192        ]
14193    },
14194    "aui-widget-position-align-suggestion": {
14195        "requires": [
14196            "widget-position-align",
14197            "widget-stdmod"
14198        ]
14199    },
14200    "aui-widget-responsive": {
14201        "requires": [
14202            "event-resize",
14203            "widget-base"
14204        ]
14205    },
14206    "aui-widget-shortcut": {
14207        "requires": [
14208            "base"
14209        ]
14210    },
14211    "aui-widget-swipe": {
14212        "requires": [
14213            "classnamemanager",
14214            "scrollview-base",
14215            "scrollview-paginator",
14216            "timers"
14217        ]
14218    },
14219    "aui-widget-toggle": {},
14220    "aui-widget-toolbars": {
14221        "requires": [
14222            "widget-stdmod",
14223            "aui-toolbar"
14224        ]
14225    },
14226    "aui-widget-transition": {
14227        "requires": [
14228            "transition"
14229        ]
14230    },
14231    "aui-widget-trigger": {
14232        "requires": [
14233            "node"
14234        ]
14235    }
14236});
14237YUI.Env[Y.version].md5 = 'd7c627eb00edd6b6f054d8f6e7147480';
14238/*
14239 * Alloy JavaScript Library
14240 * http://alloy.liferay.com/
14241 *
14242 * Copyright (c) 2010 Liferay Inc.
14243 * http://alloy.liferay.com/LICENSE.txt
14244 *
14245 * Nate Cavanaugh ([email protected])
14246 * Eduardo Lundgren ([email protected])
14247 *
14248 * Attribution/Third-party licenses
14249 * http://alloy.liferay.com/ATTRIBUTION.txt
14250 */
14251
14252// Simple version of
14253// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
14254
14255A.UA.edge = (function() {
14256    var edgeVersion = A.UA.userAgent.match(/Edge\/(.[0-9.]+)/);
14257
14258    if (edgeVersion) {
14259        return edgeVersion[1];
14260    }
14261
14262    return 0;
14263})();
14264
14265A.supportsDOMEvent = function(domNode, eventName) {
14266    eventName = 'on' + eventName;
14267
14268    if (!(eventName in domNode)) {
14269        if (!domNode.setAttribute) {
14270            domNode = A.config.doc.createElement('div');
14271        }
14272
14273        if (domNode.setAttribute) {
14274            domNode.setAttribute(eventName, '');
14275            return (typeof domNode[eventName] === 'function');
14276        }
14277    }
14278
14279    domNode = null;
14280
14281    return true;
14282};
14283(function() {
14284    var slice = Array.prototype.slice;
14285
14286    YUI.prototype.ready = function() {
14287        var instance = this,
14288            xargs = arguments,
14289            index = xargs.length - 1,
14290            modules = slice.call(arguments, 0, index);
14291
14292        modules.unshift('event-base');
14293        modules.push(function(instance) {
14294            var args = arguments;
14295
14296            instance.on('domready', function() {
14297                xargs[index].apply(this, args);
14298            });
14299        });
14300        instance.use.apply(instance, modules);
14301    };
14302}());
14303
14304
14305}, '3.1.0-deprecated.77');
14306YUI.add('aui', function (A, NAME) {}, '3.1.0-deprecated.77');
14307YUI.Env.core.push.apply(YUI.Env.core, ["aui-base-core"]);
14308/**
14309 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
14310 *
14311 * This library is free software; you can redistribute it and/or modify it under
14312 * the terms of the GNU Lesser General Public License as published by the Free
14313 * Software Foundation; either version 2.1 of the License, or (at your option)
14314 * any later version.
14315 *
14316 * This library is distributed in the hope that it will be useful, but WITHOUT
14317 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14318 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14319 * details.
14320 */
14321
14322/**
14323 * @deprecated As of Athanasius (7.3.x), with no direct replacement
14324 */
14325(function () {
14326  var LiferayAUI = Liferay.AUI;
14327  var COMBINE = LiferayAUI.getCombine();
14328  var CORE_MODULES = YUI.Env.core;
14329  var INPUT_EL = document.createElement('input');
14330  var PATH_EDITOR_CKEDITOR = LiferayAUI.getEditorCKEditorPath();
14331  var PATH_JAVASCRIPT = '/o/frontend-js-aui-web';
14332  var SUPPORTS_INPUT_SELECTION = typeof INPUT_EL.selectionStart === 'number' && typeof INPUT_EL.selectionEnd === 'number';
14333
14334  var testHistory = function testHistory(A) {
14335    var WIN = A.config.win;
14336    var HISTORY = WIN.history;
14337    return HISTORY && HISTORY.pushState && HISTORY.replaceState && ('onpopstate' in WIN || A.UA.gecko >= 2);
14338  };
14339
14340  window.YUI_config = {
14341    base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/aui/',
14342    combine: COMBINE,
14343    comboBase: LiferayAUI.getComboPath(),
14344    filter: Liferay.AUI.getFilter(),
14345    groups: {
14346      editor: {
14347        base: PATH_EDITOR_CKEDITOR,
14348        combine: COMBINE,
14349        modules: {
14350          'inline-editor-ckeditor': {
14351            path: 'ckeditor/main.js'
14352          }
14353        },
14354        root: PATH_EDITOR_CKEDITOR
14355      },
14356      liferay: {
14357        base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/liferay/',
14358        combine: COMBINE,
14359        filter: Liferay.AUI.getFilterConfig(),
14360        modules: {
14361          'liferay-address': {
14362            path: 'address.js',
14363            requires: []
14364          },
14365          'liferay-alert': {
14366            path: 'alert.js',
14367            requires: ['aui-alert', 'aui-component', 'event-mouseenter', 'liferay-portlet-base', 'timers']
14368          },
14369          'liferay-asset-addon-entry-selector': {
14370            path: 'asset_addon_entry_selector.js',
14371            requires: ['aui-component', 'liferay-portlet-base', 'liferay-util-window']
14372          },
14373          'liferay-asset-categories-selector': {
14374            path: 'asset_categories_selector.js',
14375            requires: ['aui-tree', 'liferay-asset-tags-selector']
14376          },
14377          'liferay-asset-tags-selector': {
14378            path: 'asset_tags_selector.js',
14379            requires: ['array-extras', 'async-queue', 'aui-autocomplete-deprecated', 'aui-io-plugin-deprecated', 'aui-live-search-deprecated', 'aui-modal', 'aui-template-deprecated', 'aui-textboxlist-deprecated', 'datasource-cache', 'liferay-service-datasource']
14380          },
14381          'liferay-auto-fields': {
14382            path: 'auto_fields.js',
14383            requires: ['aui-base', 'aui-data-set-deprecated', 'aui-parse-content', 'base', 'liferay-form', 'liferay-menu', 'liferay-portlet-base', 'liferay-undo-manager', 'sortable']
14384          },
14385          'liferay-autocomplete-input': {
14386            path: 'autocomplete_input.js',
14387            requires: ['aui-base', 'autocomplete', 'autocomplete-filters', 'autocomplete-highlighters']
14388          },
14389          'liferay-autocomplete-input-caretindex': {
14390            condition: {
14391              name: 'liferay-autocomplete-input-caretindex',
14392              test: function test() {
14393                return SUPPORTS_INPUT_SELECTION;
14394              },
14395              trigger: 'liferay-autocomplete-textarea'
14396            },
14397            path: 'autocomplete_input_caretindex.js',
14398            requires: ['liferay-autocomplete-textarea']
14399          },
14400          'liferay-autocomplete-input-caretindex-sel': {
14401            condition: {
14402              name: 'liferay-autocomplete-input-caretindex-sel',
14403              test: function test() {
14404                return !SUPPORTS_INPUT_SELECTION;
14405              },
14406              trigger: 'liferay-autocomplete-textarea'
14407            },
14408            path: 'autocomplete_input_caretindex_sel.js',
14409            requires: ['liferay-autocomplete-textarea']
14410          },
14411          'liferay-autocomplete-input-caretoffset': {
14412            condition: {
14413              name: 'liferay-autocomplete-input-caretoffset',
14414              test: function test(A) {
14415                return !(A.UA.ie && A.UA.ie < 9);
14416              },
14417              trigger: 'liferay-autocomplete-textarea'
14418            },
14419            path: 'autocomplete_input_caretoffset.js',
14420            requires: ['liferay-autocomplete-textarea']
14421          },
14422          'liferay-autocomplete-input-caretoffset-sel': {
14423            condition: {
14424              name: 'liferay-autocomplete-input-caretoffset-sel',
14425              test: function test(A) {
14426                return A.UA.ie && A.UA.ie < 9;
14427              },
14428              trigger: 'liferay-autocomplete-textarea'
14429            },
14430            path: 'autocomplete_input_caretoffset_sel.js',
14431            requires: ['liferay-autocomplete-textarea']
14432          },
14433          'liferay-autocomplete-textarea': {
14434            path: 'autocomplete_textarea.js',
14435            requires: ['liferay-autocomplete-input']
14436          },
14437          'liferay-browser-selectors': {
14438            path: 'browser_selectors.js',
14439            requires: ['yui-base']
14440          },
14441          'liferay-cover-cropper': {
14442            path: 'cover_cropper.js',
14443            requires: ['aui-base', 'aui-component', 'dd-constrain', 'dd-drag', 'plugin']
14444          },
14445          'liferay-crop-region': {
14446            path: 'crop_region.js',
14447            requires: ['aui-base']
14448          },
14449          'liferay-dd-proxy': {
14450            path: 'dd_proxy.js',
14451            requires: ['dd-proxy']
14452          },
14453          'liferay-dynamic-select': {
14454            path: 'dynamic_select.js',
14455            requires: ['aui-base']
14456          },
14457          'liferay-form': {
14458            path: 'form.js',
14459            requires: ['aui-base', 'aui-form-validator']
14460          },
14461          'liferay-form-placeholders': {
14462            condition: {
14463              name: 'liferay-form-placeholders',
14464              test: function test() {
14465                return !('placeholder' in INPUT_EL);
14466              },
14467              trigger: 'liferay-form'
14468            },
14469            path: 'form_placeholders.js',
14470            requires: ['liferay-form', 'plugin']
14471          },
14472          'liferay-fullscreen-source-editor': {
14473            path: 'fullscreen_source_editor.js',
14474            requires: ['liferay-source-editor']
14475          },
14476          'liferay-history': {
14477            path: 'history.js',
14478            requires: ['history-hash', 'querystring-parse-simple']
14479          },
14480          'liferay-history-html5': {
14481            condition: {
14482              name: 'liferay-history-html5',
14483              test: testHistory,
14484              trigger: 'liferay-history'
14485            },
14486            path: 'history_html5.js',
14487            requires: ['history-html5', 'liferay-history', 'querystring-stringify-simple']
14488          },
14489          'liferay-history-manager': {
14490            path: 'history_manager.js',
14491            requires: ['liferay-history']
14492          },
14493          'liferay-hudcrumbs': {
14494            path: 'hudcrumbs.js',
14495            requires: ['aui-base', 'aui-debounce', 'event-resize']
14496          },
14497          'liferay-icon': {
14498            path: 'icon.js',
14499            requires: ['aui-base']
14500          },
14501          'liferay-inline-editor-base': {
14502            path: 'inline_editor_base.js',
14503            requires: ['aui-base', 'aui-overlay-base-deprecated']
14504          },
14505          'liferay-input-localized': {
14506            path: 'input_localized.js',
14507            requires: ['aui-base', 'aui-component', 'aui-event-input', 'aui-palette', 'aui-set', 'portal-available-languages']
14508          },
14509          'liferay-input-move-boxes': {
14510            path: 'input_move_boxes.js',
14511            plugins: {
14512              'liferay-input-move-boxes-touch': {
14513                condition: {
14514                  name: 'liferay-input-move-boxes-touch',
14515                  test: function test(A) {
14516                    return A.UA.touchEnabled && !!A.UA.mobile;
14517                  },
14518                  trigger: 'liferay-input-move-boxes'
14519                }
14520              }
14521            },
14522            requires: ['aui-base', 'aui-toolbar']
14523          },
14524          'liferay-input-move-boxes-touch': {
14525            path: 'input_move_boxes_touch.js',
14526            requires: ['aui-base', 'aui-template-deprecated', 'liferay-input-move-boxes', 'sortable']
14527          },
14528          'liferay-item-selector-dialog': {
14529            path: 'item_selector_dialog.js',
14530            requires: ['aui-component']
14531          },
14532          'liferay-item-selector-repository-entry-browser': {
14533            path: 'item_selector_repository_entry_browser.js',
14534            requires: ['liferay-item-selector-uploader', 'liferay-item-viewer', 'liferay-notice', 'liferay-portlet-base']
14535          },
14536          'liferay-item-selector-uploader': {
14537            path: 'item_selector_uploader.js',
14538            requires: ['aui-base', 'aui-progressbar', 'liferay-portlet-base', 'uploader']
14539          },
14540          'liferay-item-selector-url': {
14541            path: 'item_selector_url.js',
14542            requires: ['aui-event-input', 'liferay-item-viewer', 'liferay-portlet-base']
14543          },
14544          'liferay-item-viewer': {
14545            path: 'item_viewer.js',
14546            requires: ['aui-component', 'aui-image-viewer', 'liferay-portlet-url']
14547          },
14548          'liferay-language': {
14549            path: 'language.js'
14550          },
14551          'liferay-layout': {
14552            path: 'layout.js'
14553          },
14554          'liferay-layout-column': {
14555            path: 'layout_column.js',
14556            requires: ['aui-sortable-layout', 'dd']
14557          },
14558          'liferay-list-view': {
14559            path: 'list_view.js',
14560            requires: ['aui-base', 'transition']
14561          },
14562          'liferay-logo-editor': {
14563            path: 'logo_editor.js',
14564            requires: ['aui-image-cropper', 'liferay-portlet-base']
14565          },
14566          'liferay-logo-selector': {
14567            path: 'logo_selector.js',
14568            requires: ['aui-base']
14569          },
14570          'liferay-menu': {
14571            path: 'menu.js',
14572            requires: ['aui-debounce', 'aui-node']
14573          },
14574          'liferay-menu-filter': {
14575            path: 'menu_filter.js',
14576            requires: ['autocomplete-base', 'autocomplete-filters', 'autocomplete-highlighters']
14577          },
14578          'liferay-menu-toggle': {
14579            path: 'menu_toggle.js',
14580            requires: ['aui-node', 'event-outside', 'event-tap', 'liferay-menu-filter']
14581          },
14582          'liferay-message': {
14583            path: 'message.js',
14584            requires: ['aui-base']
14585          },
14586          'liferay-navigation': {
14587            path: 'navigation.js',
14588            requires: ['aui-component', 'event-mouseenter']
14589          },
14590          'liferay-navigation-interaction': {
14591            path: 'navigation_interaction.js',
14592            plugins: {
14593              'liferay-navigation-interaction-touch': {
14594                condition: {
14595                  name: 'liferay-navigation-interaction-touch',
14596                  test: function test(A) {
14597                    return A.UA.touchEnabled;
14598                  },
14599                  trigger: 'liferay-navigation-interaction'
14600                }
14601              }
14602            },
14603            requires: ['aui-base', 'aui-component', 'event-mouseenter', 'node-focusmanager', 'plugin']
14604          },
14605          'liferay-navigation-interaction-touch': {
14606            path: 'navigation_interaction_touch.js',
14607            requires: ['event-tap', 'event-touch', 'liferay-navigation-interaction']
14608          },
14609          'liferay-node': {
14610            path: 'node.js',
14611            requires: ['dom-base']
14612          },
14613          'liferay-notice': {
14614            path: 'notice.js',
14615            requires: ['aui-base', 'transition']
14616          },
14617          'liferay-notification': {
14618            path: 'notification.js',
14619            requires: ['liferay-alert']
14620          },
14621          'liferay-pagination': {
14622            path: 'pagination.js',
14623            requires: ['aui-pagination']
14624          },
14625          'liferay-panel-search': {
14626            path: 'panel_search.js',
14627            requires: ['aui-base', 'liferay-search-filter']
14628          },
14629          'liferay-poller': {
14630            path: 'poller.js',
14631            requires: ['aui-base', 'json']
14632          },
14633          'liferay-portlet-base': {
14634            path: 'portlet_base.js',
14635            requires: ['aui-base']
14636          },
14637          'liferay-portlet-url': {
14638            path: 'portlet_url.js',
14639            requires: ['aui-base']
14640          },
14641          'liferay-preview': {
14642            path: 'preview.js',
14643            requires: ['aui-base', 'aui-overlay-mask-deprecated', 'aui-toolbar', 'liferay-widget-zindex']
14644          },
14645          'liferay-progress': {
14646            path: 'progress.js',
14647            requires: ['aui-progressbar']
14648          },
14649          'liferay-ratings': {
14650            path: 'ratings.js',
14651            requires: ['aui-rating']
14652          },
14653          'liferay-resize-rtl': {
14654            condition: {
14655              test: function test() {
14656                return document.documentElement.dir === 'rtl';
14657              },
14658              trigger: 'resize-base'
14659            },
14660            path: 'resize_rtl.js'
14661          },
14662          'liferay-restore-entry': {
14663            path: 'restore_entry.js',
14664            requires: ['aui-io-plugin-deprecated', 'aui-modal', 'liferay-portlet-base']
14665          },
14666          'liferay-search-container': {
14667            path: 'search_container.js',
14668            requires: ['aui-base', 'aui-datatable-core']
14669          },
14670          'liferay-search-container-move': {
14671            path: 'search_container_move.js',
14672            requires: ['aui-component', 'dd-constrain', 'dd-delegate', 'dd-drag', 'dd-drop', 'dd-proxy', 'plugin']
14673          },
14674          'liferay-search-container-select': {
14675            path: 'search_container_select.js',
14676            requires: ['aui-component', 'aui-url', 'plugin']
14677          },
14678          'liferay-search-filter': {
14679            path: 'search_filter.js',
14680            requires: ['aui-base', 'autocomplete-base', 'autocomplete-filters']
14681          },
14682          'liferay-service-datasource': {
14683            path: 'service_datasource.js',
14684            requires: ['aui-base', 'datasource-local']
14685          },
14686          'liferay-session': {
14687            path: 'session.js',
14688            requires: ['aui-base', 'aui-component', 'aui-timer', 'cookie', 'plugin']
14689          },
14690          'liferay-sign-in-modal': {
14691            path: 'sign_in_modal.js',
14692            requires: ['aui-base', 'aui-component', 'aui-parse-content', 'liferay-form', 'liferay-portlet-url', 'liferay-util-window', 'plugin']
14693          },
14694          'liferay-social-bookmarks': {
14695            path: 'social_bookmarks.js',
14696            requires: ['aui-component', 'aui-node']
14697          },
14698          'liferay-sortable': {
14699            path: 'sortable.js',
14700            requires: ['liferay-dd-proxy', 'sortable']
14701          },
14702          'liferay-source-editor': {
14703            path: 'source_editor.js',
14704            requires: ['aui-ace-editor']
14705          },
14706          'liferay-storage-formatter': {
14707            path: 'storage_formatter.js',
14708            requires: ['aui-base', 'datatype-number-format']
14709          },
14710          'liferay-store': {
14711            path: 'store.js'
14712          },
14713          'liferay-toggler-interaction': {
14714            path: 'toggler_interaction.js',
14715            requires: ['liferay-toggler-key-filter']
14716          },
14717          'liferay-toggler-key-filter': {
14718            path: 'toggler_key_filter.js',
14719            requires: ['aui-event-base']
14720          },
14721          'liferay-token-list': {
14722            path: 'token_list.js',
14723            requires: ['aui-base', 'aui-template-deprecated']
14724          },
14725          'liferay-translation-manager': {
14726            path: 'translation_manager.js',
14727            requires: ['aui-base']
14728          },
14729          'liferay-tree-view-icons': {
14730            condition: {
14731              name: 'liferay-tree-view-icons',
14732              trigger: 'aui-tree-view'
14733            },
14734            path: 'tree_view_icons.js',
14735            requires: ['aui-tree-view']
14736          },
14737          'liferay-undo-manager': {
14738            path: 'undo_manager.js',
14739            requires: ['aui-data-set-deprecated', 'base']
14740          },
14741          'liferay-upload': {
14742            path: 'upload.js',
14743            requires: ['aui-template-deprecated', 'collection', 'liferay-portlet-base', 'uploader']
14744          },
14745          'liferay-util-window': {
14746            path: 'util_window.js',
14747            requires: ['aui-dialog-iframe-deprecated', 'aui-modal', 'aui-url', 'event-resize', 'liferay-widget-zindex']
14748          },
14749          'liferay-widget-size-animation-plugin': {
14750            path: 'widget_size_animation_plugin.js',
14751            requires: ['anim-easing', 'plugin', 'widget']
14752          },
14753          'liferay-widget-zindex': {
14754            path: 'widget_zindex.js',
14755            requires: ['aui-modal', 'plugin']
14756          },
14757          'liferay-xml-formatter': {
14758            path: 'xml_formatter.js',
14759            requires: ['aui-base']
14760          }
14761        },
14762        root: PATH_JAVASCRIPT + '/liferay/'
14763      },
14764      misc: {
14765        base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/misc/',
14766        combine: COMBINE,
14767        modules: {
14768          swfobject: {
14769            path: 'swfobject.js'
14770          },
14771          swfupload: {
14772            path: 'swfupload/swfupload.js'
14773          }
14774        },
14775        root: PATH_JAVASCRIPT + '/misc/'
14776      },
14777      portal: {
14778        base: Liferay.ThemeDisplay.getCDNBaseURL() + LiferayAUI.getJavaScriptRootPath() + '/liferay/',
14779        combine: false,
14780        modules: {
14781          'portal-available-languages': {
14782            path: LiferayAUI.getAvailableLangPath(),
14783            requires: ['liferay-language']
14784          }
14785        },
14786        root: PATH_JAVASCRIPT + '/liferay/'
14787      }
14788    },
14789    insertBefore: 'liferayPortalCSS',
14790    lang: themeDisplay.getBCP47LanguageId(),
14791    root: PATH_JAVASCRIPT + '/aui/',
14792    useBrowserConsole: false
14793  };
14794  CORE_MODULES.push('liferay-browser-selectors');
14795})();
14796//# sourceMappingURL=modules.js.map
14797/**
14798 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
14799 *
14800 * This library is free software; you can redistribute it and/or modify it under
14801 * the terms of the GNU Lesser General Public License as published by the Free
14802 * Software Foundation; either version 2.1 of the License, or (at your option)
14803 * any later version.
14804 *
14805 * This library is distributed in the hope that it will be useful, but WITHOUT
14806 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14807 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14808 * details.
14809 */
14810
14811/**
14812 * @deprecated As of Athanasius (7.3.x), with no direct replacement
14813 */
14814(function () {
14815  var ALLOY = YUI();
14816
14817  if (ALLOY.html5shiv) {
14818    ALLOY.html5shiv();
14819  }
14820
14821  var originalUse = ALLOY.use;
14822
14823  ALLOY.use = function () {
14824    var args = Array.prototype.slice.call(arguments, 0);
14825    var currentURL = Liferay.currentURL;
14826    var originalCallback = args[args.length - 1];
14827
14828    if (typeof originalCallback === 'function') {
14829      args[args.length - 1] = function () {
14830        if (Liferay.currentURL === currentURL) {
14831          originalCallback.apply(this, arguments);
14832        }
14833      };
14834    }
14835
14836    return originalUse.apply(this, args);
14837  };
14838
14839  window.AUI = function () {
14840    return ALLOY;
14841  };
14842
14843  ALLOY.mix(AUI, YUI);
14844  AUI.$ = window.jQuery;
14845  AUI._ = window._;
14846})();
14847//# sourceMappingURL=aui_sandbox.js.map
14848YUI.add('attribute-base', function (Y, NAME) {
14849
14850    /**
14851     * The attribute module provides an augmentable Attribute implementation, which
14852     * adds configurable attributes and attribute change events to the class being
14853     * augmented. It also provides a State class, which is used internally by Attribute,
14854     * but can also be used independently to provide a name/property/value data structure to
14855     * store state.
14856     *
14857     * @module attribute
14858     */
14859
14860    /**
14861     * The attribute-base submodule provides core attribute handling support, with everything
14862     * aside from complex attribute handling in the provider's constructor.
14863     *
14864     * @module attribute
14865     * @submodule attribute-base
14866     */
14867
14868    /**
14869     * <p>
14870     * Attribute provides configurable attribute support along with attribute change events. It is designed to be
14871     * augmented on to a host class, and provides the host with the ability to configure attributes to store and retrieve state,
14872     * along with attribute change events.
14873     * </p>
14874     * <p>For example, attributes added to the host can be configured:</p>
14875     * <ul>
14876     *     <li>As read only.</li>
14877     *     <li>As write once.</li>
14878     *     <li>With a setter function, which can be used to manipulate
14879     *     values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li>
14880     *     <li>With a getter function, which can be used to manipulate stored values,
14881     *     before they are returned by Attribute's <a href="#method_get">get</a> method.</li>
14882     *     <li>With a validator function, to validate values before they are stored.</li>
14883     * </ul>
14884     *
14885     * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration
14886     * options available for attributes.</p>
14887     *
14888     * <p><strong>NOTE:</strong> Most implementations will be better off extending the <a href="Base.html">Base</a> class,
14889     * instead of augmenting Attribute directly. Base augments Attribute and will handle the initial configuration
14890     * of attributes for derived classes, accounting for values passed into the constructor.</p>
14891     *
14892     * @class Attribute
14893     * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
14894     *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
14895     * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
14896     *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
14897     * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
14898     * @uses AttributeCore
14899     * @uses AttributeObservable
14900     * @uses EventTarget
14901     * @uses AttributeExtras
14902     */
14903    function Attribute() {
14904        Y.AttributeCore.apply(this, arguments);
14905        Y.AttributeObservable.apply(this, arguments);
14906        Y.AttributeExtras.apply(this, arguments);
14907    }
14908
14909    Y.mix(Attribute, Y.AttributeCore, false, null, 1);
14910    Y.mix(Attribute, Y.AttributeExtras, false, null, 1);
14911
14912    // Needs to be `true`, to overwrite methods from AttributeCore
14913    Y.mix(Attribute, Y.AttributeObservable, true, null, 1);
14914
14915    /**
14916     * <p>The value to return from an attribute setter in order to prevent the set from going through.</p>
14917     *
14918     * <p>You can return this value from your setter if you wish to combine validator and setter
14919     * functionality into a single setter function, which either returns the massaged value to be stored or
14920     * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p>
14921     *
14922     * @property INVALID_VALUE
14923     * @type Object
14924     * @static
14925     * @final
14926     */
14927    Attribute.INVALID_VALUE = Y.AttributeCore.INVALID_VALUE;
14928
14929    /**
14930     * The list of properties which can be configured for
14931     * each attribute (e.g. setter, getter, writeOnce etc.).
14932     *
14933     * This property is used internally as a whitelist for faster
14934     * Y.mix operations.
14935     *
14936     * @property _ATTR_CFG
14937     * @type Array
14938     * @static
14939     * @protected
14940     */
14941    Attribute._ATTR_CFG = Y.AttributeCore._ATTR_CFG.concat(Y.AttributeObservable._ATTR_CFG);
14942
14943    /**
14944     * Utility method to protect an attribute configuration hash, by merging the
14945     * entire object and the individual attr config objects.
14946     *
14947     * @method protectAttrs
14948     * @static
14949     * @param {Object} attrs A hash of attribute to configuration object pairs.
14950     * @return {Object} A protected version of the `attrs` argument.
14951     */
14952    Attribute.protectAttrs = Y.AttributeCore.protectAttrs;
14953
14954    Y.Attribute = Attribute;
14955
14956
14957}, 'patched-v3.18.1', {"requires": ["attribute-core", "attribute-observable", "attribute-extras"]});
14958
14959YUI.add('attribute-complex', function (Y, NAME) {
14960
14961    /**
14962     * Adds support for attribute providers to handle complex attributes in the constructor
14963     *
14964     * @module attribute
14965     * @submodule attribute-complex
14966     * @for Attribute
14967     * @deprecated AttributeComplex's overrides are now part of AttributeCore.
14968     */
14969
14970    var Attribute = Y.Attribute;
14971
14972    Attribute.Complex = function() {};
14973    Attribute.Complex.prototype = {
14974
14975        /**
14976         * Utility method to split out simple attribute name/value pairs ("x")
14977         * from complex attribute name/value pairs ("x.y.z"), so that complex
14978         * attributes can be keyed by the top level attribute name.
14979         *
14980         * @method _normAttrVals
14981         * @param {Object} valueHash An object with attribute name/value pairs
14982         *
14983         * @return {Object} An object literal with 2 properties - "simple" and "complex",
14984         * containing simple and complex attribute values respectively keyed
14985         * by the top level attribute name, or null, if valueHash is falsey.
14986         *
14987         * @private
14988         */
14989        _normAttrVals : Attribute.prototype._normAttrVals,
14990
14991        /**
14992         * Returns the initial value of the given attribute from
14993         * either the default configuration provided, or the
14994         * over-ridden value if it exists in the set of initValues
14995         * provided and the attribute is not read-only.
14996         *
14997         * @param {String} attr The name of the attribute
14998         * @param {Object} cfg The attribute configuration object
14999         * @param {Object}
14999 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
15000         *
15001         * @return {Any} The initial value of the attribute.
15002         *
15003         * @method _getAttrInitVal
15004         * @private
15005         */
15006        _getAttrInitVal : Attribute.prototype._getAttrInitVal
15007
15008    };
15009
15010    // Consistency with the rest of the Attribute addons for now.
15011    Y.AttributeComplex = Attribute.Complex;
15012
15013
15014}, 'patched-v3.18.1', {"requires": ["attribute-base"]});
15015
15016YUI.add('attribute-core', function (Y, NAME) {
15017
15018    /**
15019     * The State class maintains state for a collection of named items, with
15020     * a varying number of properties defined.
15021     *
15022     * It avoids the need to create a separate class for the item, and separate instances
15023     * of these classes for each item, by storing the state in a 2 level hash table,
15024     * improving performance when the number of items is likely to be large.
15025     *
15026     * @constructor
15027     * @class State
15028     */
15029    Y.State = function() {
15030        /**
15031         * Hash of attributes
15032         * @property data
15033         */
15034        this.data = {};
15035    };
15036
15037    Y.State.prototype = {
15038
15039        /**
15040         * Adds a property to an item.
15041         *
15042         * @method add
15043         * @param name {String} The name of the item.
15044         * @param key {String} The name of the property.
15045         * @param val {Any} The value of the property.
15046         */
15047        add: function(name, key, val) {
15048            var item = this.data[name];
15049
15050            if (!item) {
15051                item = this.data[name] = {};
15052            }
15053
15054            item[key] = val;
15055        },
15056
15057        /**
15058         * Adds multiple properties to an item.
15059         *
15060         * @method addAll
15061         * @param name {String} The name of the item.
15062         * @param obj {Object} A hash of property/value pairs.
15063         */
15064        addAll: function(name, obj) {
15065            var item = this.data[name],
15066                key;
15067
15068            if (!item) {
15069                item = this.data[name] = {};
15070            }
15071
15072            for (key in obj) {
15073                if (obj.hasOwnProperty(key)) {
15074                    item[key] = obj[key];
15075                }
15076            }
15077        },
15078
15079        /**
15080         * Removes a property from an item.
15081         *
15082         * @method remove
15083         * @param name {String} The name of the item.
15084         * @param key {String} The property to remove.
15085         */
15086        remove: function(name, key) {
15087            var item = this.data[name];
15088
15089            if (item) {
15090                delete item[key];
15091            }
15092        },
15093
15094        /**
15095         * Removes multiple properties from an item, or removes the item completely.
15096         *
15097         * @method removeAll
15098         * @param name {String} The name of the item.
15099         * @param obj {Object|Array} Collection of properties to delete. If not provided, the entire item is removed.
15100         */
15101        removeAll: function(name, obj) {
15102            var data;
15103
15104            if (!obj) {
15105                data = this.data;
15106
15107                if (name in data) {
15108                    delete data[name];
15109                }
15110            } else {
15111                Y.each(obj, function(value, key) {
15112                    this.remove(name, typeof key === 'string' ? key : value);
15113                }, this);
15114            }
15115        },
15116
15117        /**
15118         * For a given item, returns the value of the property requested, or undefined if not found.
15119         *
15120         * @method get
15121         * @param name {String} The name of the item
15122         * @param key {String} Optional. The property value to retrieve.
15123         * @return {Any} The value of the supplied property.
15124         */
15125        get: function(name, key) {
15126            var item = this.data[name];
15127
15128            if (item) {
15129                return item[key];
15130            }
15131        },
15132
15133        /**
15134         * For the given item, returns an object with all of the
15135         * item's property/value pairs. By default the object returned
15136         * is a shallow copy of the stored data, but passing in true
15137         * as the second parameter will return a reference to the stored
15138         * data.
15139         *
15140         * @method getAll
15141         * @param name {String} The name of the item
15142         * @param reference {boolean} true, if you want a reference to the stored
15143         * object
15144         * @return {Object} An object with property/value pairs for the item.
15145         */
15146        getAll : function(name, reference) {
15147            var item = this.data[name],
15148                key, obj;
15149
15150            if (reference) {
15151                obj = item;
15152            } else if (item) {
15153                obj = {};
15154
15155                for (key in item) {
15156                    if (item.hasOwnProperty(key)) {
15157                        obj[key] = item[key];
15158                    }
15159                }
15160            }
15161
15162            return obj;
15163        }
15164    };
15165    /*For log lines*/
15166    /*jshint maxlen:200*/
15167
15168    /**
15169     * The attribute module provides an augmentable Attribute implementation, which
15170     * adds configurable attributes and attribute change events to the class being
15171     * augmented. It also provides a State class, which is used internally by Attribute,
15172     * but can also be used independently to provide a name/property/value data structure to
15173     * store state.
15174     *
15175     * @module attribute
15176     */
15177
15178    /**
15179     * The attribute-core submodule provides the lightest level of attribute handling support
15180     * without Attribute change events, or lesser used methods such as reset(), modifyAttrs(),
15181     * and removeAttr().
15182     *
15183     * @module attribute
15184     * @submodule attribute-core
15185     */
15186    var O = Y.Object,
15187        Lang = Y.Lang,
15188
15189        DOT = ".",
15190
15191        // Externally configurable props
15192        GETTER = "getter",
15193        SETTER = "setter",
15194        READ_ONLY = "readOnly",
15195        WRITE_ONCE = "writeOnce",
15196        INIT_ONLY = "initOnly",
15197        VALIDATOR = "validator",
15198        VALUE = "value",
15199        VALUE_FN = "valueFn",
15200        LAZY_ADD = "lazyAdd",
15201
15202        // Used for internal state management
15203        ADDED = "added",
15204        BYPASS_PROXY = "_bypassProxy",
15205        INIT_VALUE = "initValue",
15206        LAZY = "lazy",
15207
15208        INVALID_VALUE;
15209
15210    /**
15211     * <p>
15212     * AttributeCore provides the lightest level of configurable attribute support. It is designed to be
15213     * augmented on to a host class, and provides the host with the ability to configure
15214     * attributes to store and retrieve state, <strong>but without support for attribute change events</strong>.
15215     * </p>
15216     * <p>For example, attributes added to the host can be configured:</p>
15217     * <ul>
15218     *     <li>As read only.</li>
15219     *     <li>As write once.</li>
15220     *     <li>With a setter function, which can be used to manipulate
15221     *     values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li>
15222     *     <li>With a getter function, which can be used to manipulate stored values,
15223     *     before they are returned by Attribute's <a href="#method_get">get</a> method.</li>
15224     *     <li>With a validator function, to validate values before they are stored.</li>
15225     * </ul>
15226     *
15227     * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration
15228     * options available for attributes.</p>
15229     *
15230     * <p>Object/Classes based on AttributeCore can augment <a href="AttributeObservable.html">AttributeObservable</a>
15231     * (with true for overwrite) and <a href="AttributeExtras.html">AttributeExtras</a> to add attribute event and
15232     * additional, less commonly used attribute methods, such as `modifyAttr`, `removeAttr` and `reset`.</p>
15233     *
15234     * @class AttributeCore
15235     * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
15236     *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
15237     * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
15238     *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
15239     * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
15240     */
15241    function AttributeCore(attrs, values, lazy) {
15242        // HACK: Fix #2531929
15243        // Complete hack, to make sure the first clone of a node value in IE doesn't doesn't hurt state - maintains 3.4.1 behavior.
15244        // Too late in the release cycle to do anything about the core problem.
15245        // The root issue is that cloning a Y.Node instance results in an object which barfs in IE, when you access it's properties (since 3.3.0).
15246        this._yuievt = null;
15247
15248        this._initAttrHost(attrs, values, lazy);
15249    }
15250
15251    /**
15252     * <p>The value to return from an attribute setter in order to prevent the set from going through.</p>
15253     *
15254     * <p>You can return this value from your setter if you wish to combine validator and setter
15255     * functionality into a single setter function, which either returns the massaged value to be stored or
15256     * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p>
15257     *
15258     * @property INVALID_VALUE
15259     * @type Object
15260     * @static
15261     * @final
15262     */
15263    AttributeCore.INVALID_VALUE = {};
15264    INVALID_VALUE = AttributeCore.INVALID_VALUE;
15265
15266    /**
15267     * The list of properties which can be configured for
15268     * each attribute (e.g. setter, getter, writeOnce etc.).
15269     *
15270     * This property is used internally as a whitelist for faster
15271     * Y.mix operations.
15272     *
15273     * @property _ATTR_CFG
15274     * @type Array
15275     * @static
15276     * @protected
15277     */
15278    AttributeCore._ATTR_CFG = [SETTER, GETTER, VALIDATOR, VALUE, VALUE_FN, WRITE_ONCE, READ_ONLY, LAZY_ADD, BYPASS_PROXY];
15279
15280    /**
15281     * Utility method to protect an attribute configuration hash, by merging the
15282     * entire object and the individual attr config objects.
15283     *
15284     * @method protectAttrs
15285     * @static
15286     * @param {Object} attrs A hash of attribute to configuration object pairs.
15287     * @return {Object} A protected version of the `attrs` argument.
15288     */
15289    AttributeCore.protectAttrs = function (attrs) {
15290        if (attrs) {
15291            attrs = Y.merge(attrs);
15292            for (var attr in attrs) {
15293                if (attrs.hasOwnProperty(attr)) {
15294                    attrs[attr] = Y.merge(attrs[attr]);
15295                }
15296            }
15297        }
15298
15299        return attrs;
15300    };
15301
15302    AttributeCore.prototype = {
15303
15304        /**
15305         * Constructor logic for attributes. Initializes the host state, and sets up the inital attributes passed to the
15306         * constructor.
15307         *
15308         * @method _initAttrHost
15309         * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
15310         *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
15311         * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
15312         *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
15313         * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
15314         * @private
15315         */
15316        _initAttrHost : function(attrs, values, lazy) {
15317            this._state = new Y.State();
15318            this._initAttrs(attrs, values, lazy);
15319        },
15320
15321        /**
15322         * <p>
15323         * Adds an attribute with the provided configuration to the host object.
15324         * </p>
15325         * <p>
15326         * The config argument object supports the following properties:
15327         * </p>
15328         *
15329         * <dl>
15330         *    <dt>value &#60;Any&#62;</dt>
15331         *    <dd>The initial value to set on the attribute</dd>
15332         *
15333         *    <dt>valueFn &#60;Function | String&#62;</dt>
15334         *    <dd>
15335         *    <p>A function, which will return the initial value to set on the attribute. This is useful
15336         *    for cases where the attribute configuration is defined statically, but needs to
15337         *    reference the host instance ("this") to obtain an initial value. If both the value and valueFn properties are defined,
15338         *    the value returned by the valueFn has precedence over the value property, unless it returns undefined, in which
15339         *    case the value property is used.</p>
15340         *
15341         *    <p>valueFn can also be set to a string, representing the name of the instance method to be used to retrieve the value.</p>
15342         *    </dd>
15343         *
15344         *    <dt>readOnly &#60;boolean&#62;</dt>
15345         *    <dd>Whether or not the attribute is read only. Attributes having readOnly set to true
15346         *        cannot be modified by invoking the set method.</dd>
15347         *
15348         *    <dt>writeOnce &#60;boolean&#62; or &#60;string&#62;</dt>
15349         *    <dd>
15350         *        Whether or not the attribute is "write once". Attributes having writeOnce set to true,
15351         *        can only have their values set once, be it through the default configuration,
15352         *        constructor configuration arguments, or by invoking set.
15353         *        <p>The writeOnce attribute can also be set to the string "initOnly",
15354         *         in which case the attribute can only be set during initialization
15355         *        (when used with Base, this means it can only be set during construction)</p>
15356         *    </dd>
15357         *
15358         *    <dt>setter &#60;Function | String&#62;</dt>
15359         *    <dd>
15360         *    <p>The setter function used to massage or normalize the value passed to the set method for the attribute.
15361         *    The value returned by the setter will be the final stored value. Returning
15362         *    <a href="#property_Attribute.INVALID_VALUE">Attribute.INVALID_VALUE</a>, from the setter will prevent
15363         *    the value from being stored.
15364         *    </p>
15365         *
15366         *    <p>setter can also be set to a string, representing the name of the instance method to be used as the setter function.</p>
15367         *    </dd>
15368         *
15369         *    <dt>getter &#60;Function | String&#62;</dt>
15370         *    <dd>
15371         *    <p>
15372         *    The getter function used to massage or normalize the value returned by the get method for the attribute.
15373         *    The value returned by the getter function is the value which will be returned to the user when they
15374         *    invoke get.
15375         *    </p>
15376         *
15377         *    <p>getter can also be set to a string, representing the name of the instance method to be used as the getter function.</p>
15378         *    </dd>
15379         *
15380         *    <dt>validator &#60;Function | String&#62;</dt>
15381         *    <dd>
15382         *    <p>
15383         *    The validator function invoked prior to setting the stored value. Returning
15384         *    false from the validator function will prevent the value from being stored.
15385         *    </p>
15386         *
15387         *    <p>validator can also be set to a string, representing the name of the instance method to be used as the validator function.</p>
15388         *    </dd>
15389         *
15390         *    <dt>lazyAdd &#60;boolean&#62;</dt>
15391         *    <dd>Whether or not to delay initialization of the attribute until the first call to get/set it.
15392         *    This flag can be used to over-ride lazy initialization on a per attribute basis, when adding multiple attributes through
15393         *    the <a href="#method_addAttrs">addAttrs</a> method.</dd>
15394         *
15395         * </dl>
15396         *
15397         * <p>The setter, getter and validator are invoked with the value and name passed in as the first and second arguments, and with
15398         * the context ("this") set to the host object.</p>
15399         *
15400         * <p>Configuration properties outside of the list mentioned above are considered private properties used internally by attribute,
15401         * and are not intended for public use.</p>
15402         *
15403         * @method addAttr
15404         *
15405         * @param {String} name The name of the attribute.
15406         * @param {Object} config An object with attribute configuration property/value pairs, specifying the configuration for the attribute.
15407         *
15408         * <p>
15409         * <strong>NOTE:</strong> The configuration object is modified when adding an attribute, so if you need
15410         * to protect the original values, you will need to merge the object.
15411         * </p>
15412         *
15413         * @param {boolean} lazy (optional) Whether or not to add this attribute lazily (on the first call to get/set).
15414         *
15415         * @return {Object} A reference to the host object.
15416         *
15417         * @chainable
15418         */
15419        addAttr : function(name, config, lazy) {
15420
15421
15422            var host = this, // help compression
15423                state = host._state,
15424                data = state.data,
15425                value,
15426                added,
15427                hasValue;
15428
15429            config = config || {};
15430
15431            if (LAZY_ADD in config) {
15432                lazy = config[LAZY_ADD];
15433            }
15434
15435            added = state.get(name, ADDED);
15436
15437            if (lazy && !added) {
15438                state.data[name] = {
15439                    lazy : config,
15440                    added : true
15441                };
15442            } else {
15443
15444
15445                if (!added || config.isLazyAdd) {
15446
15447                    hasValue = (VALUE in config);
15448
15449
15450                    if (hasValue) {
15451
15452                        // We'll go through set, don't want to set value in config directly
15453
15454                        // PERF TODO: VALIDATE: See if setting this to undefined is sufficient. We use to delete before.
15455                        // In certain code paths/use cases, undefined may not be the same as not present.
15456                        // If not, we can set it to some known fixed value (like INVALID_VALUE, say INITIALIZING_VALUE) for performance,
15457                        // to avoid a delete which seems to help a lot.
15458
15459                        value = config.value;
15460                        config.value = undefined;
15461                    }
15462
15463                    config.added = true;
15464                    config.initializing = true;
15465
15466                    data[name] = config;
15467
15468                    if (hasValue) {
15469                        // Go through set, so that raw values get normalized/validated
15470                        host.set(name, value);
15471                    }
15472
15473                    config.initializing = false;
15474                }
15475            }
15476
15477            return host;
15478        },
15479
15480        /**
15481         * Checks if the given attribute has been added to the host
15482         *
15483         * @method attrAdded
15484         * @param {String} name The name of the attribute to check.
15485         * @return {boolean} true if an attribute with the given name has been added, false if it hasn't.
15486         *         This method will return true for lazily added attributes.
15487         */
15488        attrAdded: function(name) {
15489            return !!(this._state.get(name, ADDED));
15490        },
15491
15492        /**
15493         * Returns the current value of the attribute. If the attribute
15494         * has been configured with a 'getter' function, this method will delegate
15495         * to the 'getter' to obtain the value of the attribute.
15496         *
15497         * @method get
15498         *
15499         * @param {String} name The name of the attribute. If the value of the attribute is an Object,
15500         * dot notation can be used to obtain the value of a property of the object (e.g. <code>get("x.y.z")</code>)
15501         *
15502         * @return {Any} The value of the attribute
15503         */
15504        get : function(name) {
15505            return this._getAttr(name);
15506        },
15507
15508        /**
15509         * Checks whether or not the attribute is one which has been
15510         * added lazily and still requires initialization.
15511         *
15512         * @method _isLazyAttr
15513         * @private
15514         * @param {String} name The name of the attribute
15515         * @return {boolean} true if it's a lazily added attribute, false otherwise.
15516         */
15517        _isLazyAttr: function(name) {
15518            return this._state.get(name, LAZY);
15519        },
15520
15521        /**
15522         * Finishes initializing an attribute which has been lazily added.
15523         *
15524         * @method _addLazyAttr
15525         * @private
15526         * @param {Object} name The name of the attribute
15527         * @param {Object} [lazyCfg] Optional config hash for the attribute. This is added for performance
15528         * along the critical path, where the calling method has already obtained lazy config from state.
15529         */
15530        _addLazyAttr: function(name, lazyCfg) {
15531            var state = this._state;
15532
15533            lazyCfg = lazyCfg || state.get(name, LAZY);
15534
15535            if (lazyCfg) {
15536
15537                // PERF TODO: For App's id override, otherwise wouldn't be
15538                // needed. It expects to find it in the cfg for it's
15539                // addAttr override. Would like to remove, once App override is
15540                // removed.
15541                state.data[name].lazy = undefined;
15542
15543                lazyCfg.isLazyAdd = true;
15544
15545                this.addAttr(name, lazyCfg);
15546            }
15547        },
15548
15549        /**
15550         * Sets the value of an attribute.
15551         *
15552         * @method set
15553         * @chainable
15554         *
15555         * @param {String} name The name of the attribute. If the
15556         * current value of the attribute is an Object, dot notation can be used
15557         * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
15558         * @param {Any} value The value to set the attribute to.
15559         * @param {Object} [opts] Optional data providing the circumstances for the change.
15560         * @return {Object} A reference to the host object.
15561         */
15562        set : function(name, val, opts) {
15563            return this._setAttr(name, val, opts);
15564        },
15565
15566        /**
15567         * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
15568         *
15569         * @method _set
15570         * @protected
15571         * @chainable
15572         *
15573         * @param {String} name The name of the attribute.
15574         * @param {Any} val The value to set the attribute to.
15575         * @param {Object} [opts] Optional data providing the circumstances for the change.
15576         * @return {Object} A reference to the host object.
15577         */
15578        _set : function(name, val, opts) {
15579            return this._setAttr(name, val, opts, true);
15580        },
15581
15582        /**
15583         * Provides the common implementation for the public set and protected _set methods.
15584         *
15585         * See <a href="#method_set">set</a> for argument details.
15586         *
15587         * @method _setAttr
15588         * @protected
15589         * @chainable
15590         *
15591         * @param {String} name The name of the attribute.
15592         * @param {Any} value The value to set the attribute to.
15593         * @param {Object} [opts] Optional data providing the circumstances for the change.
15594         * @param {boolean} force If true, allows the caller to set values for
15595         * readOnly or writeOnce attributes which have already been set.
15596         *
15597         * @return {Object} A reference to the host object.
15598         */
15599        _setAttr : function(name, val, opts, force)  {
15600            var allowSet = true,
15601                state = this._state,
15602                stateProxy = this._stateProxy,
15603                tCfgs = this._tCfgs,
15604                cfg,
15605                initialSet,
15606                strPath,
15607                path,
15608                currVal,
15609                writeOnce,
15610                initializing;
15611
15612            if (name.indexOf(DOT) !== -1) {
15613                strPath = name;
15614
15615                path = name.split(DOT);
15616                name = path.shift();
15617            }
15618
15619            // On Demand - Should be rare - handles out of order valueFn, setter, getter references
15620            if (tCfgs && tCfgs[name]) {
15621                this._addOutOfOrder(name, tCfgs[name]);
15622            }
15623
15624            cfg = state.data[name] || {};
15625
15626            if (cfg.lazy) {
15627                cfg = cfg.lazy;
15628                this._addLazyAttr(name, cfg);
15629            }
15630
15631            initialSet = (cfg.value === undefined);
15632
15633            if (stateProxy && name in stateProxy && !cfg._bypassProxy) {
15634                // TODO: Value is always set for proxy. Can we do any better? Maybe take a snapshot as the initial value for the first call to set?
15635                initialSet = false;
15636            }
15637
15638            writeOnce = cfg.writeOnce;
15639            initializing = cfg.initializing;
15640
15641            if (!initialSet && !force) {
15642
15643                if (writeOnce) {
15644                    allowSet = false;
15645                }
15646
15647                if (cfg.readOnly) {
15648                    allowSet = false;
15649                }
15650            }
15651
15652            if (!initializing && !force && writeOnce === INIT_ONLY) {
15653                allowSet = false;
15654            }
15655
15656            if (allowSet) {
15657                // Don't need currVal if initialSet (might fail in custom getter if it always expects a non-undefined/non-null value)
15658                if (!initialSet) {
15659                    currVal =  this.get(name);
15660                }
15661
15662                if (path) {
15663                    var copyVal = [currVal].reduce(
15664                        function(retVal, currVal) {
15665                            Object.keys(currVal).forEach(
15666                                function(item) {
15667                                    retVal[item] = currVal[item];
15668                                }
15669                            );
15670                        return retVal;
15671                        },
15672                        {}
15673                    );
15674
15675                    var pathNode = copyVal;
15676                    var leafIdx = path.length - 1;
15677
15678                    for (var i = 0; i < leafIdx && pathNode; i++) {
15679                        pathNode = pathNode[path[i]];
15680                    }
15681
15682                    if (pathNode) {
15683                        delete pathNode[path[leafIdx]];
15684                    }
15685
15686                    val = O.setValue(Y.clone(copyVal), path, val);
15687
15688                    if (val === undefined) {
15689                        allowSet = false;
15690                    }
15691                }
15692
15693                if (allowSet) {
15694                    if (!this._fireAttrChange || initializing) {
15695                        this._setAttrVal(name, strPath, currVal, val, opts, cfg);
15696                    } else {
15697                        // HACK - no real reason core needs to know about _fireAttrChange, but
15698                        // it adds fn hops if we want to break it out. Not sure it's worth it for this critical path
15699                        this._fireAttrChange(name, strPath, currVal, val, opts, cfg);
15700                    }
15701                }
15702            }
15703
15704            return this;
15705        },
15706
15707        /**
15708         * Utility method used by get/set to add attributes
15709         * encountered out of order when calling addAttrs().
15710         *
15711         * For example, if:
15712         *
15713         *     this.addAttrs({
15714         *          foo: {
15715         *              setter: function() {
15716         *                 // make sure this bar is available when foo is added
15717         *                 this.get("bar");
15718         *              }
15719         *          },
15720         *          bar: {
15721         *              value: ...
15722         *          }
15723         *     });
15724         *
15725         * @method _addOutOfOrder
15726         * @private
15727         * @param name {String} attribute name
15728         * @param cfg {Object} attribute configuration
15729         */
15730        _addOutOfOrder : function(name, cfg) {
15731
15732            var attrs = {};
15733            attrs[name] = cfg;
15734
15735            delete this._tCfgs[name];
15736
15737            // TODO: The original code went through addAttrs, so
15738            // sticking with it for this pass. Seems like we could
15739            // just jump straight to _addAttr() and get some perf
15740            // improvement.
15741            this._addAttrs(attrs, this._tVals);
15742        },
15743
15744        /**
15745         * Provides the common implementation for the public get method,
15746         * allowing Attribute hosts to over-ride either method.
15747         *
15748         * See <a href="#method_get">get</a> for argument details.
15749         *
15750         * @method _getAttr
15751         * @protected
15752         * @chainable
15753         *
15754         * @param {String} name The name of the attribute.
15755         * @return {Any} The value of the attribute.
15756         */
15757        _getAttr : function(name) {
15758            var fullName = name,
15759                tCfgs = this._tCfgs,
15760                path,
15761                getter,
15762                val,
15763                attrCfg;
15764
15765            if (name.indexOf(DOT) !== -1) {
15766                path = name.split(DOT);
15767                name = path.shift();
15768            }
15769
15770            // On Demand - Should be rare - handles out of
15771            // order valueFn, setter, getter references
15772            if (tCfgs && tCfgs[name]) {
15773                this._addOutOfOrder(name, tCfgs[name]);
15774            }
15775
15776            attrCfg = this._state.data[name] || {};
15777
15778            // Lazy Init
15779            if (attrCfg.lazy) {
15780                attrCfg = attrCfg.lazy;
15781                this._addLazyAttr(name, attrCfg);
15782            }
15783
15784            val = this._getStateVal(name, attrCfg);
15785
15786            getter = attrCfg.getter;
15787
15788            if (getter && !getter.call) {
15789                getter = this[getter];
15790            }
15791
15792            val = (getter) ? getter.call(this, val, fullName) : val;
15793            val = (path) ? O.getValue(val, path) : val;
15794
15795            return val;
15796        },
15797
15798        /**
15799         * Gets the stored value for the attribute, from either the
15800         * internal state object, or the state proxy if it exits
15801         *
15802         * @method _getStateVal
15803         * @private
15804         * @param {String} name The name of the attribute
15805         * @param {Object} [cfg] Optional config hash for the attribute. This is added for performance along the critical path,
15806         * where the calling method has already obtained the config from state.
15807         *
15808         * @return {Any} The stored value of the attribute
15809         */
15810        _getStateVal : function(name, cfg) {
15811            var stateProxy = this._stateProxy;
15812
15813            if (!cfg) {
15814                cfg = this._state.getAll(name) || {};
15815            }
15816
15817            return (stateProxy && (name in stateProxy) && !(cfg._bypassProxy)) ? stateProxy[name] : cfg.value;
15818        },
15819
15820        /**
15821         * Sets the stored value for the attribute, in either the
15822         * internal state object, or the state proxy if it exits
15823         *
15824         * @method _setStateVal
15825         * @private
15826         * @param {String} name The name of the attribute
15827         * @param {Any} value The value of the attribute
15828         */
15829        _setStateVal : function(name, value) {
15830            var stateProxy = this._stateProxy;
15831            if (stateProxy && (name in stateProxy) && !this._state.get(name, BYPASS_PROXY)) {
15832                stateProxy[name] = value;
15833            } else {
15834                this._state.add(name, VALUE, value);
15835            }
15836        },
15837
15838        /**
15839         * Updates the stored value of the attribute in the privately held State object,
15840         * if validation and setter passes.
15841         *
15842         * @method _setAttrVal
15843         * @private
15844         * @param {String} attrName The attribute name.
15845         * @param {String} subAttrName The sub-attribute name, if setting a sub-attribute property ("x.y.z").
15846         * @param {Any} prevVal The currently stored value of the attribute.
15847         * @param {Any} newVal The value which is going to be stored.
15848         * @param {Object} [opts] Optional data providing the circumstances for the change.
15849         * @param {Object} [attrCfg] Optional config hash for the attribute. This is added for performance along the critical path,
15850         * where the calling method has already obtained the config from state.
15851         *
15852         * @return {Boolean} true if the new attribute value was stored, false if not.
15853         */
15854        _setAttrVal : function(attrName, subAttrName, prevVal, newVal, opts, attrCfg) {
15855
15856            var host = this,
15857                allowSet = true,
15858                cfg = attrCfg || this._state.data[attrName] || {},
15859                validator = cfg.validator,
15860                setter = cfg.setter,
15861                initializing = cfg.initializing,
15862                prevRawVal = this._getStateVal(attrName, cfg),
15863                name = subAttrName || attrName,
15864                retVal,
15865                valid;
15866
15867            if (validator) {
15868                if (!validator.call) {
15869                    // Assume string - trying to keep critical path tight, so avoiding Lang check
15870                    validator = this[validator];
15871                }
15872                if (validator) {
15873                    valid = validator.call(host, newVal, name, opts);
15874
15875                    if (!valid && initializing) {
15876                        newVal = cfg.defaultValue;
15877                        valid = true; // Assume it's valid, for perf.
15878                    }
15879                }
15880            }
15881
15882            if (!validator || valid) {
15883                if (setter) {
15884                    if (!setter.call) {
15885                        // Assume string - trying to keep critical path tight, so avoiding Lang check
15886                        setter = this[setter];
15887                    }
15888                    if (setter) {
15889                        retVal = setter.call(host, newVal, name, opts);
15890
15891                        if (retVal === INVALID_VALUE) {
15892                            if (initializing) {
15893                                newVal = cfg.defaultValue;
15894                            } else {
15895                                allowSet = false;
15896                            }
15897                        } else if (retVal !== undefined){
15898                            newVal = retVal;
15899                        }
15900                    }
15901                }
15902
15903                if (allowSet) {
15904                    if(!subAttrName && (newVal === prevRawVal) && !Lang.isObject(newVal)) {
15905                        allowSet = false;
15906                    } else {
15907                        // Store value
15908                        if (!(INIT_VALUE in cfg)) {
15909                            cfg.initValue = newVal;
15910                        }
15911                        host._setStateVal(attrName, newVal);
15912                    }
15913                }
15914
15915            } else {
15916                allowSet = false;
15917            }
15918
15919            return allowSet;
15920        },
15921
15922        /**
15923         * Sets multiple attribute values.
15924         *
15925         * @method setAttrs
15926         * @param {Object} attrs  An object with attributes name/value pairs.
15927         * @param {Object} [opts] Optional data providing the circumstances for the change.
15928         * @return {Object} A reference to the host object.
15929         * @chainable
15930         */
15931        setAttrs : function(attrs, opts) {
15932            return this._setAttrs(attrs, opts);
15933        },
15934
15935        /**
15936         * Implementation behind the public setAttrs method, to set multiple attribute values.
15937         *
15938         * @method _setAttrs
15939         * @protected
15940         * @param {Object} attrs  An object with attributes name/value pairs.
15941         * @param {Object} [opts] Optional data providing the circumstances for the change
15942         * @return {Object} A reference to the host object.
15943         * @chainable
15944         */
15945        _setAttrs : function(attrs, opts) {
15946            var attr;
15947            for (attr in attrs) {
15948                if ( attrs.hasOwnProperty(attr) ) {
15949                    this.set(attr, attrs[attr], opts);
15950                }
15951            }
15952            return this;
15953        },
15954
15955        /**
15956         * Gets multiple attribute values.
15957         *
15958         * @method getAttrs
15959         * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are
15960         * returned. If set to true, all attributes modified from their initial values are returned.
15961         * @return {Object} An object with attribute name/value pairs.
15962         */
15963        getAttrs : function(attrs) {
15964            return this._getAttrs(attrs);
15965        },
15966
15967        /**
15968         * Implementation behind the public getAttrs method, to get multiple attribute values.
15969         *
15970         * @method _getAttrs
15971         * @protected
15972         * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are
15973         * returned. If set to true, all attributes modified from their initial values are returned.
15974         * @return {Object} An object with attribute name/value pairs.
15975         */
15976        _getAttrs : function(attrs) {
15977            var obj = {},
15978                attr, i, len,
15979                modifiedOnly = (attrs === true);
15980
15981            // TODO - figure out how to get all "added"
15982            if (!attrs || modifiedOnly) {
15983                attrs = O.keys(this._state.data);
15984            }
15985
15986            for (i = 0, len = attrs.length; i < len; i++) {
15987                attr = attrs[i];
15988
15989                if (!modifiedOnly || this._getStateVal(attr) != this._state.get(attr, INIT_VALUE)) {
15990                    // Go through get, to honor cloning/normalization
15991                    obj[attr] = this.get(attr);
15992                }
15993            }
15994
15995            return obj;
15996        },
15997
15998        /**
15999         * Configures a group of attributes, and sets initial values.
16000         *
16001         * <p>
16002         * <strong>NOTE:</strong> This method does not isolate the configuration object by merging/cloning.
16003         * The caller is responsible for merging/cloning the configuration object if required.
16004         * </p>
16005         *
16006         * @method addAttrs
16007         * @chainable
16008         *
16009         * @param {Object} cfgs An object with attribute name/configuration pairs.
16010         * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply.
16011         * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only.
16012         * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set.
16013         * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration.
16014         * See <a href="#method_addAttr">addAttr</a>.
16015         *
16016         * @return {Object} A reference to the host object.
16017         */
16018        addAttrs : function(cfgs, values, lazy) {
16019            if (cfgs) {
16020                this._tCfgs = cfgs;
16021                this._tVals = (values) ? this._normAttrVals(values) : null;
16022                this._addAttrs(cfgs, this._tVals, lazy);
16023                this._tCfgs = this._tVals = null;
16024            }
16025
16026            return this;
16027        },
16028
16029        /**
16030         * Implementation behind the public addAttrs method.
16031         *
16032         * This method is invoked directly by get if it encounters a scenario
16033         * in which an attribute's valueFn attempts to obtain the
16034         * value an attribute in the same group of attributes, which has not yet
16035         * been added (on demand initialization).
16036         *
16037         * @method _addAttrs
16038         * @private
16039         * @param {Object} cfgs An object with attribute name/configuration pairs.
16040         * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply.
16041         * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only.
16042         * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set.
16043         * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration.
16044         * See <a href="#method_addAttr">addAttr</a>.
16045         */
16046        _addAttrs : function(cfgs, values, lazy) {
16047            var tCfgs = this._tCfgs,
16048                tVals = this._tVals,
16049                attr,
16050                attrCfg,
16051                value;
16052
16053            for (attr in cfgs) {
16054                if (cfgs.hasOwnProperty(attr)) {
16055
16056                    // Not Merging. Caller is responsible for isolating configs
16057                    attrCfg = cfgs[attr];
16058                    attrCfg.defaultValue = attrCfg.value;
16059
16060                    // Handle simple, complex and user values, accounting for read-only
16061                    value = this._getAttrInitVal(attr, attrCfg, tVals);
16062
16063                    if (value !== undefined) {
16064                        attrCfg.value = value;
16065                    }
16066
16067                    if (tCfgs[attr]) {
16068                        tCfgs[attr] = undefined;
16069                    }
16070
16071                    this.addAttr(attr, attrCfg, lazy);
16072                }
16073            }
16074        },
16075
16076        /**
16077         * Utility method to protect an attribute configuration
16078         * hash, by merging the entire object and the individual
16079         * attr config objects.
16080         *
16081         * @method _protectAttrs
16082         * @protected
16083         * @param {Object} attrs A hash of attribute to configuration object pairs.
16084         * @return {Object} A protected version of the attrs argument.
16085         * @deprecated Use `AttributeCore.protectAttrs()` or
16086         *   `Attribute.protectAttrs()` which are the same static utility method.
16087         */
16088        _protectAttrs : AttributeCore.protectAttrs,
16089
16090        /**
16091         * Utility method to normalize attribute values. The base implementation
16092         * simply merges the hash to protect the original.
16093         *
16094         * @method _normAttrVals
16095         * @param {Object} valueHash An object with attribute name/value pairs
16096         *
16097         * @return {Object} An object literal with 2 properties - "simple" and "complex",
16098         * containing simple and complex attribute values respectively keyed
16099         * by the top level attribute name, or null, if valueHash is falsey.
16100         *
16101         * @private
16102         */
16103        _normAttrVals : function(valueHash) {
16104            var vals,
16105                subvals,
16106                path,
16107                attr,
16108                v, k;
16109
16110            if (!valueHash) {
16111                return null;
16112            }
16113
16114            vals = {};
16115
16116            for (k in valueHash) {
16117                if (valueHash.hasOwnProperty(k)) {
16118                    if (k.indexOf(DOT) !== -1) {
16119                        path = k.split(DOT);
16120                        attr = path.shift();
16121
16122                        subvals = subvals || {};
16123
16124                        v = subvals[attr] = subvals[attr] || [];
16125                        v[v.length] = {
16126                            path : path,
16127                            value: valueHash[k]
16128                        };
16129                    } else {
16130                        vals[k] = valueHash[k];
16131                    }
16132                }
16133            }
16134
16135            return { simple:vals, complex:subvals };
16136        },
16137
16138        /**
16139         * Returns the initial value of the given attribute from
16140         * either the default configuration provided, or the
16141         * over-ridden value if it exists in the set of initValues
16142         * provided and the attribute is not read-only.
16143         *
16144         * @param {String} attr The name of the attribute
16145         * @param {Object} cfg The attribute configuration object
16146         * @param {Object}
16146 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
16147         *
16148         * @return {Any} The initial value of the attribute.
16149         *
16150         * @method _getAttrInitVal
16151         * @private
16152         */
16153        _getAttrInitVal : function(attr, cfg, initValues) {
16154            var val = cfg.value,
16155                valFn = cfg.valueFn,
16156                tmpVal,
16157                initValSet = false,
16158                readOnly = cfg.readOnly,
16159                simple,
16160                complex,
16161                i,
16162                l,
16163                path,
16164                subval,
16165                subvals;
16166
16167            if (!readOnly && initValues) {
16168                // Simple Attributes
16169                simple = initValues.simple;
16170                if (simple && simple.hasOwnProperty(attr)) {
16171                    val = simple[attr];
16172                    initValSet = true;
16173                }
16174            }
16175
16176            if (valFn && !initValSet) {
16177                if (!valFn.call) {
16178                    valFn = this[valFn];
16179                }
16180                if (valFn) {
16181                    tmpVal = valFn.call(this, attr);
16182                    val = tmpVal;
16183                }
16184            }
16185
16186            if (!readOnly && initValues) {
16187
16188                // Complex Attributes (complex values applied, after simple, in case both are set)
16189                complex = initValues.complex;
16190
16191                if (complex && complex.hasOwnProperty(attr) && (val !== undefined) && (val !== null)) {
16192                    subvals = complex[attr];
16193                    for (i = 0, l = subvals.length; i < l; ++i) {
16194                        path = subvals[i].path;
16195                        subval = subvals[i].value;
16196                        O.setValue(val, path, subval);
16197                    }
16198                }
16199            }
16200
16201            return val;
16202        },
16203
16204        /**
16205         * Utility method to set up initial attributes defined during construction,
16206         * either through the constructor.ATTRS property, or explicitly passed in.
16207         *
16208         * @method _initAttrs
16209         * @protected
16210         * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
16211         *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
16212         * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
16213         *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
16214         * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
16215         */
16216        _initAttrs : function(attrs, values, lazy) {
16217            // ATTRS support for Node, which is not Base based
16218            attrs = attrs || this.constructor.ATTRS;
16219
16220            var Base = Y.Base,
16221                BaseCore = Y.BaseCore,
16222                baseInst = (Base && Y.instanceOf(this, Base)),
16223                baseCoreInst = (!baseInst && BaseCore && Y.instanceOf(this, BaseCore));
16224
16225            if (attrs && !baseInst && !baseCoreInst) {
16226                this.addAttrs(Y.AttributeCore.protectAttrs(attrs), values, lazy);
16227            }
16228        }
16229    };
16230
16231    Y.AttributeCore = AttributeCore;
16232
16233
16234}, 'patched-v3.18.1', {"requires": ["oop"]});
16235
16236YUI.add('attribute-observable', function (Y, NAME) {
16237
16238    /*For log lines*/
16239    /*jshint maxlen:200*/
16240
16241
16242    /**
16243     * The attribute module provides an augmentable Attribute implementation, which
16244     * adds configurable attributes and attribute change events to the class being
16245     * augmented. It also provides a State class, which is used internally by Attribute,
16246     * but can also be used independently to provide a name/property/value data structure to
16247     * store state.
16248     *
16249     * @module attribute
16250     */
16251
16252    /**
16253     * The `attribute-observable` submodule provides augmentable attribute change event support
16254     * for AttributeCore based implementations.
16255     *
16256     * @module attribute
16257     * @submodule attribute-observable
16258     */
16259    var EventTarget = Y.EventTarget,
16260
16261        CHANGE = "Change",
16262        BROADCAST = "broadcast";
16263
16264    /**
16265     * Provides an augmentable implementation of attribute change events for
16266     * AttributeCore.
16267     *
16268     * @class AttributeObservable
16269     * @extensionfor AttributeCore
16270     * @uses EventTarget
16271     */
16272    function AttributeObservable() {
16273        // Perf tweak - avoid creating event literals if not required.
16274        this._ATTR_E_FACADE = {};
16275
16276        EventTarget.call(this, {emitFacade:true});
16277    }
16278
16279    AttributeObservable._ATTR_CFG = [BROADCAST];
16280
16281    AttributeObservable.prototype = {
16282
16283        /**
16284         * Sets the value of an attribute.
16285         *
16286         * @method set
16287         * @chainable
16288         *
16289         * @param {String} name The name of the attribute. If the
16290         * current value of the attribute is an Object, dot notation can be used
16291         * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
16292         *
16293         * @param {Any} value The value to set the attribute to.
16294         *
16295         * @param {Object} opts (Optional) Optional event data to be mixed into
16296         * the event facade passed to subscribers of the attribute's change event. This
16297         * can be used as a flexible way to identify the source of a call to set, allowing
16298         * the developer to distinguish between set called internally by the host, vs.
16299         * set called externally by the application developer.
16300         *
16301         * @return {Object} A reference to the host object.
16302         */
16303        set : function(name, val, opts) {
16304            return this._setAttr(name, val, opts);
16305        },
16306
16307        /**
16308         * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
16309         *
16310         * @method _set
16311         * @protected
16312         * @chainable
16313         *
16314         * @param {String} name The name of the attribute.
16315         * @param {Any} val The value to set the attribute to.
16316         * @param {Object} opts (Optional) Optional event data to be mixed into
16317         * the event facade passed to subscribers of the attribute's change event.
16318         * @return {Object} A reference to the host object.
16319         */
16320        _set : function(name, val, opts) {
16321            return this._setAttr(name, val, opts, true);
16322        },
16323
16324        /**
16325         * Sets multiple attribute values.
16326         *
16327         * @method setAttrs
16328         * @param {Object} attrs  An object with attributes name/value pairs.
16329         * @param {Object} opts  Properties to mix into the event payload. These are shared and mixed into each set
16330         * @return {Object} A reference to the host object.
16331         * @chainable
16332         */
16333        setAttrs : function(attrs, opts) {
16334            return this._setAttrs(attrs, opts);
16335        },
16336
16337        /**
16338         * Implementation behind the public setAttrs method, to set multiple attribute values.
16339         *
16340         * @method _setAttrs
16341         * @protected
16342         * @param {Object} attrs  An object with attributes name/value pairs.
16343         * @param {Object} opts  Properties to mix into the event payload. These are shared and mixed into each set
16344         * @return {Object} A reference to the host object.
16345         * @chainable
16346         */
16347        _setAttrs : function(attrs, opts) {
16348            var attr;
16349            for (attr in attrs) {
16350                if ( attrs.hasOwnProperty(attr) ) {
16351                    this.set(attr, attrs[attr], opts);
16352                }
16353            }
16354            return this;
16355        },
16356
16357        /**
16358         * Utility method to help setup the event payload and fire the attribute change event.
16359         *
16360         * @method _fireAttrChange
16361         * @private
16362         * @param {String} attrName The name of the attribute
16363         * @param {String} subAttrName The full path of the property being changed,
16364         * if this is a sub-attribute value being change. Otherwise null.
16365         * @param {Any} currVal The current value of the attribute
16366         * @param {Any} newVal The new value of the attribute
16367         * @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
16368         * @param {Object} [cfg] The attribute config stored in State, if already available.
16369         */
16370        _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
16371            var host = this,
16372                eventName = this._getFullType(attrName + CHANGE),
16373                state = host._state,
16374                facade,
16375                broadcast,
16376                e;
16377
16378            if (!cfg) {
16379                cfg = state.data[attrName] || {};
16380            }
16381
16382            if (!cfg.published) {
16383
16384                // PERF: Using lower level _publish() for
16385                // critical path performance
16386                e = host._publish(eventName);
16387
16388                e.emitFacade = true;
16389                e.defaultTargetOnly = true;
16390                e.defaultFn = host._defAttrChangeFn;
16391
16392                broadcast = cfg.broadcast;
16393                if (broadcast !== undefined) {
16394                    e.broadcast = broadcast;
16395                }
16396
16397                cfg.published = true;
16398            }
16399
16400            if (opts) {
16401                facade = Y.merge(opts);
16402                facade._attrOpts = opts;
16403            } else {
16404                facade = host._ATTR_E_FACADE;
16405            }
16406
16407            // Not using the single object signature for fire({type:..., newVal:...}), since
16408            // we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
16409
16410            facade.attrName = attrName;
16411            facade.subAttrName = subAttrName;
16412            facade.prevVal = currVal;
16413            facade.newVal = newVal;
16414
16415            if (host._hasPotentialSubscribers(eventName)) {
16416                host.fire(eventName, facade);
16417            } else {
16418                this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
16419            }
16420        },
16421
16422        /**
16423         * Default function for attribute change events.
16424         *
16425         * @private
16426         * @method _defAttrChangeFn
16427         * @param {EventFacade} e The event object for attribute change events.
16428         * @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not
16429         */
16430        _defAttrChangeFn : function(e, eventFastPath) {
16431
16432            var opts = e._attrOpts;
16433            if (opts) {
16434                delete e._attrOpts;
16435            }
16436
16437            if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) {
16438
16439
16440                if (!eventFastPath) {
16441                    // Prevent "after" listeners from being invoked since nothing changed.
16442                    e.stopImmediatePropagation();
16443                }
16444
16445            } else {
16446                if (!eventFastPath) {
16447                    e.newVal = this.get(e.attrName);
16448                }
16449            }
16450        }
16451    };
16452
16453    // Basic prototype augment - no lazy constructor invocation.
16454    Y.mix(AttributeObservable, EventTarget, false, null, 1);
16455
16456    Y.AttributeObservable = AttributeObservable;
16457
16458    /**
16459    The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now
16460    an alias for the `AttributeObservable` class extension. Use that class
16461    extnesion instead. This alias will be removed in a future version of YUI.
16462
16463    @class AttributeEvents
16464    @uses EventTarget
16465    @deprecated Use `AttributeObservable` instead.
16466    @see AttributeObservable
16467    **/
16468    Y.AttributeEvents = AttributeObservable;
16469
16470
16471}, 'patched-v3.18.1', {"requires": ["event-custom"]});
16472
16473YUI.add('attribute-extras', function (Y, NAME) {
16474
16475    /**
16476     * The attribute module provides an augmentable Attribute implementation, which
16477     * adds configurable attributes and attribute change events to the class being
16478     * augmented. It also provides a State class, which is used internally by Attribute,
16479     * but can also be used independently to provide a name/property/value data structure to
16480     * store state.
16481     *
16482     * @module attribute
16483     */
16484
16485    /**
16486     * The attribute-extras submodule provides less commonly used attribute methods, and can
16487     * be augmented/mixed into an implemention which used attribute-core.
16488     *
16489     * @module attribute
16490     * @submodule attribute-extras
16491     */
16492    var BROADCAST = "broadcast",
16493        PUBLISHED = "published",
16494        INIT_VALUE = "initValue",
16495
16496        MODIFIABLE = {
16497            readOnly:1,
16498            writeOnce:1,
16499            getter:1,
16500            broadcast:1
16501        };
16502
16503    /**
16504     * A augmentable implementation for AttributeCore, providing less frequently used
16505     * methods for Attribute management such as modifyAttrs(), removeAttr and reset()
16506     *
16507     * @class AttributeExtras
16508     * @extensionfor AttributeCore
16509     */
16510    function AttributeExtras() {}
16511
16512    AttributeExtras.prototype = {
16513
16514        /**
16515         * Updates the configuration of an attribute which has already been added.
16516         * <p>
16517         * The properties which can be modified through this interface are limited
16518         * to the following subset of attributes, which can be safely modified
16519         * after a value has already been set on the attribute:
16520         * </p>
16521         * <dl>
16522         *  <dt>readOnly;</dt>
16523         *  <dt>writeOnce;</dt>
16524         *  <dt>broadcast; and</dt>
16525         *  <dt>getter.</dt>
16526         * </dl>
16527         * <p>
16528         * Note: New attributes cannot be added using this interface. New attributes must be
16529         * added using {{#crossLink "AttributeCore/addAttr:method"}}addAttr{{/crossLink}}, or an
16530         * appropriate manner for a class which utilises Attributes (e.g. the
16531         * {{#crossLink "Base/ATTRS:property"}}ATTRS{{/crossLink}} property in
16532         * {{#crossLink "Base"}}Base{{/crossLink}}).
16533         * </p>
16534         * @method modifyAttr
16535         * @param {String} name The name of the attribute whose configuration is to be updated.
16536         * @param {Object} config An object with configuration property/value pairs, specifying the configuration properties to modify.
16537         */
16538        modifyAttr: function(name, config) {
16539            var host = this, // help compression
16540                prop, state;
16541
16542            if (host.attrAdded(name)) {
16543
16544                if (host._isLazyAttr(name)) {
16545                    host._addLazyAttr(name);
16546                }
16547
16548                state = host._state;
16549                for (prop in config) {
16550                    if (MODIFIABLE[prop] && config.hasOwnProperty(prop)) {
16551                        state.add(name, prop, config[prop]);
16552
16553                        // If we reconfigured broadcast, need to republish
16554                        if (prop === BROADCAST) {
16555                            state.remove(name, PUBLISHED);
16556                        }
16557                    }
16558                }
16559            } else {
16560            }
16561        },
16562
16563        /**
16564         * Removes an attribute from the host object
16565         *
16566         * @method removeAttr
16567         * @param {String} name The name of the attribute to be removed.
16568         */
16569        removeAttr: function(name) {
16570            this._state.removeAll(name);
16571        },
16572
16573        /**
16574         * Resets the attribute (or all attributes) to its initial value, as long as
16575         * the attribute is not readOnly, or writeOnce.
16576         *
16577         * @method reset
16578         * @param {String} name Optional. The name of the attribute to reset.  If omitted, all attributes are reset.
16579         * @return {Object} A reference to the host object.
16580         * @chainable
16581         */
16582        reset : function(name) {
16583            var host = this;  // help compression
16584
16585            if (name) {
16586                if (host._isLazyAttr(name)) {
16587                    host._addLazyAttr(name);
16588                }
16589                host.set(name, host._state.get(name, INIT_VALUE));
16590            } else {
16591                Y.Object.each(host._state.data, function(v, n) {
16592                    host.reset(n);
16593                });
16594            }
16595            return host;
16596        },
16597
16598        /**
16599         * Returns an object with the configuration properties (and value)
16600         * for the given attribute. If attrName is not provided, returns the
16601         * configuration properties for all attributes.
16602         *
16603         * @method _getAttrCfg
16604         * @protected
16605         * @param {String} name Optional. The attribute name. If not provided, the method will return the configuration for all attributes.
16606         * @return {Object} The configuration properties for the given attribute, or all attributes.
16607         */
16608        _getAttrCfg : function(name) {
16609            var o,
16610                state = this._state;
16611
16612            if (name) {
16613                o = state.getAll(name) || {};
16614            } else {
16615                o = {};
16616                Y.each(state.data, function(v, n) {
16617                    o[n] = state.getAll(n);
16618                });
16619            }
16620
16621            return o;
16622        }
16623    };
16624
16625    Y.AttributeExtras = AttributeExtras;
16626
16627
16628}, 'patched-v3.18.1', {"requires": ["oop"]});
16629
16630YUI.add('event-custom-base', function (Y, NAME) {
16631
16632/**
16633 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
16634 * events.
16635 * @module event-custom
16636 */
16637
16638Y.Env.evt = {
16639    handles: {},
16640    plugins: {}
16641};
16642
16643/**
16644 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
16645 * events.
16646 * @module event-custom
16647 * @submodule event-custom-base
16648 */
16649
16650/**
16651 * Allows for the insertion of methods that are executed before or after
16652 * a specified method
16653 * @class Do
16654 * @static
16655 */
16656
16657var DO_BEFORE = 0,
16658    DO_AFTER = 1,
16659
16660DO = {
16661
16662    /**
16663     * Cache of objects touched by the utility
16664     * @property objs
16665     * @static
16666     * @deprecated Since 3.6.0. The `_yuiaop` property on the AOP'd object
16667     * replaces the role of this property, but is considered to be private, and
16668     * is only mentioned to provide a migration path.
16669     *
16670     * If you have a use case which warrants migration to the _yuiaop property,
16671     * please file a ticket to let us know what it's used for and we can see if
16672     * we need to expose hooks for that functionality more formally.
16673     */
16674    objs: null,
16675
16676    /**
16677     * <p>Execute the supplied method before the specified function.  Wrapping
16678     * function may optionally return an instance of the following classes to
16679     * further alter runtime behavior:</p>
16680     * <dl>
16681     *     <dt></code>Y.Do.Halt(message, returnValue)</code></dt>
16682     *         <dd>Immediatly stop execution and return
16683     *         <code>returnValue</code>.  No other wrapping functions will be
16684     *         executed.</dd>
16685     *     <dt></code>Y.Do.AlterArgs(message, newArgArray)</code></dt>
16686     *         <dd>Replace the arguments that the original function will be
16687     *         called with.</dd>
16688     *     <dt></code>Y.Do.Prevent(message)</code></dt>
16689     *         <dd>Don't execute the wrapped function.  Other before phase
16690     *         wrappers will be executed.</dd>
16691     * </dl>
16692     *
16693     * @method before
16694     * @param fn {Function} the function to execute
16695     * @param obj the object hosting the method to displace
16696     * @param sFn {string} the name of the method to displace
16697     * @param c The execution context for fn
16698     * @param arg* {mixed} 0..n additional arguments to supply to the subscriber
16699     * when the event fires.
16700     * @return {EventHandle} handle for the subscription
16701     * @static
16702     */
16703    before: function(fn, obj, sFn, c) {
16704        var f = fn, a;
16705        if (c) {
16706            a = [fn, c].concat(Y.Array(arguments, 4, true));
16707            f = Y.rbind.apply(Y, a);
16708        }
16709
16710        return this._inject(DO_BEFORE, f, obj, sFn);
16711    },
16712
16713    /**
16714     * <p>Execute the supplied method after the specified function.  Wrapping
16715     * function may optionally return an instance of the following classes to
16716     * further alter runtime behavior:</p>
16717     * <dl>
16718     *     <dt></code>Y.Do.Halt(message, returnValue)</code></dt>
16719     *         <dd>Immediatly stop execution and return
16720     *         <code>returnValue</code>.  No other wrapping functions will be
16721     *         executed.</dd>
16722     *     <dt></code>Y.Do.AlterReturn(message, returnValue)</code></dt>
16723     *         <dd>Return <code>returnValue</code> instead of the wrapped
16724     *         method's original return value.  This can be further altered by
16725     *         other after phase wrappers.</dd>
16726     * </dl>
16727     *
16728     * <p>The static properties <code>Y.Do.originalRetVal</code> and
16729     * <code>Y.Do.currentRetVal</code> will be populated for reference.</p>
16730     *
16731     * @method after
16732     * @param fn {Function} the function to execute
16733     * @param obj the object hosting the method to displace
16734     * @param sFn {string} the name of the method to displace
16735     * @param c The execution context for fn
16736     * @param arg* {mixed} 0..n additional arguments to supply to the subscriber
16737     * @return {EventHandle} handle for the subscription
16738     * @static
16739     */
16740    after: function(fn, obj, sFn, c) {
16741        var f = fn, a;
16742        if (c) {
16743            a = [fn, c].concat(Y.Array(arguments, 4, true));
16744            f = Y.rbind.apply(Y, a);
16745        }
16746
16747        return this._inject(DO_AFTER, f, obj, sFn);
16748    },
16749
16750    /**
16751     * Execute the supplied method before or after the specified function.
16752     * Used by <code>before</code> and <code>after</code>.
16753     *
16754     * @method _inject
16755     * @param when {string} before or after
16756     * @param fn {Function} the function to execute
16757     * @param obj the object hosting the method to displace
16758     * @param sFn {string} the name of the method to displace
16759     * @param c The execution context for fn
16760     * @return {EventHandle} handle for the subscription
16761     * @private
16762     * @static
16763     */
16764    _inject: function(when, fn, obj, sFn) {
16765        // object id
16766        var id = Y.stamp(obj), o, sid;
16767
16768        if (!obj._yuiaop) {
16769            // create a map entry for the obj if it doesn't exist, to hold overridden methods
16770            obj._yuiaop = {};
16771        }
16772
16773        o = obj._yuiaop;
16774
16775        if (!o[sFn]) {
16776            // create a map entry for the method if it doesn't exist
16777            o[sFn] = new Y.Do.Method(obj, sFn);
16778
16779            // re-route the method to our wrapper
16780            obj[sFn] = function() {
16781                return o[sFn].exec.apply(o[sFn], arguments);
16782            };
16783        }
16784
16785        // subscriber id
16786        sid = id + Y.stamp(fn) + sFn;
16787
16788        // register the callback
16789        o[sFn].register(sid, fn, when);
16790
16791        return new Y.EventHandle(o[sFn], sid);
16792    },
16793
16794    /**
16795     * Detach a before or after subscription.
16796     *
16797     * @method detach
16798     * @param handle {EventHandle} the subscription handle
16799     * @static
16800     */
16801    detach: function(handle) {
16802        if (handle.detach) {
16803            handle.detach();
16804        }
16805    }
16806};
16807
16808Y.Do = DO;
16809
16810//////////////////////////////////////////////////////////////////////////
16811
16812/**
16813 * Contains the return value from the wrapped method, accessible
16814 * by 'after' event listeners.
16815 *
16816 * @property originalRetVal
16817 * @static
16818 * @since 3.2.0
16819 */
16820
16821/**
16822 * Contains the current state of the return value, consumable by
16823 * 'after' event listeners, and updated if an after subscriber
16824 * changes the return value generated by the wrapped function.
16825 *
16826 * @property currentRetVal
16827 * @static
16828 * @since 3.2.0
16829 */
16830
16831//////////////////////////////////////////////////////////////////////////
16832
16833/**
16834 * Wrapper for a displaced method with aop enabled
16835 * @class Do.Method
16836 * @constructor
16837 * @param obj The object to operate on
16838 * @param sFn The name of the method to displace
16839 */
16840DO.Method = function(obj, sFn) {
16841    this.obj = obj;
16842    this.methodName = sFn;
16843    this.method = obj[sFn];
16844    this.before = {};
16845    this.after = {};
16846};
16847
16848/**
16849 * Register a aop subscriber
16850 * @method register
16851 * @param sid {string} the subscriber id
16852 * @param fn {Function} the function to execute
16853 * @param when {string} when to execute the function
16854 */
16855DO.Method.prototype.register = function (sid, fn, when) {
16856    if (when) {
16857        this.after[sid] = fn;
16858    } else {
16859        this.before[sid] = fn;
16860    }
16861};
16862
16863/**
16864 * Unregister a aop subscriber
16865 * @method delete
16866 * @param sid {string} the subscriber id
16867 * @param fn {Function} the function to execute
16868 * @param when {string} when to execute the function
16869 */
16870DO.Method.prototype._delete = function (sid) {
16871    delete this.before[sid];
16872    delete this.after[sid];
16873};
16874
16875/**
16876 * <p>Execute the wrapped method.  All arguments are passed into the wrapping
16877 * functions.  If any of the before wrappers return an instance of
16878 * <code>Y.Do.Halt</code> or <code>Y.Do.Prevent</code>, neither the wrapped
16879 * function nor any after phase subscribers will be executed.</p>
16880 *
16881 * <p>The return value will be the return value of the wrapped function or one
16882 * provided by a wrapper function via an instance of <code>Y.Do.Halt</code> or
16883 * <code>Y.Do.AlterReturn</code>.
16884 *
16885 * @method exec
16886 * @param arg* {any} Arguments are passed to the wrapping and wrapped functions
16887 * @return {any} Return value of wrapped function unless overwritten (see above)
16888 */
16889DO.Method.prototype.exec = function () {
16890
16891    var args = Y.Array(arguments, 0, true),
16892        i, ret, newRet,
16893        bf = this.before,
16894        af = this.after,
16895        prevented = false;
16896
16897    // execute before
16898    for (i in bf) {
16899        if (bf.hasOwnProperty(i)) {
16900            ret = bf[i].apply(this.obj, args);
16901            if (ret) {
16902                switch (ret.constructor) {
16903                    case DO.Halt:
16904                        return ret.retVal;
16905                    case DO.AlterArgs:
16906                        args = ret.newArgs;
16907                        break;
16908                    case DO.Prevent:
16909                        prevented = true;
16910                        break;
16911                    default:
16912                }
16913            }
16914        }
16915    }
16916
16917    // execute method
16918    if (!prevented) {
16919        ret = this.method.apply(this.obj, args);
16920    }
16921
16922    DO.originalRetVal = ret;
16923    DO.currentRetVal = ret;
16924
16925    // execute after methods.
16926    for (i in af) {
16927        if (af.hasOwnProperty(i)) {
16928            newRet = af[i].apply(this.obj, args);
16929            // Stop processing if a Halt object is returned
16930            if (newRet && newRet.constructor === DO.Halt) {
16931                return newRet.retVal;
16932            // Check for a new return value
16933            } else if (newRet && newRet.constructor === DO.AlterReturn) {
16934                ret = newRet.newRetVal;
16935                // Update the static retval state
16936                DO.currentRetVal = ret;
16937            }
16938        }
16939    }
16940
16941    return ret;
16942};
16943
16944//////////////////////////////////////////////////////////////////////////
16945
16946/**
16947 * Return an AlterArgs object when you want to change the arguments that
16948 * were passed into the function.  Useful for Do.before subscribers.  An
16949 * example would be a service that scrubs out illegal characters prior to
16950 * executing the core business logic.
16951 * @class Do.AlterArgs
16952 * @constructor
16953 * @param msg {String} (optional) Explanation of the altered return value
16954 * @param newArgs {Array} Call parameters to be used for the original method
16955 *                        instead of the arguments originally passed in.
16956 */
16957DO.AlterArgs = function(msg, newArgs) {
16958    this.msg = msg;
16959    this.newArgs = newArgs;
16960};
16961
16962/**
16963 * Return an AlterReturn object when you want to change the result returned
16964 * from the core method to the caller.  Useful for Do.after subscribers.
16965 * @class Do.AlterReturn
16966 * @constructor
16967 * @param msg {String} (optional) Explanation of the altered return value
16968 * @param newRetVal {any} Return value passed to code that invoked the wrapped
16969 *                      function.
16970 */
16971DO.AlterReturn = function(msg, newRetVal) {
16972    this.msg = msg;
16973    this.newRetVal = newRetVal;
16974};
16975
16976/**
16977 * Return a Halt object when you want to terminate the execution
16978 * of all subsequent subscribers as well as the wrapped method
16979 * if it has not exectued yet.  Useful for Do.before subscribers.
16980 * @class Do.Halt
16981 * @constructor
16982 * @param msg {String} (optional) Explanation of why the termination was done
16983 * @param retVal {any} Return value passed to code that invoked the wrapped
16984 *                      function.
16985 */
16986DO.Halt = function(msg, retVal) {
16987    this.msg = msg;
16988    this.retVal = retVal;
16989};
16990
16991/**
16992 * Return a Prevent object when you want to prevent the wrapped function
16993 * from executing, but want the remaining listeners to execute.  Useful
16994 * for Do.before subscribers.
16995 * @class Do.Prevent
16996 * @constructor
16997 * @param msg {String} (optional) Explanation of why the termination was done
16998 */
16999DO.Prevent = function(msg) {
17000    this.msg = msg;
17001};
17002
17003/**
17004 * Return an Error object when you want to terminate the execution
17005 * of all subsequent method calls.
17006 * @class Do.Error
17007 * @constructor
17008 * @param msg {String} (optional) Explanation of the altered return value
17009 * @param retVal {any} Return value passed to code that invoked the wrapped
17010 *                      function.
17011 * @deprecated use Y.Do.Halt or Y.Do.Prevent
17012 */
17013DO.Error = DO.Halt;
17014
17015
17016//////////////////////////////////////////////////////////////////////////
17017
17018/**
17019 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
17020 * events.
17021 * @module event-custom
17022 * @submodule event-custom-base
17023 */
17024
17025
17026// var onsubscribeType = "_event:onsub",
17027var YArray = Y.Array,
17028
17029    AFTER = 'after',
17030    CONFIGS = [
17031        'broadcast',
17032        'monitored',
17033        'bubbles',
17034        'context',
17035        'contextFn',
17036        'currentTarget',
17037        'defaultFn',
17038        'defaultTargetOnly',
17039        'details',
17040        'emitFacade',
17041        'fireOnce',
17042        'async',
17043        'host',
17044        'preventable',
17045        'preventedFn',
17046        'queuable',
17047        'silent',
17048        'stoppedFn',
17049        'target',
17050        'type'
17051    ],
17052
17053    CONFIGS_HASH = YArray.hash(CONFIGS),
17054
17055    nativeSlice = Array.prototype.slice,
17056
17057    YUI3_SIGNATURE = 9,
17058    YUI_LOG = 'yui:log',
17059
17060    mixConfigs = function(r, s, ov) {
17061        var p;
17062
17063        for (p in s) {
17064            if (CONFIGS_HASH[p] && (ov || !(p in r))) {
17065                r[p] = s[p];
17066            }
17067        }
17068
17069        return r;
17070    };
17071
17072/**
17073 * The CustomEvent class lets you define events for your application
17074 * that can be subscribed to by one or more independent component.
17075 *
17076 * @param {String} type The type of event, which is passed to the callback
17077 * when the event fires.
17078 * @param {object} defaults configuration object.
17079 * @class CustomEvent
17080 * @constructor
17081 */
17082
17083 /**
17084 * The type of event, returned to subscribers when the event fires
17085 * @property type
17086 * @type string
17087 */
17088
17089/**
17090 * By default all custom events are logged in the debug build, set silent
17091 * to true to disable debug outpu for this event.
17092 * @property silent
17093 * @type boolean
17094 */
17095
17096Y.CustomEvent = function(type, defaults) {
17097
17098    this._kds = Y.CustomEvent.keepDeprecatedSubs;
17099
17100    this.id = Y.guid();
17101
17102    this.type = type;
17103    this.silent = this.logSystem = (type === YUI_LOG);
17104
17105    if (this._kds) {
17106        /**
17107         * The subscribers to this event
17108         * @property subscribers
17109         * @type Subscriber {}
17110         * @deprecated
17111         */
17112
17113        /**
17114         * 'After' subscribers
17115         * @property afters
17116         * @type Subscriber {}
17117         * @deprecated
17118         */
17119        this.subscribers = {};
17120        this.afters = {};
17121    }
17122
17123    if (defaults) {
17124        mixConfigs(this, defaults, true);
17125    }
17126};
17127
17128/**
17129 * Static flag to enable population of the <a href="#property_subscribers">`subscribers`</a>
17130 * and  <a href="#property_subscribers">`afters`</a> properties held on a `CustomEvent` instance.
17131 *
17132 * These properties were changed to private properties (`_subscribers` and `_afters`), and
17133 * converted from objects to arrays for performance reasons.
17134 *
17135 * Setting this property to true will populate the deprecated `subscribers` and `afters`
17136 * properties for people who may be using them (which is expected to be rare). There will
17137 * be a performance hit, compared to the new array based implementation.
17138 *
17139 * If you are using these deprecated properties for a use case which the public API
17140 * does not support, please file an enhancement request, and we can provide an alternate
17141 * public implementation which doesn't have the performance cost required to maintiain the
17142 * properties as objects.
17143 *
17144 * @property keepDeprecatedSubs
17145 * @static
17146 * @for CustomEvent
17147 * @type boolean
17148 * @default false
17149 * @deprecated
17150 */
17151Y.CustomEvent.keepDeprecatedSubs = false;
17152
17153Y.CustomEvent.mixConfigs = mixConfigs;
17154
17155Y.CustomEvent.prototype = {
17156
17157    constructor: Y.CustomEvent,
17158
17159    /**
17160     * Monitor when an event is attached or detached.
17161     *
17162     * @property monitored
17163     * @type boolean
17164     */
17165
17166    /**
17167     * If 0, this event does not broadcast.  If 1, the YUI instance is notified
17168     * every time this event fires.  If 2, the YUI instance and the YUI global
17169     * (if event is enabled on the global) are notified every time this event
17170     * fires.
17171     * @property broadcast
17172     * @type int
17173     */
17174
17175    /**
17176     * Specifies whether this event should be queued when the host is actively
17177     * processing an event.  This will effect exectution order of the callbacks
17178     * for the various events.
17179     * @property queuable
17180     * @type boolean
17181     * @default false
17182     */
17183
17184    /**
17185     * This event has fired if true
17186     *
17187     * @property fired
17188     * @type boolean
17189     * @default false;
17190     */
17191
17192    /**
17193     * An array containing the arguments the custom event
17194     * was last fired with.
17195     * @property firedWith
17196     * @type Array
17197     */
17198
17199    /**
17200     * This event should only fire one time if true, and if
17201     * it has fired, any new subscribers should be notified
17202     * immediately.
17203     *
17204     * @property fireOnce
17205     * @type boolean
17206     * @default false;
17207     */
17208
17209    /**
17210     * fireOnce listeners will fire syncronously unless async
17211     * is set to true
17212     * @property async
17213     * @type boolean
17214     * @default false
17215     */
17216
17217    /**
17218     * Flag for stopPropagation that is modified during fire()
17219     * 1 means to stop propagation to bubble targets.  2 means
17220     * to also stop additional subscribers on this target.
17221     * @property stopped
17222     * @type int
17223     */
17224
17225    /**
17226     * Flag for preventDefault that is modified during fire().
17227     * if it is not 0, the default behavior for this event
17228     * @property prevented
17229     * @type int
17230     */
17231
17232    /**
17233     * Specifies the host for this custom event.  This is used
17234     * to enable event bubbling
17235     * @property host
17236     * @type EventTarget
17237     */
17238
17239    /**
17240     * The default function to execute after event listeners
17241     * have fire, but only if the default action was not
17242     * prevented.
17243     * @property defaultFn
17244     * @type Function
17245     */
17246
17247    /**
17248     * Flag for the default function to execute only if the
17249     * firing event is the current target. This happens only
17250     * when using custom event delegation and setting the
17251     * flag to `true` mimics the behavior of event delegation
17252     * in the DOM.
17253     *
17254     * @property defaultTargetOnly
17255     * @type Boolean
17256     * @default false
17257     */
17258
17259    /**
17260     * The function to execute if a subscriber calls
17261     * stopPropagation or stopImmediatePropagation
17262     * @property stoppedFn
17263     * @type Function
17264     */
17265
17266    /**
17267     * The function to execute if a subscriber calls
17268     * preventDefault
17269     * @property preventedFn
17270     * @type Function
17271     */
17272
17273    /**
17274     * The subscribers to this event
17275     * @property _subscribers
17276     * @type Subscriber []
17277     * @private
17278     */
17279
17280    /**
17281     * 'After' subscribers
17282     * @property _afters
17283     * @type Subscriber []
17284     * @private
17285     */
17286
17287    /**
17288     * If set to true, the custom event will deliver an EventFacade object
17289     * that is similar to a DOM event object.
17290     * @property emitFacade
17291     * @type boolean
17292     * @default false
17293     */
17294
17295    /**
17296     * Supports multiple options for listener signatures in order to
17297     * port YUI 2 apps.
17298     * @property signature
17299     * @type int
17300     * @default 9
17301     */
17302    signature : YUI3_SIGNATURE,
17303
17304    /**
17305     * The context the the event will fire from by default.  Defaults to the YUI
17306     * instance.
17307     * @property context
17308     * @type object
17309     */
17310    context : Y,
17311
17312    /**
17313     * Specifies whether or not this event's default function
17314     * can be cancelled by a subscriber by executing preventDefault()
17315     * on the event facade
17316     * @property preventable
17317     * @type boolean
17318     * @default true
17319     */
17320    preventable : true,
17321
17322    /**
17323     * Specifies whether or not a subscriber can stop the event propagation
17324     * via stopPropagation(), stopImmediatePropagation(), or halt()
17325     *
17326     * Events can only bubble if emitFacade is true.
17327     *
17328     * @property bubbles
17329     * @type boolean
17330     * @default true
17331     */
17332    bubbles : true,
17333
17334    /**
17335     * Returns the number of subscribers for this event as the sum of the on()
17336     * subscribers and after() subscribers.
17337     *
17338     * @method hasSubs
17339     * @return Number
17340     */
17341    hasSubs: function(when) {
17342        var s = 0,
17343            a = 0,
17344            subs = this._subscribers,
17345            afters = this._afters,
17346            sib = this.sibling;
17347
17348        if (subs) {
17349            s = subs.length;
17350        }
17351
17352        if (afters) {
17353            a = afters.length;
17354        }
17355
17356        if (sib) {
17357            subs = sib._subscribers;
17358            afters = sib._afters;
17359
17360            if (subs) {
17361                s += subs.length;
17362            }
17363
17364            if (afters) {
17365                a += afters.length;
17366            }
17367        }
17368
17369        if (when) {
17370            return (when === 'after') ? a : s;
17371        }
17372
17373        return (s + a);
17374    },
17375
17376    /**
17377     * Monitor the event state for the subscribed event.  The first parameter
17378     * is what should be monitored, the rest are the normal parameters when
17379     * subscribing to an event.
17380     * @method monitor
17381     * @param what {string} what to monitor ('detach', 'attach', 'publish').
17382     * @return {EventHandle} return value from the monitor event subscription.
17383     */
17384    monitor: function(what) {
17385        this.monitored = true;
17386        var type = this.id + '|' + this.type + '_' + what,
17387            args = nativeSlice.call(arguments, 0);
17388        args[0] = type;
17389        return this.host.on.apply(this.host, args);
17390    },
17391
17392    /**
17393     * Get all of the subscribers to this event and any sibling event
17394     * @method getSubs
17395     * @return {Array} first item is the on subscribers, second the after.
17396     */
17397    getSubs: function() {
17398
17399        var sibling = this.sibling,
17400            subs = this._subscribers,
17401            afters = this._afters,
17402            siblingSubs,
17403            siblingAfters;
17404
17405        if (sibling) {
17406            siblingSubs = sibling._subscribers;
17407            siblingAfters = sibling._afters;
17408        }
17409
17410        if (siblingSubs) {
17411            if (subs) {
17412                subs = subs.concat(siblingSubs);
17413            } else {
17414                subs = siblingSubs.concat();
17415            }
17416        } else {
17417            if (subs) {
17418                subs = subs.concat();
17419            } else {
17420                subs = [];
17421            }
17422        }
17423
17424        if (siblingAfters) {
17425            if (afters) {
17426                afters = afters.concat(siblingAfters);
17427            } else {
17428                afters = siblingAfters.concat();
17429            }
17430        } else {
17431            if (afters) {
17432                afters = afters.concat();
17433            } else {
17434                afters = [];
17435            }
17436        }
17437
17438        return [subs, afters];
17439    },
17440
17441    /**
17442     * Apply configuration properties.  Only applies the CONFIG whitelist
17443     * @method applyConfig
17444     * @param o hash of properties to apply.
17445     * @param force {boolean} if true, properties that exist on the event
17446     * will be overwritten.
17447     */
17448    applyConfig: function(o, force) {
17449        mixConfigs(this, o, force);
17450    },
17451
17452    /**
17453     * Create the Subscription for subscribing function, context, and bound
17454     * arguments.  If this is a fireOnce event, the subscriber is immediately
17455     * notified.
17456     *
17457     * @method _on
17458     * @param fn {Function} Subscription callback
17459     * @param [context] {Object} Override `this` in the callback
17460     * @param [args] {Array} bound arguments that will be passed to the callback after the arguments generated by fire()
17461     * @param [when] {String} "after" to slot into after subscribers
17462     * @return {EventHandle}
17463     * @protected
17464     */
17465    _on: function(fn, context, args, when) {
17466
17467
17468        var s = new Y.Subscriber(fn, context, args, when),
17469            firedWith;
17470
17471        if (this.fireOnce && this.fired) {
17472
17473            firedWith = this.firedWith;
17474
17475            // It's a little ugly for this to know about facades,
17476            // but given the current breakup, not much choice without
17477            // moving a whole lot of stuff around.
17478            if (this.emitFacade && this._addFacadeToArgs) {
17479                this._addFacadeToArgs(firedWith);
17480            }
17481
17482            if (this.async) {
17483                setTimeout(Y.bind(this._notify, this, s, firedWith), 0);
17484            } else {
17485                this._notify(s, firedWith);
17486            }
17487        }
17488
17489        if (when === AFTER) {
17490            if (!this._afters) {
17491                this._afters = [];
17492            }
17493            this._afters.push(s);
17494        } else {
17495            if (!this._subscribers) {
17496                this._subscribers = [];
17497            }
17498            this._subscribers.push(s);
17499        }
17500
17501        if (this._kds) {
17502            if (when === AFTER) {
17503                this.afters[s.id] = s;
17504            } else {
17505                this.subscribers[s.id] = s;
17506            }
17507        }
17508
17509        return new Y.EventHandle(this, s);
17510    },
17511
17512    /**
17513     * Listen for this event
17514     * @method subscribe
17515     * @param {Function} fn The function to execute.
17516     * @return {EventHandle} Unsubscribe handle.
17517     * @deprecated use on.
17518     */
17519    subscribe: function(fn, context) {
17520        var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
17521        return this._on(fn, context, a, true);
17522    },
17523
17524    /**
17525     * Listen for this event
17526     * @method on
17527     * @param {Function} fn The function to execute.
17528     * @param {object} context optional execution context.
17529     * @param {mixed} arg* 0..n additional arguments to supply to the subscriber
17530     * when the event fires.
17531     * @return {EventHandle} An object with a detach method to detch the handler(s).
17532     */
17533    on: function(fn, context) {
17534        var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
17535
17536        if (this.monitored && this.host) {
17537            this.host._monitor('attach', this, {
17538                args: arguments
17539            });
17540        }
17541        return this._on(fn, context, a, true);
17542    },
17543
17544    /**
17545     * Listen for this event after the normal subscribers have been notified and
17546     * the default behavior has been applied.  If a normal subscriber prevents the
17547     * default behavior, it also prevents after listeners from firing.
17548     * @method after
17549     * @param {Function} fn The function to execute.
17550     * @param {object} context optional execution context.
17551     * @param {mixed} arg* 0..n additional arguments to supply to the subscriber
17552     * when the event fires.
17553     * @return {EventHandle} handle Unsubscribe handle.
17554     */
17555    after: function(fn, context) {
17556        var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
17557        return this._on(fn, context, a, AFTER);
17558    },
17559
17560    /**
17561     * Detach listeners.
17562     * @method detach
17563     * @param {Function} fn  The subscribed function to remove, if not supplied
17564     *                       all will be removed.
17565     * @param {Object}   context The context object passed to subscribe.
17566     * @return {Number} returns the number of subscribers unsubscribed.
17567     */
17568    detach: function(fn, context) {
17569        // unsubscribe handle
17570        if (fn && fn.detach) {
17571            return fn.detach();
17572        }
17573
17574        var i, s,
17575            found = 0,
17576            subs = this._subscribers,
17577            afters = this._afters;
17578
17579        if (subs) {
17580            for (i = subs.length; i >= 0; i--) {
17581                s = subs[i];
17582                if (s && (!fn || fn === s.fn)) {
17583                    this._delete(s, subs, i);
17584                    found++;
17585                }
17586            }
17587        }
17588
17589        if (afters) {
17590            for (i = afters.length; i >= 0; i--) {
17591                s = afters[i];
17592                if (s && (!fn || fn === s.fn)) {
17593                    this._delete(s, afters, i);
17594                    found++;
17595                }
17596            }
17597        }
17598
17599        return found;
17600    },
17601
17602    /**
17603     * Detach listeners.
17604     * @method unsubscribe
17605     * @param {Function} fn  The subscribed function to remove, if not supplied
17606     *                       all will be removed.
17607     * @param {Object}   context The context object passed to subscribe.
17608     * @return {int|undefined} returns the number of subscribers unsubscribed.
17609     * @deprecated use detach.
17610     */
17611    unsubscribe: function() {
17612        return this.detach.apply(this, arguments);
17613    },
17614
17615    /**
17616     * Notify a single subscriber
17617     * @method _notify
17618     * @param {Subscriber} s the subscriber.
17619     * @param {Array} args the arguments array to apply to the listener.
17620     * @protected
17621     */
17622    _notify: function(s, args, ef) {
17623
17624
17625        var ret;
17626
17627        ret = s.notify(args, this);
17628
17629        if (false === ret || this.stopped > 1) {
17630            return false;
17631        }
17632
17633        return true;
17634    },
17635
17636    /**
17637     * Logger abstraction to centralize the application of the silent flag
17638     * @method log
17639     * @param {string} msg message to log.
17640     * @param {string} cat log category.
17641     */
17642    log: function(msg, cat) {
17643    },
17644
17645    /**
17646     * Notifies the subscribers.  The callback functions will be executed
17647     * from the context specified when the event was created, and with the
17648     * following parameters:
17649     *   <ul>
17650     *   <li>The type of event</li>
17651     *   <li>All of the arguments fire() was executed with as an array</li>
17652     *   <li>The custom object (if any) that was passed into the subscribe()
17653     *       method</li>
17654     *   </ul>
17655     * @method fire
17656     * @param {Object*} arguments an arbitrary set of parameters to pass to
17657     *                            the handler.
17658     * @return {boolean} false if one of the subscribers returned false,
17659     *                   true otherwise.
17660     *
17661     */
17662    fire: function() {
17663
17664        // push is the fastest way to go from arguments to arrays
17665        // for most browsers currently
17666        // http://jsperf.com/push-vs-concat-vs-slice/2
17667
17668        var args = [];
17669        args.push.apply(args, arguments);
17670
17671        return this._fire(args);
17672    },
17673
17674    /**
17675     * Private internal implementation for `fire`, which is can be used directly by
17676     * `EventTarget` and other event module classes which have already converted from
17677     * an `arguments` list to an array, to avoid the repeated overhead.
17678     *
17679     * @method _fire
17680     * @private
17681     * @param {Array} args The array of arguments passed to be passed to handlers.
17682     * @return {boolean} false if one of the subscribers returned false, true otherwise.
17683     */
17684    _fire: function(args) {
17685
17686        if (this.fireOnce && this.fired) {
17687            return true;
17688        } else {
17689
17690            // this doesn't happen if the event isn't published
17691            // this.host._monitor('fire', this.type, args);
17692
17693            this.fired = true;
17694
17695            if (this.fireOnce) {
17696                this.firedWith = args;
17697            }
17698
17699            if (this.emitFacade) {
17700                return this.fireComplex(args);
17701            } else {
17702                return this.fireSimple(args);
17703            }
17704        }
17705    },
17706
17707    /**
17708     * Set up for notifying subscribers of non-emitFacade events.
17709     *
17710     * @method fireSimple
17711     * @param args {Array} Arguments passed to fire()
17712     * @return Boolean false if a subscriber returned false
17713     * @protected
17714     */
17715    fireSimple: function(args) {
17716        this.stopped = 0;
17717        this.prevented = 0;
17718        if (this.hasSubs()) {
17719            var subs = this.getSubs();
17720            this._procSubs(subs[0], args);
17721            this._procSubs(subs[1], args);
17722        }
17723        if (this.broadcast) {
17724            this._broadcast(args);
17725        }
17726        return this.stopped ? false : true;
17727    },
17728
17729    // Requires the event-custom-complex module for full funcitonality.
17730    fireComplex: function(args) {
17731        args[0] = args[0] || {};
17732        return this.fireSimple(args);
17733    },
17734
17735    /**
17736     * Notifies a list of subscribers.
17737     *
17738     * @method _procSubs
17739     * @param subs {Array} List of subscribers
17740     * @param args {Array} Arguments passed to fire()
17741     * @param ef {}
17742     * @return Boolean false if a subscriber returns false or stops the event
17743     *              propagation via e.stopPropagation(),
17744     *              e.stopImmediatePropagation(), or e.halt()
17745     * @private
17746     */
17747    _procSubs: function(subs, args, ef) {
17748        var s, i, l;
17749
17750        for (i = 0, l = subs.length; i < l; i++) {
17751            s = subs[i];
17752            if (s && s.fn) {
17753                if (false === this._notify(s, args, ef)) {
17754                    this.stopped = 2;
17755                }
17756                if (this.stopped === 2) {
17757                    return false;
17758                }
17759            }
17760        }
17761
17762        return true;
17763    },
17764
17765    /**
17766     * Notifies the YUI instance if the event is configured with broadcast = 1,
17767     * and both the YUI instance and Y.Global if configured with broadcast = 2.
17768     *
17769     * @method _broadcast
17770     * @param args {Array} Arguments sent to fire()
17771     * @private
17772     */
17773    _broadcast: function(args) {
17774        if (!this.stopped && this.broadcast) {
17775
17776            var a = args.concat();
17777            a.unshift(this.type);
17778
17779            if (this.host !== Y) {
17780                Y.fire.apply(Y, a);
17781            }
17782
17783            if (this.broadcast === 2) {
17784                Y.Global.fire.apply(Y.Global, a);
17785            }
17786        }
17787    },
17788
17789    /**
17790     * Removes all listeners
17791     * @method unsubscribeAll
17792     * @return {Number} The number of listeners unsubscribed.
17793     * @deprecated use detachAll.
17794     */
17795    unsubscribeAll: function() {
17796        return this.detachAll.apply(this, arguments);
17797    },
17798
17799    /**
17800     * Removes all listeners
17801     * @method detachAll
17802     * @return {Number} The number of listeners unsubscribed.
17803     */
17804    detachAll: function() {
17805        return this.detach();
17806    },
17807
17808    /**
17809     * Deletes the subscriber from the internal store of on() and after()
17810     * subscribers.
17811     *
17812     * @method _delete
17813     * @param s subscriber object.
17814     * @param subs (optional) on or after subscriber array
17815     * @param index (optional) The index found.
17816     * @private
17817     */
17818    _delete: function(s, subs, i) {
17819        var when = s._when;
17820
17821        if (!subs) {
17822            subs = (when === AFTER) ? this._afters : this._subscribers;
17823        }
17824
17825        if (subs) {
17826            i = YArray.indexOf(subs, s, 0);
17827
17828            if (s && subs[i] === s) {
17829                subs.splice(i, 1);
17830            }
17831        }
17832
17833        if (this._kds) {
17834            if (when === AFTER) {
17835                delete this.afters[s.id];
17836            } else {
17837                delete this.subscribers[s.id];
17838            }
17839        }
17840
17841        if (this.monitored && this.host) {
17842            this.host._monitor('detach', this, {
17843                ce: this,
17844                sub: s
17845            });
17846        }
17847
17848        if (s) {
17849            s.deleted = true;
17850        }
17851    }
17852};
17853/**
17854 * Stores the subscriber information to be used when the event fires.
17855 * @param {Function} fn       The wrapped function to execute.
17856 * @param {Object}   context  The value of the keyword 'this' in the listener.
17857 * @param {Array} args*       0..n additional arguments to supply the listener.
17858 *
17859 * @class Subscriber
17860 * @constructor
17861 */
17862Y.Subscriber = function(fn, context, args, when) {
17863
17864    /**
17865     * The callback that will be execute when the event fires
17866     * This is wrapped by Y.rbind if obj was supplied.
17867     * @property fn
17868     * @type Function
17869     */
17870    this.fn = fn;
17871
17872    /**
17873     * Optional 'this' keyword for the listener
17874     * @property context
17875     * @type Object
17876     */
17877    this.context = context;
17878
17879    /**
17880     * Unique subscriber id
17881     * @property id
17882     * @type String
17883     */
17884    this.id = Y.guid();
17885
17886    /**
17887     * Additional arguments to propagate to the subscriber
17888     * @property args
17889     * @type Array
17890     */
17891    this.args = args;
17892
17893    this._when = when;
17894
17895    /**
17896     * Custom events for a given fire transaction.
17897     * @property events
17898     * @type {EventTarget}
17899     */
17900    // this.events = null;
17901
17902    /**
17903     * This listener only reacts to the event once
17904     * @property once
17905     */
17906    // this.once = false;
17907
17908};
17909
17910Y.Subscriber.prototype = {
17911    constructor: Y.Subscriber,
17912
17913    _notify: function(c, args, ce) {
17914        if (this.deleted && !this.postponed) {
17915            if (this.postponed) {
17916                delete this.fn;
17917                delete this.context;
17918            } else {
17919                delete this.postponed;
17920                return null;
17921            }
17922        }
17923        var a = this.args, ret;
17924        switch (ce.signature) {
17925            case 0:
17926                ret = this.fn.call(c, ce.type, args, c);
17927                break;
17928            case 1:
17929                ret = this.fn.call(c, args[0] || null, c);
17930                break;
17931            default:
17932                if (a || args) {
17933                    args = args || [];
17934                    a = (a) ? args.concat(a) : args;
17935                    ret = this.fn.apply(c, a);
17936                } else {
17937                    ret = this.fn.call(c);
17938                }
17939        }
17940
17941        if (this.once) {
17942            ce._delete(this);
17943        }
17944
17945        return ret;
17946    },
17947
17948    /**
17949     * Executes the subscriber.
17950     * @method notify
17951     * @param args {Array} Arguments array for the subscriber.
17952     * @param ce {CustomEvent} The custom event that sent the notification.
17953     */
17954    notify: function(args, ce) {
17955        var c = this.context,
17956            ret = true;
17957
17958        if (!c) {
17959            c = (ce.contextFn) ? ce.contextFn() : ce.context;
17960        }
17961
17962        // only catch errors if we will not re-throw them.
17963        if (Y.config && Y.config.throwFail) {
17964            ret = this._notify(c, args, ce);
17965        } else {
17966            try {
17967                ret = this._notify(c, args, ce);
17968            } catch (e) {
17969                Y.error(this + ' failed: ' + e.message, e);
17970            }
17971        }
17972
17973        return ret;
17974    },
17975
17976    /**
17977     * Returns true if the fn and obj match this objects properties.
17978     * Used by the unsubscribe method to match the right subscriber.
17979     *
17980     * @method contains
17981     * @param {Function} fn the function to execute.
17982     * @param {Object} context optional 'this' keyword for the listener.
17983     * @return {boolean} true if the supplied arguments match this
17984     *                   subscriber's signature.
17985     */
17986    contains: function(fn, context) {
17987        if (context) {
17988            return ((this.fn === fn) && this.context === context);
17989        } else {
17990            return (this.fn === fn);
17991        }
17992    },
17993
17994    valueOf : function() {
17995        return this.id;
17996    }
17997
17998};
17999/**
18000 * Return value from all subscribe operations
18001 * @class EventHandle
18002 * @constructor
18003 * @param {CustomEvent} evt the custom event.
18004 * @param {Subscriber} sub the subscriber.
18005 */
18006Y.EventHandle = function(evt, sub) {
18007
18008    /**
18009     * The custom event
18010     *
18011     * @property evt
18012     * @type CustomEvent
18013     */
18014    this.evt = evt;
18015
18016    /**
18017     * The subscriber object
18018     *
18019     * @property sub
18020     * @type Subscriber
18021     */
18022    this.sub = sub;
18023};
18024
18025Y.EventHandle.prototype = {
18026    batch: function(f, c) {
18027        f.call(c || this, this);
18028        if (Y.Lang.isArray(this.evt)) {
18029            Y.Array.each(this.evt, function(h) {
18030                h.batch.call(c || h, f);
18031            });
18032        }
18033    },
18034
18035    /**
18036     * Detaches this subscriber
18037     * @method detach
18038     * @return {Number} the number of detached listeners
18039     */
18040    detach: function() {
18041        var evt = this.evt, detached = 0, i;
18042        if (evt) {
18043            if (Y.Lang.isArray(evt)) {
18044                for (i = 0; i < evt.length; i++) {
18045                    detached += evt[i].detach();
18046                }
18047            } else {
18048                evt._delete(this.sub);
18049                detached = 1;
18050            }
18051
18052        }
18053
18054        return detached;
18055    },
18056
18057    /**
18058     * Monitor the event state for the subscribed event.  The first parameter
18059     * is what should be monitored, the rest are the normal parameters when
18060     * subscribing to an event.
18061     * @method monitor
18062     * @param what {string} what to monitor ('attach', 'detach', 'publish').
18063     * @return {EventHandle} return value from the monitor event subscription.
18064     */
18065    monitor: function(what) {
18066        return this.evt.monitor.apply(this.evt, arguments);
18067    }
18068};
18069
18070/**
18071 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
18072 * events.
18073 * @module event-custom
18074 * @submodule event-custom-base
18075 */
18076
18077/**
18078 * EventTarget provides the implementation for any object to
18079 * publish, subscribe and fire to custom events, and also
18080 * alows other EventTargets to target the object with events
18081 * sourced from the other object.
18082 * EventTarget is designed to be used with Y.augment to wrap
18083 * EventCustom in an interface that allows events to be listened to
18084 * and fired by name.  This makes it possible for implementing code to
18085 * subscribe to an event that either has not been created yet, or will
18086 * not be created at all.
18087 * @class EventTarget
18088 * @param opts a configuration object
18089 * @config emitFacade {boolean} if true, all events will emit event
18090 * facade payloads by default (default false)
18091 * @config prefix {String} the prefix to apply to non-prefixed event names
18092 */
18093
18094var L = Y.Lang,
18095    PREFIX_DELIMITER = ':',
18096    CATEGORY_DELIMITER = '|',
18097    AFTER_PREFIX = '~AFTER~',
18098    WILD_TYPE_RE = /(.*?)(:)(.*?)/,
18099
18100    _wildType = Y.cached(function(type) {
18101        return type.replace(WILD_TYPE_RE, "*$2$3");
18102    }),
18103
18104    /**
18105     * If the instance has a prefix attribute and the
18106     * event type is not prefixed, the instance prefix is
18107     * applied to the supplied type.
18108     * @method _getType
18109     * @private
18110     */
18111    _getType = function(type, pre) {
18112
18113        if (!pre || (typeof type !== "string") || type.indexOf(PREFIX_DELIMITER) > -1) {
18114            return type;
18115        }
18116
18117        return pre + PREFIX_DELIMITER + type;
18118    },
18119
18120    /**
18121     * Returns an array with the detach key (if provided),
18122     * and the prefixed event name from _getType
18123     * Y.on('detachcategory| menu:click', fn)
18124     * @method _parseType
18125     * @private
18126     */
18127    _parseType = Y.cached(function(type, pre) {
18128
18129        var t = type, detachcategory, after, i;
18130
18131        if (!L.isString(t)) {
18132            return t;
18133        }
18134
18135        i = t.indexOf(AFTER_PREFIX);
18136
18137        if (i > -1) {
18138            after = true;
18139            t = t.substr(AFTER_PREFIX.length);
18140        }
18141
18142        i = t.indexOf(CATEGORY_DELIMITER);
18143
18144        if (i > -1) {
18145            detachcategory = t.substr(0, (i));
18146            t = t.substr(i+1);
18147            if (t === '*') {
18148                t = null;
18149            }
18150        }
18151
18152        // detach category, full type with instance prefix, is this an after listener, short type
18153        return [detachcategory, (pre) ? _getType(t, pre) : t, after, t];
18154    }),
18155
18156    ET = function(opts) {
18157
18158        var etState = this._yuievt,
18159            etConfig;
18160
18161        if (!etState) {
18162            etState = this._yuievt = {
18163                events: {},    // PERF: Not much point instantiating lazily. We're bound to have events
18164                targets: null, // PERF: Instantiate lazily, if user actually adds target,
18165                config: {
18166                    host: this,
18167                    context: this
18168                },
18169                chain: Y.config.chain
18170            };
18171        }
18172
18173        etConfig = etState.config;
18174
18175        if (opts) {
18176            mixConfigs(etConfig, opts, true);
18177
18178            if (opts.chain !== undefined) {
18179                etState.chain = opts.chain;
18180            }
18181
18182            if (opts.prefix) {
18183                etConfig.prefix = opts.prefix;
18184            }
18185        }
18186    };
18187
18188ET.prototype = {
18189
18190    constructor: ET,
18191
18192    /**
18193     * Listen to a custom event hosted by this object one time.
18194     * This is the equivalent to <code>on</code> except the
18195     * listener is immediatelly detached when it is executed.
18196     * @method once
18197     * @param {String} type The name of the event
18198     * @param {Function} fn The callback to execute in response to the event
18199     * @param {Object} [context] Override `this` object in callback
18200     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
18201     * @return {EventHandle} A subscription handle capable of detaching the
18202     *                       subscription
18203     */
18204    once: function() {
18205        var handle = this.on.apply(this, arguments);
18206        handle.batch(function(hand) {
18207            if (hand.sub) {
18208                hand.sub.once = true;
18209            }
18210        });
18211        return handle;
18212    },
18213
18214    /**
18215     * Listen to a custom event hosted by this object one time.
18216     * This is the equivalent to <code>after</code> except the
18217     * listener is immediatelly detached when it is executed.
18218     * @method onceAfter
18219     * @param {String} type The name of the event
18220     * @param {Function} fn The callback to execute in response to the event
18221     * @param {Object} [context] Override `this` object in callback
18222     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
18223     * @return {EventHandle} A subscription handle capable of detaching that
18224     *                       subscription
18225     */
18226    onceAfter: function() {
18227        var handle = this.after.apply(this, arguments);
18228        handle.batch(function(hand) {
18229            if (hand.sub) {
18230                hand.sub.once = true;
18231            }
18232        });
18233        return handle;
18234    },
18235
18236    /**
18237     * Takes the type parameter passed to 'on' and parses out the
18238     * various pieces that could be included in the type.  If the
18239     * event type is passed without a prefix, it will be expanded
18240     * to include the prefix one is supplied or the event target
18241     * is configured with a default prefix.
18242     * @method parseType
18243     * @param {String} type the type
18244     * @param {String} [pre] The prefix. Defaults to this._yuievt.config.prefix
18245     * @since 3.3.0
18246     * @return {Array} an array containing:
18247     *  * the detach category, if supplied,
18248     *  * the prefixed event type,
18249     *  * whether or not this is an after listener,
18250     *  * the supplied event type
18251     */
18252    parseType: function(type, pre) {
18253        return _parseType(type, pre || this._yuievt.config.prefix);
18254    },
18255
18256    /**
18257     * Subscribe a callback function to a custom event fired by this object or
18258     * from an object that bubbles its events to this object.
18259     *
18260     *      this.on("change", this._onChange, this);
18261     *
18262     * Callback functions for events published with `emitFacade = true` will
18263     * receive an `EventFacade` as the first argument (typically named "e").
18264     * These callbacks can then call `e.preventDefault()` to disable the
18265     * behavior published to that event's `defaultFn`.  See the `EventFacade`
18266     * API for all available properties and methods. Subscribers to
18267     * non-`emitFacade` events will receive the arguments passed to `fire()`
18268     * after the event name.
18269     *
18270     * To subscribe to multiple events at once, pass an object as the first
18271     * argument, where the key:value pairs correspond to the eventName:callback.
18272     *
18273     *      this.on({
18274     *          "attrChange" : this._onAttrChange,
18275     *          "change"     : this._onChange
18276     *      });
18277     *
18278     * You can also pass an array of event names as the first argument to
18279     * subscribe to all listed events with the same callback.
18280     *
18281     *      this.on([ "change", "attrChange" ], this._onChange);
18282     *
18283     * Returning `false` from a callback is supported as an alternative to
18284     * calling `e.preventDefault(); e.stopPropagation();`.  However, it is
18285     * recommended to use the event methods whenever possible.
18286     *
18287     * @method on
18288     * @param {String} type The name of the event
18289     * @param {Function} fn The callback to execute in response to the event
18290     * @param {Object} [context] Override `this` object in callback
18291     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
18292     * @return {EventHandle} A subscription handle capable of detaching that
18293     *                       subscription
18294     */
18295    on: function(type, fn, context) {
18296
18297        var yuievt = this._yuievt,
18298            parts = _parseType(type, yuievt.config.prefix), f, c, args, ret, ce,
18299            detachcategory, handle, store = Y.Env.evt.handles, after, adapt, shorttype,
18300            Node = Y.Node, n, domevent, isArr;
18301
18302        // full name, args, detachcategory, after
18303        this._monitor('attach', parts[1], {
18304            args: arguments,
18305            category: parts[0],
18306            after: parts[2]
18307        });
18308
18309        if (L.isObject(type)) {
18310
18311            if (L.isFunction(type)) {
18312                return Y.Do.before.apply(Y.Do, arguments);
18313            }
18314
18315            f = fn;
18316            c = context;
18317            args = nativeSlice.call(arguments, 0);
18318            ret = [];
18319
18320            if (L.isArray(type)) {
18321                isArr = true;
18322            }
18323
18324            after = type._after;
18325            delete type._after;
18326
18327            Y.each(type, function(v, k) {
18328
18329                if (L.isObject(v)) {
18330                    f = v.fn || ((L.isFunction(v)) ? v : f);
18331                    c = v.context || c;
18332                }
18333
18334                var nv = (after) ? AFTER_PREFIX : '';
18335
18336                args[0] = nv + ((isArr) ? v : k);
18337                args[1] = f;
18338                args[2] = c;
18339
18340                ret.push(this.on.apply(this, args));
18341
18342            }, this);
18343
18344            return (yuievt.chain) ? this : new Y.EventHandle(ret);
18345        }
18346
18347        detachcategory = parts[0];
18348        after = parts[2];
18349        shorttype = parts[3];
18350
18351        // extra redirection so we catch adaptor events too.  take a look at this.
18352        if (Node && Y.instanceOf(this, Node) && (shorttype in Node.DOM_EVENTS)) {
18353            args = nativeSlice.call(arguments, 0);
18354            args.splice(2, 0, Node.getDOMNode(this));
18355            return Y.on.apply(Y, args);
18356        }
18357
18358        type = parts[1];
18359
18360        if (Y.instanceOf(this, YUI)) {
18361
18362            adapt = Y.Env.evt.plugins[type];
18363            args  = nativeSlice.call(arguments, 0);
18364            args[0] = shorttype;
18365
18366            if (Node) {
18367                n = args[2];
18368
18369                if (Y.instanceOf(n, Y.NodeList)) {
18370                    n = Y.NodeList.getDOMNodes(n);
18371                } else if (Y.instanceOf(n, Node)) {
18372                    n = Node.getDOMNode(n);
18373                }
18374
18375                domevent = (shorttype in Node.DOM_EVENTS);
18376
18377                // Captures both DOM events and event plugins.
18378                if (domevent) {
18379                    args[2] = n;
18380                }
18381            }
18382
18383            // check for the existance of an event adaptor
18384            if (adapt) {
18385                handle = adapt.on.apply(Y, args);
18386            } else if ((!type) || domevent) {
18387                handle = Y.Event._attach(args);
18388            }
18389
18390        }
18391
18392        if (!handle) {
18393            ce = yuievt.events[type] || this.publish(type);
18394            handle = ce._on(fn, context, (arguments.length > 3) ? nativeSlice.call(arguments, 3) : null, (after) ? 'after' : true);
18395
18396            // TODO: More robust regex, accounting for category
18397            if (type.indexOf("*:") !== -1) {
18398                this._hasSiblings = true;
18399            }
18400        }
18401
18402        if (detachcategory) {
18403            store[detachcategory] = store[detachcategory] || {};
18404            store[detachcategory][type] = store[detachcategory][type] || [];
18405            store[detachcategory][type].push(handle);
18406        }
18407
18408        return (yuievt.chain) ? this : handle;
18409
18410    },
18411
18412    /**
18413     * subscribe to an event
18414     * @method subscribe
18415     * @deprecated use on
18416     */
18417    subscribe: function() {
18418        return this.on.apply(this, arguments);
18419    },
18420
18421    /**
18422     * Detach one or more listeners the from the specified event
18423     * @method detach
18424     * @param type {string|Object}   Either the handle to the subscriber or the
18425     *                        type of event.  If the type
18426     *                        is not specified, it will attempt to remove
18427     *                        the listener from all hosted events.
18428     * @param fn   {Function} The subscribed function to unsubscribe, if not
18429     *                          supplied, all subscribers will be removed.
18430     * @param context  {Object}   The custom object passed to subscribe.  This is
18431     *                        optional, but if supplied will be used to
18432     *                        disambiguate multiple listeners that are the same
18433     *                        (e.g., you subscribe many object using a function
18434     *                        that lives on the prototype)
18435     * @return {EventTarget} the host
18436     */
18437    detach: function(type, fn, context) {
18438
18439        var evts = this._yuievt.events,
18440            i,
18441            Node = Y.Node,
18442            isNode = Node && (Y.instanceOf(this, Node));
18443
18444        // detachAll disabled on the Y instance.
18445        if (!type && (this !== Y)) {
18446            for (i in evts) {
18447                if (evts.hasOwnProperty(i)) {
18448                    evts[i].detach(fn, context);
18449                }
18450            }
18451            if (isNode) {
18452                Y.Event.purgeElement(Node.getDOMNode(this));
18453            }
18454
18455            return this;
18456        }
18457
18458        var parts = _parseType(type, this._yuievt.config.prefix),
18459        detachcategory = L.isArray(parts) ? parts[0] : null,
18460        shorttype = (parts) ? parts[3] : null,
18461        adapt, store = Y.Env.evt.handles, detachhost, cat, args,
18462        ce,
18463
18464        keyDetacher = function(lcat, ltype, host) {
18465            var handles = lcat[ltype], ce, i;
18466            if (handles) {
18467                for (i = handles.length - 1; i >= 0; --i) {
18468                    ce = handles[i].evt;
18469                    if (ce.host === host || ce.el === host) {
18470                        handles[i].detach();
18471                    }
18472                }
18473            }
18474        };
18475
18476        if (detachcategory) {
18477
18478            cat = store[detachcategory];
18479            type = parts[1];
18480            detachhost = (isNode) ? Y.Node.getDOMNode(this) : this;
18481
18482            if (cat) {
18483                if (type) {
18484                    keyDetacher(cat, type, detachhost);
18485                } else {
18486                    for (i in cat) {
18487                        if (cat.hasOwnProperty(i)) {
18488                            keyDetacher(cat, i, detachhost);
18489                        }
18490                    }
18491                }
18492
18493                return this;
18494            }
18495
18496        // If this is an event handle, use it to detach
18497        } else if (L.isObject(type) && type.detach) {
18498            type.detach();
18499            return this;
18500        // extra redirection so we catch adaptor events too.  take a look at this.
18501        } else if (isNode && ((!shorttype) || (shorttype in Node.DOM_EVENTS))) {
18502            args = nativeSlice.call(arguments, 0);
18503            args[2] = Node.getDOMNode(this);
18504            Y.detach.apply(Y, args);
18505            return this;
18506        }
18507
18508        adapt = Y.Env.evt.plugins[shorttype];
18509
18510        // The YUI instance handles DOM events and adaptors
18511        if (Y.instanceOf(this, YUI)) {
18512            args = nativeSlice.call(arguments, 0);
18513            // use the adaptor specific detach code if
18514            if (adapt && adapt.detach) {
18515                adapt.detach.apply(Y, args);
18516                return this;
18517            // DOM event fork
18518            } else if (!type || (!adapt && Node && (type in Node.DOM_EVENTS))) {
18519                args[0] = type;
18520                Y.Event.detach.apply(Y.Event, args);
18521                return this;
18522            }
18523        }
18524
18525        // ce = evts[type];
18526        ce = evts[parts[1]];
18527        if (ce) {
18528            ce.detach(fn, context);
18529        }
18530
18531        return this;
18532    },
18533
18534    /**
18535     * detach a listener
18536     * @method unsubscribe
18537     * @deprecated use detach
18538     */
18539    unsubscribe: function() {
18540        return this.detach.apply(this, arguments);
18541    },
18542
18543    /**
18544     * Removes all listeners from the specified event.  If the event type
18545     * is not specified, all listeners from all hosted custom events will
18546     * be removed.
18547     * @method detachAll
18548     * @param type {String}   The type, or name of the event
18549     */
18550    detachAll: function(type) {
18551        return this.detach(type);
18552    },
18553
18554    /**
18555     * Removes all listeners from the specified event.  If the event type
18556     * is not specified, all listeners from all hosted custom events will
18557     * be removed.
18558     * @method unsubscribeAll
18559     * @param type {String}   The type, or name of the event
18560     * @deprecated use detachAll
18561     */
18562    unsubscribeAll: function() {
18563        return this.detachAll.apply(this, arguments);
18564    },
18565
18566    /**
18567     * Creates a new custom event of the specified type.  If a custom event
18568     * by that name already exists, it will not be re-created.  In either
18569     * case the custom event is returned.
18570     *
18571     * @method publish
18572     *
18573     * @param type {String} the type, or name of the event
18574     * @param opts {object} optional config params.  Valid properties are:
18575     * @param [opts.broadcast=false] {Boolean} whether or not the YUI instance and YUI global
18576     *      are notified when the event is fired.
18577     * @param [opts.bubbles=true] {Boolean} Whether or not this event bubbles. Events can
18578     *      only bubble if `emitFacade` is true.
18579     * @param [opts.context=this] {Object} the default execution context for the listeners.
18580     * @param [opts.defaultFn] {Function} the default function to execute when this event
18581     *      fires if preventDefault was not called.
18582     * @param [opts.emitFacade=false] {Boolean} whether or not this event emits a facade.
18583     * @param [opts.prefix] {String} the prefix for this targets events, e.g., 'menu' in 'menu:click'.
18584     * @param [opts.fireOnce=false] {Boolean} if an event is configured to fire once,
18585     *      new subscribers after the fire will be notified immediately.
18586     * @param [opts.async=false] {Boolean} fireOnce event listeners will fire synchronously
18587     *      if the event has already fired unless `async` is `true`.
18588     * @param [opts.preventable=true] {Boolean} whether or not `preventDefault()` has an effect.
18589     * @param [opts.preventedFn] {Function} a function that is executed when `preventDefault()` is called.
18590     * @param [opts.queuable=false] {Boolean} whether or not this event can be queued during bubbling.
18591     * @param [opts.silent] {Boolean} if silent is true, debug messages are not provided for this event.
18592     * @param [opts.stoppedFn] {Function} a function that is executed when stopPropagation is called.
18593     * @param [opts.monitored] {Boolean} specifies whether or not this event should send notifications about
18594     *      when the event has been attached, detached, or published.
18595     * @param [opts.type] {String} the event type (valid option if not provided as the first parameter to publish).
18596     *
18597     * @return {CustomEvent} the custom event
18598     *
18599     */
18600    publish: function(type, opts) {
18601
18602        var ret,
18603            etState = this._yuievt,
18604            etConfig = etState.config,
18605            pre = etConfig.prefix;
18606
18607        if (typeof type === "string")  {
18608            if (pre) {
18609                type = _getType(type, pre);
18610            }
18611            ret = this._publish(type, etConfig, opts);
18612        } else {
18613            ret = {};
18614
18615            Y.each(type, function(v, k) {
18616                if (pre) {
18617                    k = _getType(k, pre);
18618                }
18619                ret[k] = this._publish(k, etConfig, v || opts);
18620            }, this);
18621
18622        }
18623
18624        return ret;
18625    },
18626
18627    /**
18628     * Returns the fully qualified type, given a short type string.
18629     * That is, returns "foo:bar" when given "bar" if "foo" is the configured prefix.
18630     *
18631     * NOTE: This method, unlike _getType, does no checking of the value passed in, and
18632     * is designed to be used with the low level _publish() method, for critical path
18633     * implementations which need to fast-track publish for performance reasons.
18634     *
18635     * @method _getFullType
18636     * @private
18637     * @param {String} type The short type to prefix
18638     * @return {String} The prefixed type, if a prefix is set, otherwise the type passed in
18639     */
18640    _getFullType : function(type) {
18641
18642        var pre = this._yuievt.config.prefix;
18643
18644        if (pre) {
18645            return pre + PREFIX_DELIMITER + type;
18646        } else {
18647            return type;
18648        }
18649    },
18650
18651    /**
18652     * The low level event publish implementation. It expects all the massaging to have been done
18653     * outside of this method. e.g. the `type` to `fullType` conversion. It's designed to be a fast
18654     * path publish, which can be used by critical code paths to improve performance.
18655     *
18656     * @method _publish
18657     * @private
18658     * @param {String} fullType The prefixed type of the event to publish.
18659     * @param {Object} etOpts The EventTarget specific configuration to mix into the published event.
18660     * @param {Object} ceOpts The publish specific configuration to mix into the published event.
18661     * @return {CustomEvent} The published event. If called without `etOpts` or `ceOpts`, this will
18662     * be the default `CustomEvent` instance, and can be configured independently.
18663     */
18664    _publish : function(fullType, etOpts, ceOpts) {
18665
18666        var ce,
18667            etState = this._yuievt,
18668            etConfig = etState.config,
18669            host = etConfig.host,
18670            context = etConfig.context,
18671            events = etState.events;
18672
18673        ce = events[fullType];
18674
18675        // PERF: Hate to pull the check out of monitor, but trying to keep critical path tight.
18676        if ((etConfig.monitored && !ce) || (ce && ce.monitored)) {
18677            this._monitor('publish', fullType, {
18678                args: arguments
18679            });
18680        }
18681
18682        if (!ce) {
18683            // Publish event
18684            ce = events[fullType] = new Y.CustomEvent(fullType, etOpts);
18685
18686            if (!etOpts) {
18687                ce.host = host;
18688                ce.context = context;
18689            }
18690        }
18691
18692        if (ceOpts) {
18693            mixConfigs(ce, ceOpts, true);
18694        }
18695
18696        return ce;
18697    },
18698
18699    /**
18700     * This is the entry point for the event monitoring system.
18701     * You can monitor 'attach', 'detach', 'fire', and 'publish'.
18702     * When configured, these events generate an event.  click ->
18703     * click_attach, click_detach, click_publish -- these can
18704     * be subscribed to like other events to monitor the event
18705     * system.  Inividual published events can have monitoring
18706     * turned on or off (publish can't be turned off before it
18707     * it published) by setting the events 'monitor' config.
18708     *
18709     * @method _monitor
18710     * @param what {String} 'attach', 'detach', 'fire', or 'publish'
18711     * @param eventType {String|CustomEvent} The prefixed name of the event being monitored, or the CustomEvent object.
18712     * @param o {Object} Information about the event interaction, such as
18713     *                  fire() args, subscription category, publish config
18714     * @private
18715     */
18716    _monitor: function(what, eventType, o) {
18717        var monitorevt, ce, type;
18718
18719        if (eventType) {
18720            if (typeof eventType === "string") {
18721                type = eventType;
18722                ce = this.getEvent(eventType, true);
18723            } else {
18724                ce = eventType;
18725                type = eventType.type;
18726            }
18727
18728            if ((this._yuievt.config.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) {
18729                monitorevt = type + '_' + what;
18730                o.monitored = what;
18731                this.fire.call(this, monitorevt, o);
18732            }
18733        }
18734    },
18735
18736    /**
18737     * Fire a custom event by name.  The callback functions will be executed
18738     * from the context specified when the event was created, and with the
18739     * following parameters.
18740     *
18741     * The first argument is the event type, and any additional arguments are
18742     * passed to the listeners as parameters.  If the first of these is an
18743     * object literal, and the event is configured to emit an event facade,
18744     * that object is mixed into the event facade and the facade is provided
18745     * in place of the original object.
18746     *
18747     * If the custom event object hasn't been created, then the event hasn't
18748     * been published and it has no subscribers.  For performance sake, we
18749     * immediate exit in this case.  This means the event won't bubble, so
18750     * if the intention is that a bubble target be notified, the event must
18751     * be published on this object first.
18752     *
18753     * @method fire
18754     * @param type {String|Object} The type of the event, or an object that contains
18755     * a 'type' property.
18756     * @param arguments {Object*} an arbitrary set of parameters to pass to
18757     * the handler.  If the first of these is an object literal and the event is
18758     * configured to emit an event facade, the event facade will replace that
18759     * parameter after the properties the object literal contains are copied to
18760     * the event facade.
18761     * @return {Boolean} True if the whole lifecycle of the event went through,
18762     * false if at any point the event propagation was halted.
18763     */
18764    fire: function(type) {
18765
18766        var typeIncluded = (typeof type === "string"),
18767            argCount = arguments.length,
18768            t = type,
18769            yuievt = this._yuievt,
18770            etConfig = yuievt.config,
18771            pre = etConfig.prefix,
18772            ret,
18773            ce,
18774            ce2,
18775            args;
18776
18777        if (typeIncluded && argCount <= 3) {
18778
18779            // PERF: Try to avoid slice/iteration for the common signatures
18780
18781            // Most common
18782            if (argCount === 2) {
18783                args = [arguments[1]]; // fire("foo", {})
18784            } else if (argCount === 3) {
18785                args = [arguments[1], arguments[2]]; // fire("foo", {}, opts)
18786            } else {
18787                args = []; // fire("foo")
18788            }
18789
18790        } else {
18791            args = nativeSlice.call(arguments, ((typeIncluded) ? 1 : 0));
18792        }
18793
18794        if (!typeIncluded) {
18795            t = (type && type.type);
18796        }
18797
18798        if (pre) {
18799            t = _getType(t, pre);
18800        }
18801
18802        ce = yuievt.events[t];
18803
18804        if (this._hasSiblings) {
18805            ce2 = this.getSibling(t, ce);
18806
18807            if (ce2 && !ce) {
18808                ce = this.publish(t);
18809            }
18810        }
18811
18812        // PERF: trying to avoid function call, since this is a critical path
18813        if ((etConfig.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) {
18814            this._monitor('fire', (ce || t), {
18815                args: args
18816            });
18817        }
18818
18819        // this event has not been published or subscribed to
18820        if (!ce) {
18821            if (yuievt.hasTargets) {
18822                return this.bubble({ type: t }, args, this);
18823            }
18824
18825            // otherwise there is nothing to be done
18826            ret = true;
18827        } else {
18828
18829            if (ce2) {
18830                ce.sibling = ce2;
18831            }
18832
18833            ret = ce._fire(args);
18834        }
18835
18836        return (yuievt.chain) ? this : ret;
18837    },
18838
18839    getSibling: function(type, ce) {
18840        var ce2;
18841
18842        // delegate to *:type events if there are subscribers
18843        if (type.indexOf(PREFIX_DELIMITER) > -1) {
18844            type = _wildType(type);
18845            ce2 = this.getEvent(type, true);
18846            if (ce2) {
18847                ce2.applyConfig(ce);
18848                ce2.bubbles = false;
18849                ce2.broadcast = 0;
18850            }
18851        }
18852
18853        return ce2;
18854    },
18855
18856    /**
18857     * Returns the custom event of the provided type has been created, a
18858     * falsy value otherwise
18859     * @method getEvent
18860     * @param type {String} the type, or name of the event
18861     * @param prefixed {String} if true, the type is prefixed already
18862     * @return {CustomEvent} the custom event or null
18863     */
18864    getEvent: function(type, prefixed) {
18865        var pre, e;
18866
18867        if (!prefixed) {
18868            pre = this._yuievt.config.prefix;
18869            type = (pre) ? _getType(type, pre) : type;
18870        }
18871        e = this._yuievt.events;
18872        return e[type] || null;
18873    },
18874
18875    /**
18876     * Subscribe to a custom event hosted by this object.  The
18877     * supplied callback will execute after any listeners add
18878     * via the subscribe method, and after the default function,
18879     * if configured for the event, has executed.
18880     *
18881     * @method after
18882     * @param {String} type The name of the event
18883     * @param {Function} fn The callback to execute in response to the event
18884     * @param {Object} [context] Override `this` object in callback
18885     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
18886     * @return {EventHandle} A subscription handle capable of detaching the
18887     *                       subscription
18888     */
18889    after: function(type, fn) {
18890
18891        var a = nativeSlice.call(arguments, 0);
18892
18893        switch (L.type(type)) {
18894            case 'function':
18895                return Y.Do.after.apply(Y.Do, arguments);
18896            case 'array':
18897            //     YArray.each(a[0], function(v) {
18898            //         v = AFTER_PREFIX + v;
18899            //     });
18900            //     break;
18901            case 'object':
18902                a[0]._after = true;
18903                break;
18904            default:
18905                a[0] = AFTER_PREFIX + type;
18906        }
18907
18908        return this.on.apply(this, a);
18909
18910    },
18911
18912    /**
18913     * Executes the callback before a DOM event, custom event
18914     * or method.  If the first argument is a function, it
18915     * is assumed the target is a method.  For DOM and custom
18916     * events, this is an alias for Y.on.
18917     *
18918     * For DOM and custom events:
18919     * type, callback, context, 0-n arguments
18920     *
18921     * For methods:
18922     * callback, object (method host), methodName, context, 0-n arguments
18923     *
18924     * @method before
18925     * @return detach handle
18926     */
18927    before: function() {
18928        return this.on.apply(this, arguments);
18929    }
18930
18931};
18932
18933Y.EventTarget = ET;
18934
18935// make Y an event target
18936Y.mix(Y, ET.prototype);
18937ET.call(Y, { bubbles: false });
18938
18939YUI.Env.globalEvents = YUI.Env.globalEvents || new ET();
18940
18941/**
18942 * Hosts YUI page level events.  This is where events bubble to
18943 * when the broadcast config is set to 2.  This property is
18944 * only available if the custom event module is loaded.
18945 * @property Global
18946 * @type EventTarget
18947 * @for YUI
18948 */
18949Y.Global = YUI.Env.globalEvents;
18950
18951// @TODO implement a global namespace function on Y.Global?
18952
18953/**
18954`Y.on()` can do many things:
18955
18956<ul>
18957    <li>Subscribe to custom events `publish`ed and `fire`d from Y</li>
18958    <li>Subscribe to custom events `publish`ed with `broadcast` 1 or 2 and
18959        `fire`d from any object in the YUI instance sandbox</li>
18960    <li>Subscribe to DOM events</li>
18961    <li>Subscribe to the execution of a method on any object, effectively
18962    treating that method as an event</li>
18963</ul>
18964
18965For custom event subscriptions, pass the custom event name as the first argument
18966and callback as the second. The `this` object in the callback will be `Y` unless
18967an override is passed as the third argument.
18968
18969    Y.on('io:complete', function () {
18970        Y.MyApp.updateStatus('Transaction complete');
18971    });
18972
18973To subscribe to DOM events, pass the name of a DOM event as the first argument
18974and a CSS selector string as the third argument after the callback function.
18975Alternately, the third argument can be a `Node`, `NodeList`, `HTMLElement`,
18976array, or simply omitted (the default is the `window` object).
18977
18978    Y.on('click', function (e) {
18979        e.preventDefault();
18980
18981        // proceed with ajax form submission
18982        var url = this.get('action');
18983        ...
18984    }, '#my-form');
18985
18986The `this` object in DOM event callbacks will be the `Node` targeted by the CSS
18987selector or other identifier.
18988
18989`on()` subscribers for DOM events or custom events `publish`ed with a
18990`defaultFn` can prevent the default behavior with `e.preventDefault()` from the
18991event object passed as the first parameter to the subscription callback.
18992
18993To subscribe to the execution of an object method, pass arguments corresponding to the call signature for
18994<a href="../classes/Do.html#methods_before">`Y.Do.before(...)`</a>.
18995
18996NOTE: The formal parameter list below is for events, not for function
18997injection.  See `Y.Do.before` for that signature.
18998
18999@method on
19000@param {String} type DOM or custom event name
19001@param {Function} fn The callback to execute in response to the event
19002@param {Object} [context] Override `this` object in callback
19003@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
19004@return {EventHandle} A subscription handle capable of detaching the
19005                      subscription
19006@see Do.before
19007@for YUI
19008**/
19009
19010/**
19011Listen for an event one time.  Equivalent to `on()`, except that
19012the listener is immediately detached when executed.
19013
19014See the <a href="#methods_on">`on()` method</a> for additional subscription
19015options.
19016
19017@see on
19018@method once
19019@param {String} type DOM or custom event name
19020@param {Function} fn The callback to execute in response to the event
19021@param {Object} [context] Override `this` object in callback
19022@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
19023@return {EventHandle} A subscription handle capable of detaching the
19024                      subscription
19025@for YUI
19026**/
19027
19028/**
19029Listen for an event one time.  Equivalent to `once()`, except, like `after()`,
19030the subscription callback executes after all `on()` subscribers and the event's
19031`defaultFn` (if configured) have executed.  Like `after()` if any `on()` phase
19032subscriber calls `e.preventDefault()`, neither the `defaultFn` nor the `after()`
19033subscribers will execute.
19034
19035The listener is immediately detached when executed.
19036
19037See the <a href="#methods_on">`on()` method</a> for additional subscription
19038options.
19039
19040@see once
19041@method onceAfter
19042@param {String} type The custom event name
19043@param {Function} fn The callback to execute in response to the event
19044@param {Object} [context] Override `this` object in callback
19045@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
19046@return {EventHandle} A subscription handle capable of detaching the
19047                      subscription
19048@for YUI
19049**/
19050
19051/**
19052Like `on()`, this method creates a subscription to a custom event or to the
19053execution of a method on an object.
19054
19055For events, `after()` subscribers are executed after the event's
19056`defaultFn` unless `e.preventDefault()` was called from an `on()` subscriber.
19057
19058See the <a href="#methods_on">`on()` method</a> for additional subscription
19059options.
19060
19061NOTE: The subscription signature shown is for events, not for function
19062injection.  See <a href="../classes/Do.html#methods_after">`Y.Do.after`</a>
19063for that signature.
19064
19065@see on
19066@see Do.after
19067@method after
19068@param {String} type The custom event name
19069@param {Function} fn The callback to execute in response to the event
19070@param {Object} [context] Override `this` object in callback
19071@param {Any} [args*] 0..n additional arguments to supply to the subscriber
19072@return {EventHandle} A subscription handle capable of detaching the
19073                      subscription
19074@for YUI
19075**/
19076
19077
19078}, 'patched-v3.18.1', {"requires": ["oop"]});
19079
19080YUI.add('event-custom-complex', function (Y, NAME) {
19081
19082
19083/**
19084 * Adds event facades, preventable default behavior, and bubbling.
19085 * events.
19086 * @module event-custom
19087 * @submodule event-custom-complex
19088 */
19089
19090var FACADE,
19091    FACADE_KEYS,
19092    YObject = Y.Object,
19093    key,
19094    EMPTY = {},
19095    CEProto = Y.CustomEvent.prototype,
19096    ETProto = Y.EventTarget.prototype,
19097
19098    mixFacadeProps = function(facade, payload) {
19099        var p;
19100
19101        for (p in payload) {
19102            if (!(FACADE_KEYS.hasOwnProperty(p))) {
19103                facade[p] = payload[p];
19104            }
19105        }
19106    };
19107
19108/**
19109 * Wraps and protects a custom event for use when emitFacade is set to true.
19110 * Requires the event-custom-complex module
19111 * @class EventFacade
19112 * @param e {Event} the custom event
19113 * @param currentTarget {HTMLElement} the element the listener was attached to
19114 */
19115
19116Y.EventFacade = function(e, currentTarget) {
19117
19118    if (!e) {
19119        e = EMPTY;
19120    }
19121
19122    this._event = e;
19123
19124    /**
19125     * The arguments passed to fire
19126     * @property details
19127     * @type Array
19128     */
19129    this.details = e.details;
19130
19131    /**
19132     * The event type, this can be overridden by the fire() payload
19133     * @property type
19134     * @type string
19135     */
19136    this.type = e.type;
19137
19138    /**
19139     * The real event type
19140     * @property _type
19141     * @type string
19142     * @private
19143     */
19144    this._type = e.type;
19145
19146    //////////////////////////////////////////////////////
19147
19148    /**
19149     * Node reference for the targeted eventtarget
19150     * @property target
19151     * @type Node
19152     */
19153    this.target = e.target;
19154
19155    /**
19156     * Node reference for the element that the listener was attached to.
19157     * @property currentTarget
19158     * @type Node
19159     */
19160    this.currentTarget = currentTarget;
19161
19162    /**
19163     * Node reference to the relatedTarget
19164     * @property relatedTarget
19165     * @type Node
19166     */
19167    this.relatedTarget = e.relatedTarget;
19168
19169};
19170
19171Y.mix(Y.EventFacade.prototype, {
19172
19173    /**
19174     * Stops the propagation to the next bubble target
19175     * @method stopPropagation
19176     */
19177    stopPropagation: function() {
19178        this._event.stopPropagation();
19179        this.stopped = 1;
19180    },
19181
19182    /**
19183     * Stops the propagation to the next bubble target and
19184     * prevents any additional listeners from being exectued
19185     * on the current target.
19186     * @method stopImmediatePropagation
19187     */
19188    stopImmediatePropagation: function() {
19189        this._event.stopImmediatePropagation();
19190        this.stopped = 2;
19191    },
19192
19193    /**
19194     * Prevents the event's default behavior
19195     * @method preventDefault
19196     */
19197    preventDefault: function() {
19198        this._event.preventDefault();
19199        this.prevented = 1;
19200    },
19201
19202    /**
19203     * Stops the event propagation and prevents the default
19204     * event behavior.
19205     * @method halt
19206     * @param immediate {boolean} if true additional listeners
19207     * on the current target will not be executed
19208     */
19209    halt: function(immediate) {
19210        this._event.halt(immediate);
19211        this.prevented = 1;
19212        this.stopped = (immediate) ? 2 : 1;
19213    }
19214
19215});
19216
19217CEProto.fireComplex = function(args) {
19218
19219    var es,
19220        ef,
19221        q,
19222        queue,
19223        ce,
19224        ret = true,
19225        events,
19226        subs,
19227        ons,
19228        afters,
19229        afterQueue,
19230        postponed,
19231        prevented,
19232        preventedFn,
19233        defaultFn,
19234        self = this,
19235        host = self.host || self,
19236        next,
19237        oldbubble,
19238        stack = self.stack,
19239        yuievt = host._yuievt,
19240        hasPotentialSubscribers;
19241
19242    if (stack) {
19243
19244        // queue this event if the current item in the queue bubbles
19245        if (self.queuable && self.type !== stack.next.type) {
19246
19247            if (!stack.queue) {
19248                stack.queue = [];
19249            }
19250            stack.queue.push([self, args]);
19251
19252            return true;
19253        }
19254    }
19255
19256    hasPotentialSubscribers = self.hasSubs() || yuievt.hasTargets || self.broadcast;
19257
19258    self.target = self.target || host;
19259    self.currentTarget = host;
19260
19261    self.details = args.concat();
19262
19263    if (hasPotentialSubscribers) {
19264
19265        es = stack || {
19266
19267           id: self.id, // id of the first event in the stack
19268           next: self,
19269           silent: self.silent,
19270           stopped: 0,
19271           prevented: 0,
19272           bubbling: null,
19273           type: self.type,
19274           // defaultFnQueue: new Y.Queue(),
19275           defaultTargetOnly: self.defaultTargetOnly
19276
19277        };
19278
19279        subs = self.getSubs();
19280        ons = subs[0];
19281        afters = subs[1];
19282
19283        self.stopped = (self.type !== es.type) ? 0 : es.stopped;
19284        self.prevented = (self.type !== es.type) ? 0 : es.prevented;
19285
19286        if (self.stoppedFn) {
19287            // PERF TODO: Can we replace with callback, like preventedFn. Look into history
19288            events = new Y.EventTarget({
19289                fireOnce: true,
19290                context: host
19291            });
19292            self.events = events;
19293            events.on('stopped', self.stoppedFn);
19294        }
19295
19296
19297        self._facade = null; // kill facade to eliminate stale properties
19298
19299        ef = self._createFacade(args);
19300
19301        if (ons) {
19302            self._procSubs(ons, args, ef);
19303        }
19304
19305        // bubble if this is hosted in an event target and propagation has not been stopped
19306        if (self.bubbles && host.bubble && !self.stopped) {
19307            oldbubble = es.bubbling;
19308
19309            es.bubbling = self.type;
19310
19311            if (es.type !== self.type) {
19312                es.stopped = 0;
19313                es.prevented = 0;
19314            }
19315
19316            ret = host.bubble(self, args, null, es);
19317
19318            self.stopped = Math.max(self.stopped, es.stopped);
19319            self.prevented = Math.max(self.prevented, es.prevented);
19320
19321            es.bubbling = oldbubble;
19322        }
19323
19324        prevented = self.prevented;
19325
19326        if (prevented) {
19327            preventedFn = self.preventedFn;
19328            if (preventedFn) {
19329                preventedFn.apply(host, args);
19330            }
19331        } else {
19332            defaultFn = self.defaultFn;
19333
19334            if (defaultFn && ((!self.defaultTargetOnly && !es.defaultTargetOnly) || host === ef.target)) {
19335                defaultFn.apply(host, args);
19336            }
19337        }
19338
19339        // broadcast listeners are fired as discreet events on the
19340        // YUI instance and potentially the YUI global.
19341        if (self.broadcast) {
19342            self._broadcast(args);
19343        }
19344
19345        if (afters && !self.prevented && self.stopped < 2) {
19346
19347            // Queue the after
19348            afterQueue = es.afterQueue;
19349
19350            if (es.id === self.id || self.type !== yuievt.bubbling) {
19351
19352                self._procSubs(afters, args, ef);
19353
19354                if (afterQueue) {
19355                    while ((next = afterQueue.last())) {
19356                        next();
19357                    }
19358                }
19359            } else {
19360                postponed = afters;
19361
19362                if (es.execDefaultCnt) {
19363                    postponed = Y.merge(postponed);
19364
19365                    Y.each(postponed, function(s) {
19366                        s.postponed = true;
19367                    });
19368                }
19369
19370                if (!afterQueue) {
19371                    es.afterQueue = new Y.Queue();
19372                }
19373
19374                es.afterQueue.add(function() {
19375                    self._procSubs(postponed, args, ef);
19376                });
19377            }
19378
19379        }
19380
19381        self.target = null;
19382
19383        if (es.id === self.id) {
19384
19385            queue = es.queue;
19386
19387            if (queue) {
19388                while (queue.length) {
19389                    q = queue.pop();
19390                    ce = q[0];
19391                    // set up stack to allow the next item to be processed
19392                    es.next = ce;
19393                    ce._fire(q[1]);
19394                }
19395            }
19396
19397            self.stack = null;
19398        }
19399
19400        ret = !(self.stopped);
19401
19402        if (self.type !== yuievt.bubbling) {
19403            es.stopped = 0;
19404            es.prevented = 0;
19405            self.stopped = 0;
19406            self.prevented = 0;
19407        }
19408
19409    } else {
19410        defaultFn = self.defaultFn;
19411
19412        if(defaultFn) {
19413            ef = self._createFacade(args);
19414
19415            if ((!self.defaultTargetOnly) || (host === ef.target)) {
19416                defaultFn.apply(host, args);
19417            }
19418        }
19419    }
19420
19421    // Kill the cached facade to free up memory.
19422    // Otherwise we have the facade from the last fire, sitting around forever.
19423    self._facade = null;
19424
19425    return ret;
19426};
19427
19428/**
19429 * @method _hasPotentialSubscribers
19430 * @for CustomEvent
19431 * @private
19432 * @return {boolean} Whether the event has potential subscribers or not
19433 */
19434CEProto._hasPotentialSubscribers = function() {
19435    return this.hasSubs() || this.host._yuievt.hasTargets || this.broadcast;
19436};
19437
19438/**
19439 * Internal utility method to create a new facade instance and
19440 * insert it into the fire argument list, accounting for any payload
19441 * merging which needs to happen.
19442 *
19443 * This used to be called `_getFacade`, but the name seemed inappropriate
19444 * when it was used without a need for the return value.
19445 *
19446 * @method _createFacade
19447 * @private
19448 * @param fireArgs {Array} The arguments passed to "fire", which need to be
19449 * shifted (and potentially merged) when the facade is added.
19450 * @return {EventFacade} The event facade created.
19451 */
19452
19453// TODO: Remove (private) _getFacade alias, once synthetic.js is updated.
19454CEProto._createFacade = CEProto._getFacade = function(fireArgs) {
19455
19456    var userArgs = this.details,
19457        firstArg = userArgs && userArgs[0],
19458        firstArgIsObj = (firstArg && (typeof firstArg === "object")),
19459        ef = this._facade;
19460
19461    if (!ef) {
19462        ef = new Y.EventFacade(this, this.currentTarget);
19463    }
19464
19465    if (firstArgIsObj) {
19466        // protect the event facade properties
19467        mixFacadeProps(ef, firstArg);
19468
19469        // Allow the event type to be faked http://yuilibrary.com/projects/yui3/ticket/2528376
19470        if (firstArg.type) {
19471            ef.type = firstArg.type;
19472        }
19473
19474        if (fireArgs) {
19475            fireArgs[0] = ef;
19476        }
19477    } else {
19478        if (fireArgs) {
19479            fireArgs.unshift(ef);
19480        }
19481    }
19482
19483    // update the details field with the arguments
19484    ef.details = this.details;
19485
19486    // use the original target when the event bubbled to this target
19487    ef.target = this.originalTarget || this.target;
19488
19489    ef.currentTarget = this.currentTarget;
19490    ef.stopped = 0;
19491    ef.prevented = 0;
19492
19493    this._facade = ef;
19494
19495    return this._facade;
19496};
19497
19498/**
19499 * Utility method to manipulate the args array passed in, to add the event facade,
19500 * if it's not already the first arg.
19501 *
19502 * @method _addFacadeToArgs
19503 * @private
19504 * @param {Array} The arguments to manipulate
19505 */
19506CEProto._addFacadeToArgs = function(args) {
19507    var e = args[0];
19508
19509    // Trying not to use instanceof, just to avoid potential cross Y edge case issues.
19510    if (!(e && e.halt && e.stopImmediatePropagation && e.stopPropagation && e._event)) {
19511        this._createFacade(args);
19512    }
19513};
19514
19515/**
19516 * Stop propagation to bubble targets
19517 * @for CustomEvent
19518 * @method stopPropagation
19519 */
19520CEProto.stopPropagation = function() {
19521    this.stopped = 1;
19522    if (this.stack) {
19523        this.stack.stopped = 1;
19524    }
19525    if (this.events) {
19526        this.events.fire('stopped', this);
19527    }
19528};
19529
19530/**
19531 * Stops propagation to bubble targets, and prevents any remaining
19532 * subscribers on the current target from executing.
19533 * @method stopImmediatePropagation
19534 */
19535CEProto.stopImmediatePropagation = function() {
19536    this.stopped = 2;
19537    if (this.stack) {
19538        this.stack.stopped = 2;
19539    }
19540    if (this.events) {
19541        this.events.fire('stopped', this);
19542    }
19543};
19544
19545/**
19546 * Prevents the execution of this event's defaultFn
19547 * @method preventDefault
19548 */
19549CEProto.preventDefault = function() {
19550    if (this.preventable) {
19551        this.prevented = 1;
19552        if (this.stack) {
19553            this.stack.prevented = 1;
19554        }
19555    }
19556};
19557
19558/**
19559 * Stops the event propagation and prevents the default
19560 * event behavior.
19561 * @method halt
19562 * @param immediate {boolean} if true additional listeners
19563 * on the current target will not be executed
19564 */
19565CEProto.halt = function(immediate) {
19566    if (immediate) {
19567        this.stopImmediatePropagation();
19568    } else {
19569        this.stopPropagation();
19570    }
19571    this.preventDefault();
19572};
19573
19574/**
19575 * Registers another EventTarget as a bubble target.  Bubble order
19576 * is determined by the order registered.  Multiple targets can
19577 * be specified.
19578 *
19579 * Events can only bubble if emitFacade is true.
19580 *
19581 * Included in the event-custom-complex submodule.
19582 *
19583 * @method addTarget
19584 * @chainable
19585 * @param o {EventTarget} the target to add
19586 * @for EventTarget
19587 */
19588ETProto.addTarget = function(o) {
19589    var etState = this._yuievt;
19590
19591    if (!etState.targets) {
19592        etState.targets = {};
19593    }
19594
19595    etState.targets[Y.stamp(o)] = o;
19596    etState.hasTargets = true;
19597
19598    return this;
19599};
19600
19601/**
19602 * Returns an array of bubble targets for this object.
19603 * @method getTargets
19604 * @return EventTarget[]
19605 */
19606ETProto.getTargets = function() {
19607    var targets = this._yuievt.targets;
19608    return targets ? YObject.values(targets) : [];
19609};
19610
19611/**
19612 * Removes a bubble target
19613 * @method removeTarget
19614 * @chainable
19615 * @param o {EventTarget} the target to remove
19616 * @for EventTarget
19617 */
19618ETProto.removeTarget = function(o) {
19619    var targets = this._yuievt.targets;
19620
19621    if (targets) {
19622        delete targets[Y.stamp(o, true)];
19623
19624        if (YObject.size(targets) === 0) {
19625            this._yuievt.hasTargets = false;
19626        }
19627    }
19628
19629    return this;
19630};
19631
19632/**
19633 * Propagate an event.  Requires the event-custom-complex module.
19634 * @method bubble
19635 * @param evt {CustomEvent} the custom event to propagate
19636 * @return {boolean} the aggregated return value from Event.Custom.fire
19637 * @for EventTarget
19638 */
19639ETProto.bubble = function(evt, args, target, es) {
19640
19641    var targs = this._yuievt.targets,
19642        ret = true,
19643        t,
19644        ce,
19645        i,
19646        bc,
19647        ce2,
19648        type = evt && evt.type,
19649        originalTarget = target || (evt && evt.target) || this,
19650        oldbubble;
19651
19652    if (!evt || ((!evt.stopped) && targs)) {
19653
19654        for (i in targs) {
19655            if (targs.hasOwnProperty(i)) {
19656
19657                t = targs[i];
19658
19659                ce = t._yuievt.events[type];
19660
19661                if (t._hasSiblings) {
19662                    ce2 = t.getSibling(type, ce);
19663                }
19664
19665                if (ce2 && !ce) {
19666                    ce = t.publish(type);
19667                }
19668
19669                oldbubble = t._yuievt.bubbling;
19670                t._yuievt.bubbling = type;
19671
19672                // if this event was not published on the bubble target,
19673                // continue propagating the event.
19674                if (!ce) {
19675                    if (t._yuievt.hasTargets) {
19676                        t.bubble(evt, args, originalTarget, es);
19677                    }
19678                } else {
19679
19680                    if (ce2) {
19681                        ce.sibling = ce2;
19682                    }
19683
19684                    // set the original target to that the target payload on the facade is correct.
19685                    ce.target = originalTarget;
19686                    ce.originalTarget = originalTarget;
19687                    ce.currentTarget = t;
19688                    bc = ce.broadcast;
19689                    ce.broadcast = false;
19690
19691                    // default publish may not have emitFacade true -- that
19692                    // shouldn't be what the implementer meant to do
19693                    ce.emitFacade = true;
19694
19695                    ce.stack = es;
19696
19697                    // TODO: See what's getting in the way of changing this to use
19698                    // the more performant ce._fire(args || evt.details || []).
19699
19700                    // Something in Widget Parent/Child tests is not happy if we
19701                    // change it - maybe evt.details related?
19702                    ret = ret && ce.fire.apply(ce, args || evt.details || []);
19703
19704                    ce.broadcast = bc;
19705                    ce.originalTarget = null;
19706
19707                    // stopPropagation() was called
19708                    if (ce.stopped) {
19709                        break;
19710                    }
19711                }
19712
19713                t._yuievt.bubbling = oldbubble;
19714            }
19715        }
19716    }
19717
19718    return ret;
19719};
19720
19721/**
19722 * @method _hasPotentialSubscribers
19723 * @for EventTarget
19724 * @private
19725 * @param {String} fullType The fully prefixed type name
19726 * @return {boolean} Whether the event has potential subscribers or not
19727 */
19728ETProto._hasPotentialSubscribers = function(fullType) {
19729
19730    var etState = this._yuievt,
19731        e = etState.events[fullType];
19732
19733    if (e) {
19734        return e.hasSubs() || etState.hasTargets  || e.broadcast;
19735    } else {
19736        return false;
19737    }
19738};
19739
19740FACADE = new Y.EventFacade();
19741FACADE_KEYS = {};
19742
19743// Flatten whitelist
19744for (key in FACADE) {
19745    FACADE_KEYS[key] = true;
19746}
19747
19748
19749}, 'patched-v3.18.1', {"requires": ["event-custom-base"]});
19750
19751YUI.add('oop', function (Y, NAME) {
19752
19753/**
19754Adds object inheritance and manipulation utilities to the YUI instance. This
19755module is required by most YUI components.
19756
19757@module oop
19758**/
19759
19760var L            = Y.Lang,
19761    A            = Y.Array,
19762    OP           = Object.prototype,
19763    CLONE_MARKER = '_~yuim~_',
19764
19765    hasOwn   = OP.hasOwnProperty,
19766    toString = OP.toString;
19767
19768/**
19769Calls the specified _action_ method on _o_ if it exists. Otherwise, if _o_ is an
19770array, calls the _action_ method on `Y.Array`, or if _o_ is an object, calls the
19771_action_ method on `Y.Object`.
19772
19773If _o_ is an array-like object, it will be coerced to an array.
19774
19775This is intended to be used with array/object iteration methods that share
19776signatures, such as `each()`, `some()`, etc.
19777
19778@method dispatch
19779@param {Object} o Array or object to dispatch to.
19780@param {Function} f Iteration callback.
19781    @param {Mixed} f.value Value being iterated.
19782    @param {Mixed} f.key Current object key or array index.
19783    @param {Mixed} f.object Object or array being iterated.
19784@param {Object} c `this` object to bind the iteration callback to.
19785@param {Boolean} proto If `true`, prototype properties of objects will be
19786    iterated.
19787@param {String} action Function name to be dispatched on _o_. For example:
19788    'some', 'each', etc.
19789@private
19790@return {Mixed} Returns the value returned by the chosen iteration action, which
19791    varies.
19792**/
19793function dispatch(o, f, c, proto, action) {
19794    if (o && o[action] && o !== Y) {
19795        return o[action].call(o, f, c);
19796    } else {
19797        switch (A.test(o)) {
19798            case 1:
19799                return A[action](o, f, c);
19800            case 2:
19801                return A[action](Y.Array(o, 0, true), f, c);
19802            default:
19803                return Y.Object[action](o, f, c, proto);
19804        }
19805    }
19806}
19807
19808/**
19809Augments the _receiver_ with prototype properties from the _supplier_. The
19810receiver may be a constructor function or an object. The supplier must be a
19811constructor function.
19812
19813If the _receiver_ is an object, then the _supplier_ constructor will be called
19814immediately after _receiver_ is augmented, with _receiver_ as the `this` object.
19815
19816If the _receiver_ is a constructor function, then all prototype methods of
19817_supplier_ that are copied to _receiver_ will be sequestered, and the
19818_supplier_ constructor will not be called immediately. The first time any
19819sequestered method is called on the _receiver_'s prototype, all sequestered
19820methods will be immediately copied to the _receiver_'s prototype, the
19821_supplier_'s constructor will be executed, and finally the newly unsequestered
19822method that was called will be executed.
19823
19824This sequestering logic sounds like a bunch of complicated voodoo, but it makes
19825it cheap to perform frequent augmentation by ensuring that suppliers'
19826constructors are only called if a supplied method is actually used. If none of
19827the supplied methods is ever used, then there's no need to take the performance
19828hit of calling the _supplier_'s constructor.
19829
19830@method augment
19831@param {Function|Object} receiver Object or function to be augmented.
19832@param {Function} supplier Function that supplies the prototype properties with
19833  which to augment the _receiver_.
19834@param {Boolean} [overwrite=false] If `true`, properties already on the receiver
19835  will be overwritten if found on the supplier's prototype.
19836@param {String[]} [whitelist] An array of property names. If specified,
19837  only the whitelisted prototype properties will be applied to the receiver, and
19838  all others will be ignored.
19839@param {Array|any} [args] Argument or array of arguments to pass to the
19840  supplier's constructor when initializing.
19841@return {Function} Augmented object.
19842@for YUI
19843**/
19844Y.augment = function (receiver, supplier, overwrite, whitelist, args) {
19845    var rProto    = receiver.prototype,
19846        sequester = rProto && supplier,
19847        sProto    = supplier.prototype,
19848        to        = rProto || receiver,
19849
19850        copy,
19851        newPrototype,
19852        replacements,
19853        sequestered,
19854        unsequester;
19855
19856    args = args ? Y.Array(args) : [];
19857
19858    if (sequester) {
19859        newPrototype = {};
19860        replacements = {};
19861        sequestered  = {};
19862
19863        copy = function (value, key) {
19864            if (overwrite || !(key in rProto)) {
19865                if (toString.call(value) === '[object Function]') {
19866                    sequestered[key] = value;
19867
19868                    newPrototype[key] = replacements[key] = function () {
19869                        return unsequester(this, value, arguments);
19870                    };
19871                } else {
19872                    newPrototype[key] = value;
19873                }
19874            }
19875        };
19876
19877        unsequester = function (instance, fn, fnArgs) {
19878            // Unsequester all sequestered functions.
19879            for (var key in sequestered) {
19880                if (hasOwn.call(sequestered, key)
19881                        && instance[key] === replacements[key]) {
19882
19883                    instance[key] = sequestered[key];
19884                }
19885            }
19886
19887            // Execute the supplier constructor.
19888            supplier.apply(instance, args);
19889
19890            // Finally, execute the original sequestered function.
19891            return fn.apply(instance, fnArgs);
19892        };
19893
19894        if (whitelist) {
19895            Y.Array.each(whitelist, function (name) {
19896                if (name in sProto) {
19897                    copy(sProto[name], name);
19898                }
19899            });
19900        } else {
19901            Y.Object.each(sProto, copy, null, true);
19902        }
19903    }
19904
19905    Y.mix(to, newPrototype || sProto, overwrite, whitelist);
19906
19907    if (!sequester) {
19908        supplier.apply(to, args);
19909    }
19910
19911    return receiver;
19912};
19913
19914/**
19915 * Copies object properties from the supplier to the receiver. If the target has
19916 * the property, and the property is an object, the target object will be
19917 * augmented with the supplier's value.
19918 *
19919 * @method aggregate
19920 * @param {Object} receiver Object to receive the augmentation.
19921 * @param {Object} supplier Object that supplies the properties with which to
19922 *     augment the receiver.
19923 * @param {Boolean} [overwrite=false] If `true`, properties already on the receiver
19924 *     will be overwritten if found on the supplier.
19925 * @param {String[]} [whitelist] Whitelist. If supplied, only properties in this
19926 *     list will be applied to the receiver.
19927 * @return {Object} Augmented object.
19928 */
19929Y.aggregate = function(r, s, ov, wl) {
19930    return Y.mix(r, s, ov, wl, 0, true);
19931};
19932
19933/**
19934 * Utility to set up the prototype, constructor and superclass properties to
19935 * support an inheritance strategy that can chain constructors and methods.
19936 * Static members will not be inherited.
19937 *
19938 * @method extend
19939 * @param {function} r   the object to modify.
19940 * @param {function} s the object to inherit.
19941 * @param {object} px prototype properties to add/override.
19942 * @param {object} sx static properties to add/override.
19943 * @return {object} the extended object.
19944 */
19945Y.extend = function(r, s, px, sx) {
19946    if (!s || !r) {
19947        Y.error('extend failed, verify dependencies');
19948    }
19949
19950    var sp = s.prototype, rp = Y.Object(sp);
19951    r.prototype = rp;
19952
19953    rp.constructor = r;
19954    r.superclass = sp;
19955
19956    // assign constructor property
19957    if (s != Object && sp.constructor == OP.constructor) {
19958        sp.constructor = s;
19959    }
19960
19961    // add prototype overrides
19962    if (px) {
19963        Y.mix(rp, px, true);
19964    }
19965
19966    // add object overrides
19967    if (sx) {
19968        Y.mix(r, sx, true);
19969    }
19970
19971    return r;
19972};
19973
19974/**
19975 * Executes the supplied function for each item in
19976 * a collection.  Supports arrays, objects, and
19977 * NodeLists
19978 * @method each
19979 * @param {object} o the object to iterate.
19980 * @param {function} f the function to execute.  This function
19981 * receives the value, key, and object as parameters.
19982 * @param {object} c the execution context for the function.
19983 * @param {boolean} proto if true, prototype properties are
19984 * iterated on objects.
19985 * @return {YUI} the YUI instance.
19986 */
19987Y.each = function(o, f, c, proto) {
19988    return dispatch(o, f, c, proto, 'each');
19989};
19990
19991/**
19992 * Executes the supplied function for each item in
19993 * a collection.  The operation stops if the function
19994 * returns true. Supports arrays, objects, and
19995 * NodeLists.
19996 * @method some
19997 * @param {object} o the object to iterate.
19998 * @param {function} f the function to execute.  This function
19999 * receives the value, key, and object as parameters.
20000 * @param {object} c the execution context for the function.
20001 * @param {boolean} proto if true, prototype properties are
20002 * iterated on objects.
20003 * @return {boolean} true if the function ever returns true,
20004 * false otherwise.
20005 */
20006Y.some = function(o, f, c, proto) {
20007    return dispatch(o, f, c, proto, 'some');
20008};
20009
20010/**
20011Deep object/array copy. Function clones are actually wrappers around the
20012original function. Array-like objects are treated as arrays. Primitives are
20013returned untouched. Optionally, a function can be provided to handle other data
20014types, filter keys, validate values, etc.
20015
20016**Note:** Cloning a non-trivial object is a reasonably heavy operation, due to
20017the need to recursively iterate down non-primitive properties. Clone should be
20018used only when a deep clone down to leaf level properties is explicitly
20019required. This method will also
20020
20021In many cases (for example, when trying to isolate objects used as hashes for
20022configuration properties), a shallow copy, using `Y.merge()` is normally
20023sufficient. If more than one level of isolation is required, `Y.merge()` can be
20024used selectively at each level which needs to be isolated from the original
20025without going all the way to leaf properties.
20026
20027@method clone
20028@param {object} o what to clone.
20029@param {boolean} safe if true, objects will not have prototype items from the
20030    source. If false, they will. In this case, the original is initially
20031    protected, but the clone is not completely immune from changes to the source
20032    object prototype. Also, cloned prototype items that are deleted from the
20033    clone will result in the value of the source prototype being exposed. If
20034    operating on a non-safe clone, items should be nulled out rather than
20035    deleted.
20036@param {function} f optional function to apply to each item in a collection; it
20037    will be executed prior to applying the value to the new object.
20038    Return false to prevent the copy.
20039@param {object} c optional execution context for f.
20040@param {object} owner Owner object passed when clone is iterating an object.
20041    Used to set up context for cloned functions.
20042@param {object} cloned hash of previously cloned objects to avoid multiple
20043    clones.
20044@return {Array|Object} the cloned object.
20045**/
20046Y.clone = function(o, safe, f, c, owner, cloned) {
20047    var o2, marked, stamp;
20048
20049    // Does not attempt to clone:
20050    //
20051    // * Non-typeof-object values, "primitive" values don't need cloning.
20052    //
20053    // * YUI instances, cloning complex object like YUI instances is not
20054    //   advised, this is like cloning the world.
20055    //
20056    // * DOM nodes (#2528250), common host objects like DOM nodes cannot be
20057    //   "subclassed" in Firefox and old versions of IE. Trying to use
20058    //   `Object.create()` or `Y.extend()` on a DOM node will throw an error in
20059    //   these browsers.
20060    //
20061    // Instad, the passed-in `o` will be return as-is when it matches one of the
20062    // above criteria.
20063    if (!L.isObject(o) ||
20064            Y.instanceOf(o, YUI) ||
20065            (o.addEventListener || o.attachEvent)) {
20066
20067        return o;
20068    }
20069
20070    marked = cloned || {};
20071
20072    switch (L.type(o)) {
20073        case 'date':
20074            return new Date(o);
20075        case 'regexp':
20076            // if we do this we need to set the flags too
20077            // return new RegExp(o.source);
20078            return o;
20079        case 'function':
20080            // o2 = Y.bind(o, owner);
20081            // break;
20082            return o;
20083        case 'array':
20084            o2 = [];
20085            break;
20086        default:
20087
20088            // #2528250 only one clone of a given object should be created.
20089            if (o[CLONE_MARKER]) {
20090                return marked[o[CLONE_MARKER]];
20091            }
20092
20093            stamp = Y.guid();
20094
20095            o2 = (safe) ? {} : Y.Object(o);
20096
20097            o[CLONE_MARKER] = stamp;
20098            marked[stamp] = o;
20099    }
20100
20101    Y.each(o, function(v, k) {
20102        if ((k || k === 0) && (!f || (f.call(c || this, v, k, this, o) !== false))) {
20103            if (k !== CLONE_MARKER) {
20104                if (k == 'prototype') {
20105                    // skip the prototype
20106                // } else if (o[k] === o) {
20107                //     this[k] = this;
20108                } else {
20109                    this[k] =
20110                        Y.clone(v, safe, f, c, owner || o, marked);
20111                }
20112            }
20113        }
20114    }, o2);
20115
20116    if (!cloned) {
20117        Y.Object.each(marked, function(v, k) {
20118            if (v[CLONE_MARKER]) {
20119                try {
20120                    delete v[CLONE_MARKER];
20121                } catch (e) {
20122                    v[CLONE_MARKER] = null;
20123                }
20124            }
20125        }, this);
20126        marked = null;
20127    }
20128
20129    return o2;
20130};
20131
20132/**
20133 * Returns a function that will execute the supplied function in the
20134 * supplied object's context, optionally adding any additional
20135 * supplied parameters to the beginning of the arguments collection the
20136 * supplied to the function.
20137 *
20138 * @method bind
20139 * @param {Function|String} f the function to bind, or a function name
20140 * to execute on the context object.
20141 * @param {object} c the execution context.
20142 * @param {any} args* 0..n arguments to include before the arguments the
20143 * function is executed with.
20144 * @return {function} the wrapped function.
20145 */
20146Y.bind = function(f, c) {
20147    var xargs = arguments.length > 2 ?
20148            Y.Array(arguments, 2, true) : null;
20149    return function() {
20150        var fn = L.isString(f) ? c[f] : f,
20151            args = (xargs) ?
20152                xargs.concat(Y.Array(arguments, 0, true)) : arguments;
20153        return fn.apply(c || fn, args);
20154    };
20155};
20156
20157/**
20158 * Returns a function that will execute the supplied function in the
20159 * supplied object's context, optionally adding any additional
20160 * supplied parameters to the end of the arguments the function
20161 * is executed with.
20162 *
20163 * @method rbind
20164 * @param {Function|String} f the function to bind, or a function name
20165 * to execute on the context object.
20166 * @param {object} c the execution context.
20167 * @param {any} args* 0..n arguments to append to the end of
20168 * arguments collection supplied to the function.
20169 * @return {function} the wrapped function.
20170 */
20171Y.rbind = function(f, c) {
20172    var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null;
20173    return function() {
20174        var fn = L.isString(f) ? c[f] : f,
20175            args = (xargs) ?
20176                Y.Array(arguments, 0, true).concat(xargs) : arguments;
20177        return fn.apply(c || fn, args);
20178    };
20179};
20180
20181
20182}, 'patched-v3.18.1', {"requires": ["yui-base"]});
20183
20184YUI.add('aui-base-lang', function (A, NAME) {
20185
20186(function() {
20187    var Lang = A.Lang,
20188        aArray = A.Array,
20189        AObject = A.Object,
20190
20191        isArray = Lang.isArray,
20192        isNumber = Lang.isNumber,
20193        isString = Lang.isString,
20194        isUndefined = Lang.isUndefined,
20195
20196        owns = AObject.owns;
20197
20198    A.fn = function(fn, context, args) {
20199        var wrappedFn,
20200            dynamicLookup;
20201
20202        // Explicitly set function arguments
20203        if (!isNumber(fn)) {
20204            var xargs = arguments;
20205
20206            if (xargs.length > 2) {
20207                xargs = aArray(xargs, 2, true);
20208            }
20209
20210            dynamicLookup = (isString(fn) && context);
20211
20212            wrappedFn = function() {
20213                var method = (!dynamicLookup) ? fn : context[fn];
20214
20215                return method.apply(context || fn, xargs);
20216            };
20217        }
20218        else {
20219            // Set function arity
20220            var argLength = fn;
20221
20222            fn = context;
20223            context = args;
20224            dynamicLookup = (isString(fn) && context);
20225
20226            wrappedFn = function() {
20227                var method = (!dynamicLookup) ? fn : context[fn],
20228                    returnValue;
20229
20230                context = context || method;
20231
20232                if (argLength > 0) {
20233                    returnValue = method.apply(context, aArray(arguments, 0, true).slice(0, argLength));
20234                }
20235                else {
20236                    returnValue = method.call(context);
20237                }
20238
20239                return returnValue;
20240            };
20241        }
20242
20243        return wrappedFn;
20244    };
20245
20246    A.mix(Lang, {
20247        constrain: function(num, min, max) {
20248            return Math.min(Math.max(num, min), max);
20249        },
20250
20251        emptyFn: function() {},
20252
20253        emptyFnFalse: function() {
20254            return false;
20255        },
20256
20257        emptyFnTrue: function() {
20258            return true;
20259        },
20260
20261        isGuid: function(id) {
20262            return String(id).indexOf(A.Env._guidp) === 0;
20263        },
20264
20265        isInteger: function(val) {
20266            return typeof val === 'number' &&
20267                isFinite(val) &&
20268                val > -9007199254740992 &&
20269                val < 9007199254740992 &&
20270                Math.floor(val) === val;
20271        },
20272
20273        isNode: function(val) {
20274            return A.instanceOf(val, A.Node);
20275        },
20276
20277        isNodeList: function(val) {
20278            return A.instanceOf(val, A.NodeList);
20279        },
20280
20281        toFloat: function(value, defaultValue) {
20282            return parseFloat(value) || defaultValue || 0;
20283        },
20284
20285        toInt: function(value, radix, defaultValue) {
20286            return parseInt(value, radix || 10) || defaultValue || 0;
20287        }
20288    });
20289
20290    A.mix(aArray, {
20291        remove: function(a, from, to) {
20292            var rest = a.slice((to || from) + 1 || a.length);
20293            a.length = (from < 0) ? (a.length + from) : from;
20294
20295            return a.push.apply(a, rest);
20296        },
20297
20298        removeItem: function(a, item) {
20299            var index = aArray.indexOf(a, item);
20300
20301            if (index > -1) {
20302                return aArray.remove(a, index);
20303            }
20304
20305            return a;
20306        }
20307    });
20308
20309    var LString = A.namespace('Lang.String'),
20310
20311        DOC = A.config.doc,
20312        REGEX_DASH = /-([a-z])/gi,
20313        REGEX_ESCAPE_REGEX = /([.*+?^$(){}|[\]\/\\])/g,
20314        REGEX_NL2BR = /\r?\n/g,
20315        REGEX_STRIP_SCRIPTS = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/gi,
20316        REGEX_STRIP_TAGS = /<\/?[^>]+>/gi,
20317        REGEX_UNCAMELIZE = /([a-zA-Z][a-zA-Z])([A-Z])([a-z])/g,
20318        REGEX_UNCAMELIZE_REPLACE_SEPARATOR = /([a-z])([A-Z])/g,
20319        STR_ELLIPSIS = '...',
20320
20321        htmlUnescapedValues = [],
20322
20323        MAP_HTML_CHARS_ESCAPED = {
20324            '&': '&amp;',
20325            '<': '&lt;',
20326            '>': '&gt;',
20327            '"': '&#034;',
20328            '\'': '&#039;',
20329            '/': '&#047;',
20330            '`': '&#096;'
20331        },
20332        htmlChar,
20333        MAP_HTML_CHARS_UNESCAPED = {};
20334
20335    for (htmlChar in MAP_HTML_CHARS_ESCAPED) {
20336        if (MAP_HTML_CHARS_ESCAPED.hasOwnProperty(htmlChar)) {
20337            var escapedValue = MAP_HTML_CHARS_ESCAPED[htmlChar];
20338
20339            MAP_HTML_CHARS_UNESCAPED[escapedValue] = htmlChar;
20340
20341            htmlUnescapedValues.push(htmlChar);
20342        }
20343    }
20344
20345    var REGEX_HTML_ESCAPE = new RegExp('[' + htmlUnescapedValues.join('') + ']', 'g'),
20346        REGEX_HTML_UNESCAPE = /&([^;]+);/g;
20347
20348    A.mix(LString, {
20349        camelize: A.cached(
20350            function(str, separator) {
20351                var regex = REGEX_DASH;
20352
20353                str = String(str);
20354
20355                if (separator) {
20356                    regex = new RegExp(separator + '([a-z])', 'gi');
20357                }
20358
20359                return str.replace(regex, LString._camelize);
20360            }
20361        ),
20362
20363        capitalize: A.cached(
20364            function(str) {
20365                if (str) {
20366                    str = String(str);
20367
20368                    str = str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
20369                }
20370
20371                return str;
20372            }
20373        ),
20374
20375        contains: function(str, searchString) {
20376            return str.indexOf(searchString) !== -1;
20377        },
20378
20379        defaultValue: function(str, defaultValue) {
20380            if (isUndefined(str) || str === '') {
20381                if (isUndefined(defaultValue)) {
20382                    defaultValue = '';
20383                }
20384
20385                str = defaultValue;
20386            }
20387
20388            return str;
20389        },
20390
20391        endsWith: function(str, suffix) {
20392            var length = (str.length - suffix.length);
20393
20394            return ((length >= 0) && (str.indexOf(suffix, length) === length));
20395        },
20396
20397        escapeHTML: function(str) {
20398            return str.replace(REGEX_HTML_ESCAPE, LString._escapeHTML);
20399        },
20400
20401        // Courtesy of: http://simonwillison.net/2006/Jan/20/escape/
20402        escapeRegEx: function(str) {
20403            return str.replace(REGEX_ESCAPE_REGEX, '\\$1');
20404        },
20405
20406        nl2br: function(str) {
20407            return String(str).replace(REGEX_NL2BR, '<br />');
20408        },
20409
20410        padNumber: function(num, length, precision) {
20411            var str = precision ? Number(num).toFixed(precision) : String(num);
20412            var index = str.indexOf('.');
20413
20414            if (index === -1) {
20415                index = str.length;
20416            }
20417
20418            return LString.repeat('0', Math.max(0, length - index)) + str;
20419        },
20420
20421        pluralize: function(count, singularVersion, pluralVersion) {
20422            var suffix;
20423
20424            if (count === 1) {
20425                suffix = singularVersion;
20426            }
20427            else {
20428                suffix = pluralVersion || singularVersion + 's';
20429            }
20430
20431            return count + ' ' + suffix;
20432        },
20433
20434        prefix: function(prefix, str) {
20435            str = String(str);
20436
20437            if (str.indexOf(prefix) !== 0) {
20438                str = prefix + str;
20439            }
20440
20441            return str;
20442        },
20443
20444        remove: function(str, substitute, all) {
20445            var re = new RegExp(LString.escapeRegEx(substitute), all ? 'g' : '');
20446
20447            return str.replace(re, '');
20448        },
20449
20450        removeAll: function(str, substitute) {
20451            return LString.remove(str, substitute, true);
20452        },
20453
20454        repeat: function(str, length) {
20455            return new Array(length + 1).join(str);
20456        },
20457
20458        round: function(value, precision) {
20459            value = Number(value);
20460
20461            if (isNumber(precision)) {
20462                precision = Math.pow(10, precision);
20463                value = Math.round(value * precision) / precision;
20464            }
20465
20466            return value;
20467        },
20468
20469        startsWith: function(str, prefix) {
20470            return (str.lastIndexOf(prefix, 0) === 0);
20471        },
20472
20473        stripScripts: function(str) {
20474            if (str) {
20475                str = String(str).replace(REGEX_STRIP_SCRIPTS, '');
20476            }
20477
20478            return str;
20479        },
20480
20481        stripTags: function(str) {
20482            if (str) {
20483                str = String(str).replace(REGEX_STRIP_TAGS, '');
20484            }
20485
20486            return str;
20487        },
20488
20489        substr: function(str, start, length) {
20490            return String(str).substr(start, length);
20491        },
20492
20493        uncamelize: A.cached(
20494            function(str, separator) {
20495                separator = separator || ' ';
20496
20497                str = String(str);
20498
20499                str = str.replace(REGEX_UNCAMELIZE, '$1' + separator + '$2$3');
20500                str = str.replace(REGEX_UNCAMELIZE_REPLACE_SEPARATOR, '$1' + separator + '$2');
20501
20502                return str;
20503            }
20504        ),
20505
20506        toLowerCase: function(str) {
20507            return String(str).toLowerCase();
20508        },
20509
20510        toUpperCase: function(str) {
20511            return String(str).toUpperCase();
20512        },
20513
20514        trim: Lang.trim,
20515
20516        truncate: function(str, length, where) {
20517            str = String(str);
20518
20519            var ellipsisLength = STR_ELLIPSIS.length,
20520                strLength = str.length;
20521
20522            if (length > 3) {
20523                if (str && (strLength > length)) {
20524                    where = where || 'end';
20525
20526                    if (where === 'end') {
20527                        str = str.substr(0, (length - ellipsisLength)) + STR_ELLIPSIS;
20528                    }
20529                    else if (where === 'middle') {
20530                        var middlePointA = Math.floor((length - ellipsisLength) / 2),
20531                            middlePointB = middlePointA;
20532
20533                        if (length % 2 === 0) {
20534                            middlePointA = Math.ceil((length - ellipsisLength) / 2);
20535                            middlePointB = Math.floor((length - ellipsisLength) / 2);
20536                        }
20537
20538                        str = str.substr(0, middlePointA) + STR_ELLIPSIS + str.substr(strLength - middlePointB);
20539                    }
20540                    else if (where === 'start') {
20541                        str = STR_ELLIPSIS + str.substr(strLength - length + ellipsisLength);
20542                    }
20543                }
20544            }
20545            else {
20546                str = STR_ELLIPSIS;
20547            }
20548
20549            return str;
20550        },
20551
20552        undef: function(str) {
20553            if (isUndefined(str)) {
20554                str = '';
20555            }
20556
20557            return str;
20558        },
20559
20560        // inspired from Google unescape entities
20561        unescapeEntities: function(str) {
20562            if (LString.contains(str, '&')) {
20563                if (DOC && !LString.contains(str, '<')) {
20564                    str = LString._unescapeEntitiesUsingDom(str);
20565                }
20566                else {
20567                    str = LString.unescapeHTML(str);
20568                }
20569            }
20570
20571            return str;
20572        },
20573
20574        unescapeHTML: function(str) {
20575            return str.replace(REGEX_HTML_UNESCAPE, LString._unescapeHTML);
20576        },
20577
20578        _camelize: function(match0, match1) {
20579            return match1.toUpperCase();
20580        },
20581
20582        _escapeHTML: function(match) {
20583            return MAP_HTML_CHARS_ESCAPED[match];
20584        },
20585
20586        _unescapeHTML: function(match, entity) {
20587            var value = MAP_HTML_CHARS_UNESCAPED[match] || match;
20588
20589            if (!value && entity.charAt(0) === '#') {
20590                var charCode = Number('0' + value.substr(1));
20591
20592                if (!isNaN(charCode)) {
20593                    value = String.fromCharCode(charCode);
20594                }
20595            }
20596
20597            return value;
20598        },
20599
20600        _unescapeEntitiesUsingDom: function(str) {
20601            var el = DOC.createElement('a');
20602
20603            el.innerHTML = str;
20604
20605            if (el.normalize) {
20606                el.normalize();
20607            }
20608
20609            str = el.firstChild.nodeValue;
20610
20611            el.innerHTML = '';
20612
20613            return str;
20614        }
20615    });
20616
20617    /*
20618     * Maps an object to an array, using the return value of fn as the values
20619     * for the new array.
20620     */
20621    AObject.map = function(obj, fn, context) {
20622        var map = [],
20623            i;
20624
20625        for (i in obj) {
20626            if (owns(obj, i)) {
20627                map[map.length] = fn.call(context, obj[i], i, obj);
20628            }
20629        }
20630
20631        return map;
20632    };
20633
20634    /*
20635     * Maps an array or object to a resulting array, using the return value of
20636     * fn as the values for the new array. Like A.each, this function can accept
20637     * an object or an array.
20638     */
20639    A.map = function(obj) {
20640        var module = AObject;
20641
20642        if (isArray(obj)) {
20643            module = aArray;
20644        }
20645
20646        return module.map.apply(this, arguments);
20647    };
20648}());
20649
20650
20651}, '3.1.0-deprecated.77');
20652
20653/**
20654 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
20655 *
20656 * This library is free software; you can redistribute it and/or modify it under
20657 * the terms of the GNU Lesser General Public License as published by the Free
20658 * Software Foundation; either version 2.1 of the License, or (at your option)
20659 * any later version.
20660 *
20661 * This library is distributed in the hope that it will be useful, but WITHOUT
20662 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20663 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
20664 * details.
20665 */
20666(function () {
20667  var A = AUI().use('oop');
20668  var usedModules = {};
20669  var Dependency = {
20670    _getAOP: function _getAOP(obj, methodName) {
20671      return obj._yuiaop && obj._yuiaop[methodName];
20672    },
20673    _proxy: function _proxy(obj, methodName, methodFn, context, guid, modules, _A) {
20674      var args;
20675      var queue = Dependency._proxyLoaders[guid];
20676
20677      Dependency._replaceMethod(obj, methodName, methodFn, context);
20678
20679      while (args = queue.next()) {
20680        methodFn.apply(context, args);
20681      }
20682
20683      for (var i = modules.length - 1; i >= 0; i--) {
20684        usedModules[modules[i]] = true;
20685      }
20686    },
20687    _proxyLoaders: {},
20688    _replaceMethod: function _replaceMethod(obj, methodName, methodFn) {
20689      var AOP = Dependency._getAOP(obj, methodName);
20690
20691      var proxy = obj[methodName];
20692
20693      if (AOP) {
20694        proxy = AOP.method;
20695        AOP.method = methodFn;
20696      } else {
20697        obj[methodName] = methodFn;
20698      }
20699
20700      A.mix(methodFn, proxy);
20701    },
20702    provide: function provide(obj, methodName, methodFn, modules, proto) {
20703      if (!Array.isArray(modules)) {
20704        modules = [modules];
20705      }
20706
20707      var before;
20708      var guid = A.guid();
20709
20710      if (A.Lang.isObject(methodFn, true)) {
20711        var config = methodFn;
20712        methodFn = config.fn;
20713        before = config.before;
20714
20715        if (!A.Lang.isFunction(before)) {
20716          before = null;
20717        }
20718      }
20719
20720      if (proto && A.Lang.isFunction(obj)) {
20721        obj = obj.prototype;
20722      }
20723
20724      var AOP = Dependency._getAOP(obj, methodName);
20725
20726      if (AOP) {
20727        delete obj._yuiaop[methodName];
20728      }
20729
20730      var proxy = function proxy() {
20731        var args = arguments;
20732        var context = obj;
20733
20734        if (proto) {
20735          context = this;
20736        }
20737
20738        if (modules.length == 1) {
20739          if (modules[0] in usedModules) {
20740            Dependency._replaceMethod(obj, methodName, methodFn, context);
20741
20742            methodFn.apply(context, args);
20743            return;
20744          }
20745        }
20746
20747        var firstLoad = false;
20748        var queue = Dependency._proxyLoaders[guid];
20749
20750        if (!queue) {
20751          firstLoad = true;
20752          Dependency._proxyLoaders[guid] = new A.Queue();
20753          queue = Dependency._proxyLoaders[guid];
20754        }
20755
20756        queue.add(args);
20757
20758        if (firstLoad) {
20759          modules.push(A.bind(Dependency._proxy, Liferay, obj, methodName, methodFn, context, guid, modules));
20760          A.use.apply(A, modules);
20761        }
20762      };
20763
20764      proxy.toString = function () {
20765        return methodFn.toString();
20766      };
20767
20768      obj[methodName] = proxy;
20769    }
20770  };
20771  Liferay.Dependency = Dependency;
20772  Liferay.provide = Dependency.provide;
20773})();
20774//# sourceMappingURL=dependency.js.map
20775function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
20776
20777function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
20778
20779function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
20780
20781function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
20782
20783/**
20784 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
20785 *
20786 * This library is free software; you can redistribute it and/or modify it under
20787 * the terms of the GNU Lesser General Public License as published by the Free
20788 * Software Foundation; either version 2.1 of the License, or (at your option)
20789 * any later version.
20790 *
20791 * This library is distributed in the hope that it will be useful, but WITHOUT
20792 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20793 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
20794 * details.
20795 */
20796(function (A, Liferay) {
20797  A.use('aui-base-lang');
20798  var AArray = A.Array;
20799  var Lang = A.Lang;
20800  var EVENT_CLICK = 'click';
20801  var MAP_TOGGLE_STATE = {
20802    "false": {
20803      cssClass: 'controls-hidden',
20804      iconCssClass: 'hidden',
20805      state: 'hidden'
20806    },
20807    "true": {
20808      cssClass: 'controls-visible',
20809      iconCssClass: 'view',
20810      state: 'visible'
20811    }
20812  };
20813  var REGEX_SUB = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g;
20814  var SRC_HIDE_LINK = {
20815    src: 'hideLink'
20816  };
20817  var STR_RIGHT_SQUARE_BRACKET = ']';
20818  var TPL_LEXICON_ICON = '<svg class="lexicon-icon lexicon-icon-{0} {1}" focusable="false" role="image">' + '<use data-href="' + themeDisplay.getPathThemeImages() + '/lexicon/icons.svg#{0}" />' + '</svg>';
20819  var Window = {
20820    _map: {},
20821    getById: function getById(id) {
20822      var instance = this;
20823      return instance._map[id];
20824    }
20825  };
20826  var Util = {
20827    _getEditableInstance: function _getEditableInstance(title) {
20828      var editable = Util._EDITABLE;
20829
20830      if (!editable) {
20831        editable = new A.Editable({
20832          after: {
20833            contentTextChange: function contentTextChange(event) {
20834              var instance = this;
20835
20836              if (!event.initial) {
20837                var title = instance.get('node');
20838                var portletTitleEditOptions = title.getData('portletTitleEditOptions');
20839                Util.savePortletTitle({
20840                  doAsUserId: portletTitleEditOptions.doAsUserId,
20841                  plid: portletTitleEditOptions.plid,
20842                  portletId: portletTitleEditOptions.portletId,
20843                  title: event.newVal
20844                });
20845              }
20846            },
20847            startEditing: function startEditing() {
20848              var instance = this;
20849              var Layout = Liferay.Layout;
20850
20851              if (Layout) {
20852                instance._dragListener = Layout.getLayoutHandler().on('drag:start', function () {
20853                  instance.fire('save');
20854                });
20855              }
20856
20857              var title = instance.get('node');
20858              instance._titleListener = title.on('mouseupoutside', function (event) {
20859                var editable = Util._getEditableInstance(title);
20860
20861                if (!editable.get('boundingBox').contains(event.target)) {
20862                  editable.save();
20863                }
20864              });
20865            },
20866            stopEditing: function stopEditing() {
20867              var instance = this;
20868
20869              if (instance._dragListener) {
20870                instance._dragListener.detach();
20871              }
20872
20873              if (instance._titleListener) {
20874                instance._titleListener.detach();
20875              }
20876            }
20877          },
20878          cssClass: 'lfr-portlet-title-editable',
20879          node: title
20880        });
20881        editable.get('cancelButton').icon = 'times';
20882        editable.get('saveButton').icon = 'check';
20883        Util._EDITABLE = editable;
20884      }
20885
20886      return editable;
20887    },
20888    addInputCancel: function addInputCancel() {
20889      A.use('aui-button-search-cancel', function (A) {
20890        new A.ButtonSearchCancel({
20891          trigger: 'input[type=password], input[type=search], input.clearable, input.search-query'
20892        });
20893      });
20894
20895      Util.addInputCancel = function () {};
20896    },
20897    checkAll: function checkAll(form, name, allBox, selectClassName) {
20898      if (form) {
20899        form = Util.getDOM(form);
20900
20901        if (typeof form === 'string') {
20902          form = document.querySelector(form);
20903        }
20904
20905        allBox = Util.getDOM(allBox);
20906
20907        if (typeof allBox === 'string') {
20908          allBox = document.querySelector(allBox);
20909        }
20910
20911        var selector;
20912
20913        if (Array.isArray(name)) {
20914          selector = 'input[name=' + name.join('], input[name=') + STR_RIGHT_SQUARE_BRACKET;
20915        } else {
20916          selector = 'input[name=' + name + STR_RIGHT_SQUARE_BRACKET;
20917        }
20918
20919        var allBoxChecked = allBox.checked;
20920        var uploadedItems = Array.from(form.querySelectorAll(selector));
20921        uploadedItems.forEach(function (item) {
20922          if (!item.disabled) {
20923            item.checked = allBoxChecked;
20924          }
20925        });
20926
20927        if (selectClassName) {
20928          var selectItem = form.querySelector(selectClassName);
20929
20930          if (allBoxChecked) {
20931            selectItem.classList.add('info');
20932          } else {
20933            selectItem.classList.remove('info');
20934          }
20935        }
20936      }
20937    },
20938    checkAllBox: function checkAllBox(form, name, allBox) {
20939      var totalOn = 0;
20940
20941      if (form) {
20942        form = Util.getDOM(form);
20943
20944        if (typeof form === 'string') {
20945          form = document.querySelector(form);
20946        }
20947
20948        allBox = Util.getDOM(allBox);
20949
20950        if (typeof allBox === 'string') {
20951          allBox = document.querySelector(allBox) || form.querySelector("input[name=\"".concat(allBox, "\"]"));
20952        }
20953
20954        var inputs = Array.from(form.querySelectorAll('input[type=checkbox]'));
20955
20956        if (!Array.isArray(name)) {
20957          name = [name];
20958        }
20959
20960        var totalBoxes = 0;
20961        inputs.forEach(function (input) {
20962          if (input.id !== allBox.id || input.id !== allBox.name && name.indexOf(input.name) > -1) {
20963            totalBoxes++;
20964
20965            if (input.checked) {
20966              totalOn++;
20967            }
20968          }
20969        });
20970        allBox.checked = totalBoxes === totalOn;
20971      }
20972
20973      return totalOn;
20974    },
20975    checkTab: function checkTab(box) {
20976      if (document.all && window.event.keyCode == 9) {
20977        box.selection = document.selection.createRange();
20978        setTimeout(function () {
20979          Util.processTab(box.id);
20980        }, 0);
20981      }
20982    },
20983    disableElements: function disableElements(el) {
20984      var currentElement = Util.getElement(el);
20985
20986      if (currentElement) {
20987        var children = currentElement.getElementsByTagName('*');
20988
20989        var emptyFnFalse = function emptyFnFalse() {
20990          return false;
20991        };
20992
20993        for (var i = children.length - 1; i >= 0; i--) {
20994          var item = children[i];
20995          item.style.cursor = 'default';
20996          item.onclick = emptyFnFalse;
20997          item.onmouseover = emptyFnFalse;
20998          item.onmouseout = emptyFnFalse;
20999          item.onmouseenter = emptyFnFalse;
21000          item.onmouseleave = emptyFnFalse;
21001          item.action = '';
21002          item.disabled = true;
21003          item.href = 'javascript:;';
21004          item.onsubmit = emptyFnFalse;
21005        }
21006      }
21007    },
21008    disableFormButtons: function disableFormButtons(inputs, form) {
21009      inputs.attr('disabled', true);
21010      inputs.setStyle('opacity', 0.5);
21011
21012      if (A.UA.gecko) {
21013        A.getWin().on('unload', function () {
21014          inputs.attr('disabled', false);
21015        });
21016      } else if (A.UA.safari) {
21017        A.use('node-event-html5', function (A) {
21018          A.getWin().on('pagehide', function () {
21019            Util.enableFormButtons(inputs, form);
21020          });
21021        });
21022      }
21023    },
21024    disableToggleBoxes: function disableToggleBoxes(checkBoxId, toggleBoxId, checkDisabled) {
21025      var checkBox = document.getElementById(checkBoxId);
21026      var toggleBox = document.getElementById(toggleBoxId);
21027
21028      if (checkBox && toggleBox) {
21029        toggleBox.disabled = checkDisabled && checkBox.checked;
21030        checkBox.addEventListener(EVENT_CLICK, function () {
21031          toggleBox.disabled = !toggleBox.disabled;
21032        });
21033      }
21034    },
21035    enableFormButtons: function enableFormButtons(inputs) {
21036      Util._submitLocked = null;
21037      Util.toggleDisabled(inputs, false);
21038    },
21039
21040    /**
21041     * @deprecated As of Athanasius (7.3.x), with no direct replacement
21042     */
21043    escapeCDATA: function escapeCDATA(str) {
21044      return str.replace(/<!\[CDATA\[|\]\]>/gi, function (match) {
21045        var str = '';
21046
21047        if (match == ']]>') {
21048          str = ']]&gt;';
21049        } else if (match == '<![CDATA[') {
21050          str = '&lt;![CDATA[';
21051        }
21052
21053        return str;
21054      });
21055    },
21056    forcePost: function forcePost(link) {
21057      var currentElement = Util.getElement(link);
21058
21059      if (currentElement) {
21060        var url = currentElement.getAttribute('href');
21061        var newWindow = currentElement.getAttribute('target') == '_blank';
21062        var hrefFm = document.hrefFm;
21063
21064        if (newWindow) {
21065          hrefFm.setAttribute('target', '_blank');
21066        }
21067
21068        submitForm(hrefFm, url, !newWindow);
21069        Util._submitLocked = null;
21070      }
21071    },
21072    getAttributes: function getAttributes(el, attributeGetter) {
21073      var result = null;
21074
21075      if (el) {
21076        el = Util.getDOM(el);
21077
21078        if (el.jquery) {
21079          el = el[0];
21080        }
21081
21082        result = {};
21083        var getterFn = typeof attributeGetter === 'function';
21084        var getterString = typeof attributeGetter === 'string';
21085        var attrs = el.attributes;
21086        var length = attrs.length;
21087
21088        while (length--) {
21089          var attr = attrs[length];
21090          var name = attr.nodeName.toLowerCase();
21091          var value = attr.nodeValue;
21092
21093          if (getterString) {
21094            if (name.indexOf(attributeGetter) === 0) {
21095              name = name.substr(attributeGetter.length);
21096            } else {
21097              continue;
21098            }
21099          } else if (getterFn) {
21100            value = attributeGetter(value, name, attrs);
21101
21102            if (value === false) {
21103              continue;
21104            }
21105          }
21106
21107          result[name] = value;
21108        }
21109      }
21110
21111      return result;
21112    },
21113    getColumnId: function getColumnId(str) {
21114      var columnId = str.replace(/layout-column_/, '');
21115      return columnId;
21116    },
21117    getGeolocation: function getGeolocation(success, fallback, options) {
21118      if (success && navigator.geolocation) {
21119        navigator.geolocation.getCurrentPosition(function (position) {
21120          success(position.coords.latitude, position.coords.longitude, position);
21121        }, fallback, options);
21122      } else if (fallback) {
21123        fallback();
21124      }
21125    },
21126    getLexiconIcon: function getLexiconIcon(icon, cssClass) {
21127      var instance = this;
21128      var tempElement = document.createElement('div');
21129      tempElement.innerHTML = instance.getLexiconIconTpl(icon, cssClass);
21130      return tempElement.firstChild;
21131    },
21132    getLexiconIconTpl: function getLexiconIconTpl(icon, cssClass) {
21133      return Liferay.Util.sub(TPL_LEXICON_ICON, icon, cssClass || '');
21134    },
21135    getOpener: function getOpener() {
21136      var openingWindow = Window._opener;
21137
21138      if (!openingWindow) {
21139        var topUtil = Liferay.Util.getTop().Liferay.Util;
21140        var windowName = Liferay.Util.getWindowName();
21141        var dialog = topUtil.Window.getById(windowName);
21142
21143        if (dialog) {
21144          openingWindow = dialog._opener;
21145          Window._opener = openingWindow;
21146        }
21147      }
21148
21149      return openingWindow || window.opener || window.parent;
21150    },
21151    getTop: function getTop() {
21152      var topWindow = Util._topWindow;
21153
21154      if (!topWindow) {
21155        var parentWindow = window.parent;
21156        var parentThemeDisplay;
21157
21158        while (parentWindow != window) {
21159          try {
21160            if (typeof parentWindow.location.href == 'undefined') {
21161              break;
21162            }
21163
21164            parentThemeDisplay = parentWindow.themeDisplay;
21165          } catch (e) {
21166            break;
21167          }
21168
21169          if (!parentThemeDisplay || window.name === 'simulationDeviceIframe') {
21170            break;
21171          } else if (!parentThemeDisplay.isStatePopUp() || parentWindow == parentWindow.parent) {
21172            topWindow = parentWindow;
21173            break;
21174          }
21175
21176          parentWindow = parentWindow.parent;
21177        }
21178
21179        if (!topWindow) {
21180          topWindow = window;
21181        }
21182
21183        Util._topWindow = topWindow;
21184      }
21185
21186      return topWindow;
21187    },
21188    getURLWithSessionId: function getURLWithSessionId(url) {
21189      if (!themeDisplay.isAddSessionIdToURL()) {
21190        return url;
21191      } // LEP-4787
21192
21193
21194      var x = url.indexOf(';');
21195
21196      if (x > -1) {
21197        return url;
21198      }
21199
21200      var sessionId = ';jsessionid=' + themeDisplay.getSessionId();
21201      x = url.indexOf('?');
21202
21203      if (x > -1) {
21204        return url.substring(0, x) + sessionId + url.substring(x);
21205      } // In IE6, http://www.abc.com;jsessionid=XYZ does not work, but
21206      // http://www.abc.com/;jsessionid=XYZ does work.
21207
21208
21209      x = url.indexOf('//');
21210
21211      if (x > -1) {
21212        var y = url.lastIndexOf('/');
21213
21214        if (x + 1 == y) {
21215          return url + '/' + sessionId;
21216        }
21217      }
21218
21219      return url + sessionId;
21220    },
21221    getWindow: function getWindow(id) {
21222      if (!id) {
21223        id = Util.getWindowName();
21224      }
21225
21226      return Util.getTop().Liferay.Util.Window.getById(id);
21227    },
21228    getWindowName: function getWindowName() {
21229      return window.name || Window._name || '';
21230    },
21231
21232    /**
21233     * @deprecated As of Athanasius (7.3.x), replaced by `window.innerWidth`
21234     */
21235    getWindowWidth: function getWindowWidth() {
21236      return window.innerWidth;
21237    },
21238
21239    /**
21240     * @deprecated As of Athanasius (7.3.x), replaced by `typeof val === 'function'`
21241     */
21242    isFunction: function isFunction(val) {
21243      return typeof val === 'function';
21244    },
21245    listCheckboxesExcept: function listCheckboxesExcept(form, except, name, checked) {
21246      form = Util.getDOM(form);
21247
21248      if (typeof form === 'string') {
21249        form = document.querySelector(form);
21250      }
21251
21252      var selector = 'input[type=checkbox]';
21253
21254      if (name) {
21255        selector += '[name=' + name + ']';
21256      }
21257
21258      var checkboxes = Array.from(form.querySelectorAll(selector));
21259      return checkboxes.reduce(function (prev, item) {
21260        var value = item.value;
21261
21262        if (value && item.name !== except && item.checked === checked && !item.disabled) {
21263          prev.push(value);
21264        }
21265
21266        return prev;
21267      }, []).join();
21268    },
21269    listCheckedExcept: function listCheckedExcept(form, except, name) {
21270      return Util.listCheckboxesExcept(form, except, name, true);
21271    },
21272    listSelect: function listSelect(select, delimeter) {
21273      select = Util.getElement(select);
21274      return Array.from(select.querySelectorAll('option')).reduce(function (prev, item) {
21275        var val = item.value;
21276
21277        if (val) {
21278          prev.push(val);
21279        }
21280
21281        return prev;
21282      }, []).join(delimeter || ',');
21283    },
21284    listUncheckedExcept: function listUncheckedExcept(form, except, name) {
21285      return Util.listCheckboxesExcept(form, except, name, false);
21286    },
21287    openInDialog: function openInDialog(event, config) {
21288      event.preventDefault();
21289      var currentTarget = Util.getElement(event.currentTarget);
21290      config = A.mix(A.merge({}, currentTarget.dataset), config);
21291
21292      if (!config.uri) {
21293        config.uri = currentTarget.dataset.href || currentTarget.getAttribute('href');
21294      }
21295
21296      if (!config.title) {
21297        config.title = currentTarget.getAttribute('title');
21298      }
21299
21300      Liferay.Util.openWindow(config);
21301    },
21302    openWindow: function openWindow(config, callback) {
21303      config.openingWindow = window;
21304      var top = Util.getTop();
21305      var topUtil = top.Liferay.Util;
21306
21307      topUtil._openWindowProvider(config, callback);
21308    },
21309    processTab: function processTab(id) {
21310      document.all[id].selection.text = String.fromCharCode(9);
21311      document.all[id].focus();
21312    },
21313
21314    /**
21315     * @deprecated As of Athanasius (7.3.x), with no direct replacement
21316     */
21317    randomInt: function randomInt() {
21318      return Math.ceil(Math.random() * new Date().getTime());
21319    },
21320    removeEntitySelection: function removeEntitySelection(entityIdString, entityNameString, removeEntityButton, namespace) {
21321      var elementByEntityId = document.getElementById("".concat(namespace).concat(entityIdString));
21322
21323      if (elementByEntityId) {
21324        elementByEntityId.value = 0;
21325      }
21326
21327      var elementByEntityName = document.getElementById("".concat(namespace).concat(entityNameString));
21328
21329      if (elementByEntityName) {
21330        elementByEntityName.value = '';
21331      }
21332
21333      Liferay.Util.toggleDisabled(removeEntityButton, true);
21334      Liferay.fire('entitySelectionRemoved');
21335    },
21336    reorder: function reorder(box, down) {
21337      box = Util.getElement(box);
21338
21339      if (box) {
21340        if (box.getAttribute('selectedIndex') == -1) {
21341          box.setAttribute('selectedIndex', 0);
21342        } else {
21343          var selectedItems = Array.from(box.querySelectorAll('option:checked'));
21344          var items = Array.from(box.querySelectorAll('option'));
21345
21346          if (down) {
21347            selectedItems.reverse().forEach(function (item) {
21348              var itemIndex = items.indexOf(item);
21349              var lastIndex = items.length - 1;
21350
21351              if (itemIndex === lastIndex) {
21352                box.insertBefore(item, box.firstChild);
21353              } else {
21354                var nextItem = item.nextElementSibling.nextElementSibling;
21355                box.insertBefore(item, nextItem);
21356              }
21357            });
21358          } else {
21359            selectedItems.forEach(function (item) {
21360              var itemIndex = items.indexOf(item);
21361
21362              if (itemIndex === 0) {
21363                box.appendChild(item);
21364              } else {
21365                box.insertBefore(item, item.previousElementSibling);
21366              }
21367            });
21368          }
21369        }
21370      }
21371    },
21372    rowCheckerCheckAllBox: function rowCheckerCheckAllBox(ancestorTable, ancestorRow, checkboxesIds, checkboxAllIds, cssClass) {
21373      Util.checkAllBox(ancestorTable, checkboxesIds, checkboxAllIds);
21374
21375      if (ancestorRow) {
21376        ancestorRow.toggleClass(cssClass);
21377      }
21378    },
21379    savePortletTitle: function savePortletTitle(params) {
21380      params = _objectSpread({
21381        doAsUserId: 0,
21382        plid: 0,
21383        portletId: 0,
21384        title: '',
21385        url: themeDisplay.getPathMain() + '/portal/update_portlet_title'
21386      }, params);
21387      var data = {
21388        doAsUserId: params.doAsUserId,
21389        p_auth: Liferay.authToken,
21390        p_l_id: params.plid,
21391        portletId: params.portletId,
21392        title: params.title
21393      };
21394      Liferay.Util.fetch(params.url, {
21395        body: Liferay.Util.objectToFormData(data),
21396        method: 'POST'
21397      });
21398    },
21399    selectFolder: function selectFolder(folderData, namespace) {
21400      var folderDataElement = document.getElementById(namespace + folderData.idString);
21401
21402      if (folderDataElement) {
21403        folderDataElement.value = folderData.idValue;
21404      }
21405
21406      var folderNameElement = document.getElementById(namespace + folderData.nameString);
21407
21408      if (folderNameElement) {
21409        folderNameElement.value = this.unescape(folderData.nameValue);
21410      }
21411
21412      var removeFolderButton = document.getElementById("".concat(namespace, "removeFolderButton"));
21413
21414      if (removeFolderButton) {
21415        this.toggleDisabled(removeFolderButton, false);
21416      }
21417    },
21418    setCursorPosition: function setCursorPosition(el, position) {
21419      var instance = this;
21420      instance.setSelectionRange(el, position, position);
21421    },
21422    setSelectionRange: function setSelectionRange(el, selectionStart, selectionEnd) {
21423      el = Util.getDOM(el);
21424
21425      if (el.jquery) {
21426        el = el[0];
21427      }
21428
21429      if (el.setSelectionRange) {
21430        el.focus();
21431        el.setSelectionRange(selectionStart, selectionEnd);
21432      } else if (el.createTextRange) {
21433        var textRange = el.createTextRange();
21434        textRange.collapse(true);
21435        textRange.moveEnd('character', selectionEnd);
21436        textRange.moveEnd('character', selectionStart);
21437        textRange.select();
21438      }
21439    },
21440    showCapsLock: function showCapsLock(event, spanId) {
21441      var span = document.getElementById(spanId);
21442
21443      if (span) {
21444        var keyCode = event.keyCode ? event.keyCode : event.which;
21445        var shiftKeyCode = keyCode === 16;
21446        var shiftKey = event.shiftKey ? event.shiftKey : shiftKeyCode;
21447        var display = 'none';
21448
21449        if (keyCode >= 65 && keyCode <= 90 && !shiftKey || keyCode >= 97 && keyCode <= 122 && shiftKey) {
21450          display = '';
21451        }
21452
21453        span.style.display = display;
21454      }
21455    },
21456
21457    /**
21458     * @deprecated As of Athanasius (7.3.x), with no direct replacement
21459     */
21460    sortByAscending: function sortByAscending(a, b) {
21461      a = a[1].toLowerCase();
21462      b = b[1].toLowerCase();
21463
21464      if (a > b) {
21465        return 1;
21466      }
21467
21468      if (a < b) {
21469        return -1;
21470      }
21471
21472      return 0;
21473    },
21474    sub: function sub(string, data) {
21475      if (arguments.length > 2 || _typeof(data) !== 'object' && typeof data !== 'function') {
21476        data = Array.prototype.slice.call(arguments, 1);
21477      }
21478
21479      return string.replace ? string.replace(REGEX_SUB, function (match, key) {
21480        return data[key] === undefined ? match : data[key];
21481      }) : string;
21482    },
21483    submitCountdown: 0,
21484    submitForm: function submitForm(form) {
21485      form.submit();
21486    },
21487
21488    /**
21489     * @deprecated As of Athanasius (7.3.x), replaced by `parseInt()`
21490     */
21491    toNumber: function toNumber(value) {
21492      return parseInt(value, 10) || 0;
21493    },
21494    toggleBoxes: function toggleBoxes(checkBoxId, toggleBoxId, displayWhenUnchecked, toggleChildCheckboxes) {
21495      var checkBox = document.getElementById(checkBoxId);
21496      var toggleBox = document.getElementById(toggleBoxId);
21497
21498      if (checkBox && toggleBox) {
21499        var checked = checkBox.checked;
21500
21501        if (displayWhenUnchecked) {
21502          checked = !checked;
21503        }
21504
21505        if (checked) {
21506          toggleBox.classList.remove('hide');
21507        } else {
21508          toggleBox.classList.add('hide');
21509        }
21510
21511        checkBox.addEventListener(EVENT_CLICK, function () {
21512          toggleBox.classList.toggle('hide');
21513
21514          if (toggleChildCheckboxes) {
21515            var childCheckboxes = toggleBox.querySelectorAll('input[type=checkbox]');
21516            childCheckboxes.forEach(function (childCheckbox) {
21517              childCheckbox.checked = checkBox.checked;
21518            });
21519          }
21520        });
21521      }
21522    },
21523    toggleRadio: function toggleRadio(radioId, showBoxIds, hideBoxIds) {
21524      var radioButton = document.getElementById(radioId);
21525
21526      if (radioButton) {
21527        var showBoxes;
21528
21529        if (showBoxIds) {
21530          if (Array.isArray(showBoxIds)) {
21531            showBoxIds = showBoxIds.join(',#');
21532          }
21533
21534          showBoxes = document.querySelectorAll('#' + showBoxIds);
21535          showBoxes.forEach(function (showBox) {
21536            if (radioButton.checked) {
21537              showBox.classList.remove('hide');
21538            } else {
21539              showBox.classList.add('hide');
21540            }
21541          });
21542        }
21543
21544        radioButton.addEventListener('change', function () {
21545          if (showBoxes) {
21546            showBoxes.forEach(function (showBox) {
21547              showBox.classList.remove('hide');
21548            });
21549          }
21550
21551          if (hideBoxIds) {
21552            if (Array.isArray(hideBoxIds)) {
21553              hideBoxIds = hideBoxIds.join(',#');
21554            }
21555
21556            var hideBoxes = document.querySelectorAll('#' + hideBoxIds);
21557            hideBoxes.forEach(function (hideBox) {
21558              hideBox.classList.add('hide');
21559            });
21560          }
21561        });
21562      }
21563    },
21564
21565    /*
21566     * @deprecated As of Athanasius (7.3.x), with no direct replacement
21567     */
21568    toggleSearchContainerButton: function toggleSearchContainerButton(buttonId, searchContainerId, form, ignoreFieldName) {
21569      A.one(searchContainerId).delegate(EVENT_CLICK, function () {
21570        Util.toggleDisabled(buttonId, !Util.listCheckedExcept(form, ignoreFieldName));
21571      }, 'input[type=checkbox]');
21572    },
21573    toggleSelectBox: function toggleSelectBox(selectBoxId, value, toggleBoxId) {
21574      var selectBox = document.getElementById(selectBoxId);
21575      var toggleBox = document.getElementById(toggleBoxId);
21576
21577      if (selectBox && toggleBox) {
21578        var dynamicValue = typeof value === 'function';
21579
21580        var toggle = function toggle() {
21581          var currentValue = selectBox.value;
21582          var visible = value == currentValue;
21583
21584          if (dynamicValue) {
21585            visible = value(currentValue, value);
21586          }
21587
21588          if (visible) {
21589            toggleBox.classList.remove('hide');
21590          } else {
21591            toggleBox.classList.add('hide');
21592          }
21593        };
21594
21595        toggle();
21596        selectBox.addEventListener('change', toggle);
21597      }
21598    }
21599  };
21600  Liferay.provide(Util, 'afterIframeLoaded', function (event) {
21601    var nodeInstances = A.Node._instances;
21602    var docEl = event.doc;
21603    var docUID = docEl._yuid;
21604
21605    if (docUID in nodeInstances) {
21606      delete nodeInstances[docUID];
21607    }
21608
21609    var iframeDocument = A.one(docEl);
21610    var iframeBody = iframeDocument.one('body');
21611    var dialog = event.dialog;
21612    var lfrFormContent = iframeBody.one('.lfr-form-content');
21613    iframeBody.addClass('dialog-iframe-popup');
21614
21615    if (lfrFormContent && iframeBody.one('.button-holder.dialog-footer')) {
21616      iframeBody.addClass('dialog-with-footer');
21617      var stagingAlert = iframeBody.one('.portlet-body > .lfr-portlet-message-staging-alert');
21618
21619      if (stagingAlert) {
21620        stagingAlert.remove();
21621        lfrFormContent.prepend(stagingAlert);
21622      }
21623    }
21624
21625    iframeBody.addClass(dialog.iframeConfig.bodyCssClass);
21626    event.win.focus();
21627    var iframeWindow = event.win;
21628
21629    if (iframeWindow.Liferay.SPA) {
21630      var beforeScreenFlipHandler = iframeWindow.Liferay.on('beforeScreenFlip', function () {
21631        iframeWindow.document.body.classList.add('dialog-iframe-popup');
21632      });
21633
21634      iframeWindow.onunload = function () {
21635        if (beforeScreenFlipHandler) {
21636          iframeWindow.Liferay.detach(beforeScreenFlipHandler);
21637        }
21638      };
21639    }
21640
21641    var detachEventHandles = function detachEventHandles() {
21642      AArray.invoke(eventHandles, 'detach');
21643      iframeDocument.purge(true);
21644    };
21645
21646    var eventHandles = [iframeBody.delegate('submit', detachEventHandles, 'form'), iframeBody.delegate(EVENT_CLICK, function (event) {
21647      dialog.set('visible', false, event.currentTarget.hasClass('lfr-hide-dialog') ? SRC_HIDE_LINK : null);
21648      detachEventHandles();
21649    }, '.btn-cancel,.lfr-hide-dialog')];
21650    Liferay.fire('modalIframeLoaded', {
21651      src: event.dialog.iframe.node.getAttribute('src')
21652    });
21653  }, ['aui-base']);
21654  Liferay.provide(Util, 'openDDMPortlet', function (config, callback) {
21655    var defaultValues = {
21656      eventName: 'selectStructure'
21657    };
21658    config = A.merge(defaultValues, config);
21659    var params = {
21660      classNameId: config.classNameId,
21661      classPK: config.classPK,
21662      doAsGroupId: config.doAsGroupId || themeDisplay.getScopeGroupId(),
21663      eventName: config.eventName,
21664      groupId: config.groupId,
21665      mvcPath: config.mvcPath || '/view.jsp',
21666      p_p_state: 'pop_up',
21667      portletResourceNamespace: config.portletResourceNamespace,
21668      resourceClassNameId: config.resourceClassNameId,
21669      scopeTitle: config.title,
21670      structureAvailableFields: config.structureAvailableFields,
21671      templateId: config.templateId
21672    };
21673
21674    if ('mode' in config) {
21675      params.mode = config.mode;
21676    }
21677
21678    if ('navigationStartsOn' in config) {
21679      params.navigationStartsOn = config.navigationStartsOn;
21680    }
21681
21682    if ('redirect' in config) {
21683      params.redirect = config.redirect;
21684    }
21685
21686    if ('refererPortletName' in config) {
21687      params.refererPortletName = config.refererPortletName;
21688    }
21689
21690    if ('refererWebDAVToken' in config) {
21691      params.refererWebDAVToken = config.refererWebDAVToken;
21692    }
21693
21694    if ('searchRestriction' in config) {
21695      params.searchRestriction = config.searchRestriction;
21696      params.searchRestrictionClassNameId = config.searchRestrictionClassNameId;
21697      params.searchRestrictionClassPK = config.searchRestrictionClassPK;
21698    }
21699
21700    if ('showAncestorScopes' in config) {
21701      params.showAncestorScopes = config.showAncestorScopes;
21702    }
21703
21704    if ('showBackURL' in config) {
21705      params.showBackURL = config.showBackURL;
21706    }
21707
21708    if ('showCacheableInput' in config) {
21709      params.showCacheableInput = config.showCacheableInput;
21710    }
21711
21712    if ('showHeader' in config) {
21713      params.showHeader = config.showHeader;
21714    }
21715
21716    if ('showManageTemplates' in config) {
21717      params.showManageTemplates = config.showManageTemplates;
21718    }
21719
21720    var url = Liferay.Util.PortletURL.createRenderURL(config.basePortletURL, params);
21721    config.uri = url.toString();
21722    var dialogConfig = config.dialog;
21723
21724    if (!dialogConfig) {
21725      dialogConfig = {};
21726      config.dialog = dialogConfig;
21727    }
21728
21729    var eventHandles = [];
21730
21731    if (callback) {
21732      eventHandles.push(Liferay.once(config.eventName, callback));
21733    }
21734
21735    var detachSelectionOnHideFn = function detachSelectionOnHideFn(event) {
21736      Liferay.fire(config.eventName);
21737
21738      if (!event.newVal) {
21739        new A.EventHandle(eventHandles).detach();
21740      }
21741    };
21742
21743    Util.openWindow(config, function (dialogWindow) {
21744      eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));
21745    });
21746  }, ['aui-base']);
21747  Liferay.provide(Util, 'openDocument', function (webDavUrl, onSuccess, onError) {
21748    if (A.UA.ie) {
21749      try {
21750        var executor = new A.config.win.ActiveXObject('SharePoint.OpenDocuments');
21751        executor.EditDocument(webDavUrl);
21752
21753        if (Lang.isFunction(onSuccess)) {
21754          onSuccess();
21755        }
21756      } catch (e) {
21757        if (Lang.isFunction(onError)) {
21758          onError(e);
21759        }
21760      }
21761    }
21762  }, ['aui-base']);
21763  Liferay.provide(Util, 'selectEntityHandler', function (containerSelector, selectEventName, disableButton) {
21764    var container = A.one(containerSelector);
21765
21766    if (!container) {
21767      return;
21768    }
21769
21770    var openingLiferay = Util.getOpener().Liferay;
21771    var selectorButtons = container.getDOM().querySelectorAll('.selector-button');
21772    container.delegate(EVENT_CLICK, function (event) {
21773      var currentTarget = event.currentTarget.getDOM();
21774
21775      if (currentTarget.disabled || currentTarget.dataset['preventSelection']) {
21776        return;
21777      }
21778
21779      var confirmSelection = currentTarget.dataset['confirmSelection'] === 'true';
21780
21781      if (!confirmSelection || confirm(currentTarget.dataset['confirmSelectionMessage'])) {
21782        if (disableButton) {
21783          selectorButtons.forEach(function (selectorButton) {
21784            selectorButton.disabled = false;
21785          });
21786          currentTarget.disabled = true;
21787        }
21788
21789        var result = Util.getAttributes(currentTarget, 'data-');
21790        openingLiferay.fire(selectEventName, result);
21791
21792        var _window = Util.getWindow();
21793
21794        if (_window) {
21795          _window.hide();
21796        }
21797      }
21798    }, '.selector-button');
21799    openingLiferay.on('entitySelectionRemoved', function () {
21800      selectorButtons.forEach(function (selectorButton) {
21801        selectorButton.disabled = false;
21802      });
21803    });
21804  }, ['aui-base']);
21805  Liferay.provide(Util, 'portletTitleEdit', function (options) {
21806    var obj = options.obj;
21807    A.Event.defineOutside('mouseup');
21808
21809    if (obj) {
21810      var title = obj.one('.portlet-title-text');
21811
21812      if (title && !title.hasClass('not-editable')) {
21813        title.addClass('portlet-title-editable');
21814        title.on(EVENT_CLICK, function (event) {
21815          var editable = Util._getEditableInstance(title);
21816
21817          var rendered = editable.get('rendered');
21818
21819          if (rendered) {
21820            editable.fire('stopEditing');
21821          }
21822
21823          editable.set('node', event.currentTarget);
21824
21825          if (rendered) {
21826            editable.syncUI();
21827          }
21828
21829          editable._startEditing(event);
21830
21831          if (!rendered) {
21832            var defaultIconsTpl = A.ToolbarRenderer.prototype.TEMPLATES.icon;
21833            A.ToolbarRenderer.prototype.TEMPLATES.icon = Liferay.Util.getLexiconIconTpl('{cssClass}');
21834
21835            editable._comboBox.icons.destroy();
21836
21837            editable._comboBox._renderIcons();
21838
21839            A.ToolbarRenderer.prototype.TEMPLATES.icon = defaultIconsTpl;
21840          }
21841        });
21842        title.setData('portletTitleEditOptions', options);
21843      }
21844    }
21845  }, ['aui-editable-deprecated', 'event-outside']);
21846  Liferay.provide(Util, 'editEntity', function (config, callback) {
21847    var dialog = Util.getWindow(config.id);
21848    var eventName = config.eventName || config.id;
21849    var eventHandles = [Liferay.on(eventName, callback)];
21850
21851    var detachSelectionOnHideFn = function detachSelectionOnHideFn(event) {
21852      if (!event.newVal) {
21853        new A.EventHandle(eventHandles).detach();
21854      }
21855    };
21856
21857    if (dialog) {
21858      eventHandles.push(dialog.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));
21859      dialog.show();
21860    } else {
21861      var destroyDialog = function destroyDialog(event) {
21862        var dialogId = config.id;
21863        var dialogWindow = Util.getWindow(dialogId);
21864
21865        if (dialogWindow && Util.getPortletId(dialogId) === event.portletId) {
21866          dialogWindow.destroy();
21867          Liferay.detach('destroyPortlet', destroyDialog);
21868        }
21869      };
21870
21871      var editURL = new Liferay.Util.PortletURL.createPortletURL(config.uri, A.merge({
21872        eventName: eventName
21873      }, config.urlParams));
21874      config.uri = editURL.toString();
21875      config.dialogIframe = A.merge({
21876        bodyCssClass: 'dialog-with-footer'
21877      }, config.dialogIframe || {});
21878      Util.openWindow(config, function (dialogWindow) {
21879        eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));
21880        Liferay.on('destroyPortlet', destroyDialog);
21881      });
21882    }
21883  }, ['aui-base', 'liferay-util-window']);
21884  Liferay.provide(Util, 'selectEntity', function (config, callback) {
21885    var dialog = Util.getWindow(config.id);
21886    var eventName = config.eventName || config.id;
21887    var eventHandles = [Liferay.on(eventName, callback)];
21888    var selectedData = config.selectedData;
21889
21890    if (selectedData) {
21891      config.dialog.destroyOnHide = true;
21892    }
21893
21894    var detachSelectionOnHideFn = function detachSelectionOnHideFn(event) {
21895      if (!event.newVal) {
21896        new A.EventHandle(eventHandles).detach();
21897      }
21898    };
21899
21900    var syncAssets = function syncAssets(event) {
21901      var currentWindow = event.currentTarget.node.get('contentWindow.document');
21902      var selectorButtons = currentWindow.all('.lfr-search-container-wrapper .selector-button');
21903      A.each(selectorButtons, function (item) {
21904        var assetEntryId = item.attr('data-entityid') || item.attr('data-entityname');
21905        var assetGroupId = item.attr('data-groupid');
21906
21907        if (assetGroupId) {
21908          assetEntryId = assetGroupId + '-' + assetEntryId;
21909        }
21910
21911        var disabled = selectedData && selectedData.includes(assetEntryId);
21912
21913        if (disabled) {
21914          item.attr('data-prevent-selection', true);
21915        } else {
21916          item.removeAttribute('data-prevent-selection');
21917        }
21918
21919        Util.toggleDisabled(item, disabled);
21920      });
21921    };
21922
21923    if (dialog) {
21924      eventHandles.push(dialog.after(['destroy', 'visibleChange'], detachSelectionOnHideFn));
21925      dialog.show();
21926    } else {
21927      var destroyDialog = function destroyDialog(event) {
21928        var dialogId = config.id;
21929        var dialogWindow = Util.getWindow(dialogId);
21930
21931        if (dialogWindow && Util.getPortletId(dialogId) === event.portletId) {
21932          dialogWindow.destroy();
21933          Liferay.detach('destroyPortlet', destroyDialog);
21934        }
21935      };
21936
21937      Util.openWindow(config, function (dialogWindow) {
21938        eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn), dialogWindow.iframe.after(['load'], syncAssets));
21939        Liferay.on('destroyPortlet', destroyDialog);
21940      });
21941    }
21942  }, ['aui-base', 'liferay-util-window']);
21943  Liferay.provide(Util, 'toggleControls', function (node) {
21944    var docBody = A.getBody();
21945    node = node || docBody;
21946    var trigger = node.one('.toggle-controls');
21947
21948    if (trigger) {
21949      var controlsVisible = Liferay._editControlsState === 'visible';
21950      var currentState = MAP_TOGGLE_STATE[controlsVisible];
21951      var icon = trigger.one('.lexicon-icon');
21952
21953      if (icon) {
21954        currentState.icon = icon;
21955      }
21956
21957      docBody.addClass(currentState.cssClass);
21958      Liferay.fire('toggleControls', {
21959        enabled: controlsVisible
21960      });
21961      trigger.on('tap', function () {
21962        controlsVisible = !controlsVisible;
21963        var prevState = currentState;
21964        currentState = MAP_TOGGLE_STATE[controlsVisible];
21965        docBody.toggleClass(prevState.cssClass);
21966        docBody.toggleClass(currentState.cssClass);
21967        var editControlsIconClass = currentState.iconCssClass;
21968        var editControlsState = currentState.state;
21969
21970        if (icon) {
21971          var newIcon = currentState.icon;
21972
21973          if (!newIcon) {
21974            newIcon = Util.getLexiconIcon(editControlsIconClass);
21975            newIcon = A.one(newIcon);
21976            currentState.icon = newIcon;
21977          }
21978
21979          icon.replace(newIcon);
21980          icon = newIcon;
21981        }
21982
21983        Liferay._editControlsState = editControlsState;
21984        Liferay.Util.Session.set('com.liferay.frontend.js.web_toggleControls', editControlsState);
21985        Liferay.fire('toggleControls', {
21986          enabled: controlsVisible,
21987          src: 'ui'
21988        });
21989      });
21990    }
21991  }, ['event-tap']);
21992  Liferay.provide(Util, '_openWindowProvider', function (config, callback) {
21993    var dialog = Window.getWindow(config);
21994
21995    if (Lang.isFunction(callback)) {
21996      callback(dialog);
21997    }
21998  }, ['liferay-util-window']);
21999  Util.Window = Window;
22000  Liferay.Util = Util;
22001  Liferay.STATUS_CODE = {
22002    BAD_REQUEST: 400,
22003    INTERNAL_SERVER_ERROR: 500,
22004    OK: 200,
22005    SC_DUPLICATE_FILE_EXCEPTION: 490,
22006    SC_FILE_ANTIVIRUS_EXCEPTION: 494,
22007    SC_FILE_CUSTOM_EXCEPTION: 499,
22008    SC_FILE_EXTENSION_EXCEPTION: 491,
22009    SC_FILE_NAME_EXCEPTION: 492,
22010    SC_FILE_SIZE_EXCEPTION: 493,
22011    SC_UPLOAD_REQUEST_SIZE_EXCEPTION: 495
22012  }; // 0-200: Theme Developer
22013  // 200-400: Portlet Developer
22014  // 400+: Liferay
22015
22016  Liferay.zIndex = {
22017    ALERT: 430,
22018    DOCK: 10,
22019    DOCK_PARENT: 20,
22020    DRAG_ITEM: 460,
22021    DROP_AREA: 440,
22022    DROP_POSITION: 450,
22023    MENU: 5000,
22024    OVERLAY: 1000,
22025    POPOVER: 1600,
22026    TOOLTIP: 10000,
22027    WINDOW: 1200
22028  };
22029})(AUI(), Liferay);
22030//# sourceMappingURL=util.js.map
22031YUI.add('aui-base-html5-shiv', function (A, NAME) {
22032
22033A.HTML5_ELEMENTS = [
22034    'abbr',
22035    'article',
22036    'aside',
22037    'audio',
22038    'canvas',
22039    'command',
22040    'datalist',
22041    'details',
22042    'figure',
22043    'figcaption',
22044    'footer',
22045    'header',
22046    'hgroup',
22047    'keygen',
22048    'mark',
22049    'meter',
22050    'nav',
22051    'output',
22052    'progress',
22053    'section',
22054    'source',
22055    'summary',
22056    'time',
22057    'video'
22058];
22059
22060A.html5shiv = function(frag) {
22061    var DOC = frag || A.config.doc;
22062
22063    if (A.UA.ie && DOC && DOC.createElement) {
22064        var elements = A.HTML5_ELEMENTS,
22065            length = elements.length;
22066
22067        while (length--) {
22068            DOC.createElement(elements[length]);
22069        }
22070    }
22071
22072    return frag;
22073};
22074
22075
22076}, '3.1.0-deprecated.77');
22077
22078YUI.add('arraylist-add', function (Y, NAME) {
22079
22080/**
22081 * Collection utilities beyond what is provided in the YUI core
22082 * @module collection
22083 * @submodule arraylist-add
22084 * @deprecated Use ModelList or a custom ArrayList subclass
22085 */
22086
22087/*
22088 * Adds methods add and remove to Y.ArrayList
22089 */
22090Y.mix(Y.ArrayList.prototype, {
22091
22092    /**
22093     * Add a single item to the ArrayList.  Does not prevent duplicates.
22094     *
22095     * @method add
22096     * @param { mixed } item Item presumably of the same type as others in the
22097     *                       ArrayList.
22098     * @param {Number} index (Optional.)  Number representing the position at
22099     * which the item should be inserted.
22100     * @return {ArrayList} the instance.
22101     * @for ArrayList
22102     * @deprecated Use ModelList or a custom ArrayList subclass
22103     * @chainable
22104     */
22105    add: function(item, index) {
22106        var items = this._items;
22107
22108        if (Y.Lang.isNumber(index)) {
22109            items.splice(index, 0, item);
22110        }
22111        else {
22112            items.push(item);
22113        }
22114
22115        return this;
22116    },
22117
22118    /**
22119     * Removes first or all occurrences of an item to the ArrayList.  If a
22120     * comparator is not provided, uses itemsAreEqual method to determine
22121     * matches.
22122     *
22123     * @method remove
22124     * @param { mixed } needle Item to find and remove from the list.
22125     * @param { Boolean } all If true, remove all occurrences.
22126     * @param { Function } comparator optional a/b function to test equivalence.
22127     * @return {ArrayList} the instance.
22128     * @for ArrayList
22129     * @deprecated Use ModelList or a custom ArrayList subclass
22130     * @chainable
22131     */
22132    remove: function(needle, all, comparator) {
22133        comparator = comparator || this.itemsAreEqual;
22134
22135        for (var i = this._items.length - 1; i >= 0; --i) {
22136            if (comparator.call(this, needle, this.item(i))) {
22137                this._items.splice(i, 1);
22138                if (!all) {
22139                    break;
22140                }
22141            }
22142        }
22143
22144        return this;
22145    },
22146
22147    /**
22148     * Default comparator for items stored in this list.  Used by remove().
22149     *
22150     * @method itemsAreEqual
22151     * @param { mixed } a item to test equivalence with.
22152     * @param { mixed } b other item to test equivalance.
22153     * @return { Boolean } true if items are deemed equivalent.
22154     * @for ArrayList
22155     * @deprecated Use ModelList or a custom ArrayList subclass
22156     */
22157    itemsAreEqual: function(a, b) {
22158        return a === b;
22159    }
22160
22161});
22162
22163
22164}, 'patched-v3.18.1', {"requires": ["arraylist"]});
22165
22166YUI.add('arraylist-filter', function (Y, NAME) {
22167
22168/**
22169 * Collection utilities beyond what is provided in the YUI core
22170 * @module collection
22171 * @submodule arraylist-filter
22172 * @deprecated Use ModelList or a custom subclass implementation
22173 */
22174
22175/*
22176 * Adds filter method to ArrayList prototype
22177 */
22178Y.mix(Y.ArrayList.prototype, {
22179
22180    /**
22181     * <p>Create a new ArrayList (or augmenting class instance) from a subset
22182     * of items as determined by the boolean function passed as the
22183     * argument.  The original ArrayList is unchanged.</p>
22184     *
22185     * <p>The validator signature is <code>validator( item )</code>.</p>
22186     *
22187     * @method filter
22188     * @param { Function } validator Boolean function to determine in or out.
22189     * @return { ArrayList } New instance based on who passed the validator.
22190     * @for ArrayList
22191     * @deprecated Use ModelList or a custom subclass implementation
22192     */
22193    filter: function(validator) {
22194        var items = [];
22195
22196        Y.Array.each(this._items, function(item, i) {
22197            item = this.item(i);
22198
22199            if (validator(item)) {
22200                items.push(item);
22201            }
22202        }, this);
22203
22204        return new this.constructor(items);
22205    }
22206
22207});
22208
22209
22210}, 'patched-v3.18.1', {"requires": ["arraylist"]});
22211
22212YUI.add('arraylist', function (Y, NAME) {
22213
22214/**
22215 * Collection utilities beyond what is provided in the YUI core
22216 * @module collection
22217 * @submodule arraylist
22218 */
22219
22220var YArray      = Y.Array,
22221    YArray_each = YArray.each,
22222    ArrayListProto;
22223
22224/**
22225 * Generic ArrayList class for managing lists of items and iterating operations
22226 * over them.  The targeted use for this class is for augmentation onto a
22227 * class that is responsible for managing multiple instances of another class
22228 * (e.g. NodeList for Nodes).  The recommended use is to augment your class with
22229 * ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
22230 * items on the list's API.
22231 *
22232 * The default implementation creates immutable lists, but mutability can be
22233 * provided via the arraylist-add submodule or by implementing mutation methods
22234 * directly on the augmented class's prototype.
22235 *
22236 * @class ArrayList
22237 * @constructor
22238 * @param items { Array } array of items this list will be responsible for
22239 */
22240function ArrayList( items ) {
22241    if ( items !== undefined ) {
22242        this._items = Y.Lang.isArray( items ) ? items : YArray( items );
22243    } else {
22244        // ||= to support lazy initialization from augment
22245        this._items = this._items || [];
22246    }
22247}
22248
22249ArrayListProto = {
22250    /**
22251     * Get an item by index from the list.  Override this method if managing a
22252     * list of objects that have a different public representation (e.g. Node
22253     * instances vs DOM nodes).  The iteration methods that accept a user
22254     * function will use this method for access list items for operation.
22255     *
22256     * @method item
22257     * @param i { Integer } index to fetch
22258     * @return { mixed } the item at the requested index
22259     */
22260    item: function ( i ) {
22261        return this._items[i];
22262    },
22263
22264    /**
22265     * <p>Execute a function on each item of the list, optionally providing a
22266     * custom execution context.  Default context is the item.</p>
22267     *
22268     * <p>The callback signature is <code>callback( item, index )</code>.</p>
22269     *
22270     * @method each
22271     * @param fn { Function } the function to execute
22272     * @param context { mixed } optional override 'this' in the function
22273     * @return { ArrayList } this instance
22274     * @chainable
22275     */
22276    each: function ( fn, context ) {
22277        YArray_each( this._items, function ( item, i ) {
22278            item = this.item( i );
22279
22280            fn.call( context || item, item, i, this );
22281        }, this);
22282
22283        return this;
22284    },
22285
22286    /**
22287     * <p>Execute a function on each item of the list, optionally providing a
22288     * custom execution context.  Default context is the item.</p>
22289     *
22290     * <p>The callback signature is <code>callback( item, index )</code>.</p>
22291     *
22292     * <p>Unlike <code>each</code>, if the callback returns true, the
22293     * iteration will stop.</p>
22294     *
22295     * @method some
22296     * @param fn { Function } the function to execute
22297     * @param context { mixed } optional override 'this' in the function
22298     * @return { Boolean } True if the function returned true on an item
22299     */
22300    some: function ( fn, context ) {
22301        return YArray.some( this._items, function ( item, i ) {
22302            item = this.item( i );
22303
22304            return fn.call( context || item, item, i, this );
22305        }, this);
22306    },
22307
22308    /**
22309     * Finds the first index of the needle in the managed array of items.
22310     *
22311     * @method indexOf
22312     * @param needle { mixed } The item to search for
22313     * @return { Integer } Array index if found.  Otherwise -1
22314     */
22315    indexOf: function ( needle ) {
22316        return YArray.indexOf( this._items, needle );
22317    },
22318
22319    /**
22320     * How many items are in this list?
22321     *
22322     * @method size
22323     * @return { Integer } Number of items in the list
22324     */
22325    size: function () {
22326        return this._items.length;
22327    },
22328
22329    /**
22330     * Is this instance managing any items?
22331     *
22332     * @method isEmpty
22333     * @return { Boolean } true if 1 or more items are being managed
22334     */
22335    isEmpty: function () {
22336        return !this.size();
22337    },
22338
22339    /**
22340     * Provides an array-like representation for JSON.stringify.
22341     *
22342     * @method toJSON
22343     * @return { Array } an array representation of the ArrayList
22344     */
22345    toJSON: function () {
22346        return this._items;
22347    }
22348};
22349// Default implementation does not distinguish between public and private
22350// item getter
22351/**
22352 * Protected method for optimizations that may be appropriate for API
22353 * mirroring. Similar in functionality to <code>item</code>, but is used by
22354 * methods added with <code>ArrayList.addMethod()</code>.
22355 *
22356 * @method _item
22357 * @protected
22358 * @param i { Integer } Index of item to fetch
22359 * @return { mixed } The item appropriate for pass through API methods
22360 */
22361ArrayListProto._item = ArrayListProto.item;
22362
22363// Mixed onto existing proto to preserve constructor NOT being an own property.
22364// This has bitten me when composing classes by enumerating, copying prototypes.
22365Y.mix(ArrayList.prototype, ArrayListProto);
22366
22367Y.mix( ArrayList, {
22368
22369    /**
22370     * <p>Adds a pass through method to dest (typically the prototype of a list
22371     * class) that calls the named method on each item in the list with
22372     * whatever parameters are passed in.  Allows for API indirection via list
22373     * instances.</p>
22374     *
22375     * <p>Accepts a single string name or an array of string names.</p>
22376     *
22377     * <pre><code>list.each( function ( item ) {
22378     *     item.methodName( 1, 2, 3 );
22379     * } );
22380     * // becomes
22381     * list.methodName( 1, 2, 3 );</code></pre>
22382     *
22383     * <p>Additionally, the pass through methods use the item retrieved by the
22384     * <code>_item</code> method in case there is any special behavior that is
22385     * appropriate for API mirroring.</p>
22386     *
22387     * <p>If the iterated method returns a value, the return value from the
22388     * added method will be an array of values with each value being at the
22389     * corresponding index for that item.  If the iterated method does not
22390     * return a value, the added method will be chainable.
22391     *
22392     * @method addMethod
22393     * @static
22394     * @param dest {Object} Object or prototype to receive the iterator method
22395     * @param name {String|String[]} Name of method of methods to create
22396     */
22397    addMethod: function ( dest, names ) {
22398
22399        names = YArray( names );
22400
22401        YArray_each( names, function ( name ) {
22402            dest[ name ] = function () {
22403                var args = YArray( arguments, 0, true ),
22404                    ret  = [];
22405
22406                YArray_each( this._items, function ( item, i ) {
22407                    item = this._item( i );
22408
22409                    var result = item[ name ].apply( item, args );
22410
22411                    if ( result !== undefined && result !== item ) {
22412                        ret[i] = result;
22413                    }
22414                }, this);
22415
22416                return ret.length ? ret : this;
22417            };
22418        } );
22419    }
22420} );
22421
22422Y.ArrayList = ArrayList;
22423
22424
22425}, 'patched-v3.18.1', {"requires": ["yui-base"]});
22426
22427YUI.add('array-extras', function (Y, NAME) {
22428
22429/**
22430Adds additional utility methods to the `Y.Array` class.
22431
22432@module collection
22433@submodule array-extras
22434**/
22435
22436var A          = Y.Array,
22437    L          = Y.Lang,
22438    ArrayProto = Array.prototype;
22439
22440/**
22441Returns the index of the last item in the array that contains the specified
22442value, or `-1` if the value isn't found.
22443
22444@method lastIndexOf
22445@param {Array} a Array to search in.
22446@param {Any} val Value to search for.
22447@param {Number} [fromIndex] Index at which to start searching backwards.
22448  Defaults to the array's length - 1. If negative, it will be taken as an offset
22449  from the end of the array. If the calculated index is less than 0, the array
22450  will not be searched and `-1` will be returned.
22451@return {Number} Index of the item that contains the value, or `-1` if not
22452  found.
22453@static
22454@for Array
22455**/
22456A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ?
22457    function(a, val, fromIndex) {
22458        // An undefined fromIndex is still considered a value by some (all?)
22459        // native implementations, so we can't pass it unless it's actually
22460        // specified.
22461        return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) :
22462                a.lastIndexOf(val);
22463    } :
22464    function(a, val, fromIndex) {
22465        var len = a.length,
22466            i   = len - 1;
22467
22468        if (fromIndex || fromIndex === 0) {
22469            i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len);
22470        }
22471
22472        if (i > -1 && len > 0) {
22473            for (; i > -1; --i) {
22474                if (i in a && a[i] === val) {
22475                    return i;
22476                }
22477            }
22478        }
22479
22480        return -1;
22481    };
22482
22483/**
22484Returns a copy of the input array with duplicate items removed.
22485
22486Note: If the input array only contains strings, the `Y.Array.dedupe()` method is
22487a much faster alternative.
22488
22489@method unique
22490@param {Array} array Array to dedupe.
22491@param {Function} [testFn] Custom function to use to test the equality of two
22492    values. A truthy return value indicates that the values are equal. A falsy
22493    return value indicates that the values are not equal.
22494
22495    @param {Any} testFn.a First value to compare.
22496    @param {Any} testFn.b Second value to compare.
22497    @param {Number} testFn.index Index of the current item in the original
22498        array.
22499    @param {Array} testFn.array The original array.
22500    @return {Boolean} _true_ if the items are equal, _false_ otherwise.
22501
22502@return {Array} Copy of the input array with duplicate items removed.
22503@static
22504**/
22505A.unique = function (array, testFn) {
22506    var i       = 0,
22507        len     = array.length,
22508        results = [],
22509        j, result, resultLen, value;
22510
22511    // Note the label here. It's used to jump out of the inner loop when a value
22512    // is not unique.
22513    outerLoop: for (; i < len; i++) {
22514        value = array[i];
22515
22516        // For each value in the input array, iterate through the result array
22517        // and check for uniqueness against each result value.
22518        for (j = 0, resultLen = results.length; j < resultLen; j++) {
22519            result = results[j];
22520
22521            // If the test function returns true or there's no test function and
22522            // the value equals the current result item, stop iterating over the
22523            // results and continue to the next value in the input array.
22524            if (testFn) {
22525                if (testFn.call(array, value, result, i, array)) {
22526                    continue outerLoop;
22527                }
22528            } else if (value === result) {
22529                continue outerLoop;
22530            }
22531        }
22532
22533        // If we get this far, that means the current value is not already in
22534        // the result array, so add it.
22535        results.push(value);
22536    }
22537
22538    return results;
22539};
22540
22541/**
22542Executes the supplied function on each item in the array. Returns a new array
22543containing the items for which the supplied function returned a truthy value.
22544
22545@method filter
22546@param {Array} a Array to filter.
22547@param {Function} f Function to execute on each item.
22548@param {Object} [o] Optional context object.
22549@return {Array} Array of items for which the supplied function returned a
22550  truthy value (empty if it never returned a truthy value).
22551@static
22552*/
22553A.filter = L._isNative(ArrayProto.filter) ?
22554    function(a, f, o) {
22555        return ArrayProto.filter.call(a, f, o);
22556    } :
22557    function(a, f, o) {
22558        var i       = 0,
22559            len     = a.length,
22560            results = [],
22561            item;
22562
22563        for (; i < len; ++i) {
22564            if (i in a) {
22565                item = a[i];
22566
22567                if (f.call(o, item, i, a)) {
22568                    results.push(item);
22569                }
22570            }
22571        }
22572
22573        return results;
22574    };
22575
22576/**
22577The inverse of `Array.filter()`. Executes the supplied function on each item.
22578Returns a new array containing the items for which the supplied function
22579returned `false`.
22580
22581@method reject
22582@param {Array} a the array to iterate.
22583@param {Function} f the function to execute on each item.
22584@param {object} [o] Optional context object.
22585@return {Array} The items for which the supplied function returned `false`.
22586@static
22587*/
22588A.reject = function(a, f, o) {
22589    return A.filter(a, function(item, i, a) {
22590        return !f.call(o, item, i, a);
22591    });
22592};
22593
22594/**
22595Executes the supplied function on each item in the array. Iteration stops if the
22596supplied function does not return a truthy value.
22597
22598@method every
22599@param {Array} a the array to iterate.
22600@param {Function} f the function to execute on each item.
22601@param {Object} [o] Optional context object.
22602@return {Boolean} `true` if every item in the array returns `true` from the
22603  supplied function, `false` otherwise.
22604@static
22605*/
22606A.every = L._isNative(ArrayProto.every) ?
22607    function(a, f, o) {
22608        return ArrayProto.every.call(a, f, o);
22609    } :
22610    function(a, f, o) {
22611        for (var i = 0, l = a.length; i < l; ++i) {
22612            if (i in a && !f.call(o, a[i], i, a)) {
22613                return false;
22614            }
22615        }
22616
22617        return true;
22618    };
22619
22620/**
22621Executes the supplied function on each item in the array and returns a new array
22622containing all the values returned by the supplied function.
22623
22624@example
22625
22626    // Convert an array of numbers into an array of strings.
22627    Y.Array.map([1, 2, 3, 4], function (item) {
22628      return '' + item;
22629    });
22630    // => ['1', '2', '3', '4']
22631
22632@method map
22633@param {Array} a the array to iterate.
22634@param {Function} f the function to execute on each item.
22635@param {object} [o] Optional context object.
22636@return {Array} A new array containing the return value of the supplied function
22637  for each item in the original array.
22638@static
22639*/
22640A.map = L._isNative(ArrayProto.map) ?
22641    function(a, f, o) {
22642        return ArrayProto.map.call(a, f, o);
22643    } :
22644    function(a, f, o) {
22645        var i       = 0,
22646            len     = a.length,
22647            results = ArrayProto.concat.call(a);
22648
22649        for (; i < len; ++i) {
22650            if (i in a) {
22651                results[i] = f.call(o, a[i], i, a);
22652            }
22653        }
22654
22655        return results;
22656    };
22657
22658
22659/**
22660Executes the supplied function on each item in the array, "folding" the array
22661into a single value.
22662
22663@method reduce
22664@param {Array} a Array to iterate.
22665@param {Any} init Initial value to start with.
22666@param {Function} f Function to execute on each item. This function should
22667  update and return the value of the computation. It will receive the following
22668  arguments:
22669    @param {Any} f.previousValue Value returned from the previous iteration,
22670      or the initial value if this is the first iteration.
22671    @param {Any} f.currentValue Value of the current item being iterated.
22672    @param {Number} f.index Index of the current item.
22673    @param {Array} f.array Array being iterated.
22674@param {Object} [o] Optional context object.
22675@return {Any} Final result from iteratively applying the given function to each
22676  element in the array.
22677@static
22678*/
22679A.reduce = L._isNative(ArrayProto.reduce) ?
22680    function(a, init, f, o) {
22681        // ES5 Array.reduce doesn't support a thisObject, so we need to
22682        // implement it manually.
22683        return ArrayProto.reduce.call(a, function(init, item, i, a) {
22684            return f.call(o, init, item, i, a);
22685        }, init);
22686    } :
22687    function(a, init, f, o) {
22688        var i      = 0,
22689            len    = a.length,
22690            result = init;
22691
22692        for (; i < len; ++i) {
22693            if (i in a) {
22694                result = f.call(o, result, a[i], i, a);
22695            }
22696        }
22697
22698        return result;
22699    };
22700
22701/**
22702Executes the supplied function on each item in the array, searching for the
22703first item that matches the supplied function.
22704
22705@method find
22706@param {Array} a the array to search.
22707@param {Function} f the function to execute on each item. Iteration is stopped
22708  as soon as this function returns `true`.
22709@param {Object} [o] Optional context object.
22710@return {Object} the first item that the supplied function returns `true` for,
22711  or `null` if it never returns `true`.
22712@static
22713*/
22714A.find = function(a, f, o) {
22715    for (var i = 0, l = a.length; i < l; i++) {
22716        if (i in a && f.call(o, a[i], i, a)) {
22717            return a[i];
22718        }
22719    }
22720    return null;
22721};
22722
22723/**
22724Iterates over an array, returning a new array of all the elements that match the
22725supplied regular expression.
22726
22727@method grep
22728@param {Array} a Array to iterate over.
22729@param {RegExp} pattern Regular expression to test against each item.
22730@return {Array} All the items in the array that produce a match against the
22731  supplied regular expression. If no items match, an empty array is returned.
22732@static
22733*/
22734A.grep = function(a, pattern) {
22735    return A.filter(a, function(item, index) {
22736        return pattern.test(item);
22737    });
22738};
22739
22740/**
22741Partitions an array into two new arrays, one with the items for which the
22742supplied function returns `true`, and one with the items for which the function
22743returns `false`.
22744
22745@method partition
22746@param {Array} a Array to iterate over.
22747@param {Function} f Function to execute for each item in the array. It will
22748  receive the following arguments:
22749    @param {Any} f.item Current item.
22750    @param {Number} f.index Index of the current item.
22751    @param {Array} f.array The array being iterated.
22752@param {Object} [o] Optional execution context.
22753@return {Object} An object with two properties: `matches` and `rejects`. Each is
22754  an array containing the items that were selected or rejected by the test
22755  function (or an empty array if none).
22756@static
22757*/
22758A.partition = function(a, f, o) {
22759    var results = {
22760        matches: [],
22761        rejects: []
22762    };
22763
22764    A.each(a, function(item, index) {
22765        var set = f.call(o, item, index, a) ? results.matches : results.rejects;
22766        set.push(item);
22767    });
22768
22769    return results;
22770};
22771
22772/**
22773Creates an array of arrays by pairing the corresponding elements of two arrays
22774together into a new array.
22775
22776@method zip
22777@param {Array} a Array to iterate over.
22778@param {Array} a2 Another array whose values will be paired with values of the
22779  first array.
22780@return {Array} An array of arrays formed by pairing each element of the first
22781  array with an item in the second array having the corresponding index.
22782@static
22783*/
22784A.zip = function(a, a2) {
22785    var results = [];
22786    A.each(a, function(item, index) {
22787        results.push([item, a2[index]]);
22788    });
22789    return results;
22790};
22791
22792/**
22793Flattens an array of nested arrays at any abitrary depth into a single, flat
22794array.
22795
22796@method flatten
22797@param {Array} a Array with nested arrays to flatten.
22798@return {Array} An array whose nested arrays have been flattened.
22799@static
22800@since 3.7.0
22801**/
22802A.flatten = function(a) {
22803    var result = [],
22804        i, len, val;
22805
22806    // Always return an array.
22807    if (!a) {
22808        return result;
22809    }
22810
22811    for (i = 0, len = a.length; i < len; ++i) {
22812        val = a[i];
22813
22814        if (L.isArray(val)) {
22815            // Recusively flattens any nested arrays.
22816            result.push.apply(result, A.flatten(val));
22817        } else {
22818            result.push(val);
22819        }
22820    }
22821
22822    return result;
22823};
22824
22825
22826}, 'patched-v3.18.1', {"requires": ["yui-base"]});
22827
22828YUI.add('array-invoke', function (Y, NAME) {
22829
22830/**
22831@module collection
22832@submodule array-invoke
22833*/
22834
22835/**
22836Executes a named method on each item in an array of objects. Items in the array
22837that do not have a function by that name will be skipped.
22838
22839@example
22840
22841    Y.Array.invoke(arrayOfDrags, 'plug', Y.Plugin.DDProxy);
22842
22843@method invoke
22844@param {Array} items Array of objects supporting the named method.
22845@param {String} name the name of the method to execute on each item.
22846@param {Any} [args*] Any number of additional args are passed as parameters to
22847  the execution of the named method.
22848@return {Array} All return values, indexed according to the item index.
22849@static
22850@for Array
22851**/
22852Y.Array.invoke = function(items, name) {
22853    var args = Y.Array(arguments, 2, true),
22854        isFunction = Y.Lang.isFunction,
22855        ret = [];
22856
22857    Y.Array.each(Y.Array(items), function(item, i) {
22858        if (item && isFunction(item[name])) {
22859            ret[i] = item[name].apply(item, args);
22860        }
22861    });
22862
22863    return ret;
22864};
22865
22866
22867}, 'patched-v3.18.1', {"requires": ["yui-base"]});
22868
22869YUI.add('base-base', function (Y, NAME) {
22870
22871    /**
22872     * The base module provides the Base class, which objects requiring attribute and custom event support can extend.
22873     * The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides
22874     * plugin support and also provides the BaseCore.build method which provides a way to build custom classes using extensions.
22875     *
22876     * @module base
22877     */
22878
22879    /**
22880     * The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
22881     * and without the extension support provided by BaseCore.build.
22882     *
22883     * @module base
22884     * @submodule base-base
22885     */
22886
22887    var AttributeCore   = Y.AttributeCore,
22888        AttributeExtras = Y.AttributeExtras,
22889        BaseCore        = Y.BaseCore,
22890        BaseObservable  = Y.BaseObservable;
22891
22892    /**
22893     * <p>
22894     * A base class which objects requiring attributes and custom event support can
22895     * extend. Base also handles the chaining of initializer and destructor methods across
22896     * the hierarchy as part of object construction and destruction. Additionally, attributes configured
22897     * through the static <a href="#property_ATTRS">ATTRS</a> property for each class
22898     * in the hierarchy will be initialized by Base.
22899     * </p>
22900     *
22901     * <p>
22902     * **NOTE:** Prior to version 3.11.0, ATTRS would get added a class at a time. That is,
22903     * Base would loop through each class in the hierarchy, and add the class' ATTRS, and
22904     * then call it's initializer, and move on to the subclass' ATTRS and initializer. As of
22905     * 3.11.0, ATTRS from all classes in the hierarchy are added in one `addAttrs` call before
22906     * any initializers are called. This fixes subtle edge-case issues with subclass ATTRS overriding
22907     * superclass `setter`, `getter` or `valueFn` definitions and being unable to get/set attributes
22908     * defined by the subclass. This order of operation change may impact `setter`, `getter` or `valueFn`
22909     * code which expects a superclass' initializer to have run. This is expected to be rare, but to supp
22909ort
22910     * it, Base supports a `_preAddAttrs()`, method hook (same signature as `addAttrs`). Components can
22911     * implement this method on their prototype for edge cases which do require finer control over
22912     * the order in which attributes are added (see widget-htmlparser).
22913     * </p>
22914     *
22915     * <p>
22916     * The static <a href="#property_NAME">NAME</a> property of each class extending
22917     * from Base will be used as the identifier for the class, and is used by Base to prefix
22918     * all events fired by instances of that class.
22919     * </p>
22920     *
22921     * @class Base
22922     * @constructor
22923     * @uses BaseCore
22924     * @uses BaseObservable
22925     * @uses AttributeCore
22926     * @uses AttributeObservable
22927     * @uses AttributeExtras
22928     * @uses EventTarget
22929     *
22930     * @param {Object} config Object with configuration property name/value pairs. The object can be
22931     * used to provide default values for the objects published attributes.
22932     *
22933     * <p>
22934     * The config object can also contain the following non-attribute properties, providing a convenient
22935     * way to configure events listeners and plugins for the instance, as part of the constructor call:
22936     * </p>
22937     *
22938     * <dl>
22939     *   <dt>on</dt>
22940     *   <dd>An event name to listener function map, to register event listeners for the "on" moment of the event.
22941     *       A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd>
22942     *   <dt>after</dt>
22943     *   <dd>An event name to listener function map, to register event listeners for the "after" moment of the event.
22944     *       A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd>
22945     *   <dt>bubbleTargets</dt>
22946     *   <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance.
22947     *       A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd>
22948     *   <dt>plugins</dt>
22949     *   <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details).
22950     *       A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd>
22951     * </dl>
22952     */
22953    function Base() {
22954        BaseCore.apply(this, arguments);
22955        BaseObservable.apply(this, arguments);
22956        AttributeExtras.apply(this, arguments);
22957    }
22958
22959    /**
22960     * The list of properties which can be configured for
22961     * each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
22962     *
22963     * @property _ATTR_CFG
22964     * @type Array
22965     * @static
22966     * @private
22967     */
22968    Base._ATTR_CFG = BaseCore._ATTR_CFG.concat(BaseObservable._ATTR_CFG);
22969
22970    /**
22971     * The array of non-attribute configuration properties supported by this class.
22972     *
22973     * `Base` supports "on", "after", "plugins" and "bubbleTargets" properties,
22974     * which are not set up as attributes.
22975     *
22976     * This property is primarily required so that when
22977     * <a href="#property__allowAdHocAttrs">`_allowAdHocAttrs`</a> is enabled by
22978     * a class, non-attribute configurations don't get added as ad-hoc attributes.
22979     *
22980     * @property _NON_ATTRS_CFG
22981     * @type Array
22982     * @static
22983     * @private
22984     */
22985    Base._NON_ATTRS_CFG = BaseCore._NON_ATTRS_CFG.concat(BaseObservable._NON_ATTRS_CFG);
22986
22987    /**
22988     * <p>
22989     * The string to be used to identify instances of
22990     * this class, for example in prefixing events.
22991     * </p>
22992     * <p>
22993     * Classes extending Base, should define their own
22994     * static NAME property, which should be camelCase by
22995     * convention (e.g. MyClass.NAME = "myClass";).
22996     * </p>
22997     * @property NAME
22998     * @type String
22999     * @static
23000     */
23001    Base.NAME = 'base';
23002
23003    /**
23004     * The default set of attributes which will be available for instances of this class, and
23005     * their configuration. In addition to the configuration properties listed by
23006     * Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
23007     * can also be configured with a "cloneDefaultValue" property, which defines how the statically
23008     * defined value field should be protected ("shallow", "deep" and false are supported values).
23009     *
23010     * By default if the value is an object literal or an array it will be "shallow" cloned, to
23011     * protect the default value.
23012     *
23013     * @property ATTRS
23014     * @type Object
23015     * @static
23016     */
23017    Base.ATTRS = AttributeCore.protectAttrs(BaseCore.ATTRS);
23018
23019    /**
23020    Provides a way to safely modify a `Y.Base` subclass' static `ATTRS` after
23021    the class has been defined or created.
23022
23023    Base-based classes cache information about the class hierarchy in order to
23024    efficiently create instances. This cache includes includes the aggregated
23025    `ATTRS` configs. If the static `ATTRS` configs need to be modified after the
23026    class has been defined or create, then use this method which will make sure
23027    to clear any cached data before making any modifications.
23028
23029    @method modifyAttrs
23030    @param {Function} [ctor] The constructor function whose `ATTRS` should be
23031        modified. If a `ctor` function is not specified, then `this` is assumed
23032        to be the constructor which hosts the `ATTRS`.
23033    @param {Object} configs The collection of `ATTRS` configs to mix with the
23034        existing attribute configurations.
23035    @static
23036    @since 3.10.0
23037    **/
23038    Base.modifyAttrs = BaseCore.modifyAttrs;
23039
23040    Y.mix(Base, BaseCore, false, null, 1);
23041    Y.mix(Base, AttributeExtras, false, null, 1);
23042
23043    // Needs to be `true`, to overwrite methods from `BaseCore`.
23044    Y.mix(Base, BaseObservable, true, null, 1);
23045
23046    // Fix constructor
23047    Base.prototype.constructor = Base;
23048
23049    Y.Base = Base;
23050
23051
23052}, 'patched-v3.18.1', {"requires": ["attribute-base", "base-core", "base-observable"]});
23053
23054YUI.add('base-pluginhost', function (Y, NAME) {
23055
23056    /**
23057     * The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
23058     * Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
23059     *
23060     * @module base
23061     * @submodule base-pluginhost
23062     * @for Base
23063     */
23064
23065    var Base = Y.Base,
23066        PluginHost = Y.Plugin.Host;
23067
23068    Y.mix(Base, PluginHost, false, null, 1);
23069
23070    /**
23071     * Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
23072     * method for argument and return value details.
23073     *
23074     * @method plug
23075     * @static
23076     */
23077    Base.plug = PluginHost.plug;
23078
23079    /**
23080     * Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
23081     * aliased method for argument and return value details.
23082     *
23083     * @method unplug
23084     * @static
23085     */
23086    Base.unplug = PluginHost.unplug;
23087
23088
23089}, 'patched-v3.18.1', {"requires": ["base-base", "pluginhost"]});
23090
23091YUI.add('classnamemanager', function (Y, NAME) {
23092
23093/**
23094* Contains a singleton (ClassNameManager) that enables easy creation and caching of
23095* prefixed class names.
23096* @module classnamemanager
23097*/
23098
23099/**
23100 * A singleton class providing:
23101 *
23102 * <ul>
23103 *    <li>Easy creation of prefixed class names</li>
23104 *    <li>Caching of previously created class names for improved performance.</li>
23105 * </ul>
23106 *
23107 * @class ClassNameManager
23108 * @static
23109 */
23110
23111// String constants
23112var CLASS_NAME_PREFIX = 'classNamePrefix',
23113	CLASS_NAME_DELIMITER = 'classNameDelimiter',
23114    CONFIG = Y.config;
23115
23116// Global config
23117
23118/**
23119 * Configuration property indicating the prefix for all CSS class names in this YUI instance.
23120 *
23121 * @property classNamePrefix
23122 * @type {String}
23123 * @default "yui"
23124 * @static
23125 */
23126CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui3';
23127
23128/**
23129 * Configuration property indicating the delimiter used to compose all CSS class names in
23130 * this YUI instance.
23131 *
23132 * @property classNameDelimiter
23133 * @type {String}
23134 * @default "-"
23135 * @static
23136 */
23137CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-';
23138
23139Y.ClassNameManager = function () {
23140
23141	var sPrefix    = CONFIG[CLASS_NAME_PREFIX],
23142		sDelimiter = CONFIG[CLASS_NAME_DELIMITER];
23143
23144	return {
23145
23146		/**
23147		 * Returns a class name prefixed with the value of the
23148		 * <code>Y.config.classNamePrefix</code> attribute + the provided strings.
23149		 * Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the
23150		 * provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar
23151		 *
23152		 * @method getClassName
23153		 * @param {String} [classnameSection*] one or more classname sections to be joined
23154		 * @param {Boolean} skipPrefix If set to true, the classname will not be prefixed with the default Y.config.classNameDelimiter value.
23155		 */
23156		getClassName: Y.cached(function () {
23157
23158            var args = Y.Array(arguments);
23159
23160            if (args[args.length-1] !== true) {
23161                args.unshift(sPrefix);
23162            } else {
23163                args.pop();
23164            }
23165
23166			return args.join(sDelimiter);
23167		})
23168
23169	};
23170
23171}();
23172
23173
23174}, 'patched-v3.18.1', {"requires": ["yui-base"]});
23175
23176YUI.add('datatype-xml-format', function (Y, NAME) {
23177
23178/**
23179 * The Number Utility provides type-conversion and string-formatting
23180 * convenience methods for Numbers.
23181 *
23182 * @module datatype-xml
23183 * @submodule datatype-xml-format
23184 */
23185
23186/**
23187 * XML provides a set of utility functions to operate against XML documents.
23188 *
23189 * @class XML
23190 * @static
23191 */
23192var LANG = Y.Lang;
23193
23194Y.mix(Y.namespace("XML"), {
23195    /**
23196     * Converts data to type XMLDocument.
23197     *
23198     * @method format
23199     * @param data {XMLDocument} Data to convert.
23200     * @return {String} String.
23201     */
23202    format: function(data) {
23203        try {
23204            if(!LANG.isUndefined(data.getXml)) {
23205                return data.getXml();
23206            }
23207
23208            if(!LANG.isUndefined(XMLSerializer)) {
23209                return (new XMLSerializer()).serializeToString(data);
23210            }
23211        }
23212        catch(e) {
23213            if(data && data.xml) {
23214                return data.xml;
23215            }
23216            else {
23217                return (LANG.isValue(data) && data.toString) ? data.toString() : "";
23218            }
23219        }
23220    }
23221});
23222
23223Y.namespace("DataType");
23224Y.DataType.XML = Y.XML;
23225
23226
23227}, 'patched-v3.18.1');
23228
23229YUI.add('datatype-xml-parse', function (Y, NAME) {
23230
23231/**
23232 * Parse XML submodule.
23233 *
23234 * @module datatype-xml
23235 * @submodule datatype-xml-parse
23236 * @for XML
23237 */
23238
23239Y.mix(Y.namespace("XML"), {
23240    /**
23241     * Converts data to type XMLDocument.
23242     *
23243     * @method parse
23244     * @param data {String} Data to convert.
23245     * @return {XMLDocument} XML Document.
23246     */
23247    parse: function(data) {
23248        var xmlDoc = null, win;
23249        if (typeof data === "string") {
23250            win = Y.config.win;
23251            if (win.ActiveXObject !== undefined) {
23252                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
23253                xmlDoc.async = false;
23254                xmlDoc.loadXML(data);
23255            } else if (win.DOMParser !== undefined) {
23256                xmlDoc = new DOMParser().parseFromString(data, "text/xml");
23257            } else if (win.Windows !== undefined) {
23258                xmlDoc = new Windows.Data.Xml.Dom.XmlDocument();
23259                xmlDoc.loadXml(data);
23260            }
23261        }
23262
23263        if (xmlDoc === null || xmlDoc.documentElement === null || xmlDoc.documentElement.nodeName === "parsererror") {
23264        }
23265
23266        return xmlDoc;
23267    }
23268});
23269
23270// Add Parsers shortcut
23271Y.namespace("Parsers").xml = Y.XML.parse;
23272
23273Y.namespace("DataType");
23274Y.DataType.XML = Y.XML;
23275
23276
23277}, 'patched-v3.18.1');
23278
23279YUI.add('dom-base', function (Y, NAME) {
23280
23281/**
23282* @for DOM
23283* @module dom
23284*/
23285var documentElement = Y.config.doc.documentElement,
23286    Y_DOM = Y.DOM,
23287    TAG_NAME = 'tagName',
23288    OWNER_DOCUMENT = 'ownerDocument',
23289    EMPTY_STRING = '',
23290    addFeature = Y.Features.add,
23291    testFeature = Y.Features.test;
23292
23293Y.mix(Y_DOM, {
23294    /**
23295     * Returns the text content of the HTMLElement.
23296     * @method getText
23297     * @param {HTMLElement} element The html element.
23298     * @return {String} The text content of the element (includes text of any descending elements).
23299     */
23300    getText: (documentElement.textContent !== undefined) ?
23301        function(element) {
23302            var ret = '';
23303            if (element) {
23304                ret = element.textContent;
23305            }
23306            return ret || '';
23307        } : function(element) {
23308            var ret = '';
23309            if (element) {
23310                ret = element.innerText || element.nodeValue; // might be a textNode
23311            }
23312            return ret || '';
23313        },
23314
23315    /**
23316     * Sets the text content of the HTMLElement.
23317     * @method setText
23318     * @param {HTMLElement} element The html element.
23319     * @param {String} content The content to add.
23320     */
23321    setText: (documentElement.textContent !== undefined) ?
23322        function(element, content) {
23323            if (element) {
23324                element.textContent = content;
23325            }
23326        } : function(element, content) {
23327            if ('innerText' in element) {
23328                element.innerText = content;
23329            } else if ('nodeValue' in element) {
23330                element.nodeValue = content;
23331            }
23332    },
23333
23334    CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
23335        'for': 'htmlFor',
23336        'class': 'className'
23337    } : { // w3c
23338        'htmlFor': 'for',
23339        'className': 'class'
23340    },
23341
23342    /**
23343     * Provides a normalized attribute interface.
23344     * @method setAttribute
23345     * @param {HTMLElement} el The target element for the attribute.
23346     * @param {String} attr The attribute to set.
23347     * @param {String} val The value of the attribute.
23348     */
23349    setAttribute: function(el, attr, val, ieAttr) {
23350        if (el && attr && el.setAttribute) {
23351            attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
23352            el.setAttribute(attr, val, ieAttr);
23353        }
23354    },
23355
23356
23357    /**
23358     * Provides a normalized attribute interface.
23359     * @method getAttribute
23360     * @param {HTMLElement} el The target element for the attribute.
23361     * @param {String} attr The attribute to get.
23362     * @return {String} The current value of the attribute.
23363     */
23364    getAttribute: function(el, attr, ieAttr) {
23365        ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
23366        var ret = '';
23367        if (el && attr && el.getAttribute) {
23368            attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
23369            // BUTTON value issue for IE < 8
23370            ret = (el.tagName === "BUTTON" && attr === 'value') ? Y_DOM.getValue(el) : el.getAttribute(attr, ieAttr);
23371
23372            if (ret === null) {
23373                ret = ''; // per DOM spec
23374            }
23375        }
23376        return ret;
23377    },
23378
23379    VALUE_SETTERS: {},
23380
23381    VALUE_GETTERS: {},
23382
23383    getValue: function(node) {
23384        var ret = '', // TODO: return null?
23385            getter;
23386
23387        if (node && node[TAG_NAME]) {
23388            getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
23389
23390            if (getter) {
23391                ret = getter(node);
23392            } else {
23393                ret = node.value;
23394            }
23395        }
23396
23397        // workaround for IE8 JSON stringify bug
23398        // which converts empty string values to null
23399        if (ret === EMPTY_STRING) {
23400            ret = EMPTY_STRING; // for real
23401        }
23402
23403        return (typeof ret === 'string') ? ret : '';
23404    },
23405
23406    setValue: function(node, val) {
23407        var setter;
23408
23409        if (node && node[TAG_NAME]) {
23410            setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
23411            val = (val === null) ? '' : val;
23412            if (setter) {
23413                setter(node, val);
23414            } else {
23415                node.value = val;
23416            }
23417        }
23418    },
23419
23420    creators: {}
23421});
23422
23423addFeature('value-set', 'select', {
23424    test: function() {
23425        var node = Y.config.doc.createElement('select');
23426        node.innerHTML = '<option>1</option><option>2</option>';
23427        node.value = '2';
23428        return (node.value && node.value === '2');
23429    }
23430});
23431
23432if (!testFeature('value-set', 'select')) {
23433    Y_DOM.VALUE_SETTERS.select = function(node, val) {
23434        for (var i = 0, options = node.getElementsByTagName('option'), option;
23435                option = options[i++];) {
23436            if (Y_DOM.getValue(option) === val) {
23437                option.selected = true;
23438                //Y_DOM.setAttribute(option, 'selected', 'selected');
23439                break;
23440            }
23441        }
23442    };
23443}
23444
23445Y.mix(Y_DOM.VALUE_GETTERS, {
23446    button: function(node) {
23447        return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
23448    }
23449});
23450
23451Y.mix(Y_DOM.VALUE_SETTERS, {
23452    // IE: node.value changes the button text, which should be handled via innerHTML
23453    button: function(node, val) {
23454        var attr = node.attributes.value;
23455        if (!attr) {
23456            attr = node[OWNER_DOCUMENT].createAttribute('value');
23457            node.setAttributeNode(attr);
23458        }
23459
23460        attr.value = val;
23461    }
23462});
23463
23464
23465Y.mix(Y_DOM.VALUE_GETTERS, {
23466    option: function(node) {
23467        var attrs = node.attributes;
23468        return (attrs.value && attrs.value.specified) ? node.value : node.text;
23469    },
23470
23471    select: function(node) {
23472        var val = node.value,
23473            options = node.options;
23474
23475        if (options && options.length) {
23476            // TODO: implement multipe select
23477            if (node.multiple) {
23478            } else if (node.selectedIndex > -1) {
23479                val = Y_DOM.getValue(options[node.selectedIndex]);
23480            }
23481        }
23482
23483        return val;
23484    }
23485});
23486var addClass, hasClass, removeClass;
23487
23488Y.mix(Y.DOM, {
23489    /**
23490     * Determines whether a DOM element has the given className.
23491     * @method hasClass
23492     * @for DOM
23493     * @param {HTMLElement} element The DOM element.
23494     * @param {String} className the class name to search for
23495     * @return {Boolean} Whether or not the element has the given class.
23496     */
23497    hasClass: function(node, className) {
23498        var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
23499        return re.test(node.className);
23500    },
23501
23502    /**
23503     * Adds a class name to a given DOM element.
23504     * @method addClass
23505     * @for DOM
23506     * @param {HTMLElement} element The DOM element.
23507     * @param {String} className the class name to add to the class attribute
23508     */
23509    addClass: function(node, className) {
23510        if (!Y.DOM.hasClass(node, className)) { // skip if already present
23511            node.className = Y.Lang.trim([node.className, className].join(' '));
23512        }
23513    },
23514
23515    /**
23516     * Removes a class name from a given element.
23517     * @method removeClass
23518     * @for DOM
23519     * @param {HTMLElement} element The DOM element.
23520     * @param {String} className the class name to remove from the class attribute
23521     */
23522    removeClass: function(node, className) {
23523        if (className && hasClass(node, className)) {
23524            node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' +
23525                            className + '(?:\\s+|$)'), ' '));
23526
23527            if ( hasClass(node, className) ) { // in case of multiple adjacent
23528                removeClass(node, className);
23529            }
23530        }
23531    },
23532
23533    /**
23534     * Replace a class with another class for a given element.
23535     * If no oldClassName is present, the newClassName is simply added.
23536     * @method replaceClass
23537     * @for DOM
23538     * @param {HTMLElement} element The DOM element
23539     * @param {String} oldClassName the class name to be replaced
23540     * @param {String} newClassName the class name that will be replacing the old class name
23541     */
23542    replaceClass: function(node, oldC, newC) {
23543        removeClass(node, oldC); // remove first in case oldC === newC
23544        addClass(node, newC);
23545    },
23546
23547    /**
23548     * If the className exists on the node it is removed, if it doesn't exist it is added.
23549     * @method toggleClass
23550     * @for DOM
23551     * @param {HTMLElement} element The DOM element
23552     * @param {String} className the class name to be toggled
23553     * @param {Boolean} addClass optional boolean to indicate whether class
23554     * should be added or removed regardless of current state
23555     */
23556    toggleClass: function(node, className, force) {
23557        var add = (force !== undefined) ? force :
23558                !(hasClass(node, className));
23559
23560        if (add) {
23561            addClass(node, className);
23562        } else {
23563            removeClass(node, className);
23564        }
23565    }
23566});
23567
23568hasClass = Y.DOM.hasClass;
23569removeClass = Y.DOM.removeClass;
23570addClass = Y.DOM.addClass;
23571
23572var re_tag = /<([a-z]+)/i,
23573
23574    Y_DOM = Y.DOM,
23575
23576    addFeature = Y.Features.add,
23577    testFeature = Y.Features.test,
23578
23579    creators = {},
23580
23581    createFromDIV = function(html, tag) {
23582        var div = Y.config.doc.createElement('div'),
23583            ret = true;
23584
23585        div.innerHTML = html;
23586        if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) {
23587            ret = false;
23588        }
23589
23590        return ret;
23591    },
23592
23593    re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
23594
23595    TABLE_OPEN = '<table>',
23596    TABLE_CLOSE = '</table>',
23597
23598    selectedIndex;
23599
23600Y.mix(Y.DOM, {
23601    _fragClones: {},
23602
23603    _create: function(html, doc, tag) {
23604        tag = tag || 'div';
23605
23606        var frag = Y_DOM._fragClones[tag];
23607        if (frag) {
23608            frag = frag.cloneNode(false);
23609        } else {
23610            frag = Y_DOM._fragClones[tag] = doc.createElement(tag);
23611        }
23612        frag.innerHTML = html;
23613        return frag;
23614    },
23615
23616    _children: function(node, tag) {
23617            var i = 0,
23618            children = node.children,
23619            childNodes,
23620            hasComments,
23621            child;
23622
23623        if (children && children.tags) { // use tags filter when possible
23624            if (tag) {
23625                children = node.children.tags(tag);
23626            } else { // IE leaks comments into children
23627                hasComments = children.tags('!').length;
23628            }
23629        }
23630
23631        if (!children || (!children.tags && tag) || hasComments) {
23632            childNodes = children || node.childNodes;
23633            children = [];
23634            while ((child = childNodes[i++])) {
23635                if (child.nodeType === 1) {
23636                    if (!tag || tag === child.tagName) {
23637                        children.push(child);
23638                    }
23639                }
23640            }
23641        }
23642
23643        return children || [];
23644    },
23645
23646    /**
23647     * Creates a new dom node using the provided markup string.
23648     * @method create
23649     * @param {String} html The markup used to create the element
23650     * @param {HTMLDocument} doc An optional document context
23651     * @return {HTMLElement|DocumentFragment} returns a single HTMLElement
23652     * when creating one node, and a documentFragment when creating
23653     * multiple nodes.
23654     */
23655    create: function(html, doc) {
23656        if (typeof html === 'string') {
23657            html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
23658
23659        }
23660
23661        doc = doc || Y.config.doc;
23662        var m = re_tag.exec(html),
23663            create = Y_DOM._create,
23664            custom = creators,
23665            ret = null,
23666            creator, tag, node, nodes;
23667
23668        if (html != undefined) { // not undefined or null
23669            if (m && m[1]) {
23670                creator = custom[m[1].toLowerCase()];
23671                if (typeof creator === 'function') {
23672                    create = creator;
23673                } else {
23674                    tag = creator;
23675                }
23676            }
23677
23678            node = create(html, doc, tag);
23679            nodes = node.childNodes;
23680
23681            if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
23682                ret = node.removeChild(nodes[0]);
23683            } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected)
23684                selectedIndex = node.selectedIndex;
23685
23686                if (nodes.length === 2) {
23687                    ret = nodes[0].nextSibling;
23688                } else {
23689                    node.removeChild(nodes[0]);
23690                    ret = Y_DOM._nl2frag(nodes, doc);
23691                }
23692            } else { // return multiple nodes as a fragment
23693                 ret = Y_DOM._nl2frag(nodes, doc);
23694            }
23695
23696        }
23697
23698        return ret;
23699    },
23700
23701    _nl2frag: function(nodes, doc) {
23702        var ret = null,
23703            i, len;
23704
23705        if (nodes && (nodes.push || nodes.item) && nodes[0]) {
23706            doc = doc || nodes[0].ownerDocument;
23707            ret = doc.createDocumentFragment();
23708
23709            if (nodes.item) { // convert live list to static array
23710                nodes = Y.Array(nodes, 0, true);
23711            }
23712
23713            for (i = 0, len = nodes.length; i < len; i++) {
23714                ret.appendChild(nodes[i]);
23715            }
23716        } // else inline with log for minification
23717        return ret;
23718    },
23719
23720    /**
23721     * Inserts content in a node at the given location
23722     * @method addHTML
23723     * @param {HTMLElement} node The node to insert into
23724     * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted
23725     * @param {HTMLElement} where Where to insert the content
23726     * If no "where" is given, content is appended to the node
23727     * Possible values for "where"
23728     * <dl>
23729     * <dt>HTMLElement</dt>
23730     * <dd>The element to insert before</dd>
23731     * <dt>"replace"</dt>
23732     * <dd>Replaces the existing HTML</dd>
23733     * <dt>"before"</dt>
23734     * <dd>Inserts before the existing HTML</dd>
23735     * <dt>"before"</dt>
23736     * <dd>Inserts content before the node</dd>
23737     * <dt>"after"</dt>
23738     * <dd>Inserts content after the node</dd>
23739     * </dl>
23740     */
23741    addHTML: function(node, content, where) {
23742        var nodeParent = node.parentNode,
23743            i = 0,
23744            item,
23745            ret = content,
23746            newNode;
23747
23748
23749        if (content != undefined) { // not null or undefined (maybe 0)
23750            if (content.nodeType) { // DOM node, just add it
23751                newNode = content;
23752            } else if (typeof content == 'string' || typeof content == 'number') {
23753                ret = newNode = Y_DOM.create(content);
23754            } else if (content[0] && content[0].nodeType) { // array or collection
23755                newNode = Y.config.doc.createDocumentFragment();
23756                while ((item = content[i++])) {
23757                    newNode.appendChild(item); // append to fragment for insertion
23758                }
23759            }
23760        }
23761
23762        if (where) {
23763            if (newNode && where.parentNode) { // insert regardless of relationship to node
23764                where.parentNode.insertBefore(newNode, where);
23765            } else {
23766                switch (where) {
23767                    case 'replace':
23768                        while (node.firstChild) {
23769                            node.removeChild(node.firstChild);
23770                        }
23771                        if (newNode) { // allow empty content to clear node
23772                            node.appendChild(newNode);
23773                        }
23774                        break;
23775                    case 'before':
23776                        if (newNode) {
23777                            nodeParent.insertBefore(newNode, node);
23778                        }
23779                        break;
23780                    case 'after':
23781                        if (newNode) {
23782                            if (node.nextSibling) { // IE errors if refNo
23782de is null
23783                                nodeParent.insertBefore(newNode, node.nextSibling);
23784                            } else {
23785                                nodeParent.appendChild(newNode);
23786                            }
23787                        }
23788                        break;
23789                    default:
23790                        if (newNode) {
23791                            node.appendChild(newNode);
23792                        }
23793                }
23794            }
23795        } else if (newNode) {
23796            node.appendChild(newNode);
23797        }
23798
23799        // `select` elements are the only elements with `selectedIndex`.
23800        // Don't grab the dummy `option` element's `selectedIndex`.
23801        if (node.nodeName == "SELECT" && selectedIndex > 0) {
23802            node.selectedIndex = selectedIndex - 1;
23803        }
23804
23805        return ret;
23806    },
23807
23808    wrap: function(node, html) {
23809        var parent = (html && html.nodeType) ? html : Y.DOM.create(html),
23810            nodes = parent.getElementsByTagName('*');
23811
23812        if (nodes.length) {
23813            parent = nodes[nodes.length - 1];
23814        }
23815
23816        if (node.parentNode) {
23817            node.parentNode.replaceChild(parent, node);
23818        }
23819        parent.appendChild(node);
23820    },
23821
23822    unwrap: function(node) {
23823        var parent = node.parentNode,
23824            lastChild = parent.lastChild,
23825            next = node,
23826            grandparent;
23827
23828        if (parent) {
23829            grandparent = parent.parentNode;
23830            if (grandparent) {
23831                node = parent.firstChild;
23832                while (node !== lastChild) {
23833                    next = node.nextSibling;
23834                    grandparent.insertBefore(node, parent);
23835                    node = next;
23836                }
23837                grandparent.replaceChild(lastChild, parent);
23838            } else {
23839                parent.removeChild(node);
23840            }
23841        }
23842    }
23843});
23844
23845addFeature('innerhtml', 'table', {
23846    test: function() {
23847        var node = Y.config.doc.createElement('table');
23848        try {
23849            node.innerHTML = '<tbody></tbody>';
23850        } catch(e) {
23851            return false;
23852        }
23853        return (node.firstChild && node.firstChild.nodeName === 'TBODY');
23854    }
23855});
23856
23857addFeature('innerhtml-div', 'tr', {
23858    test: function() {
23859        return createFromDIV('<tr></tr>', 'tr');
23860    }
23861});
23862
23863addFeature('innerhtml-div', 'script', {
23864    test: function() {
23865        return createFromDIV('<script></script>', 'script');
23866    }
23867});
23868
23869if (!testFeature('innerhtml', 'table')) {
23870    // TODO: thead/tfoot with nested tbody
23871        // IE adds TBODY when creating TABLE elements (which may share this impl)
23872    creators.tbody = function(html, doc) {
23873        var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc),
23874            tb = Y.DOM._children(frag, 'tbody')[0];
23875
23876        if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
23877            tb.parentNode.removeChild(tb); // strip extraneous tbody
23878        }
23879        return frag;
23880    };
23881}
23882
23883if (!testFeature('innerhtml-div', 'script')) {
23884    creators.script = function(html, doc) {
23885        var frag = doc.createElement('div');
23886
23887        frag.innerHTML = '-' + html;
23888        frag.removeChild(frag.firstChild);
23889        return frag;
23890    };
23891
23892    creators.link = creators.style = creators.script;
23893}
23894
23895if (!testFeature('innerhtml-div', 'tr')) {
23896    Y.mix(creators, {
23897        option: function(html, doc) {
23898            return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc);
23899        },
23900
23901        tr: function(html, doc) {
23902            return Y_DOM.create('<tbody>' + html + '</tbody>', doc);
23903        },
23904
23905        td: function(html, doc) {
23906            return Y_DOM.create('<tr>' + html + '</tr>', doc);
23907        },
23908
23909        col: function(html, doc) {
23910            return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc);
23911        },
23912
23913        tbody: 'table'
23914    });
23915
23916    Y.mix(creators, {
23917        legend: 'fieldset',
23918        th: creators.td,
23919        thead: creators.tbody,
23920        tfoot: creators.tbody,
23921        caption: creators.tbody,
23922        colgroup: creators.tbody,
23923        optgroup: creators.option
23924    });
23925}
23926
23927Y_DOM.creators = creators;
23928Y.mix(Y.DOM, {
23929    /**
23930     * Sets the width of the element to the given size, regardless
23931     * of box model, border, padding, etc.
23932     * @method setWidth
23933     * @param {HTMLElement} element The DOM element.
23934     * @param {String|Number} size The pixel height to size to
23935     */
23936
23937    setWidth: function(node, size) {
23938        Y.DOM._setSize(node, 'width', size);
23939    },
23940
23941    /**
23942     * Sets the height of the element to the given size, regardless
23943     * of box model, border, padding, etc.
23944     * @method setHeight
23945     * @param {HTMLElement} element The DOM element.
23946     * @param {String|Number} size The pixel height to size to
23947     */
23948
23949    setHeight: function(node, size) {
23950        Y.DOM._setSize(node, 'height', size);
23951    },
23952
23953    _setSize: function(node, prop, val) {
23954        val = (val > 0) ? val : 0;
23955        var size = 0;
23956
23957        node.style[prop] = val + 'px';
23958        size = (prop === 'height') ? node.offsetHeight : node.offsetWidth;
23959
23960        if (size > val) {
23961            val = val - (size - val);
23962
23963            if (val < 0) {
23964                val = 0;
23965            }
23966
23967            node.style[prop] = val + 'px';
23968        }
23969    }
23970});
23971
23972
23973}, 'patched-v3.18.1', {"requires": ["dom-core"]});
23974
23975YUI.add('dom-core', function (Y, NAME) {
23976
23977var NODE_TYPE = 'nodeType',
23978    OWNER_DOCUMENT = 'ownerDocument',
23979    DOCUMENT_ELEMENT = 'documentElement',
23980    DEFAULT_VIEW = 'defaultView',
23981    PARENT_WINDOW = 'parentWindow',
23982    TAG_NAME = 'tagName',
23983    PARENT_NODE = 'parentNode',
23984    PREVIOUS_SIBLING = 'previousSibling',
23985    NEXT_SIBLING = 'nextSibling',
23986    CONTAINS = 'contains',
23987    COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
23988    EMPTY_ARRAY = [],
23989
23990    // IE < 8 throws on node.contains(textNode)
23991    supportsContainsTextNode = (function() {
23992        var node = Y.config.doc.createElement('div'),
23993            textNode = node.appendChild(Y.config.doc.createTextNode('')),
23994            result = false;
23995
23996        try {
23997            result = node.contains(textNode);
23998        } catch(e) {}
23999
24000        return result;
24001    })(),
24002
24003/**
24004 * The DOM utility provides a cross-browser abtraction layer
24005 * normalizing DOM tasks, and adds extra helper functionality
24006 * for other common tasks.
24007 * @module dom
24008 * @main dom
24009 * @submodule dom-base
24010 * @for DOM
24011 *
24012 */
24013
24014/**
24015 * Provides DOM helper methods.
24016 * @class DOM
24017 *
24018 */
24019
24020Y_DOM = {
24021    /**
24022     * Returns the HTMLElement with the given ID (Wrapper for document.getElementById).
24023     * @method byId
24024     * @param {String} id the id attribute
24025     * @param {Object} doc optional The document to search. Defaults to current document
24026     * @return {HTMLElement | null} The HTMLElement with the id, or null if none found.
24027     */
24028    byId: function(id, doc) {
24029        // handle dupe IDs and IE name collision
24030        return Y_DOM.allById(id, doc)[0] || null;
24031    },
24032
24033    getId: function(node) {
24034        var id;
24035        // HTMLElement returned from FORM when INPUT name === "id"
24036        // IE < 8: HTMLCollection returned when INPUT id === "id"
24037        // via both getAttribute and form.id
24038        if (node.id && !node.id.tagName && !node.id.item) {
24039            id = node.id;
24040        } else if (node.attributes && node.attributes.id) {
24041            id = node.attributes.id.value;
24042        }
24043
24044        return id;
24045    },
24046
24047    setId: function(node, id) {
24048        if (node.setAttribute) {
24049            node.setAttribute('id', id);
24050        } else {
24051            node.id = id;
24052        }
24053    },
24054
24055    /*
24056     * Finds the ancestor of the element.
24057     * @method ancestor
24058     * @param {HTMLElement} element The html element.
24059     * @param {Function} fn optional An optional boolean test to apply.
24060     * The optional function is passed the current DOM node being tested as its only argument.
24061     * If no function is given, the parentNode is returned.
24062     * @param {Boolean} testSelf optional Whether or not to include the element in the scan
24063     * @return {HTMLElement | null} The matching DOM node or null if none found.
24064     */
24065    ancestor: function(element, fn, testSelf, stopFn) {
24066        var ret = null;
24067        if (testSelf) {
24068            ret = (!fn || fn(element)) ? element : null;
24069
24070        }
24071        return ret || Y_DOM.elementByAxis(element, PARENT_NODE, fn, null, stopFn);
24072    },
24073
24074    /*
24075     * Finds the ancestors of the element.
24076     * @method ancestors
24077     * @param {HTMLElement} element The html element.
24078     * @param {Function} fn optional An optional boolean test to apply.
24079     * The optional function is passed the current DOM node being tested as its only argument.
24080     * If no function is given, all ancestors are returned.
24081     * @param {Boolean} testSelf optional Whether or not to include the element in the scan
24082     * @return {Array} An array containing all matching DOM nodes.
24083     */
24084    ancestors: function(element, fn, testSelf, stopFn) {
24085        var ancestor = element,
24086            ret = [];
24087
24088        while ((ancestor = Y_DOM.ancestor(ancestor, fn, testSelf, stopFn))) {
24089            testSelf = false;
24090            if (ancestor) {
24091                ret.unshift(ancestor);
24092
24093                if (stopFn && stopFn(ancestor)) {
24094                    return ret;
24095                }
24096            }
24097        }
24098
24099        return ret;
24100    },
24101
24102    /**
24103     * Searches the element by the given axis for the first matching element.
24104     * @method elementByAxis
24105     * @param {HTMLElement} element The html element.
24106     * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling).
24107     * @param {Function} [fn] An optional boolean test to apply.
24108     * @param {Boolean} [all] Whether text nodes as well as element nodes should be returned, or
24109     * just element nodes will be returned(default)
24110     * The optional function is passed the current HTMLElement being tested as its only argument.
24111     * If no function is given, the first element is returned.
24112     * @return {HTMLElement | null} The matching element or null if none found.
24113     */
24114    elementByAxis: function(element, axis, fn, all, stopAt) {
24115        while (element && (element = element[axis])) { // NOTE: assignment
24116                if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) {
24117                    return element;
24118                }
24119
24120                if (stopAt && stopAt(element)) {
24121                    return null;
24122                }
24123        }
24124        return null;
24125    },
24126
24127    /**
24128     * Determines whether or not one HTMLElement is or contains another HTMLElement.
24129     * @method contains
24130     * @param {HTMLElement} element The containing html element.
24131     * @param {HTMLElement} needle The html element that may be contained.
24132     * @return {Boolean} Whether or not the element is or contains the needle.
24133     */
24134    contains: function(element, needle) {
24135        var ret = false;
24136
24137        if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
24138            ret = false;
24139        } else if (element[CONTAINS] &&
24140                // IE < 8 throws on node.contains(textNode) so fall back to brute.
24141                // Falling back for other nodeTypes as well.
24142                (needle[NODE_TYPE] === 1 || supportsContainsTextNode)) {
24143                ret = element[CONTAINS](needle);
24144        } else if (element[COMPARE_DOCUMENT_POSITION]) {
24145            // Match contains behavior (node.contains(node) === true).
24146            // Needed for Firefox < 4.
24147            if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
24148                ret = true;
24149            }
24150        } else {
24151            ret = Y_DOM._bruteContains(element, needle);
24152        }
24153
24154        return ret;
24155    },
24156
24157    /**
24158     * Determines whether or not the HTMLElement is part of the document.
24159     * @method inDoc
24160     * @param {HTMLElement} element The containing html element.
24161     * @param {HTMLElement} doc optional The document to check.
24162     * @return {Boolean} Whether or not the element is attached to the document.
24163     */
24164    inDoc: function(element, doc) {
24165        var ret = false,
24166            rootNode;
24167
24168        if (element && element.nodeType) {
24169            (doc) || (doc = element[OWNER_DOCUMENT]);
24170
24171            rootNode = doc[DOCUMENT_ELEMENT];
24172
24173            // contains only works with HTML_ELEMENT
24174            if (rootNode && rootNode.contains && element.tagName) {
24175                ret = rootNode.contains(element);
24176            } else {
24177                ret = Y_DOM.contains(rootNode, element);
24178            }
24179        }
24180
24181        return ret;
24182
24183    },
24184
24185   allById: function(id, root) {
24186        root = root || Y.config.doc;
24187        var nodes = [],
24188            ret = [],
24189            i,
24190            node;
24191
24192        if (root.querySelectorAll) {
24193            ret = root.querySelectorAll('[id="' + id + '"]');
24194        } else if (root.all) {
24195            nodes = root.all(id);
24196
24197            if (nodes) {
24198                // root.all may return HTMLElement or HTMLCollection.
24199                // some elements are also HTMLCollection (FORM, SELECT).
24200                if (nodes.nodeName) {
24201                    if (nodes.id === id) { // avoid false positive on name
24202                        ret.push(nodes);
24203                        nodes = EMPTY_ARRAY; // done, no need to filter
24204                    } else { //  prep for filtering
24205                        nodes = [nodes];
24206                    }
24207                }
24208
24209                if (nodes.length) {
24210                    // filter out matches on node.name
24211                    // and element.id as reference to element with id === 'id'
24212                    for (i = 0; node = nodes[i++];) {
24213                        if (node.id === id  ||
24214                                (node.attributes && node.attributes.id &&
24215                                node.attributes.id.value === id)) {
24216                            ret.push(node);
24217                        }
24218                    }
24219                }
24220            }
24221        } else {
24222            ret = [Y_DOM._getDoc(root).getElementById(id)];
24223        }
24224
24225        return ret;
24226   },
24227
24228
24229    isWindow: function(obj) {
24230        return !!(obj && obj.scrollTo && obj.document);
24231    },
24232
24233    _removeChildNodes: function(node) {
24234        while (node.firstChild) {
24235            node.removeChild(node.firstChild);
24236        }
24237    },
24238
24239    siblings: function(node, fn) {
24240        var nodes = [],
24241            sibling = node;
24242
24243        while ((sibling = sibling[PREVIOUS_SIBLING])) {
24244            if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
24245                nodes.unshift(sibling);
24246            }
24247        }
24248
24249        sibling = node;
24250        while ((sibling = sibling[NEXT_SIBLING])) {
24251            if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
24252                nodes.push(sibling);
24253            }
24254        }
24255
24256        return nodes;
24257    },
24258
24259    /**
24260     * Brute force version of contains.
24261     * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc).
24262     * @method _bruteContains
24263     * @private
24264     * @param {HTMLElement} element The containing html element.
24265     * @param {HTMLElement} needle The html element that may be contained.
24266     * @return {Boolean} Whether or not the element is or contains the needle.
24267     */
24268    _bruteContains: function(element, needle) {
24269        while (needle) {
24270            if (element === needle) {
24271                return true;
24272            }
24273            needle = needle.parentNode;
24274        }
24275        return false;
24276    },
24277
24278// TODO: move to Lang?
24279    /**
24280     * Memoizes dynamic regular expressions to boost runtime performance.
24281     * @method _getRegExp
24282     * @private
24283     * @param {String} str The string to convert to a regular expression.
24284     * @param {String} flags optional An optinal string of flags.
24285     * @return {RegExp} An instance of RegExp
24286     */
24287    _getRegExp: function(str, flags) {
24288        flags = flags || '';
24289        Y_DOM._regexCache = Y_DOM._regexCache || {};
24290        if (!Y_DOM._regexCache[str + flags]) {
24291            Y_DOM._regexCache[str + flags] = new RegExp(str, flags);
24292        }
24293        return Y_DOM._regexCache[str + flags];
24294    },
24295
24296// TODO: make getDoc/Win true privates?
24297    /**
24298     * returns the appropriate document.
24299     * @method _getDoc
24300     * @private
24301     * @param {HTMLElement} element optional Target element.
24302     * @return {Object} The document for the given element or the default document.
24303     */
24304    _getDoc: function(element) {
24305        var doc = Y.config.doc;
24306        if (element) {
24307            doc = (element[NODE_TYPE] === 9) ? element : // element === document
24308                element[OWNER_DOCUMENT] || // element === DOM node
24309                element.document || // element === window
24310                Y.config.doc; // default
24311        }
24312
24313        return doc;
24314    },
24315
24316    /**
24317     * returns the appropriate window.
24318     * @method _getWin
24319     * @private
24320     * @param {HTMLElement} element optional Target element.
24321     * @return {Object} The window for the given element or the default window.
24322     */
24323    _getWin: function(element) {
24324        var doc = Y_DOM._getDoc(element);
24325        return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win;
24326    },
24327
24328    _batch: function(nodes, fn, arg1, arg2, arg3, etc) {
24329        fn = (typeof fn === 'string') ? Y_DOM[fn] : fn;
24330        var result,
24331            i = 0,
24332            node,
24333            ret;
24334
24335        if (fn && nodes) {
24336            while ((node = nodes[i++])) {
24337                result = result = fn.call(Y_DOM, node, arg1, arg2, arg3, etc);
24338                if (typeof result !== 'undefined') {
24339                    (ret) || (ret = []);
24340                    ret.push(result);
24341                }
24342            }
24343        }
24344
24345        return (typeof ret !== 'undefined') ? ret : nodes;
24346    },
24347
24348    generateID: function(el) {
24349        var id = el.id;
24350
24351        if (!id) {
24352            id = Y.stamp(el);
24353            el.id = id;
24354        }
24355
24356        return id;
24357    }
24358};
24359
24360
24361Y.DOM = Y_DOM;
24362
24363
24364}, 'patched-v3.18.1', {"requires": ["oop", "features"]});
24365
24366YUI.add('dom-screen', function (Y, NAME) {
24367
24368(function(Y) {
24369
24370/**
24371 * Adds position and region management functionality to DOM.
24372 * @module dom
24373 * @submodule dom-screen
24374 * @for DOM
24375 */
24376
24377var DOCUMENT_ELEMENT = 'documentElement',
24378    COMPAT_MODE = 'compatMode',
24379    POSITION = 'position',
24380    FIXED = 'fixed',
24381    RELATIVE = 'relative',
24382    LEFT = 'left',
24383    TOP = 'top',
24384    _BACK_COMPAT = 'BackCompat',
24385    MEDIUM = 'medium',
24386    BORDER_LEFT_WIDTH = 'borderLeftWidth',
24387    BORDER_TOP_WIDTH = 'borderTopWidth',
24388    GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
24389    GET_COMPUTED_STYLE = 'getComputedStyle',
24390
24391    Y_DOM = Y.DOM,
24392
24393    // TODO: how about thead/tbody/tfoot/tr?
24394    // TODO: does caption matter?
24395    RE_TABLE = /^t(?:able|d|h)$/i,
24396
24397    SCROLL_NODE;
24398
24399if (Y.UA.ie) {
24400    if (Y.config.doc[COMPAT_MODE] !== 'BackCompat') {
24401        SCROLL_NODE = DOCUMENT_ELEMENT;
24402    } else {
24403        SCROLL_NODE = 'body';
24404    }
24405}
24406
24407Y.mix(Y_DOM, {
24408    /**
24409     * Returns the inner height of the viewport (exludes scrollbar).
24410     * @method winHeight
24411     * @return {Number} The current height of the viewport.
24412     */
24413    winHeight: function(node) {
24414        var h = Y_DOM._getWinSize(node).height;
24415        return h;
24416    },
24417
24418    /**
24419     * Returns the inner width of the viewport (exludes scrollbar).
24420     * @method winWidth
24421     * @return {Number} The current width of the viewport.
24422     */
24423    winWidth: function(node) {
24424        var w = Y_DOM._getWinSize(node).width;
24425        return w;
24426    },
24427
24428    /**
24429     * Document height
24430     * @method docHeight
24431     * @return {Number} The current height of the document.
24432     */
24433    docHeight:  function(node) {
24434        var h = Y_DOM._getDocSize(node).height;
24435        return Math.max(h, Y_DOM._getWinSize(node).height);
24436    },
24437
24438    /**
24439     * Document width
24440     * @method docWidth
24441     * @return {Number} The current width of the document.
24442     */
24443    docWidth:  function(node) {
24444        var w = Y_DOM._getDocSize(node).width;
24445        return Math.max(w, Y_DOM._getWinSize(node).width);
24446    },
24447
24448    /**
24449     * Amount page has been scroll horizontally
24450     * @method docScrollX
24451     * @return {Number} The current amount the screen is scrolled horizontally.
24452     */
24453    docScrollX: function(node, doc) {
24454        doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
24455        var dv = doc.defaultView,
24456            pageOffset = (dv) ? dv.pageXOffset : 0;
24457        return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset);
24458    },
24459
24460    /**
24461     * Amount page has been scroll vertically
24462     * @method docScrollY
24463     * @return {Number} The current amount the screen is scrolled vertically.
24464     */
24465    docScrollY:  function(node, doc) {
24466        doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
24467        var dv = doc.defaultView,
24468            pageOffset = (dv) ? dv.pageYOffset : 0;
24469        return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset);
24470    },
24471
24472    /**
24473     * Gets the current position of an element based on page coordinates.
24474     * Element must be part of the DOM tree to have page coordinates
24475     * (display:none or elements not appended return false).
24476     * @method getXY
24477     * @param element The target element
24478     * @return {Array} The XY position of the element
24479
24480     TODO: test inDocument/display?
24481     */
24482    getXY: function() {
24483        if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) {
24484            return function(node) {
24485                var xy = null,
24486                    scrollLeft,
24487                    scrollTop,
24488                    mode,
24489                    box,
24490                    offX,
24491                    offY,
24492                    doc,
24493                    win,
24494                    inDoc,
24495                    rootNode;
24496
24497                if (node && node.tagName) {
24498                    doc = node.ownerDocument;
24499                    mode = doc[COMPAT_MODE];
24500
24501                    if (mode !== _BACK_COMPAT) {
24502                        rootNode = doc[DOCUMENT_ELEMENT];
24503                    } else {
24504                        rootNode = doc.body;
24505                    }
24506
24507                    // inline inDoc check for perf
24508                    if (rootNode.contains) {
24509                        inDoc = rootNode.contains(node);
24510                    } else {
24511                        inDoc = Y.DOM.contains(rootNode, node);
24512                    }
24513
24514                    if (inDoc) {
24515                        win = doc.defaultView;
24516
24517                        // inline scroll calc for perf
24518                        if (win && 'pageXOffset' in win) {
24519                            scrollLeft = win.pageXOffset;
24520                            scrollTop = win.pageYOffset;
24521                        } else {
24522                            scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc);
24523                            scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc);
24524                        }
24525
24526                        if (Y.UA.ie) { // IE < 8, quirks, or compatMode
24527                            if (!doc.documentMode || doc.documentMode < 8 || mode === _BACK_COMPAT) {
24528                                offX = rootNode.clientLeft;
24529                                offY = rootNode.clientTop;
24530                            }
24531                        }
24532                        box = node[GET_BOUNDING_CLIENT_RECT]();
24533                        xy = [box.left, box.top];
24534
24535                        if (offX || offY) {
24536                                xy[0] -= offX;
24537                                xy[1] -= offY;
24538
24539                        }
24540                        if ((scrollTop || scrollLeft)) {
24541                            if (!Y.UA.ios || (Y.UA.ios >= 4.2)) {
24542                                xy[0] += scrollLeft;
24543                                xy[1] += scrollTop;
24544                            }
24545
24546                        }
24547                    } else {
24548                        xy = Y_DOM._getOffset(node);
24549                    }
24550                }
24551                return xy;
24552            };
24553        } else {
24554            return function(node) { // manually calculate by crawling up offsetParents
24555                //Calculate the Top and Left border sizes (assumes pixels)
24556                var xy = null,
24557                    doc,
24558                    parentNode,
24559                    bCheck,
24560                    scrollTop,
24561                    scrollLeft;
24562
24563                if (node) {
24564                    if (Y_DOM.inDoc(node)) {
24565                        xy = [node.offsetLeft, node.offsetTop];
24566                        doc = node.ownerDocument;
24567                        parentNode = node;
24568                        // TODO: refactor with !! or just falsey
24569                        bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false);
24570
24571                        // TODO: worth refactoring for TOP/LEFT only?
24572                        while ((parentNode = parentNode.offsetParent)) {
24573                            xy[0] += parentNode.offsetLeft;
24574                            xy[1] += parentNode.offsetTop;
24575                            if (bCheck) {
24576                                xy = Y_DOM._calcBorders(parentNode, xy);
24577                            }
24578                        }
24579
24580                        // account for any scrolled ancestors
24581                        if (Y_DOM.getStyle(node, POSITION) != FIXED) {
24582                            parentNode = node;
24583
24584                            while ((parentNode = parentNode.parentNode)) {
24585                                scrollTop = parentNode.scrollTop;
24586                                scrollLeft = parentNode.scrollLeft;
24587
24588                                //Firefox does something funky with borders when overflow is not visible.
24589                                if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) {
24590                                        xy = Y_DOM._calcBorders(parentNode, xy);
24591                                }
24592
24593
24594                                if (scrollTop || scrollLeft) {
24595                                    xy[0] -= scrollLeft;
24596                                    xy[1] -= scrollTop;
24597                                }
24598                            }
24599                            xy[0] += Y_DOM.docScrollX(node, doc);
24600                            xy[1] += Y_DOM.docScrollY(node, doc);
24601
24602                        } else {
24603                            //Fix FIXED position -- add scrollbars
24604                            xy[0] += Y_DOM.docScrollX(node, doc);
24605                            xy[1] += Y_DOM.docScrollY(node, doc);
24606                        }
24607                    } else {
24608                        xy = Y_DOM._getOffset(node);
24609                    }
24610                }
24611
24612                return xy;
24613            };
24614        }
24615    }(),// NOTE: Executing for loadtime branching
24616
24617    /**
24618    Gets the width of vertical scrollbars on overflowed containers in the body
24619    content.
24620
24621    @method getScrollbarWidth
24622    @return {Number} Pixel width of a scrollbar in the current browser
24623    **/
24624    getScrollbarWidth: Y.cached(function () {
24625        var doc      = Y.config.doc,
24626            testNode = doc.createElement('div'),
24627            body     = doc.getElementsByTagName('body')[0],
24628            // 0.1 because cached doesn't support falsy refetch values
24629            width    = 0.1;
24630
24631        if (body) {
24632            testNode.style.cssText = "position:absolute;visibility:hidden;overflow:scroll;width:20px;";
24633            testNode.appendChild(doc.createElement('p')).style.height = '1px';
24634            body.insertBefore(testNode, body.firstChild);
24635            width = testNode.offsetWidth - testNode.clientWidth;
24636
24637            body.removeChild(testNode);
24638        }
24639
24640        return width;
24641    }, null, 0.1),
24642
24643    /**
24644     * Gets the current X position of an element based on page coordinates.
24645     * Element must be part of the DOM tree to have page coordinates
24646     * (display:none or elements not appended return false).
24647     * @method getX
24648     * @param element The target element
24649     * @return {Number} The X position of the element
24650     */
24651
24652    getX: function(node) {
24653        return Y_DOM.getXY(node)[0];
24654    },
24655
24656    /**
24657     * Gets the current Y position of an element based on page coordinates.
24658     * Element must be part of the DOM tree to have page coordinates
24659     * (display:none or elements not appended return false).
24660     * @method getY
24661     * @param element The target element
24662     * @return {Number} The Y position of the element
24663     */
24664
24665    getY: function(node) {
24666        return Y_DOM.getXY(node)[1];
24667    },
24668
24669    /**
24670     * Set the position of an html element in page coordinates.
24671     * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
24672     * @method setXY
24673     * @param element The target element
24674     * @param {Array} xy Contains X & Y values for new position (coordinates are page-based)
24675     * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
24676     */
24677    setXY: function(node, xy, noRetry) {
24678        var setStyle = Y_DOM.setStyle,
24679            pos,
24680            delta,
24681            newXY,
24682            currentXY,
24683            offsetDir,
24684            dir,
24685            x;
24686
24687        if (node && xy) {
24688            pos = Y_DOM.getStyle(node, POSITION);
24689
24690            offsetDir = Y_DOM.OFFSET_XY;
24691
24692            if (!offsetDir) {
24693                dir = Y_DOM.getComputedStyle(node, 'direction');
24694
24695                offsetDir = (dir === 'rtl' ? 'right' : LEFT);
24696            }
24697
24698            delta = Y_DOM._getOffset(node, offsetDir);
24699            if (pos == 'static') { // default to relative
24700                pos = RELATIVE;
24701                setStyle(node, POSITION, pos);
24702            }
24703            currentXY = Y_DOM._getDirXY(node, offsetDir);
24704
24705            x = xy[0];
24706
24707            if (offsetDir === 'right') {
24708                x = Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10));
24709
24710                if (!delta[0] && !noRetry) {
24711                    noRetry = false;
24712                }
24713            }
24714
24715            if (x !== null) {
24716                setStyle(node, offsetDir, x - currentXY[0] + delta[0] + 'px');
24717            }
24718
24719            if (xy[1] !== null) {
24720                setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px');
24721            }
24722
24723            if (!noRetry) {
24724                newXY = Y_DOM.getXY(node);
24725                if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) {
24726                    Y_DOM.setXY(node, xy, true);
24727                }
24728            }
24729
24730        } else {
24731        }
24732    },
24733
24734    /**
24735     * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
24736     * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
24737     * @method setX
24738     * @param element The target element
24739     * @param {Number} x The X values for new position (coordinates are page-based)
24740     */
24741    setX: function(node, x) {
24742        return Y_DOM.setXY(node, [x, null]);
24743    },
24744
24745    /**
24746     * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
24747     * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
24748     * @method setY
24749     * @param element The target element
24750     * @param {Number} y The Y values for new position (coordinates are page-based)
24751     */
24752    setY: function(node, y) {
24753        return Y_DOM.setXY(node, [null, y]);
24754    },
24755
24756    /**
24757     * @method swapXY
24758     * @description Swap the xy position with another node
24759     * @param {Node} node The node to swap with
24760     * @param {Node} otherNode The other node to swap with
24761     * @return {Node}
24762     */
24763    swapXY: function(node, otherNode) {
24764        var xy = Y_DOM.getXY(node);
24765        Y_DOM.setXY(node, Y_DOM.getXY(otherNode));
24766        Y_DOM.setXY(otherNode, xy);
24767    },
24768
24769    _calcBorders: function(node, xy2) {
24770        var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0,
24771            l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0;
24772        if (Y.UA.gecko) {
24773            if (RE_TABLE.test(node.tagName)) {
24774                t = 0;
24775                l = 0;
24776            }
24777        }
24778        xy2[0] += l;
24779        xy2[1] += t;
24780        return xy2;
24781    },
24782
24783    _getWinSize: function(node, doc) {
24784        doc  = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc;
24785        var win = doc.defaultView || doc.parentWindow,
24786            mode = doc[COMPAT_MODE],
24787            h = win.innerHeight,
24788            w = win.innerWidth,
24789            root = doc[DOCUMENT_ELEMENT];
24790
24791        if ( mode && !Y.UA.opera ) { // IE, Gecko
24792            if (mode != 'CSS1Compat') { // Quirks
24793                root = doc.body;
24794            }
24795            h = root.clientHeight;
24796            w = root.clientWidth;
24797        }
24798        return { height: h, width: w };
24799    },
24800
24801    _getDocSize: function(node) {
24802        var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc,
24803            root = doc[DOCUMENT_ELEMENT];
24804
24805        if (doc[COMPAT_MODE] != 'CSS1Compat') {
24806            root = doc.body;
24807        }
24808
24809        return { height: root.scrollHeight, width: root.scrollWidth };
24810    },
24811
24812    _getDirXY: function(node, dir) {
24813        var xy = Y_DOM.getXY(node);
24814
24815        if (dir === 'right') {
24816            xy[0] = (Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10)));
24817        }
24818
24819        return xy;
24820    }
24821});
24822
24823})(Y);
24824(function(Y) {
24825var TOP = 'top',
24826    RIGHT = 'right',
24827    BOTTOM = 'bottom',
24828    LEFT = 'left',
24829
24830    getOffsets = function(r1, r2) {
24831        var t = Math.max(r1[TOP], r2[TOP]),
24832            r = Math.min(r1[RIGHT], r2[RIGHT]),
24833            b = Math.min(r1[BOTTOM], r2[BOTTOM]),
24834            l = Math.max(r1[LEFT], r2[LEFT]),
24835            ret = {};
24836
24837        ret[TOP] = t;
24838        ret[RIGHT] = r;
24839        ret[BOTTOM] = b;
24840        ret[LEFT] = l;
24841        return ret;
24842    },
24843
24844    DOM = Y.DOM;
24845
24846Y.mix(DOM, {
24847    /**
24848     * Returns an Object literal containing the following about this element: (top, right, bottom, left)
24849     * @for DOM
24850     * @method region
24851     * @param {HTMLElement} element The DOM element.
24852     * @return {Object} Object literal containing the following about this element: (top, right, bottom, left)
24853     */
24854    region: function(node) {
24855        var xy = DOM.getXY(node),
24856            ret = false;
24857
24858        if (node && xy) {
24859            ret = DOM._getRegion(
24860                xy[1], // top
24861                xy[0] + node.offsetWidth, // right
24862                xy[1] + node.offsetHeight, // bottom
24863                xy[0] // left
24864            );
24865        }
24866
24867        return ret;
24868    },
24869
24870    /**
24871     * Find the intersect information for the passed nodes.
24872     * @method intersect
24873     * @for DOM
24874     * @param {HTMLElement} element The first element
24875     * @param {HTMLElement | Object} element2 The element or region to check the interect with
24876     * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance e.g. DragDrop)
24877     * @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion)
24878     */
24879    intersect: function(node, node2, altRegion) {
24880        var r = altRegion || DOM.region(node), region = {},
24881            n = node2,
24882            off;
24883
24884        if (n.tagName) {
24885            region = DOM.region(n);
24886        } else if (Y.Lang.isObject(node2)) {
24887            region = node2;
24888        } else {
24889            return false;
24890        }
24891
24892        off = getOffsets(region, r);
24893        return {
24894            top: off[TOP],
24895            right: off[RIGHT],
24896            bottom: off[BOTTOM],
24897            left: off[LEFT],
24898            area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])),
24899            yoff: ((off[BOTTOM] - off[TOP])),
24900            xoff: (off[RIGHT] - off[LEFT]),
24901            inRegion: DOM.inRegion(node, node2, false, altRegion)
24902        };
24903
24904    },
24905    /**
24906     * Check if any part of this node is in the passed region
24907     * @method inRegion
24908     * @for DOM
24909     * @param {Object} node The node to get the region from
24910     * @param {Object} node2 The second node to get the region from or an Object literal of the region
24911     * @param {Boolean} all Should all of the node be inside the region
24912     * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop)
24913     * @return {Boolean} True if in region, false if not.
24914     */
24915    inRegion: function(node, node2, all, altRegion) {
24916        var region = {},
24917            r = altRegion || DOM.region(node),
24918            n = node2,
24919            off;
24920
24921        if (n.tagName) {
24922            region = DOM.region(n);
24923        } else if (Y.Lang.isObject(node2)) {
24924            region = node2;
24925        } else {
24926            return false;
24927        }
24928
24929        if (all) {
24930            return (
24931                r[LEFT]   >= region[LEFT]   &&
24932                r[RIGHT]  <= region[RIGHT]  &&
24933                r[TOP]    >= region[TOP]    &&
24934                r[BOTTOM] <= region[BOTTOM]  );
24935        } else {
24936            off = getOffsets(region, r);
24937            if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) {
24938                return true;
24939            } else {
24940                return false;
24941            }
24942
24943        }
24944    },
24945
24946    /**
24947     * Check if any part of this element is in the viewport
24948     * @method inViewportRegion
24949     * @for DOM
24950     * @param {HTMLElement} element The DOM element.
24951     * @param {Boolean} all Should all of the node be inside the region
24952     * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop)
24953     * @return {Boolean} True if in region, false if not.
24954     */
24955    inViewportRegion: function(node, all, altRegion) {
24956        return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion);
24957
24958    },
24959
24960    _getRegion: function(t, r, b, l) {
24961        var region = {};
24962
24963        region[TOP] = region[1] = t;
24964        region[LEFT] = region[0] = l;
24965        region[BOTTOM] = b;
24966        region[RIGHT] = r;
24967        region.width = region[RIGHT] - region[LEFT];
24968        region.height = region[BOTTOM] - region[TOP];
24969
24970        return region;
24971    },
24972
24973    /**
24974     * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left)
24975     * @method viewportRegion
24976     * @for DOM
24977     * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left)
24978     */
24979    viewportRegion: function(node) {
24980        node = node || Y.config.doc.documentElement;
24981        var ret = false,
24982            scrollX,
24983            scrollY;
24984
24985        if (node) {
24986            scrollX = DOM.docScrollX(node);
24987            scrollY = DOM.docScrollY(node);
24988
24989            ret = DOM._getRegion(scrollY, // top
24990                DOM.winWidth(node) + scrollX, // right
24991                scrollY + DOM.winHeight(node), // bottom
24992                scrollX); // left
24993        }
24994
24995        return ret;
24996    }
24997});
24998})(Y);
24999
25000
25001}, 'patched-v3.18.1', {"requires": ["dom-base", "dom-style"]});
25002
25003YUI.add('dom-style', function (Y, NAME) {
25004
25005/**
25006 * Add style management functionality to DOM.
25007 * @module dom
25008 * @submodule dom-style
25009 * @for DOM
25010 */
25011
25012var DOCUMENT_ELEMENT = 'documentElement',
25013    DEFAULT_VIEW = 'defaultView',
25014    OWNER_DOCUMENT = 'ownerDocument',
25015    STYLE = 'style',
25016    FLOAT = 'float',
25017    CSS_FLOAT = 'cssFloat',
25018    STYLE_FLOAT = 'styleFloat',
25019    TRANSPARENT = 'transparent',
25020    GET_COMPUTED_STYLE = 'getComputedStyle',
25021    GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
25022
25023    DOCUMENT = Y.config.doc,
25024
25025    Y_DOM = Y.DOM,
25026
25027    TRANSFORM,
25028    TRANSFORMORIGIN,
25029    VENDOR_TRANSFORM = [
25030        'WebkitTransform',
25031        'MozTransform',
25032        'OTransform',
25033        'msTransform',
25034        'transform'
25035    ],
25036
25037    re_unit = /width|height|top|left|right|bottom|margin|padding/i;
25038
25039Y.Array.each(VENDOR_TRANSFORM, function(val) {
25040    if (val in DOCUMENT[DOCUMENT_ELEMENT].style) {
25041        TRANSFORM = val;
25042        TRANSFORMORIGIN = val + "Origin";
25043    }
25044});
25045
25046Y.mix(Y_DOM, {
25047    DEFAULT_UNIT: 'px',
25048
25049    CUSTOM_STYLES: {
25050    },
25051
25052
25053    /**
25054     * Sets a style property for a given element.
25055     * @method setStyle
25056     * @param {HTMLElement} node The HTMLElement to apply the style to.
25057     * @param {String} att The style property to set.
25058     * @param {String|Number} val The value.
25059     * @param {Object} [style] The style node. Defaults to `node.style`.
25060     */
25061    setStyle: function(node, att, val, style) {
25062        style = style || node.style;
25063        var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES;
25064
25065        if (style) {
25066            if (val === null || val === '') { // normalize unsetting
25067                val = '';
25068            } else if (!isNaN(Number(val)) && re_unit.test(att)) { // number values may need a unit
25069                val += Y_DOM.DEFAULT_UNIT;
25070            }
25071
25072            if (att in CUSTOM_STYLES) {
25073                if (CUSTOM_STYLES[att].set) {
25074                    CUSTOM_STYLES[att].set(node, val, style);
25075                    return; // NOTE: return
25076                } else if (typeof CUSTOM_STYLES[att] === 'string') {
25077                    att = CUSTOM_STYLES[att];
25078                }
25079            } else if (att === '') { // unset inline styles
25080                att = 'cssText';
25081                val = '';
25082            }
25083            style[att] = val;
25084        }
25085    },
25086
25087    /**
25088     * Returns the current style value for the given property.
25089     * @method getStyle
25090     * @param {HTMLElement} node The HTMLElement to get the style from.
25091     * @param {String} att The style property to get.
25092     * @param {Object} [style] The style node. Defaults to `node.style`.
25093     */
25094    getStyle: function(node, att, style) {
25095        style = style || node.style;
25096        var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES,
25097            val = '';
25098
25099        if (style) {
25100            if (att in CUSTOM_STYLES) {
25101                if (CUSTOM_STYLES[att].get) {
25102                    return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
25103                } else if (typeof CUSTOM_STYLES[att] === 'string') {
25104                    att = CUSTOM_STYLES[att];
25105                }
25106            }
25107            val = style[att];
25108            if (val === '') { // TODO: is empty string sufficient?
25109                val = Y_DOM[GET_COMPUTED_STYLE](node, att);
25110            }
25111        }
25112
25113        return val;
25114    },
25115
25116    /**
25117     * Sets multiple style properties.
25118     * @method setStyles
25119     * @param {HTMLElement} node The HTMLElement to apply the styles to.
25120     * @param {Object} hash An object literal of property:value pairs.
25121     */
25122    setStyles: function(node, hash) {
25123        var style = node.style;
25124        Y.each(hash, function(v, n) {
25125            Y_DOM.setStyle(node, n, v, style);
25126        }, Y_DOM);
25127    },
25128
25129    /**
25130     * Returns the computed style for the given node.
25131     * @method getComputedStyle
25132     * @param {HTMLElement} node The HTMLElement to get the style from.
25133     * @param {String} att The style property to get.
25134     * @return {String} The computed value of the style property.
25135     */
25136    getComputedStyle: function(node, att) {
25137        var val = '',
25138            doc = node[OWNER_DOCUMENT],
25139            computed;
25140
25141        if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) {
25142            computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null);
25143            if (computed) { // FF may be null in some cases (ticket #2530548)
25144                val = computed[att];
25145            }
25146        }
25147        return val;
25148    }
25149});
25150
25151// normalize reserved word float alternatives ("cssFloat" or "styleFloat")
25152if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== undefined) {
25153    Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
25154} else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== undefined) {
25155    Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
25156}
25157
25158// safari converts transparent to rgba(), others use "transparent"
25159if (Y.UA.webkit) {
25160    Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
25161        var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
25162            val = view[GET_COMPUTED_STYLE](node, '')[att];
25163
25164        if (val === 'rgba(0, 0, 0, 0)') {
25165            val = TRANSPARENT;
25166        }
25167
25168        return val;
25169    };
25170
25171}
25172
25173Y.DOM._getAttrOffset = function(node, attr) {
25174    var val = Y.DOM[GET_COMPUTED_STYLE](node, attr),
25175        offsetParent = node.offsetParent,
25176        position,
25177        parentOffset,
25178        offset;
25179
25180    if (val === 'auto') {
25181        position = Y.DOM.getStyle(node, 'position');
25182        if (position === 'static' || position === 'relative') {
25183            val = 0;
25184        } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) {
25185            parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr];
25186            offset = node[GET_BOUNDING_CLIENT_RECT]()[attr];
25187            if (attr === 'left' || attr === 'top') {
25188                val = offset - parentOffset;
25189            } else {
25190                val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr];
25191            }
25192        }
25193    }
25194
25195    return val;
25196};
25197
25198Y.DOM._getOffset = function(node, dir) {
25199    var pos,
25200        xy = null,
25201        offset = {
25202            left: 'offsetLeft',
25203            right: 'offsetRight'
25204        },
25205        margins = {
25206            left: 'marginLeft',
25207            right: 'marginRight'
25208        },
25209        margin;
25210
25211    dir = dir || 'left';
25212
25213    if (node) {
25214        pos = Y_DOM.getStyle(node, 'position');
25215        margin = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, margins[dir]), 10);
25216        xy = [
25217            parseInt(Y_DOM[GET_COMPUTED_STYLE](node, dir), 10),
25218            parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10)
25219        ];
25220
25221        if ( isNaN(xy[0]) ) { // in case of 'auto'
25222            xy[0] = parseInt(Y_DOM.getStyle(node, dir), 10); // try inline
25223            if ( isNaN(xy[0]) ) { // default to offset value
25224                xy[0] = (pos === 'relative') ? 0 : (node[offset[dir]] - margin) || 0;
25225            }
25226        }
25227
25228        if ( isNaN(xy[1]) ) { // in case of 'auto'
25229            xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline
25230            if ( isNaN(xy[1]) ) { // default to offset value
25231                xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0;
25232            }
25233        }
25234    }
25235
25236    return xy;
25237
25238};
25239
25240if (TRANSFORM) {
25241    Y_DOM.CUSTOM_STYLES.transform = {
25242        set: function(node, val, style) {
25243            style[TRANSFORM] = val;
25244        },
25245
25246        get: function(node) {
25247            return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM);
25248        }
25249    };
25250
25251    Y_DOM.CUSTOM_STYLES.transformOrigin = {
25252        set: function(node, val, style) {
25253            style[TRANSFORMORIGIN] = val;
25254        },
25255
25256        get: function(node) {
25257            return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORMORIGIN);
25258        }
25259    };
25260}
25261
25262
25263}, 'patched-v3.18.1', {"requires": ["dom-base"]});
25264
25265YUI.add('event-base', function (Y, NAME) {
25266
25267/*
25268 * DOM event listener abstraction layer
25269 * @module event
25270 * @submodule event-base
25271 */
25272
25273/**
25274 * The domready event fires at the moment the browser's DOM is
25275 * usable. In most cases, this is before images are fully
25276 * downloaded, allowing you to provide a more responsive user
25277 * interface.
25278 *
25279 * In YUI 3, domready subscribers will be notified immediately if
25280 * that moment has already passed when the subscription is created.
25281 *
25282 * One exception is if the yui.js file is dynamically injected into
25283 * the page.  If this is done, you must tell the YUI instance that
25284 * you did this in order for DOMReady (and window load events) to
25285 * fire normally.  That configuration option is 'injected' -- set
25286 * it to true if the yui.js script is not included inline.
25287 *
25288 * This method is part of the 'event-ready' module, which is a
25289 * submodule of 'event'.
25290 *
25291 * @event domready
25292 * @for YUI
25293 */
25294Y.publish('domready', {
25295    fireOnce: true,
25296    async: true
25297});
25298
25299if (YUI.Env.DOMReady) {
25300    Y.fire('domready');
25301} else {
25302    Y.Do.before(function() { Y.fire('domready'); }, YUI.Env, '_ready');
25303}
25304
25305/**
25306 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
25307 * events.
25308 * @module event
25309 * @submodule event-base
25310 */
25311
25312/**
25313 * Wraps a DOM event, properties requiring browser abstraction are
25314 * fixed here.  Provids a security layer when required.
25315 * @class DOMEventFacade
25316 * @param ev {Event} the DOM event
25317 * @param currentTarget {HTMLElement} the element the listener was attached to
25318 * @param wrapper {CustomEvent} the custom event wrapper for this DOM event
25319 */
25320
25321    var ua = Y.UA,
25322
25323    EMPTY = {},
25324
25325    /**
25326     * webkit key remapping required for Safari < 3.1
25327     * @property webkitKeymap
25328     * @private
25329     */
25330    webkitKeymap = {
25331        63232: 38, // up
25332        63233: 40, // down
25333        63234: 37, // left
25334        63235: 39, // right
25335        63276: 33, // page up
25336        63277: 34, // page down
25337        25:     9, // SHIFT-TAB (Safari provides a different key code in
25338                   // this case, even though the shiftKey modifier is set)
25339        63272: 46, // delete
25340        63273: 36, // home
25341        63275: 35  // end
25342    },
25343
25344    /**
25345     * Returns a wrapped node.  Intended to be used on event targets,
25346     * so it will return the node's parent if the target is a text
25347     * node.
25348     *
25349     * If accessing a property of the node throws an error, this is
25350     * probably the anonymous div wrapper Gecko adds inside text
25351     * nodes.  This likely will only occur when attempting to access
25352     * the relatedTarget.  In this case, we now return null because
25353     * the anonymous div is completely useless and we do not know
25354     * what the related target was because we can't even get to
25355     * the element's parent node.
25356     *
25357     * @method resolve
25358     * @private
25359     */
25360    resolve = function(n) {
25361        if (!n) {
25362            return n;
25363        }
25364        try {
25365            if (n && 3 == n.nodeType) {
25366                n = n.parentNode;
25367            }
25368        } catch(e) {
25369            return null;
25370        }
25371
25372        return Y.one(n);
25373    },
25374
25375    DOMEventFacade = function(ev, currentTarget, wrapper) {
25376        this._event = ev;
25377        this._currentTarget = currentTarget;
25378        this._wrapper = wrapper || EMPTY;
25379
25380        // if not lazy init
25381        this.init();
25382    };
25383
25384Y.extend(DOMEventFacade, Object, {
25385
25386    init: function() {
25387
25388        var e = this._event,
25389            overrides = this._wrapper.overrides,
25390            x = e.pageX,
25391            y = e.pageY,
25392            c,
25393            currentTarget = this._currentTarget;
25394
25395        this.altKey   = e.altKey;
25396        this.ctrlKey  = e.ctrlKey;
25397        this.metaKey  = e.metaKey;
25398        this.shiftKey = e.shiftKey;
25399        this.type     = (overrides && overrides.type) || e.type;
25400        this.clientX  = e.clientX;
25401        this.clientY  = e.clientY;
25402
25403        this.pageX = x;
25404        this.pageY = y;
25405
25406        // charCode is unknown in keyup, keydown. keyCode is unknown in keypress.
25407        // FF 3.6 - 8+? pass 0 for keyCode in keypress events.
25408        // Webkit, FF 3.6-8+?, and IE9+? pass 0 for charCode in keydown, keyup.
25409        // Webkit and IE9+? duplicate charCode in keyCode.
25410        // Opera never sets charCode, always keyCode (though with the charCode).
25411        // IE6-8 don't set charCode or which.
25412        // All browsers other than IE6-8 set which=keyCode in keydown, keyup, and
25413        // which=charCode in keypress.
25414        //
25415        // Moral of the story: (e.which || e.keyCode) will always return the
25416        // known code for that key event phase. e.keyCode is often different in
25417        // keypress from keydown and keyup.
25418        c = e.keyCode || e.charCode;
25419
25420        if (ua.webkit && (c in webkitKeymap)) {
25421            c = webkitKeymap[c];
25422        }
25423
25424        this.keyCode = c;
25425        this.charCode = c;
25426        // Fill in e.which for IE - implementers should always use this over
25427        // e.keyCode or e.charCode.
25428        this.which = e.which || e.charCode || c;
25429        // this.button = e.button;
25430        this.button = this.which;
25431
25432        this.target = resolve(e.target);
25433        this.currentTarget = resolve(currentTarget);
25434        this.relatedTarget = resolve(e.relatedTarget);
25435
25436        if (e.type == "mousewheel" || e.type == "DOMMouseScroll") {
25437            this.wheelDelta = (e.detail) ? (e.detail * -1) : Math.round(e.wheelDelta / 80) || ((e.wheelDelta < 0) ? -1 : 1);
25438        }
25439
25440        if (this._touch) {
25441            this._touch(e, currentTarget, this._wrapper);
25442        }
25443    },
25444
25445    stopPropagation: function() {
25446        this._event.stopPropagation();
25447        this._wrapper.stopped = 1;
25448        this.stopped = 1;
25449    },
25450
25451    stopImmediatePropagation: function() {
25452        var e = this._event;
25453        if (e.stopImmediatePropagation) {
25454            e.stopImmediatePropagation();
25455        } else {
25456            this.stopPropagation();
25457        }
25458        this._wrapper.stopped = 2;
25459        this.stopped = 2;
25460    },
25461
25462    preventDefault: function(returnValue) {
25463        var e = this._event;
25464        e.preventDefault();
25465        if (returnValue) {
25466            e.returnValue = returnValue;
25467        }
25468        this._wrapper.prevented = 1;
25469        this.prevented = 1;
25470    },
25471
25472    halt: function(immediate) {
25473        if (immediate) {
25474            this.stopImmediatePropagation();
25475        } else {
25476            this.stopPropagation();
25477        }
25478
25479        this.preventDefault();
25480    }
25481
25482});
25483
25484DOMEventFacade.resolve = resolve;
25485Y.DOM2EventFacade = DOMEventFacade;
25486Y.DOMEventFacade = DOMEventFacade;
25487
25488    /**
25489     * The native event
25490     * @property _event
25491     * @type {DOMEvent}
25492     * @private
25493     */
25494
25495    /**
25496    The name of the event (e.g. "click")
25497
25498    @property type
25499    @type {String}
25500    **/
25501
25502    /**
25503    `true` if the "alt" or "option" key is pressed.
25504
25505    @property altKey
25506    @type {Boolean}
25507    **/
25508
25509    /**
25510    `true` if the shift key is pressed.
25511
25512    @property shiftKey
25513    @type {Boolean}
25514    **/
25515
25516    /**
25517    `true` if the "Windows" key on a Windows keyboard, "command" key on an
25518    Apple keyboard, or "meta" key on other keyboards is pressed.
25519
25520    @property metaKey
25521    @type {Boolean}
25522    **/
25523
25524    /**
25525    `true` if the "Ctrl" or "control" key is pressed.
25526
25527    @property ctrlKey
25528    @type {Boolean}
25529    **/
25530
25531    /**
25532     * The X location of the event on the page (including scroll)
25533     * @property pageX
25534     * @type {Number}
25535     */
25536
25537    /**
25538     * The Y location of the event on the page (including scroll)
25539     * @property pageY
25540     * @type {Number}
25541     */
25542
25543    /**
25544     * The X location of the event in the viewport
25545     * @property clientX
25546     * @type {Number}
25547     */
25548
25549    /**
25550     * The Y location of the event in the viewport
25551     * @property clientY
25552     * @type {Number}
25553     */
25554
25555    /**
25556     * The keyCode for key events.  Uses charCode if keyCode is not available
25557     * @property keyCode
25558     * @type {Number}
25559     */
25560
25561    /**
25562     * The charCode for key events.  Same as keyCode
25563     * @property charCode
25564     * @type {Number}
25565     */
25566
25567    /**
25568     * The button that was pushed. 1 for left click, 2 for middle click, 3 for
25569     * right click.  This is only reliably populated on `mouseup` events.
25570     * @property button
25571     * @type {Number}
25572     */
25573
25574    /**
25575     * The button that was pushed.  Same as button.
25576     * @property which
25577     * @type {Number}
25578     */
25579
25580    /**
25581     * Node reference for the targeted element
25582     * @property target
25583     * @type {Node}
25584     */
25585
25586    /**
25587     * Node reference for the element that the listener was attached to.
25588     * @property currentTarget
25589     * @type {Node}
25590     */
25591
25592    /**
25593     * Node reference to the relatedTarget
25594     * @property relatedTarget
25595     * @type {Node}
25596     */
25597
25598    /**
25599     * Number representing the direction and velocity of the movement of the mousewheel.
25600     * Negative is down, the higher the number, the faster.  Applies to the mousewheel event.
25601     * @property wheelDelta
25602     * @type {Number}
25603     */
25604
25605    /**
25606     * Stops the propagation to the next bubble target
25607     * @method stopPropagation
25608     */
25609
25610    /**
25611     * Stops the propagation to the next bubble target and
25612     * prevents any additional listeners from being exectued
25613     * on the current target.
25614     * @method stopImmediatePropagation
25615     */
25616
25617    /**
25618     * Prevents the event's default behavior
25619     * @method preventDefault
25620     * @param returnValue {string} sets the returnValue of the event to this value
25621     * (rather than the default false value).  This can be used to add a customized
25622     * confirmation query to the beforeunload event).
25623     */
25624
25625    /**
25626     * Stops the event propagation and prevents the default
25627     * event behavior.
25628     * @method halt
25629     * @param immediate {boolean} if true additional listeners
25630     * on the current target will not be executed
25631     */
25632(function() {
25633
25634/**
25635 * The event utility provides functions to add and remove event listeners,
25636 * event cleansing.  It also tries to automatically remove listeners it
25637 * registers during the unload event.
25638 * @module event
25639 * @main event
25640 * @submodule event-base
25641 */
25642
25643/**
25644 * The event utility provides functions to add and remove event listeners,
25645 * event cleansing.  It also tries to automatically remove listeners it
25646 * registers during the unload event.
25647 *
25648 * @class Event
25649 * @static
25650 */
25651
25652Y.Env.evt.dom_wrappers = {};
25653Y.Env.evt.dom_map = {};
25654
25655var _eventenv = Y.Env.evt,
25656    config = Y.config,
25657    win = config.win,
25658    add = YUI.Env.add,
25659    remove = YUI.Env.remove,
25660
25661    onLoad = function() {
25662        YUI.Env.windowLoaded = true;
25663        Y.Event._load();
25664        remove(win, "load", onLoad);
25665    },
25666
25667    onUnload = function() {
25668        Y.Event._unload();
25669    },
25670
25671    EVENT_READY = 'domready',
25672
25673    COMPAT_ARG = '~yui|2|compat~',
25674
25675    shouldIterate = function(o) {
25676        try {
25677            // TODO: See if there's a more performant way to return true early on this, for the common case
25678            return (o && typeof o !== "string" && Y.Lang.isNumber(o.length) && !o.tagName && !Y.DOM.isWindow(o));
25679        } catch(ex) {
25680            return false;
25681        }
25682    },
25683
25684    // aliases to support DOM event subscription clean up when the last
25685    // subscriber is detached. deleteAndClean overrides the DOM event's wrapper
25686    // CustomEvent _delete method.
25687    _ceProtoDelete = Y.CustomEvent.prototype._delete,
25688    _deleteAndClean = function(s) {
25689        var ret = _ceProtoDelete.apply(this, arguments);
25690
25691        if (!this.hasSubs()) {
25692            Y.Event._clean(this);
25693        }
25694
25695        return ret;
25696    },
25697
25698Event = function() {
25699
25700    /**
25701     * True after the onload event has fired
25702     * @property _loadComplete
25703     * @type boolean
25704     * @static
25705     * @private
25706     */
25707    var _loadComplete =  false,
25708
25709    /**
25710     * The number of times to poll after window.onload.  This number is
25711     * increased if additional late-bound handlers are requested after
25712     * the page load.
25713     * @property _retryCount
25714     * @static
25715     * @private
25716     */
25717    _retryCount = 0,
25718
25719    /**
25720     * onAvailable listeners
25721     * @property _avail
25722     * @static
25723     * @private
25724     */
25725    _avail = [],
25726
25727    /**
25728     * Custom event wrappers for DOM events.  Key is
25729     * 'event:' + Element uid stamp + event type
25730     * @property _wrappers
25731     * @type CustomEvent
25732     * @static
25733     * @private
25734     */
25735    _wrappers = _eventenv.dom_wrappers,
25736
25737    _windowLoadKey = null,
25738
25739    /**
25740     * Custom event wrapper map DOM events.  Key is
25741     * Element uid stamp.  Each item is a hash of custom event
25742     * wrappers as provided in the _wrappers collection.  This
25743     * provides the infrastructure for getListeners.
25744     * @property _el_events
25745     * @static
25746     * @private
25747     */
25748    _el_events = _eventenv.dom_map;
25749
25750    return {
25751
25752        /**
25753         * The number of times we should look for elements that are not
25754         * in the DOM at the time the event is requested after the document
25755         * has been loaded.  The default is 1000@amp;40 ms, so it will poll
25756         * for 40 seconds or until all outstanding handlers are bound
25757         * (whichever comes first).
25758         * @property POLL_RETRYS
25759         * @type int
25760         * @static
25761         * @final
25762         */
25763        POLL_RETRYS: 1000,
25764
25765        /**
25766         * The poll interval in milliseconds
25767         * @property POLL_INTERVAL
25768         * @type int
25769         * @static
25770         * @final
25771         */
25772        POLL_INTERVAL: 40,
25773
25774        /**
25775         * addListener/removeListener can throw errors in unexpected scenarios.
25776         * These errors are suppressed, the method returns false, and this property
25777         * is set
25778         * @property lastError
25779         * @static
25780         * @type Error
25781         */
25782        lastError: null,
25783
25784
25785        /**
25786         * poll handle
25787         * @property _interval
25788         * @static
25789         * @private
25790         */
25791        _interval: null,
25792
25793        /**
25794         * document readystate poll handle
25795         * @property _dri
25796         * @static
25797         * @private
25798         */
25799         _dri: null,
25800
25801        /**
25802         * True when the document is initially usable
25803         * @property DOMReady
25804         * @type boolean
25805         * @static
25806         */
25807        DOMReady: false,
25808
25809        /**
25810         * @method startInterval
25811         * @static
25812         * @private
25813         */
25814        startInterval: function() {
25815            if (!Event._interval) {
25816Event._interval = setInterval(Event._poll, Event.POLL_INTERVAL);
25817            }
25818        },
25819
25820        /**
25821         * Executes the supplied callback when the item with the supplied
25822         * id is found.  This is meant to be used to execute behavior as
25823         * soon as possible as the page loads.  If you use this after the
25824         * initial page load it will poll for a fixed time for the element.
25825         * The number of times it will poll and the frequency are
25826         * configurable.  By default it will poll for 10 seconds.
25827         *
25828         * <p>The callback is executed with a single parameter:
25829         * the custom object parameter, if provided.</p>
25830         *
25831         * @method onAvailable
25832         *
25833         * @param {string||string[]}   id the id of the element, or an array
25834         * of ids to look for.
25835         * @param {function} fn what to execute when the element is found.
25836         * @param {object}   p_obj an optional object to be passed back as
25837         *                   a parameter to fn.
25838         * @param {boolean|object}  p_override If set to true, fn will execute
25839         *                   in the context of p_obj, if set to an object it
25840         *                   will execute in the context of that object
25841         * @param checkContent {boolean} check child node readiness (onContentReady)
25842         * @static
25843         * @deprecated Use Y.on("available")
25844         */
25845        // @TODO fix arguments
25846        onAvailable: function(id, fn, p_obj, p_override, checkContent, compat) {
25847
25848            var a = Y.Array(id), i, availHandle;
25849
25850            for (i=0; i<a.length; i=i+1) {
25851                _avail.push({
25852                    id:         a[i],
25853                    fn:         fn,
25854                    obj:        p_obj,
25855                    override:   p_override,
25856                    checkReady: checkContent,
25857                    compat:     compat
25858                });
25859            }
25860            _retryCount = this.POLL_RETRYS;
25861
25862            // We want the first test to be immediate, but async
25863            setTimeout(Event._poll, 0);
25864
25865            availHandle = new Y.EventHandle({
25866
25867                _delete: function() {
25868                    // set by the event system for lazy DOM listeners
25869                    if (availHandle.handle) {
25870                        availHandle.handle.detach();
25871                        return;
25872                    }
25873
25874                    var i, j;
25875
25876                    // otherwise try to remove the onAvailable listener(s)
25877                    for (i = 0; i < a.length; i++) {
25878                        for (j = 0; j < _avail.length; j++) {
25879                            if (a[i] === _avail[j].id) {
25880                                _avail.splice(j, 1);
25881                            }
25882                        }
25883                    }
25884                }
25885
25886            });
25887
25888            return availHandle;
25889        },
25890
25891        /**
25892         * Works the same way as onAvailable, but additionally checks the
25893         * state of sibling elements to determine if the content of the
25894         * available element is safe to modify.
25895         *
25896         * <p>The callback is executed with a single parameter:
25897         * the custom object parameter, if provided.</p>
25898         *
25899         * @method onContentReady
25900         *
25901         * @param {string}   id the id of the element to look for.
25902         * @param {function} fn what to execute when the element is ready.
25903         * @param {object}   obj an optional object to be passed back as
25904         *                   a parameter to fn.
25905         * @param {boolean|object}  override If set to true, fn will execute
25906         *                   in the context of p_obj.  If an object, fn will
25907         *                   exectute in the context of that object
25908         *
25909         * @static
25910         * @deprecated Use Y.on("contentready")
25911         */
25912        // @TODO fix arguments
25913        onContentReady: function(id, fn, obj, override, compat) {
25914            return Event.onAvailable(id, fn, obj, override, true, compat);
25915        },
25916
25917        /**
25918         * Adds an event listener
25919         *
25920         * @method attach
25921         *
25922         * @param {String}   type     The type of event to append
25923         * @param {Function} fn        The method the event invokes
25924         * @param {String|HTMLElement|Array|NodeList} el An id, an element
25925         *  reference, or a collection of ids and/or elements to assign the
25926         *  listener to.
25927         * @param {Object}   context optional context object
25928         * @param {Boolean|object}  args 0..n arguments to pass to the callback
25929         * @return {EventHandle} an object to that can be used to detach the listener
25930         *
25931         * @static
25932         */
25933
25934        attach: function(type, fn, el, context) {
25935            return Event._attach(Y.Array(arguments, 0, true));
25936        },
25937
25938        _createWrapper: function (el, type, capture, compat, facade) {
25939
25940            var cewrapper,
25941                ek  = Y.stamp(el),
25942                key = 'event:' + ek + type;
25943
25944            if (false === facade) {
25945                key += 'native';
25946            }
25947            if (capture) {
25948                key += 'capture';
25949            }
25950
25951
25952            cewrapper = _wrappers[key];
25953
25954
25955            if (!cewrapper) {
25956                // create CE wrapper
25957                cewrapper = Y.publish(key, {
25958                    silent: true,
25959                    bubbles: false,
25960                    emitFacade:false,
25961                    contextFn: function() {
25962                        if (compat) {
25963                            return cewrapper.el;
25964                        } else {
25965                            cewrapper.nodeRef = cewrapper.nodeRef || Y.one(cewrapper.el);
25966                            return cewrapper.nodeRef;
25967                        }
25968                    }
25969                });
25970
25971                cewrapper.overrides = {};
25972
25973                // for later removeListener calls
25974                cewrapper.el = el;
25975                cewrapper.key = key;
25976                cewrapper.domkey = ek;
25977                cewrapper.type = type;
25978                cewrapper.fn = function(e) {
25979                    cewrapper.fire(Event.getEvent(e, el, (compat || (false === facade))));
25980                };
25981                cewrapper.capture = capture;
25982
25983                if (el == win && type == "load") {
25984                    // window load happens once
25985                    cewrapper.fireOnce = true;
25986                    _windowLoadKey = key;
25987                }
25988                cewrapper._delete = _deleteAndClean;
25989
25990                _wrappers[key] = cewrapper;
25991                _el_events[ek] = _el_events[ek] || {};
25992                _el_events[ek][key] = cewrapper;
25993
25994                add(el, type, cewrapper.fn, capture);
25995            }
25996
25997            return cewrapper;
25998
25999        },
26000
26001        _attach: function(args, conf) {
26002
26003            var compat,
26004                handles, oEl, cewrapper, context,
26005                fireNow = false, ret,
26006                type = args[0],
26007                fn = args[1],
26008                el = args[2] || win,
26009                facade = conf && conf.facade,
26010                capture = conf && conf.capture,
26011                overrides = conf && conf.overrides;
26012
26013            if (args[args.length-1] === COMPAT_ARG) {
26014                compat = true;
26015            }
26016
26017            if (!fn || !fn.call) {
26018                return false;
26019            }
26020
26021            // The el argument can be an array of elements or element ids.
26022            if (shouldIterate(el)) {
26023
26024                handles=[];
26025
26026                Y.each(el, function(v, k) {
26027                    args[2] = v;
26028                    handles.push(Event._attach(args.slice(), conf));
26029                });
26030
26031                // return (handles.length === 1) ? handles[0] : handles;
26032                return new Y.EventHandle(handles);
26033
26034            // If the el argument is a string, we assume it is
26035            // actually the id of the element.  If the page is loaded
26036            // we convert el to the actual element, otherwise we
26037            // defer attaching the event until the element is
26038            // ready
26039            } else if (Y.Lang.isString(el)) {
26040
26041                // oEl = (compat) ? Y.DOM.byId(el) : Y.Selector.query(el);
26042
26043                if (compat) {
26044                    oEl = Y.DOM.byId(el);
26045                } else {
26046
26047                    oEl = Y.Selector.query(el);
26048
26049                    switch (oEl.length) {
26050                        case 0:
26051                            oEl = null;
26052                            break;
26053                        case 1:
26054                            oEl = oEl[0];
26055                            break;
26056                        default:
26057                            args[2] = oEl;
26058                            return Event._attach(args, conf);
26059                    }
26060                }
26061
26062                if (oEl) {
26063
26064                    el = oEl;
26065
26066                // Not found = defer adding the event until the element is available
26067                } else {
26068
26069                    ret = Event.onAvailable(el, function() {
26070
26071                        ret.handle = Event._attach(args, conf);
26072
26073                    }, Event, true, false, compat);
26074
26075                    return ret;
26076
26077                }
26078            }
26079
26080            // Element should be an html element or node
26081            if (!el) {
26082                return false;
26083            }
26084
26085            if (Y.Node && Y.instanceOf(el, Y.Node)) {
26086                el = Y.Node.getDOMNode(el);
26087            }
26088
26089            cewrapper = Event._createWrapper(el, type, capture, compat, facade);
26090            if (overrides) {
26091                Y.mix(cewrapper.overrides, overrides);
26092            }
26093
26094            if (el == win && type == "load") {
26095
26096                // if the load is complete, fire immediately.
26097                // all subscribers, including the current one
26098                // will be notified.
26099                if (YUI.Env.windowLoaded) {
26100                    fireNow = true;
26101                }
26102            }
26103
26104            if (compat) {
26105                args.pop();
26106            }
26107
26108            context = args[3];
26109
26110            // set context to the Node if not specified
26111            // ret = cewrapper.on.apply(cewrapper, trimmedArgs);
26112            ret = cewrapper._on(fn, context, (args.length > 4) ? args.slice(4) : null);
26113
26114            if (fireNow) {
26115                cewrapper.fire();
26116            }
26117
26118            return ret;
26119
26120        },
26121
26122        /**
26123         * Removes an event listener.  Supports the signature the event was bound
26124         * with, but the preferred way to remove listeners is using the handle
26125         * that is returned when using Y.on
26126         *
26127         * @method detach
26128         *
26129         * @param {String} type the type of event to remove.
26130         * @param {Function} fn the method the event invokes.  If fn is
26131         * undefined, then all event handlers for the type of event are
26132         * removed.
26133         * @param {String|HTMLElement|Array|NodeList|EventHandle} el An
26134         * event handle, an id, an element reference, or a collection
26135         * of ids and/or elements to remove the listener from.
26136         * @return {boolean} true if the unbind was successful, false otherwise.
26137         * @static
26138         */
26139        detach: function(type, fn, el, obj) {
26140
26141            var args=Y.Array(arguments, 0, true), compat, l, ok, i,
26142                id, ce;
26143
26144            if (args[args.length-1] === COMPAT_ARG) {
26145                compat = true;
26146                // args.pop();
26147            }
26148
26149            if (type && type.detach) {
26150                return type.detach();
26151            }
26152
26153            // The el argument can be a string
26154            if (typeof el == "string") {
26155
26156                // el = (compat) ? Y.DOM.byId(el) : Y.all(el);
26157                if (compat) {
26158                    el = Y.DOM.byId(el);
26159                } else {
26160                    el = Y.Selector.query(el);
26161                    l = el.length;
26162                    if (l < 1) {
26163                        el = null;
26164                    } else if (l == 1) {
26165                        el = el[0];
26166                    }
26167                }
26168                // return Event.detach.apply(Event, args);
26169            }
26170
26171            if (!el) {
26172                return false;
26173            }
26174
26175            if (el.detach) {
26176                args.splice(2, 1);
26177                return el.detach.apply(el, args);
26178            // The el argument can be an array of elements or element ids.
26179            } else if (shouldIterate(el)) {
26180                ok = true;
26181                for (i=0, l=el.length; i<l; ++i) {
26182                    args[2] = el[i];
26183                    ok = ( Y.Event.detach.apply(Y.Event, args) && ok );
26184                }
26185
26186                return ok;
26187            }
26188
26189            if (!type || !fn || !fn.call) {
26190                return Event.purgeElement(el, false, type);
26191            }
26192
26193            id = 'event:' + Y.stamp(el) + type;
26194            ce = _wrappers[id];
26195
26196            if (ce) {
26197                return ce.detach(fn);
26198            } else {
26199                return false;
26200            }
26201
26202        },
26203
26204        /**
26205         * Finds the event in the window object, the caller's arguments, or
26206         * in the arguments of another method in the callstack.  This is
26207         * executed automatically for events registered through the event
26208         * manager, so the implementer should not normally need to execute
26209         * this function at all.
26210         * @method getEvent
26211         * @param {Event} e the event parameter from the handler
26212         * @param {HTMLElement} el the element the listener was attached to
26213         * @return {Event} the event
26214         * @static
26215         */
26216        getEvent: function(e, el, noFacade) {
26217            var ev = e || win.event;
26218
26219            return (noFacade) ? ev :
26220                new Y.DOMEventFacade(ev, el, _wrappers['event:' + Y.stamp(el) + e.type]);
26221        },
26222
26223        /**
26224         * Generates an unique ID for the element if it does not already
26225         * have one.
26226         * @method generateId
26227         * @param el the element to create the id for
26228         * @return {string} the resulting id of the element
26229         * @static
26230         */
26231        generateId: function(el) {
26232            return Y.DOM.generateID(el);
26233        },
26234
26235        /**
26236         * We want to be able to use getElementsByTagName as a collection
26237         * to attach a group of events to.  Unfortunately, different
26238         * browsers return different types of collections.  This function
26239         * tests to determine if the object is array-like.  It will also
26240         * fail if the object is an array, but is empty.
26241         * @method _isValidCollection
26242         * @param o the object to test
26243         * @return {boolean} true if the object is array-like and populated
26244         * @deprecated was not meant to be used directly
26245         * @static
26246         * @private
26247         */
26248        _isValidCollection: shouldIterate,
26249
26250        /**
26251         * hook up any deferred listeners
26252         * @method _load
26253         * @static
26254         * @private
26255         */
26256        _load: function(e) {
26257            if (!_loadComplete) {
26258                _loadComplete = true;
26259
26260                // Just in case DOMReady did not go off for some reason
26261                // E._ready();
26262                if (Y.fire) {
26263                    Y.fire(EVENT_READY);
26264                }
26265
26266                // Available elements may not have been detected before the
26267                // window load event fires. Try to find them now so that the
26268                // the user is more likely to get the onAvailable notifications
26269                // before the window load notification
26270                Event._poll();
26271            }
26272        },
26273
26274        /**
26275         * Polling function that runs before the onload event fires,
26276         * attempting to attach to DOM Nodes as soon as they are
26277         * available
26278         * @method _poll
26279         * @static
26280         * @private
26281         */
26282        _poll: function() {
26283            if (Event.locked) {
26284                return;
26285            }
26286
26287            if (Y.UA.ie && !YUI.Env.DOMReady) {
26288                // Hold off if DOMReady has not fired and check current
26289                // readyState to protect against the IE operation aborted
26290                // issue.
26291                Event.startInterval();
26292                return;
26293            }
26294
26295            Event.locked = true;
26296
26297            // keep trying until after the page is loaded.  We need to
26298            // check the page load state prior to trying to bind the
26299            // elements so that we can be certain all elements have been
26300            // tested appropriately
26301            var i, len, item, el, notAvail, executeItem,
26302                tryAgain = !_loadComplete;
26303
26304            if (!tryAgain) {
26305                tryAgain = (_retryCount > 0);
26306            }
26307
26308            // onAvailable
26309            notAvail = [];
26310
26311            executeItem = function (el, item) {
26312                var context, ov = item.override;
26313                try {
26314                    if (item.compat) {
26315                        if (item.override) {
26316                            if (ov === true) {
26317                                context = item.obj;
26318                            } else {
26319                                context = ov;
26320                            }
26321                        } else {
26322                            context = el;
26323                        }
26324                        item.fn.call(context, item.obj);
26325                    } else {
26326                        context = item.obj || Y.one(el);
26327                        item.fn.apply(context, (Y.Lang.isArray(ov)) ? ov : []);
26328                    }
26329                } catch (e) {
26330                }
26331            };
26332
26333            // onAvailable
26334            for (i=0,len=_avail.length; i<len; ++i) {
26335                item = _avail[i];
26336                if (item && !item.checkReady) {
26337
26338                    // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id);
26339                    el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true);
26340
26341                    if (el) {
26342                        executeItem(el, item);
26343                        _avail[i] = null;
26344                    } else {
26345                        notAvail.push(item);
26346                    }
26347                }
26348            }
26349
26350            // onContentReady
26351            for (i=0,len=_avail.length; i<len; ++i) {
26352                item = _avail[i];
26353                if (item && item.checkReady) {
26354
26355                    // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id);
26356                    el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true);
26357
26358                    if (el) {
26359                        // The element is available, but not necessarily ready
26360                        // @todo should we test parentNode.nextSibling?
26361                        if (_loadComplete || (el.get && el.get('nextSibling')) || el.nextSibling) {
26362                            executeItem(el, item);
26363                            _avail[i] = null;
26364                        }
26365                    } else {
26366                        notAvail.push(item);
26367                    }
26368                }
26369            }
26370
26371            _retryCount = (notAvail.length === 0) ? 0 : _retryCount - 1;
26372
26373            if (tryAgain) {
26374                // we may need to strip the nulled out items here
26375                Event.startInterval();
26376            } else {
26377                clearInterval(Event._interval);
26378                Event._interval = null;
26379            }
26380
26381            Event.locked = false;
26382
26383            return;
26384
26385        },
26386
26387        /**
26388         * Removes all listeners attached to the given element via addListener.
26389         * Optionally, the node's children can also be purged.
26390         * Optionally, you can specify a specific type of event to remove.
26391         * @method purgeElement
26392         * @param {HTMLElement} el the element to purge
26393         * @param {boolean} recurse recursively purge this element's children
26394         * as well.  Use with caution.
26395         * @param {string} type optional type of listener to purge. If
26396         * left out, all listeners will be removed
26397         * @static
26398         */
26399        purgeElement: function(el, recurse, type) {
26400            // var oEl = (Y.Lang.isString(el)) ? Y.one(el) : el,
26401            var oEl = (Y.Lang.isString(el)) ?  Y.Selector.query(el, null, true) : el,
26402                lis = Event.getListeners(oEl, type), i, len, children, child;
26403
26404            if (recurse && oEl) {
26405                lis = lis || [];
26406                children = Y.Selector.query('*', oEl);
26407                len = children.length;
26408                for (i = 0; i < len; ++i) {
26409                    child = Event.getListeners(children[i], type);
26410                    if (child) {
26411                        lis = lis.concat(child);
26412                    }
26413                }
26414            }
26415
26416            if (lis) {
26417                for (i = 0, len = lis.length; i < len; ++i) {
26418                    lis[i].detachAll();
26419                }
26420            }
26421
26422        },
26423
26424        /**
26425         * Removes all object references and the DOM proxy subscription for
26426         * a given event for a DOM node.
26427         *
26428         * @method _clean
26429         * @param wrapper {CustomEvent} Custom event proxy for the DOM
26430         *                  subscription
26431         * @private
26432         * @static
26433         * @since 3.4.0
26434         */
26435        _clean: function (wrapper) {
26436            var key    = wrapper.key,
26437                domkey = wrapper.domkey;
26438
26439            remove(wrapper.el, wrapper.type, wrapper.fn, wrapper.capture);
26440            delete _wrappers[key];
26441            delete Y._yuievt.events[key];
26442            if (_el_events[domkey]) {
26443                delete _el_events[domkey][key];
26444                if (!Y.Object.size(_el_events[domkey])) {
26445                    delete _el_events[domkey];
26446                }
26447            }
26448        },
26449
26450        /**
26451         * Returns all listeners attached to the given element via addListener.
26452         * Optionally, you can specify a specific type of event to return.
26453         * @method getListeners
26454         * @param el {HTMLElement|string} the element or element id to inspect
26455         * @param type {string} optional type of listener to return. If
26456         * left out, all listeners will be returned
26457         * @return {CustomEvent} the custom event wrapper for the DOM event(s)
26458         * @static
26459         */
26460        getListeners: function(el, type) {
26461            var ek = Y.stamp(el, true), evts = _el_events[ek],
26462                results=[] , key = (type) ? 'event:' + ek + type : null,
26463                adapters = _eventenv.plugins;
26464
26465            if (!evts) {
26466                return null;
26467            }
26468
26469            if (key) {
26470                // look for synthetic events
26471                if (adapters[type] && adapters[type].eventDef) {
26472                    key += '_synth';
26473                }
26474
26475                if (evts[key]) {
26476                    results.push(evts[key]);
26477                }
26478
26479                // get native events as well
26480                key += 'native';
26481                if (evts[key]) {
26482                    results.push(evts[key]);
26483                }
26484
26485            } else {
26486                Y.each(evts, function(v, k) {
26487                    results.push(v);
26488                });
26489            }
26490
26491            return (results.length) ? results : null;
26492        },
26493
26494        /**
26495         * Removes all listeners registered by pe.event.  Called
26496         * automatically during the unload event.
26497         * @method _unload
26498         * @static
26499         * @private
26500         */
26501        _unload: function(e) {
26502            Y.each(_wrappers, function(v, k) {
26503                if (v.type == 'unload') {
26504                    v.fire(e);
26505                }
26506                v.detachAll();
26507            });
26508            remove(win, "unload", onUnload);
26509        },
26510
26511        /**
26512         * Adds a DOM event directly without the caching, cleanup, context adj, etc
26513         *
26514         * @method nativeAdd
26515         * @param {HTMLElement} el      the element to bind the handler to
26516         * @param {string}      type   the type of event handler
26517         * @param {function}    fn      the callback to invoke
26518         * @param {Boolean}      capture capture or bubble phase
26519         * @static
26520         * @private
26521         */
26522        nativeAdd: add,
26523
26524        /**
26525         * Basic remove listener
26526         *
26527         * @method nativeRemove
26528         * @param {HTMLElement} el      the element to bind the handler to
26529         * @param {string}      type   the type of event handler
26530         * @param {function}    fn      the callback to invoke
26531         * @param {Boolean}      capture capture or bubble phase
26532         * @static
26533         * @private
26534         */
26535        nativeRemove: remove
26536    };
26537
26538}();
26539
26540Y.Event = Event;
26541
26542if (config.injected || YUI.Env.windowLoaded) {
26543    onLoad();
26544} else {
26545    add(win, "load", onLoad);
26546}
26547
26548// Process onAvailable/onContentReady items when when the DOM is ready in IE
26549if (Y.UA.ie) {
26550    Y.on(EVENT_READY, Event._poll);
26551
26552    // In IE6 and below, detach event handlers when the page is unloaded in
26553    // order to try and prevent cross-page memory leaks. This isn't done in
26554    // other browsers because a) it's not necessary, and b) it breaks the
26555    // back/forward cache.
26556    if (Y.UA.ie < 7) {
26557        try {
26558            add(win, "unload", onUnload);
26559        } catch(e) {
26560        }
26561    }
26562}
26563
26564Event.Custom = Y.CustomEvent;
26565Event.Subscriber = Y.Subscriber;
26566Event.Target = Y.EventTarget;
26567Event.Handle = Y.EventHandle;
26568Event.Facade = Y.EventFacade;
26569
26570Event._poll();
26571
26572}());
26573
26574/**
26575 * DOM event listener abstraction layer
26576 * @module event
26577 * @submodule event-base
26578 */
26579
26580/**
26581 * Executes the callback as soon as the specified element
26582 * is detected in the DOM.  This function expects a selector
26583 * string for the element(s) to detect.  If you already have
26584 * an element reference, you don't need this event.
26585 * @event available
26586 * @param type {string} 'available'
26587 * @param fn {function} the callback function to execute.
26588 * @param el {string} an selector for the element(s) to attach
26589 * @param context optional argument that specifies what 'this' refers to.
26590 * @param args* 0..n additional arguments to pass on to the callback function.
26591 * These arguments will be added after the event object.
26592 * @return {EventHandle} the detach handle
26593 * @for YUI
26594 */
26595Y.Env.evt.plugins.available = {
26596    on: function(type, fn, id, o) {
26597        var a = arguments.length > 4 ?  Y.Array(arguments, 4, true) : null;
26598        return Y.Event.onAvailable.call(Y.Event, id, fn, o, a);
26599    }
26600};
26601
26602/**
26603 * Executes the callback as soon as the specified element
26604 * is detected in the DOM with a nextSibling property
26605 * (indicating that the element's children are available).
26606 * This function expects a selector
26607 * string for the element(s) to detect.  If you already have
26608 * an element reference, you don't need this event.
26609 * @event contentready
26610 * @param type {string} 'contentready'
26611 * @param fn {function} the callback function to execute.
26612 * @param el {string} an selector for the element(s) to attach.
26613 * @param context optional argument that specifies what 'this' refers to.
26614 * @param args* 0..n additional arguments to pass on to the callback function.
26615 * These arguments will be added after the event object.
26616 * @return {EventHandle} the detach handle
26617 * @for YUI
26618 */
26619Y.Env.evt.plugins.contentready = {
26620    on: function(type, fn, id, o) {
26621        var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null;
26622        return Y.Event.onContentReady.call(Y.Event, id, fn, o, a);
26623    }
26624};
26625
26626
26627}, 'patched-v3.18.1', {"requires": ["event-custom-base"]});
26628
26629YUI.add('event-delegate', function (Y, NAME) {
26630
26631/**
26632 * Adds event delegation support to the library.
26633 *
26634 * @module event
26635 * @submodule event-delegate
26636 */
26637
26638var toArray          = Y.Array,
26639    YLang            = Y.Lang,
26640    isString         = YLang.isString,
26641    isObject         = YLang.isObject,
26642    isArray          = YLang.isArray,
26643    selectorTest     = Y.Selector.test,
26644    detachCategories = Y.Env.evt.handles;
26645
26646/**
26647 * <p>Sets up event delegation on a container element.  The delegated event
26648 * will use a supplied selector or filtering function to test if the event
26649 * references at least one node that should trigger the subscription
26650 * callback.</p>
26651 *
26652 * <p>Selector string filters will trigger the callback if the event originated
26653 * from a node that matches it or is contained in a node that matches it.
26654 * Function filters are called for each Node up the parent axis to the
26655 * subscribing container node, and receive at each level the Node and the event
26656 * object.  The function should return true (or a truthy value) if that Node
26657 * should trigger the subscription callback.  Note, it is possible for filters
26658 * to match multiple Nodes for a single event.  In this case, the delegate
26659 * callback will be executed for each matching Node.</p>
26660 *
26661 * <p>For each matching Node, the callback will be executed with its 'this'
26662 * object set to the Node matched by the filter (unless a specific context was
26663 * provided during subscription), and the provided event's
26664 * <code>currentTarget</code> will also be set to the matching Node.  The
26665 * containing Node from which the subscription was originally made can be
26666 * referenced as <code>e.container</code>.
26667 *
26668 * @method delegate
26669 * @param type {String} the event type to delegate
26670 * @param fn {Function} the callback function to execute.  This function
26671 *              will be provided the event object for the delegated event.
26672 * @param el {String|node} the element that is the delegation container
26673 * @param filter {string|Function} a selector that must match the target of the
26674 *              event or a function to test target and its parents for a match
26675 * @param context optional argument that specifies what 'this' refers to.
26676 * @param args* 0..n additional arguments to pass on to the callback function.
26677 *              These arguments will be added after the event object.
26678 * @return {EventHandle} the detach handle
26679 * @static
26680 * @for Event
26681 */
26682function delegate(type, fn, el, filter) {
26683    var args     = toArray(arguments, 0, true),
26684        query    = isString(el) ? el : null,
26685        typeBits, synth, container, categories, cat, i, len, handles, handle;
26686
26687    // Support Y.delegate({ click: fnA, key: fnB }, el, filter, ...);
26688    // and Y.delegate(['click', 'key'], fn, el, filter, ...);
26689    if (isObject(type)) {
26690        handles = [];
26691
26692        if (isArray(type)) {
26693            for (i = 0, len = type.length; i < len; ++i) {
26694                args[0] = type[i];
26695                handles.push(Y.delegate.apply(Y, args));
26696            }
26697        } else {
26698            // Y.delegate({'click', fn}, el, filter) =>
26699            // Y.delegate('click', fn, el, filter)
26700            args.unshift(null); // one arg becomes two; need to make space
26701
26702            for (i in type) {
26703                if (type.hasOwnProperty(i)) {
26704                    args[0] = i;
26705                    args[1] = type[i];
26706                    handles.push(Y.delegate.apply(Y, args));
26707                }
26708            }
26709        }
26710
26711        return new Y.EventHandle(handles);
26712    }
26713
26714    typeBits = type.split(/\|/);
26715
26716    if (typeBits.length > 1) {
26717        cat  = typeBits.shift();
26718        args[0] = type = typeBits.shift();
26719    }
26720
26721    synth = Y.Node.DOM_EVENTS[type];
26722
26723    if (isObject(synth) && synth.delegate) {
26724        handle = synth.delegate.apply(synth, arguments);
26725    }
26726
26727    if (!handle) {
26728        if (!type || !fn || !el || !filter) {
26729            return;
26730        }
26731
26732        container = (query) ? Y.Selector.query(query, null, true) : el;
26733
26734        if (!container && isString(el)) {
26735            handle = Y.on('available', function () {
26736                Y.mix(handle, Y.delegate.apply(Y, args), true);
26737            }, el);
26738        }
26739
26740        if (!handle && container) {
26741            args.splice(2, 2, container); // remove the filter
26742
26743            handle = Y.Event._attach(args, { facade: false });
26744            handle.sub.filter  = filter;
26745            handle.sub._notify = delegate.notifySub;
26746        }
26747    }
26748
26749    if (handle && cat) {
26750        categories = detachCategories[cat]  || (detachCategories[cat] = {});
26751        categories = categories[type] || (categories[type] = []);
26752        categories.push(handle);
26753    }
26754
26755    return handle;
26756}
26757
26758/**
26759Overrides the <code>_notify</code> method on the normal DOM subscription to
26760inject the filtering logic and only proceed in the case of a match.
26761
26762This method is hosted as a private property of the `delegate` method
26763(e.g. `Y.delegate.notifySub`)
26764
26765@method notifySub
26766@param thisObj {Object} default 'this' object for the callback
26767@param args {Array} arguments passed to the event's <code>fire()</code>
26768@param ce {CustomEvent} the custom event managing the DOM subscriptions for
26769             the subscribed event on the subscribing node.
26770@return {Boolean} false if the event was stopped
26771@private
26772@static
26773@since 3.2.0
26774**/
26775delegate.notifySub = function (thisObj, args, ce) {
26776    // Preserve args for other subscribers
26777    args = args.slice();
26778    if (this.args) {
26779        args.push.apply(args, this.args);
26780    }
26781
26782    // Only notify subs if the event occurred on a targeted element
26783    var currentTarget = delegate._applyFilter(this.filter, args, ce),
26784        //container     = e.currentTarget,
26785        e, i, len, ret;
26786
26787    if (currentTarget) {
26788        // Support multiple matches up the the container subtree
26789        currentTarget = toArray(currentTarget);
26790
26791        // The second arg is the currentTarget, but we'll be reusing this
26792        // facade, replacing the currentTarget for each use, so it doesn't
26793        // matter what element we seed it with.
26794        e = args[0] = new Y.DOMEventFacade(args[0], ce.el, ce);
26795
26796        e.container = Y.one(ce.el);
26797
26798        for (i = 0, len = currentTarget.length; i < len && !e.stopped; ++i) {
26799            e.currentTarget = Y.one(currentTarget[i]);
26800
26801            ret = this.fn.apply(this.context || e.currentTarget, args);
26802
26803            if (ret === false) { // stop further notifications
26804                break;
26805            }
26806        }
26807
26808        return ret;
26809    }
26810};
26811
26812/**
26813Compiles a selector string into a filter function to identify whether
26814Nodes along the parent axis of an event's target should trigger event
26815notification.
26816
26817This function is memoized, so previously compiled filter functions are
26818returned if the same selector string is provided.
26819
26820This function may be useful when defining synthetic events for delegate
26821handling.
26822
26823Hosted as a property of the `delegate` method (e.g. `Y.delegate.compileFilter`).
26824
26825@method compileFilter
26826@param selector {String} the selector string to base the filtration on
26827@return {Function}
26828@since 3.2.0
26829@static
26830**/
26831delegate.compileFilter = Y.cached(function (selector) {
26832    return function (target, e) {
26833        return selectorTest(target._node, selector,
26834            (e.currentTarget === e.target) ? null : e.currentTarget._node);
26835    };
26836});
26837
26838/**
26839Regex to test for disabled elements during filtering. This is only relevant to
26840IE to normalize behavior with other browsers, which swallow events that occur
26841to disabled elements. IE fires the event from the parent element instead of the
26842original target, though it does preserve `event.srcElement` as the disabled
26843element. IE also supports disabled on `<a>`, but the event still bubbles, so it
26844acts more like `e.preventDefault()` plus styling. That issue is not handled here
26845because other browsers fire the event on the `<a>`, so delegate is supported in
26846both cases.
26847
26848@property _disabledRE
26849@type {RegExp}
26850@protected
26851@since 3.8.1
26852**/
26853delegate._disabledRE = /^(?:button|input|select|textarea)$/i;
26854
26855/**
26856Walks up the parent axis of an event's target, and tests each element
26857against a supplied filter function.  If any Nodes, including the container,
26858satisfy the filter, the delegated callback will be triggered for each.
26859
26860Hosted as a protected property of the `delegate` method (e.g.
26861`Y.delegate._applyFilter`).
26862
26863@method _applyFilter
26864@param filter {Function} boolean function to test for inclusion in event
26865                 notification
26866@param args {Array} the arguments that would be passed to subscribers
26867@param ce   {CustomEvent} the DOM event wrapper
26868@return {Node|Node[]|undefined} The Node or Nodes that satisfy the filter
26869@protected
26870**/
26871delegate._applyFilter = function (filter, args, ce) {
26872    var e         = args[0],
26873        container = ce.el, // facadeless events in IE, have no e.currentTarget
26874        target    = e.target || e.srcElement,
26875        match     = [],
26876        isContainer = false;
26877
26878    // Resolve text nodes to their containing element
26879    if (target.nodeType === 3) {
26880        target = target.parentNode;
26881    }
26882
26883    // For IE. IE propagates events from the parent element of disabled
26884    // elements, where other browsers swallow the event entirely. To normalize
26885    // this in IE, filtering for matching elements should abort if the target
26886    // is a disabled form control.
26887    if (target.disabled && delegate._disabledRE.test(target.nodeName)) {
26888        return match;
26889    }
26890
26891    // passing target as the first arg rather than leaving well enough alone
26892    // making 'this' in the filter function refer to the target.  This is to
26893    // support bound filter functions.
26894    args.unshift(target);
26895
26896    if (isString(filter)) {
26897        while (target) {
26898            isContainer = (target === container);
26899            if (selectorTest(target, filter, (isContainer ? null: container))) {
26900                match.push(target);
26901            }
26902
26903            if (isContainer) {
26904                break;
26905            }
26906
26907            target = target.parentNode;
26908        }
26909    } else {
26910        // filter functions are implementer code and should receive wrappers
26911        args[0] = Y.one(target);
26912        args[1] = new Y.DOMEventFacade(e, container, ce);
26913
26914        while (target) {
26915            // filter(target, e, extra args...) - this === target
26916            if (filter.apply(args[0], args)) {
26917                match.push(target);
26918            }
26919
26920            if (target === container) {
26921                break;
26922            }
26923
26924            target = target.parentNode;
26925            args[0] = Y.one(target);
26926        }
26927        args[1] = e; // restore the raw DOM event
26928    }
26929
26930    if (match.length <= 1) {
26931        match = match[0]; // single match or undefined
26932    }
26933
26934    // remove the target
26935    args.shift();
26936
26937    return match;
26938};
26939
26940/**
26941 * Sets up event delegation on a container element.  The delegated event
26942 * will use a supplied filter to test if the callback should be executed.
26943 * This filter can be either a selector string or a function that returns
26944 * a Node to use as the currentTarget for the event.
26945 *
26946 * The event object for the delegated event is supplied to the callback
26947 * function.  It is modified slightly in order to support all properties
26948 * that may be needed for event delegation.  'currentTarget' is set to
26949 * the element that matched the selector string filter or the Node returned
26950 * from the filter function.  'container' is set to the element that the
26951 * listener is delegated from (this normally would be the 'currentTarget').
26952 *
26953 * Filter functions will be called with the arguments that would be passed to
26954 * the callback function, including the event object as the first parameter.
26955 * The function should return false (or a falsey value) if the success criteria
26956 * aren't met, and the Node to use as the event's currentTarget and 'this'
26957 * object if they are.
26958 *
26959 * @method delegate
26960 * @param type {string} the event type to delegate
26961 * @param fn {function} the callback function to execute.  This function
26962 * will be provided the event object for the delegated event.
26963 * @param el {string|node} the element that is the delegation container
26964 * @param filter {string|function} a selector that must match the target of the
26965 * event or a function that returns a Node or false.
26966 * @param context optional argument that specifies what 'this' refers to.
26967 * @param args* 0..n additional arguments to pass on to the callback function.
26968 * These arguments will be added after the event object.
26969 * @return {EventHandle} the detach handle
26970 * @for YUI
26971 */
26972Y.delegate = Y.Event.delegate = delegate;
26973
26974
26975}, 'patched-v3.18.1', {"requires": ["node-base"]});
26976
26977YUI.add('event-focus', function (Y, NAME) {
26978
26979/**
26980 * Adds bubbling and delegation support to DOM events focus and blur.
26981 *
26982 * @module event
26983 * @submodule event-focus
26984 */
26985var Event    = Y.Event,
26986
26987    YLang    = Y.Lang,
26988
26989    isString = YLang.isString,
26990
26991    arrayIndex = Y.Array.indexOf,
26992
26993    useActivate = (function() {
26994
26995        // Changing the structure of this test, so that it doesn't use inline JS in HTML,
26996        // which throws an exception in Win8 packaged apps, due to additional security restrictions:
26997        // http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences
26998
26999        var supported = false,
27000            doc = Y.config.doc,
27001            p;
27002
27003        if (doc) {
27004
27005            p = doc.createElement("p");
27006            p.setAttribute("onbeforeactivate", ";");
27007
27008            // onbeforeactivate is a function in IE8+.
27009            // onbeforeactivate is a string in IE6,7 (unfortunate, otherwise we could have just checked for function below).
27010            // onbeforeactivate is a function in IE10, in a Win8 App environment (no exception running the test).
27011
27012            // onbeforeactivate is undefined in Webkit/Gecko.
27013            // onbeforeactivate is a function in Webkit/Gecko if it's a supported event (e.g. onclick).
27014
27015            supported = (p.onbeforeactivate !== undefined);
27016        }
27017
27018        return supported;
27019    }());
27020
27021function define(type, proxy, directEvent) {
27022    var nodeDataKey = '_' + type + 'Notifiers';
27023
27024    Y.Event.define(type, {
27025
27026        _useActivate : useActivate,
27027
27028        _attach: function (el, notifier, delegate) {
27029            if (Y.DOM.isWindow(el)) {
27030                return Event._attach([type, function (e) {
27031                    notifier.fire(e);
27032                }, el]);
27033            } else {
27034                return Event._attach(
27035                    [proxy, this._proxy, el, this, notifier, delegate],
27036                    { capture: true });
27037            }
27038        },
27039
27040        _proxy: function (e, notifier, delegate) {
27041            var target        = e.target,
27042                currentTarget = e.currentTarget,
27043                notifiers     = target.getData(nodeDataKey),
27044                yuid          = Y.stamp(currentTarget._node),
27045                defer         = (useActivate || target !== currentTarget),
27046                directSub;
27047
27048            notifier.currentTarget = (delegate) ? target : currentTarget;
27049            notifier.container     = (delegate) ? currentTarget : null;
27050
27051            // Maintain a list to handle subscriptions from nested
27052            // containers div#a>div#b>input #a.on(focus..) #b.on(focus..),
27053            // use one focus or blur subscription that fires notifiers from
27054            // #b then #a to emulate bubble sequence.
27055            if (!notifiers) {
27056                notifiers = {};
27057                target.setData(nodeDataKey, notifiers);
27058
27059                // only subscribe to the element's focus if the target is
27060                // not the current target (
27061                if (defer) {
27062                    directSub = Event._attach(
27063                        [directEvent, this._notify, target._node]).sub;
27064                    directSub.once = true;
27065                }
27066            } else {
27067                // In old IE, defer is always true.  In capture-phase browsers,
27068                // The delegate subscriptions will be encountered first, which
27069                // will establish the notifiers data and direct subscription
27070                // on the node.  If there is also a direct subscription to the
27071                // node's focus/blur, it should not call _notify because the
27072                // direct subscription from the delegate sub(s) exists, which
27073                // will call _notify.  So this avoids _notify being called
27074                // twice, unnecessarily.
27075                defer = true;
27076            }
27077
27078            if (!notifiers[yuid]) {
27079                notifiers[yuid] = [];
27080            }
27081
27082            notifiers[yuid].push(notifier);
27083
27084            if (!defer) {
27085                this._notify(e);
27086            }
27087        },
27088
27089        _notify: function (e, container) {
27090            var currentTarget = e.currentTarget,
27091                notifierData  = currentTarget.getData(nodeDataKey),
27092                axisNodes     = currentTarget.ancestors(),
27093                doc           = currentTarget.get('ownerDocument'),
27094                delegates     = [],
27095                                // Used to escape loops when there are no more
27096                                // notifiers to consider
27097                count         = notifierData ?
27098                                    Y.Object.keys(notifierData).length :
27099                                    0,
27100                target, notifiers, notifier, yuid, match, tmp, i, len, sub, ret;
27101
27102            // clear the notifications list (mainly for delegation)
27103            currentTarget.clearData(nodeDataKey);
27104
27105            // Order the delegate subs by their placement in the parent axis
27106            axisNodes.push(currentTarget);
27107            // document.get('ownerDocument') returns null
27108            // which we'll use to prevent having duplicate Nodes in the list
27109            if (doc) {
27110                axisNodes.unshift(doc);
27111            }
27112
27113            // ancestors() returns the Nodes from top to bottom
27114            axisNodes._nodes.reverse();
27115
27116            if (count) {
27117                // Store the count for step 2
27118                tmp = count;
27119                axisNodes.some(function (node) {
27120                    var yuid      = Y.stamp(node),
27121                        notifiers = notifierData[yuid],
27122                        i, len;
27123
27124                    if (notifiers) {
27125                        count--;
27126                        for (i = 0, len = notifiers.length; i < len; ++i) {
27127                            if (notifiers[i].handle.sub.filter) {
27128                                delegates.push(notifiers[i]);
27129                            }
27130                        }
27131                    }
27132
27133                    return !count;
27134                });
27135                count = tmp;
27136            }
27137
27138            // Walk up the parent axis, notifying direct subscriptions and
27139            // testing delegate filters.
27140            while (count && (target = axisNodes.shift())) {
27141                yuid = Y.stamp(target);
27142
27143                notifiers = notifierData[yuid];
27144
27145                if (notifiers) {
27146                    for (i = 0, len = notifiers.length; i < len; ++i) {
27147                        notifier = notifiers[i];
27148                        sub      = notifier.handle.sub;
27149                        match    = true;
27150
27151                        e.currentTarget = target;
27152
27153                        if (sub.filter) {
27154                            match = sub.filter.apply(target,
27155                                [target, e].concat(sub.args || []));
27156
27157                            // No longer necessary to test against this
27158                            // delegate subscription for the nodes along
27159                            // the parent axis.
27160                            delegates.splice(
27161                                arrayIndex(delegates, notifier), 1);
27162                        }
27163
27164                        if (match) {
27165                            // undefined for direct subs
27166                            e.container = notifier.container;
27167                            ret = notifier.fire(e);
27168                        }
27169
27170                        if (ret === false || e.stopped === 2) {
27171                            break;
27172                        }
27173                    }
27174
27175                    delete notifiers[yuid];
27176                    count--;
27177                }
27178
27179                if (e.stopped !== 2) {
27180                    // delegates come after subs targeting this specific node
27181                    // because they would not normally report until they'd
27182                    // bubbled to the container node.
27183                    for (i = 0, len = delegates.length; i < len; ++i) {
27184                        notifier = delegates[i];
27185                        sub = notifier.handle.sub;
27186
27187                        if (sub.filter.apply(target,
27188                            [target, e].concat(sub.args || []))) {
27189
27190                            e.container = notifier.container;
27191                            e.currentTarget = target;
27192                            ret = notifier.fire(e);
27193                        }
27194
27195                        if (ret === false || e.stopped === 2 ||
27196                            // If e.stopPropagation() is called, notify any
27197                            // delegate subs from the same container, but break
27198                            // once the container changes. This emulates
27199                            // delegate() behavior for events like 'click' which
27200                            // won't notify delegates higher up the parent axis.
27201                            (e.stopped && delegates[i+1] &&
27202                             delegates[i+1].container !== notifier.container)) {
27203                            break;
27204                        }
27205                    }
27206                }
27207
27208                if (e.stopped) {
27209                    break;
27210                }
27211            }
27212        },
27213
27214        on: function (node, sub, notifier) {
27215            sub.handle = this._attach(node._node, notifier);
27216        },
27217
27218        detach: function (node, sub) {
27219            sub.handle.detach();
27220        },
27221
27222        delegate: function (node, sub, notifier, filter) {
27223            if (isString(filter)) {
27224                sub.filter = function (target) {
27225                    return Y.Selector.test(target._node, filter,
27226                        node === target ? null : node._node);
27227                };
27228            }
27229
27230            sub.handle = this._attach(node._node, notifier, true);
27231        },
27232
27233        detachDelegate: function (node, sub) {
27234            sub.handle.detach();
27235        }
27236    }, true);
27237}
27238
27239// For IE, we need to defer to focusin rather than focus because
27240// `el.focus(); doSomething();` executes el.onbeforeactivate, el.onactivate,
27241// el.onfocusin, doSomething, then el.onfocus.  All others support capture
27242// phase focus, which executes before doSomething.  To guarantee consistent
27243// behavior for this use case, IE's direct subscriptions are made against
27244// focusin so subscribers will be notified before js following el.focus() is
27245// executed.
27246if (useActivate) {
27247    //     name     capture phase       direct subscription
27248    define("focus", "beforeactivate",   "focusin");
27249    define("blur",  "beforedeactivate", "focusout");
27250} else {
27251    define("focus", "focus", "focus");
27252    define("blur",  "blur",  "blur");
27253}
27254
27255
27256}, 'patched-v3.18.1', {"requires": ["event-synthetic"]});
27257
27258YUI.add('event-hover', function (Y, NAME) {
27259
27260/**
27261 * Adds support for a "hover" event.  The event provides a convenience wrapper
27262 * for subscribing separately to mouseenter and mouseleave.  The signature for
27263 * subscribing to the event is</p>
27264 *
27265 * <pre><code>node.on("hover", overFn, outFn);
27266 * node.delegate("hover", overFn, outFn, ".filterSelector");
27267 * Y.on("hover", overFn, outFn, ".targetSelector");
27268 * Y.delegate("hover", overFn, outFn, "#container", ".filterSelector");
27269 * </code></pre>
27270 *
27271 * <p>Additionally, for compatibility with a more typical subscription
27272 * signature, the following are also supported:</p>
27273 *
27274 * <pre><code>Y.on("hover", overFn, ".targetSelector", outFn);
27275 * Y.delegate("hover", overFn, "#container", outFn, ".filterSelector");
27276 * </code></pre>
27277 *
27278 * @module event
27279 * @submodule event-hover
27280 */
27281var isFunction = Y.Lang.isFunction,
27282    noop = function () {},
27283    conf = {
27284        processArgs: function (args) {
27285            // Y.delegate('hover', over, out, '#container', '.filter')
27286            // comes in as ['hover', over, out, '#container', '.filter'], but
27287            // node.delegate('hover', over, out, '.filter')
27288            // comes in as ['hover', over, containerEl, out, '.filter']
27289            var i = isFunction(args[2]) ? 2 : 3;
27290
27291            return (isFunction(args[i])) ? args.splice(i,1)[0] : noop;
27292        },
27293
27294        on: function (node, sub, notifier, filter) {
27295            var args = (sub.args) ? sub.args.slice() : [];
27296
27297            args.unshift(null);
27298
27299            sub._detach = node[(filter) ? "delegate" : "on"]({
27300                mouseenter: function (e) {
27301                    e.phase = 'over';
27302                    notifier.fire(e);
27303                },
27304                mouseleave: function (e) {
27305                    var thisObj = sub.context || this;
27306
27307                    args[0] = e;
27308
27309                    e.type = 'hover';
27310                    e.phase = 'out';
27311                    sub._extra.apply(thisObj, args);
27312                }
27313            }, filter);
27314        },
27315
27316        detach: function (node, sub, notifier) {
27317            sub._detach.detach();
27318        }
27319    };
27320
27321conf.delegate = conf.on;
27322conf.detachDelegate = conf.detach;
27323
27324Y.Event.define("hover", conf);
27325
27326
27327}, 'patched-v3.18.1', {"requires": ["event-mouseenter"]});
27328
27329YUI.add('event-key', function (Y, NAME) {
27330
27331/**
27332 * Functionality to listen for one or more specific key combinations.
27333 * @module event
27334 * @submodule event-key
27335 */
27336
27337var ALT      = "+alt",
27338    CTRL     = "+ctrl",
27339    META     = "+meta",
27340    SHIFT    = "+shift",
27341
27342    trim     = Y.Lang.trim,
27343
27344    eventDef = {
27345        KEY_MAP: {
27346            enter    : 13,
27347            space    : 32,
27348            esc      : 27,
27349            backspace: 8,
27350            tab      : 9,
27351            pageup   : 33,
27352            pagedown : 34
27353        },
27354
27355        _typeRE: /^(up|down|press):/,
27356        _keysRE: /^(?:up|down|press):|\+(alt|ctrl|meta|shift)/g,
27357
27358        processArgs: function (args) {
27359            var spec = args.splice(3,1)[0],
27360                mods = Y.Array.hash(spec.match(/\+(?:alt|ctrl|meta|shift)\b/g) || []),
27361                config = {
27362                    type: this._typeRE.test(spec) ? RegExp.$1 : null,
27363                    mods: mods,
27364                    keys: null
27365                },
27366                // strip type and modifiers from spec, leaving only keyCodes
27367                bits = spec.replace(this._keysRE, ''),
27368                chr, uc, lc, i;
27369
27370            if (bits) {
27371                bits = bits.split(',');
27372
27373                config.keys = {};
27374
27375                // FIXME: need to support '65,esc' => keypress, keydown
27376                for (i = bits.length - 1; i >= 0; --i) {
27377                    chr = trim(bits[i]);
27378
27379                    // catch sloppy filters, trailing commas, etc 'a,,'
27380                    if (!chr) {
27381                        continue;
27382                    }
27383
27384                    // non-numerics are single characters or key names
27385                    if (+chr == chr) {
27386                        config.keys[chr] = mods;
27387                    } else {
27388                        lc = chr.toLowerCase();
27389
27390                        if (this.KEY_MAP[lc]) {
27391                            config.keys[this.KEY_MAP[lc]] = mods;
27392                            // FIXME: '65,enter' defaults keydown for both
27393                            if (!config.type) {
27394                                config.type = "down"; // safest
27395                            }
27396                        } else {
27397                            // FIXME: Character mapping only works for keypress
27398                            // events. Otherwise, it uses String.fromCharCode()
27399                            // from the keyCode, which is wrong.
27400                            chr = chr.charAt(0);
27401                            uc  = chr.toUpperCase();
27402
27403                            if (mods["+shift"]) {
27404                                chr = uc;
27405                            }
27406
27407                            // FIXME: stupid assumption that
27408                            // the keycode of the lower case == the
27409                            // charCode of the upper case
27410                            // a (key:65,char:97), A (key:65,char:65)
27411                            config.keys[chr.charCodeAt(0)] =
27412                                (chr === uc) ?
27413                                    // upper case chars get +shift free
27414                                    Y.merge(mods, { "+shift": true }) :
27415                                    mods;
27416                        }
27417                    }
27418                }
27419            }
27420
27421            if (!config.type) {
27422                config.type = "press";
27423            }
27424
27425            return config;
27426        },
27427
27428        on: function (node, sub, notifier, filter) {
27429            var spec   = sub._extra,
27430                type   = "key" + spec.type,
27431                keys   = spec.keys,
27432                method = (filter) ? "delegate" : "on";
27433
27434            // Note: without specifying any keyCodes, this becomes a
27435            // horribly inefficient alias for 'keydown' (et al), but I
27436            // can't abort this subscription for a simple
27437            // Y.on('keypress', ...);
27438            // Please use keyCodes or just subscribe directly to keydown,
27439            // keyup, or keypress
27440            sub._detach = node[method](type, function (e) {
27441                var key = keys ? keys[e.which] : spec.mods;
27442
27443                if (key &&
27444                    (!key[ALT]   || (key[ALT]   && e.altKey)) &&
27445                    (!key[CTRL]  || (key[CTRL]  && e.ctrlKey)) &&
27446                    (!key[META]  || (key[META]  && e.metaKey)) &&
27447                    (!key[SHIFT] || (key[SHIFT] && e.shiftKey)))
27448                {
27449                    notifier.fire(e);
27450                }
27451            }, filter);
27452        },
27453
27454        detach: function (node, sub, notifier) {
27455            sub._detach.detach();
27456        }
27457    };
27458
27459eventDef.delegate = eventDef.on;
27460eventDef.detachDelegate = eventDef.detach;
27461
27462/**
27463 * <p>Add a key listener.  The listener will only be notified if the
27464 * keystroke detected meets the supplied specification.  The
27465 * specification is a string that is defined as:</p>
27466 *
27467 * <dl>
27468 *   <dt>spec</dt>
27469 *   <dd><code>[{type}:]{code}[,{code}]*</code></dd>
27470 *   <dt>type</dt>
27471 *   <dd><code>"down", "up", or "press"</code></dd>
27472 *   <dt>code</dt>
27473 *   <dd><code>{keyCode|character|keyName}[+{modifier}]*</code></dd>
27474 *   <dt>modifier</dt>
27475 *   <dd><code>"shift", "ctrl", "alt", or "meta"</code></dd>
27476 *   <dt>keyName</dt>
27477 *   <dd><code>"enter", "space", "backspace", "esc", "tab", "pageup", or "pagedown"</code></dd>
27478 * </dl>
27479 *
27480 * <p>Examples:</p>
27481 * <ul>
27482 *   <li><code>Y.on("key", callback, "press:12,65+shift+ctrl", "#my-input");</code></li>
27483 *   <li><code>Y.delegate("key", preventSubmit, "#forms", "enter", "input[type=text]");</code></li>
27484 *   <li><code>Y.one("doc").on("key", viNav, "j,k,l,;");</code></li>
27485 * </ul>
27486 *
27487 * @event key
27488 * @for YUI
27489 * @param type {string} 'key'
27490 * @param fn {function} the function to execute
27491 * @param id {string|HTMLElement|collection}
27491 the element(s) to bind
27492 * @param spec {string} the keyCode and modifier specification
27493 * @param o optional context object
27494 * @param args 0..n additional arguments to provide to the listener.
27495 * @return {Event.Handle} the detach handle
27496 */
27497Y.Event.define('key', eventDef, true);
27498
27499
27500}, 'patched-v3.18.1', {"requires": ["event-synthetic"]});
27501

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.