PageSourceSearch

https://idee.es/combo?browserId=other&minifierType=js&languageId=e…/aui/event-mousewheel/event-mousewheel.js

js idee.es collected 2026-10-02 03:06:32 UTC 810,656 bytes, 25,742 lines download raw bytes

1/**
2 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 2.1 of the License, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.
13 */
14(function () {
15  var LiferayAUI = Liferay.AUI;
16  var combine = LiferayAUI.getCombine();
17  window.__CONFIG__ = {
18    basePath: '',
19    combine: combine,
20    reportMismatchedAnonymousModules: 'warn',
21    url: combine ? LiferayAUI.getComboPath() : Liferay.ThemeDisplay.getCDNBaseURL()
22  };
23
24  if (!combine) {
25    __CONFIG__.defaultURLParams = {
26      languageId: themeDisplay.getLanguageId()
27    };
28  }
29
30  __CONFIG__.maps = Liferay.MAPS;
31  __CONFIG__.modules = Liferay.MODULES;
32  __CONFIG__.paths = Liferay.PATHS;
33  __CONFIG__.resolvePath = Liferay.RESOLVE_PATH;
34  __CONFIG__.namespace = 'Liferay';
35  __CONFIG__.explainResolutions = Liferay.EXPLAIN_RESOLUTIONS;
36  __CONFIG__.exposeGlobal = Liferay.EXPOSE_GLOBAL;
37  __CONFIG__.logLevel = Liferay.LOG_LEVEL;
38  __CONFIG__.waitTimeout = Liferay.WAIT_TIMEOUT;
39})();
40//# sourceMappingURL=config.js.map
41!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();var o=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=t}return r(e,[{key:"build",value:function(e){var t=this,n=this._config,r=[],o=[],i=[],a=n.basePath;return a.length&&"/"!==a.charAt(a.length-1)&&(a+="/"),e.forEach(function(e){var l=n.getModule(e),u=t._getModulePath(l);n.combine?(r.push(u),o.push(l.name)):i.push({modules:[l.name],url:t._getURLWithParams(n.url+a+u)})}),r.length&&(i=i.concat(this._generateBufferURLs(o,r,{basePath:a,url:n.url,urlMaxLength:n.urlMaxLength})),r.length=0),i}},{key:"_generateBufferURLs",value:function(e,t,n){for(var r=n.basePath,o=[],i=n.urlMaxLength,a={modules:[e[0]],url:n.url+r+t[0]},l=1;l<t.length;l++){var u=e[l],s=t[l];a.url.length+r.length+s.length+1<i?(a.modules.push(u),a.url+="&"+r+s):(o.push(a),a={modules:[u],url:n.url+r+s})}return a.url=this._getURLWithParams(a.url),o.push(a),o}},{key:"_getModulePath",value:function(e){var t=this._config.paths,n=e.name;return Object.keys(t).forEach(function(e){n!==e&&0!==n.indexOf(e+"/")||(n=t[e]+n.substring(e.length))}),n.lastIndexOf(".js")!==n.length-3&&(n+=".js"),n}},{key:"_getURLWithParams",value:function(e){var t=this._config.defaultURLParams||{},n=Object.keys(t);if(!n.length)return e;var r=n.map(function(e){return e+"="+t[e]}).join("&");return e+(e.indexOf("?")>-1?"&":"?")+r}}]),e}();t.default=o},function(e,t,n){"use strict";var r,o=n(2),i=(r=o)&&r.__esModule?r:{default:r};var a=window.__CONFIG__||{},l="string"==typeof a.namespace?a.namespace:void 0,u=void 0===a.exposeGlobal||a.exposeGlobal,s=new i.default(a);if(l){var c=window[l]?window[l]:{};c.Loader=s,window[l]=c}else window.Loader=s;u&&(window.Loader=s,window.require=i.default.prototype.require.bind(s),window.define=i.default.prototype.define.bind(s),window.define.amd={})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=c(n(3)),i=c(n(6)),a=c(n(7)),l=c(n(0)),u=c(n(8)),s=c(n(9));function c(e){return e&&e.__esModule?e:{default:e}}function f(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var d=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=new o.default(t||window.__CONFIG__),this._log=new u.default(this._config),this._dependencyResolver=new i.default(this._config),this._urlBuilder=new l.default(this._config),this._scriptLoader=new a.default(n||window.document,this._config,this._log),this._requireCallId=0}return r(e,[{key:"version",value:function(){return s.default.version}},{key:"define",value:function(){for(var e=this._config,t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];var o=n[0],i=e.getModule(o);if(i&&i.defined)this._log.warn("Module '"+o+"' is being redefined. Only the first","definition will be used");else{var a=n[1],l=n[2];if(2==n.length&&(l=a,a=["require","exports","module"]),"function"!=typeof l){var u=l;l=function(){return u}}if(!(i=e.getModule(o)))throw new Error("Trying to define a module that was not registered: "+o+"\nThis usually means that someone is calling define() for a module that has not been previously required.");
41if(i.defined)throw new Error("Trying to define a module more than once: "+o+"\nThis usually means that someone is calling define() more than once for the same module, which can lead to unexpected results.");this._log.resolution("Defining",i.name),i.factory=l,i.dependencies=a,i.define.resolve(n)}}},{key:"require",value:function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];var o=this._scriptLoader,i=this._config,a=this._requireCallId++,l=void 0,u=void 0,s=void 0;if(1==n.length)l=n[0],u=void 0,s=void 0;else if(2==n.length){var c=n[n.length-1];"function"==typeof c?(l=n[0],u=c,s=void 0):null==c?(l=n[0],u=void 0,s=void 0):(l=n,u=void 0,s=void 0)}else{var d=n[n.length-1],h=!1;if("function"!=typeof d&&null!=d||(h=!0),h){var p=n[n.length-2],m=!1;"function"!=typeof p&&null!=p||(m=!0),m?(l=n.slice(0,n.length-2),u=p,s=d):(l=n.slice(0,n.length-1),u=d,s=void 0)}else l=n,u=void 0,s=void 0}if("string"==typeof l)l=[l];else if(1==l.length&&Array.isArray(l[0])){var v;l=(v=[]).concat.apply(v,f(l))}if(void 0===u&&(u=function(){}),void 0===s){var g=new Error("");s=function(t){var n="(n/a)";g.stack&&(n="\n"+(n=g.stack.split("\n").map(function(e){return"        "+e}).join("\n"))),e._log.error("\n","A require() call has failed but no failure handler was","provided.\n","Note that even if the call stack of this error trace","looks like coming from the Liferay AMD Loader, it is not","an error in the Loader what has caused it, but an error","caused by the require() call.\n","The reason why the Loader is in the stack trace is","because it is printing the error so that it doesn't get","lost.\n","However, we recommend providing a failure handler in all","require() calls to be able to recover from errors better","and to avoid the appearance of this message.\n","\n","Some information about the require() call follows:\n","  · Require call id:",a,"\n","  · Required modules:",l,"\n","  · Missing modules:",t.missingModules?t.missingModules:"(n/a)","\n","  · Stack trace of the require() call:",""+n,"\n",t)}}u=this._interceptHandler(u,"success",a),s=this._interceptHandler(s,"failure",a);var y=void 0,_=void 0,b=void 0,w=!1;this._dependencyResolver.resolve(l).then(function(t){return e._log.resolution("Require call",a,"resolved modules",l,"to",t),e._throwOnResolutionErrors(t),i.addMappings(t.configMap),i.addPaths(t.pathMap),y=t.resolvedModules,(_=e._getUnregisteredModuleNames(y)).forEach(function(e){var n={map:t.moduleMap[e]},r=t.moduleFlags?t.moduleFlags[e]:{};(r=r||{}).esModule&&(n.esModule=!0),i.addModule(e,n)}),b=e._setRejectTimeout(l,t,function(){w=!0,s.apply(void 0,arguments)}),e._log.resolution("Fetching",_,"from require call",a),o.loadModules(_)}).then(function(){if(!w)return e._waitForModuleDefinitions(y)}).then(function(){if(!w){clearTimeout(b),e._setModuleImplementations(a,y);var t=e._getModuleImplementations(l);u.apply(void 0,f(t))}}).catch(function(e){w||(b&&clearTimeout(b),s(e))})}},{key:"_interceptHandler",value:function(e,t,n){var r=this;return function(){r._log.resolution("Invoking",t,"handler for","require call",n);try{e.apply(void 0,arguments)}catch(e){r._log.error("\n","A require() call",t,"handler has thrown an error.\n","Note that even if the call stack of this error trace","looks like coming from the Liferay AMD Loader, it is not","an error in the Loader what has caused it, but an error","in the handler's code.\n","The reason why the Loader is in the stack trace is","because it is printing the error on behalf of the handler","so that it doesn't get lost.\n","However, we recommend wrapping all handler code inside a","try/catch to be able to recover from errors better and to","avoid the appearance of this message.\n","\n",e)}}}},{key:"_throwOnResolutionErrors",value:function(e){var t=e.resolvedModules.filter(function(e){return 0===e.indexOf(":ERROR:")}).map(function(e){return e.substr(7)});if(t.length>0)throw Object.assign(new Error("The following problems where detected while resolving modules:\n"+t.map(function(e){return"    · "+e}).join("\n")),{resolutionErrors:t})}},{key:"_getUnregisteredModuleNames",value:function(e){var t=this._config;return e.filter(function(e){return!t.getModule(e)})}},{key:"_setRejectTimeout",value:function(e,t,n){var r=this._config;if(0!==r.waitTimeout)return setTimeout(function(){var o=t.resolvedModules.filter(function(e){var t=r.getModule(e);return!t||!t.implemented}),i=Object.assign(new Error("Load timeout for modules: "+e),{modules:e,resolution:t,missingModules:o});n(i)},r.waitTimeout)}},{key:"_waitForModuleDefinitions",value:function(e){var t=this._config;return Promise.all(t.getModules(e).map(function(e){return e.define}))}},{key:"_waitForModuleImplementations",value:function(e){var t=this._config;return Promise.all(t.getModules(e).map(function(e){return e.implement}))}},{key:"_setModuleImplementations",value:function(e,t){var n=this,r=this._config;r.getModules(t).forEach(function(t){if(!t.implemented){if(t.implement.rejected)throw t.implement.rejection;n._log.resolution("Implementing",t.name,"from require call",e);try{var o={get exports(){return t.implementation},set exports(e){t.implementation=e}},i=t.dependencies.map(function(e){if("exports"===e)return o.exports;if("module"===e)return o;if("require"===e)return n._createLocalRequire(t);var i=r.getDependency(t.name,e);if(!i)throw new Error("Unsatisfied dependency: "+e+" found in module "+t.name);if(!i.implementation&&!i.implemented)throw new Error('Module "'+i.name+'" has not been loaded yet for context: '+t.name);return i.implementation}),a=t.factory.apply(t,f(i));void 0!==a&&(t.implementation=a),t.implement.resolve(t.implementation)}catch(e){throw t.implement.fulfilled||t.implement.reject(e),e}}})}},{key:"_createLocalRequire",value:function(e){var t=this,n=this._config,r=function(r){for(var o=arguments.length,i=Array(o>1?o-1:0),a=1;a<o;a++)i[a-1]=arguments[a];if(i.length>0)return t.require.apply(t,[r].concat(i));var l=n.getDependency(e.name,r);
41if(!(l&&"implementation"in l))throw new Error('Module "'+r+'" has not been loaded yet for context: '+e.name);return l.implementation};return r.toUrl=function(e){return t._urlBuilder.build([e])[0].url},r}},{key:"_getModuleImplementations",value:function(e){return this._config.getModules(e).map(function(e){return e.implementation})}}]),e}();t.default=d,d.prototype.define.amd={}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,l=e[Symbol.iterator]();!(r=(a=l.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{!r&&l.return&&l.return()}finally{if(o)throw i}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),l=n(4),u=(r=l)&&r.__esModule?r:{default:r};var s=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._modules={},this._maps={},this._paths={},this._config={maps:{},paths:{}},this._parse(t,"defaultURLParams",{}),this._parse(t,"explainResolutions",!1),this._parse(t,"showWarnings",!1),this._parse(t,"waitTimeout",7e3),this._parse(t,"basePath","/"),this._parse(t,"resolvePath","/o/js_resolve_modules"),this._parse(t,"combine",!1),this._parse(t,"url",""),this._parse(t,"urlMaxLength",2e3),this._parse(t,"logLevel","error")}return a(e,[{key:"addModule",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this._modules[e])throw new Error("Module is already registered: "+e);var n=new u.default(e);return Object.entries(t).forEach(function(e){var t=i(e,2),r=t[0],o=t[1];n[r]=o}),this._modules[e]=n,n}},{key:"addMappings",value:function(e){Object.assign(this._maps,e)}},{key:"addPaths",value:function(e){Object.assign(this._paths,e)}},{key:"getModules",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return void 0===t?Object.values(this._modules):t.map(function(t){return e.getModule(t)})}},{key:"getModule",value:function(e){var t=this._modules[e];if(!t){var n=this._mapModule(e);t=this._modules[n]}return t}},{key:"getDependency",value:function(e,t){var n=this.getModule(e),r=this._modules[t];if(!r){var o=this._mapModule(t,n.map);r=this._modules[o]}return r}},{key:"_parse",value:function(e,t,n){this._config[t]=e.hasOwnProperty(t)?e[t]:n}},{key:"_mapModule",value:function(e,t){return t&&(e=this._mapMatches(e,t)),Object.keys(this._maps).length>0&&(e=this._mapMatches(e,this._maps)),e}},{key:"_mapMatches",value:function(e,t){var n=t[e];return n?"object"===(void 0===n?"undefined":o(n))?n.value:n:((n=this._mapExactMatch(e,t))||(n=this._mapPartialMatch(e,t)),n||(n=this._mapWildcardMatch(e,t)),n||e)}},{key:"_mapExactMatch",value:function(e,t){for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){var r=t[n];if(r.value&&r.exactMatch&&e===n)return r.value}}},{key:"_mapPartialMatch",value:function(e,t){for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){var r=t[n];if(!r.exactMatch&&(r.value&&(r=r.value),e===n||0===e.indexOf(n+"/")))return r+e.substring(n.length)}}},{key:"_mapWildcardMatch",value:function(e,t){if("function"==typeof t["*"])return t["*"](e)}},{key:"explainResolutions",get:function(){return this._config.explainResolutions}},{key:"showWarnings",get:function(){return this._config.showWarnings}},{key:"waitTimeout",get:function(){return this._config.waitTimeout}},{key:"basePath",get:function(){return this._config.basePath}},{key:"resolvePath",get:function(){return this._config.resolvePath}},{key:"combine",get:function(){return this._config.combine}},{key:"url",get:function(){return this._config.url}},{key:"urlMaxLength",get:function(){return this._config.urlMaxLength}},{key:"logLevel",get:function(){return this._config.logLevel}},{key:"defaultURLParams",get:function(){return this._config.defaultURLParams}},{key:"paths",get:function(){return this._paths}}]),e}();t.default=s},function(e,t,n){"use strict";
41Object.defineProperty(t,"__esModule",{value:!0});var r,o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(5),a=(r=i)&&r.__esModule?r:{default:r};var l=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._name=t,this._dependencies=void 0,this._factory=void 0,this._implementation={},this._map=void 0,this._state={_fetch:a.default.new(),_define:a.default.new(),_implement:a.default.new()}}return o(e,[{key:"name",get:function(){return this._name},set:function(e){throw new Error("Name of module "+this.name+" is read-only")}},{key:"dependencies",get:function(){return this._dependencies},set:function(e){if(this._dependencies)throw new Error("Dependencies of module "+this.name+" already set");this._dependencies=e}},{key:"factory",get:function(){return this._factory},set:function(e){if(this._factory)throw new Error("Factory of module "+this.name+" already set");this._factory=e}},{key:"implementation",get:function(){return this._implementation},set:function(e){this._implementation=e}},{key:"map",get:function(){return this._map},set:function(e){if(this._map)throw new Error("Local module map of module "+this.name+" already set");this._map=e}},{key:"esModule",get:function(){return this._implementation.__esModule},set:function(e){Object.defineProperty(this._implementation,"__esModule",{configurable:!0,value:e,writable:!0})}},{key:"fetch",get:function(){return this._state._fetch}},{key:"fetched",get:function(){return this.fetch.resolved}},{key:"define",get:function(){return this._state._define}},{key:"defined",get:function(){return this.define.resolved}},{key:"implement",get:function(){return this._state._implement}},{key:"implemented",get:function(){return this.implement.resolved}}]),e}();t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function e(){throw function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),new Error("Don't construct ResolvablePromise objects directly: rely on ResolvablePromise.new() instead")};function o(e){if(e.fulfilled)throw new Error("Promise already fulfilled")}t.default=r,r.new=function(){var e={},t=new Promise(function(t,n){e._resolve=t,e._reject=n});return Object.assign(t,e,{fulfilled:!1,resolved:!1,rejected:!1,resolution:void 0,rejection:void 0}),t.resolve=function(e){return function(e,t){o(e),e.fulfilled=!0,e.resolved=!0,e.resolution=t,e._resolve(t)}(t,e)},t.reject=function(e){return function(e,t){o(e),e.fulfilled=!0,e.rejected=!0,e.rejection=t,e._reject(t)}(t,e)},"undefined"!=typeof jest&&t.catch(function(){}),t}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();var o=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=t,this._cachedResolutions={}}return r(e,[{key:"resolve",value:function(e){var t=this;if(void 0===e||0==e.length)throw new Error("Argument 'modules' cannot be undefined or empty");var n=this._config;return new Promise(function(r,o){var i=t._cachedResolutions[e];if(i)r(i);else{var a="modules="+encodeURIComponent(e),l=n.resolvePath+"?"+a,u={};l.length>n.urlMaxLength&&(l=n.resolvePath,u={method:"POST",body:a}),fetch(l,u).then(function(e){return e.text()}).then(function(n){var o=JSON.parse(n);t._cachedResolutions[e]=o,r(o)}).catch(o)}})}}]),e}();t.default=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(0),a=(r=i)&&r.__esModule?r:{default:r};var l=function(){function e(t,n,r){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._document=t,this._config=n,this._log=r,this._urlBuilder=new a.default(n),this._injectedScripts={}}return o(e,[{key:"loadModules",value:function(e){var t=this,n=this._urlBuilder;if(0==e.length)return Promise.resolve();var r=n.build(e).map(function(e){return t._loadScript(e)});return Promise.all(r)}},{key:"_loadScript",value:function(e){var t=this,n=this._config.getModules(e.modules),r=this._injectedScripts[e.url];return r||((r=this._document.createElement("script")).src=e.url,r.async=!1,r.onload=r.onreadystatechange=function(){t.readyState&&"complete"!==t.readyState&&"load"!==t.readyState||(r.onload=r.onreadystatechange=null,r.onerror=null,n.forEac
41h(function(e){e.fetch.fulfilled?t._log.warn("Module '"+e.name+"' is being fetched from\n",r.src,"but was already fetched from\n",e.fetch.resolved?e.fetch.resolution.src:e.fetch.rejection.script.src):e.fetch.resolve(r)}))},r.onerror=function(){r.onload=r.onreadystatechange=null,r.onerror=null;var t=Object.assign(new Error("Unable to load script from URL "+e.url),{url:e.url,modules:e.modules,script:r});n.forEach(function(e){return e.fetch.reject(t)})},this._injectedScripts[e.url]=r,this._document.head.appendChild(r)),Promise.all(n.map(function(e){return e.fetch}))}}]),e}();t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();var o={off:0,error:1,warn:2,info:3,debug:4},i="liferay-amd-loader |",a=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=t}return r(e,[{key:"error",value:function(){var e;if(this._applies("error")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).error.apply(e,[i].concat(n))}}},{key:"warn",value:function(){var e;if(this._applies("warn")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).warn.apply(e,[i].concat(n))}}},{key:"info",value:function(){var e;if(this._applies("info")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).info.apply(e,[i].concat(n))}}},{key:"debug",value:function(){var e;if(this._applies("debug")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).debug.apply(e,[i].concat(n))}}},{key:"resolution",value:function(){var e;if(this._config.explainResolutions){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).log.apply(e,[i].concat(n))}}},{key:"_applies",value:function(e){var t=o[this._config.logLevel];return o[e]<=t}}]),e}();t.default=a},function(e){e.exports={name:"liferay-amd-loader",version:"4.2.0",description:"AMD Loader with support for combo URL and conditional loading",scripts:{clean:"rm -rf build",build:"node bin/build-loader.js",ci:"npm run format:check && npm run lint && npm run build && npm run build-demo && npm test","build-demo":"node bin/build-demo.js",demo:"node bin/run-demo.js",test:"jest --runInBand",format:"prettier --write '{*,.*}.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'","format:check":"prettier --list-different '{*,.*}.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'",lint:"eslint '*.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'","lint:fix":"eslint --fix '*.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'",prepublish:"publish-please guard","publish-please":"publish-please",prepublishOnly:"npm run build && npm run build-demo && npm test",proxyPortal:"webpack-dev-server --config webpack.proxyPortal.js"},repository:{type:"git",url:"git+https://github.com/liferay/liferay-amd-loader.git"},jest:{collectCoverage:!0,coverageDirectory:"build/coverage",modulePathIgnorePatterns:["liferay-amd-loader/build/.*",".*/__tests__/__fixtures__/.*"],testPathIgnorePatterns:[".eslintrc.js"],testURL:"http://localhost/"},author:{name:"Iliyan Peychev"},license:"LGPL-3.0",keywords:["Liferay","AMD","ES6","Loader"],bugs:{url:"https://github.com/liferay/liferay-amd-loader/issues"},homepage:"https://github.com/liferay/liferay-amd-loader",files:[".babelrc",".eslintrc.js",".publishrc","LICENSE.md","package.json","README.md","webpack.config.js","src","bin","build","src"],devDependencies:{"babel-loader":"^7.1.2","babel-preset-es2015":"^6.24.1",combohandler:"^0.4.0",eslint:"^5.15.1","eslint-config-liferay":"^3.0.0","fs-extra":"^5.0.0",globby:"^7.1.1","http-server":"^0.11.1",jest:"^22.2.1",prettier:"^1.16.4","publish-please":"^2.3.1","uglifyjs-webpack-plugin":"^1.2.0",webpack:"^4.29.6","webpack-cli":"^3.3.0","webpack-dev-server":"^3.2.1"}}}]);
42//# sourceMappingURL=loader.js.map
43/**
44The YUI module contains the components required for building the YUI seed file.
45This includes the script loading mechanism, a simple queue, and the core
46utilities for the library.
47
48@module yui
49@main yui
50@submodule yui-base
51**/
52
53/*jshint eqeqeq: false*/
54if (typeof YUI != 'undefined') {
55    YUI._YUI = YUI;
56}
57
58/**
59The YUI global namespace object. This is the constructor for all YUI instances.
60
61This is a self-instantiable factory function, meaning you don't need to precede
62it with the `new` operator. You can invoke it directly like this:
63
64    YUI().use('*', function (Y) {
65        // Y is a new YUI instance.
66    });
67
68But it also works like this:
69
70    var Y = YUI();
71
72The `YUI` constructor accepts an optional config object, like this:
73
74    YUI({
75        debug: true,
76        combine: false
77    }).use('node', function (Y) {
78        // Y.Node is ready to use.
79    });
80
81See the API docs for the <a href="config.html">Config</a> class for the complete
82list of supported configuration properties accepted by the YUI constuctor.
83
84If a global `YUI` object is already defined, the existing YUI object will not be
85overwritten, to ensure that defined namespaces are preserved.
86
87Each YUI instance has full custom event support, but only if the event system is
88available.
89
90@class YUI
91@uses EventTarget
92@constructor
93@global
94@param {Object} [config]* Zero or more optional configuration objects. Config
95    values are stored in the `Y.config` property. See the
96    <a href="config.html">Config</a> docs for the list of supported properties.
97**/
98
99    /*global YUI*/
100    /*global YUI_config*/
101    var YUI = function() {
102        var i = 0,
103            Y = this,
104            args = arguments,
105            l = args.length,
106            instanceOf = function(o, type) {
107                return (o && o.hasOwnProperty && (o instanceof type));
108            },
109            gconf = (typeof YUI_config !== 'undefined') && YUI_config;
110
111        if (!(instanceOf(Y, YUI))) {
112            Y = new YUI();
113        } else {
114            // set up the core environment
115            Y._init();
116
117            /**
118            Master configuration that might span multiple contexts in a non-
119            browser environment. It is applied first to all instances in all
120            contexts.
121
122            @example
123
124                YUI.GlobalConfig = {
125                    filter: 'debug'
126                };
127
128                YUI().use('node', function (Y) {
129                    // debug files used here
130                });
131
132                YUI({
133                    filter: 'min'
134                }).use('node', function (Y) {
135                    // min files used here
136                });
137
138            @property {Object} GlobalConfig
139            @global
140            @static
141            **/
142            if (YUI.GlobalConfig) {
143                Y.applyConfig(YUI.GlobalConfig);
144            }
145
146            /**
147            Page-level config applied to all YUI instances created on the
148            current page. This is applied after `YUI.GlobalConfig` and before
149            any instance-level configuration.
150
151            @example
152
153                // Single global var to include before YUI seed file
154                YUI_config = {
155                    filter: 'debug'
156                };
157
158                YUI().use('node', function (Y) {
159                    // debug files used here
160                });
161
162                YUI({
163                    filter: 'min'
164                }).use('node', function (Y) {
165                    // min files used here
166                });
167
168            @property {Object} YUI_config
169            @global
170            **/
171            if (gconf) {
172                Y.applyConfig(gconf);
173            }
174
175            // bind the specified additional modules for this instance
176            if (!l) {
177                Y._afterConfig();
178                Y._setup();
179            }
180        }
181
182        if (l) {
183            // Each instance can accept one or more configuration objects.
184            // These are applied after YUI.GlobalConfig and YUI_Config,
185            // overriding values set in those config files if there is a
186            // matching property.
187            for (; i < l; i++) {
188                Y.applyConfig(args[i]);
189            }
190
191            Y._afterConfig();
192            Y._setup();
193        }
194
195        Y.instanceOf = instanceOf;
196
197        return Y;
198    };
199
200(function() {
201
202    var proto, prop,
203        VERSION = 'patched-v3.18.1',
204        PERIOD = '.',
205        BASE = 'http://yui.yahooapis.com/',
206        /*
207            These CSS class names can't be generated by
208            getClassName since it is not available at the
209            time they are being used.
210        */
211        DOC_LABEL = 'yui3-js-enabled',
212        CSS_STAMP_EL = 'yui3-css-stamp',
213        NOOP = function() {},
214        SLICE = Array.prototype.slice,
215        APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
216                          'io.xdrResponse': 1,   // can call. this should
217                          'SWF.eventHandler': 1 }, // be done at build time
218        hasWin = (typeof window != 'undefined'),
219        win = (hasWin) ? window : null,
220        doc = (hasWin) ? win.document : null,
221        docEl = doc && doc.documentElement,
222        docClass = docEl && docEl.className,
223        instances = {},
224        time = new Date().getTime(),
225        add = function(el, type, fn, capture) {
226            if (el && el.addEventListener) {
227                el.addEventListener(type, fn, capture);
228            } else if (el && el.attachEvent) {
229                el.attachEvent('on' + type, fn);
230            }
231        },
232        remove = function(el, type, fn, capture) {
233            if (el && el.removeEventListener) {
234                // this can throw an uncaught exception in FF
235                try {
236                    el.removeEventListener(type, fn, capture);
237                } catch (ex) {}
238            } else if (el && el.detachEvent) {
239                el.detachEvent('on' + type, fn);
240            }
241        },
242        handleReady = function() {
243            YUI.Env.DOMReady = true;
244            if (hasWin) {
245                remove(doc, 'DOMContentLoaded', handleReady);
246            }
247        },
248        handleLoad = function() {
249            YUI.Env.windowLoaded = true;
250            YUI.Env.DOMReady = true;
251            if (hasWin) {
252                remove(window, 'load', handleLoad);
253            }
254        },
255        getLoader = function(Y, o) {
256            var loader = Y.Env._loader,
257                lCore = [ 'loader-base' ],
258                G_ENV = YUI.Env,
259                mods = G_ENV.mods;
260
261            if (loader) {
262                //loader._config(Y.config);
263                loader.ignoreRegistered = false;
264                loader.onEnd = null;
265                loader.data = null;
266                loader.required = [];
267                loader.loadType = null;
268            } else {
269                loader = new Y.Loader(Y.config);
270                Y.Env._loader = loader;
271            }
272            if (mods && mods.loader) {
273                lCore = [].concat(lCore, YUI.Env.loaderExtras);
274            }
275            YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
276
277            return loader;
278        },
279
280        clobber = function(r, s) {
281            for (var i in s) {
282                if (s.hasOwnProperty(i)) {
283                    r[i] = s[i];
284                }
285            }
286        },
287
288        ALREADY_DONE = { success: true };
289
290//  Stamp the documentElement (HTML) with a class of "yui-loaded" to
291//  enable styles that need to key off of JS being enabled.
292if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
293    if (docClass) {
294        docClass += ' ';
295    }
296    docClass += DOC_LABEL;
297    docEl.className = docClass;
298}
299
300if (VERSION.indexOf('@') > -1) {
301    VERSION = '3.5.0'; // dev time hack for cdn test
302}
303
304proto = {
305    /**
306    Applies a new configuration object to the config of this YUI instance. This
307    will merge new group/module definitions, and will also update the loader
308    cache if necessary. Updating `Y.config` directly will not update the cache.
309
310    @method applyConfig
311    @param {Object} o the configuration object.
312    @since 3.2.0
313    **/
314    applyConfig: function(o) {
315
316        o = o || NOOP;
317
318        var attr,
319            name,
320            // detail,
321            config = this.config,
322            mods = config.modules,
323            groups = config.groups,
324            aliases = config.aliases,
325            loader = this.Env._loader;
326
327        for (name in o) {
328            if (o.hasOwnProperty(name)) {
329                attr = o[name];
330                if (mods && name == 'modules') {
331                    clobber(mods, attr);
332                } else if (aliases && name == 'aliases') {
333                    clobber(aliases, attr);
334                } else if (groups && name == 'groups') {
335                    clobber(groups, attr);
336                } else if (name == 'win') {
337                    config[name] = (attr && attr.contentWindow) || attr;
338                    config.doc = config[name] ? config[name].document : null;
339                } else if (name == '_yuid') {
340                    // preserve the guid
341                } else {
342                    config[name] = attr;
343                }
344            }
345        }
346
347        if (loader) {
348            loader._config(o);
349        }
350
351    },
352
353    /**
354    Old way to apply a config to this instance (calls `applyConfig` under the
355    hood).
356
357    @private
358    @method _config
359    @param {Object} o The config to apply
360    **/
361    _config: function(o) {
362        this.applyConfig(o);
363    },
364
365    /**
366    Initializes this YUI instance.
367
368    @private
369    @method _init
370    **/
371    _init: function() {
372        var filter, el,
373            Y = this,
374            G_ENV = YUI.Env,
375            Env = Y.Env,
376            prop;
377
378        /**
379        The version number of this YUI instance.
380
381        This value is typically updated by a script when a YUI release is built,
382        so it may not reflect the correct version number when YUI is run from
383        the development source tree.
384
385        @property {String} version
386        **/
387        Y.version = VERSION;
388
389        if (!Env) {
390            Y.Env = {
391                core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'],
392                loaderExtras: ['loader-rollup', 'loader-yui3'],
393                mods: {}, // flat module map
394                versions: {}, // version module map
395                base: BASE,
396                cdn: BASE + VERSION + '/',
397                // bootstrapped: false,
398                _idx: 0,
399                _used: {},
400                _attached: {},
401                _exported: {},
402                _missed: [],
403                _yidx: 0,
404                _uidx: 0,
405                _guidp: 'y',
406                _loaded: {},
407                // serviced: {},
408                // Regex in English:
409                // I'll start at the \b(yui).
410                // 1. Look in the test string for "yui" or
411                //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
412                //    can't match "foyui" or "i_heart_yui". This can be anywhere in the string.
413                // 2. After #1 must come a forward slash followed by the string matched in #1, so
414                //    "yui-base/yui-base" or "yui-pants/yui-pants".
415                // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
416                //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
417                // 4. This is followed by ".js", so "yui/yui.js".
418                // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
419                //    then capture the junk between the LAST "&" and the string in 1-4.  So
420                //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
421                //    will capture "3.3.0/build/"
422                //
423                // Regex Exploded:
424                // (?:\?             Find a ?
425                //   (?:[^&]*&)      followed by 0..n characters followed by an &
426                //   *               in fact, find as many sets of characters followed by a & as you can
427                //   ([^&]*)         capture the stuff after the last & in \1
428                // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
429                // \b(               after a word break find either the string
430                //    yui(?:-\w+)?   "yui" optionally followed by a -, then more characters
431                // )                 and store the yui-* string in \2
432                // \/\2              then comes a / followed by the yui-* string in \2
433                // (?:-(min|debug))? optionally followed by "-min" or "-debug"
434                // .js               and ending in ".js"
435                _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(aui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
436                parseBasePath: function(src, pattern) {
437                    var match = src.match(pattern),
438                        path, filter;
439
440                    if (match) {
441                        path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
442
443                        // this is to set up the path to the loader.  The file
444                        // filter for loader should match the yui include.
445                        filter = match[3];
446
447                        // extract correct path for mixed combo urls
448                        // http://yuilibrary.com/projects/yui3/ticket/2528423
449                        if (match[1]) {
450                            path += '?' + match[1];
451                        }
452                        path = {
453                            filter: filter,
454                            path: path
455                        };
456                    }
457                    return path;
458                },
459                getBase: G_ENV && G_ENV.getBase ||
460                        function(pattern) {
461                            var nodes = (doc && doc.getElementsByTagName('script')) || [],
462                                path = Env.cdn, parsed,
463                                i, len, src;
464
465                            for (i = 0, len = nodes.length; i < len; ++i) {
466                                src = nodes[i].src;
467                                if (src) {
468                                    parsed = Y.Env.parseBasePath(src, pattern);
469                                    if (parsed) {
470                                        filter = parsed.filter;
471                                        path = parsed.path;
472                                        break;
473                                    }
474                                }
475                            }
476
477                            // use CDN default
478                            return path;
479                        }
480
481            };
482
483            Env = Y.Env;
484
485            Env._loaded[VERSION] = {};
486
487            if (G_ENV && Y !== YUI) {
488                Env._yidx = ++G_ENV._yidx;
489                Env._guidp = ('yui_' + VERSION + '_' +
490                             Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
491            } else if (YUI._YUI) {
492
493                G_ENV = YUI._YUI.Env;
494                Env._yidx += G_ENV._yidx;
495                Env._uidx += G_ENV._uidx;
496
497                for (prop in G_ENV) {
498                    if (!(prop in Env)) {
499                        Env[prop] = G_ENV[prop];
500                    }
501                }
502
503                delete YUI._YUI;
504            }
505
506            Y.id = Y.stamp(Y);
507            instances[Y.id] = Y;
508
509        }
510
511        Y.constructor = YUI;
512
513        // configuration defaults
514        Y.config = Y.config || {
515            bootstrap: true,
516            cacheUse: true,
517            debug: true,
518            doc: doc,
519            fetchCSS: true,
520            throwFail: true,
521            useBrowserConsole: true,
522            useNativeES5: true,
523            win: win
524        };
525
526        //Register the CSS stamp element
527        if (doc && !doc.getElementById(CSS_STAMP_EL)) {
528            el = doc.createElement('div');
529            el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
530            YUI.Env.cssStampEl = el.firstChild;
531            if (doc.body) {
532                doc.body.appendChild(YUI.Env.cssStampEl);
533            } else {
534                docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
535            }
536        } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
537            YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
538        }
539
540        Y.config.lang = Y.config.lang || 'en-US';
541
542        Y.config.base = YUI.config.base ||
543                (YUI.config.defaultBase && YUI.config.root && YUI.config.defaultBase + YUI.config.root) ||
544                Y.Env.getBase(Y.Env._BASE_RE);
545
546        if (!filter || (!('mindebug').indexOf(filter))) {
547            filter = 'min';
548        }
549        filter = (filter) ? '-' + filter : filter;
550        Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
551
552    },
553
554    /**
555    This method is called after all other configuration has been applied to
556    the YUI instance.
557
558    @method _afterConfig
559    @private
560    **/
561    _afterConfig: function () {
562        var Y = this;
563
564        // We need to set up Y.config.global after the rest of the configuration
565        // so that setting it in user configuration prevents the library from
566        // using eval(). This is critical for Content Security Policy enabled
567        // sites and other environments like Chrome extensions
568        if (!Y.config.hasOwnProperty('global')) {
569            Y.config.global = Function('return this')();
570        }
571    },
572
573    /**
574    Finishes the instance setup. Attaches whatever YUI modules were defined
575    at the time that this instance was created.
576
577    @method _setup
578    @private
579    **/
580    _setup: function() {
581        var i, Y = this,
582            core = [],
583            mods = YUI.Env.mods,
584            extendedCore = Y.config.extendedCore || [],
585            extras = Y.config.core || [].concat(YUI.Env.core).concat(extendedCore); //Clone it..
586   
587        for (i = 0; i < extras.length; i++) {
588            if (mods[extras[i]]) {
589                core.push(extras[i]);
590            }
591        }
592
593        Y._attach(['yui-base']);
594        Y._attach(core);
595
596        if (Y.Loader) {
597            getLoader(Y);
598        }
599
600    },
601
602    /**
603    Executes the named method on the specified YUI instance if that method is
604    whitelisted.
605
606    @method applyTo
607    @param {String} id YUI instance id.
608    @param {String} method Name of the method to execute. For example:
609        'Object.keys'.
610    @param {Array} args Arguments to apply to the method.
611    @return {Mixed} Return value from the applied method, or `null` if the
612        specified instance was not found or the method was not whitelisted.
613    **/
614    applyTo: function(id, method, args) {
615        if (!(method in APPLY_TO_AUTH)) {
616            this.log(method + ': applyTo not allowed', 'warn', 'yui');
617            return null;
618        }
619
620        var instance = instances[id], nest, m, i;
621        if (instance) {
622            nest = method.split('.');
623            m = instance;
624            for (i = 0; i < nest.length; i = i + 1) {
625                m = m[nest[i]];
626                if (!m) {
627                    this.log('applyTo not found: ' + method, 'warn', 'yui');
628                }
629            }
630            return m && m.apply(instance, args);
631        }
632
633        return null;
634    },
635
636/**
637Registers a YUI module and makes it available for use in a `YUI().use()` call or
638as a dependency for other modules.
639
640The easiest way to create a first-class YUI module is to use
641<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
642tool.
643
644Shifter will automatically wrap your module code in a `YUI.add()` call along
645with any configuration info required for the module.
646
647@example
648
649    YUI.add('davglass', function (Y) {
650        Y.davglass = function () {
651        };
652    }, '3.4.0', {
653        requires: ['harley-davidson', 'mt-dew']
654    });
655
656@method add
657@param {String} name Module name.
658@param {Function} fn Function containing module code. This function will be
659    executed whenever the module is attached to a specific YUI instance.
660
661    @param {YUI} fn.Y The YUI instance to which this module is attached.
662    @param {String} fn.name Name of the module
663
664@param {String} version Module version number. This is currently used only for
665    informational purposes, and is not used internally by YUI.
666
667@param {Object} [details] Module config.
668    @param {Array} [details.requires] Array of other module names that must be
669        attached before this module can be attached.
670    @param {Array} [details.optional] Array of optional module names that should
671        be attached before this module is attached if they've already been
672        loaded. If the `loadOptional` YUI option is `true`, optional modules
673        that have not yet been loaded will be loaded just as if they were hard
674        requirements.
675    @param {Array} [details.use] Array of module names that are included within
676        or otherwise provided by this module, and which should be attached
677        automatically when this module is attached. This makes it possible to
678        create "virtual rollup" modules that simply attach a collection of other
679        modules or submodules.
680
681@return {YUI} This YUI instance.
682**/
683    add: function(name, fn, version, details) {
684        details = details || {};
685        var env = YUI.Env,
686            mod = {
687                name: name,
688                fn: fn,
689                version: version,
690                details: details
691            },
692            //Instance hash so we don't apply it to the same instance twice
693            applied = {},
694            loader, inst, modInfo,
695            i, versions = env.versions;
696
697        env.mods[name] = mod;
698        versions[version] = versions[version] || {};
699        versions[version][name] = mod;
700
701        for (i in instances) {
702            if (instances.hasOwnProperty(i)) {
703                inst = instances[i];
704                if (!applied[inst.id]) {
705                    applied[inst.id] = true;
706                    loader = inst.Env._loader;
707                    if (loader) {
708                        modInfo = loader.getModuleInfo(name);
709                        if (!modInfo || modInfo.temp) {
710                            loader.addModule(details, name);
711                        }
712                    }
713                }
714            }
715        }
716
717        return this;
718    },
719
720    /**
721    Executes the callback function associated with each required module,
722    attaching the module to this YUI instance.
723
724    @method _attach
725    @param {Array} r The array of modules to attach
726    @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
727        is not attached.
728    @private
729    **/
730    _attach: function(r, moot) {
731        var i, name, mod, details, req, use, after,
732            mods = YUI.Env.mods,
733            aliases = YUI.Env.aliases,
734            Y = this, j,
735            cache = YUI.Env._renderedMods,
736            loader = Y.Env._loader,
737            done = Y.Env._attached,
738            exported = Y.Env._exported,
739            len = r.length, loader, def, go,
740            c = [],
741            modArgs, esCompat, reqlen, modInfo,
742            condition,
743            __exports__, __imports__;
744
745        //Check for conditional modules (in a second+ instance) and add their requirements
746        //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
747        for (i = 0; i < len; i++) {
748            name = r[i];
749            mod = mods[name];
750            c.push(name);
751            if (loader && loader.conditions[name]) {
752                for (j in loader.conditions[name]) {
753                    if (loader.conditions[name].hasOwnProperty(j)) {
754                        def = loader.conditions[name][j];
755                        go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
756                        if (go) {
757                            c.push(def.name);
758                        }
759                    }
760                }
761            }
762        }
763        r = c;
764        len = r.length;
765
766        for (i = 0; i < len; i++) {
767            if (!done[r[i]]) {
768                name = r[i];
769                mod = mods[name];
770
771                if (aliases && aliases[name] && !mod) {
772                    Y._attach(aliases[name]);
773                    continue;
774                }
775                if (!mod) {
776                    modInfo = loader && loader.getModuleInfo(name);
777                    if (modInfo) {
778                        mod = modInfo;
779                        moot = true;
780                    }
781
782
783                    //if (!loader || !loader.moduleInfo[name]) {
784                    //if ((!loader || !loader.moduleInfo[name]) && !moot) {
785                    if (!moot && name) {
786                        if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
787                            Y.Env._missed.push(name);
788                            Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
789                            Y.message('NOT loaded: ' + name, 'warn', 'yui');
790                        }
791                    }
792                } else {
793                    done[name] = true;
794                    //Don't like this, but in case a mod was asked for once, then we fetch it
795                    //We need to remove it from the missed list ^davglass
796                    for (j = 0; j < Y.Env._missed.length; j++) {
797                        if (Y.Env._missed[j] === name) {
798                            Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
799                            Y.Env._missed.splice(j, 1);
800                        }
801                    }
802
803                    // Optional dependencies normally work by modifying the
804                    // dependency list of a module. If the dependency's test
805                    // passes it is added to the list. If not, it's not loaded.
806                    // This following check ensures that optional dependencies
807                    // are not attached when they were already loaded into the
808                    // page (when bundling for example)
809                    if (loader && !loader._canBeAttached(name)) {
810                        return true;
811                    }
812
813                    /*
814                        If it's a temp module, we need to redo it's requirements if it's already loaded
815                        since it may have been loaded by another instance and it's dependencies might
816                        have been redefined inside the fetched file.
817                    */
818                    if (loader && cache && cache[name] && cache[name].temp) {
819                        loader.getRequires(cache[name]);
820                        req = [];
821                        modInfo = loader.getModuleInfo(name);
822                        for (j in modInfo.expanded_map) {
823                            if (modInfo.expanded_map.hasOwnProperty(j)) {
824                                req.push(j);
825                            }
826                        }
827                        Y._attach(req);
828                    }
829
830                    details = mod.details;
831                    req = details.requires;
832                    esCompat = details.es;
833                    use = details.use;
834                    after = details.after;
835                    //Force Intl load if there is a language (Loader logic) @todo fix this shit
836                    if (details.lang) {
837                        req = req || [];
838                        req.unshift('intl');
839                    }
840
841                    if (req) {
842                        reqlen = req.length;
843                        for (j = 0; j < reqlen; j++) {
844                            if (!done[req[j]]) {
845                                if (!Y._attach(req)) {
846                                    return false;
847                                }
848                                break;
849                            }
850                        }
851                    }
852
853                    if (after) {
854                        for (j = 0; j < after.length; j++) {
855                            if (!done[after[j]]) {
856                                if (!Y._attach(after, true)) {
857                                    return false;
858                                }
859                                break;
860                            }
861                        }
862                    }
863
864                    if (mod.fn) {
865                        modArgs = [Y, name];
866                        if (esCompat) {
867                            __imports__ = {};
868                            __exports__ = {};
869                            // passing `exports` and `imports` onto the module function
870                            modArgs.push(__imports__, __exports__);
871                            if (req) {
872                                reqlen = req.length;
873                                for (j = 0; j < reqlen; j++) {
874                                    __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y;
875                                }
876                            }
877                        }
878                        if (Y.config.throwFail) {
879                            __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
880                        } else {
881                            try {
882                                __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
883                            } catch (e) {
884                                Y.error('Attach error: ' + name, e, name);
885                                return false;
886                            }
887                        }
888                        if (esCompat) {
889                            // store the `exports` in case others `es` modules requires it
890                            exported[name] = __exports__;
891
892                            // If an ES module is conditionally loaded and set
893                            // to be used "instead" another module, replace the
894                            // trigger module's content with the conditionally
895                            // loaded one so the values returned by require()
896                            // still makes sense
897                            condition = mod.details.condition;
898                            if (condition && condition.when === 'instead') {
899                                exported[condition.trigger] = __exports__;
900                            }
901                        }
902                    }
903
904                    if (use) {
905                        for (j = 0; j < use.length; j++) {
906                            if (!done[use[j]]) {
907                                if (!Y._attach(use)) {
908                                    return false;
909                                }
910                                break;
911                            }
912                        }
913                    }
914
915
916
917                }
918            }
919        }
920
921        return true;
922    },
923
924    /**
925    Delays the `use` callback until another event has taken place such as
926    `window.onload`, `domready`, `contentready`, or `available`.
927
928    @private
929    @method _delayCallback
930    @param {Function} cb The original `use` callback.
931    @param {String|Object} until Either an event name ('load', 'domready', etc.)
932        or an object containing event/args keys for contentready/available.
933    @return {Function}
934    **/
935    _delayCallback: function(cb, until) {
936
937        var Y = this,
938            mod = ['event-base'];
939
940        until = (Y.Lang.isObject(until) ? until : { event: until });
941
942        if (until.event === 'load') {
943            mod.push('event-synthetic');
944        }
945
946        return function() {
947            var args = arguments;
948            Y._use(mod, function() {
949                Y.on(until.event, function() {
950                    args[1].delayUntil = until.event;
951                    cb.apply(Y, args);
952                }, until.args);
953            });
954        };
955    },
956
957    /**
958    Attaches one or more modules to this YUI instance. When this is executed,
959    the requirements of the desired modules are analyzed, and one of several
960    things can happen:
961
962
963      * All required modules have already been loaded, and just need to be
964        attached to this YUI instance. In this case, the `use()` callback will
965        be executed synchronously after the modules are attached.
966
967      * One or more modules have not yet been loaded, or the Get utility is not
968        available, or the `bootstrap` config option is `false`. In this case,
969        a warning is issued indicating that modules are missing, but all
970        available modules will still be attached and the `use()` callback will
971        be executed synchronously.
972
973      * One or more modules are missing and the Loader is not available but the
974        Get utility is, and `bootstrap` is not `false`. In this case, the Get
975        utility will be used to load the Loader, and we will then proceed to
976        the following state:
977
978      * One or more modules are missing and the Loader is available. In this
979        case, the Loader will be used to resolve the dependency tree for the
980        missing modules and load them and their dependencies. When the Loader is
981        finished loading modules, the `use()` callback will be executed
982        asynchronously.
983
984    @example
985
986        // Loads and attaches dd and its dependencies.
987        YUI().use('dd', function (Y) {
988            // ...
989        });
990
991        // Loads and attaches dd and node as well as all of their dependencies.
992        YUI().use(['dd', 'node'], function (Y) {
993            // ...
994        });
995
996        // Attaches all modules that have already been loaded.
997        YUI().use('*', function (Y) {
998            // ...
999        });
1000
1001        // Attaches a gallery module.
1002        YUI().use('gallery-yql', function (Y) {
1003            // ...
1004        });
1005
1006        // Attaches a YUI 2in3 module.
1007        YUI().use('yui2-datatable', function (Y) {
1008            // ...
1009        });
1010
1011    @method use
1012    @param {String|Array} modules* One or more module names to attach.
1013    @param {Function} [callback] Callback function to be executed once all
1014        specified modules and their dependencies have been attached.
1015    @param {YUI} callback.Y The YUI instance created for this sandbox.
1016    @param {Object} callback.status Object containing `success`, `msg` and
1017        `data` properties.
1018    @chainable
1019    **/
1020    use: function() {
1021        var args = SLICE.call(arguments, 0),
1022            callback = args[args.length - 1],
1023            Y = this,
1024            i = 0,
1025            name,
1026            Env = Y.Env,
1027            provisioned = true;
1028
1029        // The last argument supplied to use can be a load complete callback
1030        if (Y.Lang.isFunction(callback)) {
1031            args.pop();
1032            if (Y.config.delayUntil) {
1033                callback = Y._delayCallback(callback, Y.config.delayUntil);
1034            }
1035        } else {
1036            callback = null;
1037        }
1038        if (Y.Lang.isArray(args[0])) {
1039            args = args[0];
1040        }
1041
1042        if (Y.config.cacheUse) {
1043            while ((name = args[i++])) {
1044                if (!Env._attached[name]) {
1045                    provisioned = false;
1046                    break;
1047                }
1048            }
1049
1050            if (provisioned) {
1051                if (args.length) {
1052                }
1053                Y._notify(callback, ALREADY_DONE, args);
1054                return Y;
1055            }
1056        }
1057
1058        if (Y._loading) {
1059            Y._useQueue = Y._useQueue || new Y.Queue();
1060            Y._useQueue.add([args, callback]);
1061        } else {
1062            Y._use(args, function(Y, response) {
1063                Y._notify(callback, response, args);
1064            });
1065        }
1066
1067        return Y;
1068    },
1069
1070    /**
1071    Sugar for loading both legacy and ES6-based YUI modules.
1072
1073    @method require
1074    @param {String} [modules*] List of module names to import or a single
1075        module name.
1076    @param {Function} callback Callback that gets called once all the modules
1077        were loaded. Each parameter of the callback is the export value of the
1078        corresponding module in the list. If the module is a legacy YUI module,
1079        the YUI instance is used instead of the module exports.
1080    @example
1081    ```
1082    YUI().require(['es6-set'], function (Y, imports) {
1083        var Set = imports.Set,
1084            set = new Set();
1085    });
1086    ```
1087    **/
1088    require: function () {
1089        var args = SLICE.call(arguments),
1090            callback;
1091
1092        if (typeof args[args.length - 1] === 'function') {
1093            callback = args.pop();
1094
1095            // only add the callback if one was provided
1096            // YUI().require('foo'); is valid
1097            args.push(function (Y) {
1098                var i, length = args.length,
1099                    exported = Y.Env._exported,
1100                    __imports__ = {};
1101
1102                // Get only the imports requested as arguments
1103                for (i = 0; i < length; i++) {
1104                    if (exported.hasOwnProperty(args[i])) {
1105                        __imports__[args[i]] = exported[args[i]];
1106                    }
1107                }
1108
1109                // Using `undefined` because:
1110                // - Using `Y.config.global` would force the value of `this` to be
1111                //   the global object even in strict mode
1112                // - Using `Y` goes against the goal of moving away from a shared
1113                //   object and start thinking in terms of imported and exported
1114                //   objects
1115                callback.call(undefined, Y, __imports__);
1116            });
1117        }
1118        // Do not return the Y object. This makes it hard to follow this
1119        // traditional pattern:
1120        //   var Y = YUI().use(...);
1121        // This is a good idea in the light of ES6 modules, to avoid working
1122        // in the global scope.
1123        // This also leaves the door open for returning a promise, once the
1124        // YUI loader is based on the ES6 loader which uses
1125        // loader.import(...).then(...)
1126        this.use.apply(this, args);
1127    },
1128
1129    /**
1130    Handles Loader notifications about attachment/load errors.
1131
1132    @method _notify
1133    @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
1134    @param {Object} response Response returned from Loader.
1135    @param {Array} args Arguments passed from Loader.
1136    @private
1137    **/
1138    _notify: function(callback, response, args) {
1139        if (!response.success && this.config.loadErrorFn) {
1140            this.config.loadErrorFn.call(this, this, callback, response, args);
1141        } else if (callback) {
1142            if (this.Env._missed && this.Env._missed.length) {
1143                response.msg = 'Missing modules: ' + this.Env._missed.join();
1144                response.success = false;
1145            }
1146            if (this.config.throwFail) {
1147                callback(this, response);
1148            } else {
1149                try {
1150                    callback(this, response);
1151                } catch (e) {
1152                    this.error('use callback error', e, args);
1153                }
1154            }
1155        }
1156    },
1157
1158    /**
1159    Called from the `use` method queue to ensure that only one set of loading
1160    logic is performed at a time.
1161
1162    @method _use
1163    @param {String} args* One or more modules to attach.
1164    @param {Function} [callback] Function to call once all required modules have
1165        been attached.
1166    @private
1167    **/
1168    _use: function(args, callback) {
1169
1170        if (!this.Array) {
1171            this._attach(['yui-base']);
1172        }
1173
1174        var len, loader, handleBoot,
1175            Y = this,
1176            G_ENV = YUI.Env,
1177            mods = G_ENV.mods,
1178            Env = Y.Env,
1179            used = Env._used,
1180            aliases = G_ENV.aliases,
1181            queue = G_ENV._loaderQueue,
1182            firstArg = args[0],
1183            YArray = Y.Array,
1184            config = Y.config,
1185            boot = config.bootstrap,
1186            missing = [],
1187            i,
1188            r = [],
1189            ret = true,
1190            fetchCSS = config.fetchCSS,
1191            process = function(names, skip) {
1192
1193                var i = 0, a = [], name, len, m, req, use;
1194
1195                if (!names.length) {
1196                    return;
1197                }
1198
1199                if (aliases) {
1200                    len = names.length;
1201                    for (i = 0; i < len; i++) {
1202                        if (aliases[names[i]] && !mods[names[i]]) {
1203                            a = [].concat(a, aliases[names[i]]);
1204                        } else {
1205                            a.push(names[i]);
1206                        }
1207                    }
1208                    names = a;
1209                }
1210
1211                len = names.length;
1212
1213                for (i = 0; i < len; i++) {
1214                    name = names[i];
1215                    if (!skip) {
1216                        r.push(name);
1217                    }
1218
1219                    // only attach a module once
1220                    if (used[name]) {
1221                        continue;
1222                    }
1223
1224                    m = mods[name];
1225                    req = null;
1226                    use = null;
1227
1228                    if (m) {
1229                        used[name] = true;
1230                        req = m.details.requires;
1231                        use = m.details.use;
1232                    } else {
1233                        // CSS files don't register themselves, see if it has
1234                        // been loaded
1235                        if (!G_ENV._loaded[VERSION][name]) {
1236                            missing.push(name);
1237                        } else {
1238                            used[name] = true; // probably css
1239                        }
1240                    }
1241
1242                    // make sure requirements are attached
1243                    if (req && req.length) {
1244                        process(req);
1245                    }
1246
1247                    // make sure we grab the submodule dependencies too
1248                    if (use && use.length) {
1249                        process(use, 1);
1250                    }
1251                }
1252
1253            },
1254
1255            handleLoader = function(fromLoader) {
1256                var response = fromLoader || {
1257                        success: true,
1258                        msg: 'not dynamic'
1259                    },
1260                    redo, origMissing,
1261                    ret = true,
1262                    data = response.data;
1263
1264                Y._loading = false;
1265
1266                if (data) {
1267                    origMissing = missing;
1268                    missing = [];
1269                    r = [];
1270                    process(data);
1271                    redo = missing.length;
1272                    if (redo) {
1273                        if ([].concat(missing).sort().join() ==
1274                                origMissing.sort().join()) {
1275                            redo = false;
1276                        }
1277                    }
1278                }
1279
1280                if (redo && data) {
1281                    Y._loading = true;
1282                    Y._use(missing, function() {
1283                        if (Y._attach(data)) {
1284                            Y._notify(callback, response, data);
1285                        }
1286                    });
1287                } else {
1288                    if (data) {
1289                        ret = Y._attach(data);
1290                    }
1291                    if (ret) {
1292                        Y._notify(callback, response, args);
1293                    }
1294                }
1295
1296                if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1297                    Y._use.apply(Y, Y._useQueue.next());
1298                }
1299
1300            };
1301
1302
1303        // YUI().use('*'); // bind everything available
1304        if (firstArg === '*') {
1305            args = [];
1306            for (i in mods) {
1307                if (mods.hasOwnProperty(i)) {
1308                    args.push(i);
1309                }
1310            }
1311            ret = Y._attach(args);
1312            if (ret) {
1313                handleLoader();
1314            }
1315            return Y;
1316        }
1317
1318        if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1319            Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1320        }
1321
1322
1323        // use loader to expand dependencies and sort the
1324        // requirements if it is available.
1325        if (boot && Y.Loader && args.length) {
1326            loader = getLoader(Y);
1327            loader.require(args);
1328            loader.ignoreRegistered = true;
1329            loader._boot = true;
1330            loader.calculate(null, (fetchCSS) ? null : 'js');
1331            args = loader.sorted;
1332            loader._boot = false;
1333        }
1334
1335        process(args);
1336
1337        len = missing.length;
1338
1339
1340        if (len) {
1341            missing = YArray.dedupe(missing);
1342            len = missing.length;
1343        }
1344
1345
1346        // dynamic load
1347        if (boot && len && Y.Loader) {
1348            Y._loading = true;
1349            loader = getLoader(Y);
1350            loader.onEnd = handleLoader;
1351            loader.context = Y;
1352            loader.data = args;
1353            loader.ignoreRegistered = false;
1354            loader.require(missing);
1355            loader.insert(null, (fetchCSS) ? null : 'js');
1356
1357        } else if (boot && len && Y.Get && !Env.bootstrapped) {
1358
1359            Y._loading = true;
1360
1361            handleBoot = function() {
1362                Y._loading = false;
1363                queue.running = false;
1364                Env.bootstrapped = true;
1365                G_ENV._bootstrapping = false;
1366                if (Y._attach(['loader'])) {
1367                    Y._use(args, callback);
1368                }
1369            };
1370
1371            if (G_ENV._bootstrapping) {
1372                queue.add(handleBoot);
1373            } else {
1374                G_ENV._bootstrapping = true;
1375                Y.Get.script(config.base + config.loaderPath, {
1376                    onEnd: handleBoot
1377                });
1378            }
1379
1380        } else {
1381            ret = Y._attach(args);
1382            if (ret) {
1383                handleLoader();
1384            }
1385        }
1386
1387        return Y;
1388    },
1389
1390
1391    /**
1392    Utility method for safely creating namespaces if they don't already exist.
1393    May be called statically on the YUI global object or as a method on a YUI
1394    instance.
1395
1396    When called statically, a namespace will be created on the YUI global
1397    object:
1398
1399        // Create `YUI.your.namespace.here` as nested objects, preserving any
1400        // objects that already exist instead of overwriting them.
1401        YUI.namespace('your.namespace.here');
1402
1403    When called as a method on a YUI instance, a namespace will be created on
1404    that instance:
1405
1406        // Creates `Y.property.package`.
1407        Y.namespace('property.package');
1408
1409    Dots in the input string cause `namespace` to create nested objects for each
1410    token. If any part of the requested namespace already exists, the current
1411    object will be left in place and will not be overwritten. This allows
1412    multiple calls to `namespace` to preserve existing namespaced properties.
1413
1414    If the first token in the namespace string is "YAHOO", that token is
1415    discarded. This is legacy behavior for backwards compatibility with YUI 2.
1416
1417    Be careful with namespace tokens. Reserved words may work in some browsers
1418    and not others. For instance, the following will fail in some browsers
1419    because the supported version of JavaScript reserves the word "long":
1420
1421        Y.namespace('really.long.nested.namespace');
1422
1423    Note: If you pass multiple arguments to create multiple namespaces, only the
1424    last one created is returned from this function.
1425
1426    @method namespace
1427    @param {String} namespace* One or more namespaces to create.
1428    @return {Object} Reference to the last namespace object created.
1429    **/
1430    namespace: function() {
1431        var a = arguments, o, i = 0, j, d, arg;
1432
1433        for (; i < a.length; i++) {
1434            o = this; //Reset base object per argument or it will get reused from the last
1435            arg = a[i];
1436            if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1437                d = arg.split(PERIOD);
1438                for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1439                    o[d[j]] = o[d[j]] || {};
1440                    o = o[d[j]];
1441                }
1442            } else {
1443                o[arg] = o[arg] || {};
1444                o = o[arg]; //Reset base object to the new object so it's returned
1445            }
1446        }
1447        return o;
1448    },
1449
1450    // this is replaced if the log module is included
1451    log: NOOP,
1452    message: NOOP,
1453    // this is replaced if the dump module is included
1454    dump: function (o) { return ''+o; },
1455
1456    /**
1457    Reports an error.
1458
1459    The reporting mechanism is controlled by the `throwFail` configuration
1460    attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1461    truthy, a JS exception is thrown.
1462
1463    If an `errorFn` is specified in the config it must return `true` to indicate
1464    that the exception was handled and keep it from being thrown.
1465
1466    @method error
1467    @param {String} msg Error message.
1468    @param {Error|String} [e] JavaScript error object or an error string.
1469    @param {String} [src] Source of the error (such as the name of the module in
1470        which the error occurred).
1471    @chainable
1472    **/
1473    error: function(msg, e, src) {
1474        //TODO Add check for window.onerror here
1475
1476        var Y = this, ret;
1477
1478        if (Y.config.errorFn) {
1479            ret = Y.config.errorFn.apply(Y, arguments);
1480        }
1481
1482        if (!ret) {
1483            throw (e || new Error(msg));
1484        } else {
1485            Y.message(msg, 'error', ''+src); // don't scrub this one
1486        }
1487
1488        return Y;
1489    },
1490
1491    /**
1492    Generates an id string that is unique among all YUI instances in this
1493    execution context.
1494
1495    @method guid
1496    @param {String} [pre] Prefix.
1497    @return {String} Unique id.
1498    **/
1499    guid: function(pre) {
1500        var id = this.Env._guidp + '_' + (++this.Env._uidx);
1501        return (pre) ? (pre + id) : id;
1502    },
1503
1504    /**
1505    Returns a unique id associated with the given object and (if *readOnly* is
1506    falsy) stamps the object with that id so it can be identified in the future.
1507
1508    Stamping an object involves adding a `_yuid` property to it that contains
1509    the object's id. One exception to this is that in Internet Explorer, DOM
1510    nodes have a `uniqueID` property that contains a browser-generated unique
1511    id, which will be used instead of a YUI-generated id when available.
1512
1513    @method stamp
1514    @param {Object} o Object to stamp.
1515    @param {Boolean} readOnly If truthy and the given object has not already
1516        been stamped, the object will not be modified and `null` will be
1517        returned.
1518    @return {String} Object's unique id, or `null` if *readOnly* was truthy and
1519        the given object was not already stamped.
1520    **/
1521    stamp: function(o, readOnly) {
1522        var uid;
1523        if (!o) {
1524            return o;
1525        }
1526
1527        // IE generates its own unique ID for dom nodes
1528        // The uniqueID property of a document node returns a new ID
1529        if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1530            uid = o.uniqueID;
1531        } else {
1532            uid = (typeof o === 'string') ? o : o._yuid;
1533        }
1534
1535        if (!uid) {
1536            uid = this.guid();
1537            if (!readOnly) {
1538                try {
1539                    o._yuid = uid;
1540                } catch (e) {
1541                    uid = null;
1542                }
1543            }
1544        }
1545        return uid;
1546    },
1547
1548    /**
1549    Destroys this YUI instance.
1550
1551    @method destroy
1552    @since 3.3.0
1553    **/
1554    destroy: function() {
1555        var Y = this;
1556        if (Y.Event) {
1557            Y.Event._unload();
1558        }
1559        delete instances[Y.id];
1560        delete Y.Env;
1561        delete Y.config;
1562    }
1563
1564    /**
1565    Safe `instanceof` wrapper that works around a memory leak in IE when the
1566    object being tested is `window` or `document`.
1567
1568    Unless you are testing objects that may be `window` or `document`, you
1569    should use the native `instanceof` operator instead of this method.
1570
1571    @method instanceOf
1572    @param {Object} o Object to check.
1573    @param {Object} type Class to check against.
1574    @since 3.3.0
1575    **/
1576};
1577
1578    YUI.prototype = proto;
1579
1580    // inheritance utilities are not available yet
1581    for (prop in proto) {
1582        if (proto.hasOwnProperty(prop)) {
1583            YUI[prop] = proto[prop];
1584        }
1585    }
1586
1587    /**
1588    Applies a configuration to all YUI instances in this execution context.
1589
1590    The main use case for this method is in "mashups" where several third-party
1591    scripts need to write to a global YUI config, but cannot share a single
1592    centrally-managed config object. This way they can all call
1593    `YUI.applyConfig({})` instead of overwriting the single global config.
1594
1595    @example
1596
1597        YUI.applyConfig({
1598            modules: {
1599                davglass: {
1600                    fullpath: './davglass.js'
1601                }
1602            }
1603        });
1604
1605        YUI.applyConfig({
1606            modules: {
1607                foo: {
1608                    fullpath: './foo.js'
1609                }
1610            }
1611        });
1612
1613        YUI().use('davglass', function (Y) {
1614            // Module davglass will be available here.
1615        });
1616
1617    @method applyConfig
1618    @param {Object} o Configuration object to apply.
1619    @static
1620    @since 3.5.0
1621    **/
1622    YUI.applyConfig = function(o) {
1623        if (!o) {
1624            return;
1625        }
1626        //If there is a GlobalConfig, apply it first to set the defaults
1627        if (YUI.GlobalConfig) {
1628            this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1629        }
1630        //Apply this config to it
1631        this.prototype.applyConfig.call(this, o);
1632        //Reset GlobalConfig to the combined config
1633        YUI.GlobalConfig = this.config;
1634    };
1635
1636    // set up the environment
1637    YUI._init();
1638
1639    if (hasWin) {
1640        add(doc, 'DOMContentLoaded', handleReady);
1641
1642        // add a window load event at load time so we can capture
1643        // the case where it fires before dynamic loading is
1644        // complete.
1645        add(window, 'load', handleLoad);
1646    } else {
1647        handleReady();
1648        handleLoad();
1649    }
1650
1651    YUI.Env.add = add;
1652    YUI.Env.remove = remove;
1653
1654    /*global exports*/
1655    // Support the CommonJS method for exporting our single global
1656    if (typeof exports == 'object') {
1657        exports.YUI = YUI;
1658        /**
1659        * Set a method to be called when `Get.script` is called in Node.js
1660        * `Get` will open the file, then pass it's content and it's path
1661        * to this method before attaching it. Commonly used for code coverage
1662        * instrumentation. <strong>Calling this multiple times will only
1663        * attach the last hook method</strong>. This method is only
1664        * available in Node.js.
1665        * @method setLoadHook
1666        * @static
1667        * @param {Function} fn The function to set
1668        * @param {String} fn.data The content of the file
1669        * @param {String} fn.path The file path of the file
1670        */
1671        YUI.setLoadHook = function(fn) {
1672            YUI._getLoadHook = fn;
1673        };
1674        /**
1675        * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1676        * @method _getLoadHook
1677        * @private
1678        * @param {String} data The content of the file
1679        * @param {String} path The file path of the file
1680        */
1681        YUI._getLoadHook = null;
1682    }
1683
1684    YUI.Env[VERSION] = {};
1685}());
1686
1687
1688/**
1689Config object that contains all of the configuration options for
1690this `YUI` instance.
1691
1692This object is supplied by the implementer when instantiating YUI. Some
1693properties have default values if they are not supplied by the implementer.
1694
1695This object should not be updated directly because some values are cached. Use
1696`applyConfig()` to update the config object on a YUI instance that has already
1697been configured.
1698
1699@class config
1700@static
1701**/
1702
1703/**
1704If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1705if they're needed to load additional dependencies and aren't already available.
1706
1707Setting this to `false` will prevent YUI from automatically loading the Loader
1708and module metadata, so you will need to manually ensure that they're available
1709or handle dependency resolution yourself.
1710
1711@property {Boolean} bootstrap
1712@default true
1713**/
1714
1715/**
1716
1717@property {Object} filters
1718**/
1719
1720/**
1721If `true`, YUI will use a combo handler to load multiple modules in as few
1722requests as possible.
1723
1724The YUI CDN (which YUI uses by default) supports combo handling, but other
1725servers may not. If the server from which you're loading YUI does not support
1726combo handling, set this to `false`.
1727
1728Providing a value for the `base` config property will cause `combine` to default
1729to `false` instead of `true`.
1730
1731@property {Boolean} combine
1732@default true
1733*/
1734
1735/**
1736Array of module names that should never be dynamically loaded.
1737
1738@property {String[]} ignore
1739**/
1740
1741/**
1742Array of module names that should always be loaded when required, even if
1743already present on the page.
1744
1745@property {String[]} force
1746**/
1747
1748/**
1749DOM element or id that should be used as the insertion point for dynamically
1750added `<script>` and `<link>` nodes.
1751
1752@property {HTMLElement|String} insertBefore
1753**/
1754
1755/**
1756Object hash containing attributes to add to dynamically added `<script>` nodes.
1757
1758@property {Object} jsAttributes
1759**/
1760
1761/**
1762Object hash containing attributes to add to dynamically added `<link>` nodes.
1763
1764@property {Object} cssAttributes
1765**/
1766
1767/**
1768Timeout in milliseconds before a dynamic JS or CSS request will be considered a
1769failure. If not set, no timeout will be enforced.
1770
1771@property {Number} timeout
1772**/
1773
1774/**
1775A hash of module definitions to add to the list of available YUI modules. These
1776modules can then be dynamically loaded via the `use()` method.
1777
1778This is a hash in which keys are module names and values are objects containing
1779module metadata.
1780
1781See `Loader.addModule()` for the supported module metadata fields. Also see
1782`groups`, which provides a way to configure the base and combo spec for a set of
1783modules.
1784
1785@example
1786
1787    modules: {
1788        mymod1: {
1789            requires: ['node'],
1790            fullpath: '/mymod1/mymod1.js'
1791        },
1792
1793        mymod2: {
1794            requires: ['mymod1'],
1795            fullpath: '/mymod2/mymod2.js'
1796        },
1797
1798        mymod3: '/js/mymod3.js',
1799        mycssmod: '/css/mycssmod.css'
1800    }
1801
1802@property {Object} modules
1803**/
1804
1805/**
1806Aliases are dynamic groups of modules that can be used as shortcuts.
1807
1808@example
1809
1810    YUI({
1811        aliases: {
1812            davglass: [ 'node', 'yql', 'dd' ],
1813            mine: [ 'davglass', 'autocomplete']
1814        }
1815    }).use('mine', function (Y) {
1816        // Node, YQL, DD & AutoComplete available here.
1817    });
1818
1819@property {Object} aliases
1820**/
1821
1822/**
1823A hash of module group definitions.
1824
1825For each group you can specify a list of modules and the base path and
1826combo spec to use when dynamically loading the modules.
1827
1828@example
1829
1830    groups: {
1831        yui2: {
1832            // specify whether or not this group has a combo service
1833            combine: true,
1834
1835            // The comboSeperator to use with this group's combo handler
1836            comboSep: ';',
1837
1838            // The maxURLLength for this server
1839            maxURLLength: 500,
1840
1841            // the base path for non-combo paths
1842            base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1843
1844            // the path to the combo service
1845            comboBase: 'http://yui.yahooapis.com/combo?',
1846
1847            // a fragment to prepend to the path attribute when
1848            // when building combo urls
1849            root: '2.8.0r4/build/',
1850
1851            // the module definitions
1852            modules:  {
1853                yui2_yde: {
1854                    path: "yahoo-dom-event/yahoo-dom-event.js"
1855                },
1856                yui2_anim: {
1857                    path: "animation/animation.js",
1858                    requires: ['yui2_yde']
1859                }
1860            }
1861        }
1862    }
1863
1864@property {Object} groups
1865**/
1866
1867/**
1868Path to the Loader JS file, relative to the `base` path.
1869
1870This is used to dynamically bootstrap the Loader when it's needed and isn't yet
1871available.
1872
1873@property {String} loaderPath
1874@default "loader/loader-min.js"
1875**/
1876
1877/**
1878If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
1879`false` to prevent YUI from loading any CSS, or set it to the string `"force"`
1880to force CSS dependencies to be loaded even if their associated JS modules are
1881already loaded.
1882
1883@property {Boolean|String} fetchCSS
1884@default true
1885**/
1886
1887/**
1888Default gallery version used to build gallery module urls.
1889
1890@property {String} gallery
1891@since 3.1.0
1892**/
1893
1894/**
1895Default YUI 2 version used to build YUI 2 module urls.
1896
1897This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
1898`2in3` config for pulling different revisions of the wrapped YUI 2 modules.
1899
1900@property {String} yui2
1901@default "2.9.0"
1902@since 3.1.0
1903**/
1904
1905/**
1906Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
1907
1908@property {String} 2in3
1909@default "4"
1910@since 3.1.0
1911**/
1912
1913/**
1914Alternate console log function that should be used in environments without a
1915supported native console. This function is executed with the YUI instance as its
1916`this` object.
1917
1918@property {Function} logFn
1919@since 3.1.0
1920**/
1921
1922/**
1923The minimum log level to log messages for. Log levels are defined
1924incrementally. Messages greater than or equal to the level specified will
1925be shown. All others will be discarded. The order of log levels in
1926increasing priority is:
1927
1928    debug
1929    info
1930    warn
1931    error
1932
1933@property {String} logLevel
1934@default 'debug'
1935@since 3.10.0
1936**/
1937
1938/**
1939Callback to execute when `Y.error()` is called. It receives the error message
1940and a JavaScript error object if one was provided.
1941
1942This function is executed with the YUI instance as its `this` object.
1943
1944Returning `true` from this function will prevent an exception from being thrown.
1945
1946@property {Function} errorFn
1947@param {String} errorFn.msg Error message
1948@param {Object} [errorFn.err] Error object (if one was provided).
1949@since 3.2.0
1950**/
1951
1952/**
1953A callback to execute when Loader fails to load one or more resources.
1954
1955This could be because of a script load failure. It could also be because a
1956module fails to register itself when the `requireRegistration` config is `true`.
1957
1958If this function is defined, the `use()` callback will only be called when the
1959loader succeeds. Otherwise, `use()` will always executes unless there was a
1960JavaScript error when attaching a module.
1961
1962@property {Function} loadErrorFn
1963@since 3.3.0
1964**/
1965
1966/**
1967If `true`, Loader will expect all loaded scripts to be first-class YUI modules
1968that register themselves with the YUI global, and will trigger a failure if a
1969loaded script does not register a YUI module.
1970
1971@property {Boolean} requireRegistration
1972@default false
1973@since 3.3.0
1974**/
1975
1976/**
1977Cache serviced use() requests.
1978
1979@property {Boolean} cacheUse
1980@default true
1981@since 3.3.0
1982@deprecated No longer used.
1983**/
1984
1985/**
1986Whether or not YUI should use native ES5 functionality when available for
1987features like `Y.Array.each()`, `Y.Object()`, etc.
1988
1989When `false`, YUI will always use its own fallback implementations instead of
1990relying on ES5 functionality, even when ES5 functionality is available.
1991
1992@property {Boolean} useNativeES5
1993@default true
1994@since 3.5.0
1995**/
1996
1997/**
1998 * Leverage native JSON stringify if the browser has a native
1999 * implementation.  In general, this is a good idea.  See the Known Issues
2000 * section in the JSON user guide for caveats.  The default value is true
2001 * for browsers with native JSON support.
2002 *
2003 * @property useNativeJSONStringify
2004 * @type Boolean
2005 * @default true
2006 * @since 3.8.0
2007 */
2008
2009 /**
2010 * Leverage native JSON parse if the browser has a native implementation.
2011 * In general, this is a good idea.  See the Known Issues section in the
2012 * JSON user guide for caveats.  The default value is true for browsers with
2013 * native JSON support.
2014 *
2015 * @property useNativeJSONParse
2016 * @type Boolean
2017 * @default true
2018 * @since 3.8.0
2019 */
2020
2021/**
2022Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
2023
2024@property {Object|String} delayUntil
2025@since 3.6.0
2026@example
2027
2028You can use `load` or `domready` strings by default:
2029
2030    YUI({
2031        delayUntil: 'domready'
2032    }, function (Y) {
2033        // This will not execute until 'domeready' occurs.
2034    });
2035
2036Or you can delay until a node is available (with `available` or `contentready`):
2037
2038    YUI({
2039        delayUntil: {
2040            event: 'available',
2041            args : '#foo'
2042        }
2043    }, function (Y) {
2044        // This will not execute until a node matching the selector "#foo" is
2045        // available in the DOM.
2046    });
2047
2048**/
2049YUI.add('yui-base', function (Y, NAME) {
2050
2051/*
2052 * YUI stub
2053 * @module yui
2054 * @submodule yui-base
2055 */
2056/**
2057 * The YUI module contains the components required for building the YUI
2058 * seed file.  This includes the script loading mechanism, a simple queue,
2059 * and the core utilities for the library.
2060 * @module yui
2061 * @submodule yui-base
2062 */
2063
2064/**
2065 * Provides core language utilites and extensions used throughout YUI.
2066 *
2067 * @class Lang
2068 * @static
2069 */
2070
2071var L = Y.Lang || (Y.Lang = {}),
2072
2073STRING_PROTO = String.prototype,
2074TOSTRING     = Object.prototype.toString,
2075
2076TYPES = {
2077    'undefined'        : 'undefined',
2078    'number'           : 'number',
2079    'boolean'          : 'boolean',
2080    'string'           : 'string',
2081    '[object Function]': 'function',
2082    '[object RegExp]'  : 'regexp',
2083    '[object Array]'   : 'array',
2084    '[object Date]'    : 'date',
2085    '[object Error]'   : 'error'
2086},
2087
2088SUBREGEX         = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
2089
2090WHITESPACE       = "\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",
2091WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+",
2092TRIM_LEFT_REGEX  = new RegExp("^" + WHITESPACE_CLASS),
2093TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"),
2094TRIMREGEX        = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"),
2095
2096NATIVE_FN_REGEX  = /\{\s*\[(?:native code|function)\]\s*\}/i;
2097
2098// -- Protected Methods --------------------------------------------------------
2099
2100/**
2101Returns `true` if the given function appears to be implemented in native code,
2102`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
2103if the `useNativeES5` YUI config option is set to `false`.
2104
2105This isn't guaranteed to be 100% accurate and won't work for anything other than
2106functions, but it can be useful for determining whether a function like
2107`Array.prototype.forEach` is native or a JS shim provided by another library.
2108
2109There's a great article by @kangax discussing certain flaws with this technique:
2110<http://perfectionkills.com/detecting-built-in-host-methods/>
2111
2112While his points are valid, it's still possible to benefit from this function
2113as long as it's used carefully and sparingly, and in such a way that false
2114negatives have minimal consequences. It's used internally to avoid using
2115potentially broken non-native ES5 shims that have been added to the page b
2115y
2116other libraries.
2117
2118@method _isNative
2119@param {Function} fn Function to test.
2120@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
2121@static
2122@protected
2123@since 3.5.0
2124**/
2125L._isNative = function (fn) {
2126    return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
2127};
2128
2129// -- Public Methods -----------------------------------------------------------
2130
2131/**
2132 * Determines whether or not the provided item is an array.
2133 *
2134 * Returns `false` for array-like collections such as the function `arguments`
2135 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
2136 * test for an array-like collection.
2137 *
2138 * @method isArray
2139 * @param o The object to test.
2140 * @return {boolean} true if o is an array.
2141 * @static
2142 */
2143L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
2144    return L.type(o) === 'array';
2145};
2146
2147/**
2148 * Determines whether or not the provided item is a boolean.
2149 * @method isBoolean
2150 * @static
2151 * @param o The object to test.
2152 * @return {boolean} true if o is a boolean.
2153 */
2154L.isBoolean = function(o) {
2155    return typeof o === 'boolean';
2156};
2157
2158/**
2159 * Determines whether or not the supplied item is a date instance.
2160 * @method isDate
2161 * @static
2162 * @param o The object to test.
2163 * @return {boolean} true if o is a date.
2164 */
2165L.isDate = function(o) {
2166    return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
2167};
2168
2169/**
2170 * <p>
2171 * Determines whether or not the provided item is a function.
2172 * Note: Internet Explorer thinks certain functions are objects:
2173 * </p>
2174 *
2175 * <pre>
2176 * var obj = document.createElement("object");
2177 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
2178 * &nbsp;
2179 * var input = document.createElement("input"); // append to body
2180 * Y.Lang.isFunction(input.focus) // reports false in IE
2181 * </pre>
2182 *
2183 * <p>
2184 * You will have to implement additional tests if these functions
2185 * matter to you.
2186 * </p>
2187 *
2188 * @method isFunction
2189 * @static
2190 * @param o The object to test.
2191 * @return {boolean} true if o is a function.
2192 */
2193L.isFunction = function(o) {
2194    return L.type(o) === 'function';
2195};
2196
2197/**
2198 * Determines whether or not the provided item is null.
2199 * @method isNull
2200 * @static
2201 * @param o The object to test.
2202 * @return {boolean} true if o is null.
2203 */
2204L.isNull = function(o) {
2205    return o === null;
2206};
2207
2208/**
2209 * Determines whether or not the provided item is a legal number.
2210 * @method isNumber
2211 * @static
2212 * @param o The object to test.
2213 * @return {boolean} true if o is a number.
2214 */
2215L.isNumber = function(o) {
2216    return typeof o === 'number' && isFinite(o);
2217};
2218
2219/**
2220 * Determines whether or not the provided item is of type object
2221 * or function. Note that arrays are also objects, so
2222 * <code>Y.Lang.isObject([]) === true</code>.
2223 * @method isObject
2224 * @static
2225 * @param o The object to test.
2226 * @param failfn {boolean} fail if the input is a function.
2227 * @return {boolean} true if o is an object.
2228 * @see isPlainObject
2229 */
2230L.isObject = function(o, failfn) {
2231    var t = typeof o;
2232    return (o && (t === 'object' ||
2233        (!failfn && (t === 'function' || L.isFunction(o))))) || false;
2234};
2235
2236/**
2237 * Determines whether or not the provided value is a regexp.
2238 * @method isRegExp
2239 * @static
2240 * @param value The value or object to test.
2241 * @return {boolean} true if value is a regexp.
2242 */
2243L.isRegExp = function(value) {
2244    return L.type(value) === 'regexp';
2245};
2246
2247/**
2248 * Determines whether or not the provided item is a string.
2249 * @method isString
2250 * @static
2251 * @param o The object to test.
2252 * @return {boolean} true if o is a string.
2253 */
2254L.isString = function(o) {
2255    return typeof o === 'string';
2256};
2257
2258/**
2259 * Determines whether or not the provided item is undefined.
2260 * @method isUndefined
2261 * @static
2262 * @param o The object to test.
2263 * @return {boolean} true if o is undefined.
2264 */
2265L.isUndefined = function(o) {
2266    return typeof o === 'undefined';
2267};
2268
2269/**
2270 * A convenience method for detecting a legitimate non-null value.
2271 * Returns false for null/undefined/NaN, true for other values,
2272 * including 0/false/''
2273 * @method isValue
2274 * @static
2275 * @param o The item to test.
2276 * @return {boolean} true if it is not null/undefined/NaN || false.
2277 */
2278L.isValue = function(o) {
2279    var t = L.type(o);
2280
2281    switch (t) {
2282        case 'number':
2283            return isFinite(o);
2284
2285        case 'null': // fallthru
2286        case 'undefined':
2287            return false;
2288
2289        default:
2290            return !!t;
2291    }
2292};
2293
2294/**
2295 * Returns the current time in milliseconds.
2296 *
2297 * @method now
2298 * @return {Number} Current time in milliseconds.
2299 * @static
2300 * @since 3.3.0
2301 */
2302L.now = Date.now || function () {
2303    return new Date().getTime();
2304};
2305
2306/**
2307 * Performs `{placeholder}` substitution on a string. The object passed as the
2308 * second parameter provides values to replace the `{placeholder}`s.
2309 * `{placeholder}` token names must match property names of the object. For example,
2310 *
2311 *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });`
2312 *
2313 * `{placeholder}` tokens that are undefined on the object map will be left
2314 * in tact (leaving unsightly `{placeholder}`'s in the output string).
2315 *
2316 * @method sub
2317 * @param {string} s String to be modified.
2318 * @param {object} o Object containing replacement values.
2319 * @return {string} the substitute result.
2320 * @static
2321 * @since 3.2.0
2322 */
2323L.sub = function(s, o) {
2324
2325    /**
2326    Finds the value of `key` in given object.
2327    If the key has a 'dot' notation e.g. 'foo.bar.baz', the function will
2328    try to resolve this path if it doesn't exist as a property
2329    @example
2330        value({ 'a.b': 1, a: { b: 2 } }, 'a.b'); // 1
2331        value({ a: { b: 2 } }          , 'a.b'); // 2
2332    @param {Object} obj A key/value pairs object
2333    @param {String} key
2334    @return {Any}
2335    @private
2336    **/
2337    function value(obj, key) {
2338
2339        var subkey;
2340
2341        if ( typeof obj[key] !== 'undefined' ) {
2342            return obj[key];
2343        }
2344
2345        key    = key.split('.');         // given 'a.b.c'
2346        subkey = key.slice(1).join('.'); // 'b.c'
2347        key    = key[0];                 // 'a'
2348
2349        // special case for null as typeof returns object and we don't want that.
2350        if ( subkey && typeof obj[key] === 'object' && obj[key] !== null ) {
2351            return value(obj[key], subkey);
2352        }
2353    }
2354
2355    return s.replace ? s.replace(SUBREGEX, function (match, key) {
2356        var val = key.indexOf('.')>-1 ? value(o, key) : o[key];
2357        return typeof val === 'undefined' ? match : val;
2358    }) : s;
2359};
2360
2361/**
2362 * Returns a string without any leading or trailing whitespace.  If
2363 * the input is not a string, the input will be returned untouched.
2364 * @method trim
2365 * @static
2366 * @param s {string} the string to trim.
2367 * @return {string} the trimmed string.
2368 */
2369L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) {
2370    return s && s.trim ? s.trim() : s;
2371} : function (s) {
2372    try {
2373        return s.replace(TRIMREGEX, '');
2374    } catch (e) {
2375        return s;
2376    }
2377};
2378
2379/**
2380 * Returns a string without any leading whitespace.
2381 * @method trimLeft
2382 * @static
2383 * @param s {string} the string to trim.
2384 * @return {string} the trimmed string.
2385 */
2386L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) {
2387    return s.trimLeft();
2388} : function (s) {
2389    return s.replace(TRIM_LEFT_REGEX, '');
2390};
2391
2392/**
2393 * Returns a string without any trailing whitespace.
2394 * @method trimRight
2395 * @static
2396 * @param s {string} the string to trim.
2397 * @return {string} the trimmed string.
2398 */
2399L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) {
2400    return s.trimRight();
2401} : function (s) {
2402    return s.replace(TRIM_RIGHT_REGEX, '');
2403};
2404
2405/**
2406Returns one of the following strings, representing the type of the item passed
2407in:
2408
2409 * "array"
2410 * "boolean"
2411 * "date"
2412 * "error"
2413 * "function"
2414 * "null"
2415 * "number"
2416 * "object"
2417 * "regexp"
2418 * "string"
2419 * "undefined"
2420
2421Known issues:
2422
2423 * `typeof HTMLElementCollection` returns function in Safari, but
2424    `Y.Lang.type()` reports "object", which could be a good thing --
2425    but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2426
2427@method type
2428@param o the item to test.
2429@return {string} the detected type.
2430@static
2431**/
2432L.type = function(o) {
2433    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2434};
2435/**
2436@module yui
2437@submodule yui-base
2438*/
2439
2440var Lang   = Y.Lang,
2441    Native = Array.prototype,
2442
2443    hasOwn = Object.prototype.hasOwnProperty;
2444
2445/**
2446Provides utility methods for working with arrays. Additional array helpers can
2447be found in the `collection` and `array-extras` modules.
2448
2449`Y.Array(thing)` returns a native array created from _thing_. Depending on
2450_thing_'s type, one of the following will happen:
2451
2452  * Arrays are returned unmodified unless a non-zero _startIndex_ is
2453    specified.
2454  * Array-like collections (see `Array.test()`) are converted to arrays.
2455  * For everything else, a new array is created with _thing_ as the sole
2456    item.
2457
2458Note: elements that are also collections, such as `<form>` and `<select>`
2459elements, are not automatically converted to arrays. To force a conversion,
2460pass `true` as the value of the _force_ parameter.
2461
2462@class Array
2463@constructor
2464@param {Any} thing The thing to arrayify.
2465@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2466  collection, a subset of items starting at the specified index will be
2467  returned.
2468@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2469  array-like collection no matter what.
2470@return {Array} A native array created from _thing_, according to the rules
2471  described above.
2472**/
2473function YArray(thing, startIndex, force) {
2474    var len, result;
2475
2476    /*jshint expr: true*/
2477    startIndex || (startIndex = 0);
2478
2479    if (force || YArray.test(thing)) {
2480        // IE throws when trying to slice HTMLElement collections.
2481        try {
2482            return Native.slice.call(thing, startIndex);
2483        } catch (ex) {
2484            result = [];
2485
2486            for (len = thing.length; startIndex < len; ++startIndex) {
2487                result.push(thing[startIndex]);
2488            }
2489
2490            return result;
2491        }
2492    }
2493
2494    return [thing];
2495}
2496
2497Y.Array = YArray;
2498
2499/**
2500Dedupes an array of strings, returning an array that's guaranteed to contain
2501only one copy of a given string.
2502
2503This method differs from `Array.unique()` in that it's optimized for use only
2504with arrays consisting entirely of strings or entirely of numbers, whereas
2505`unique` may be used with other value types (but is slower).
2506
2507Using `dedupe()` with values other than strings or numbers, or with arrays
2508containing a mix of strings and numbers, may result in unexpected behavior.
2509
2510@method dedupe
2511@param {String[]|Number[]} array Array of strings or numbers to dedupe.
2512@return {Array} Copy of _array_ containing no duplicate values.
2513@static
2514@since 3.4.0
2515**/
2516YArray.dedupe = Lang._isNative(Object.create) ? function (array) {
2517    var hash    = Object.create(null),
2518        results = [],
2519        i, item, len;
2520
2521    for (i = 0, len = array.length; i < len; ++i) {
2522        item = array[i];
2523
2524        if (!hash[item]) {
2525            hash[item] = 1;
2526            results.push(item);
2527        }
2528    }
2529
2530    return results;
2531} : function (array) {
2532    var hash    = {},
2533        results = [],
2534        i, item, len;
2535
2536    for (i = 0, len = array.length; i < len; ++i) {
2537        item = array[i];
2538
2539        if (!hasOwn.call(hash, item)) {
2540            hash[item] = 1;
2541            results.push(item);
2542        }
2543    }
2544
2545    return results;
2546};
2547
2548/**
2549Executes the supplied function on each item in the array. This method wraps
2550the native ES5 `Array.forEach()` method if available.
2551
2552@method each
2553@param {Array} array Array to iterate.
2554@param {Function} fn Function to execute on each item in the array. The function
2555  will receive the following arguments:
2556    @param {Any} fn.item Current array item.
2557    @param {Number} fn.index Current array index.
2558    @param {Array} fn.array Array being iterated.
2559@param {Object} [thisObj] `this` object to use when calling _fn_.
2560@return {YUI} The YUI instance.
2561@static
2562**/
2563YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2564    Native.forEach.call(array || [], fn, thisObj || Y);
2565    return Y;
2566} : function (array, fn, thisObj) {
2567    for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2568        if (i in array) {
2569            fn.call(thisObj || Y, array[i], i, array);
2570        }
2571    }
2572
2573    return Y;
2574};
2575
2576/**
2577Alias for `each()`.
2578
2579@method forEach
2580@static
2581**/
2582
2583/**
2584Returns an object using the first array as keys and the second as values. If
2585the second array is not provided, or if it doesn't contain the same number of
2586values as the first array, then `true` will be used in place of the missing
2587values.
2588
2589@example
2590
2591    Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2592    // => {a: 'foo', b: 'bar', c: true}
2593
2594@method hash
2595@param {String[]} keys Array of strings to use as keys.
2596@param {Array} [values] Array to use as values.
2597@return {Object} Hash using the first array as keys and the second as values.
2598@static
2599**/
2600YArray.hash = function (keys, values) {
2601    var hash = {},
2602        vlen = (values && values.length) || 0,
2603        i, len;
2604
2605    for (i = 0, len = keys.length; i < len; ++i) {
2606        if (i in keys) {
2607            hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2608        }
2609    }
2610
2611    return hash;
2612};
2613
2614/**
2615Returns the index of the first item in the array that's equal (using a strict
2616equality check) to the specified _value_, or `-1` if the value isn't found.
2617
2618This method wraps the native ES5 `Array.indexOf()` method if available.
2619
2620@method indexOf
2621@param {Array} array Array to search.
2622@param {Any} value Value to search for.
2623@param {Number} [from=0] The index at which to begin the search.
2624@return {Number} Index of the item strictly equal to _value_, or `-1` if not
2625    found.
2626@static
2627**/
2628YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2629    return Native.indexOf.call(array, value, from);
2630} : function (array, value, from) {
2631    // http://es5.github.com/#x15.4.4.14
2632    var len = array.length;
2633
2634    from = +from || 0;
2635    from = (from > 0 || -1) * Math.floor(Math.abs(from));
2636
2637    if (from < 0) {
2638        from += len;
2639
2640        if (from < 0) {
2641            from = 0;
2642        }
2643    }
2644
2645    for (; from < len; ++from) {
2646        if (from in array && array[from] === value) {
2647            return from;
2648        }
2649    }
2650
2651    return -1;
2652};
2653
2654/**
2655Numeric sort convenience function.
2656
2657The native `Array.prototype.sort()` function converts values to strings and
2658sorts them in lexicographic order, which is unsuitable for sorting numeric
2659values. Provide `Array.numericSort` as a custom sort function when you want
2660to sort values in numeric order.
2661
2662@example
2663
2664    [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2665    // => [4, 8, 15, 16, 23, 42]
2666
2667@method numericSort
2668@param {Number} a First value to compare.
2669@param {Number} b Second value to compare.
2670@return {Number} Difference between _a_ and _b_.
2671@static
2672**/
2673YArray.numericSort = function (a, b) {
2674    return a - b;
2675};
2676
2677/**
2678Executes the supplied function on each item in the array. Returning a truthy
2679value from the function will stop the processing of remaining items.
2680
2681@method some
2682@param {Array} array Array to iterate over.
2683@param {Function} fn Function to execute on each item. The function will receive
2684  the following arguments:
2685    @param {Any} fn.value Current array item.
2686    @param {Number} fn.index Current array index.
2687    @param {Array} fn.array Array being iterated over.
2688@param {Object} [thisObj] `this` object to use when calling _fn_.
2689@return {Boolean} `true` if the function returns a truthy value on any of the
2690  items in the array; `false` otherwise.
2691@static
2692**/
2693YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2694    return Native.some.call(array, fn, thisObj);
2695} : function (array, fn, thisObj) {
2696    for (var i = 0, len = array.length; i < len; ++i) {
2697        if (i in array && fn.call(thisObj, array[i], i, array)) {
2698            return true;
2699        }
2700    }
2701
2702    return false;
2703};
2704
2705/**
2706Evaluates _obj_ to determine if it's an array, an array-like collection, or
2707something else. This is useful when working with the function `arguments`
2708collection and `HTMLElement` collections.
2709
2710Note: This implementation doesn't consider elements that are also
2711collections, such as `<form>` and `<select>`, to be array-like.
2712
2713@method test
2714@param {Object} obj Object to test.
2715@return {Number} A number indicating the results of the test:
2716
2717  * 0: Neither an array nor an array-like collection.
2718  * 1: Real array.
2719  * 2: Array-like collection.
2720
2721@static
2722**/
2723YArray.test = function (obj) {
2724    var result = 0;
2725
2726    if (Lang.isArray(obj)) {
2727        result = 1;
2728    } else if (Lang.isObject(obj)) {
2729        try {
2730            // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2731            // or functions without apply/call (Safari
2732            // HTMLElementCollection bug).
2733            if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2734                result = 2;
2735            }
2736        } catch (ex) {}
2737    }
2738
2739    return result;
2740};
2741/**
2742 * The YUI module contains the components required for building the YUI
2743 * seed file.  This includes the script loading mechanism, a simple queue,
2744 * and the core utilities for the library.
2745 * @module yui
2746 * @submodule yui-base
2747 */
2748
2749/**
2750 * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
2751 * removed using next().
2752 *
2753 * @class Queue
2754 * @constructor
2755 * @param {MIXED} item* 0..n items to seed the queue.
2756 */
2757function Queue() {
2758    this._init();
2759    this.add.apply(this, arguments);
2760}
2761
2762Queue.prototype = {
2763    /**
2764     * Initialize the queue
2765     *
2766     * @method _init
2767     * @protected
2768     */
2769    _init: function() {
2770        /**
2771         * The collection of enqueued items
2772         *
2773         * @property _q
2774         * @type Array
2775         * @protected
2776         */
2777        this._q = [];
2778    },
2779
2780    /**
2781     * Get the next item in the queue. FIFO support
2782     *
2783     * @method next
2784     * @return {MIXED} the next item in the queue.
2785     */
2786    next: function() {
2787        return this._q.shift();
2788    },
2789
2790    /**
2791     * Get the last in the queue. LIFO support.
2792     *
2793     * @method last
2794     * @return {MIXED} the last item in the queue.
2795     */
2796    last: function() {
2797        return this._q.pop();
2798    },
2799
2800    /**
2801     * Add 0..n items to the end of the queue.
2802     *
2803     * @method add
2804     * @param {MIXED} item* 0..n items.
2805     * @return {object} this queue.
2806     */
2807    add: function() {
2808        this._q.push.apply(this._q, arguments);
2809
2810        return this;
2811    },
2812
2813    /**
2814     * Returns the current number of queued items.
2815     *
2816     * @method size
2817     * @return {Number} The size.
2818     */
2819    size: function() {
2820        return this._q.length;
2821    }
2822};
2823
2824Y.Queue = Queue;
2825
2826YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2827
2828/**
2829The YUI module contains the components required for building the YUI seed file.
2830This includes the script loading mechanism, a simple queue, and the core
2831utilities for the library.
2832
2833@module yui
2834@submodule yui-base
2835**/
2836
2837var CACHED_DELIMITER = '__',
2838
2839    hasOwn   = Object.prototype.hasOwnProperty,
2840    isObject = Y.Lang.isObject;
2841
2842/**
2843Returns a wrapper for a function which caches the return value of that function,
2844keyed off of the combined string representation of the argument values provided
2845when the wrapper is called.
2846
2847Calling this function again with the same arguments will return the cached value
2848rather than executing the wrapped function.
2849
2850Note that since the cache is keyed off of the string representation of arguments
2851passed to the wrapper function, arguments that aren't strings and don't provide
2852a meaningful `toString()` method may result in unexpected caching behavior. For
2853example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2854string `[object Object]` when used as a cache key.
2855
2856@method cached
2857@param {Function} source The function to memoize.
2858@param {Object} [cache={}] Object in which to store cached values. You may seed
2859  this object with pre-existing cached values if desired.
2860@param {any} [refetch] If supplied, this value is compared with the cached value
2861  using a `==` comparison. If the values are equal, the wrapped function is
2862  executed again even though a cached value exists.
2863@return {Function} Wrapped function.
2864@for YUI
2865**/
2866Y.cached = function (source, cache, refetch) {
2867    /*jshint expr: true*/
2868    cache || (cache = {});
2869
2870    return function (arg) {
2871        var key = arguments.length > 1 ?
2872                Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2873                String(arg);
2874
2875        /*jshint eqeqeq: false*/
2876        if (!(key in cache) || (refetch && cache[key] == refetch)) {
2877            cache[key] = source.apply(source, arguments);
2878        }
2879
2880        return cache[key];
2881    };
2882};
2883
2884/**
2885Returns the `location` object from the window/frame in which this YUI instance
2886operates, or `undefined` when executing in a non-browser environment
2887(e.g. Node.js).
2888
2889It is _not_ recommended to hold references to the `window.location` object
2890outside of the scope of a function in which its properties are being accessed or
2891its methods are being called. This is because of a nasty bug/issue that exists
2892in both Safari and MobileSafari browsers:
2893[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
2894
2895@method getLocation
2896@return {location} The `location` object from the window/frame in which this YUI
2897    instance operates.
2898@since 3.5.0
2899**/
2900Y.getLocation = function () {
2901    // It is safer to look this up every time because yui-base is attached to a
2902    // YUI instance before a user's config is applied; i.e. `Y.config.win` does
2903    // not point the correct window object when this file is loaded.
2904    var win = Y.config.win;
2905
2906    // It is not safe to hold a reference to the `location` object outside the
2907    // scope in which it is being used. The WebKit engine used in Safari and
2908    // MobileSafari will "disconnect" the `location` object from the `window`
2909    // when a page is restored from back/forward history cache.
2910    return win && win.location;
2911};
2912
2913/**
2914Returns a new object containing all of the properties of all the supplied
2915objects. The properties from later objects will overwrite those in earlier
2916objects.
2917
2918Passing in a single object will create a shallow copy of it. For a deep copy,
2919use `clone()`.
2920
2921@method merge
2922@param {Object} objects* One or more objects to merge.
2923@return {Object} A new merged object.
2924**/
2925Y.merge = function () {
2926    var i      = 0,
2927        len    = arguments.length,
2928        result = {},
2929        key,
2930        obj;
2931
2932    for (; i < len; ++i) {
2933        obj = arguments[i];
2934
2935        for (key in obj) {
2936            if (hasOwn.call(obj, key)) {
2937                result[key] = obj[key];
2938            }
2939        }
2940    }
2941
2942    return result;
2943};
2944
2945/**
2946Mixes _supplier_'s properties into _receiver_.
2947
2948Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2949shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2950unless the _merge_ parameter is `true`.
2951
2952In the default mode (0), only properties the supplier owns are copied (prototype
2953properties are not copied). The following copying modes are available:
2954
2955  * `0`: _Default_. Object to object.
2956  * `1`: Prototype to prototype.
2957  * `2`: Prototype to prototype and object to object.
2958  * `3`: Prototype to object.
2959  * `4`: Object to prototype.
2960
2961@method mix
2962@param {Function|Object} receiver The object or function to receive the mixed
2963  properties.
2964@param {Function|Object} supplier The object or function supplying the
2965  properties to be mixed.
2966@param {Boolean} [overwrite=false] If `true`, properties that already exist
2967  on the receiver will be overwritten with properties from the supplier.
2968@param {String[]} [whitelist] An array of property names to copy. If
2969  specified, only the whitelisted properties will be copied, and all others
2970  will be ignored.
2971@param {Number} [mode=0] Mix mode to use. See above for available modes.
2972@param {Boolean} [merge=false] If `true`, objects and arrays that already
2973  exist on the receiver will have the corresponding object/array from the
2974  supplier merged into them, rather than being skipped or overwritten. When
2975  both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2976@return {Function|Object|YUI} The receiver, or the YUI instance if the
2977  specified receiver is falsy.
2978**/
2979Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2980    var alwaysOverwrite, exists, from, i, key, len, to;
2981
2982    // If no supplier is given, we return the receiver. If no receiver is given,
2983    // we return Y. Returning Y doesn't make much sense to me, but it's
2984    // grandfathered in for backcompat reasons.
2985    if (!receiver || !supplier) {
2986        return receiver || Y;
2987    }
2988
2989    if (mode) {
2990        // In mode 2 (prototype to prototype and object to object), we recurse
2991        // once to do the proto to proto mix. The object to object mix will be
2992        // handled later on.
2993        if (mode === 2) {
2994            Y.mix(receiver.prototype, supplier.prototype, overwrite,
2995                    whitelist, 0, merge);
2996        }
2997
2998        // Depending on which mode is specified, we may be copying from or to
2999        // the prototypes of the supplier and receiver.
3000        from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
3001        to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
3002
3003        // If either the supplier or receiver doesn't actually have a
3004        // prototype property, then we could end up with an undefined `from`
3005        // or `to`. If that happens, we abort and return the receiver.
3006        if (!from || !to) {
3007            return receiver;
3008        }
3009    } else {
3010        from = supplier;
3011        to   = receiver;
3012    }
3013
3014    // If `overwrite` is truthy and `merge` is falsy, then we can skip a
3015    // property existence check on each iteration and save some time.
3016    alwaysOverwrite = overwrite && !merge;
3017
3018    if (whitelist) {
3019        for (i = 0, len = whitelist.length; i < len; ++i) {
3020            key = whitelist[i];
3021
3022            // We call `Object.prototype.hasOwnProperty` instead of calling
3023            // `hasOwnProperty` on the object itself, since the object's
3024            // `hasOwnProperty` method may have been overridden or removed.
3025            // Also, some native objects don't implement a `hasOwnProperty`
3026            // method.
3027            if (!hasOwn.call(from, key)) {
3028                continue;
3029            }
3030
3031            // The `key in to` check here is (sadly) intentional for backwards
3032            // compatibility reasons. It prevents undesired shadowing of
3033            // prototype members on `to`.
3034            exists = alwaysOverwrite ? false : key in to;
3035
3036            if (merge && exists && isObject(to[key], true)
3037                    && isObject(from[key], true)) {
3038                // If we're in merge mode, and the key is present on both
3039                // objects, and the value on both objects is either an object or
3040                // an array (but not a function), then we recurse to merge the
3041                // `from` value into the `to` value instead of overwriting it.
3042                //
3043                // Note: It's intentional that the whitelist isn't passed to the
3044                // recursive call here. This is legacy behavior that lots of
3045                // code still depends on.
3046                Y.mix(to[key], from[key], overwrite, null, 0, merge);
3047            } else if (overwrite || !exists) {
3048                // We're not in merge mode, so we'll only copy the `from` value
3049                // to the `to` value if we're in overwrite mode or if the
3050                // current key doesn't exist on the `to` object.
3051                to[key] = from[key];
3052            }
3053        }
3054    } else {
3055        for (key in from) {
3056            // The code duplication here is for runtime performance reasons.
3057            // Combining whitelist and non-whitelist operations into a single
3058            // loop or breaking the shared logic out into a function both result
3059            // in worse performance, and Y.mix is critical enough that the byte
3060            // tradeoff is worth it.
3061            if (!hasOwn.call(from, key)) {
3062                continue;
3063            }
3064
3065            // The `key in to` check here is (sadly) intentional for backwards
3066            // compatibility reasons. It prevents undesired shadowing of
3067            // prototype members on `to`.
3068            exists = alwaysOverwrite ? false : key in to;
3069
3070            if (merge && exists && isObject(to[key], true)
3071                    && isObject(from[key], true)) {
3072                Y.mix(to[key], from[key], overwrite, null, 0, merge);
3073            } else if (overwrite || !exists) {
3074                to[key] = from[key];
3075            }
3076        }
3077
3078        // If this is an IE browser with the JScript enumeration bug, force
3079        // enumeration of the buggy properties by making a recursive call with
3080        // the buggy properties as the whitelist.
3081        if (Y.Object._hasEnumBug) {
3082            Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
3083        }
3084    }
3085
3086    return receiver;
3087};
3088/**
3089 * The YUI module contains the components required for building the YUI
3090 * seed file.  This includes the script loading mechanism, a simple queue,
3091 * and the core utilities for the library.
3092 * @module yui
3093 * @submodule yui-base
3094 */
3095
3096/**
3097 * Adds utilities to the YUI instance for working with objects.
3098 *
3099 * @class Object
3100 */
3101
3102var Lang   = Y.Lang,
3103    hasOwn = Object.prototype.hasOwnProperty,
3104
3105    UNDEFINED, // <-- Note the comma. We're still declaring vars.
3106
3107/**
3108 * Returns a new object that uses _obj_ as its prototype. This method wraps the
3109 * native ES5 `Object.create()` method if available, but doesn't currently
3110 * pass through `Object.create()`'s second argument (properties) in order to
3111 * ensure compatibility with older browsers.
3112 *
3113 * @method ()
3114 * @param {Object} obj Prototype object.
3115 * @return {Object} New object using _obj_ as its prototype.
3116 * @static
3117 */
3118O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
3119    // We currently wrap the native Object.create instead of simply aliasing it
3120    // to ensure consistency with our fallback shim, which currently doesn't
3121    // support Object.create()'s second argument (properties). Once we have a
3122    // safe fallback for the properties arg, we can stop wrapping
3123    // Object.create().
3124    return Object.create(obj);
3125} : (function () {
3126    // Reusable constructor function for the Object.create() shim.
3127    function F() {}
3128
3129    // The actual shim.
3130    return function (obj) {
3131        F.prototype = obj;
3132        return new F();
3133    };
3134}()),
3135
3136/**
3137 * Property names that IE doesn't enumerate in for..in loops, even when they
3138 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
3139 * manually enumerate these properties.
3140 *
3141 * @property _forceEnum
3142 * @type String[]
3143 * @protected
3144 * @static
3145 */
3146forceEnum = O._forceEnum = [
3147    'hasOwnProperty',
3148    'isPrototypeOf',
3149    'propertyIsEnumerable',
3150    'toString',
3151    'toLocaleString',
3152    'valueOf'
3153],
3154
3155/**
3156 * `true` if this browser has the JScript enumeration bug that prevents
3157 * enumeration of the properties named in the `_forceEnum` array, `false`
3158 * otherwise.
3159 *
3160 * See:
3161 *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
3162 *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
3163 *
3164 * @property _hasEnumBug
3165 * @type Boolean
3166 * @protected
3167 * @static
3168 */
3169hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
3170
3171/**
3172 * `true` if this browser incorrectly considers the `prototype` property of
3173 * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x.
3174 *
3175 * @property _hasProtoEnumBug
3176 * @type Boolean
3177 * @protected
3178 * @static
3179 */
3180hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
3181
3182/**
3183 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
3184 * exists only on _obj_'s prototype. This is essentially a safer version of
3185 * `obj.hasOwnProperty()`.
3186 *
3187 * @method owns
3188 * @param {Object} obj Object to test.
3189 * @param {String} key Property name to look for.
3190 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3191 * @static
3192 */
3193owns = O.owns = function (obj, key) {
3194    return !!obj && hasOwn.call(obj, key);
3195}; // <-- End of var declarations.
3196
3197/**
3198 * Alias for `owns()`.
3199 *
3200 * @method hasKey
3201 * @param {Object} obj Object to test.
3202 * @param {String} key Property name to look for.
3203 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3204 * @static
3205 */
3206O.hasKey = owns;
3207
3208/**
3209 * Returns an array containing the object's enumerable keys. Does not include
3210 * prototype keys or non-enumerable keys.
3211 *
3212 * Note that keys are returned in enumeration order (that is, in the same order
3213 * that they would be enumerated by a `for-in` loop), which may not be the same
3214 * as the order in which they were defined.
3215 *
3216 * This method is an alias for the native ES5 `Object.keys()` method if
3217 * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of
3218 * `Object.keys()` have an inconsistency as they consider `prototype` to be
3219 * enumerable, so a non-native shim is used to rectify the difference.
3220 *
3221 * @example
3222 *
3223 *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
3224 *     // => ['a', 'b', 'c']
3225 *
3226 * @method keys
3227 * @param {Object} obj An object.
3228 * @return {String[]} Array of keys.
3229 * @static
3230 */
3231O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) {
3232    if (!Lang.isObject(obj)) {
3233        throw new TypeError('Object.keys called on a non-object');
3234    }
3235
3236    var keys = [],
3237        i, key, len;
3238
3239    if (hasProtoEnumBug && typeof obj === 'function') {
3240        for (key in obj) {
3241            if (owns(obj, key) && key !== 'prototype') {
3242                keys.push(key);
3243            }
3244        }
3245    } else {
3246        for (key in obj) {
3247            if (owns(obj, key)) {
3248                keys.push(key);
3249            }
3250        }
3251    }
3252
3253    if (hasEnumBug) {
3254        for (i = 0, len = forceEnum.length; i < len; ++i) {
3255            key = forceEnum[i];
3256
3257            if (owns(obj, key)) {
3258                keys.push(key);
3259            }
3260        }
3261    }
3262
3263    return keys;
3264};
3265
3266/**
3267 * Returns an array containing the values of the object's enumerable keys.
3268 *
3269 * Note that values are returned in enumeration order (that is, in the same
3270 * order that they would be enumerated by a `for-in` loop), which may not be the
3271 * same as the order in which they were defined.
3272 *
3273 * @example
3274 *
3275 *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
3276 *     // => ['foo', 'bar', 'baz']
3277 *
3278 * @method values
3279 * @param {Object} obj An object.
3280 * @return {Array} Array of values.
3281 * @static
3282 */
3283O.values = function (obj) {
3284    var keys   = O.keys(obj),
3285        i      = 0,
3286        len    = keys.length,
3287        values = [];
3288
3289    for (; i < len; ++i) {
3290        values.push(obj[keys[i]]);
3291    }
3292
3293    return values;
3294};
3295
3296/**
3297 * Returns the number of enumerable keys owned by an object.
3298 *
3299 * @method size
3300 * @param {Object} obj An object.
3301 * @return {Number} The object's size.
3302 * @static
3303 */
3304O.size = function (obj) {
3305    try {
3306        return O.keys(obj).length;
3307    } catch (ex) {
3308        return 0; // Legacy behavior for non-objects.
3309    }
3310};
3311
3312/**
3313 * Returns `true` if the object owns an enumerable property with the specified
3314 * value.
3315 *
3316 * @method hasValue
3317 * @param {Object} obj An object.
3318 * @param {any} value The value to search for.
3319 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
3320 * @static
3321 */
3322O.hasValue = function (obj, value) {
3323    return Y.Array.indexOf(O.values(obj), value) > -1;
3324};
3325
3326/**
3327 * Executes a function on each enumerable property in _obj_. The function
3328 * receives the value, the key, and the object itself as parameters (in that
3329 * order).
3330 *
3331 * By default, only properties owned by _obj_ are enumerated. To include
3332 * prototype properties, set the _proto_ parameter to `true`.
3333 *
3334 * @method each
3335 * @param {Object} obj Object to enumerate.
3336 * @param {Function} fn Function to execute on each enumerable property.
3337 *   @param {mixed} fn.value Value of the current property.
3338 *   @param {String} fn.key Key of the current property.
3339 *   @param {Object} fn.obj Object being enumerated.
3340 * @param {Object} [thisObj] `this` object to use when calling _fn_.
3341 * @param {Boolean} [proto=false] Include prototype properties.
3342 * @return {YUI} the YUI instance.
3343 * @chainable
3344 * @static
3345 */
3346O.each = function (obj, fn, thisObj, proto) {
3347    var key;
3348
3349    for (key in obj) {
3350        if (proto || owns(obj, key)) {
3351            fn.call(thisObj || Y, obj[key], key, obj);
3352        }
3353    }
3354
3355    return Y;
3356};
3357
3358/**
3359 * Executes a function on each enumerable property in _obj_, but halts if the
3360 * function returns a truthy value. The function receives the value, the key,
3361 * and the object itself as paramters (in that order).
3362 *
3363 * By default, only properties owned by _obj_ are enumerated. To include
3364 * prototype properties, set the _proto_ parameter to `true`.
3365 *
3366 * @method some
3367 * @param {Object} obj Object to enumerate.
3368 * @param {Function} fn Function to execute on each enumerable property.
3369 *   @param {mixed} fn.value Value of the current property.
3370 *   @param {String} fn.key Key of the current property.
3371 *   @param {Object} fn.obj Object being enumerated.
3372 * @param {Object} [thisObj] `this` object to use when calling _fn_.
3373 * @param {Boolean} [proto=false] Include prototype properties.
3374 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3375 *   `false` otherwise.
3376 * @static
3377 */
3378O.some = function (obj, fn, thisObj, proto) {
3379    var key;
3380
3381    for (key in obj) {
3382        if (proto || owns(obj, key)) {
3383            if (fn.call(thisObj || Y, obj[key], key, obj)) {
3384                return true;
3385            }
3386        }
3387    }
3388
3389    return false;
3390};
3391
3392/**
3393 * Retrieves the sub value at the provided path,
3394 * from the value object provided.
3395 *
3396 * @method getValue
3397 * @static
3398 * @param o The object from which to extract the property value.
3399 * @param path {Array} A path array, specifying the object traversal path
3400 * from which to obtain the sub value.
3401 * @return {Any} The value stored in the path, undefined if not found,
3402 * undefined if the source is not an object.  Returns the source object
3403 * if an empty path is provided.
3404 */
3405O.getValue = function(o, path) {
3406    if (!Lang.isObject(o)) {
3407        return UNDEFINED;
3408    }
3409
3410    var i,
3411        p = Y.Array(path),
3412        l = p.length;
3413
3414    for (i = 0; o !== UNDEFINED && i < l; i++) {
3415        o = o[p[i]];
3416    }
3417
3418    return o;
3419};
3420
3421/**
3422 * Sets the sub-attribute value at the provided path on the
3423 * value object.  Returns the modified value object, or
3424 * undefined if the path is invalid.
3425 *
3426 * @method setValue
3427 * @static
3428 * @param o             The object on which to set the sub value.
3429 * @param path {Array}  A path array, specifying the object traversal path
3430 *                      at which to set the sub value.
3431 * @param val {Any}     The new value for the sub-attribute.
3432 * @return {Object}     The modified object, with the new sub value set, or
3433 *                      undefined, if the path was invalid.
3434 */
3435O.setValue = function(o, path, val) {
3436    var i,
3437        p = Y.Array(path),
3438        leafIdx = p.length - 1,
3439        ref = o;
3440
3441    if (leafIdx >= 0) {
3442        for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3443            ref = ref[p[i]];
3444        }
3445
3446        if (ref !== UNDEFINED) {
3447            ref[p[i]] = val;
3448        } else {
3449            return UNDEFINED;
3450        }
3451    }
3452
3453    return o;
3454};
3455
3456/**
3457 * Returns `true` if the object has no enumerable properties of its own.
3458 *
3459 * @method isEmpty
3460 * @param {Object} obj An object.
3461 * @return {Boolean} `true` if the object is empty.
3462 * @static
3463 * @since 3.2.0
3464 */
3465O.isEmpty = function (obj) {
3466    return !O.keys(Object(obj)).length;
3467};
3468/**
3469 * The YUI module contains the components required for building the YUI seed
3470 * file.  This includes the script loading mechanism, a simple queue, and the
3471 * core utilities for the library.
3472 * @module yui
3473 * @submodule yui-base
3474 */
3475
3476/**
3477 * YUI user agent detection.
3478 * Do not fork for a browser if it can be avoided.  Use feature detection when
3479 * you can.  Use the user agent as a last resort.  For all fields listed
3480 * as @type float, UA stores a version number for the browser engine,
3481 * 0 otherwise.  This value may or may not map to the version number of
3482 * the browser using the engine.  The value is presented as a float so
3483 * that it can easily be used for boolean evaluation as well as for
3484 * looking for a particular range of versions.  Because of this,
3485 * some of the granularity of the version info may be lost.  The fields that
3486 * are @type string default to null.  The API docs list the values that
3487 * these fields can have.
3488 * @class UA
3489 * @static
3490 */
3491
3492/**
3493* Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
3494* to populate `Y.UA`.
3495*
3496* @static
3497* @method parseUA
3498* @param {String} [subUA=navigator.userAgent] UA string to parse
3499* @return {Object} The Y.UA object
3500*/
3501YUI.Env.parseUA = function(subUA) {
3502
3503    var numberify = function(s) {
3504            var c = 0;
3505            return parseFloat(s.replace(/\./g, function() {
3506                return (c++ === 1) ? '' : '.';
3507            }));
3508        },
3509
3510        win = Y.config.win,
3511
3512        nav = win && win.navigator,
3513
3514        o = {
3515
3516        /**
3517         * Internet Explorer version number or 0.  Example: 6
3518         * @property ie
3519         * @type float
3520         * @static
3521         */
3522        ie: 0,
3523
3524        /**
3525         * Opera version number or 0.  Example: 9.2
3526         * @property opera
3527         * @type float
3528         * @static
3529         */
3530        opera: 0,
3531
3532        /**
3533         * Gecko engine revision number.  Will evaluate to 1 if Gecko
3534         * is detected but the revision could not be found. Other browsers
3535         * will be 0.  Example: 1.8
3536         * <pre>
3537         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
3538         * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3539         * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3540         * Firefox 3.0   <-- 1.9
3541         * Firefox 3.5   <-- 1.91
3542         * </pre>
3543         * @property gecko
3544         * @type float
3545         * @static
3546         */
3547        gecko: 0,
3548
3549        /**
3550         * AppleWebKit version.  KHTML browsers that are not WebKit browsers
3551         * will evaluate to 1, other browsers 0.  Example: 418.9
3552         * <pre>
3553         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3554         *                                   latest available for Mac OSX 10.3.
3555         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
3556         * Safari 2.0.4:         418     <-- preventDefault fixed
3557         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3558         *                                   different versions of webkit
3559         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
3560         *                                   updated, but not updated
3561         *                                   to the latest patch.
3562         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
3563         * SVG and many major issues fixed).
3564         * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
3565         * update from 2.x via the 10.4.11 OS patch.
3566         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
3567         *                                   yahoo.com user agent hack removed.
3568         * </pre>
3569         * http://en.wikipedia.org/wiki/Safari_version_history
3570         * @property webkit
3571         * @type float
3572         * @static
3573         */
3574        webkit: 0,
3575
3576        /**
3577         * Safari will be detected as webkit, but this property will also
3578         * be populated with the Safari version number
3579         * @property safari
3580         * @type float
3581         * @static
3582         */
3583        safari: 0,
3584
3585        /**
3586         * Chrome will be detected as webkit, but this property will also
3587         * be populated with the Chrome version number
3588         * @property chrome
3589         * @type float
3590         * @static
3591         */
3592        chrome: 0,
3593
3594        /**
3595         * The mobile property will be set to a string containing any relevant
3596         * user agent information when a modern mobile browser is detected.
3597         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3598         * devices with the WebKit-based browser, and Opera Mini.
3599         * @property mobile
3600         * @type string
3601         * @default null
3602         * @static
3603         */
3604        mobile: null,
3605
3606        /**
3607         * Adobe AIR version number or 0.  Only populated if webkit is detected.
3608         * Example: 1.0
3609         * @property air
3610         * @type float
3611         */
3612        air: 0,
3613        /**
3614         * PhantomJS version number or 0.  Only populated if webkit is detected.
3615         * Example: 1.0
3616         * @property phantomjs
3617         * @type float
3618         */
3619        phantomjs: 0,
3620        /**
3621         * Detects Apple iPad's OS version
3622         * @property ipad
3623         * @type float
3624         * @static
3625         */
3626        ipad: 0,
3627        /**
3628         * Detects Apple iPhone's OS version
3629         * @property iphone
3630         * @type float
3631         * @static
3632         */
3633        iphone: 0,
3634        /**
3635         * Detects Apples iPod's OS version
3636         * @property ipod
3637         * @type float
3638         * @static
3639         */
3640        ipod: 0,
3641        /**
3642         * General truthy check for iPad, iPhone or iPod
3643         * @property ios
3644         * @type Boolean
3645         * @default null
3646         * @static
3647         */
3648        ios: null,
3649        /**
3650         * Detects Googles Android OS version
3651         * @property android
3652         * @type float
3653         * @static
3654         */
3655        android: 0,
3656        /**
3657         * Detects Kindle Silk
3658         * @property silk
3659         * @type float
3660         * @static
3661         */
3662        silk: 0,
3663        /**
3664         * Detects Ubuntu version
3665         * @property ubuntu
3666         * @type float
3667         * @static
3668         */
3669        ubuntu: 0,
3670        /**
3671         * Detects Kindle Silk Acceleration
3672         * @property accel
3673         * @type Boolean
3674         * @static
3675         */
3676        accel: false,
3677        /**
3678         * Detects Palms WebOS version
3679         * @property webos
3680         * @type float
3681         * @static
3682         */
3683        webos: 0,
3684
3685        /**
3686         * Google Caja version number or 0.
3687         * @property caja
3688         * @type float
3689         */
3690        caja: nav && nav.cajaVersion,
3691
3692        /**
3693         * Set to true if the page appears to be in SSL
3694         * @property secure
3695         * @type boolean
3696         * @static
3697         */
3698        secure: false,
3699
3700        /**
3701         * The operating system.
3702         *
3703         * Possible values are `windows`, `macintosh`, `android`, `symbos`, `linux`, `rhino` and `ios`.
3704         *
3705         * @property os
3706         * @type string
3707         * @default null
3708         * @static
3709         */
3710        os: null,
3711
3712        /**
3713         * The Nodejs Version
3714         * @property nodejs
3715         * @type float
3716         * @default 0
3717         * @static
3718         */
3719        nodejs: 0,
3720        /**
3721        * Window8/IE10 Application host environment
3722        * @property winjs
3723        * @type Boolean
3724        * @static
3725        */
3726        winjs: !!((typeof Windows !== "undefined") && Windows.System),
3727        /**
3728        * Are touch/msPointer events available on this device
3729        * @property touchEnabled
3730        * @type Boolean
3731        * @static
3732        */
3733        touchEnabled: false
3734    },
3735
3736    ua = subUA || nav && nav.userAgent,
3737
3738    loc = win && win.location,
3739
3740    href = loc && loc.href,
3741
3742    m;
3743
3744    /**
3745    * The User Agent string that was parsed
3746    * @property userAgent
3747    * @type String
3748    * @static
3749    */
3750    o.userAgent = ua;
3751
3752
3753    o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3754
3755    if (ua) {
3756
3757        if ((/windows|win32/i).test(ua)) {
3758            o.os = 'windows';
3759        } else if ((/macintosh|mac_powerpc/i).test(ua)) {
3760            o.os = 'macintosh';
3761        } else if ((/android/i).test(ua)) {
3762            o.os = 'android';
3763        } else if ((/symbos/i).test(ua)) {
3764            o.os = 'symbos';
3765        } else if ((/linux/i).test(ua)) {
3766            o.os = 'linux';
3767        } else if ((/rhino/i).test(ua)) {
3768            o.os = 'rhino';
3769        }
3770
3771        // Modern KHTML browsers should qualify as Safari X-Grade
3772        if ((/KHTML/).test(ua)) {
3773            o.webkit = 1;
3774        }
3775        if ((/IEMobile|XBLWP7/).test(ua)) {
3776            o.mobile = 'windows';
3777        }
3778        if ((/Fennec/).test(ua)) {
3779            o.mobile = 'gecko';
3780        }
3781        // Modern WebKit browsers are at least X-Grade
3782        m = ua.match(/AppleWebKit\/([^\s]*)/);
3783        if (m && m[1]) {
3784            o.webkit = numberify(m[1]);
3785            o.safari = o.webkit;
3786
3787            if (/PhantomJS/.test(ua)) {
3788                m = ua.match(/PhantomJS\/([^\s]*)/);
3789                if (m && m[1]) {
3790                    o.phantomjs = numberify(m[1]);
3791                }
3792            }
3793
3794            // Mobile browser check
3795            if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3796                o.mobile = 'Apple'; // iPhone or iPod Touch
3797
3798                m = ua.match(/OS ([^\s]*)/);
3799                if (m && m[1]) {
3800                    m = numberify(m[1].replace('_', '.'));
3801                }
3802                o.ios = m;
3803                o.os = 'ios';
3804                o.ipad = o.ipod = o.iphone = 0;
3805
3806                m = ua.match(/iPad|iPod|iPhone/);
3807                if (m && m[0]) {
3808                    o[m[0].toLowerCase()] = o.ios;
3809                }
3810            } else {
3811                m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3812                if (m) {
3813                    // Nokia N-series, webOS, ex: NokiaN95
3814                    o.mobile = m[0];
3815                }
3816                if (/webOS/.test(ua)) {
3817                    o.mobile = 'WebOS';
3818                    m = ua.match(/webOS\/([^\s]*);/);
3819                    if (m && m[1]) {
3820                        o.webos = numberify(m[1]);
3821                    }
3822                }
3823                if (/ Android/.test(ua)) {
3824                    o.mobile = 'Android';
3825                    m = ua.match(/Android ([^\s]*);/);
3826                    if (m && m[1]) {
3827                        o.android = numberify(m[1]);
3828                    }
3829
3830                }
3831                if (/Silk/.test(ua)) {
3832                    m = ua.match(/Silk\/([^\s]*)/);
3833                    if (m && m[1]) {
3834                        o.silk = numberify(m[1]);
3835                    }
3836                    if (!o.android) {
3837                        o.android = 2.34; //Hack for desktop mode in Kindle
3838                        o.os = 'Android';
3839                    }
3840                    if (/Accelerated=true/.test(ua)) {
3841                        o.accel = true;
3842                    }
3843                }
3844            }
3845
3846            m = ua.match(/OPR\/(\d+\.\d+)/);
3847
3848            if (m && m[1]) {
3849                // Opera 15+ with Blink (pretends to be both Chrome and Safari)
3850                o.opera = numberify(m[1]);
3851            } else {
3852                m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
3853
3854                if (m && m[1] && m[2]) {
3855                    o.chrome = numberify(m[2]); // Chrome
3856                    o.safari = 0; //Reset safari back to 0
3857                    if (m[1] === 'CrMo') {
3858                        o.mobile = 'chrome';
3859                    }
3860                } else {
3861                    m = ua.match(/AdobeAIR\/([^\s]*)/);
3862                    if (m) {
3863                        o.air = m[0]; // Adobe AIR 1.0 or better
3864                    }
3865                }
3866            }
3867        }
3868
3869        m = ua.match(/Ubuntu\ (\d+\.\d+)/);
3870        if (m && m[1]) {
3871
3872            o.os = 'linux';
3873            o.ubuntu = numberify(m[1]);
3874
3875            m = ua.match(/\ WebKit\/([^\s]*)/);
3876            if (m && m[1]) {
3877                o.webkit = numberify(m[1]);
3878            }
3879            m = ua.match(/\ Chromium\/([^\s]*)/);
3880            if (m && m[1]) {
3881                o.chrome = numberify(m[1]);
3882            }
3883            if (/ Mobile$/.test(ua)) {
3884                o.mobile = 'Ubuntu';
3885            }
3886        }
3887
3888        if (!o.webkit) { // not webkit
3889// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3890            if (/Opera/.test(ua)) {
3891                m = ua.match(/Opera[\s\/]([^\s]*)/);
3892                if (m && m[1]) {
3893                    o.opera = numberify(m[1]);
3894                }
3895                m = ua.match(/Version\/([^\s]*)/);
3896                if (m && m[1]) {
3897                    o.opera = numberify(m[1]); // opera 10+
3898                }
3899
3900                if (/Opera Mobi/.test(ua)) {
3901                    o.mobile = 'opera';
3902                    m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
3903                    if (m && m[1]) {
3904                        o.opera = numberify(m[1]);
3905                    }
3906                }
3907                m = ua.match(/Opera Mini[^;]*/);
3908
3909                if (m) {
3910                    o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3911                }
3912            } else { // not opera or webkit
3913                m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);
3914
3915                if (m && (m[1] || m[2])) {
3916                    o.ie = numberify(m[1] || m[2]);
3917                } else { // not opera, webkit, or ie
3918                    m = ua.match(/Gecko\/([^\s]*)/);
3919
3920                    if (m) {
3921                        o.gecko = 1; // Gecko detected, look for revision
3922                        m = ua.match(/rv:([^\s\)]*)/);
3923                        if (m && m[1]) {
3924                            o.gecko = numberify(m[1]);
3925                            if (/Mobile|Tablet/.test(ua)) {
3926                                o.mobile = "ffos";
3927                            }
3928                        }
3929                    }
3930                }
3931            }
3932        }
3933    }
3934
3935    //Check for known properties to tell if touch events are enabled on this device or if
3936    //the number of MSPointer touchpoints on this device is greater than 0.
3937    if (win && nav && !(o.chrome && o.chrome < 6)) {
3938        o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
3939    }
3940
3941    //It was a parsed UA, do not assign the global value.
3942    if (!subUA) {
3943
3944        if (typeof process === 'object') {
3945
3946            if (process.versions && process.versions.node) {
3947                //NodeJS
3948                o.os = process.platform;
3949                o.nodejs = numberify(process.versions.node);
3950            }
3951        }
3952
3953        YUI.Env.UA = o;
3954
3955    }
3956
3957    return o;
3958};
3959
3960
3961Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3962
3963/**
3964Performs a simple comparison between two version numbers, accounting for
3965standard versioning logic such as the fact that "535.8" is a lower version than
3966"535.24", even though a simple numerical comparison would indicate that it's
3967greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
3968considered equivalent.
3969
3970Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
39711 if _a_ is higher than _b_.
3972
3973Versions may be numbers or strings containing numbers and dots. For example,
3974both `535` and `"535.8.10"` are acceptable. A version string containing
3975non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
3976
3977@method compareVersions
3978@param {Number|String} a First version number to compare.
3979@param {Number|String} b Second version number to compare.
3980@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
3981    higher than _b_.
3982**/
3983Y.UA.compareVersions = function (a, b) {
3984    var aPart, aParts, bPart, bParts, i, len;
3985
3986    if (a === b) {
3987        return 0;
3988    }
3989
3990    aParts = (a + '').split('.');
3991    bParts = (b + '').split('.');
3992
3993    for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
3994        aPart = parseInt(aParts[i], 10);
3995        bPart = parseInt(bParts[i], 10);
3996
3997        /*jshint expr: true*/
3998        isNaN(aPart) && (aPart = 0);
3999        isNaN(bPart) && (bPart = 0);
4000
4001        if (aPart < bPart) {
4002            return -1;
4003        }
4004
4005        if (aPart > bPart) {
4006            return 1;
4007        }
4008    }
4009
4010    return 0;
4011};
4012YUI.Env.aliases = {
4013    "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
4014    "anim-shape-transform": ["anim-shape"],
4015    "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"],
4016    "attribute": ["attribute-base","attribute-complex"],
4017    "attribute-events": ["attribute-observable"],
4018    "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
4019    "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
4020    "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
4021    "base": ["base-base","base-pluginhost","base-build"],
4022    "cache": ["cache-base","cache-offline","cache-plugin"],
4023    "charts": ["charts-base"],
4024    "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
4025    "color": ["color-base","color-hsl","color-harmony"],
4026    "controller": ["router"],
4027    "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
4028    "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
4029    "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
4030    "datatype": ["datatype-date","datatype-number","datatype-xml"],
4031    "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
4032    "datatype-number": ["datatype-number-parse","datatype-number-format"],
4033    "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
4034    "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
4035    "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
4036    "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
4037    "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"],
4038    "event-custom": ["event-custom-base","event-custom-complex"],
4039    "event-gestures": ["event-flick","event-move"],
4040    "handlebars": ["handlebars-compiler"],
4041    "highlight": ["highlight-base","highlight-accentfold"],
4042    "history": ["history-base","history-hash","history-html5"],
4043    "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
4044    "json": ["json-parse","json-stringify"],
4045    "loader": ["loader-base","loader-rollup","loader-yui3"],
4046    "loader-pathogen-encoder": ["loader-base","loader-rollup","loader-yui3","loader-pathogen-combo
4046handler"],
4047    "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
4048    "pluginhost": ["pluginhost-base","pluginhost-config"],
4049    "querystring": ["querystring-parse","querystring-stringify"],
4050    "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
4051    "resize": ["resize-base","resize-proxy","resize-constrain"],
4052    "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
4053    "template": ["template-base","template-micro"],
4054    "text": ["text-accentfold","text-wordbreak"],
4055    "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
4056};
4057
4058
4059}, 'patched-v3.18.1', {
4060    "use": [
4061        "yui-base",
4062        "get",
4063        "features",
4064        "intl-base",
4065        "yui-log",
4066        "yui-later",
4067        "loader-base",
4068        "loader-rollup",
4069        "loader-yui3"
4070    ]
4071});
4072YUI.add('get', function (Y, NAME) {
4073
4074/*jslint boss:true, expr:true, laxbreak: true */
4075
4076/**
4077Provides dynamic loading of remote JavaScript and CSS resources.
4078
4079@module get
4080@class Get
4081@static
4082**/
4083
4084var Lang = Y.Lang,
4085
4086    CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
4087
4088    Get, Transaction;
4089
4090Y.Get = Get = {
4091    // -- Public Properties ----------------------------------------------------
4092
4093    /**
4094    Default options for CSS requests. Options specified here will override
4095    global defaults for CSS requests.
4096
4097    See the `options` property for all available options.
4098
4099    @property cssOptions
4100    @type Object
4101    @static
4102    @since 3.5.0
4103    **/
4104    cssOptions: {
4105        attributes: {
4106            rel: 'stylesheet'
4107        },
4108
4109        doc         : Y.config.linkDoc || Y.config.doc,
4110        pollInterval: 50
4111    },
4112
4113    /**
4114    Default options for JS requests. Options specified here will override global
4115    defaults for JS requests.
4116
4117    See the `options` property for all available options.
4118
4119    @property jsOptions
4120    @type Object
4121    @static
4122    @since 3.5.0
4123    **/
4124    jsOptions: {
4125        autopurge: true,
4126        doc      : Y.config.scriptDoc || Y.config.doc
4127    },
4128
4129    /**
4130    Default options to use for all requests.
4131
4132    Note that while all available options are documented here for ease of
4133    discovery, some options (like callback functions) only make sense at the
4134    transaction level.
4135
4136    Callback functions specified via the options object or the `options`
4137    parameter of the `css()`, `js()`, or `load()` methods will receive the
4138    transaction object as a parameter. See `Y.Get.Transaction` for details on
4139    the properties and methods available on transactions.
4140
4141    @static
4142    @since 3.5.0
4143    @property {Object} options
4144
4145    @property {Boolean} [options.async=false] Whether or not to load scripts
4146        asynchronously, meaning they're requested in parallel and execution
4147        order is not guaranteed. Has no effect on CSS, since CSS is always
4148        loaded asynchronously.
4149
4150    @property {Object} [options.attributes] HTML attribute name/value pairs that
4151        should be added to inserted nodes. By default, the `charset` attribute
4152        will be set to "utf-8" and nodes will be given an auto-generated `id`
4153        attribute, but you can override these with your own values if desired.
4154
4155    @property {Boolean} [options.autopurge] Whether or not to automatically
4156        purge inserted nodes after the purge threshold is reached. This is
4157        `true` by default for JavaScript, but `false` for CSS since purging a
4158        CSS node will also remove any styling applied by the referenced file.
4159
4160    @property {Object} [options.context] `this` object to use when calling
4161        callback functions. Defaults to the transaction object.
4162
4163    @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
4164        callbacks.
4165
4166    @property {Document} [options.doc] Document into which nodes should be
4167        inserted. By default, the current document is used.
4168
4169    @property {HTMLElement|String} [options.insertBefore] HTML element or id
4170        string of an element before which all generated nodes should be
4171        inserted. If not specified, Get will automatically determine the best
4172        place to insert nodes for maximum compatibility.
4173
4174    @property {Function} [options.onEnd] Callback to execute after a transaction
4175        is complete, regardless of whether it succeeded or failed.
4176
4177    @property {Function} [options.onFailure] Callback to execute after a
4178        transaction fails, times out, or is aborted.
4179
4180    @property {Function} [options.onProgress] Callback to execute after each
4181        individual request in a transaction either succeeds or fails.
4182
4183    @property {Function} [options.onSuccess] Callback to execute after a
4184        transaction completes successfully with no errors. Note that in browsers
4185        that don't support the `error` event on CSS `<link>` nodes, a failed CSS
4186        request may still be reported as a success because in these browsers
4187        it can be difficult or impossible to distinguish between success and
4188        failure for CSS resources.
4189
4190    @property {Function} [options.onTimeout] Callback to execute after a
4191        transaction times out.
4192
4193    @property {Number} [options.pollInterval=50] Polling interval (in
4194        milliseconds) for detecting CSS load completion in browsers that don't
4195        support the `load` event on `<link>` nodes. This isn't used for
4196        JavaScript.
4197
4198    @property {Number} [options.purgethreshold=20] Number of nodes to insert
4199        before triggering an automatic purge when `autopurge` is `true`.
4200
4201    @property {Number} [options.timeout] Number of milliseconds to wait before
4202        aborting a transaction. When a timeout occurs, the `onTimeout` callback
4203        is called, followed by `onFailure` and finally `onEnd`. By default,
4204        there is no timeout.
4205
4206    @property {String} [options.type] Resource type ("css" or "js"). This option
4207        is set automatically by the `css()` and `js()` functions and will be
4208        ignored there, but may be useful when using the `load()` function. If
4209        not specified, the type will be inferred from the URL, defaulting to
4210        "js" if the URL doesn't contain a recognizable file extension.
4211    **/
4212    options: {
4213        attributes: {
4214            charset: 'utf-8'
4215        },
4216
4217        purgethreshold: 20
4218    },
4219
4220    // -- Protected Properties -------------------------------------------------
4221
4222    /**
4223    Regex that matches a CSS URL. Used to guess the file type when it's not
4224    specified.
4225
4226    @property REGEX_CSS
4227    @type RegExp
4228    @final
4229    @protected
4230    @static
4231    @since 3.5.0
4232    **/
4233    REGEX_CSS: /\.css(?:[?;].*)?$/i,
4234
4235    /**
4236    Regex that matches a JS URL. Used to guess the file type when it's not
4237    specified.
4238
4239    @property REGEX_JS
4240    @type RegExp
4241    @final
4242    @protected
4243    @static
4244    @since 3.5.0
4245    **/
4246    REGEX_JS : /\.js(?:[?;].*)?$/i,
4247
4248    /**
4249    Contains information about the current environment, such as what script and
4250    link injection features it supports.
4251
4252    This object is created and populated the first time the `_getEnv()` method
4253    is called.
4254
4255    @property _env
4256    @type Object
4257    @protected
4258    @static
4259    @since 3.5.0
4260    **/
4261
4262    /**
4263    Mapping of document _yuid strings to <head> or <base> node references so we
4264    don't have to look the node up each time we want to insert a request node.
4265
4266    @property _insertCache
4267    @type Object
4268    @protected
4269    @static
4270    @since 3.5.0
4271    **/
4272    _insertCache: {},
4273
4274    /**
4275    Information about the currently pending transaction, if any.
4276
4277    This is actually an object with two properties: `callback`, containing the
4278    optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
4279    containing the actual transaction instance.
4280
4281    @property _pending
4282    @type Object
4283    @protected
4284    @static
4285    @since 3.5.0
4286    **/
4287    _pending: null,
4288
4289    /**
4290    HTML nodes eligible to be purged next time autopurge is triggered.
4291
4292    @property _purgeNodes
4293    @type HTMLElement[]
4294    @protected
4295    @static
4296    @since 3.5.0
4297    **/
4298    _purgeNodes: [],
4299
4300    /**
4301    Queued transactions and associated callbacks.
4302
4303    @property _queue
4304    @type Object[]
4305    @protected
4306    @static
4307    @since 3.5.0
4308    **/
4309    _queue: [],
4310
4311    // -- Public Methods -------------------------------------------------------
4312
4313    /**
4314    Aborts the specified transaction.
4315
4316    This will cause the transaction's `onFailure` callback to be called and
4317    will prevent any new script and link nodes from being added to the document,
4318    but any resources that have already been requested will continue loading
4319    (there's no safe way to prevent this, unfortunately).
4320
4321    *Note:* This method is deprecated as of 3.5.0, and will be removed in a
4322    future version of YUI. Use the transaction-level `abort()` method instead.
4323
4324    @method abort
4325    @param {Get.Transaction} transaction Transaction to abort.
4326    @deprecated Use the `abort()` method on the transaction instead.
4327    @static
4328    **/
4329    abort: function (transaction) {
4330        var i, id, item, len, pending;
4331
4332
4333        if (!transaction.abort) {
4334            id          = transaction;
4335            pending     = this._pending;
4336            transaction = null;
4337
4338            if (pending && pending.transaction.id === id) {
4339                transaction   = pending.transaction;
4340                this._pending = null;
4341            } else {
4342                for (i = 0, len = this._queue.length; i < len; ++i) {
4343                    item = this._queue[i].transaction;
4344
4345                    if (item.id === id) {
4346                        transaction = item;
4347                        this._queue.splice(i, 1);
4348                        break;
4349                    }
4350                }
4351            }
4352        }
4353
4354        transaction && transaction.abort();
4355    },
4356
4357    /**
4358    Loads one or more CSS files.
4359
4360    The _urls_ parameter may be provided as a URL string, a request object,
4361    or an array of URL strings and/or request objects.
4362
4363    A request object is just an object that contains a `url` property and zero
4364    or more options that should apply specifically to that request.
4365    Request-specific options take priority over transaction-level options and
4366    default options.
4367
4368    URLs may be relative or absolute, and do not have to have the same origin
4369    as the current page.
4370
4371    The `options` parameter may be omitted completely and a callback passed in
4372    its place, if desired.
4373
4374    @example
4375
4376        // Load a single CSS file and log a message on completion.
4377        Y.Get.css('foo.css', function (err) {
4378            if (err) {
4379            } else {
4380            }
4381        });
4382
4383        // Load multiple CSS files and log a message when all have finished
4384        // loading.
4385        var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
4386
4387        Y.Get.css(urls, function (err) {
4388            if (err) {
4389            } else {
4390            }
4391        });
4392
4393        // Specify transaction-level options, which will apply to all requests
4394        // within the transaction.
4395        Y.Get.css(urls, {
4396            attributes: {'class': 'my-css'},
4397            timeout   : 5000
4398        });
4399
4400        // Specify per-request options, which override transaction-level and
4401        // default options.
4402        Y.Get.css([
4403            {url: 'foo.css', attributes: {id: 'foo'}},
4404            {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4405        ]);
4406
4407    @method css
4408    @param {String|Object|Array}
4408 urls URL string, request object, or array
4409        of URLs and/or request objects to load.
4410    @param {Object} [options] Options for this transaction. See the
4411        `Y.Get.options` property for a complete list of available options.
4412    @param {Function} [callback] Callback function to be called on completion.
4413        This is a general callback and will be called before any more granular
4414        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4415        object.
4416
4417        @param {Array|null} callback.err Array of errors that occurred during
4418            the transaction, or `null` on success.
4419        @param {Get.Transaction} callback.transaction Transaction object.
4420
4421    @return {Get.Transaction} Transaction object.
4422    @static
4423    **/
4424    css: function (urls, options, callback) {
4425        return this._load('css', urls, options, callback);
4426    },
4427
4428    /**
4429    Loads one or more JavaScript resources.
4430
4431    The _urls_ parameter may be provided as a URL string, a request object,
4432    or an array of URL strings and/or request objects.
4433
4434    A request object is just an object that contains a `url` property and zero
4435    or more options that should apply specifically to that request.
4436    Request-specific options take priority over transaction-level options and
4437    default options.
4438
4439    URLs may be relative or absolute, and do not have to have the same origin
4440    as the current page.
4441
4442    The `options` parameter may be omitted completely and a callback passed in
4443    its place, if desired.
4444
4445    Scripts will be executed in the order they're specified unless the `async`
4446    option is `true`, in which case they'll be loaded in parallel and executed
4447    in whatever order they finish loading.
4448
4449    @example
4450
4451        // Load a single JS file and log a message on completion.
4452        Y.Get.js('foo.js', function (err) {
4453            if (err) {
4454            } else {
4455            }
4456        });
4457
4458        // Load multiple JS files, execute them in order, and log a message when
4459        // all have finished loading.
4460        var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4461
4462        Y.Get.js(urls, function (err) {
4463            if (err) {
4464            } else {
4465            }
4466        });
4467
4468        // Specify transaction-level options, which will apply to all requests
4469        // within the transaction.
4470        Y.Get.js(urls, {
4471            attributes: {'class': 'my-js'},
4472            timeout   : 5000
4473        });
4474
4475        // Specify per-request options, which override transaction-level and
4476        // default options.
4477        Y.Get.js([
4478            {url: 'foo.js', attributes: {id: 'foo'}},
4479            {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4480        ]);
4481
4482    @method js
4483    @param {String|Object|Array} urls URL string, request object, or array
4484        of URLs and/or request objects to load.
4485    @param {Object} [options] Options for this transaction. See the
4486        `Y.Get.options` property for a complete list of available options.
4487    @param {Function} [callback] Callback function to be called on completion.
4488        This is a general callback and will be called before any more granular
4489        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4490        object.
4491
4492        @param {Array|null} callback.err Array of errors that occurred during
4493            the transaction, or `null` on success.
4494        @param {Get.Transaction} callback.transaction Transaction object.
4495
4496    @return {Get.Transaction} Transaction object.
4497    @since 3.5.0
4498    @static
4499    **/
4500    js: function (urls, options, callback) {
4501        return this._load('js', urls, options, callback);
4502    },
4503
4504    /**
4505    Loads one or more CSS and/or JavaScript resources in the same transaction.
4506
4507    Use this method when you want to load both CSS and JavaScript in a single
4508    transaction and be notified when all requested URLs have finished loading,
4509    regardless of type.
4510
4511    Behavior and options are the same as for the `css()` and `js()` methods. If
4512    a resource type isn't specified in per-request options or transaction-level
4513    options, Get will guess the file type based on the URL's extension (`.css`
4514    or `.js`, with or without a following query string). If the file type can't
4515    be guessed from the URL, a warning will be logged and Get will assume the
4516    URL is a JavaScript resource.
4517
4518    @example
4519
4520        // Load both CSS and JS files in a single transaction, and log a message
4521        // when all files have finished loading.
4522        Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4523            if (err) {
4524            } else {
4525            }
4526        });
4527
4528    @method load
4529    @param {String|Object|Array}
4529 urls URL string, request object, or array
4530        of URLs and/or request objects to load.
4531    @param {Object} [options] Options for this transaction. See the
4532        `Y.Get.options` property for a complete list of available options.
4533    @param {Function} [callback] Callback function to be called on completion.
4534        This is a general callback and will be called before any more granular
4535        callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4536        object.
4537
4538        @param {Array|null} err Array of errors that occurred during the
4539            transaction, or `null` on success.
4540        @param {Get.Transaction} Transaction object.
4541
4542    @return {Get.Transaction} Transaction object.
4543    @since 3.5.0
4544    @static
4545    **/
4546    load: function (urls, options, callback) {
4547        return this._load(null, urls, options, callback);
4548    },
4549
4550    // -- Protected Methods ----------------------------------------------------
4551
4552    /**
4553    Triggers an automatic purge if the purge threshold has been reached.
4554
4555    @method _autoPurge
4556    @param {Number} threshold Purge threshold to use, in milliseconds.
4557    @protected
4558    @since 3.5.0
4559    @static
4560    **/
4561    _autoPurge: function (threshold) {
4562        if (threshold && this._purgeNodes.length >= threshold) {
4563            this._purge(this._purgeNodes);
4564        }
4565    },
4566
4567    /**
4568    Populates the `_env` property with information about the current
4569    environment.
4570
4571    @method _getEnv
4572    @return {Object} Environment information.
4573    @protected
4574    @since 3.5.0
4575    @static
4576    **/
4577    _getEnv: function () {
4578        var doc = Y.config.doc,
4579            ua  = Y.UA;
4580
4581        // Note: some of these checks require browser sniffs since it's not
4582        // feasible to load test files on every pageview just to perform a
4583        // feature test. I'm sorry if this makes you sad.
4584        return (this._env = {
4585
4586            // True if this is a browser that supports disabling async mode on
4587            // dynamically created script nodes. See
4588            // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4589
4590            // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4591            // because it is async by default, and allows you to disable async by setting it to false
4592            async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4593
4594            // True if this browser fires an event when a dynamically injected
4595            // link node fails to load. This is currently true for Firefox 9+
4596            // and WebKit 535.24+
4597            cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4598
4599            // True if this browser fires an event when a dynamically injected
4600            // link node finishes loading. This is currently true for IE, Opera,
4601            // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4602            // DOM 0 "onload" event, but not "load". All versions of IE fire
4603            // "onload".
4604            // davglass: Seems that Chrome on Android needs this to be false.
4605            cssLoad: (
4606                    (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4607                    ua.compareVersions(ua.webkit, 535.24) >= 0
4608                ) && !(ua.chrome && ua.chrome <= 18),
4609
4610            // True if this browser preserves script execution order while
4611            // loading scripts in parallel as long as the script node's `async`
4612            // attribute is set to false to explicitly disable async execution.
4613            preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4614        });
4615    },
4616
4617    _getTransaction: function (urls, options) {
4618        var requests = [],
4619            i, len, req, url;
4620
4621        if (!Lang.isArray(urls)) {
4622            urls = [urls];
4623        }
4624
4625        options = Y.merge(this.options, options);
4626
4627        // Clone the attributes object so we don't end up modifying it by ref.
4628        options.attributes = Y.merge(this.options.attributes,
4629                options.attributes);
4630
4631        for (i = 0, len = urls.length; i < len; ++i) {
4632            url = urls[i];
4633            req = {attributes: {}};
4634
4635            // If `url` is a string, we create a URL object for it, then mix in
4636            // global options and request-specific options. If it's an object
4637            // with a "url" property, we assume it's a request object c
4637ontaining
4638            // URL-specific options.
4639            if (typeof url === 'string') {
4640                req.url = url;
4641            } else if (url.url) {
4642                // URL-specific options override both global defaults and
4643                // request-specific options.
4644                Y.mix(req, url, false, null, 0, true);
4645                url = url.url; // Make url a string so we can use it later.
4646            } else {
4647                continue;
4648            }
4649
4650            Y.mix(req, options, false, null, 0, true);
4651
4652            // If we didn't get an explicit type for this URL either in the
4653            // request options or the URL-specific options, try to determine
4654            // one from the file extension.
4655            if (!req.type) {
4656                if (this.REGEX_CSS.test(url)) {
4657                    req.type = 'css';
4658                } else {
4659                    if (!this.REGEX_JS.test(url)) {
4660                    }
4661
4662                    req.type = 'js';
4663                }
4664            }
4665
4666            // Mix in type-specific default options, but don't overwrite any
4667            // options that have already been set.
4668            Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4669                false, null, 0, true);
4670
4671            // Give the node an id attribute if it doesn't already have one.
4672            req.attributes.id || (req.attributes.id = Y.guid());
4673
4674            // Backcompat for <3.5.0 behavior.
4675            if (req.win) {
4676                req.doc = req.win.document;
4677            } else {
4678                req.win = req.doc.defaultView || req.doc.parentWindow;
4679            }
4680
4681            if (req.charset) {
4682                req.attributes.charset = req.charset;
4683            }
4684
4685            requests.push(req);
4686        }
4687
4688        return new Transaction(requests, options);
4689    },
4690
4691    _load: function (type, urls, options, callback) {
4692        var transaction;
4693
4694        // Allow callback as third param.
4695        if (typeof options === 'function') {
4696            callback = options;
4697            options  = {};
4698        }
4699
4700        options || (options = {});
4701        options.type = type;
4702
4703        options._onFinish = Get._onTransactionFinish;
4704
4705        if (!this._env) {
4706            this._getEnv();
4707        }
4708
4709        transaction = this._getTransaction(urls, options);
4710
4711        this._queue.push({
4712            callback   : callback,
4713            transaction: transaction
4714        });
4715
4716        this._next();
4717
4718        return transaction;
4719    },
4720
4721    _onTransactionFinish : function() {
4722        Get._pending = null;
4723        Get._next();
4724    },
4725
4726    _next: function () {
4727        var item;
4728
4729        if (this._pending) {
4730            return;
4731        }
4732
4733        item = this._queue.shift();
4734
4735        if (item) {
4736            this._pending = item;
4737            item.transaction.execute(item.callback);
4738        }
4739    },
4740
4741    _purge: function (nodes) {
4742        var purgeNodes    = this._purgeNodes,
4743            isTransaction = nodes !== purgeNodes,
4744            index, node;
4745
4746        while (node = nodes.pop()) { // assignment
4747            // Don't purge nodes that haven't finished loading (or errored out),
4748            // since this can hang the transaction.
4749            if (!node._yuiget_finished) {
4750                continue;
4751            }
4752
4753            node.parentNode && node.parentNode.removeChild(node);
4754
4755            // If this is a transaction-level purge and this node also exists in
4756            // the Get-level _purgeNodes array, we need to remove it from
4757            // _purgeNodes to avoid creating a memory leak. The indexOf lookup
4758            // sucks, but until we get WeakMaps, this is the least troublesome
4759            // way to do this (we can't just hold onto node ids because they may
4760            // not be in the same document).
4761            if (isTransaction) {
4762                index = Y.Array.indexOf(purgeNodes, node);
4763
4764                if (index > -1) {
4765                    purgeNodes.splice(index, 1);
4766                }
4767            }
4768        }
4769    }
4770};
4771
4772/**
4773Alias for `js()`.
4774
4775@method script
4776@static
4777**/
4778Get.script = Get.js;
4779
4780/**
4781Represents a Get transaction, which may contain requests for one or more JS or
4782CSS files.
4783
4784This class should not be instantiated manually. Instances will be created and
4785returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4786
4787@class Get.Transaction
4788@constructor
4789@since 3.5.0
4790**/
4791Get.Transaction = Transaction = function (requests, options) {
4792    var self = this;
4793
4794    self.id       = Transaction._lastId += 1;
4795    self.data     = options.data;
4796    self.errors   = [];
4797    self.nodes    = [];
4798    self.options  = options;
4799    self.requests = requests;
4800
4801    self._callbacks = []; // callbacks to call after execution finishes
4802    self._queue     = [];
4803    self._reqsWaiting   = 0;
4804
4805    // Deprecated pre-3.5.0 properties.
4806    self.tId = self.id; // Use `id` instead.
4807    self.win = options.win || Y.config.win;
4808};
4809
4810/**
4811Arbitrary data object associated with this transaction.
4812
4813This object comes from the options passed to `Get.css()`, `Get.js()`, or
4814`Get.load()`, and will be `undefined` if no data object was specified.
4815
4816@property {Object} data
4817**/
4818
4819/**
4820Array of errors that have occurred during this transaction, if any. Each error
4821object has the following properties:
4822`errors.error`: Error message.
4823`errors.request`: Request object related to the error.
4824
4825@since 3.5.0
4826@property {Object[]} errors
4827**/
4828
4829/**
4830Numeric id for this transaction, unique among all transactions within the same
4831YUI sandbox in the current pageview.
4832
4833@property {Number} id
4834@since 3.5.0
4835**/
4836
4837/**
4838HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
4839during the current transaction.
4840
4841@property {HTMLElement[]} nodes
4842**/
4843
4844/**
4845Options associated with this transaction.
4846
4847See `Get.options` for the full list of available options.
4848
4849@property {Object} options
4850@since 3.5.0
4851**/
4852
4853/**
4854Request objects contained in this transaction. Each request object represents
4855one CSS or JS URL that will be (or has been) requested and loaded into the page.
4856
4857@property {Object} requests
4858@since 3.5.0
4859**/
4860
4861/**
4862Id of the most recent transaction.
4863
4864@property _lastId
4865@type Number
4866@protected
4867@static
4868**/
4869Transaction._lastId = 0;
4870
4871Transaction.prototype = {
4872    // -- Public Properties ----------------------------------------------------
4873
4874    /**
4875    Current state of this transaction. One of "new", "executing", or "done".
4876
4877    @property _state
4878    @type String
4879    @protected
4880    **/
4881    _state: 'new', // "new", "executing", or "done"
4882
4883    // -- Public Methods -------------------------------------------------------
4884
4885    /**
4886    Aborts this transaction.
4887
4888    This will cause the transaction's `onFailure` callback to be called and
4889    will prevent any new script and link nodes from being added to the document,
4890    but any resources that have already been requested will continue loading
4891    (there's no safe way to prevent this, unfortunately).
4892
4893    @method abort
4894    @param {String} [msg="Aborted."] Optional message to use in the `errors`
4895        array describing why the transaction was aborted.
4896    **/
4897    abort: function (msg) {
4898        this._pending    = null;
4899        this._pendingCSS = null;
4900        this._pollTimer  = clearTimeout(this._pollTimer);
4901        this._queue      = [];
4902        this._reqsWaiting    = 0;
4903
4904        this.errors.push({error: msg || 'Aborted'});
4905        this._finish();
4906    },
4907
4908    /**
4909    Begins execting the transaction.
4910
4911    There's usually no reason to call this manually, since Get will call it
4912    automatically when other pending transactions have finished. If you really
4913    want to execute your transaction before Get does, you can, but be aware that
4914    this transaction's scripts may end up executing before the scripts in other
4915    pending transactions.
4916
4917    If the transaction is already executing, the specified callback (if any)
4918    will be queued and called after execution finishes. If the transaction has
4919    already finished, the callback will be called immediately (the transaction
4920    will not be executed again).
4921
4922    @method execute
4923    @param {Function} callback Callback function to execute after all requests
4924        in the transaction are complete, or after the transaction is aborted.
4925    **/
4926    execute: function (callback) {
4927        var self     = this,
4928            requests = self.requests,
4929            state    = self._state,
4930            i, len, queue, req;
4931
4932        if (state === 'done') {
4933            callback && callback(self.errors.length ? self.errors : null, self);
4934            return;
4935        } else {
4936            callback && self._callbacks.push(callback);
4937
4938            if (state === 'executing') {
4939                return;
4940            }
4941        }
4942
4943        self._state = 'executing';
4944        self._queue = queue = [];
4945
4946        if (self.options.timeout) {
4947            self._timeout = setTimeout(function () {
4948                self.abort('Timeout');
4949            }, self.options.timeout);
4950        }
4951
4952        self._reqsWaiting = requests.length;
4953
4954        for (i = 0, len = requests.length; i < len; ++i) {
4955            req = requests[i];
4956
4957            if (req.async || req.type === 'css') {
4958                // No need to queue CSS or fully async JS.
4959                self._insert(req);
4960            } else {
4961                queue.push(req);
4962            }
4963        }
4964
4965        self._next();
4966    },
4967
4968    /**
4969    Manually purges any `<script>` or `<link>` nodes this transaction has
4970    created.
4971
4972    Be careful when purging a transaction that contains CSS requests, since
4973    removing `<link>` nodes will also remove any styles they applied.
4974
4975    @method purge
4976    **/
4977    purge: function () {
4978        Get._purge(this.nodes);
4979    },
4980
4981    // -- Protected Methods ----------------------------------------------------
4982    _createNode: function (name, attrs, doc) {
4983        var node = doc.createElement(name),
4984            attr, testEl;
4985
4986        if (!CUSTOM_ATTRS) {
4987            // IE6 and IE7 expect property names rather than attribute names for
4988            // certain attributes. Rather than sniffing, we do a quick feature
4989            // test the first time _createNode() runs to determine whether we
4990            // need to provide a workaround.
4991            testEl = doc.createElement('div');
4992            testEl.setAttribute('class', 'a');
4993
4994            CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
4995                'for'  : 'htmlFor',
4996                'class': 'className'
4997            };
4998        }
4999
5000        for (attr in attrs) {
5001            if (attrs.hasOwnProperty(attr)) {
5002                node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
5003            }
5004        }
5005
5006        return node;
5007    },
5008
5009    _finish: function () {
5010        var errors  = this.errors.length ? this.errors : null,
5011            options = this.options,
5012            thisObj = options.context || this,
5013            data, i, len;
5014
5015        if (this._state === 'done') {
5016            return;
5017        }
5018
5019        this._state = 'done';
5020
5021        for (i = 0, len = this._callbacks.length; i < len; ++i) {
5022            this._callbacks[i].call(thisObj, errors, this);
5023        }
5024
5025        data = this._getEventData();
5026
5027        if (errors) {
5028            if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
5029                options.onTimeout.call(thisObj, data);
5030            }
5031
5032            if (options.onFailure) {
5033                options.onFailure.call(thisObj, data);
5034            }
5035        } else if (options.onSuccess) {
5036            options.onSuccess.call(thisObj, data);
5037        }
5038
5039        if (options.onEnd) {
5040            options.onEnd.call(thisObj, data);
5041        }
5042
5043        if (options._onFinish) {
5044            options._onFinish();
5045        }
5046    },
5047
5048    _getEventData: function (req) {
5049        if (req) {
5050            // This merge is necessary for backcompat. I hate it.
5051            return Y.merge(this, {
5052                abort  : this.abort, // have to copy these because the prototype isn't preserved
5053                purge  : this.purge,
5054                request: req,
5055                url    : req.url,
5056                win    : req.win
5057            });
5058        } else {
5059            return this;
5060        }
5061    },
5062
5063    _getInsertBefore: function (req) {
5064        var doc = req.doc,
5065            el  = req.insertBefore,
5066            cache, docStamp;
5067
5068        if (el) {
5069            return typeof el === 'string' ? doc.getElementById(el) : el;
5070        }
5071
5072        cache    = Get._insertCache;
5073        docStamp = Y.stamp(doc);
5074
5075        if ((el = cache[docStamp])) { // assignment
5076            return el;
5077        }
5078
5079        // Inserting before a <base> tag apparently works around an IE bug
5080        // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
5081        // bug that is, exactly. Better safe than sorry?
5082        if ((el = doc.getElementsByTagName('base')[0])) { // assignment
5083            return (cache[docStamp] = el);
5084        }
5085
5086        // Look for a <head> element.
5087        el = doc.head || doc.getElementsByTagName('head')[0];
5088
5089        if (el) {
5090            // Create a marker node at the end of <head> to use as an insertion
5091            // point. Inserting before this node will ensure that all our CSS
5092            // gets inserted in the correct order, to maintain style precedence.
5093            el.appendChild(doc.createTextNode(''));
5094            return (cache[docStamp] = el.lastChild);
5095        }
5096
5097        // If all else fails, just insert before the first script node on the
5098        // page, which is virtually guaranteed to exist.
5099        return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
5100    },
5101
5102    _insert: function (req) {
5103        var env          = Get._env,
5104            insertBefore = this._getInsertBefore(req),
5105            isScript     = req.type === 'js',
5106            node         = req.node,
5107            self         = this,
5108            ua           = Y.UA,
5109            cssTimeout, nodeType;
5110
5111        if (!node) {
5112            if (isScript) {
5113                nodeType = 'script';
5114            } else if (!env.cssLoad && ua.gecko) {
5115                nodeType = 'style';
5116            } else {
5117                nodeType = 'link';
5118            }
5119
5120            node = req.node = this._createNode(nodeType, req.attributes,
5121                req.doc);
5122        }
5123
5124        function onError() {
5125            self._progress('Failed to load ' + req.url, req);
5126        }
5127
5128        function onLoad() {
5129            if (cssTimeout) {
5130                clearTimeout(cssTimeout);
5131            }
5132
5133            self._progress(null, req);
5134        }
5135
5136        // Deal with script asynchronicity.
5137        if (isScript) {
5138            node.setAttribute('src', req.url);
5139
5140            if (req.async) {
5141                // Explicitly indicate that we want the browser to execute this
5142                // script asynchronously. This is necessary for older browsers
5143                // like Firefox <4.
5144                node.async = true;
5145            } else {
5146                if (env.async) {
5147                    // This browser treats injected scripts as async by default
5148                    // (standard HTML5 behavior) but asynchronous loading isn't
5149                    // desired, so tell the browser not to mark this script as
5150                    // async.
5151                    node.async = false;
5152                }
5153
5154                // If this browser doesn't preserve script execution order based
5155                // on insertion order, we'll need to avoid inserting other
5156                // scripts until this one finishes loading.
5157                if (!env.preservesScriptOrder) {
5158                    this._pending = req;
5159                }
5160            }
5161        } else {
5162            if (!env.cssLoad && ua.gecko) {
5163                // In Firefox <9, we can import the requested URL into a <style>
5164                // node and poll for the existence of node.sheet.cssRules. This
5165                // gives us a reliable way to determine CSS load completion that
5166                // also works for cross-domain stylesheets.
5167                //
5168                // Props to Zach Leatherman for calling my attention to this
5169                // technique.
5170                node.innerHTML = (req.attributes.charset ?
5171                    '@charset "' + req.attributes.charset + '";' : '') +
5172                    '@import "' + req.url + '";';
5173            } else {
5174                node.setAttribute('href', req.url);
5175            }
5176        }
5177
5178        // Inject the node.
5179        if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
5180            // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
5181            node.onreadystatechange = function () {
5182                if (/loaded|complete/.test(node.readyState)) {
5183                    node.onreadystatechange = null;
5184                    onLoad();
5185                }
5186            };
5187        } else if (!isScript && !env.cssLoad) {
5188            // CSS on Firefox <9 or WebKit.
5189            this._poll(req);
5190        } else {
5191            // Script or CSS on everything else. Using DOM 0 events because that
5192            // evens the playing field with older IEs.
5193
5194            if (ua.ie >= 10) {
5195
5196                // We currently need to introduce a timeout for IE10, since it
5197                // calls onerror/onload synchronously for 304s - messing up existing
5198                // program flow.
5199
5200                // Remove this block if the following bug gets fixed by GA
5201                /*jshint maxlen: 1500 */
5202                // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
5203                node.onerror = function() { setTimeout(onError, 0); };
5204                node.onload  = function() { setTimeout(onLoad, 0); };
5205            } else {
5206                node.onerror = onError;
5207                node.onload  = onLoad;
5208            }
5209
5210            // If this browser doesn't fire an event when CSS fails to load,
5211            // fail after a timeout to avoid blocking the transaction queue.
5212            if (!env.cssFail && !isScript) {
5213                cssTimeout = setTimeout(onError, req.timeout || 3000);
5214            }
5215        }
5216
5217        this.nodes.push(node);
5218        insertBefore.parentNode.insertBefore(node, insertBefore);
5219    },
5220
5221    _next: function () {
5222        if (this._pending) {
5223            return;
5224        }
5225
5226        // If there are requests in the queue, insert the next queued request.
5227        // Otherwise, if we're waiting on already-inserted requests to finish,
5228        // wait longer. If there are no queued requests and we're not waiting
5229        // for anything to load, then we're done!
5230        if (this._queue.length) {
5231            this._insert(this._queue.shift());
5232        } else if (!this._reqsWaiting) {
5233            this._finish();
5234        }
5235    },
5236
5237    _poll: function (newReq) {
5238        var self       = this,
5239            pendingCSS = self._pendingCSS,
5240            isWebKit   = Y.UA.webkit,
5241            i, hasRules, j, nodeHref, req, sheets;
5242
5243        if (newReq) {
5244            pendingCSS || (pendingCSS = self._pendingCSS = []);
5245            pendingCSS.push(newReq);
5246
5247            if (self._pollTimer) {
5248                // A poll timeout is already pending, so no need to create a
5249                // new one.
5250                return;
5251            }
5252        }
5253
5254        self._pollTimer = null;
5255
5256        // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
5257        // will still be treated as a success. There's no good workaround for
5258        // this.
5259
5260        for (i = 0; i < pendingCSS.length; ++i) {
5261            req = pendingCSS[i];
5262
5263            if (isWebKit) {
5264                // Look for a stylesheet matching the pending URL.
5265                sheets   = req.doc.styleSheets;
5266                j        = sheets.length;
5267                nodeHref = req.node.href;
5268
5269                while (--j >= 0) {
5270                    if (sheets[j].href === nodeHref) {
5271                        pendingCSS.splice(i, 1);
5272                        i -= 1;
5273                        self._progress(null, req);
5274                        break;
5275                    }
5276                }
5277            } else {
5278                // Many thanks to Zach Leatherman for calling my attention to
5279                // the @import-based cross-domain technique used here, and to
5280                // Oleg Slobodskoi for an earlier same-domain implementation.
5281                //
5282                // See Zach's blog for more details:
5283                // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
5284                try {
5285                    // We don't really need to store this value since we never
5286                    // use it again, but if we don't store it, Closure Compiler
5287                    // assumes the code is useless and removes it.
5288                    hasRules = !!req.node.sheet.cssRules;
5289
5290                    // If we get here, the stylesheet has loaded.
5291                    pendingCSS.splice(i, 1);
5292                    i -= 1;
5293                    self._progress(null, req);
5294                } catch (ex) {
5295                    // An exception means the stylesheet is still loading.
5296                }
5297            }
5298        }
5299
5300        if (pendingCSS.length) {
5301            self._pollTimer = setTimeout(function () {
5302                self._poll.call(self);
5303            }, self.options.pollInterval);
5304        }
5305    },
5306
5307    _progress: function (err, req) {
5308        var options = this.options;
5309
5310        if (err) {
5311            req.error = err;
5312
5313            this.errors.push({
5314                error  : err,
5315                request: req
5316            });
5317
5318        }
5319
5320        req.node._yuiget_finished = req.finished = true;
5321
5322        if (options.onProgress) {
5323            options.onProgress.call(options.context || this,
5324                this._getEventData(req));
5325        }
5326
5327        if (req.autopurge) {
5328            // Pre-3.5.0 Get always excludes the most recent node from an
5329            // autopurge. I find this odd, but I'm keeping that behavior for
5330            // the sake of backcompat.
5331            Get._autoPurge(this.options.purgethreshold);
5332            Get._purgeNodes.push(req.node);
5333        }
5334
5335        if (this._pending === req) {
5336            this._pending = null;
5337        }
5338
5339        this._reqsWaiting -= 1;
5340
5341        this._next();
5342    }
5343};
5344
5345
5346}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5347YUI.add('features', function (Y, NAME) {
5348
5349var feature_tests = {};
5350
5351/**
5352Contains the core of YUI's feature test architecture.
5353@module features
5354*/
5355
5356/**
5357* Feature detection
5358* @class Features
5359* @static
5360*/
5361
5362Y.mix(Y.namespace('Features'), {
5363
5364    /**
5365    * Object hash of all registered feature tests
5366    * @property tests
5367    * @type Object
5368    */
5369    tests: feature_tests,
5370
5371    /**
5372    * Add a test to the system
5373    *
5374    *   ```
5375    *   Y.Features.add("load", "1", {});
5376    *   ```
5377    *
5378    * @method add
5379    * @param {String} cat The category, right now only 'load' is supported
5380    * @param {String}
5380 name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
5381    * @param {Object} o Object containing test properties
5382    * @param {String} o.name The name of the test
5383    * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
5384    * @param {String} o.trigger The module that triggers this test.
5385    */
5386    add: function(cat, name, o) {
5387        feature_tests[cat] = feature_tests[cat] || {};
5388        feature_tests[cat][name] = o;
5389    },
5390    /**
5391    * Execute all tests of a given category and return the serialized results
5392    *
5393    *   ```
5394    *   caps=1:1;2:1;3:0
5395    *   ```
5396    * @method all
5397    * @param {String} cat The category to execute
5398    * @param {Array} args The arguments to pass to the test function
5399    * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
5400    */
5401    all: function(cat, args) {
5402        var cat_o = feature_tests[cat],
5403            // results = {};
5404            result = [];
5405        if (cat_o) {
5406            Y.Object.each(cat_o, function(v, k) {
5407                result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
5408            });
5409        }
5410
5411        return (result.length) ? result.join(';') : '';
5412    },
5413    /**
5414    * Run a specific test and return a Boolean response.
5415    *
5416    *   ```
5417    *   Y.Features.test("load", "1");
5418    *   ```
5419    *
5420    * @method test
5421    * @param {String} cat The category of the test to run
5422    * @param {String} name The name of the test to run
5423    * @param {Array} args The arguments to pass to the test function
5424    * @return {Boolean} True or false if the test passed/failed.
5425    */
5426    test: function(cat, name, args) {
5427        args = args || [];
5428        var result, ua, test,
5429            cat_o = feature_tests[cat],
5430            feature = cat_o && cat_o[name];
5431
5432        if (!feature) {
5433        } else {
5434
5435            result = feature.result;
5436
5437            if (Y.Lang.isUndefined(result)) {
5438
5439                ua = feature.ua;
5440                if (ua) {
5441                    result = (Y.UA[ua]);
5442                }
5443
5444                test = feature.test;
5445                if (test && ((!ua) || result)) {
5446                    result = test.apply(Y, args);
5447                }
5448
5449                feature.result = result;
5450            }
5451        }
5452
5453        return result;
5454    }
5455});
5456
5457// Y.Features.add("load", "1", {});
5458// Y.Features.test("load", "1");
5459// caps=1:1;2:0;3:1;
5460
5461/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
5462/*jshint maxlen:900, eqeqeq: false */
5463var add = Y.Features.add;
5464// app-transitions-native
5465add('load', '0', {
5466    "name": "app-transitions-native",
5467    "test": function (Y) {
5468    var doc  = Y.config.doc,
5469        node = doc ? doc.documentElement : null;
5470
5471    if (node && node.style) {
5472        return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5473    }
5474
5475    return false;
5476},
5477    "trigger": "app-transitions"
5478});
5479// autocomplete-list-keys
5480add('load', '1', {
5481    "name": "autocomplete-list-keys",
5482    "test": function (Y) {
5483    // Only add keyboard support to autocomplete-list if this doesn't appear to
5484    // be an iOS or Android-based mobile device.
5485    //
5486    // There's currently no feasible way to actually detect whether a device has
5487    // a hardware keyboard, so this sniff will have to do. It can easily be
5488    // overridden by manually loading the autocomplete-list-keys module.
5489    //
5490    // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5491    // doesn't fire the keyboard events used by AutoCompleteList, so there's
5492    // no point loading the -keys module even when a bluetooth keyboard may be
5493    // available.
5494    return !(Y.UA.ios || Y.UA.android);
5495},
5496    "trigger": "autocomplete-list"
5497});
5498// dd-gestures
5499add('load', '2', {
5500    "name": "dd-gestures",
5501    "trigger": "dd-drag",
5502    "ua": "touchEnabled"
5503});
5504// dom-style-ie
5505add('load', '3', {
5506    "name": "dom-style-ie",
5507    "test": function (Y) {
5508
5509    var testFeature = Y.Features.test,
5510        addFeature = Y.Features.add,
5511        WINDOW = Y.config.win,
5512        DOCUMENT = Y.config.doc,
5513        DOCUMENT_ELEMENT = 'documentElement',
5514        ret = false;
5515
5516    addFeature('style', 'computedStyle', {
5517        test: function() {
5518            return WINDOW && 'getComputedStyle' in WINDOW;
5519        }
5520    });
5521
5522    addFeature('style', 'opacity', {
5523        test: function() {
5524            return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5525        }
5526    });
5527
5528    ret =  (!testFeature('style', 'opacity') &&
5529            !testFeature('style', 'computedStyle'));
5530
5531    return ret;
5532},
5533    "trigger": "dom-style"
5534});
5535// editor-para-ie
5536add('load', '4', {
5537    "name": "editor-para-ie",
5538    "trigger": "editor-para",
5539    "ua": "ie",
5540    "when": "instead"
5541});
5542// event-base-ie
5543add('load', '5', {
5544    "name": "event-base-ie",
5545    "test": function(Y) {
5546    var imp = Y.config.doc && Y.config.doc.implementation;
5547    return (imp && (!imp.hasFeature('Events', '2.0')));
5548},
5549    "trigger": "node-base"
5550});
5551// graphics-canvas
5552add('load', '6', {
5553    "name": "graphics-canvas",
5554    "test": function(Y) {
5555    var DOCUMENT = Y.config.doc,
5556        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5557		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5558        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5559    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5560},
5561    "trigger": "graphics"
5562});
5563// graphics-canvas-default
5564add('load', '7', {
5565    "name": "graphics-canvas-default",
5566    "test": function(Y) {
5567    var DOCUMENT = Y.config.doc,
5568        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5569		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5570        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5571    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5572},
5573    "trigger": "graphics"
5574});
5575// graphics-svg
5576add('load', '8', {
5577    "name": "graphics-svg",
5578    "test": function(Y) {
5579    var DOCUMENT = Y.config.doc,
5580        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5581		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5582        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5583
5584    return svg && (useSVG || !canvas);
5585},
5586    "trigger": "graphics"
5587});
5588// graphics-svg-default
5589add('load', '9', {
5590    "name": "graphics-svg-default",
5591    "test": function(Y) {
5592    var DOCUMENT = Y.config.doc,
5593        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5594		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5595        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5596
5597    return svg && (useSVG || !canvas);
5598},
5599    "trigger": "graphics"
5600});
5601// graphics-vml
5602add('load', '10', {
5603    "name": "graphics-vml",
5604    "test": function(Y) {
5605    var DOCUMENT = Y.config.doc,
5606		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5607    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5608},
5609    "trigger": "graphics"
5610});
5611// graphics-vml-default
5612add('load', '11', {
5613    "name": "graphics-vml-default",
5614    "test": function(Y) {
5615    var DOCUMENT = Y.config.doc,
5616		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5617    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5618},
5619    "trigger": "graphics"
5620});
5621// history-hash-ie
5622add('load', '12', {
5623    "name": "history-hash-ie",
5624    "test": function (Y) {
5625    var docMode = Y.config.doc && Y.config.doc.documentMode;
5626
5627    return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5628            !docMode || docMode < 8);
5629},
5630    "trigger": "history-hash"
5631});
5632// io-nodejs
5633add('load', '13', {
5634    "name": "io-nodejs",
5635    "trigger": "io-base",
5636    "ua": "nodejs"
5637});
5638// json-parse-shim
5639add('load', '14', {
5640    "name": "json-parse-shim",
5641    "test": function (Y) {
5642    var _JSON = Y.config.global.JSON,
5643        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5644        nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5645
5646    function workingNative( k, v ) {
5647        return k === "ok" ? true : v;
5648    }
5649
5650    // Double check basic functionality.  This is mainly to catch early broken
5651    // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5652    if ( nativeSupport ) {
5653        try {
5654            nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5655        }
5656        catch ( e ) {
5657            nativeSupport = false;
5658        }
5659    }
5660
5661    return !nativeSupport;
5662},
5663    "trigger": "json-parse"
5664});
5665// json-stringify-shim
5666add('load', '15', {
5667    "name": "json-stringify-shim",
5668    "test": function (Y) {
5669    var _JSON = Y.config.global.JSON,
5670        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5671        nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5672
5673    // Double check basic native functionality.  This is primarily to catch broken
5674    // early JSON API implementations in Firefox 3.1 beta1 and beta2.
5675    if ( nativeSupport ) {
5676        try {
5677            nativeSupport = ( '0' === Native.stringify(0) );
5678        } catch ( e ) {
5679            nativeSupport = false;
5680        }
5681    }
5682
5683
5684    return !nativeSupport;
5685},
5686    "trigger": "json-stringify"
5687});
5688// scrollview-base-ie
5689add('load', '16', {
5690    "name": "scrollview-base-ie",
5691    "trigger": "scrollview-base",
5692    "ua": "ie"
5693});
5694// selector-css2
5695add('load', '17', {
5696    "name": "selector-css2",
5697    "test": function (Y) {
5698    var DOCUMENT = Y.config.doc,
5699        ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5700
5701    return ret;
5702},
5703    "trigger": "selector"
5704});
5705// transition-timer
5706add('load', '18', {
5707    "name": "transition-timer",
5708    "test": function (Y) {
5709    var DOCUMENT = Y.config.doc,
5710        node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5711        ret = true;
5712
5713    if (node && node.style) {
5714        ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5715    }
5716
5717    return ret;
5718},
5719    "trigger": "transition"
5720});
5721// widget-base-ie
5722add('load', '19', {
5723    "name": "widget-base-ie",
5724    "trigger": "widget-base",
5725    "ua": "ie"
5726});
5727// yql-jsonp
5728add('load', '20', {
5729    "name": "yql-jsonp",
5730    "test": function (Y) {
5731    /* Only load the JSONP module when not in nodejs or winjs
5732    TODO Make the winjs module a CORS module
5733    */
5734    return (!Y.UA.nodejs && !Y.UA.winjs);
5735},
5736    "trigger": "yql"
5737});
5738// yql-nodejs
5739add('load', '21', {
5740    "name": "yql-nodejs",
5741    "trigger": "yql",
5742    "ua": "nodejs"
5743});
5744// yql-winjs
5745add('load', '22', {
5746    "name": "yql-winjs",
5747    "trigger": "yql",
5748    "ua": "winjs"
5749});
5750
5751}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5752YUI.add('intl-base', function (Y, NAME) {
5753
5754/**
5755 * The Intl utility provides a central location for managing sets of
5756 * localized resources (strings and formatting patterns).
5757 *
5758 * @class Intl
5759 * @uses EventTarget
5760 * @static
5761 */
5762
5763var SPLIT_REGEX = /[, ]/;
5764
5765Y.mix(Y.namespace('Intl'), {
5766
5767 /**
5768    * Returns the language among those available that
5769    * best matches the preferred language list, using the Lookup
5770    * algorithm of BCP 47.
5771    * If none of the available languages meets the user's preferences,
5772    * then "" is returned.
5773    * Extended language ranges are not supported.
5774    *
5775    * @method lookupBestLang
5776    * @param {String[] | String} preferredLanguages The list of preferred
5777    * languages in descending preference order, represented as BCP 47
5778    * language tags. A string array or a comma-separated list.
5779    * @param {String[]} availableLanguages The list of languages
5780    * that the application supports, represented as BCP 47 language
5781    * tags.
5782    *
5783    * @return {String} The available language that best matches the
5784    * preferred language list, or "".
5785    * @since 3.1.0
5786    */
5787    lookupBestLang: function(preferredLanguages, availableLanguages) {
5788
5789        var i, language, result, index;
5790
5791        // check whether the list of available languages contains language;
5792        // if so return it
5793        function scan(language) {
5794            var i;
5795            for (i = 0; i < availableLanguages.length; i += 1) {
5796                if (language.toLowerCase() ===
5797                            availableLanguages[i].toLowerCase()) {
5798                    return availableLanguages[i];
5799                }
5800            }
5801        }
5802
5803        if (Y.Lang.isString(preferredLanguages)) {
5804            preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5805        }
5806
5807        for (i = 0; i < preferredLanguages.length; i += 1) {
5808            language = preferredLanguages[i];
5809            if (!language || language === '*') {
5810                continue;
5811            }
5812            // check the fallback sequence for one language
5813            while (language.length > 0) {
5814                result = scan(language);
5815                if (result) {
5816                    return result;
5817                } else {
5818                    index = language.lastIndexOf('-');
5819                    if (index >= 0) {
5820                        language = language.substring(0, index);
5821                        // one-character subtags get cut along with the
5822                        // following subtag
5823                        if (index >= 2 && language.charAt(index - 2) === '-') {
5824                            language = language.substring(0, index - 2);
5825                        }
5826                    } else {
5827                        // nothing available for this language
5828                        break;
5829                    }
5830                }
5831            }
5832        }
5833
5834        return '';
5835    }
5836});
5837
5838
5839}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5840YUI.add('yui-log', function (Y, NAME) {
5841
5842/**
5843 * Provides console log capability and exposes a custom event for
5844 * console implementations. This module is a `core` YUI module,
5845 * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
5846 *
5847 * @module yui
5848 * @submodule yui-log
5849 */
5850
5851var INSTANCE = Y,
5852    LOGEVENT = 'yui:log',
5853    UNDEFINED = 'undefined',
5854    LEVELS = { debug: 1,
5855               info: 2,
5856               warn: 4,
5857               error: 8 };
5858
5859/**
5860 * If the 'debug' config is true, a 'yui:log' event will be
5861 * dispatched, which the Console widget and anything else
5862 * can consume.  If the 'useBrowserConsole' config is true, it will
5863 * write to the browser console if available.  YUI-specific log
5864 * messages will only be present in the -debug versions of the
5865 * JS files.  The build system is supposed to remove log statements
5866 * from the raw and minified versions of the files.
5867 *
5868 * @method log
5869 * @for YUI
5870 * @param  {String}  msg  The message to log.
5871 * @param  {String}  cat  The log category for the message.  Default
5872 *                        categories are "info", "warn", "error", "debug".
5873 *                        Custom categories can be used as well. (opt).
5874 * @param  {String}  src  The source of the the message (opt).
5875 * @param  {boolean} silent If true, the log event won't fire.
5876 * @return {YUI}      YUI instance.
5877 */
5878INSTANCE.log = function(msg, cat, src, silent) {
5879    var bail, excl, incl, m, f, minlevel,
5880        Y = INSTANCE,
5881        c = Y.config,
5882        publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
5883    // suppress log message if the config is off or the event stack
5884    // or the event call stack contains a consumer of the yui:log event
5885    if (c.debug) {
5886        // apply source filters
5887        src = src || "";
5888        if (typeof src !== "undefined") {
5889            excl = c.logExclude;
5890            incl = c.logInclude;
5891            if (incl && !(src in incl)) {
5892                bail = 1;
5893            } else if (incl && (src in incl)) {
5894                bail = !incl[src];
5895            } else if (excl && (src in excl)) {
5896                bail = excl[src];
5897            }
5898
5899            // Set a default category of info if the category was not defined.
5900            if ((typeof cat === 'undefined')) {
5901                cat = 'info';
5902            }
5903
5904            // Determine the current minlevel as defined in configuration
5905            Y.config.logLevel = Y.config.logLevel || 'debug';
5906            minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
5907
5908            if (cat in LEVELS && LEVELS[cat] < minlevel) {
5909                // Skip this message if the we don't meet the defined minlevel
5910                bail = 1;
5911            }
5912        }
5913        if (!bail) {
5914            if (c.useBrowserConsole) {
5915                m = (src) ? src + ': ' + msg : msg;
5916                if (Y.Lang.isFunction(c.logFn)) {
5917                    c.logFn.call(Y, msg, cat, src);
5918                } else if (typeof console !== UNDEFINED && console.log) {
5919                    f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
5920                    console[f](m);
5921                } else if (typeof opera !== UNDEFINED) {
5922                    opera.postError(m);
5923                }
5924            }
5925
5926            if (publisher && !silent) {
5927
5928                if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
5929                    publisher.publish(LOGEVENT, {
5930                        broadcast: 2
5931                    });
5932                }
5933
5934                publisher.fire(LOGEVENT, {
5935                    msg: msg,
5936                    cat: cat,
5937                    src: src
5938                });
5939            }
5940        }
5941    }
5942
5943    return Y;
5944};
5945
5946/**
5947 * Write a system message.  This message will be preserved in the
5948 * minified and raw versions of the YUI files, unlike log statements.
5949 * @method message
5950 * @for YUI
5951 * @param  {String}  msg  The message to log.
5952 * @param  {String}  cat  The log category for the message.  Default
5953 *                        categories are "info", "warn", "error", "debug".
5954 *                        Custom categories can be used as well. (opt).
5955 * @param  {String}  src  The source of the the message (opt).
5956 * @param  {boolean} silent If true, the log event won't fire.
5957 * @return {YUI}      YUI instance.
5958 */
5959INSTANCE.message = function() {
5960    return INSTANCE.log.apply(INSTANCE, arguments);
5961};
5962
5963
5964}, 'patched-v3.18.1', {"requires": ["yui-base"]});
5965YUI.add('yui-later', function (Y, NAME) {
5966
5967/**
5968 * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
5969 * <a href="../classes/YUI.html#method_later">
5969it's documentation is located under the YUI class</a>.
5970 *
5971 * @module yui
5972 * @submodule yui-later
5973 */
5974
5975var NO_ARGS = [];
5976
5977/**
5978 * Executes the supplied function in the context of the supplied
5979 * object 'when' milliseconds later.  Executes the function a
5980 * single time unless periodic is set to true.
5981 * @for YUI
5982 * @method later
5983 * @param when {Number} the number of milliseconds to wait until the fn
5984 * is executed.
5985 * @param o the context object.
5986 * @param fn {Function|String} the function to execute or the name of
5987 * the method in the 'o' object to execute.
5988 * @param data [Array] data that is provided to the function.  This
5989 * accepts either a single item or an array.  If an array is provided,
5990 * the function is executed with one parameter for each array item.
5991 * If you need to pass a single array parameter, it needs to be wrapped
5992 * in an array [myarray].
5993 *
5994 * Note: native methods in IE may not have the call and apply methods.
5995 * In this case, it will work, but you are limited to four arguments.
5996 *
5997 * @param periodic {boolean} if true, executes continuously at supplied
5998 * interval until canceled.
5999 * @return {object} a timer object. Call the cancel() method on this
6000 * object to stop the timer.
6001 */
6002Y.later = function(when, o, fn, data, periodic) {
6003    when = when || 0;
6004    data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
6005    o = o || Y.config.win || Y;
6006
6007    var cancelled = false,
6008        method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
6009        wrapper = function() {
6010            // IE 8- may execute a setInterval callback one last time
6011            // after clearInterval was called, so in order to preserve
6012            // the cancel() === no more runny-run, we have to jump through
6013            // an extra hoop.
6014            if (!cancelled) {
6015                if (!method.apply) {
6016                    method(data[0], data[1], data[2], data[3]);
6017                } else {
6018                    method.apply(o, data || NO_ARGS);
6019                }
6020            }
6021        },
6022        id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
6023
6024    return {
6025        id: id,
6026        interval: periodic,
6027        cancel: function() {
6028            cancelled = true;
6029            if (this.interval) {
6030                clearInterval(id);
6031            } else {
6032                clearTimeout(id);
6033            }
6034        }
6035    };
6036};
6037
6038Y.Lang.later = Y.later;
6039
6040
6041
6042}, 'patched-v3.18.1', {"requires": ["yui-base"]});
6043YUI.add('loader-base', function (Y, NAME) {
6044
6045/**
6046 * The YUI loader core
6047 * @module loader
6048 * @submodule loader-base
6049 */
6050
6051(function() {
6052    var VERSION = Y.version,
6053        BUILD = '/build/',
6054        ROOT = VERSION + '/',
6055        CDN_BASE = Y.Env.base,
6056        GALLERY_VERSION = 'gallery-2014.06.04-21-38',
6057        TNT = '2in3',
6058        TNT_VERSION = '4',
6059        YUI2_VERSION = '2.9.0',
6060        COMBO_BASE = CDN_BASE + 'combo?',
6061        META = {
6062            version: VERSION,
6063            root: ROOT,
6064            base: Y.Env.base,
6065            comboBase: COMBO_BASE,
6066            skin: {
6067                defaultSkin: 'sam',
6068                base: 'assets/skins/',
6069                path: 'skin.css',
6070                after: [
6071                    'cssreset',
6072                    'cssfonts',
6073                    'cssgrids',
6074                    'cssbase',
6075                    'cssreset-context',
6076                    'cssfonts-context'
6077                ]
6078            },
6079            groups: {},
6080            patterns: {}
6081        },
6082        groups = META.groups,
6083        yui2Update = function(tnt, yui2, config) {
6084            var root = TNT + '.' +
6085                    (tnt || TNT_VERSION) + '/' +
6086                    (yui2 || YUI2_VERSION) + BUILD,
6087                base = (config && config.base) ? config.base : CDN_BASE,
6088                combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6089
6090            groups.yui2.base = base + root;
6091            groups.yui2.root = root;
6092            groups.yui2.comboBase = combo;
6093        },
6094        galleryUpdate = function(tag, config) {
6095            var root = (tag || GALLERY_VERSION) + BUILD,
6096                base = (config && config.base) ? config.base : CDN_BASE,
6097                combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6098
6099            groups.gallery.base = base + root;
6100            groups.gallery.root = root;
6101            groups.gallery.comboBase = combo;
6102        };
6103
6104
6105    groups[VERSION] = {};
6106
6107    groups.gallery = {
6108        ext: false,
6109        combine: true,
6110        comboBase: COMBO_BASE,
6111        update: galleryUpdate,
6112        patterns: {
6113            'gallery-': {},
6114            'lang/gallery-': {},
6115            'gallerycss-': {
6116                type: 'css'
6117            }
6118        }
6119    };
6120
6121    groups.yui2 = {
6122        combine: true,
6123        ext: false,
6124        comboBase: COMBO_BASE,
6125        update: yui2Update,
6126        patterns: {
6127            'yui2-': {
6128                configFn: function(me) {
6129                    if (/-skin|reset|fonts|grids|base/.test(me.name)) {
6130                        me.type = 'css';
6131                        me.path = me.path.replace(/\.js/, '.css');
6132                        // this makes skins in builds earlier than
6133                        // 2.6.0 work as long as combine is false
6134                        me.path = me.path.replace(/\/yui2-skin/,
6135                                            '/assets/skins/sam/yui2-skin');
6136                    }
6137                }
6138            }
6139        }
6140    };
6141
6142    galleryUpdate();
6143    yui2Update();
6144
6145    if (YUI.Env[VERSION]) {
6146        Y.mix(META, YUI.Env[VERSION], false, [
6147            'modules',
6148            'groups',
6149            'skin'
6150        ], 0, true);
6151    }
6152
6153    YUI.Env[VERSION] = META;
6154}());
6155/*jslint forin: true, maxlen: 350 */
6156
6157/**
6158 * Loader dynamically loads script and css files.  It includes the dependency
6159 * information for the version of the library in use, and will automatically pull in
6160 * dependencies for the modules requested. It can also load the
6161 * files from the Yahoo! CDN, and it can utilize the combo service provided on
6162 * this network to reduce the number of http connections required to download
6163 * YUI files.
6164 *
6165 * @module loader
6166 * @main loader
6167 * @submodule loader-base
6168 */
6169
6170var NOT_FOUND = {},
6171    NO_REQUIREMENTS = [],
6172    MAX_URL_LENGTH = 1024,
6173    GLOBAL_ENV = YUI.Env,
6174    GLOBAL_LOADED = GLOBAL_ENV._loaded,
6175    CSS = 'css',
6176    JS = 'js',
6177    INTL = 'intl',
6178    DEFAULT_SKIN = 'sam',
6179    VERSION = Y.version,
6180    ROOT_LANG = '',
6181    YObject = Y.Object,
6182    oeach = YObject.each,
6183    yArray = Y.Array,
6184    _queue = GLOBAL_ENV._loaderQueue,
6185    META = GLOBAL_ENV[VERSION],
6186    SKIN_PREFIX = 'skin-',
6187    L = Y.Lang,
6188    ON_PAGE = GLOBAL_ENV.mods,
6189    modulekey,
6190    _path = function(dir, file, type, nomin) {
6191        var path = dir + '/' + file;
6192        if (!nomin) {
6193            path += '-min';
6194        }
6195        path += '.' + (type || CSS);
6196
6197        return path;
6198    };
6199
6200
6201    if (!YUI.Env._cssLoaded) {
6202        YUI.Env._cssLoaded = {};
6203    }
6204
6205
6206/**
6207 * The component metadata is stored in Y.Env.meta.
6208 * Part of the loader module.
6209 * @property meta
6210 * @for YUI
6211 */
6212Y.Env.meta = META;
6213
6214/**
6215 * Loader dynamically loads script and css files.  It includes the dependency
6216 * info for the version of the library in use, and will automatically pull in
6217 * dependencies for the modules requested. It can load the
6218 * files from the Yahoo! CDN, and it can utilize the combo service provided on
6219 * this network to reduce the number of http connections required to download
6220 * YUI files. You can also specify an external, custom combo service to host
6221 * your modules as well.
6222
6223        var Y = YUI();
6224        var loader = new Y.Loader({
6225            filter: 'debug',
6226            base: '../../',
6227            root: 'build/',
6228            combine: true,
6229            require: ['node', 'dd', 'console']
6230        });
6231        var out = loader.resolve(true);
6232
6233 * If the Loader needs to be patched before it is used for the first time, it
6234 * should be done through the `doBeforeLoader` hook. Simply make the patch
6235 * available via configuration before YUI is loaded:
6236
6237        YUI_config = YUI_config || {};
6238        YUI_config.doBeforeLoader = function (config) {
6239            var resolve = this.context.Loader.prototype.resolve;
6240            this.context.Loader.prototype.resolve = function () {
6241                // do something here
6242                return resolve.apply(this, arguments);
6243            };
6244        };
6245
6246 * @constructor
6247 * @class Loader
6248 * @param {Object} config an optional set of configuration options.
6249 * @param {String} config.base The base dir which to fetch this module from
6250 * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?`
6251 * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/`
6252 * @param {String|Object} config.filter A filter to apply to result urls. <a href="#property_filter">See filter property</a>
6253 * @param {Object} config.filters Per-component filter specification.  If specified for a given component, this overrides the filter config.
6254 * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies
6255 * @param {Boolean} [config.async=true] Fetch files in async
6256 * @param {Array} config.ignore: A list of modules that should never be dynamically loaded
6257 * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page
6258 * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes
6259 * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes
6260 * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes
6261 * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes.  If not set, there is no timeout
6262 * @param {Object} config.context Execution context for all callbacks
6263 * @param {Function} config.onSuccess Callback for the 'success' event
6264 * @param {Function} config.onFailure Callback for the 'failure' event
6265 * @param {Function} config.onTimeout Callback for the 'timeout' event
6266 * @param {Function} config.onProgress Callback executed each time a script or css file is loaded
6267 * @param {Object} config.modules A list of module definitions.  See <a href="#method_addModule">Loader.addModule</a> for the supported module metadata
6268 * @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`.
6269 * @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.
6270 * @param {String} config.yui2 When using the 2in3 project, you can select the version of YUI 2 to use.  V
6270alid 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.
6271 * @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.
6272 */
6273Y.Loader = function(o) {
6274
6275    var self = this;
6276
6277    //Catch no config passed.
6278    o = o || {};
6279
6280    modulekey = META.md5;
6281
6282    /**
6283     * Internal callback to handle multiple internal insert() calls
6284     * so that css is inserted prior to js
6285     * @property _internalCallback
6286     * @private
6287     */
6288    // self._internalCallback = null;
6289
6290    /**
6291     * Callback that will be executed when the loader is finished
6292     * with an insert
6293     * @method onSuccess
6294     * @type function
6295     */
6296    // self.onSuccess = null;
6297
6298    /**
6299     * Callback that will be executed if there is a failure
6300     * @method onFailure
6301     * @type function
6302     */
6303    // self.onFailure = null;
6304
6305    /**
6306     * Callback executed each time a script or css file is loaded
6307     * @method onProgress
6308     * @type function
6309     */
6310    // self.onProgress = null;
6311
6312    /**
6313     * Callback that will be executed if a timeout occurs
6314     * @method onTimeout
6315     * @type function
6316     */
6317    // self.onTimeout = null;
6318
6319    /**
6320     * The execution context for all callbacks
6321     * @property context
6322     * @default {YUI} the YUI instance
6323     */
6324    self.context = Y;
6325
6326    // Hook that allows the patching of loader
6327    if (o.doBeforeLoader) {
6328        o.doBeforeLoader.apply(self, arguments);
6329    }
6330
6331    /**
6332     * Data that is passed to all callbacks
6333     * @property data
6334     */
6335    // self.data = null;
6336
6337    /**
6338     * Node reference or id where new nodes should be inserted before
6339     * @property insertBefore
6340     * @type string|HTMLElement
6341     */
6342    // self.insertBefore = null;
6343
6344    /**
6345     * The charset attribute for inserted nodes
6346     * @property charset
6347     * @type string
6348     * @deprecated , use cssAttributes or jsAttributes.
6349     */
6350    // self.charset = null;
6351
6352    /**
6353     * An object literal containing attributes to add to link nodes
6354     * @property cssAttributes
6355     * @type object
6356     */
6357    // self.cssAttributes = null;
6358
6359    /**
6360     * An object literal containing attributes to add to script nodes
6361     * @property jsAttributes
6362     * @type object
6363     */
6364    // self.jsAttributes = null;
6365
6366    /**
6367     * The base directory.
6368     * @property base
6369     * @type string
6370     * @default http://yui.yahooapis.com/[YUI VERSION]/build/
6371     */
6372    self.base = Y.Env.meta.base + Y.Env.meta.root;
6373
6374    /**
6375     * Base path for the combo service
6376     * @property comboBase
6377     * @type string
6378     * @default http://yui.yahooapis.com/combo?
6379     */
6380    self.comboBase = Y.Env.meta.comboBase;
6381
6382    /*
6383     * Base path for language packs.
6384     */
6385    // self.langBase = Y.Env.meta.langBase;
6386    // self.lang = "";
6387
6388    /**
6389     * If configured, the loader will attempt to use the combo
6390     * service for YUI resources and configured external resources.
6391     * @property combine
6392     * @type boolean
6393     * @default true if a base dir isn't in the config
6394     */
6395    self.combine = o.base &&
6396        (o.base.indexOf(self.comboBase.substr(0, 20)) > -1);
6397
6398    /**
6399    * The default seperator to use between files in a combo URL
6400    * @property comboSep
6401    * @type {String}
6402    * @default Ampersand
6403    */
6404    self.comboSep = '&';
6405    /**
6406     * Max url length for combo urls.  The default is 1024. This is the URL
6407     * limit for the Yahoo! hosted combo servers.  If consuming
6408     * a different combo service that has a different URL limit
6409     * it is possible to override this default by supplying
6410     * the maxURLLength config option.  The config option will
6411     * only take effect if lower than the default.
6412     *
6413     * @property maxURLLength
6414     * @type int
6415     */
6416    self.maxURLLength = MAX_URL_LENGTH;
6417
6418    /**
6419     * Ignore modules registered on the YUI global
6420     * @property ignoreRegistered
6421     * @default false
6422     */
6423    self.ignoreRegistered = o.ignoreRegistered;
6424
6425    /**
6426     * Root path to prepend to module path for the combo
6427     * service
6428     * @property root
6429     * @type string
6430     * @default [YUI VERSION]/build/
6431     */
6432    self.root = Y.Env.meta.root;
6433
6434    /**
6435     * Timeout value in milliseconds.  If set, self value will be used by
6436     * the get utility.  the timeout event will fire if
6437     * a timeout occurs.
6438     * @property timeout
6439     * @type int
6440     */
6441    self.timeout = 0;
6442
6443    /**
6444     * A list of modules that should not be loaded, even if
6445     * they turn up in the dependency tree
6446     * @property ignore
6447     * @type string[]
6448     */
6449    // self.ignore = null;
6450
6451    /**
6452     * A list of modules that should always be loaded, even
6453     * if they have already been inserted into the page.
6454     * @property force
6455     * @type string[]
6456     */
6457    // self.force = null;
6458
6459    self.forceMap = {};
6460
6461    /**
6462     * Should we allow rollups
6463     * @property allowRollup
6464     * @type boolean
6465     * @default false
6466     */
6467    self.allowRollup = false;
6468
6469    /**
6470     * A filter to apply to result urls.  This filter will modify the default
6471     * path for all modules.  The default path for the YUI library is the
6472     * minified version of the files (e.g., event-min.js).  The filter property
6473     * can be a predefined filter or a custom filter.  The valid predefined
6474     * filters are:
6475     * <dl>
6476     *  <dt>DEBUG</dt>
6477     *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
6478     *      This option will automatically include the Logger widget</dd>
6479     *  <dt>RAW</dt>
6480     *  <dd>Selects the non-minified version of the library (e.g., event.js).
6481     *  </dd>
6482     * </dl>
6483     * You can also define a custom filter, which must be an object literal
6484     * containing a search expression and a replace string:
6485     *
6486     *      myFilter: {
6487     *          'searchExp': "-min\\.js",
6488     *          'replaceStr': "-debug.js"
6489     *      }
6490     *
6491     * @property filter
6492     * @type string| {searchExp: string, replaceStr: string}
6493     */
6494    // self.filter = null;
6495
6496    /**
6497     * per-component filter specification.  If specified for a given
6498     * component, this overrides the filter config.
6499     * @property filters
6500     * @type object
6501     */
6502    self.filters = {};
6503
6504    /**
6505     * The list of requested modules
6506     * @property required
6507     * @type {string: boolean}
6508     */
6509    self.required = {};
6510
6511    /**
6512     * If a module name is predefined when requested, it is checked againsts
6513     * the patterns provided in this property.  If there is a match, the
6514     * module is added with the default configuration.
6515     *
6516     * At the moment only supporting module prefixes, but anticipate
6517     * supporting at least regular expressions.
6518     * @property patterns
6519     * @type Object
6520     */
6521    // self.patterns = Y.merge(Y.Env.meta.patterns);
6522    self.patterns = {};
6523
6524    /**
6525     * Internal loader instance metadata. Use accessor `getModuleInfo()` instead.
6526     */
6527    self.moduleInfo = {};
6528
6529    self.groups = Y.merge(Y.Env.meta.groups);
6530
6531    /**
6532     * Provides the information used to skin the skinnable components.
6533     * The following skin definition would result in 'skin1' and 'skin2'
6534     * being loaded for calendar (if calendar was requested), and
6535     * 'sam' for all other skinnable components:
6536     *
6537     *      skin: {
6538     *          // The default skin, which is automatically applied if not
6539     *          // overriden by a component-specific skin definition.
6540     *          // Change this in to apply a different skin globally
6541     *          defaultSkin: 'sam',
6542     *
6543     *          // This is combined with the loader base property to get
6544     *          // the default root directory for a skin. ex:
6545     *          // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
6546     *          base: 'assets/skins/',
6547     *
6548     *          // Any component-specific overrides can be specified here,
6549     *          // making it possible to load different skins for different
6550     *          // components.  It is possible to load more than one skin
6551     *          // for a given component as well.
6552     *          overrides: {
6553     *              calendar: ['skin1', 'skin2']
6554     *          }
6555     *      }
6556     * @property skin
6557     * @type {Object}
6558     */
6559    self.skin = Y.merge(Y.Env.meta.skin);
6560
6561    /*
6562     * Map of conditional modules
6563     * @since 3.2.0
6564     */
6565    self.conditions = {};
6566
6567    // map of modules with a hash of modules that meet the requirement
6568    // self.provides = {};
6569
6570    self.config = o;
6571    self._internal = true;
6572
6573    self._populateConditionsCache();
6574
6575    /**
6576     * Set when beginning to compute the dependency tree.
6577     * Composed of what YUI reports to be loaded combined
6578     * with what has been loaded by any instance on the page
6579     * with the version number specified in the metadata.
6580     * @property loaded
6581     * @type {string: boolean}
6582     */
6583    self.loaded = GLOBAL_LOADED[VERSION];
6584
6585
6586    /**
6587    * Should Loader fetch scripts in `async`, defaults to `true`
6588    * @property async
6589    */
6590
6591    self.async = true;
6592
6593    self._inspectPage();
6594
6595    self._internal = false;
6596
6597    self._config(o);
6598
6599    self.forceMap = (self.force) ? Y.Array.hash(self.force) : {};
6600
6601    self.testresults = null;
6602
6603    if (Y.config.tests) {
6604        self.testresults = Y.config.tests;
6605    }
6606
6607    /**
6608     * List of rollup files found in the library metadata
6609     * @property rollups
6610     */
6611    // self.rollups = null;
6612
6613    /**
6614     * Whether or not to load optional dependencies for
6615     * the requested modules
6616     * @property loadOptional
6617     * @type boolean
6618     * @default false
6619     */
6620    // self.loadOptional = false;
6621
6622    /**
6623     * All of the derived dependencies in sorted order, which
6624     * will be populated when either calculate() or insert()
6625     * is called
6626     * @property sorted
6627     * @type string[]
6628     */
6629    self.sorted = [];
6630
6631    /*
6632     * A list of modules to attach to the YUI instance when complete.
6633     * If not supplied, the sorted list of dependencies are applied.
6634     * @property attaching
6635     */
6636    // self.attaching = null;
6637
6638    /**
6639     * Flag to indicate the dependency tree needs to be recomputed
6640     * if insert is called again.
6641     * @property dirty
6642     * @type boolean
6643     * @default true
6644     */
6645    self.dirty = true;
6646
6647    /**
6648     * List of modules inserted by the utility
6649     * @property inserted
6650     * @type {string: boolean}
6651     */
6652    self.inserted = {};
6653
6654    /**
6655     * List of skipped modules during insert() because the module
6656     * was not defined
6657     * @property skipped
6658     */
6659    self.skipped = {};
6660
6661    // Y.on('yui:load', self.loadNext, self);
6662
6663    self.tested = {};
6664
6665    /*
6666     * Cached sorted calculate results
6667     * @property results
6668     * @since 3.2.0
6669     */
6670    //self.results = {};
6671
6672    if (self.ignoreRegistered) {
6673        //Clear inpage already processed modules.
6674        self._resetModules();
6675    }
6676
6677};
6678
6679Y.Loader.prototype = {
6680    /**
6681    * Gets the module info from the local moduleInfo hash, or from the
6682    * default metadata and populate the local moduleInfo hash.
6683    * @method getModuleInfo
6684    * @param {string} name of the module
6685    * @public
6686    */
6687    getModuleInfo: function(name) {
6688
6689        var m = this.moduleInfo[name],
6690            rawMetaModules, globalRenderedMods, internal, v;
6691
6692        if (m) {
6693            return m;
6694        }
6695
6696        rawMetaModules = META.modules;
6697        globalRenderedMods = GLOBAL_ENV._renderedMods;
6698        internal = this._internal;
6699
6700        /*
6701        The logic here is:
6702
6703        - if the `moduleInfo[name]` is avilable,
6704          then short circuit
6705        - otherwise, if the module is in the globalCache (cross Y instance),
6706          then port it from the global registry into `moduleInfo[name]`
6707        - otherwise, if the module has raw metadata (from meta modules)
6708          then add it to the global registry and to `moduleInfo[name]`
6709
6710        */
6711        if (globalRenderedMods && globalRenderedMods.hasOwnProperty(name) && !this.ignoreRegistered) {
6712            this.moduleInfo[name] = Y.merge(globalRenderedMods[name]);
6713        } else {
6714            if (rawMetaModules.hasOwnProperty(name)) {
6715                this._internal = true; // making sure that modules from raw data are marked as internal
6716                v = this.addModule(rawMetaModules[name], name);
6717                // Inspect the page for the CSS module and mark it as loaded.
6718                if (v && v.type === CSS) {
6719                    if (this.isCSSLoaded(v.name, true)) {
6720                        this.loaded[v.name] = true;
6721                    }
6722                }
6723                this._internal = internal;
6724            }
6725        }
6726        return this.moduleInfo[name];
6727    },
6728    /**
6729    * Expand the names that are aliases to other modules.
6730    * @method _expandAliases
6731    * @param {string[]} list a module name or a list of names to be expanded
6732    * @private
6733    * @return {array}
6734    */
6735    _expandAliases: function(list) {
6736        var expanded = [],
6737            aliases = YUI.Env.aliases,
6738            i, name;
6739        list = Y.Array(list);
6740        for (i = 0; i < list.length; i += 1) {
6741            name = list[i];
6742            expanded.push.apply(expanded, aliases[name] ? aliases[name] : [name]);
6743        }
6744        return expanded;
6745    },
6746    /**
6747    * Populate the conditions cache from raw modules, this is necessary
6748    * because no other module will require a conditional module, instead
6749    * the condition has to be executed and then the module is analyzed
6750    * to be included in the final requirement list. Without this cache
6751    * conditional modules will be simply ignored.
6752    * @method _populateConditionsCache
6753    * @private
6754    */
6755    _populateConditionsCache: function() {
6756        var rawMetaModules = META.modules,
6757            cache = GLOBAL_ENV._conditions,
6758            i, j, t, trigger;
6759
6760        // if we have conditions in cache and cache is enabled
6761        // we should port them to this loader instance
6762        if (cache && !this.ignoreRegistered) {
6763            for (i in cache) {
6764                if (cache.hasOwnProperty(i)) {
6765                    this.conditions[i] = Y.merge(cache[i]);
6766                }
6767            }
6768        } else {
6769            for (i in rawMetaModules) {
6770                if (rawMetaModules.hasOwnProperty(i) && rawMetaModules[i].condition) {
6771                    t = this._expandAliases(rawMetaModules[i].condition.trigger);
6772                    for (j = 0; j < t.length; j += 1) {
6773                        trigger = t[j];
6774                        this.conditions[trigger] = this.conditions[trigger] || {};
6775                        this.conditions[trigger][rawMetaModules[i].name || i] = rawMetaModules[i].condition;
6776                    }
6777                }
6778            }
6779            GLOBAL_ENV._conditions = this.conditions;
6780        }
6781    },
6782    /**
6783    * Reset modules in the module cache to a pre-processed state so additional
6784    * computations with a different skin or language will work as expected.
6785    * @method _resetModules
6786    * @private
6787    */
6788    _resetModules: function() {
6789        var self = this, i, o,
6790            mod, name, details;
6791        for (i in self.moduleInfo) {
6792            if (self.moduleInfo.hasOwnProperty(i) && self.moduleInfo[i]) {
6793                mod = self.moduleInfo[i];
6794                name = mod.name;
6795                details  = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null);
6796
6797                if (details) {
6798                    self.moduleInfo[name]._reset = true;
6799                    self.moduleInfo[name].requires = details.requires || [];
6800                    self.moduleInfo[name].optional = details.optional || [];
6801                    self.moduleInfo[name].supersedes = details.supercedes || [];
6802                }
6803
6804                if (mod.defaults) {
6805                    for (o in mod.defaults) {
6806                        if (mod.defaults.hasOwnProperty(o)) {
6807                            if (mod[o]) {
6808                                mod[o] = mod.defaults[o];
6809                            }
6810                        }
6811                    }
6812                }
6813                mod.langCache = undefined;
6814                mod.skinCache = undefined;
6815                if (mod.skinnable) {
6816                    self._addSkin(self.skin.defaultSkin, mod.name);
6817                }
6818            }
6819        }
6820    },
6821    /**
6822    Regex that matches a CSS URL. Used to guess the file type when it's not
6823    specified.
6824
6825    @property REGEX_CSS
6826    @type RegExp
6827    @final
6828    @protected
6829    @since 3.5.0
6830    **/
6831    REGEX_CSS: /\.css(?:[?;].*)?$/i,
6832
6833    /**
6834    * Default filters for raw and debug
6835    * @property FILTER_DEFS
6836    * @type Object
6837    * @final
6838    * @protected
6839    */
6840    FILTER_DEFS: {
6841        RAW: {
6842            'searchExp': '-min\\.js',
6843            'replaceStr': '.js'
6844        },
6845        DEBUG: {
6846            'searchExp': '-min\\.js',
6847            'replaceStr': '-debug.js'
6848        },
6849        COVERAGE: {
6850            'searchExp': '-min\\.js',
6851            'replaceStr': '-coverage.js'
6852        }
6853    },
6854    /*
6855    * Check the pages meta-data and cache the result.
6856    * @method _inspectPage
6857    * @private
6858    */
6859    _inspectPage: function() {
6860        var self = this, v, m, req, mr, i;
6861
6862        for (i in ON_PAGE) {
6863            if (ON_PAGE.hasOwnProperty(i)) {
6864                v = ON_PAGE[i];
6865                if (v.details) {
6866                    m = self.getModuleInfo(v.name);
6867                    req = v.details.requires;
6868                    mr = m && m.requires;
6869
6870                   if (m) {
6871                       if (!m._inspected && req && mr.length !== req.length) {
6872                           // console.log('deleting ' + m.name);
6873                           delete m.expanded;
6874                       }
6875                   } else {
6876                       m = self.addModule(v.details, i);
6877                   }
6878                   m._inspected = true;
6879               }
6880            }
6881        }
6882    },
6883    /*
6884    * returns true if b is not loaded, and is required directly or by means of modules it supersedes.
6885    * @private
6886    * @method _requires
6887    * @param {String} mod1 The first module to compare
6888    * @param {String} mod2 The second module to compare
6889    */
6890   _requires: function(mod1, mod2) {
6891
6892        var i, rm, after_map, s,
6893            m = this.getModuleInfo(mod1),
6894            other = this.getModuleInfo(mod2);
6895
6896        if (!m || !other) {
6897            return false;
6898        }
6899
6900        rm = m.expanded_map;
6901        after_map = m.after_map;
6902
6903        // check if this module should be sorted after the other
6904        // do this first to short circut circular deps
6905        if (after_map && (mod2 in after_map)) {
6906            return true;
6907        }
6908
6909        after_map = other.after_map;
6910
6911        // and vis-versa
6912        if (after_map && (mod1 in after_map)) {
6913            return false;
6914        }
6915
6916        // check if this module requires one the other supersedes
6917        s = other.supersedes;
6918        if (s) {
6919            for (i = 0; i < s.length; i++) {
6920                if (this._requires(mod1, s[i])) {
6921                    return true;
6922                }
6923            }
6924        }
6925
6926        s = m.supersedes;
6927        if (s) {
6928            for (i = 0; i < s.length; i++) {
6929                if (this._requires(mod2, s[i])) {
6930                    return false;
6931                }
6932            }
6933        }
6934
6935        // check if this module requires the other directly
6936        // if (r && yArray.indexOf(r, mod2) > -1) {
6937        if (rm && (mod2 in rm)) {
6938            return true;
6939        }
6940
6941        // external css files should be sorted below yui css
6942        if (m.ext && m.type === CSS && !other.ext && other.type === CSS) {
6943            return true;
6944        }
6945
6946        return false;
6947    },
6948    /**
6949    * Apply a new config to the Loader instance
6950    * @method _config
6951    * @private
6952    * @param {Object} o The new configuration
6953    */
6954    _config: function(o) {
6955        var i, j, val, a, f, group, groupName, self = this,
6956            mods = [], mod, modInfo;
6957        // apply config values
6958        if (o) {
6959            for (i in o) {
6960                if (o.hasOwnProperty(i)) {
6961                    val = o[i];
6962                    //TODO This should be a case
6963                    if (i === 'require') {
6964                        self.require(val);
6965                    } else if (i === 'skin') {
6966                        //If the config.skin is a string, format to the expected object
6967                        if (typeof val === 'string') {
6968                            self.skin.defaultSkin = o.skin;
6969                            val = {
6970                                defaultSkin: val
6971                            };
6972                        }
6973
6974                        Y.mix(self.skin, val, true);
6975                    } else if (i === 'groups') {
6976                        for (j in val) {
6977                            if (val.hasOwnProperty(j)) {
6978                                groupName = j;
6979                                group = val[j];
6980                                self.addGroup(group, groupName);
6981                                if (group.aliases) {
6982                                    for (a in group.aliases) {
6983                                        if (group.aliases.hasOwnProperty(a)) {
6984                                            self.addAlias(group.aliases[a], a);
6985                                        }
6986                                    }
6987                                }
6988                            }
6989                        }
6990
6991                    } else if (i === 'modules') {
6992                        // add a hash of module definitions
6993                        for (j in val) {
6994                            if (val.hasOwnProperty(j)) {
6995                                self.addModule(val[j], j);
6996                            }
6997                        }
6998                    } else if (i === 'aliases') {
6999                        for (j in val) {
7000                            if (val.hasOwnProperty(j)) {
7001                                self.addAlias(val[j], j);
7002                            }
7003                        }
7004                    } else if (i === 'gallery') {
7005                        if (this.groups.gallery.update) {
7006                            this.groups.gallery.update(val, o);
7007                        }
7008                    } else if (i === 'yui2' || i === '2in3') {
7009                        if (this.groups.yui2.update) {
7010                            this.groups.yui2.update(o['2in3'], o.yui2, o);
7011                        }
7012                    } else {
7013                        self[i] = val;
7014                    }
7015                }
7016            }
7017        }
7018
7019        // fix filter
7020        f = self.filter;
7021
7022        if (L.isString(f)) {
7023            f = f.toUpperCase();
7024            self.filterName = f;
7025            self.filter = self.FILTER_DEFS[f];
7026            if (f === 'DEBUG') {
7027                self.require('yui-log', 'dump');
7028            }
7029        }
7030
7031        if (self.filterName && self.coverage) {
7032            if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) {
7033                for (i = 0; i < self.coverage.length; i++) {
7034                    mod = self.coverage[i];
7035                    modInfo = self.getModuleInfo(mod);
7036                    if (modInfo && modInfo.use) {
7037                        mods = mods.concat(modInfo.use);
7038                    } else {
7039                        mods.push(mod);
7040                    }
7041                }
7042                self.filters = self.filters || {};
7043                Y.Array.each(mods, function(mod) {
7044                    self.filters[mod] = self.FILTER_DEFS.COVERAGE;
7045                });
7046                self.filterName = 'RAW';
7047                self.filter = self.FILTER_DEFS[self.filterName];
7048            }
7049        }
7050
7051    },
7052
7053    /**
7054     * Returns the skin module name for the specified skin name.  If a
7055     * module name is supplied, the returned skin module name is
7056     * specific to the module passed in.
7057     * @method formatSkin
7058     * @param {string} skin the name of the skin.
7059     * @param {string} mod optional: the name of a module to skin.
7060     * @return {string} the full skin module name.
7061     */
7062    formatSkin: function(skin, mod) {
7063        var s = SKIN_PREFIX + skin;
7064        if (mod) {
7065            s = s + '-' + mod;
7066        }
7067
7068        return s;
7069    },
7070
7071    /**
7072     * Adds the skin def to the module info
7073     * @method _addSkin
7074     * @param {string} skin the name of the skin.
7075     * @param {string} mod the name of the module.
7076     * @param {string} parent parent module if this is a skin of a
7077     * submodule or plugin.
7078     * @return {string} the module name for the skin.
7079     * @private
7080     */
7081    _addSkin: function(skin, mod, parent) {
7082        var pkg, name, nmod,
7083            sinf = this.skin,
7084            mdef = mod && this.getModuleInfo(mod),
7085            ext = mdef && mdef.ext;
7086
7087        // Add a module definition for the module-specific skin css
7088        if (mod) {
7089            name = this.formatSkin(skin, mod);
7090            if (!this.getModuleInfo(name)) {
7091                pkg = mdef.pkg || mod;
7092                nmod = {
7093                    skin: true,
7094                    name: name,
7095                    group: mdef.group,
7096                    type: 'css',
7097                    after: sinf.after,
7098                    path: (parent || pkg) + '/' + sinf.base + skin +
7099                          '/' + mod + '.css',
7100                    ext: ext
7101                };
7102                if (mdef.base) {
7103                    nmod.base = mdef.base;
7104                }
7105                if (mdef.configFn) {
7106                    nmod.configFn = mdef.configFn;
7107                }
7108                this.addModule(nmod, name);
7109
7110            }
7111        }
7112
7113        return name;
7114    },
7115    /**
7116    * Adds an alias module to the system
7117    * @method addAlias
7118    * @param {Array} use An array of modules that makes up this alias
7119    * @param {String} name The name of the alias
7120    * @example
7121    *       var loader = new Y.Loader({});
7122    *       loader.addAlias([ 'node', 'yql' ], 'davglass');
7123    *       loader.require(['davglass']);
7124    *       var out = loader.resolve(true);
7125    *
7126    *       //out.js will contain Node and YQL modules
7127    */
7128    addAlias: function(use, name) {
7129        YUI.Env.aliases[name] = use;
7130        this.addModule({
7131            name: name,
7132            use: use
7133        });
7134    },
7135    /**
7136     * Add a new module group
7137     * @method addGroup
7138     * @param {Object} config An object containing the group configuration data
7139     * @param {String} config.name required, the group name
7140     * @param {String} config.base The base directory for this module group
7141     * @param {String} config.root The root path to add to each combo resource path
7142     * @param {Boolean} config.combine Should the request be combined
7143     * @param {String} config.comboBase Combo service base path
7144     * @param {Object} config.modules The group of modules
7145     * @param {String} name the group name.
7146     * @example
7147     *      var loader = new Y.Loader({});
7148     *      loader.addGroup({
7149     *          name: 'davglass',
7150     *          combine: true,
7151     *          comboBase: '/combo?',
7152     *          root: '',
7153     *          modules: {
7154     *              //Module List here
7155     *          }
7156     *      }, 'davglass');
7157     */
7158    addGroup: function(o, name) {
7159        var mods = o.modules,
7160            self = this,
7161            defaultBase = o.defaultBase || Y.config.defaultBase,
7162            i, v;
7163
7164        name = name || o.name;
7165        o.name = name;
7166        self.groups[name] = o;
7167
7168        if (!o.base && defaultBase && o.root) {
7169            o.base = defaultBase + o.root;
7170        }
7171
7172        if (o.patterns) {
7173            for (i in o.patterns) {
7174                if (o.patterns.hasOwnProperty(i)) {
7175                    o.patterns[i].group = name;
7176                    self.patterns[i] = o.patterns[i];
7177                }
7178            }
7179        }
7180
7181        if (mods) {
7182            for (i in mods) {
7183                if (mods.hasOwnProperty(i)) {
7184                    v = mods[i];
7185                    if (typeof v === 'string') {
7186                        v = { name: i, fullpath: v };
7187                    }
7188                    v.group = name;
7189                    self.addModule(v, i);
7190                }
7191            }
7192        }
7193    },
7194
7195    /**
7196     * Add a new module to the component metadata.
7197     * @method addModule
7198     * @param {Object}
7198 config An object containing the module data.
7199     * @param {String} config.name Required, the component name
7200     * @param {String} config.type Required, the component type (js or css)
7201     * @param {String} config.path Required, the path to the script from `base`
7202     * @param {Array} config.requires Array of modules required by this component
7203     * @param {Array} [config.optional] Array of optional modules for this component
7204     * @param {Array} [config.supersedes] Array of the modules this component replaces
7205     * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one
7206     * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array
7207     * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup
7208     * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path`
7209     * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in
7210     * @param {Object} [config.submodules] Hash of submodules
7211     * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration.
7212     * @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"]`
7213     * @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:
7214     * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load
7215     * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded.
7216     * @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"`.
7217     * @param {String} [config.condition.when] Specifies the load order of the conditional module
7218     *  with regard to the position of the trigger module.
7219     *  This should be one of three values: `before`, `after`, or `instead`.  The default is `after`.
7220     * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()`
7221     * @param {Function} [config.configFn] A function to exectute when configuring this module
7222     * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config.
7223     * @param {String[]} [config.optionalRequires] List of dependencies that
7224        may optionally be loaded by this loader. This is targeted mostly at
7225        polyfills, since they should not be in the list of requires because
7226        polyfills are assumed to be available in the global scope.
7227     * @param {Function} [config.test] Test to be called when this module is
7228        added as an optional dependency of another module. If the test function
7229        returns `false`, the module will be ignored and will not be attached to
7230        this YUI instance.
7231     * @param {String} [name] The module name, required if not in the module data.
7232     * @return {Object} the module definition or null if the object passed in did not provide all required attributes.
7233     */
7234    addModule: function(o, name) {
7235        name = name || o.name;
7236
7237        if (typeof o === 'string') {
7238            o = { name: name, fullpath: o };
7239        }
7240
7241
7242        var subs, i, l, t, sup, s, smod, plugins, plug,
7243            j, langs, packName, supName, flatSup, flatLang, lang, ret,
7244            overrides, skinname, when, g, p,
7245            modInfo = this.moduleInfo[name],
7246            conditions = this.conditions, trigger;
7247
7248        //Only merge this data if the temp flag is set
7249        //from an earlier pass from a pattern or else
7250        //an override module (YUI_config) can not be used to
7251        //replace a default module.
7252        if (modInfo && modInfo.temp) {
7253            //This catches temp modules loaded via a pattern
7254            // The module will be added twice, once from the pattern and
7255            // Once from the actual add call, this ensures that properties
7256            // that were added to the module the first time around (group: gallery)
7257            // are also added the second time around too.
7258            o = Y.merge(modInfo, o);
7259        }
7260
7261        o.name = name;
7262
7263        if (!o || !o.name) {
7264            return null;
7265        }
7266
7267        if (!o.type) {
7268            //Always assume it's javascript unless the CSS pattern is matched.
7269            o.type = JS;
7270            p = o.path || o.fullpath;
7271            if (p && this.REGEX_CSS.test(p)) {
7272                o.type = CSS;
7273            }
7274        }
7275
7276        if (!o.path && !o.fullpath) {
7277            o.path = _path(name, name, o.type);
7278        }
7279        o.supersedes = o.supersedes || o.use;
7280
7281        o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true;
7282
7283        // Handle submodule logic
7284        subs = o.submodules;
7285
7286        this.moduleInfo[name] = o;
7287
7288        o.requires = o.requires || [];
7289
7290        /*
7291        Only allowing the cascade of requires information, since
7292        optional and supersedes are far more fine grained than
7293        a blanket requires is.
7294        */
7295        if (this.requires) {
7296            for (i = 0; i < this.requires.length; i++) {
7297                o.requires.push(this.requires[i]);
7298            }
7299        }
7300        if (o.group && this.groups && this.groups[o.group]) {
7301            g = this.groups[o.group];
7302            if (g.requires) {
7303                for (i = 0; i < g.requires.length; i++) {
7304                    o.requires.push(g.requires[i]);
7305                }
7306            }
7307        }
7308
7309
7310        if (!o.defaults) {
7311            o.defaults = {
7312                requires: o.requires ? [].concat(o.requires) : null,
7313                supersedes: o.supersedes ? [].concat(o.supersedes) : null,
7314                optional: o.optional ? [].concat(o.optional) : null
7315            };
7316        }
7317
7318        if (o.skinnable && o.ext && o.temp) {
7319            skinname = this._addSkin(this.skin.defaultSkin, name);
7320            o.requires.unshift(skinname);
7321        }
7322
7323        if (o.requires.length) {
7324            o.requires = this.filterRequires(o.requires) || [];
7325        }
7326
7327        if (!o.langPack && o.lang) {
7328            // Setup root package by default as a fallback
7329            // for languages that are not defined
7330            packName = this.getLangPackName(ROOT_LANG, name);
7331            smod = this.getModuleInfo(packName);
7332
7333            if (!smod) {
7334                this._addLangPack(null, o, packName);
7335            }
7336
7337            langs = yArray(o.lang);
7338
7339            for (j = 0; j < langs.length; j++) {
7340                lang = langs[j];
7341                packName = this.getLangPackName(lang, name);
7342                smod = this.getModuleInfo(packName);
7343                if (!smod) {
7344                    smod = this._addLangPack(lang, o, packName);
7345                }
7346            }
7347        }
7348
7349
7350        if (subs) {
7351            sup = o.supersedes || [];
7352            l = 0;
7353
7354            for (i in subs) {
7355                if (subs.hasOwnProperty(i)) {
7356                    s = subs[i];
7357
7358                    s.path = s.path || _path(name, i, o.type);
7359                    s.pkg = name;
7360                    s.group = o.group;
7361
7362                    if (s.supersedes) {
7363                        sup = sup.concat(s.supersedes);
7364                    }
7365
7366                    smod = this.addModule(s, i);
7367                    sup.push(i);
7368
7369                    if (smod.skinnable) {
7370                        o.skinnable = true;
7371                        overrides = this.skin.overrides;
7372                        if (overrides && overrides[i]) {
7373                            for (j = 0; j < overrides[i].length; j++) {
7374                                skinname = this._addSkin(overrides[i][j],
7375                                         i, name);
7376                                sup.push(skinname);
7377                            }
7378                        }
7379                        skinname = this._addSkin(this.skin.defaultSkin,
7380                                        i, name);
7381                        sup.push(skinname);
7382                    }
7383
7384                    // looks like we are expected to work out the metadata
7385                    // for the parent module language packs from what is
7386                    // specified in the child modules.
7387                    if (s.lang && s.lang.length) {
7388                        // Setup root package by default as a fallback
7389                        // for languages that are not defined
7390                        packName = this.getLangPackName(ROOT_LANG, name);
7391                        smod = this.getModuleInfo(packName);
7392
7393                        if (!smod) {
7394                            this._addLangPack(null, o, packName);
7395                        }
7396
7397                        langs = yArray(s.lang);
7398
7399                        for (j = 0; j < langs.length; j++) {
7400                            lang = langs[j];
7401                            packName = this.getLangPackName(lang, name);
7402                            supName = this.getLangPackName(lang, i);
7403                            smod = this.getModuleInfo(packName);
7404
7405                            if (!smod) {
7406                                smod = this._addLangPack(lang, o, packName);
7407                            }
7408
7409                            flatSup = flatSup || yArray.hash(smod.supersedes);
7410
7411                            if (!(supName in flatSup)) {
7412                                smod.supersedes.push(supName);
7413                            }
7414
7415                            o.lang = o.lang || [];
7416
7417                            flatLang = flatLang || yArray.hash(o.lang);
7418
7419                            if (!(lang in flatLang)) {
7420                                o.lang.push(lang);
7421                            }
7422
7423// Add rollup file, need to add to supersedes list too
7424
7425                            // default packages
7426                            packName = this.getLangPackName(ROOT_LANG, name);
7427                            supName = this.getLangPackName(ROOT_LANG, i);
7428
7429                            smod = this.getModuleInfo(packName);
7430
7431                            if (!smod) {
7432                                smod = this._addLangPack(lang, o, packName);
7433                            }
7434
7435                            if (!(supName in flatSup)) {
7436                                smod.supersedes.push(supName);
7437                            }
7438
7439// Add rollup file, need to add to supersedes list too
7440
7441                        }
7442                    }
7443
7444                    l++;
7445                }
7446            }
7447            //o.supersedes = YObject.keys(yArray.hash(sup));
7448            o.supersedes = yArray.dedupe(sup);
7449            if (this.allowRollup) {
7450                o.rollup = (l < 4) ? l : Math.min(l - 1, 4);
7451            }
7452        }
7453
7454        plugins = o.plugins;
7455        if (plugins) {
7456            for (i in plugins) {
7457                if (plugins.hasOwnProperty(i)) {
7458                    plug = plugins[i];
7459                    plug.pkg = name;
7460                    plug.path = plug.path || _path(name, i, o.type);
7461                    plug.requires = plug.requires || [];
7462                    plug.group = o.group;
7463                    this.addModule(plug, i);
7464                    if (o.skinnable) {
7465                        this._addSkin(this.skin.defaultSkin, i, name);
7466                    }
7467
7468                }
7469            }
7470        }
7471
7472        if (o.condition) {
7473            t = this._expandAliases(o.condition.trigger);
7474            for (i = 0; i < t.length; i++) {
7475                trigger = t[i];
7476                when = o.condition.when;
7477                conditions[trigger] = conditions[trigger] || {};
7478                conditions[trigger][name] = o.condition;
7479                // the 'when' attribute can be 'before', 'after', or 'instead'
7480                // the default is after.
7481                if (when && when !== 'after') {
7482                    if (when === 'instead') { // replace the trigger
7483                        o.supersedes = o.supersedes || [];
7484                        o.supersedes.push(trigger);
7485                    }
7486                    // before the trigger
7487                        // the trigger requires the conditional mod,
7488                        // so it should appear before the conditional
7489                        // mod if we do not intersede.
7490                } else { // after the trigger
7491                    o.after = o.after || [];
7492                    o.after.push(trigger);
7493                }
7494            }
7495        }
7496
7497        if (o.supersedes) {
7498            o.supersedes = this.filterRequires(o.supersedes);
7499        }
7500
7501        if (o.after) {
7502            o.after = this.filterRequires(o.after);
7503            o.after_map = yArray.hash(o.after);
7504        }
7505
7506        // this.dirty = true;
7507
7508        if (o.configFn) {
7509            ret = o.configFn(o);
7510            if (ret === false) {
7511                delete this.moduleInfo[name];
7512                delete GLOBAL_ENV._renderedMods[name];
7513                o = null;
7514            }
7515        }
7516        //Add to global cache
7517        if (o) {
7518            if (!GLOBAL_ENV._renderedMods) {
7519                GLOBAL_ENV._renderedMods = {};
7520            }
7521            GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o);
7522            GLOBAL_ENV._conditions = conditions;
7523        }
7524
7525        return o;
7526    },
7527
7528    /**
7529     * Add a requirement for one or more module
7530     * @method require
7531     * @param {string[] | string*} what the modules to load.
7532     */
7533    require: function(what) {
7534        var a = (typeof what === 'string') ? yArray(arguments) : what;
7535        this.dirty = true;
7536        this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a)));
7537
7538        this._explodeRollups();
7539    },
7540    /**
7541    * Grab all the items that were asked for, check to see if the Loader
7542    * meta-data contains a "use" array. If it doesm remove the asked item and replace it with
7543    * the content of the "use".
7544    * This will make asking for: "dd"
7545    * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin"
7546    * @private
7547    * @method _explodeRollups
7548    */
7549    _explodeRollups: function() {
7550        var self = this, m, m2, i, a, v, len, len2,
7551        r = self.required;
7552
7553        if (!self.allowRollup) {
7554            for (i in r) {
7555                if (r.hasOwnProperty(i)) {
7556                    m = self.getModule(i);
7557                    if (m && m.use) {
7558                        len = m.use.length;
7559                        for (a = 0; a < len; a++) {
7560                            m2 = self.getModule(m.use[a]);
7561                            if (m2 && m2.use) {
7562                                len2 = m2.use.length;
7563                                for (v = 0; v < len2; v++) {
7564                                    r[m2.use[v]] = true;
7565                                }
7566                            } else {
7567                                r[m.use[a]] = true;
7568                            }
7569                        }
7570                    }
7571                }
7572            }
7573            self.required = r;
7574        }
7575
7576    },
7577    /**
7578    * Explodes the required array to remove aliases and replace them with real modules
7579    * @method filterRequires
7580    * @param {Array} r The original requires array
7581    * @return {Array} The new array of exploded requirements
7582    */
7583    filterRequires: function(r) {
7584        if (r) {
7585            if (!Y.Lang.isArray(r)) {
7586                r = [r];
7587            }
7588            r = Y.Array(r);
7589            var c = [], i, mod, o, m;
7590
7591            for (i = 0; i < r.length; i++) {
7592                mod = this.getModule(r[i]);
7593                if (mod && mod.use) {
7594                    for (o = 0; o < mod.use.length; o++) {
7595                        //Must walk the other modules in case a module is a rollup of rollups (datatype)
7596                        m = this.getModule(mod.use[o]);
7597                        if (m && m.use && (m.name !== mod.name)) {
7598                            c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use)));
7599                        } else {
7600                            c.push(mod.use[o]);
7601                        }
7602                    }
7603                } else {
7604                    c.push(r[i]);
7605                }
7606            }
7607            r = c;
7608        }
7609        return r;
7610    },
7611
7612    /**
7613    Returns `true` if the module can be attached to the YUI instance. Runs
7614    the module's test if there is one and caches its result.
7615
7616    @method _canBeAttached
7617    @param {String} module Name of the module to check.
7618    @return {Boolean} Result of the module's test if it has one, or `true`.
7619    **/
7620    _canBeAttached: function (m) {
7621        m = this.getModule(m);
7622        if (m && m.test) {
7623            if (!m.hasOwnProperty('_testResult')) {
7624                m._testResult = m.test(Y);
7625            }
7626            return m._testResult;
7627        }
7628        // return `true` for modules not registered as Loader will know what
7629        // to do with them later on
7630        return true;
7631    },
7632
7633    /**
7634     * Returns an object containing properties for all modules required
7635     * in order to load the requested module
7636     * @method getRequires
7637     * @param {object}  mod The module definition from moduleInfo.
7638     * @return {array} the expanded requirement list.
7639     */
7640    getRequires: function(mod) {
7641
7642        if (!mod) {
7643            //console.log('returning no reqs for ' + mod.name);
7644            return NO_REQUIREMENTS;
7645        }
7646
7647        if (mod._parsed) {
7648            //console.log('returning requires for ' + mod.name, mod.requires);
7649            return mod.expanded || NO_REQUIREMENTS;
7650        }
7651
7652        //TODO add modue cache here out of scope..
7653
7654        var i, m, j, length, add, packName, lang, testresults = this.testresults,
7655            name = mod.name, cond,
7656            adddef = ON_PAGE[name] && ON_PAGE[name].details,
7657            optReqs = mod.optionalRequires,
7658            d, go, def,
7659            r, old_mod,
7660            o, skinmod, skindef, skinpar, skinname,
7661            intl = mod.lang || mod.intl,
7662            ftests = Y.Features && Y.Features.tests.load,
7663            hash, reparse;
7664
7665        // console.log(name);
7666
7667        // pattern match leaves module stub that needs to be filled out
7668        if (mod.temp && adddef) {
7669            old_mod = mod;
7670            mod = this.addModule(adddef, name);
7671            mod.group = old_mod.group;
7672            mod.pkg = old_mod.pkg;
7673            delete mod.expanded;
7674        }
7675
7676        // console.log('cache: ' + mod.langCache + ' == ' + this.lang);
7677
7678        //If a skin or a lang is different, reparse..
7679        reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin));
7680
7681        if (mod.expanded && !reparse) {
7682            return mod.expanded;
7683        }
7684
7685        // Optional dependencies are dependencies that may or may not be
7686        // available.
7687        // This feature was designed specifically to be used when transpiling
7688        // ES6 modules, in order to use polyfills and regular scripts that define
7689        // global variables without having to import them since they should be
7690        // available in the global scope.
7691        if (optReqs) {
7692            for (i = 0, length = optReqs.length; i < length; i++) {
7693                if (this._canBeAttached(optReqs[i])) {
7694                    mod.requires.push(optReqs[i]);
7695                }
7696            }
7697        }
7698
7699        d = [];
7700        hash = {};
7701        r = this.filterRequires(mod.requires);
7702        if (mod.lang) {
7703            //If a module has a lang attribute, auto add the intl requirement.
7704            d.unshift('intl');
7705            r.unshift('intl');
7706            intl = true;
7707        }
7708        o = this.filterRequires(mod.optional);
7709
7710
7711        mod._parsed = true;
7712        mod.langCache = this.lang;
7713        mod.skinCache = this.skin.defaultSkin;
7714
7715        for (i = 0; i < r.length; i++) {
7716            if (!hash[r[i]]) {
7717                d.push(r[i]);
7718                hash[r[i]] = true;
7719                m = this.getModule(r[i]);
7720                if (m) {
7721                    add = this.getRequires(m);
7722                    intl = intl || (m.expanded_map &&
7723                        (INTL in m.expanded_map));
7724                    for (j = 0; j < add.length; j++) {
7725                        d.push(add[j]);
7726                    }
7727                }
7728            }
7729        }
7730
7731        // get the requirements from superseded modules, if any
7732        r = this.filterRequires(mod.supersedes);
7733        if (r) {
7734            for (i = 0; i < r.length; i++) {
7735                if (!hash[r[i]]) {
7736                    // if this module has submodules, the requirements list is
7737                    // expanded to include the submodules.  This is so we can
7738                    // prevent dups when a submodule is already loaded and the
7739                    // parent is requested.
7740                    if (mod.submodules) {
7741                        d.push(r[i]);
7742                    }
7743
7744                    hash[r[i]] = true;
7745                    m = this.getModule(r[i]);
7746
7747                    if (m) {
7748                        add = this.getRequires(m);
7749                        intl = intl || (m.expanded_map &&
7750                            (INTL in m.expanded_map));
7751                        for (j = 0; j < add.length; j++) {
7752                            d.push(add[j]);
7753                        }
7754                    }
7755                }
7756            }
7757        }
7758
7759        if (o && this.loadOptional) {
7760            for (i = 0; i < o.length; i++) {
7761                if (!hash[o[i]]) {
7762                    d.push(o[i]);
7763                    hash[o[i]] = true;
7764                    m = this.getModuleInfo(o[i]);
7765                    if (m) {
7766                        add = this.getRequires(m);
7767                        intl = intl || (m.expanded_map &&
7768                            (INTL in m.expanded_map));
7769                        for (j = 0; j < add.length; j++) {
7770                            d.push(add[j]);
7771                        }
7772                    }
7773                }
7774            }
7775        }
7776
7777        cond = this.conditions[name];
7778
7779        if (cond) {
7780            //Set the module to not parsed since we have conditionals and this could change the dependency tree.
7781            mod._parsed = false;
7782            if (testresults && ftests) {
7783                oeach(testresults, function(result, id) {
7784                    var condmod = ftests[id].name;
7785                    if (!hash[condmod] && ftests[id].trigger === name) {
7786                        if (result && ftests[id]) {
7787                            hash[condmod] = true;
7788                            d.push(condmod);
7789                        }
7790                    }
7791                });
7792            } else {
7793                for (i in cond) {
7794                    if (cond.hasOwnProperty(i)) {
7795                        if (!hash[i]) {
7796                            def = cond[i];
7797                            //first see if they've specfied a ua check
7798                            //then see if they've got a test fn & if it returns true
7799                            //otherwise just having a condition block is enough
7800                            go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) ||
7801                                        (def.test && def.test(Y, r)));
7802
7803                            if (go) {
7804                                hash[i] = true;
7805                                d.push(i);
7806                                m = this.getModule(i);
7807                                if (m) {
7808                                    add = this.getRequires(m);
7809                                    for (j = 0; j < add.length; j++) {
7810                                        d.push(add[j]);
7811                                    }
7812
7813                                }
7814                            }
7815                        }
7816                    }
7817                }
7818            }
7819        }
7820
7821        // Create skin modules
7822        if (mod.skinnable) {
7823            skindef = this.skin.overrides;
7824            for (i in YUI.Env.aliases) {
7825                if (YUI.Env.aliases.hasOwnProperty(i)) {
7826                    if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) {
7827                        skinpar = i;
7828                    }
7829                }
7830            }
7831            if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) {
7832                skinname = name;
7833                if (skindef[skinpar]) {
7834                    skinname = skinpar;
7835                }
7836                for (i = 0; i < skindef[skinname].length; i++) {
7837                    skinmod = this._addSkin(skindef[skinname][i], name);
7838                    if (!this.isCSSLoaded(skinmod, this._boot)) {
7839                        d.push(skinmod);
7840                    }
7841                }
7842            } else {
7843                skinmod = this._addSkin(this.skin.defaultSkin, name);
7844                if (!this.isCSSLoaded(skinmod, this._boot)) {
7845                    d.push(skinmod);
7846                }
7847            }
7848        }
7849
7850        mod._parsed = false;
7851
7852        if (intl) {
7853
7854            if (mod.lang && !mod.langPack && Y.Intl) {
7855                lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang);
7856                packName = this.getLangPackName(lang, name);
7857                if (packName) {
7858                    d.unshift(packName);
7859                }
7860            }
7861            d.unshift(INTL);
7862        }
7863
7864        mod.expanded_map = yArray.hash(d);
7865
7866        mod.expanded = YObject.keys(mod.expanded_map);
7867
7868        return mod.expanded;
7869    },
7870    /**
7871    * Check to see if named css module is already loaded on the page
7872    * @method isCSSLoaded
7873    * @param {String} name The name of the css file
7874    * @param {Boolean} skip To skip the short-circuit for ignoreRegister
7875    * @return Boolean
7876    */
7877    isCSSLoaded: function(name, skip) {
7878        //TODO - Make this call a batching call with name being an array
7879        if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) {
7880            return false;
7881        }
7882        var el = YUI.Env.cssStampEl,
7883            ret = false,
7884            mod = YUI.Env._cssLoaded[name],
7885            style = el.currentStyle; //IE
7886
7887
7888        if (mod !== undefined) {
7889            return mod;
7890        }
7891
7892        //Add the classname to the element
7893        el.className = name;
7894
7895        if (!style) {
7896            style = Y.config.doc.defaultView.getComputedStyle(el, null);
7897        }
7898
7899        if (style && style.display === 'none') {
7900            ret = true;
7901        }
7902
7903
7904        el.className = ''; //Reset the classname to ''
7905
7906        YUI.Env._cssLoaded[name] = ret;
7907
7908        return ret;
7909    },
7910
7911    /**
7912     * Returns a hash of module names the supplied module satisfies.
7913     * @method getProvides
7914     * @param {string} name The name of the module.
7915     * @return {object} what this module provides.
7916     */
7917    getProvides: function(name) {
7918        var m = this.getModule(name), o, s;
7919            // supmap = this.provides;
7920
7921        if (!m) {
7922            return NOT_FOUND;
7923        }
7924
7925        if (m && !m.provides) {
7926            o = {};
7927            s = m.supersedes;
7928
7929            if (s) {
7930                yArray.each(s, function(v) {
7931                    Y.mix(o, this.getProvides(v));
7932                }, this);
7933            }
7934
7935            o[name] = true;
7936            m.provides = o;
7937
7938        }
7939
7940        return m.provides;
7941    },
7942
7943    /**
7944     * Calculates the dependency tree, the result is stored in the sorted
7945     * property.
7946     * @method calculate
7947     * @param {object} o optional options object.
7948     * @param {string} type optional argument to prune modules.
7949     */
7950    calculate: function(o, type) {
7951        if (o || type || this.dirty) {
7952
7953            if (o) {
7954                this._config(o);
7955            }
7956
7957            if (!this._init) {
7958                this._setup();
7959            }
7960
7961            this._explode();
7962
7963            if (this.allowRollup) {
7964                this._rollup();
7965            } else {
7966                this._explodeRollups();
7967            }
7968            this._reduce();
7969            this._sort();
7970        }
7971    },
7972    /**
7973    * Creates a "psuedo" package for languages provided in the lang array
7974    * @method _addLangPack
7975    * @private
7976    * @param {String} lang The language to create
7977    * @param {Object} m The module definition to create the language pack around
7978    * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US)
7979    * @return {Object} The module definition
7980    */
7981    _addLangPack: function(lang, m, packName) {
7982        var name = m.name,
7983            packPath, conf,
7984            existing = this.getModuleInfo(packName);
7985
7986        if (!existing) {
7987
7988            packPath = _path((m.pkg || name), packName, JS, true);
7989
7990            conf = {
7991                path: packPath,
7992                intl: true,
7993                langPack: true,
7994                ext: m.ext,
7995                group: m.group,
7996                supersedes: []
7997            };
7998            if (m.root) {
7999                conf.root = m.root;
8000            }
8001            if (m.base) {
8002                conf.base = m.base;
8003            }
8004
8005            if (m.configFn) {
8006                conf.configFn = m.configFn;
8007            }
8008
8009            this.addModule(conf, packName);
8010
8011            if (lang) {
8012                Y.Env.lang = Y.Env.lang || {};
8013                Y.Env.lang[lang] = Y.Env.lang[lang] || {};
8014                Y.Env.lang[lang][name] = true;
8015            }
8016        }
8017
8018        return this.getModuleInfo(packName);
8019    },
8020
8021    /**
8022     * Investigates the current YUI configuration on the page.  By default,
8023     * modules already detected will not be loaded again unless a force
8024     * option is encountered.  Called by calculate()
8025     * @method _setup
8026     * @private
8027     */
8028    _setup: function() {
8029        var info = this.moduleInfo, name, i, j, m, l,
8030            packName;
8031
8032        for (name in info) {
8033            if (info.hasOwnProperty(name)) {
8034                m = info[name];
8035                if (m) {
8036
8037                    // remove dups
8038                    //m.requires = YObject.keys(yArray.hash(m.requires));
8039                    m.requires = yArray.dedupe(m.requires);
8040
8041                    // Create lang pack modules
8042                    //if (m.lang && m.lang.length) {
8043                    if (m.lang) {
8044                        // Setup root package if the module has lang defined,
8045                        // it needs to provide a root language pack
8046                        packName = this.getLangPackName(ROOT_LANG, name);
8047                        this._addLangPack(null, m, packName);
8048                    }
8049
8050                }
8051            }
8052        }
8053
8054
8055        //l = Y.merge(this.inserted);
8056        l = {};
8057
8058        // available modules
8059        if (!this.ignoreRegistered) {
8060            Y.mix(l, GLOBAL_ENV.mods);
8061        }
8062
8063        // add the ignore list to the list of loaded packages
8064        if (this.ignore) {
8065            Y.mix(l, yArray.hash(this.ignore));
8066        }
8067
8068        // expand the list to include superseded modules
8069        for (j in l) {
8070            if (l.hasOwnProperty(j)) {
8071                Y.mix(l, this.getProvides(j));
8072            }
8073        }
8074
8075        // remove modules on the force list from the loaded list
8076        if (this.force) {
8077            for (i = 0; i < this.force.length; i++) {
8078                if (this.force[i] in l) {
8079                    delete l[this.force[i]];
8080                }
8081            }
8082        }
8083
8084        Y.mix(this.loaded, l);
8085
8086        this._init = true;
8087    },
8088
8089    /**
8090     * Builds a module name for a language pack
8091     * @method getLangPackName
8092     * @param {string} lang the language code.
8093     * @param {string} mname the module to build it for.
8094     * @return {string} the language pack module name.
8095     */
8096    getLangPackName: function(lang, mname) {
8097        return ('lang/' + mname + ((lang) ? '_' + lang : ''));
8098    },
8099    /**
8100     * Inspects the required modules list looking for additional
8101     * dependencies.  Expands the required list to include all
8102     * required modules.  Called by calculate()
8103     * @method _explode
8104     * @private
8105     */
8106    _explode: function() {
8107        //TODO Move done out of scope
8108        var r = this.required, m, reqs, done = {},
8109            self = this, name, expound;
8110
8111        // the setup phase is over, all modules have been created
8112        self.dirty = false;
8113
8114        self._explodeRollups();
8115        r = self.required;
8116
8117        for (name in r) {
8118            if (r.hasOwnProperty(name)) {
8119                if (!done[name]) {
8120                    done[name] = true;
8121                    m = self.getModule(name);
8122                    if (m) {
8123                        expound = m.expound;
8124
8125                        if (expound) {
8126                            r[expound] = self.getModule(expound);
8127                            reqs = self.getRequires(r[expound]);
8128                            Y.mix(r, yArray.hash(reqs));
8129                        }
8130
8131                        reqs = self.getRequires(m);
8132                        Y.mix(r, yArray.hash(reqs));
8133                    }
8134                }
8135            }
8136        }
8137
8138    },
8139    /**
8140    * The default method used to test a module against a pattern
8141    * @method _patternTest
8142    * @private
8143    * @param {String} mname The module being tested
8144    * @param {String} pname The pattern to match
8145    */
8146    _patternTest: function(mname, pname) {
8147        return (mname.indexOf(pname) > -1);
8148    },
8149    /**
8150    * Get's the loader meta data for the requested module
8151    * @method getModule
8152    * @param {String} mname The module name to get
8153    * @return {Object} The module metadata
8154    */
8155    getModule: function(mname) {
8156        //TODO: Remove name check - it's a quick hack to fix pattern WIP
8157        if (!mname) {
8158            return null;
8159        }
8160
8161        var p, found, pname,
8162            m = this.getModuleInfo(mname),
8163            patterns = this.patterns;
8164
8165        // check the patterns library to see if we should automatically add
8166        // the module with defaults
8167        if (!m || (m && m.ext)) {
8168            for (pname in patterns) {
8169                if (patterns.hasOwnProperty(pname)) {
8170                    p = patterns[pname];
8171
8172                    //There is no test method, create a default one that tests
8173                    // the pattern against the mod name
8174                    if (!p.test) {
8175                        p.test = this._patternTest;
8176                    }
8177
8178                    if (p.test(mname, pname)) {
8179                        // use the metadata supplied for the pattern
8180                        // as the module definition.
8181                        found = p;
8182                        break;
8183                    }
8184                }
8185            }
8186        }
8187
8188        if (!m) {
8189            if (found) {
8190                if (p.action) {
8191                    p.action.call(this, mname, pname);
8192                } else {
8193                    // ext true or false?
8194                    m = this.addModule(Y.merge(found, {
8195                        test: void 0,
8196                        temp: true
8197                    }), mname);
8198                    if (m && found.configFn) {
8199                        m.configFn = found.configFn;
8200                    }
8201                }
8202            }
8203        } else {
8204            if (found && m && found.configFn && !m.configFn) {
8205                m.configFn = found.configFn;
8206                m.configFn(m);
8207            }
8208        }
8209
8210        return m;
8211    },
8212
8213    // impl in rollup submodule
8214    _rollup: function() { },
8215
8216    /**
8217     * Remove superceded modules and loaded modules.  Called by
8218     * calculate() after we have the mega list of all dependencies
8219     * @method _reduce
8220     * @return {object} the reduced dependency hash.
8221     * @private
8222     */
8223    _reduce: function(r) {
8224
8225        r = r || this.required;
8226
8227        var i, j, s, m, type = this.loadType,
8228        ignore = this.ignore ? yArray.hash(this.ignore) : false;
8229
8230        for (i in r) {
8231            if (r.hasOwnProperty(i)) {
8232                m = this.getModule(i);
8233                // remove if already loaded
8234                if (((this.loaded[i] || ON_PAGE[i]) &&
8235                        !this.forceMap[i] && !this.ignoreRegistered) ||
8236                        (type && m && m.type !== type)) {
8237                    delete r[i];
8238                }
8239                if (ignore && ignore[i]) {
8240                    delete r[i];
8241                }
8242                // remove anything this module supersedes
8243                s = m && m.supersedes;
8244                if (s) {
8245                    for (j = 0; j < s.length; j++) {
8246                        if (s[j] in r) {
8247                            delete r[s[j]];
8248                        }
8249                    }
8250                }
8251            }
8252        }
8253
8254        return r;
8255    },
8256    /**
8257    * Handles the queue when a module has been loaded for all cases
8258    * @method _finish
8259    * @private
8260    * @param {String} msg The message from Loader
8261    * @param {Boolean} success A boolean denoting success or failure
8262    */
8263    _finish: function(msg, success) {
8264
8265        _queue.running = false;
8266
8267        var onEnd = this.onEnd;
8268        if (onEnd) {
8269            onEnd.call(this.context, {
8270                msg: msg,
8271                data: this.data,
8272                success: success
8273            });
8274        }
8275        this._continue();
8276    },
8277    /**
8278    * The default Loader onSuccess handler, calls this.onSuccess with a payload
8279    * @method _onSuccess
8280    * @private
8281    */
8282    _onSuccess: function() {
8283        var self = this, skipped = Y.merge(self.skipped), fn,
8284            failed = [], rreg = self.requireRegistration,
8285            success, msg, i, mod;
8286
8287        for (i in skipped) {
8288            if (skipped.hasOwnProperty(i)) {
8289                delete self.inserted[i];
8290            }
8291        }
8292
8293        self.skipped = {};
8294
8295        for (i in self.inserted) {
8296            if (self.inserted.hasOwnProperty(i)) {
8297                mod = self.getModule(i);
8298                if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) {
8299                    failed.push(i);
8300                } else {
8301                    Y.mix(self.loaded, self.getProvides(i));
8302                }
8303            }
8304        }
8305
8306        fn = self.onSuccess;
8307        msg = (failed.length) ? 'notregistered' : 'success';
8308        success = !(failed.length);
8309        if (fn) {
8310            fn.call(self.context, {
8311                msg: msg,
8312                data: self.data,
8313                success: success,
8314                failed: failed,
8315                skipped: skipped
8316            });
8317        }
8318        self._finish(msg, success);
8319    },
8320    /**
8321    * The default Loader onProgress handler, calls this.onProgress with a payload
8322    * @method _onProgress
8323    * @private
8324    */
8325    _onProgress: function(e) {
8326        var self = this, i;
8327        //set the internal cache to what just came in.
8328        if (e.data && e.data.length) {
8329            for (i = 0; i < e.data.length; i++) {
8330                e.data[i] = self.getModule(e.data[i].name);
8331            }
8332        }
8333        if (self.onProgress) {
8334            self.onProgress.call(self.context, {
8335                name: e.url,
8336                data: e.data
8337            });
8338        }
8339    },
8340    /**
8341    * The default Loader onFailure handler, calls this.onFailure with a payload
8342    * @method _onFailure
8343    * @private
8344    */
8345    _onFailure: function(o) {
8346        var f = this.onFailure, msg = [], i = 0, len = o.errors.length;
8347
8348        for (i; i < len; i++) {
8349            msg.push(o.errors[i].error);
8350        }
8351
8352        msg = msg.join(',');
8353
8354
8355        if (f) {
8356            f.call(this.context, {
8357                msg: msg,
8358                data: this.data,
8359                success: false
8360            });
8361        }
8362
8363        this._finish(msg, false);
8364
8365    },
8366
8367    /**
8368    * The default Loader onTimeout handler, calls this.onTimeout with a payload
8369    * @method _onTimeout
8370    * @param {Get.Transaction} transaction The Transaction object from `Y.Get`
8371    * @private
8372    */
8373    _onTimeout: function(transaction) {
8374        var f = this.onTimeout;
8375        if (f) {
8376            f.call(this.context, {
8377                msg: 'timeout',
8378                data: this.data,
8379                success: false,
8380                transaction: transaction
8381            });
8382        }
8383    },
8384
8385    /**
8386     * Sorts the dependency tree.  The last step of calculate()
8387     * @method _sort
8388     * @private
8389     */
8390    _sort: function() {
8391        var name,
8392
8393            // Object containing module names.
8394            required = this.required,
8395
8396            // Keep track of whether we've visited a module.
8397            visited = {};
8398
8399        // Will contain modules names, in the correct order,
8400        // according to dependencies.
8401        this.sorted = [];
8402
8403        for (name in required) {
8404            if (!visited[name] && required.hasOwnProperty(name)) {
8405                this._visit(name, visited);
8406            }
8407        }
8408    },
8409
8410    /**
8411     * Recursively visits the dependencies of the module name
8412     * passed in, and appends each module name to the `sorted` property.
8413     * @param {String} name The name of a module.
8414     * @param {Object} visited Keeps track of whether a module was visited.
8415     * @method _visit
8416     * @private
8417     */
8418    _visit: function (name, visited) {
8419        var required, condition, moduleInfo, dependency, dependencies,
8420            trigger, isAfter, i, l;
8421
8422        visited[name] = true;
8423        required = this.required;
8424        moduleInfo = this.moduleInfo[name];
8425        condition = this.conditions[name] || {};
8426
8427        if (moduleInfo) {
8428            // Recurse on each dependency of this module,
8429            // figuring out its dependencies, and so on.
8430            dependencies = moduleInfo.expanded || moduleInfo.requires;
8431
8432            for (i = 0, l = dependencies.length; i < l; ++i) {
8433                dependency = dependencies[i];
8434                trigger = condition[dependency];
8435
8436                // We cannot process this dependency yet if it must
8437                // appear after our current module.
8438                isAfter = trigger && (!trigger.when || trigger.when === "after");
8439
8440                // Is this module name in the required list of modules,
8441                // and have we not already visited it?
8442                if (required[dependency] && !visited[dependency] && !isAfter) {
8443                    this._visit(dependency, visited);
8444                }
8445            }
8446        }
8447
8448        this.sorted.push(name);
8449    },
8450
8451    /**
8452    * Handles the actual insertion of script/link tags
8453    * @method _insert
8454    * @private
8455    * @param {Object} source The YUI instance the request came from
8456    * @param {Object} o The metadata to include
8457    * @param {String} type JS or CSS
8458    * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta
8459    */
8460    _insert: function(source, o, type, skipcalc) {
8461
8462
8463        // restore the state at the time of the request
8464        if (source) {
8465            this._config(source);
8466        }
8467
8468        // build the dependency list
8469        // don't include type so we can process CSS and script in
8470        // one pass when the type is not specified.
8471
8472        var modules = this.resolve(!skipcalc),
8473            self = this, comp = 0, actions = 0,
8474            mods = {}, deps, complete;
8475
8476        self._refetch = [];
8477
8478        if (type) {
8479            //Filter out the opposite type and reset the array so the checks later work
8480            modules[((type === JS) ? CSS : JS)] = [];
8481        }
8482        if (!self.fetchCSS) {
8483            modules.css = [];
8484        }
8485        if (modules.js.length) {
8486            comp++;
8487        }
8488        if (modules.css.length) {
8489            comp++;
8490        }
8491
8492        //console.log('Resolved Modules: ', modules);
8493
8494        complete = function(d) {
8495            actions++;
8496            var errs = {}, i = 0, o = 0, u = '', fn,
8497                modName, resMods;
8498
8499            if (d && d.errors) {
8500                for (i = 0; i < d.errors.length; i++) {
8501                    if (d.errors[i].request) {
8502                        u = d.errors[i].request.url;
8503                    } else {
8504                        u = d.errors[i];
8505                    }
8506                    errs[u] = u;
8507                }
8508            }
8509
8510            if (d && d.data && d.data.length && (d.type === 'success')) {
8511                for (i = 0; i < d.data.length; i++) {
8512                    self.inserted[d.data[i].name] = true;
8513                    //If the external module has a skin or a lang, reprocess it
8514                    if (d.data[i].lang || d.data[i].skinnable) {
8515                        delete self.inserted[d.data[i].name];
8516                        self._refetch.push(d.data[i].name);
8517                    }
8518                }
8519            }
8520
8521            if (actions === comp) {
8522                self._loading = null;
8523                if (self._refetch.length) {
8524                    //Get the deps for the new meta-data and reprocess
8525                    for (i = 0; i < self._refetch.length; i++) {
8526                        deps = self.getRequires(self.getModule(self._refetch[i]));
8527                        for (o = 0; o < deps.length; o++) {
8528                            if (!self.inserted[deps[o]]) {
8529                                //We wouldn't be to this point without the module being here
8530                                mods[deps[o]] = deps[o];
8531                            }
8532                        }
8533                    }
8534                    mods = Y.Object.keys(mods);
8535                    if (mods.length) {
8536                        self.require(mods);
8537                        resMods = self.resolve(true);
8538                        if (resMods.cssMods.length) {
8539                            for (i=0; i <  resMods.cssMods.length; i++) {
8540                                modName = resMods.cssMods[i].name;
8541                                delete YUI.Env._cssLoaded[modName];
8542                                if (self.isCSSLoaded(modName)) {
8543                                    self.inserted[modName] = true;
8544                                    delete self.required[modName];
8545                                }
8546                            }
8547                            self.sorted = [];
8548                            self._sort();
8549                        }
8550                        d = null; //bail
8551                        self._insert(); //insert the new deps
8552                    }
8553                }
8554                if (d && d.fn) {
8555                    fn = d.fn;
8556                    delete d.fn;
8557                    fn.call(self, d);
8558                }
8559            }
8560        };
8561
8562        this._loading = true;
8563
8564        if (!modules.js.length && !modules.css.length) {
8565            actions = -1;
8566            complete({
8567                fn: self._onSuccess
8568            });
8569            return;
8570        }
8571
8572
8573        if (modules.css.length) { //Load CSS first
8574            Y.Get.css(modules.css, {
8575                data: modules.cssMods,
8576                attributes: self.cssAttributes,
8577                insertBefore: self.insertBefore,
8578                charset: self.charset,
8579                timeout: self.timeout,
8580                context: self,
8581                onProgress: function(e) {
8582                    self._onProgress.call(self, e);
8583                },
8584                onTimeout: function(d) {
8585                    self._onTimeout.call(self, d);
8586                },
8587                onSuccess: function(d) {
8588                    d.type = 'success';
8589                    d.fn = self._onSuccess;
8590                    complete.call(self, d);
8591                },
8592                onFailure: function(d) {
8593                    d.type = 'failure';
8594                    d.fn = self._onFailure;
8595                    complete.call(self, d);
8596                }
8597            });
8598        }
8599
8600        if (modules.js.length) {
8601            Y.Get.js(modules.js, {
8602                data: modules.jsMods,
8603                insertBefore: self.insertBefore,
8604                attributes: self.jsAttributes,
8605                charset: self.charset,
8606                timeout: self.timeout,
8607                autopurge: false,
8608                context: self,
8609                async: self.async,
8610                onProgress: function(e) {
8611                    self._onProgress.call(self, e);
8612                },
8613                onTimeout: function(d) {
8614                    self._onTimeout.call(self, d);
8615                },
8616                onSuccess: function(d) {
8617                    d.type = 'success';
8618                    d.fn = self._onSuccess;
8619                    complete.call(self, d);
8620                },
8621                onFailure: function(d) {
8622                    d.type = 'failure';
8623                    d.fn = self._onFailure;
8624                    complete.call(self, d);
8625                }
8626            });
8627        }
8628    },
8629    /**
8630    * Once a loader operation is completely finished, process any additional queued items.
8631    * @method _continue
8632    * @private
8633    */
8634    _continue: function() {
8635        if (!(_queue.running) && _queue.size() > 0) {
8636            _queue.running = true;
8637            _queue.next()();
8638        }
8639    },
8640
8641    /**
8642     * inserts the requested modules and their dependencies.
8643     * <code>type</code> can be "js" or "css".  Both script and
8644     * css are inserted if type is not provided.
8645     * @method insert
8646     * @param {object} o optional options object.
8647     * @param {string} type the type of dependency to insert.
8648     */
8649    insert: function(o, type, skipsort) {
8650        var self = this, copy = Y.merge(this);
8651        delete copy.require;
8652        delete copy.dirty;
8653        _queue.add(function() {
8654            self._insert(copy, o, type, skipsort);
8655        });
8656        this._continue();
8657    },
8658
8659    /**
8660     * Executed every time a module is loaded, and if we are in a load
8661     * cycle, we attempt to load the next script.  Public so that it
8662     * is possible to call this if using a method other than
8663     * Y.register to determine when scripts are fully loaded
8664     * @method loadNext
8665     * @deprecated
8666     * @param {string} mname optional the name of the module that has
8667     * been loaded (which is usually why it is time to load the next
8668     * one).
8669     */
8670    loadNext: function() {
8671        return;
8672    },
8673
8674    /**
8675     * Apply filter defined for this instance to a url/path
8676     * @method _filter
8677     * @param {string} u the string to filter.
8678     * @param {string} name the name of the module, if we are processing
8679     * a single module as opposed to a combined url.
8680     * @return {string} the filtered string.
8681     * @private
8682     */
8683    _filter: function(u, name, group) {
8684        var f = this.filter,
8685            hasFilter = name && (name in this.filters),
8686            modFilter = hasFilter && this.filters[name],
8687            groupName = group || (this.getModuleInfo(name) || {}).group || null;
8688
8689        if (groupName && this.groups[groupName] && this.groups[groupName].filter) {
8690            modFilter = this.groups[groupName].filter;
8691            hasFilter = true;
8692        }
8693
8694        if (u) {
8695            if (hasFilter) {
8696                f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter;
8697            }
8698            if (f) {
8699                u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr);
8700            }
8701        }
8702        return u;
8703    },
8704
8705    /**
8706     * Generates the full url for a module
8707     * @method _url
8708     * @param {string} path the path fragment.
8709     * @param {String} name The name of the module
8710     * @param {String} [base] The base url to use. Defaults to self.base
8711     * @return {string} the full url.
8712     * @private
8713     */
8714    _url: function(path, name, base) {
8715        return this._filter((base || this.base || '') + path, name);
8716    },
8717    /**
8718    * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules.
8719    * @method resolve
8720    * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else
8721    * @param {Array} [sorted=loader.sorted] An override for the loader.sorted array
8722    * @return {Object} Object hash (js and css) of two arrays of file lists
8723    * @example This method can be used as an off-line dep calculator
8724    *
8725    *        var Y = YUI();
8726    *        var loader = new Y.Loader({
8727    *            filter: 'debug',
8728    *            base: '../../',
8729    *            root: 'build/',
8730    *            combine: true,
8731    *            require: ['node', 'dd', 'console']
8732    *        });
8733    *        var out = loader.resolve(true);
8734    *
8735    */
8736    resolve: function(calc, sorted) {
8737        var self     = this,
8738            resolved = { js: [], jsMods: [], css: [], cssMods: [] },
8739            addSingle,
8740            usePathogen = Y.config.comboLoader && Y.config.customComboBase;
8741
8742        if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) {
8743            self._resetModules();
8744        }
8745
8746        if (calc) {
8747            self.calculate();
8748        }
8749        sorted = sorted || self.sorted;
8750
8751        addSingle = function(mod) {
8752            if (mod) {
8753                var group = (mod.group && self.groups[mod.group]) || NOT_FOUND,
8754                    url;
8755
8756                //Always assume it's async
8757                if (group.async === false) {
8758                    mod.async = group.async;
8759                }
8760
8761                url = (mod.fullpath) ? self._filter(mod.fullpath, mod.name) :
8762                      self._url(mod.path, mod.name, group.base || mod.base);
8763
8764                if (mod.attributes || mod.async === false) {
8765                    url = {
8766                        url: url,
8767                        async: mod.async
8768                    };
8769                    if (mod.attributes) {
8770                        url.attributes = mod.attributes;
8771                    }
8772                }
8773                resolved[mod.type].push(url);
8774                resolved[mod.type + 'Mods'].push(mod);
8775            } else {
8776            }
8777
8778        };
8779
8780        /*jslint vars: true */
8781        var inserted     = (self.ignoreRegistered) ? {}
8781 : self.inserted,
8782            comboSources,
8783            maxURLLength,
8784            comboMeta,
8785            comboBase,
8786            comboSep,
8787            group,
8788            mod,
8789            len,
8790            i,
8791            hasComboModule = false;
8792
8793        /*jslint vars: false */
8794
8795        for (i = 0, len = sorted.length; i < len; i++) {
8796            mod = self.getModule(sorted[i]);
8797            if (!mod || inserted[mod.name]) {
8798                continue;
8799            }
8800
8801            group = self.groups[mod.group];
8802
8803            comboBase = self.comboBase;
8804
8805            if (group) {
8806                if (!group.combine || mod.fullpath) {
8807                    //This is not a combo module, skip it and load it singly later.
8808                    addSingle(mod);
8809                    continue;
8810                }
8811                mod.combine = true;
8812
8813                if (typeof group.root === 'string') {
8814                    mod.root = group.root;
8815                }
8816
8817                comboBase    = group.comboBase || comboBase;
8818                comboSep     = group.comboSep;
8819                maxURLLength = group.maxURLLength;
8820            } else {
8821                if (!self.combine) {
8822                    //This is not a combo module, skip it and load it singly later.
8823                    addSingle(mod);
8824                    continue;
8825                }
8826            }
8827
8828            if (!mod.combine && mod.ext) {
8829                addSingle(mod);
8830                continue;
8831            }
8832            hasComboModule = true;
8833            comboSources = comboSources || {};
8834            comboSources[comboBase] = comboSources[comboBase] ||
8835                { js: [], jsMods: [], css: [], cssMods: [] };
8836
8837            comboMeta               = comboSources[comboBase];
8838            comboMeta.group         = mod.group;
8839            comboMeta.comboSep      = comboSep || self.comboSep;
8840            comboMeta.maxURLLength  = maxURLLength || self.maxURLLength;
8841
8842            comboMeta[mod.type + 'Mods'].push(mod);
8843            if (mod.type === JS || mod.type === CSS) {
8844                resolved[mod.type + 'Mods'].push(mod);
8845            }
8846        }
8847        //only encode if we have something to encode
8848        if (hasComboModule) {
8849            if (usePathogen) {
8850                resolved = this._pathogenEncodeComboSources(resolved);
8851            } else {
8852                resolved = this._encodeComboSources(resolved, comboSources);
8853            }
8854        }
8855        return resolved;
8856    },
8857
8858    /**
8859     * Encodes combo sources and appends them to an object hash of arrays from `loader.resolve`.
8860     *
8861     * @method _encodeComboSources
8862     * @param {Object} resolved The object hash of arrays in which to attach the encoded combo sources.
8863     * @param {Object} comboSources An object containing relevant data about modules.
8864     * @return Object
8865     * @private
8866     */
8867    _encodeComboSources: function(resolved, comboSources) {
8868        var fragSubset,
8869            modules,
8870            tmpBase,
8871            baseLen,
8872            frags,
8873            frag,
8874            type,
8875            mod,
8876            maxURLLength,
8877            comboBase,
8878            comboMeta,
8879            comboSep,
8880            i,
8881            len,
8882            self = this;
8883
8884        for (comboBase in comboSources) {
8885            if (comboSources.hasOwnProperty(comboBase)) {
8886                comboMeta    = comboSources[comboBase];
8887                comboSep     = comboMeta.comboSep;
8888                maxURLLength = comboMeta.maxURLLength;
8889                for (type in comboMeta) {
8890                    if (type === JS || type === CSS) {
8891                        modules = comboMeta[type + 'Mods'];
8892                        frags = [];
8893                        for (i = 0, len = modules.length; i < len; i += 1) {
8894                            mod = modules[i];
8895                            frag = ((typeof mod.root === 'string') ? mod.root : self.root) + (mod.path || mod.fullpath);
8896                            frags.push(
8897                                self._filter(frag, mod.name)
8898                            );
8899                        }
8900                        tmpBase = comboBase + frags.join(comboSep);
8901                        baseLen = tmpBase.length;
8902                        if (maxURLLength <= comboBase.length) {
8903                            maxURLLength = MAX_URL_LENGTH;
8904                        }
8905
8906                        if (frags.length) {
8907                            if (baseLen > maxURLLength) {
8908                                fragSubset = [];
8909                                for (i = 0, len = frags.length; i < len; i++) {
8910                                    fragSubset.push(frags[i]);
8911                                    tmpBase = comboBase + fragSubset.join(comboSep);
8912
8913                                    if (tmpBase.length > maxURLLength) {
8914                                        frag = fragSubset.pop();
8915                                        tmpBase = comboBase + fragSubset.join(comboSep);
8916                                        resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8917                                        fragSubset = [];
8918                                        if (frag) {
8919                                            fragSubset.push(frag);
8920                                        }
8921                                    }
8922                                }
8923                                if (fragSubset.length) {
8924                                    tmpBase = comboBase + fragSubset.join(comboSep);
8925                                    resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8926                                }
8927                            } else {
8928                                resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8929                            }
8930                        }
8931                    }
8932                }
8933            }
8934        }
8935        return resolved;
8936    },
8937
8938    /**
8939    Shortcut to calculate, resolve and load all modules.
8940
8941        var loader = new Y.Loader({
8942            ignoreRegistered: true,
8943            modules: {
8944                mod: {
8945                    path: 'mod.js'
8946                }
8947            },
8948            requires: [ 'mod' ]
8949        });
8950        loader.load(function() {
8951            console.log('All modules have loaded..');
8952        });
8953
8954
8955    @method load
8956    @param {Function} cb Executed after all load operations are complete
8957    */
8958    load: function(cb) {
8959        if (!cb) {
8960            return;
8961        }
8962        var self = this,
8963            out = self.resolve(true);
8964
8965        self.data = out;
8966
8967        self.onEnd = function() {
8968            cb.apply(self.context || self, arguments);
8969        };
8970
8971        self.insert();
8972    }
8973};
8974
8975
8976}, 'patched-v3.18.1', {"requires": ["get", "features"]});
8977YUI.add('loader-rollup', function (Y, NAME) {
8978
8979/**
8980 * Optional automatic rollup logic for reducing http connections
8981 * when not using a combo service.
8982 * @module loader
8983 * @submodule rollup
8984 */
8985
8986/**
8987 * Look for rollup packages to determine if all of the modules a
8988 * rollup supersedes are required.  If so, include the rollup to
8989 * help reduce the total number of connections required.  Called
8990 * by calculate().  This is an optional feature, and requires the
8991 * appropriate submodule to function.
8992 * @method _rollup
8993 * @for Loader
8994 * @private
8995 */
8996Y.Loader.prototype._rollup = function() {
8997    var i, j, m, s, r = this.required, roll,
8998        info = this.moduleInfo, rolled, c, smod;
8999
9000    // find and cache rollup modules
9001    if (this.dirty || !this.rollups) {
9002        this.rollups = {};
9003        for (i in info) {
9004            if (info.hasOwnProperty(i)) {
9005                m = this.getModule(i);
9006                // if (m && m.rollup && m.supersedes) {
9007                if (m && m.rollup) {
9008                    this.rollups[i] = m;
9009                }
9010            }
9011        }
9012    }
9013
9014    // make as many passes as needed to pick up rollup rollups
9015    for (;;) {
9016        rolled = false;
9017
9018        // go through the rollup candidates
9019        for (i in this.rollups) {
9020            if (this.rollups.hasOwnProperty(i)) {
9021                // there can be only one, unless forced
9022                if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) {
9023                    m = this.getModule(i);
9024                    s = m.supersedes || [];
9025                    roll = false;
9026
9027                    // @TODO remove continue
9028                    if (!m.rollup) {
9029                        continue;
9030                    }
9031
9032                    c = 0;
9033
9034                    // check the threshold
9035                    for (j = 0; j < s.length; j++) {
9036                        smod = info[s[j]];
9037
9038                        // if the superseded module is loaded, we can't
9039                        // load the rollup unless it has been forced.
9040                        if (this.loaded[s[j]] && !this.forceMap[s[j]]) {
9041                            roll = false;
9042                            break;
9043                        // increment the counter if this module is required.
9044                        // if we are beyond the rollup threshold, we will
9045                        // use the rollup module
9046                        } else if (r[s[j]] && m.type === smod.type) {
9047                            c++;
9048                            roll = (c >= m.rollup);
9049                            if (roll) {
9050                                break;
9051                            }
9052                        }
9053                    }
9054
9055                    if (roll) {
9056                        // add the rollup
9057                        r[i] = true;
9058                        rolled = true;
9059
9060                        // expand the rollup's dependencies
9061                        this.getRequires(m);
9062                    }
9063                }
9064            }
9065        }
9066
9067        // if we made it here w/o rolling up something, we are done
9068        if (!rolled) {
9069            break;
9070        }
9071    }
9072};
9073
9074
9075}, 'patched-v3.18.1', {"requires": ["loader-base"]});
9076YUI.add('loader-yui3', function (Y, NAME) {
9077
9078/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
9079
9080/*jshint maxlen:900, eqeqeq: false */
9081
9082/**
9083 * YUI 3 module metadata
9084 * @module loader
9085 * @submodule loader-yui3
9086 */
9087YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
9088Y.mix(YUI.Env[Y.version].modules, {
9089    "align-plugin": {
9090        "requires": [
9091            "node-screen",
9092            "node-pluginhost"
9093        ]
9094    },
9095    "anim": {
9096        "use": [
9097            "anim-base",
9098            "anim-color",
9099            "anim-curve",
9100            "anim-easing",
9101            "anim-node-plugin",
9102            "anim-scroll",
9103            "anim-xy"
9104        ]
9105    },
9106    "anim-base": {
9107        "requires": [
9108            "base-base",
9109            "node-style",
9110            "color-base"
9111        ]
9112    },
9113    "anim-color": {
9114        "requires": [
9115            "anim-base"
9116        ]
9117    },
9118    "anim-curve": {
9119        "requires": [
9120            "anim-xy"
9121        ]
9122    },
9123    "anim-easing": {
9124        "requires": [
9125            "anim-base"
9126        ]
9127    },
9128    "anim-node-plugin": {
9129        "requires": [
9130            "node-pluginhost",
9131            "anim-base"
9132        ]
9133    },
9134    "anim-scroll": {
9135        "requires": [
9136            "anim-base"
9137        ]
9138    },
9139    "anim-shape": {
9140        "requires": [
9141            "anim-base",
9142            "anim-easing",
9143            "anim-color",
9144            "matrix"
9145        ]
9146    },
9147    "anim-shape-transform": {
9148        "use": [
9149            "anim-shape"
9150        ]
9151    },
9152    "anim-xy": {
9153        "requires": [
9154            "anim-base",
9155            "node-screen"
9156        ]
9157    },
9158    "app": {
9159        "use": [
9160            "app-base",
9161            "app-content",
9162            "app-transitions",
9163            "lazy-model-list",
9164            "model",
9165            "model-list",
9166            "model-sync-rest",
9167            "model-sync-local",
9168            "router",
9169            "view",
9170            "view-node-map"
9171        ]
9172    },
9173    "app-base": {
9174        "requires": [
9175            "classnamemanager",
9176            "pjax-base",
9177            "router",
9178            "view"
9179        ]
9180    },
9181    "app-content": {
9182        "requires": [
9183            "app-base",
9184            "pjax-content"
9185        ]
9186    },
9187    "app-transitions": {
9188        "requires": [
9189            "app-base"
9190        ]
9191    },
9192    "app-transitions-css": {
9193        "type": "css"
9194    },
9195    "app-transitions-native": {
9196        "condition": {
9197            "name": "app-transitions-native",
9198            "test": function (Y) {
9199    var doc  = Y.config.doc,
9200        node = doc ? doc.documentElement : null;
9201
9202    if (node && node.style) {
9203        return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
9204    }
9205
9206    return false;
9207},
9208            "trigger": "app-transitions"
9209        },
9210        "requires": [
9211            "app-transitions",
9212            "app-transitions-css",
9213            "parallel",
9214            "transition"
9215        ]
9216    },
9217    "array-extras": {
9218        "requires": [
9219            "yui-base"
9220        ]
9221    },
9222    "array-invoke": {
9223        "requires": [
9224            "yui-base"
9225        ]
9226    },
9227    "arraylist": {
9228        "requires": [
9229            "yui-base"
9230        ]
9231    },
9232    "arraylist-add": {
9233        "requires": [
9234            "arraylist"
9235        ]
9236    },
9237    "arraylist-filter": {
9238        "requires": [
9239            "arraylist"
9240        ]
9241    },
9242    "arraysort": {
9243        "requires": [
9244            "yui-base"
9245        ]
9246    },
9247    "async-queue": {
9248        "requires": [
9249            "event-custom"
9250        ]
9251    },
9252    "attribute": {
9253        "use": [
9254            "attribute-base",
9255            "attribute-complex"
9256        ]
9257    },
9258    "attribute-base": {
9259        "requires": [
9260            "attribute-core",
9261            "attribute-observable",
9262            "attribute-extras"
9263        ]
9264    },
9265    "attribute-complex": {
9266        "requires": [
9267            "attribute-base"
9268        ]
9269    },
9270    "attribute-core": {
9271        "requires": [
9272            "oop"
9273        ]
9274    },
9275    "attribute-events": {
9276        "use": [
9277            "attribute-observable"
9278        ]
9279    },
9280    "attribute-extras": {
9281        "requires": [
9282            "oop"
9283        ]
9284    },
9285    "attribute-observable": {
9286        "requires": [
9287            "event-custom"
9288        ]
9289    },
9290    "autocomplete": {
9291        "use": [
9292            "autocomplete-base",
9293            "autocomplete-sources",
9294            "autocomplete-list",
9295            "autocomplete-plugin"
9296        ]
9297    },
9298    "autocomplete-base": {
9299        "optional": [
9300            "autocomplete-sources"
9301        ],
9302        "requires": [
9303            "array-extras",
9304            "base-build",
9305            "escape",
9306            "event-valuechange",
9307            "node-base"
9308        ]
9309    },
9310    "autocomplete-filters": {
9311        "requires": [
9312            "array-extras",
9313            "text-wordbreak"
9314        ]
9315    },
9316    "autocomplete-filters-accentfold": {
9317        "requires": [
9318            "array-extras",
9319            "text-accentfold",
9320            "text-wordbreak"
9321        ]
9322    },
9323    "autocomplete-highlighters": {
9324        "requires": [
9325            "array-extras",
9326            "highlight-base"
9327        ]
9328    },
9329    "autocomplete-highlighters-accentfold": {
9330        "requires": [
9331            "array-extras",
9332            "highlight-accentfold"
9333        ]
9334    },
9335    "autocomplete-list": {
9336        "after": [
9337            "autocomplete-sources"
9338        ],
9339        "lang": [
9340            "en",
9341            "es",
9342            "hu",
9343            "it"
9344        ],
9345        "requires": [
9346            "autocomplete-base",
9347            "event-resize",
9348            "node-screen",
9349            "selector-css3",
9350            "shim-plugin",
9351            "widget",
9352            "widget-position",
9353            "widget-position-align"
9354        ],
9355        "skinnable": true
9356    },
9357    "autocomplete-list-keys": {
9358        "condition": {
9359            "name": "autocomplete-list-keys",
9360            "test": function (Y) {
9361    // Only add keyboard support to autocomplete-list if this doesn't appear to
9362    // be an iOS or Android-based mobile device.
9363    //
9364    // There's currently no feasible way to actually detect whether a device has
9365    // a hardware keyboard, so this sniff will have to do. It can easily be
9366    // overridden by manually loading the autocomplete-list-keys module.
9367    //
9368    // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
9369    // doesn't fire the keyboard events used by AutoCompleteList, so there's
9370    // no point loading the -keys module even when a bluetooth keyboard may be
9371    // available.
9372    return !(Y.UA.ios || Y.UA.android);
9373},
9374            "trigger": "autocomplete-list"
9375        },
9376        "requires": [
9377            "autocomplete-list",
9378            "base-build"
9379        ]
9380    },
9381    "autocomplete-plugin": {
9382        "requires": [
9383            "autocomplete-list",
9384            "node-pluginhost"
9385        ]
9386    },
9387    "autocomplete-sources": {
9388        "optional": [
9389            "io-base",
9390            "json-parse",
9391            "jsonp",
9392            "yql"
9393        ],
9394        "requires": [
9395            "autocomplete-base"
9396        ]
9397    },
9398    "axes": {
9399        "use": [
9400            "axis-numeric",
9401            "axis-category",
9402            "axis-time",
9403            "axis-stacked"
9404        ]
9405    },
9406    "axes-base": {
9407        "use": [
9408            "axis-numeric-base",
9409            "axis-category-base",
9410            "axis-time-base",
9411            "axis-stacked-base"
9412        ]
9413    },
9414    "axis": {
9415        "requires": [
9416            "dom",
9417            "widget",
9418            "widget-position",
9419            "widget-stack",
9420            "graphics",
9421            "axis-base"
9422        ]
9423    },
9424    "axis-base": {
9425        "requires": [
9426            "classnamemanager",
9427            "datatype-number",
9428            "datatype-date",
9429            "base",
9430            "event-custom"
9431        ]
9432    },
9433    "axis-category": {
9434        "requires": [
9435            "axis",
9436            "axis-category-base"
9437        ]
9438    },
9439    "axis-category-base": {
9440        "requires": [
9441            "axis-base"
9442        ]
9443    },
9444    "axis-numeric": {
9445        "requires": [
9446            "axis",
9447            "axis-numeric-base"
9448        ]
9449    },
9450    "axis-numeric-base": {
9451        "requires": [
9452            "axis-base"
9453        ]
9454    },
9455    "axis-stacked": {
9456        "requires": [
9457            "axis-numeric",
9458            "axis-stacked-base"
9459        ]
9460    },
9461    "axis-stacked-base": {
9462        "requires": [
9463            "axis-numeric-base"
9464        ]
9465    },
9466    "axis-time": {
9467        "requires": [
9468            "axis",
9469            "axis-time-base"
9470        ]
9471    },
9472    "axis-time-base": {
9473        "requires": [
9474            "axis-base"
9475        ]
9476    },
9477    "base": {
9478        "use": [
9479            "base-base",
9480            "base-pluginhost",
9481            "base-build"
9482        ]
9483    },
9484    "base-base": {
9485        "requires": [
9486            "attribute-base",
9487            "base-core",
9488            "base-observable"
9489        ]
9490    },
9491    "base-build": {
9492        "requires": [
9493            "base-base"
9494        ]
9495    },
9496    "base-core": {
9497        "requires": [
9498            "attribute-core"
9499        ]
9500    },
9501    "base-observable": {
9502        "requires": [
9503            "attribute-observable",
9504            "base-core"
9505        ]
9506    },
9507    "base-pluginhost": {
9508        "requires": [
9509            "base-base",
9510            "pluginhost"
9511        ]
9512    },
9513    "button": {
9514        "requires": [
9515            "button-core",
9516            "cssbutton",
9517            "widget"
9518        ]
9519    },
9520    "button-core": {
9521        "requires": [
9522            "attribute-core",
9523            "classnamemanager",
9524            "node-base",
9525            "escape"
9526        ]
9527    },
9528    "button-group": {
9529        "requires": [
9530            "button-plugin",
9531            "cssbutton",
9532            "widget"
9533        ]
9534    },
9535    "button-plugin": {
9536        "requires": [
9537            "button-core",
9538            "cssbutton",
9539            "node-pluginhost"
9540        ]
9541    },
9542    "cache": {
9543        "use": [
9544            "cache-base",
9545            "cache-offline",
9546            "cache-plugin"
9547        ]
9548    },
9549    "cache-base": {
9550        "requires": [
9551            "base"
9552        ]
9553    },
9554    "cache-offline": {
9555        "requires": [
9556            "cache-base",
9557            "json"
9558        ]
9559    },
9560    "cache-plugin": {
9561        "requires": [
9562            "plugin",
9563            "cache-base"
9564        ]
9565    },
9566    "calendar": {
9567        "requires": [
9568            "calendar-base",
9569            "calendarnavigator"
9570        ],
9571        "skinnable": true
9572    },
9573    "calendar-base": {
9574        "lang": [
9575            "ca",
9576            "ca-ES",
9577            "de",
9578            "en",
9579            "es",
9580            "es-AR",
9581            "eu-ES",
9582            "fr",
9583            "hu",
9584            "it",
9585            "ja",
9586            "nb-NO",
9587            "nl",
9588            "pt-BR",
9589            "ru",
9590            "zh-Hans",
9591            "zh-Hans-CN",
9592            "zh-Hant",
9593            "zh-Hant-HK",
9594            "zh-HANT-TW"
9595        ],
9596        "requires": [
9597            "widget",
9598            "datatype-date",
9599            "datatype-date-math",
9600            "cssgrids"
9601        ],
9602        "skinnable": true
9603    },
9604    "calendarnavigator": {
9605        "requires": [
9606            "plugin",
9607            "classnamemanager",
9608            "datatype-date",
9609            "node"
9610        ],
9611        "skinnable": true
9612    },
9613    "charts": {
9614        "use": [
9615            "charts-base"
9616        ]
9617    },
9618    "charts-base": {
9619        "requires": [
9620            "dom",
9621            "event-mouseenter",
9622            "event-touch",
9623            "graphics-group",
9624            "axes",
9625            "series-pie",
9626            "series-line",
9627            "series-marker",
9628            "series-area",
9629            "series-spline",
9630            "series-column",
9631            "series-bar",
9632            "series-areaspline",
9633            "series-combo",
9634            "series-combospline",
9635            "series-line-stacked",
9636            "series-marker-stacked",
9637            "series-area-stacked",
9638            "series-spline-stacked",
9639            "series-column-stacked",
9640            "series-bar-stacked",
9641            "series-areaspline-stacked",
9642            "series-combo-stacked",
9643            "series-combospline-stacked"
9644        ]
9645    },
9646    "charts-legend": {
9647        "requires": [
9648            "charts-base"
9649        ]
9650    },
9651    "classnamemanager": {
9652        "requires": [
9653            "yui-base"
9654        ]
9655    },
9656    "clickable-rail": {
9657        "requires": [
9658            "slider-base"
9659        ]
9660    },
9661    "collection": {
9662        "use": [
9663            "array-extras",
9664            "arraylist",
9665            "arraylist-add",
9666            "arraylist-filter",
9667            "array-invoke"
9668        ]
9669    },
9670    "color": {
9671        "use": [
9672            "color-base",
9673            "color-hsl",
9674            "color-harmony"
9675        ]
9676    },
9677    "color-base": {
9678        "requires": [
9679            "yui-base"
9680        ]
9681    },
9682    "color-harmony": {
9683        "requires": [
9684            "color-hsl"
9685        ]
9686    },
9687    "color-hsl": {
9688        "requires": [
9689            "color-base"
9690        ]
9691    },
9692    "color-hsv": {
9693        "requires": [
9694            "color-base"
9695        ]
9696    },
9697    "console": {
9698        "lang": [
9699            "en",
9700            "es",
9701            "hu",
9702            "it",
9703            "ja"
9704        ],
9705        "requires": [
9706            "yui-log",
9707            "widget"
9708        ],
9709        "skinnable": true
9710    },
9711    "console-filters": {
9712        "requires": [
9713            "plugin",
9714            "console"
9715        ],
9716        "skinnable": true
9717    },
9718    "content-editable": {
9719        "requires": [
9720            "node-base",
9721            "editor-selection",
9722            "stylesheet",
9723            "plugin"
9724        ]
9725    },
9726    "controller": {
9727        "use": [
9728            "router"
9729        ]
9730    },
9731    "cookie": {
9732        "requires": [
9733            "yui-base"
9734        ]
9735    },
9736    "createlink-base": {
9737        "requires": [
9738            "editor-base"
9739        ]
9740    },
9741    "cssbase": {
9742        "after": [
9743            "cssreset",
9744            "cssfonts",
9745            "cssgrids",
9746            "cssreset-context",
9747            "cssfonts-context",
9748            "cssgrids-context"
9749        ],
9750        "type": "css"
9751    },
9752    "cssbase-context": {
9753        "after": [
9754            "cssreset",
9755            "cssfonts",
9756            "cssgrids",
9757            "cssreset-context",
9758            "cssfonts-context",
9759            "cssgrids-context"
9760        ],
9761        "type": "css"
9762    },
9763    "cssbutton": {
9764        "type": "css"
9765    },
9766    "cssfonts": {
9767        "type": "css"
9768    },
9769    "cssfonts-context": {
9770        "type": "css"
9771    },
9772    "cssgrids": {
9773        "optional": [
9774            "cssnormalize"
9775        ],
9776        "type": "css"
9777    },
9778    "cssgrids-base": {
9779        "optional": [
9780            "cssnormalize"
9781        ],
9782        "type": "css"
9783    },
9784    "cssgrids-responsive": {
9785        "optional": [
9786            "cssnormalize"
9787        ],
9788        "requires": [
9789            "cssgrids",
9790            "cssgrids-responsive-base"
9791        ],
9792        "type": "css"
9793    },
9794    "cssgrids-units": {
9795        "optional": [
9796            "cssnormalize"
9797        ],
9798        "requires": [
9799            "cssgrids-base"
9800        ],
9801        "type": "css"
9802    },
9803    "cssnormalize": {
9804        "type": "css"
9805    },
9806    "cssnormalize-context": {
9807        "type": "css"
9808    },
9809    "cssreset": {
9810        "type": "css"
9811    },
9812    "cssreset-context": {
9813        "type": "css"
9814    },
9815    "dataschema": {
9816        "use": [
9817            "dataschema-base",
9818            "dataschema-json",
9819            "dataschema-xml",
9820            "dataschema-array",
9821            "dataschema-text"
9822        ]
9823    },
9824    "dataschema-array": {
9825        "requires": [
9826            "dataschema-base"
9827        ]
9828    },
9829    "dataschema-base": {
9830        "requires": [
9831            "base"
9832        ]
9833    },
9834    "dataschema-json": {
9835        "requires": [
9836            "dataschema-base",
9837            "json"
9838        ]
9839    },
9840    "dataschema-text": {
9841        "requires": [
9842            "dataschema-base"
9843        ]
9844    },
9845    "dataschema-xml": {
9846        "requires": [
9847            "dataschema-base"
9848        ]
9849    },
9850    "datasource": {
9851        "use": [
9852            "datasource-local",
9853            "datasource-io",
9854            "datasource-get",
9855            "datasource-function",
9856            "datasource-cache",
9857            "datasource-jsonschema",
9858            "datasource-xmlschema",
9859            "datasource-arrayschema",
9860            "datasource-textschema",
9861            "datasource-polling"
9862        ]
9863    },
9864    "datasource-arrayschema": {
9865        "requires": [
9866            "datasource-local",
9867            "plugin",
9868            "dataschema-array"
9869        ]
9870    },
9871    "datasource-cache": {
9872        "requires": [
9873            "datasource-local",
9874            "plugin",
9875            "cache-base"
9876        ]
9877    },
9878    "datasource-function": {
9879        "requires": [
9880            "datasource-local"
9881        ]
9882    },
9883    "datasource-get": {
9884        "requires": [
9885            "datasource-local",
9886            "get"
9887        ]
9888    },
9889    "datasource-io": {
9890        "requires": [
9891            "datasource-local",
9892            "io-base"
9893        ]
9894    },
9895    "datasource-jsonschema": {
9896        "requires": [
9897            "datasource-local",
9898            "plugin",
9899            "dataschema-json"
9900        ]
9901    },
9902    "datasource-local": {
9903        "requires": [
9904            "base"
9905        ]
9906    },
9907    "datasource-polling": {
9908        "requires": [
9909            "datasource-local"
9910        ]
9911    },
9912    "datasource-textschema": {
9913        "requires": [
9914            "datasource-local",
9915            "plugin",
9916            "dataschema-text"
9917        ]
9918    },
9919    "datasource-xmlschema": {
9920        "requires": [
9921            "datasource-local",
9922            "plugin",
9923            "datatype-xml",
9924            "dataschema-xml"
9925        ]
9926    },
9927    "datatable": {
9928        "use": [
9929            "datatable-core",
9930            "datatable-table",
9931            "datatable-head",
9932            "datatable-body",
9933            "datatable-base",
9934            "datatable-column-widths",
9935            "datatable-message",
9936            "datatable-mutable",
9937            "datatable-sort",
9938            "datatable-datasource"
9939        ]
9940    },
9941    "datatable-base": {
9942        "requires": [
9943            "datatable-core",
9944            "datatable-table",
9945            "datatable-head",
9946            "datatable-body",
9947            "base-build",
9948            "widget"
9949        ],
9950        "skinnable": true
9951    },
9952    "datatable-body": {
9953        "requires": [
9954            "datatable-core",
9955            "view",
9956            "classnamemanager"
9957        ]
9958    },
9959    "datatable-column-widths": {
9960        "requires": [
9961            "datatable-base"
9962        ]
9963    },
9964    "datatable-core": {
9965        "requires": [
9966            "escape",
9967            "model-list",
9968            "node-event-delegate"
9969        ]
9970    },
9971    "datatable-datasource": {
9972        "requires": [
9973            "datatable-base",
9974            "plugin",
9975            "datasource-local"
9976        ]
9977    },
9978    "datatable-foot": {
9979        "requires": [
9980            "datatable-core",
9981            "view"
9982        ]
9983    },
9984    "datatable-formatters": {
9985        "requires": [
9986            "datatable-body",
9987   
9987         "datatype-number-format",
9988            "datatype-date-format",
9989            "escape"
9990        ]
9991    },
9992    "datatable-head": {
9993        "requires": [
9994            "datatable-core",
9995            "view",
9996            "classnamemanager"
9997        ]
9998    },
9999    "datatable-highlight": {
10000        "requires": [
10001            "datatable-base",
10002            "event-hover"
10003        ],
10004        "skinnable": true
10005    },
10006    "datatable-keynav": {
10007        "requires": [
10008            "datatable-base"
10009        ]
10010    },
10011    "datatable-message": {
10012        "lang": [
10013            "en",
10014            "fr",
10015            "es",
10016            "hu",
10017            "it"
10018        ],
10019        "requires": [
10020            "datatable-base"
10021        ],
10022        "skinnable": true
10023    },
10024    "datatable-mutable": {
10025        "requires": [
10026            "datatable-base"
10027        ]
10028    },
10029    "datatable-paginator": {
10030        "lang": [
10031            "en",
10032            "fr"
10033        ],
10034        "requires": [
10035            "model",
10036            "view",
10037            "paginator-core",
10038            "datatable-foot",
10039            "datatable-paginator-templates"
10040        ],
10041        "skinnable": true
10042    },
10043    "datatable-paginator-templates": {
10044        "requires": [
10045            "template"
10046        ]
10047    },
10048    "datatable-scroll": {
10049        "requires": [
10050            "datatable-base",
10051            "datatable-column-widths",
10052            "dom-screen"
10053        ],
10054        "skinnable": true
10055    },
10056    "datatable-sort": {
10057        "lang": [
10058            "en",
10059            "fr",
10060            "es",
10061            "hu"
10062        ],
10063        "requires": [
10064            "datatable-base"
10065        ],
10066        "skinnable": true
10067    },
10068    "datatable-table": {
10069        "requires": [
10070            "datatable-core",
10071            "datatable-head",
10072            "datatable-body",
10073            "view",
10074            "classnamemanager"
10075        ]
10076    },
10077    "datatype": {
10078        "use": [
10079            "datatype-date",
10080            "datatype-number",
10081            "datatype-xml"
10082        ]
10083    },
10084    "datatype-date": {
10085        "use": [
10086            "datatype-date-parse",
10087            "datatype-date-format",
10088            "datatype-date-math"
10089        ]
10090    },
10091    "datatype-date-format": {
10092        "lang": [
10093            "ar",
10094            "ar-JO",
10095            "ca",
10096            "ca-ES",
10097            "da",
10098            "da-DK",
10099            "de",
10100            "de-AT",
10101            "de-DE",
10102            "el",
10103            "el-GR",
10104            "en",
10105            "en-AU",
10106            "en-CA",
10107            "en-GB",
10108            "en-IE",
10109            "en-IN",
10110            "en-JO",
10111            "en-MY",
10112            "en-NZ",
10113            "en-PH",
10114            "en-SG",
10115            "en-US",
10116            "es",
10117            "es-AR",
10118            "es-BO",
10119            "es-CL",
10120            "es-CO",
10121            "es-EC",
10122            "es-ES",
10123            "es-MX",
10124            "es-PE",
10125            "es-PY",
10126            "es-US",
10127            "es-UY",
10128            "es-VE",
10129            "fi",
10130            "fi-FI",
10131            "fr",
10132            "fr-BE",
10133            "fr-CA",
10134            "fr-FR",
10135            "hi",
10136            "hi-IN",
10137            "hu",
10138            "id",
10139            "id-ID",
10140            "it",
10141            "it-IT",
10142            "ja",
10143            "ja-JP",
10144            "ko",
10145            "ko-KR",
10146            "ms",
10147            "ms-MY",
10148            "nb",
10149            "nb-NO",
10150            "nl",
10151            "nl-BE",
10152            "nl-NL",
10153            "pl",
10154            "pl-PL",
10155            "pt",
10156            "pt-BR",
10157            "ro",
10158            "ro-RO",
10159            "ru",
10160            "ru-RU",
10161            "sv",
10162            "sv-SE",
10163            "th",
10164            "th-TH",
10165            "tr",
10166            "tr-TR",
10167            "vi",
10168            "vi-VN",
10169            "zh-Hans",
10170            "zh-Hans-CN",
10171            "zh-Hant",
10172            "zh-Hant-HK",
10173            "zh-Hant-TW"
10174        ]
10175    },
10176    "datatype-date-math": {
10177        "requires": [
10178            "yui-base"
10179        ]
10180    },
10181    "datatype-date-parse": {},
10182    "datatype-number": {
10183        "use": [
10184            "datatype-number-parse",
10185            "datatype-number-format"
10186        ]
10187    },
10188    "datatype-number-format": {},
10189    "datatype-number-parse": {
10190        "requires": [
10191            "escape"
10192        ]
10193    },
10194    "datatype-xml": {
10195        "use": [
10196            "datatype-xml-parse",
10197            "datatype-xml-format"
10198        ]
10199    },
10200    "datatype-xml-format": {},
10201    "datatype-xml-parse": {},
10202    "dd": {
10203        "use": [
10204            "dd-ddm-base",
10205            "dd-ddm",
10206            "dd-ddm-drop",
10207            "dd-drag",
10208            "dd-proxy",
10209            "dd-constrain",
10210            "dd-drop",
10211            "dd-scroll",
10212            "dd-delegate"
10213        ]
10214    },
10215    "dd-constrain": {
10216        "requires": [
10217            "dd-drag"
10218        ]
10219    },
10220    "dd-ddm": {
10221        "requires": [
10222            "dd-ddm-base",
10223            "event-resize"
10224        ]
10225    },
10226    "dd-ddm-base": {
10227        "requires": [
10228            "node",
10229            "base",
10230            "yui-throttle",
10231            "classnamemanager"
10232        ]
10233    },
10234    "dd-ddm-drop": {
10235        "requires": [
10236            "dd-ddm"
10237        ]
10238    },
10239    "dd-delegate": {
10240        "requires": [
10241            "dd-drag",
10242            "dd-drop-plugin",
10243            "event-mouseenter"
10244        ]
10245    },
10246    "dd-drag": {
10247        "requires": [
10248            "dd-ddm-base",
10249            "selector-css2"
10250        ]
10251    },
10252    "dd-drop": {
10253        "requires": [
10254            "dd-drag",
10255            "dd-ddm-drop"
10256        ]
10257    },
10258    "dd-drop-plugin": {
10259        "requires": [
10260            "dd-drop"
10261        ]
10262    },
10263    "dd-gestures": {
10264        "condition": {
10265            "name": "dd-gestures",
10266            "trigger": "dd-drag",
10267            "ua": "touchEnabled"
10268        },
10269        "requires": [
10270            "dd-drag",
10271            "event-synthetic",
10272            "event-gestures"
10273        ]
10274    },
10275    "dd-plugin": {
10276        "optional": [
10277            "dd-constrain",
10278            "dd-proxy"
10279        ],
10280        "requires": [
10281            "dd-drag"
10282        ]
10283    },
10284    "dd-proxy": {
10285        "requires": [
10286            "dd-drag"
10287        ]
10288    },
10289    "dd-scroll": {
10290        "requires": [
10291            "dd-drag"
10292        ]
10293    },
10294    "dial": {
10295        "lang": [
10296            "en",
10297            "es",
10298            "hu"
10299        ],
10300        "requires": [
10301            "widget",
10302            "dd-drag",
10303            "event-mouseenter",
10304            "event-move",
10305            "event-key",
10306            "transition",
10307            "intl"
10308        ],
10309        "skinnable": true
10310    },
10311    "dom": {
10312        "use": [
10313            "dom-base",
10314            "dom-screen",
10315            "dom-style",
10316            "selector-native",
10317            "selector"
10318        ]
10319    },
10320    "dom-base": {
10321        "requires": [
10322            "dom-core"
10323        ]
10324    },
10325    "dom-core": {
10326        "requires": [
10327            "oop",
10328            "features"
10329        ]
10330    },
10331    "dom-screen": {
10332        "requires": [
10333            "dom-base",
10334            "dom-style"
10335        ]
10336    },
10337    "dom-style": {
10338        "requires": [
10339            "dom-base"
10340        ]
10341    },
10342    "dom-style-ie": {
10343        "condition": {
10344            "name": "dom-style-ie",
10345            "test": function (Y) {
10346
10347    var testFeature = Y.Features.test,
10348        addFeature = Y.Features.add,
10349        WINDOW = Y.config.win,
10350        DOCUMENT = Y.config.doc,
10351        DOCUMENT_ELEMENT = 'documentElement',
10352        ret = false;
10353
10354    addFeature('style', 'computedStyle', {
10355        test: function() {
10356            return WINDOW && 'getComputedStyle' in WINDOW;
10357        }
10358    });
10359
10360    addFeature('style', 'opacity', {
10361        test: function() {
10362            return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
10363        }
10364    });
10365
10366    ret =  (!testFeature('style', 'opacity') &&
10367            !testFeature('style', 'computedStyle'));
10368
10369    return ret;
10370},
10371            "trigger": "dom-style"
10372        },
10373        "requires": [
10374            "dom-style",
10375            "color-base"
10376        ]
10377    },
10378    "dump": {
10379        "requires": [
10380            "yui-base"
10381        ]
10382    },
10383    "editor": {
10384        "use": [
10385            "frame",
10386            "editor-selection",
10387            "exec-command",
10388            "editor-base",
10389            "editor-para",
10390            "editor-br",
10391            "editor-bidi",
10392            "editor-tab",
10393            "createlink-base"
10394        ]
10395    },
10396    "editor-base": {
10397        "requires": [
10398            "base",
10399            "frame",
10400            "node",
10401            "exec-command",
10402            "editor-selection"
10403        ]
10404    },
10405    "editor-bidi": {
10406        "requires": [
10407            "editor-base"
10408        ]
10409    },
10410    "editor-br": {
10411        "requires": [
10412            "editor-base"
10413        ]
10414    },
10415    "editor-inline": {
10416        "requires": [
10417            "editor-base",
10418            "content-editable"
10419        ]
10420    },
10421    "editor-lists": {
10422        "requires": [
10423            "editor-base"
10424        ]
10425    },
10426    "editor-para": {
10427        "requires": [
10428            "editor-para-base"
10429        ]
10430    },
10431    "editor-para-base": {
10432        "requires": [
10433            "editor-base"
10434        ]
10435    },
10436    "editor-para-ie": {
10437        "condition": {
10438            "name": "editor-para-ie",
10439            "trigger": "editor-para",
10440            "ua": "ie",
10441            "when": "instead"
10442        },
10443        "requires": [
10444            "editor-para-base"
10445        ]
10446    },
10447    "editor-selection": {
10448        "requires": [
10449            "node"
10450        ]
10451    },
10452    "editor-tab": {
10453        "requires": [
10454            "editor-base"
10455        ]
10456    },
10457    "escape": {
10458        "requires": [
10459            "yui-base"
10460        ]
10461    },
10462    "event": {
10463        "after": [
10464            "node-base"
10465        ],
10466        "use": [
10467            "event-base",
10468            "event-delegate",
10469            "event-synthetic",
10470            "event-mousewheel",
10471            "event-mouseenter",
10472            "event-key",
10473            "event-focus",
10474            "event-resize",
10475            "event-hover",
10476            "event-outside",
10477            "event-touch",
10478            "event-move",
10479            "event-flick",
10480            "event-valuechange",
10481            "event-tap"
10482        ]
10483    },
10484    "event-base": {
10485        "after": [
10486            "node-base"
10487        ],
10488        "requires": [
10489            "event-custom-base"
10490        ]
10491    },
10492    "event-base-ie": {
10493        "after": [
10494            "event-base"
10495        ],
10496        "condition": {
10497            "name": "event-base-ie",
10498            "test": function(Y) {
10499    var imp = Y.config.doc && Y.config.doc.implementation;
10500    return (imp && (!imp.hasFeature('Events', '2.0')));
10501},
10502            "trigger": "node-base"
10503        },
10504        "requires": [
10505            "node-base"
10506        ]
10507    },
10508    "event-contextmenu": {
10509        "requires": [
10510            "event-synthetic",
10511            "dom-screen"
10512        ]
10513    },
10514    "event-custom": {
10515        "use": [
10516            "event-custom-base",
10517            "event-custom-complex"
10518        ]
10519    },
10520    "event-custom-base": {
10521        "requires": [
10522            "oop"
10523        ]
10524    },
10525    "event-custom-complex": {
10526        "requires": [
10527            "event-custom-base"
10528        ]
10529    },
10530    "event-delegate": {
10531        "requires": [
10532            "node-base"
10533        ]
10534    },
10535    "event-flick": {
10536        "requires": [
10537            "node-base",
10538            "event-touch",
10539            "event-synthetic"
10540        ]
10541    },
10542    "event-focus": {
10543        "requires": [
10544            "event-synthetic"
10545        ]
10546    },
10547    "event-gestures": {
10548        "use": [
10549            "event-flick",
10550            "event-move"
10551        ]
10552    },
10553    "event-hover": {
10554        "requires": [
10555            "event-mouseenter"
10556        ]
10557    },
10558    "event-key": {
10559        "requires": [
10560            "event-synthetic"
10561        ]
10562    },
10563    "event-mouseenter": {
10564        "requires": [
10565            "event-synthetic"
10566        ]
10567    },
10568    "event-mousewheel": {
10569        "requires": [
10570            "node-base"
10571        ]
10572    },
10573    "event-move": {
10574        "requires": [
10575            "node-base",
10576            "event-touch",
10577            "event-synthetic"
10578        ]
10579    },
10580    "event-outside": {
10581        "requires": [
10582            "event-synthetic"
10583        ]
10584    },
10585    "event-resize": {
10586        "requires": [
10587            "node-base",
10588            "event-synthetic"
10589        ]
10590    },
10591    "event-simulate": {
10592        "requires": [
10593            "event-base"
10594        ]
10595    },
10596    "event-synthetic": {
10597        "requires": [
10598            "node-base",
10599            "event-custom-complex"
10600        ]
10601    },
10602    "event-tap": {
10603        "requires": [
10604            "node-base",
10605            "event-base",
10606            "event-touch",
10607            "event-synthetic"
10608        ]
10609    },
10610    "event-touch": {
10611        "requires": [
10612            "node-base"
10613        ]
10614    },
10615    "event-valuechange": {
10616        "requires": [
10617            "event-focus",
10618            "event-synthetic"
10619        ]
10620    },
10621    "exec-command": {
10622        "requires": [
10623            "frame"
10624        ]
10625    },
10626    "features": {
10627        "requires": [
10628            "yui-base"
10629        ]
10630    },
10631    "file": {
10632        "requires": [
10633            "file-flash",
10634            "file-html5"
10635        ]
10636    },
10637    "file-flash": {
10638        "requires": [
10639            "base"
10640        ]
10641    },
10642    "file-html5": {
10643        "requires": [
10644            "base"
10645        ]
10646    },
10647    "frame": {
10648        "requires": [
10649            "base",
10650            "node",
10651            "plugin",
10652            "selector-css3",
10653            "yui-throttle"
10654        ]
10655    },
10656    "gesture-simulate": {
10657        "requires": [
10658            "async-queue",
10659            "event-simulate",
10660            "node-screen"
10661        ]
10662    },
10663    "get": {
10664        "requires": [
10665            "yui-base"
10666        ]
10667    },
10668    "graphics": {
10669        "requires": [
10670            "node",
10671            "event-custom",
10672            "pluginhost",
10673            "matrix",
10674            "classnamemanager"
10675        ]
10676    },
10677    "graphics-canvas": {
10678        "condition": {
10679            "name": "graphics-canvas",
10680            "test": function(Y) {
10681    var DOCUMENT = Y.config.doc,
10682        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10683		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10684        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10685    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10686},
10687            "trigger": "graphics"
10688        },
10689        "requires": [
10690            "graphics",
10691            "color-base"
10692        ]
10693    },
10694    "graphics-canvas-default": {
10695        "condition": {
10696            "name": "graphics-canvas-default",
10697            "test": function(Y) {
10698    var DOCUMENT = Y.config.doc,
10699        useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10700		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10701        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10702    return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10703},
10704            "trigger": "graphics"
10705        }
10706    },
10707    "graphics-group": {
10708        "requires": [
10709            "graphics"
10710        ]
10711    },
10712    "graphics-svg": {
10713        "condition": {
10714            "name": "graphics-svg",
10715            "test": function(Y) {
10716    var DOCUMENT = Y.config.doc,
10717        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10718		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10719        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10720
10721    return svg && (useSVG || !canvas);
10722},
10723            "trigger": "graphics"
10724        },
10725        "requires": [
10726            "graphics"
10727        ]
10728    },
10729    "graphics-svg-default": {
10730        "condition": {
10731            "name": "graphics-svg-default",
10732            "test": function(Y) {
10733    var DOCUMENT = Y.config.doc,
10734        useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10735		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10736        svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10737
10738    return svg && (useSVG || !canvas);
10739},
10740            "trigger": "graphics"
10741        }
10742    },
10743    "graphics-vml": {
10744        "condition": {
10745            "name": "graphics-vml",
10746            "test": function(Y) {
10747    var DOCUMENT = Y.config.doc,
10748		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10749    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10750},
10751            "trigger": "graphics"
10752        },
10753        "requires": [
10754            "graphics",
10755            "color-base"
10756        ]
10757    },
10758    "graphics-vml-default": {
10759        "condition": {
10760            "name": "graphics-vml-default",
10761            "test": function(Y) {
10762    var DOCUMENT = Y.config.doc,
10763		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10764    return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10765},
10766            "trigger": "graphics"
10767        }
10768    },
10769    "handlebars": {
10770        "use": [
10771            "handlebars-compiler"
10772        ]
10773    },
10774    "handlebars-base": {
10775        "requires": []
10776    },
10777    "handlebars-compiler": {
10778        "requires": [
10779            "handlebars-base"
10780        ]
10781    },
10782    "highlight": {
10783        "use": [
10784            "highlight-base",
10785            "highlight-accentfold"
10786        ]
10787    },
10788    "highlight-accentfold": {
10789        "requires": [
10790            "highlight-base",
10791            "text-accentfold"
10792        ]
10793    },
10794    "highlight-base": {
10795        "requires": [
10796            "array-extras",
10797            "classnamemanager",
10798            "escape",
10799            "text-wordbreak"
10800        ]
10801    },
10802    "history": {
10803        "use": [
10804            "history-base",
10805            "history-hash",
10806            "history-html5"
10807        ]
10808    },
10809    "history-base": {
10810        "requires": [
10811            "event-custom-complex"
10812        ]
10813    },
10814    "history-hash": {
10815        "after": [
10816            "history-html5"
10817        ],
10818        "requires": [
10819            "event-synthetic",
10820            "history-base",
10821            "yui-later"
10822        ]
10823    },
10824    "history-hash-ie": {
10825        "condition": {
10826            "name": "history-hash-ie",
10827            "test": function (Y) {
10828    var docMode = Y.config.doc && Y.config.doc.documentMode;
10829
10830    return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
10831            !docMode || docMode < 8);
10832},
10833            "trigger": "history-hash"
10834        },
10835        "requires": [
10836            "history-hash",
10837            "node-base"
10838        ]
10839    },
10840    "history-html5": {
10841        "optional": [
10842            "json"
10843        ],
10844        "requires": [
10845            "event-base",
10846            "history-base",
10847            "node-base"
10848        ]
10849    },
10850    "imageloader": {
10851        "requires": [
10852            "base-base",
10853            "node-style",
10854            "node-screen"
10855        ]
10856    },
10857    "intl": {
10858        "requires": [
10859            "intl-base",
10860            "event-custom"
10861        ]
10862    },
10863    "intl-base": {
10864        "requires": [
10865            "yui-base"
10866        ]
10867    },
10868    "io": {
10869        "use": [
10870            "io-base",
10871            "io-xdr",
10872            "io-form",
10873            "io-upload-iframe",
10874            "io-queue"
10875        ]
10876    },
10877    "io-base": {
10878        "requires": [
10879            "event-custom-base",
10880            "querystring-stringify-simple"
10881        ]
10882    },
10883    "io-form": {
10884        "requires": [
10885            "io-base",
10886            "node-base"
10887        ]
10888    },
10889    "io-nodejs": {
10890        "condition": {
10891            "name": "io-nodejs",
10892            "trigger": "io-base",
10893            "ua": "nodejs"
10894        },
10895        "requires": [
10896            "io-base"
10897        ]
10898    },
10899    "io-queue": {
10900        "requires": [
10901            "io-base",
10902            "queue-promote"
10903        ]
10904    },
10905    "io-upload-iframe": {
10906        "requires": [
10907            "io-base",
10908            "node-base"
10909        ]
10910    },
10911    "io-xdr": {
10912        "requires": [
10913            "io-base",
10914            "datatype-xml-parse"
10915        ]
10916    },
10917    "json": {
10918        "use": [
10919            "json-parse",
10920            "json-stringify"
10921        ]
10922    },
10923    "json-parse": {
10924        "requires": [
10925            "yui-base"
10926        ]
10927    },
10928    "json-parse-shim": {
10929        "condition": {
10930            "name": "json-parse-shim",
10931            "test": function (Y) {
10932    var _JSON = Y.config.global.JSON,
10933        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
10934        nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
10935
10936    function workingNative( k, v ) {
10937        return k === "ok" ? true : v;
10938    }
10939
10940    // Double check basic functionality.  This is mainly to catch early broken
10941    // implementations of the JSON API in Firefox 3.1 beta1 and beta2
10942    if ( nativeSupport ) {
10943        try {
10944            nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
10945        }
10946        catch ( e ) {
10947            nativeSupport = false;
10948        }
10949    }
10950
10951    return !nativeSupport;
10952},
10953            "trigger": "json-parse"
10954        },
10955        "requires": [
10956            "json-parse"
10957        ]
10958    },
10959    "json-stringify": {
10960        "requires": [
10961            "yui-base"
10962        ]
10963    },
10964    "json-stringify-shim": {
10965        "condition": {
10966            "name": "json-stringify-shim",
10967            "test": function (Y) {
10968    var _JSON = Y.config.global.JSON,
10969        Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
10970        nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
10971
10972    // Double check basic native functionality.  This is primarily to catch broken
10973    // early JSON API implementations in Firefox 3.1 beta1 and beta2.
10974    if ( nativeSupport ) {
10975        try {
10976            nativeSupport = ( '0' === Native.stringify(0) );
10977        } catch ( e ) {
10978            nativeSupport = false;
10979        }
10980    }
10981
10982
10983    return !nativeSupport;
10984},
10985            "trigger": "json-stringify"
10986        },
10987        "requires": [
10988            "json-stringify"
10989        ]
10990    },
10991    "jsonp": {
10992        "requires": [
10993            "get",
10994            "oop"
10995        ]
10996    },
10997    "jsonp-url": {
10998        "requires": [
10999            "jsonp"
11000        ]
11001    },
11002    "lazy-model-list": {
11003        "requires": [
11004            "model-list"
11005        ]
11006    },
11007    "loader": {
11008        "use": [
11009            "loader-base",
11010            "loader-rollup",
11011            "loader-yui3"
11012        ]
11013    },
11014    "loader-base": {
11015        "requires": [
11016            "get",
11017            "features"
11018        ]
11019    },
11020    "loader-pathogen-combohandler": {},
11021    "loader-pathogen-encoder": {
11022        "use": [
11023            "loader-base",
11024            "loader-rollup",
11025            "loader-yui3",
11026            "loader-pathogen-combohandler"
11027        ]
11028    },
11029    "loader-rollup": {
11030        "requires": [
11031            "loader-base"
11032        ]
11033    },
11034    "loader-yui3": {
11035        "requires": [
11036            "loader-base"
11037        ]
11038    },
11039    "matrix": {
11040        "requires": [
11041            "yui-base"
11042        ]
11043    },
11044    "model": {
11045        "requires": [
11046            "base-build",
11047            "escape",
11048            "json-parse"
11049        ]
11050    },
11051    "model-list": {
11052        "requires": [
11053            "array-extras",
11054            "array-invoke",
11055            "arraylist",
11056            "base-build",
11057            "escape",
11058            "json-parse",
11059            "model"
11060        ]
11061    },
11062    "model-sync-local": {
11063        "requires": [
11064            "model",
11065            "json-stringify"
11066        ]
11067    },
11068    "model-sync-rest": {
11069        "requires": [
11070            "model",
11071            "io-base",
11072            "json-stringify"
11073        ]
11074    },
11075    "node": {
11076        "use": [
11077            "node-base",
11078            "node-event-delegate",
11079            "node-pluginhost",
11080            "node-screen",
11081            "node-style"
11082        ]
11083    },
11084    "node-base": {
11085        "requires": [
11086            "event-base",
11087            "node-core",
11088            "dom-base",
11089            "dom-style"
11090        ]
11091    },
11092    "node-core": {
11093        "requires": [
11094            "dom-core",
11095            "selector"
11096        ]
11097    },
11098    "node-event-delegate": {
11099        "requires": [
11100            "node-base",
11101            "event-delegate"
11102        ]
11103    },
11104    "node-event-html5": {
11105        "requires": [
11106            "node-base"
11107        ]
11108    },
11109    "node-event-simulate": {
11110        "requires": [
11111            "node-base",
11112            "event-simulate",
11113            "gesture-simulate"
11114        ]
11115    },
11116    "node-flick": {
11117        "requires": [
11118            "classnamemanager",
11119            "transition",
11120            "event-flick",
11121            "plugin"
11122        ],
11123        "skinnable": true
11124    },
11125    "node-focusmanager": {
11126        "requires": [
11127            "attribute",
11128            "node",
11129            "plugin",
11130            "node-event-simulate",
11131            "event-key",
11132            "event-focus"
11133        ]
11134    },
11135    "node-load": {
11136        "requires": [
11137            "node-base",
11138            "io-base"
11139        ]
11140    },
11141    "node-menunav": {
11142        "requires": [
11143            "node",
11144            "classnamemanager",
11145            "plugin",
11146            "node-focusmanager"
11147        ],
11148        "skinnable": true
11149    },
11150    "node-pluginhost": {
11151        "requires": [
11152            "node-base",
11153            "pluginhost"
11154        ]
11155    },
11156    "node-screen": {
11157        "requires": [
11158            "dom-screen",
11159            "node-base"
11160        ]
11161    },
11162    "node-scroll-info": {
11163        "requires": [
11164            "array-extras",
11165            "base-build",
11166            "event-resize",
11167            "node-pluginhost",
11168            "plugin",
11169            "selector"
11170        ]
11171    },
11172    "node-style": {
11173        "requires": [
11174            "dom-style",
11175            "node-base"
11176        ]
11177    },
11178    "oop": {
11179        "requires": [
11180            "yui-base"
11181        ]
11182    },
11183    "overlay": {
11184        "requires": [
11185            "widget",
11186            "widget-stdmod",
11187            "widget-position",
11188            "widget-position-align",
11189            "widget-stack",
11190            "widget-position-constrain"
11191        ],
11192        "skinnable": true
11193    },
11194    "paginator": {
11195        "requires": [
11196            "paginator-core"
11197        ]
11198    },
11199    "paginator-core": {
11200        "requires": [
11201            "base"
11202        ]
11203    },
11204    "paginator-url": {
11205        "requires": [
11206            "paginator"
11207        ]
11208    },
11209    "panel": {
11210        "requires": [
11211            "widget",
11212            "widget-autohide",
11213            "widget-buttons",
11214            "widget-modality",
11215            "widget-position",
11216            "widget-position-align",
11217            "widget-position-constrain",
11218            "widget-stack",
11219            "widget-stdmod"
11220        ],
11221        "skinnable": true
11222    },
11223    "parallel": {
11224        "requires": [
11225            "yui-base"
11226        ]
11227    },
11228    "pjax": {
11229        "requires": [
11230            "pjax-base",
11231            "pjax-content"
11232        ]
11233    },
11234    "pjax-base": {
11235        "requires": [
11236            "classnamemanager",
11237            "node-event-delegate",
11238            "router"
11239        ]
11240    },
11241    "pjax-content": {
11242        "requires": [
11243            "io-base",
11244            "node-base",
11245            "router"
11246        ]
11247    },
11248    "pjax-plugin": {
11249        "requires": [
11250            "node-pluginhost",
11251            "pjax",
11252            "plugin"
11253        ]
11254    },
11255    "plugin": {
11256        "requires": [
11257            "base-base"
11258        ]
11259    },
11260    "pluginhost": {
11261        "use": [
11262            "pluginhost-base",
11263            "pluginhost-config"
11264        ]
11265    },
11266    "pluginhost-base": {
11267        "requires": [
11268            "yui-base"
11269        ]
11270    },
11271    "pluginhost-config": {
11272        "requires": [
11273            "pluginhost-base"
11274        ]
11275    },
11276    "promise": {
11277        "requires": [
11278            "timers"
11279        ]
11280    },
11281    "querystring": {
11282        "use": [
11283            "querystring-parse",
11284            "querystring-stringify"
11285        ]
11286    },
11287    "querystring-parse": {
11288        "requires": [
11289            "yui-base",
11290            "array-extras"
11291        ]
11292    },
11293    "querystring-parse-simple": {
11294        "requires": [
11295            "yui-base"
11296        ]
11297    },
11298    "querystring-stringify": {
11299        "requires": [
11300            "yui-base"
11301        ]
11302    },
11303    "querystring-stringify-simple": {
11304        "requires": [
11305            "yui-base"
11306        ]
11307    },
11308    "queue-promote": {
11309        "requires": [
11310            "yui-base"
11311        ]
11312    },
11313    "range-slider": {
11314        "requires": [
11315            "slider-base",
11316            "slider-value-range",
11317            "clickable-rail"
11318        ]
11319    },
11320    "recordset": {
11321        "use": [
11322            "recordset-base",
11323            "recordset-sort",
11324            "recordset-filter",
11325            "recordset-indexer"
11326        ]
11327    },
11328    "recordset-base": {
11329        "requires": [
11330            "base",
11331            "arraylist"
11332        ]
11333    },
11334    "recordset-filter": {
11335        "requires": [
11336            "recordset-base",
11337            "array-extras",
11338            "plugin"
11339        ]
11340    },
11341    "recordset-indexer": {
11342        "requires": [
11343            "recordset-base",
11344            "plugin"
11345        ]
11346    },
11347    "recordset-sort": {
11348        "requires": [
11349            "arraysort",
11350            "recordset-base",
11351            "plugin"
11352        ]
11353    },
11354    "resize": {
11355        "use": [
11356            "resize-base",
11357            "resize-proxy",
11358            "resize-constrain"
11359        ]
11360    },
11361    "resize-base": {
11362        "requires": [
11363            "base",
11364            "widget",
11365            "event",
11366            "oop",
11367            "dd-drag",
11368            "dd-delegate",
11369            "dd-drop"
11370        ],
11371        "skinnable": true
11372    },
11373    "resize-constrain": {
11374        "requires": [
11375            "plugin",
11376            "resize-base"
11377        ]
11378    },
11379    "resize-plugin": {
11380        "optional": [
11381            "resize-constrain"
11382        ],
11383        "requires": [
11384            "resize-base",
11385            "plugin"
11386        ]
11387    },
11388    "resize-proxy": {
11389        "requires": [
11390            "plugin",
11391            "resize-base"
11392        ]
11393    },
11394    "router": {
11395        "optional": [
11396            "querystring-parse"
11397        ],
11398        "requires": [
11399            "array-extras",
11400            "base-build",
11401            "history"
11402        ]
11403    },
11404    "scrollview": {
11405        "requires": [
11406            "scrollview-base",
11407            "scrollview-scrollbars"
11408        ]
11409    },
11410    "scrollview-base": {
11411        "requires": [
11412            "widget",
11413            "event-gestures",
11414            "event-mousewheel",
11415            "transition"
11416        ],
11417        "skinnable": true
11418    },
11419    "scrollview-base-ie": {
11420        "condition": {
11421            "name": "scrollview-base-ie",
11422            "trigger": "scrollview-base",
11423            "ua": "ie"
11424        },
11425        "requires": [
11426            "scrollview-base"
11427        ]
11428    },
11429    "scrollview-list": {
11430        "requires": [
11431            "plugin",
11432            "classnamemanager"
11433        ],
11434        "skinnable": true
11435    },
11436    "scrollview-paginator": {
11437        "requires": [
11438            "plugin",
11439            "classnamemanager"
11440        ]
11441    },
11442    "scrollview-scrollbars": {
11443        "requires": [
11444            "classnamemanager",
11445            "transition",
11446            "plugin"
11447        ],
11448        "skinnable": true
11449    },
11450    "selector": {
11451        "requires": [
11452            "selector-native"
11453        ]
11454    },
11455    "selector-css2": {
11456        "condition": {
11457            "name": "selector-css2",
11458            "test": function (Y) {
11459    var DOCUMENT = Y.config.doc,
11460        ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
11461
11462    return ret;
11463},
11464            "trigger": "selector"
11465        },
11466        "requires": [
11467            "selector-native"
11468        ]
11469    },
11470    "selector-css3": {
11471        "requires": [
11472            "selector-native",
11473            "selector-css2"
11474        ]
11475    },
11476    "selector-native": {
11477        "requires": [
11478            "dom-base"
11479        ]
11480    },
11481    "series-area": {
11482        "requires": [
11483            "series-cartesian",
11484            "series-fill-util"
11485        ]
11486    },
11487    "series-area-stacked": {
11488        "requires": [
11489            "series-stacked",
11490            "series-area"
11491        ]
11492    },
11493    "series-areaspline": {
11494        "requires": [
11495            "series-area",
11496            "series-curve-util"
11497        ]
11498    },
11499    "series-areaspline-stacked": {
11500        "requires": [
11501            "series-stacked",
11502            "series-areaspline"
11503        ]
11504    },
11505    "series-bar": {
11506        "requires": [
11507            "series-marker",
11508            "series-histogram-base"
11509        ]
11510    },
11511    "series-bar-stacked": {
11512        "requires": [
11513            "series-stacked",
11514            "series-bar"
11515        ]
11516    },
11517    "series-base": {
11518        "requires": [
11519            "graphics",
11520            "axis-base"
11521        ]
11522    },
11523    "series-candlestick": {
11524        "requires": [
11525            "series-range"
11526        ]
11527    },
11528    "series-cartesian": {
11529        "requires": [
11530            "series-base"
11531        ]
11532    },
11533    "series-column": {
11534        "requires": [
11535            "series-marker",
11536            "series-histogram-base"
11537        ]
11538    },
11539    "series-column-stacked": {
11540        "requires": [
11541            "series-stacked",
11542            "series-column"
11543        ]
11544    },
11545    "series-combo": {
11546        "requires": [
11547            "series-cartesian",
11548            "series-line-util",
11549            "series-plot-util",
11550            "series-fill-util"
11551        ]
11552    },
11553    "series-combo-stacked": {
11554        "requires": [
11555            "series-stacked",
11556            "series-combo"
11557        ]
11558    },
11559    "series-combospline": {
11560        "requires": [
11561            "series-combo",
11562            "series-curve-util"
11563        ]
11564    },
11565    "series-combospline-stacked": {
11566        "requires": [
11567            "series-combo-stacked",
11568            "series-curve-util"
11569        ]
11570    },
11571    "series-curve-util": {},
11572    "series-fill-util": {},
11573    "series-histogram-base": {
11574        "requires": [
11575            "series-cartesian",
11576            "series-plot-util"
11577        ]
11578    },
11579    "series-line": {
11580        "requires": [
11581            "series-cartesian",
11582            "series-line-util"
11583        ]
11584    },
11585    "series-line-stacked": {
11586        "requires": [
11587            "series-stacked",
11588            "series-line"
11589        ]
11590    },
11591    "series-line-util": {},
11592    "series-marker": {
11593        "requires": [
11594            "series-cartesian",
11595            "series-plot-util"
11596        ]
11597    },
11598    "series-marker-stacked": {
11599        "requires": [
11600            "series-stacked",
11601            "series-marker"
11602        ]
11603    },
11604    "series-ohlc": {
11605        "requires": [
11606            "series-range"
11607        ]
11608    },
11609    "series-pie": {
11610        "requires": [
11611            "series-base",
11612            "series-plot-util"
11613        ]
11614    },
11615    "series-plot-util": {},
11616    "series-range": {
11617        "requires": [
11618            "series-cartesian"
11619        ]
11620    },
11621    "series-spline": {
11622        "requires": [
11623            "series-line",
11624            "series-curve-util"
11625        ]
11626    },
11627    "series-spline-stacked": {
11628        "requires": [
11629            "series-stacked",
11630            "series-spline"
11631        ]
11632    },
11633    "series-stacked": {
11634        "requires": [
11635            "axis-stacked"
11636        ]
11637    },
11638    "shim-plugin": {
11639        "requires": [
11640            "node-style",
11641            "node-pluginhost"
11642        ]
11643    },
11644    "slider": {
11645        "use": [
11646            "slider-base",
11647            "slider-value-range",
11648            "clickable-rail",
11649            "range-slider"
11650        ]
11651    },
11652    "slider-base": {
11653        "requires": [
11654            "widget",
11655            "dd-constrain",
11656            "event-key"
11657        ],
11658        "skinnable": true
11659    },
11660    "slider-value-range": {
11661        "requires": [
11662            "slider-base"
11663        ]
11664    },
11665    "sortable": {
11666        "requires": [
11667            "dd-delegate",
11668            "dd-drop-plugin",
11669            "dd-proxy"
11670        ]
11671    },
11672    "sortable-scroll": {
11673        "requires": [
11674            "dd-scroll",
11675            "sortable"
11676        ]
11677    },
11678    "stylesheet": {
11679        "requires": [
11680            "yui-base"
11681        ]
11682    },
11683    "substitute": {
11684        "optional": [
11685            "dump"
11686        ],
11687        "requires": [
11688            "yui-base"
11689        ]
11690    },
11691    "swf": {
11692        "requires": [
11693            "event-custom",
11694            "node",
11695            "swfdetect",
11696            "escape"
11697        ]
11698    },
11699    "swfdetect": {
11700        "requires": [
11701            "yui-base"
11702        ]
11703    },
11704    "tabview": {
11705        "requires": [
11706            "widget",
11707            "widget-parent",
11708            "widget-child",
11709            "tabview-base",
11710            "node-pluginhost",
11711            "node-focusmanager"
11712        ],
11713        "skinnable": true
11714    },
11715    "tabview-base": {
11716        "requires": [
11717            "node-event-delegate",
11718            "classnamemanager"
11719        ]
11720    },
11721    "tabview-plugin": {
11722        "requires": [
11723            "tabview-base"
11724        ]
11725    },
11726    "template": {
11727        "use": [
11728            "template-base",
11729            "template-micro"
11730        ]
11731    },
11732    "template-base": {
11733        "requires": [
11734            "yui-base"
11735        ]
11736    },
11737    "template-micro": {
11738        "requires": [
11739            "escape"
11740        ]
11741    },
11742    "test": {
11743        "requires": [
11744            "event-simulate",
11745            "event-custom",
11746            "json-stringify"
11747        ]
11748    },
11749  
11749  "test-console": {
11750        "requires": [
11751            "console-filters",
11752            "test",
11753            "array-extras"
11754        ],
11755        "skinnable": true
11756    },
11757    "text": {
11758        "use": [
11759            "text-accentfold",
11760            "text-wordbreak"
11761        ]
11762    },
11763    "text-accentfold": {
11764        "requires": [
11765            "array-extras",
11766            "text-data-accentfold"
11767        ]
11768    },
11769    "text-data-accentfold": {
11770        "requires": [
11771            "yui-base"
11772        ]
11773    },
11774    "text-data-wordbreak": {
11775        "requires": [
11776            "yui-base"
11777        ]
11778    },
11779    "text-wordbreak": {
11780        "requires": [
11781            "array-extras",
11782            "text-data-wordbreak"
11783        ]
11784    },
11785    "timers": {
11786        "requires": [
11787            "yui-base"
11788        ]
11789    },
11790    "transition": {
11791        "requires": [
11792            "node-style"
11793        ]
11794    },
11795    "transition-timer": {
11796        "condition": {
11797            "name": "transition-timer",
11798            "test": function (Y) {
11799    var DOCUMENT = Y.config.doc,
11800        node = (DOCUMENT) ? DOCUMENT.documentElement: null,
11801        ret = true;
11802
11803    if (node && node.style) {
11804        ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
11805    }
11806
11807    return ret;
11808},
11809            "trigger": "transition"
11810        },
11811        "requires": [
11812            "transition"
11813        ]
11814    },
11815    "tree": {
11816        "requires": [
11817            "base-build",
11818            "tree-node"
11819        ]
11820    },
11821    "tree-labelable": {
11822        "requires": [
11823            "tree"
11824        ]
11825    },
11826    "tree-lazy": {
11827        "requires": [
11828            "base-pluginhost",
11829            "plugin",
11830            "tree"
11831        ]
11832    },
11833    "tree-node": {},
11834    "tree-openable": {
11835        "requires": [
11836            "tree"
11837        ]
11838    },
11839    "tree-selectable": {
11840        "requires": [
11841            "tree"
11842        ]
11843    },
11844    "tree-sortable": {
11845        "requires": [
11846            "tree"
11847        ]
11848    },
11849    "uploader": {
11850        "requires": [
11851            "uploader-html5",
11852            "uploader-flash"
11853        ]
11854    },
11855    "uploader-flash": {
11856        "requires": [
11857            "swfdetect",
11858            "escape",
11859            "widget",
11860            "base",
11861            "cssbutton",
11862            "node",
11863            "event-custom",
11864            "uploader-queue"
11865        ]
11866    },
11867    "uploader-html5": {
11868        "requires": [
11869            "widget",
11870            "node-event-simulate",
11871            "file-html5",
11872            "uploader-queue"
11873        ]
11874    },
11875    "uploader-queue": {
11876        "requires": [
11877            "base"
11878        ]
11879    },
11880    "view": {
11881        "requires": [
11882            "base-build",
11883            "node-event-delegate"
11884        ]
11885    },
11886    "view-node-map": {
11887        "requires": [
11888            "view"
11889        ]
11890    },
11891    "widget": {
11892        "use": [
11893            "widget-base",
11894            "widget-htmlparser",
11895            "widget-skin",
11896            "widget-uievents"
11897        ]
11898    },
11899    "widget-anim": {
11900        "requires": [
11901            "anim-base",
11902            "plugin",
11903            "widget"
11904        ]
11905    },
11906    "widget-autohide": {
11907        "requires": [
11908            "base-build",
11909            "event-key",
11910            "event-outside",
11911            "widget"
11912        ]
11913    },
11914    "widget-base": {
11915        "requires": [
11916            "attribute",
11917            "base-base",
11918            "base-pluginhost",
11919            "classnamemanager",
11920            "event-focus",
11921            "node-base",
11922            "node-style"
11923        ],
11924        "skinnable": true
11925    },
11926    "widget-base-ie": {
11927        "condition": {
11928            "name": "widget-base-ie",
11929            "trigger": "widget-base",
11930            "ua": "ie"
11931        },
11932        "requires": [
11933            "widget-base"
11934        ]
11935    },
11936    "widget-buttons": {
11937        "requires": [
11938            "button-plugin",
11939            "cssbutton",
11940            "widget-stdmod"
11941        ]
11942    },
11943    "widget-child": {
11944        "requires": [
11945            "base-build",
11946            "widget"
11947        ]
11948    },
11949    "widget-htmlparser": {
11950        "requires": [
11951            "widget-base"
11952        ]
11953    },
11954    "widget-modality": {
11955        "requires": [
11956            "base-build",
11957            "event-outside",
11958            "widget"
11959        ],
11960        "skinnable": true
11961    },
11962    "widget-parent": {
11963        "requires": [
11964            "arraylist",
11965            "base-build",
11966            "widget"
11967        ]
11968    },
11969    "widget-position": {
11970        "requires": [
11971            "base-build",
11972            "node-screen",
11973            "widget"
11974        ]
11975    },
11976    "widget-position-align": {
11977        "requires": [
11978            "widget-position"
11979        ]
11980    },
11981    "widget-position-constrain": {
11982        "requires": [
11983            "widget-position"
11984        ]
11985    },
11986    "widget-skin": {
11987        "requires": [
11988            "widget-base"
11989        ]
11990    },
11991    "widget-stack": {
11992        "requires": [
11993            "base-build",
11994            "widget"
11995        ],
11996        "skinnable": true
11997    },
11998    "widget-stdmod": {
11999        "requires": [
12000            "base-build",
12001            "widget"
12002        ]
12003    },
12004    "widget-uievents": {
12005        "requires": [
12006            "node-event-delegate",
12007            "widget-base"
12008        ]
12009    },
12010    "yql": {
12011        "requires": [
12012            "oop"
12013        ]
12014    },
12015    "yql-jsonp": {
12016        "condition": {
12017            "name": "yql-jsonp",
12018            "test": function (Y) {
12019    /* Only load the JSONP module when not in nodejs or winjs
12020    TODO Make the winjs module a CORS module
12021    */
12022    return (!Y.UA.nodejs && !Y.UA.winjs);
12023},
12024            "trigger": "yql"
12025        },
12026        "requires": [
12027            "yql",
12028            "jsonp",
12029            "jsonp-url"
12030        ]
12031    },
12032    "yql-nodejs": {
12033        "condition": {
12034            "name": "yql-nodejs",
12035            "trigger": "yql",
12036            "ua": "nodejs"
12037        },
12038        "requires": [
12039            "yql"
12040        ]
12041    },
12042    "yql-winjs": {
12043        "condition": {
12044            "name": "yql-winjs",
12045            "trigger": "yql",
12046            "ua": "winjs"
12047        },
12048        "requires": [
12049            "yql"
12050        ]
12051    },
12052    "yui": {},
12053    "yui-base": {},
12054    "yui-later": {
12055        "requires": [
12056            "yui-base"
12057        ]
12058    },
12059    "yui-log": {
12060        "requires": [
12061            "yui-base"
12062        ]
12063    },
12064    "yui-throttle": {
12065        "requires": [
12066            "yui-base"
12067        ]
12068    }
12069});
12070YUI.Env[Y.version].md5 = 'f20377d5ab6d37137f73ea79d6eb476d';
12071
12072
12073}, 'patched-v3.18.1', {"requires": ["loader-base"]});
12074YUI.add('yui', function (Y, NAME) {}, 'patched-v3.18.1', {
12075    "use": [
12076        "yui-base",
12077        "get",
12078        "features",
12079        "intl-base",
12080        "yui-log",
12081        "yui-later",
12082        "loader-base",
12083        "loader-rollup",
12084        "loader-yui3"
12085    ]
12086});
12087YUI.add('aui-base-core', function (A, NAME) {
12088
12089var Y = A;
12090YUI.Env.aliases = YUI.Env.aliases || {};
12091Y.mix(YUI.Env.aliases, {
12092    "aui-autosize": ["aui-autosize-iframe"],
12093    "aui-base": ["oop","yui-throttle","aui-classnamemanager","aui-debounce","aui-base-core","aui-base-lang","aui-node-base"],
12094    "aui-base-deprecated": ["aui-base","aui-node","aui-component","aui-delayed-task-deprecated","aui-selector","aui-event-base"],
12095    "aui-button": ["aui-button-core"],
12096    "aui-collection": ["aui-map","aui-set","aui-linkedset"],
12097    "aui-color-picker-deprecated": ["aui-color-picker-base-deprecated","aui-color-picker-grid-plugin-deprecated"],
12098    "aui-datasource-control-deprecated": ["aui-datasource-control-base-deprecated","aui-input-text-control-deprecated"],
12099    "aui-datatable": ["aui-datatable-edit","aui-datatable-highlight","aui-datatable-selection","aui-datatable-property-list"],
12100    "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"],
12101    "aui-datepicker-deprecated": ["aui-datepicker-base-deprecated","aui-datepicker-select-deprecated"],
12102    "aui-event": ["aui-event-base"],
12103    "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"],
12104    "aui-io": ["aui-io-request"],
12105    "aui-io-deprecated": ["aui-io-request","aui-io-plugin-deprecated"],
12106    "aui-node": ["aui-node-base"],
12107    "aui-overlay-deprecated": ["aui-overlay-base-deprecated","aui-overlay-context-deprecated","aui-overlay-context-panel-deprecated","aui-overlay-manager-deprecated","aui-overlay-mask-deprecated"],
12108    "aui-rating": ["aui-rating-base","aui-rating-thumb"],
12109    "aui-resize-deprecated": ["aui-resize-base-deprecated","aui-resize-constrain-deprecated"],
12110    "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"],
12111    "aui-search": ["aui-search-tst"],
12112    "aui-sortable": ["aui-sortable-layout","aui-sortable-list"],
12113    "aui-surface": ["aui-surface-app","aui-surface-screen"],
12114    "aui-toggler": ["aui-toggler-base","aui-toggler-delegate"],
12115    "aui-tooltip": ["aui-tooltip-base","aui-tooltip-delegate"],
12116    "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"],
12117    "aui-tree": ["aui-tree-data","aui-tree-io","aui-tree-node","aui-tree-paginator","aui-tree-view"],
12118    "aui-widget": ["aui-widget-cssclass","aui-widget-toolbars"],
12119    "aui-widget-core": ["aui-widget-cssclass"]
12120});
12121/* This file is auto-generated by (yogi loader --yes --mix --js js/aui-loader.js --json js/aui-loader.json --start ../) */
12122
12123/*jshint maxlen:900, eqeqeq: false */
12124
12125/**
12126 * YUI 3 module metadata
12127 * @module loader
12128 * @submodule loader-yui3
12129 */
12130YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
12131Y.mix(YUI.Env[Y.version].modules, {
12132    "aui-ace-autocomplete-base": {
12133        "requires": [
12134            "aui-ace-editor"
12135        ]
12136    },
12137    "aui-ace-autocomplete-freemarker": {
12138        "requires": [
12139            "aui-ace-autocomplete-templateprocessor"
12140        ]
12141    },
12142    "aui-ace-autocomplete-list": {
12143        "requires": [
12144            "aui-ace-autocomplete-base",
12145            "overlay",
12146            "widget-autohide"
12147        ],
12148        "skinnable": true
12149    },
12150    "aui-ace-autocomplete-plugin": {
12151        "requires": [
12152            "aui-ace-autocomplete-list",
12153            "plugin"
12154        ]
12155    },
12156    "aui-ace-autocomplete-templateprocessor": {
12157        "requires": [
12158            "aui-ace-autocomplete-base"
12159        ]
12160    },
12161    "aui-ace-autocomplete-velocity": {
12162        "requires": [
12163            "aui-ace-autocomplete-templateprocessor"
12164        ]
12165    },
12166    "aui-ace-editor": {
12167        "requires": [
12168            "aui-node",
12169            "aui-component"
12170        ]
12171    },
12172    "aui-affix": {
12173        "requires": [
12174            "base",
12175            "node-screen",
12176            "aui-node"
12177        ]
12178    },
12179    "aui-alert": {
12180        "requires": [
12181            "aui-aria",
12182            "aui-classnamemanager",
12183            "aui-widget-cssclass",
12184            "aui-widget-transition",
12185            "timers",
12186            "widget",
12187            "widget-stdmod"
12188        ],
12189        "skinnable": true
12190    },
12191    "aui-aria": {
12192        "requires": [
12193            "plugin",
12194            "aui-component"
12195        ]
12196    },
12197    "aui-aria-table-sortable": {
12198        "requires": [
12199            "aui-aria"
12200        ]
12201    },
12202    "aui-arraysort": {
12203        "requires": [
12204            "arraysort"
12205        ]
12206    },
12207    "aui-audio": {
12208        "requires": [
12209            "aui-aria",
12210            "aui-node",
12211            "aui-component",
12212            "node-event-html5",
12213            "querystring-stringify-simple"
12214        ],
12215        "skinnable": true
12216    },
12217    "aui-autocomplete-deprecated": {
12218        "requires": [
12219            "aui-base-deprecated",
12220            "aui-overlay-base-deprecated",
12221            "datasource",
12222            "dataschema",
12223            "aui-form-combobox-deprecated"
12224        ],
12225        "skinnable": true
12226    },
12227    "aui-autosize": {
12228        "use": [
12229            "aui-autosize-iframe"
12230        ]
12231    },
12232    "aui-autosize-deprecated": {
12233        "requires": [
12234            "event-valuechange",
12235            "plugin",
12236            "aui-base-deprecated"
12237        ],
12238        "skinnable": true
12239    },
12240    "aui-autosize-iframe": {
12241        "requires": [
12242            "plugin",
12243            "aui-component",
12244            "aui-timer",
12245            "aui-node-base"
12246        ]
12247    },
12248    "aui-base": {
12249        "use": [
12250            "oop",
12251            "yui-throttle",
12252            "aui-classnamemanager",
12253            "aui-debounce",
12254            "aui-base-core",
12255            "aui-base-lang",
12256            "aui-node-base"
12257        ]
12258    },
12259    "aui-base-core": {},
12260    "aui-base-deprecated": {
12261        "use": [
12262            "aui-base",
12263            "aui-node",
12264            "aui-component",
12265            "aui-delayed-task-deprecated",
12266            "aui-selector",
12267            "aui-event-base"
12268        ]
12269    },
12270    "aui-base-html5-shiv": {
12271        "condition": {
12272            "name": "aui-base-html5-shiv",
12273            "trigger": "node-base",
12274            "ua": "ie"
12275        }
12276    },
12277    "aui-base-lang": {},
12278    "aui-boolean-data-editor": {
12279        "requires": [
12280            "aui-button-switch",
12281            "aui-data-editor"
12282        ]
12283    },
12284    "aui-button": {
12285        "use": [
12286            "aui-button-core"
12287        ]
12288    },
12289    "aui-button-core": {
12290        "requires": [
12291            "button",
12292            "button-group",
12293            "button-plugin",
12294            "aui-component",
12295            "aui-widget-cssclass",
12296            "aui-widget-toggle"
12297        ],
12298        "skinnable": true
12299    },
12300    "aui-button-item-deprecated": {
12301        "requires": [
12302            "aui-base-deprecated",
12303            "aui-state-interaction-deprecated",
12304            "widget-child"
12305        ],
12306        "skinnable": true
12307    },
12308    "aui-button-search-cancel": {
12309        "requires": [
12310            "array-invoke",
12311            "base",
12312            "base-build",
12313            "event-focus",
12314            "event-move",
12315            "event-resize",
12316            "node-screen",
12317            "node-event-delegate",
12318            "aui-node-base",
12319            "aui-classnamemanager",
12320            "aui-event-input"
12321        ]
12322    },
12323    "aui-button-switch": {
12324        "requires": [
12325            "aui-node-base",
12326            "base-build",
12327            "event-key",
12328            "transition",
12329            "widget"
12330        ],
12331        "skinnable": true
12332    },
12333    "aui-carousel": {
12334        "requires": [
12335            "anim",
12336            "aui-event",
12337            "aui-image-viewer-base",
12338            "aui-image-viewer-slideshow",
12339            "node-event-delegate",
12340            "node-focusmanager"
12341        ],
12342        "skinnable": true
12343    },
12344    "aui-carousel-mobile-touch": {
12345        "condition": {
12346            "name": "aui-carousel-mobile-touch",
12347            "test": function(A) {
12348    return A.UA.mobile && A.UA.touchEnabled;
12349},
12350            "trigger": "aui-carousel"
12351        },
12352        "requires": [
12353            "base-build",
12354            "aui-carousel"
12355        ]
12356    },
12357    "aui-carousel-swipe": {
12358        "condition": {
12359            "name": "aui-carousel-swipe",
12360            "trigger": "aui-carousel",
12361            "ua": "touchEnabled"
12362        },
12363        "requires": [
12364            "aui-carousel",
12365            "aui-widget-swipe",
12366            "base-build"
12367        ],
12368        "skinnable": true
12369    },
12370    "aui-char-counter": {
12371        "requires": [
12372            "aui-aria",
12373            "aui-node",
12374            "aui-event-input",
12375            "aui-component"
12376        ]
12377    },
12378    "aui-chart-deprecated": {
12379        "requires": [
12380            "datasource",
12381            "json",
12382            "aui-swf-deprecated"
12383        ]
12384    },
12385    "aui-classnamemanager": {
12386        "requires": [
12387            "classnamemanager"
12388        ]
12389    },
12390    "aui-collection": {
12391        "use": [
12392            "aui-map",
12393            "aui-set",
12394            "aui-linkedset"
12395        ]
12396    },
12397    "aui-color-palette": {
12398        "requires": [
12399            "array-extras",
12400            "aui-palette",
12401            "color-base",
12402            "node-core",
12403            "aui-widget-cssclass",
12404            "aui-widget-toggle"
12405        ],
12406        "skinnable": true
12407    },
12408    "aui-color-picker-base": {
12409        "requires": [
12410            "aui-color-palette",
12411            "aui-hsva-palette-modal",
12412            "event-outside"
12413        ],
12414        "skinnable": true
12415    },
12416    "aui-color-picker-base-deprecated": {
12417        "requires": [
12418            "dd-drag",
12419            "panel",
12420            "slider",
12421            "aui-button-item-deprecated",
12422            "aui-color-util-deprecated",
12423            "aui-form-base-deprecated",
12424            "aui-overlay-context-deprecated"
12425        ],
12426        "skinnable": true
12427    },
12428    "aui-color-picker-deprecated": {
12429        "use": [
12430            "aui-color-picker-base-deprecated",
12431            "aui-color-picker-grid-plugin-deprecated"
12432        ]
12433    },
12434    "aui-color-picker-grid-plugin-deprecated": {
12435        "requires": [
12436            "plugin",
12437            "aui-color-picker-base-deprecated"
12438        ],
12439        "skinnable": true
12440    },
12441    "aui-color-picker-popover": {
12442        "requires": [
12443            "aui-color-picker-base",
12444            "aui-popover",
12445            "aui-widget-cssclass",
12446            "aui-widget-toggle"
12447        ],
12448        "skinnable": true
12449    },
12450    "aui-color-util-deprecated": {
12451        "requires": []
12452    },
12453    "aui-component": {
12454        "requires": [
12455            "aui-classnamemanager",
12456            "aui-widget-cssclass",
12457            "aui-widget-toggle",
12458            "base-build",
12459            "widget-base"
12460        ]
12461    },
12462    "aui-css": {
12463        "type": "css"
12464    },
12465    "aui-data-editor": {
12466        "requires": [
12467            "aui-classnamemanager",
12468            "base-build",
12469            "node-base"
12470        ],
12471        "skinnable": true
12472    },
12473    "aui-data-set-deprecated": {
12474        "requires": [
12475            "oop",
12476            "collection",
12477            "base"
12478        ]
12479    },
12480    "aui-datasource-control-base-deprecated": {
12481        "requires": [
12482            "datasource",
12483            "dataschema",
12484            "aui-base-deprecated"
12485        ]
12486    },
12487    "aui-datasource-control-deprecated": {
12488        "use": [
12489            "aui-datasource-control-base-deprecated",
12490            "aui-input-text-control-deprecated"
12491        ]
12492    },
12493    "aui-datatable": {
12494        "use": [
12495            "aui-datatable-edit",
12496            "aui-datatable-highlight",
12497            "aui-datatable-selection",
12498            "aui-datatable-property-list"
12499        ]
12500    },
12501    "aui-datatable-base-cell-editor": {
12502        "requires": [
12503            "datatable-base",
12504            "overlay"
12505        ],
12506        "skinnable": true
12507    },
12508    "aui-datatable-base-options-cell-editor": {
12509        "requires": [
12510            "aui-datatable-base-cell-editor",
12511            "escape"
12512        ],
12513        "skinnable": true
12514    },
12515    "aui-datatable-body": {
12516        "requires": [
12517            "aui-classnamemanager",
12518            "datatable-base",
12519            "event-key",
12520            "aui-event-base"
12521        ]
12522    },
12523    "aui-datatable-cell-editor-support": {
12524        "requires": [
12525            "datatable-base"
12526        ]
12527    },
12528    "aui-datatable-checkbox-cell-editor": {
12529        "requires": [
12530            "aui-datatable-base-options-cell-editor"
12531        ]
12532    },
12533    "aui-datatable-core": {
12534        "requires": [
12535            "aui-datatable-body",
12536            "datatable-base",
12537            "event-key",
12538            "aui-event-base"
12539        ],
12540        "skinnable": true
12541    },
12542    "aui-datatable-date-cell-editor": {
12543        "requires": [
12544            "aui-datatable-base-options-cell-editor"
12545        ]
12546    },
12547    "aui-datatable-dropdown-cell-editor": {
12548        "requires": [
12549            "aui-datatable-base-options-cell-editor"
12550        ]
12551    },
12552    "aui-datatable-edit": {
12553        "use": [
12554            "datatable-base",
12555            "calendar",
12556            "overlay",
12557            "sortable",
12558            "aui-datatype",
12559            "aui-toolbar",
12560            "aui-form-validator",
12561            "aui-datatable-base-cell-editor",
12562            "aui-datatable-base-options-cell-editor",
12563            "aui-datatable-cell-editor-support",
12564            "aui-datatable-core",
12565            "aui-datatable-checkbox-cell-editor",
12566            "aui-datatable-date-cell-editor",
12567            "aui-datatable-dropdown-cell-editor",
12568            "aui-datatable-radio-cell-editor",
12569            "aui-datatable-text-cell-editor",
12570            "aui-datatable-text-area-cell-editor"
12571        ]
12572    },
12573    "aui-datatable-highlight": {
12574        "requires": [
12575            "aui-datatable-selection"
12576        ],
12577        "skinnable": true
12578    },
12579    "aui-datatable-property-list": {
12580        "requires": [
12581            "datatable-scroll",
12582            "datatable-sort",
12583            "aui-datatable-core",
12584            "aui-datatable-edit",
12585            "aui-datatable-highlight",
12586            "aui-datatable-selection",
12587            "aui-widget-cssclass",
12588            "aui-widget-toggle"
12589        ],
12590        "skinnable": true
12591    },
12592    "aui-datatable-radio-cell-editor": {
12593        "requires": [
12594            "aui-datatable-base-options-cell-editor"
12595        ]
12596    },
12597    "aui-datatable-selection": {
12598        "requires": [
12599            "aui-datatable-core"
12600        ],
12601        "skinnable": true
12602    },
12603    "aui-datatable-text-area-cell-editor": {
12604        "requires": [
12605            "aui-datatable-base-options-cell-editor"
12606        ]
12607    },
12608    "aui-datatable-text-cell-editor": {
12609        "requires": [
12610            "aui-datatable-base-options-cell-editor"
12611        ]
12612    },
12613    "aui-datatype": {
12614        "requires": [
12615            "datatype",
12616            "aui-datatype-date-parse"
12617        ]
12618    },
12619    "aui-datatype-date-parse": {
12620        "requires": [
12621            "aui-base-lang",
12622            "datatype-date-format",
12623            "datatype-date-parse",
12624            "intl"
12625        ]
12626    },
12627    "aui-datepicker": {
12628        "requires": [
12629            "aui-aria",
12630            "aui-datepicker-delegate",
12631            "aui-datepicker-popover",
12632            "base",
12633            "base-build",
12634            "calendar"
12635        ],
12636        "skinnable": true
12637    },
12638    "aui-datepicker-base-deprecated": {
12639        "requires": [
12640            "calendar",
12641            "aui-datatype",
12642            "aui-overlay-context-deprecated"
12643        ],
12644        "skinnable": true
12645    },
12646    "aui-datepicker-delegate": {
12647        "requires": [
12648            "aui-datatype-date-parse",
12649            "aui-event-input",
12650            "event-focus",
12651            "node-event-delegate"
12652        ]
12653    },
12654    "aui-datepicker-deprecated": {
12655        "skinnable": true,
12656        "use": [
12657            "aui-datepicker-base-deprecated",
12658            "aui-datepicker-select-deprecated"
12659        ]
12660    },
12661    "aui-datepicker-native": {
12662        "requires": [
12663            "aui-datepicker-delegate",
12664            "aui-node-base",
12665            "base",
12666            "base-build"
12667        ]
12668    },
12669    "aui-datepicker-popover": {
12670        "requires": [
12671            "aui-classnamemanager",
12672            "aui-popover"
12673        ]
12674    },
12675    "aui-datepicker-select-deprecated": {
12676        "requires": [
12677            "aui-datepicker-base-deprecated",
12678            "aui-button-item-deprecated"
12679        ],
12680        "skinnable": true
12681    },
12682    "aui-debounce": {},
12683    "aui-delayed-task-deprecated": {
12684        "requires": [
12685            "yui-base"
12686        ]
12687    },
12688    "aui-diagram-builder": {
12689        "requires": [
12690            "aui-aria",
12691            "aui-map",
12692            "aui-property-builder",
12693            "aui-diagram-builder-connector",
12694            "aui-property-builder-settings",
12695            "aui-diagram-node-condition",
12696            "aui-diagram-node-end",
12697            "aui-diagram-node-fork",
12698            "aui-diagram-node-join",
12699            "aui-diagram-node-start",
12700            "aui-diagram-node-state",
12701            "aui-diagram-node-task",
12702            "overlay"
12703        ],
12704        "skinnable": true
12705    },
12706    "aui-diagram-builder-connector": {
12707        "requires": [
12708            "arraylist-add",
12709            "arraylist-filter",
12710            "escape",
12711            "json",
12712            "graphics",
12713            "dd"
12714        ],
12715        "skinnable": true
12716    },
12717    "aui-diagram-node": {
12718        "requires": [
12719            "aui-aria",
12720            "aui-diagram-node-manager-base",
12721            "escape",
12722            "overlay"
12723        ]
12724    },
12725    "aui-diagram-node-condition": {
12726        "requires": [
12727            "aui-diagram-node-state"
12728        ]
12729    },
12730    "aui-diagram-node-end": {
12731        "requires": [
12732            "aui-diagram-node-state"
12733        ]
12734    },
12735    "aui-diagram-node-fork": {
12736        "requires": [
12737            "aui-diagram-node-state"
12738        ]
12739    },
12740    "aui-diagram-node-join": {
12741        "requires": [
12742            "aui-diagram-node-state"
12743        ]
12744    },
12745    "aui-diagram-node-manager-base": {
12746        "requires": [
12747            "base"
12748        ]
12749    },
12750    "aui-diagram-node-start": {
12751        "requires": [
12752            "aui-diagram-node-state"
12753        ]
12754    },
12755    "aui-diagram-node-state": {
12756        "requires": [
12757            "aui-diagram-node"
12758        ]
12759    },
12760    "aui-diagram-node-task": {
12761        "requires": [
12762            "aui-diagram-node-state"
12763        ]
12764    },
12765    "aui-dialog-iframe-deprecated": {
12766        "requires": [
12767            "plugin",
12768            "array-invoke",
12769            "aui-base-deprecated",
12770            "aui-loading-mask-deprecated"
12771        ],
12772        "skinnable": true
12773    },
12774    "aui-dropdown": {
12775        "requires": [
12776            "event-delegate",
12777            "event-key",
12778            "event-outside",
12779            "node-focusmanager",
12780            "widget",
12781            "widget-stack",
12782            "aui-classnamemanager",
12783            "aui-node",
12784            "aui-widget-cssclass",
12785            "aui-widget-toggle",
12786            "aui-widget-trigger"
12787        ],
12788        "skinnable": true
12789    },
12790    "aui-editable-deprecated": {
12791        "requires": [
12792            "aui-base-deprecated",
12793            "aui-form-combobox-deprecated",
12794            "escape",
12795            "event-resize"
12796        ],
12797        "skinnable": true
12798    },
12799    "aui-event": {
12800        "use": [
12801            "aui-event-base"
12802        ]
12803    },
12804    "aui-event-base": {
12805        "requires": [
12806            "event-base"
12807        ]
12808    },
12809    "aui-event-delegate-change": {
12810        "condition": {
12811            "name": "aui-event-delegate-change",
12812            "trigger": "event-base-ie",
12813            "ua": "ie"
12814        },
12815        "requires": [
12816            "aui-event-base",
12817            "event-delegate",
12818            "event-synthetic"
12819        ]
12820    },
12821    "aui-event-delegate-submit": {
12822        "condition": {
12823            "name": "aui-event-delegate-submit",
12824            "trigger": "event-base-ie",
12825            "ua": "ie"
12826        },
12827        "requires": [
12828            "aui-event-base",
12829            "event-delegate",
12830            "event-synthetic"
12831        ]
12832    },
12833    "aui-event-input": {
12834        "condition": {
12835            "name": "aui-event-input",
12836            "test": function(A) {
12837    var supportsDOMEvent = A.supportsDOMEvent,
12838        testFeature = A.Features.test,
12839        addFeature = A.Features.add;
12840
12841    if (testFeature('event', 'input') === undefined) {
12842        addFeature('event', 'input', {
12843            test: function() {
12844                return supportsDOMEvent(document.createElement('textarea'), 'input') && (!A.UA.ie || A.UA.ie > 9);
12845            }
12846        });
12847    }
12848
12849    return !testFeature('event', 'input');
12850},
12851            "trigger": "aui-event-base"
12852        },
12853        "requires": [
12854            "aui-event-base",
12855            "event-delegate",
12856            "event-synthetic",
12857            "timers"
12858        ]
12859    },
12860    "aui-form-base-deprecated": {
12861        "requires": [
12862            "io-form",
12863            "querystring-parse",
12864            "aui-base-deprecated",
12865            "aui-data-set-deprecated",
12866            "aui-form-field-deprecated"
12867        ]
12868    },
12869    "aui-form-builder": {
12870        "requires": [
12871            "aui-modal",
12872            "aui-layout",
12873            "aui-form-builder-field-list",
12874            "aui-form-builder-field-toolbar",
12875            "aui-form-builder-field-type",
12876            "aui-form-builder-field-types",
12877            "aui-form-builder-layout-builder",
12878            "aui-form-builder-page-manager",
12879            "aui-form-builder-settings-modal",
12880            "event-focus",
12881            "event-tap"
12882        ],
12883        "skinnable": true
12884    },
12885    "aui-form-builder-available-field-deprecated": {
12886        "requires": [
12887            "aui-property-builder-available-field"
12888        ]
12889    },
12890    "aui-form-builder-deprecated": {
12891        "requires": [
12892            "aui-button",
12893            "aui-collection",
12894            "aui-form-builder-available-field-deprecated",
12895            "aui-form-builder-field-deprecated",
12896            "aui-form-builder-field-button-deprecated",
12897            "aui-form-builder-field-checkbox-deprecated",
12898            "aui-form-builder-field-fieldset-deprecated",
12899            "aui-form-builder-field-file-upload-deprecated",
12900            "aui-form-builder-field-multiple-choice-deprecated",
12901            "aui-form-builder-field-radio-deprecated",
12902            "aui-form-builder-field-select-deprecated",
12903            "aui-form-builder-field-text-deprecated",
12904            "aui-form-builder-field-textarea-deprecated",
12905            "aui-property-builder",
12906            "aui-property-builder-settings",
12907            "aui-sortable-list",
12908            "aui-tabview",
12909            "aui-tooltip-base",
12910            "escape",
12911            "transition"
12912        ],
12913        "skinnable": true
12914    },
12915    "aui-form-builder-field-base": {
12916        "requires": [
12917            "aui-classnamemanager",
12918            "aui-node-base",
12919            "aui-text-data-editor",
12920            "aui-toggler",
12921            "base",
12922            "node-base"
12923        ],
12924        "skinnable": true
12925    },
12926    "aui-form-builder-field-button-deprecated": {
12927        "requires": [
12928            "aui-form-builder-field-deprecated"
12929        ]
12930    },
12931    "aui-form-builder-field-checkbox-deprecated": {
12932        "requires": [
12933            "aui-form-builder-field-deprecated"
12934        ]
12935    },
12936    "aui-form-builder-field-choice": {
12937        "requires": [
12938            "aui-boolean-data-editor",
12939            "aui-options-data-editor",
12940            "aui-tabs-data-editor",
12941            "aui-form-builder-field-base",
12942            "aui-form-field-choice"
12943        ]
12944    },
12945    "aui-form-builder-field-deprecated": {
12946        "requires": [
12947            "panel",
12948            "aui-datatype",
12949            "aui-datatable-edit",
12950            "aui-property-builder-field-support"
12951        ],
12952        "skinnable": true
12953    },
12954    "aui-form-builder-field-fieldset-deprecated": {
12955        "requires": [
12956            "aui-form-builder-field-deprecated"
12957        ]
12958    },
12959    "aui-form-builder-field-file-upload-deprecated": {
12960        "requires": [
12961            "aui-form-builder-field-deprecated"
12962        ]
12963    },
12964    "aui-form-builder-field-list": {
12965        "requires": [
12966            "aui-form-builder-field-type",
12967            "aui-form-builder-field-types",
12968            "aui-form-builder-layout-builder"
12969        ],
12970        "skinnable": true
12971    },
12972    "aui-form-builder-field-multiple-choice-deprecated": {
12973        "requires": [
12974            "aui-form-builder-field-deprecated"
12975        ]
12976    },
12977    "aui-form-builder-field-radio-deprecated": {
12978        "requires": [
12979            "aui-form-builder-field-deprecated"
12980        ]
12981    },
12982    "aui-form-builder-field-select-deprecated": {
12983        "requires": [
12984            "aui-form-builder-field-deprecated"
12985        ]
12986    },
12987    "aui-form-builder-field-sentence": {
12988        "requires": [
12989            "aui-form-builder-field-base",
12990            "aui-form-field"
12991        ]
12992    },
12993    "aui-form-builder-field-text": {
12994        "requires": [
12995            "aui-boolean-data-editor",
12996            "aui-radio-group-data-editor",
12997            "aui-form-builder-field-base",
12998            "aui-form-field-text"
12999        ]
13000    },
13001    "aui-form-builder-field-text-deprecated": {
13002        "requires": [
13003            "aui-form-builder-field-deprecated"
13004        ]
13005    },
13006    "aui-form-builder-field-textarea-deprecated": {
13007        "requires": [
13008            "aui-form-builder-field-deprecated"
13009        ]
13010    },
13011    "aui-form-builder-field-toolbar": {
13012        "requires": [
13013            "aui-classnamemanager",
13014            "base",
13015            "node-base"
13016        ],
13017        "skinnable": true
13018    },
13019    "aui-form-builder-field-type": {
13020        "requires": [
13021            "base",
13022            "node-base"
13023        ],
13024        "skinnable": true
13025    },
13026    "aui-form-builder-field-types": {
13027        "requires": [
13028            "aui-classnamemanager",
13029            "aui-form-builder-field-types-modal",
13030            "base",
13031            "node-base"
13032        ],
13033        "skinnable": true
13034    },
13035    "aui-form-builder-field-types-modal": {
13036        "requires": [
13037            "aui-modal"
13038        ],
13039        "skinnable": true
13040    },
13041    "aui-form-builder-layout-builder": {
13042        "requires": [
13043            "aui-classnamemanager",
13044            "aui-layout-builder",
13045            "aui-modal",
13046            "base",
13047            "node-base"
13048        ],
13049        "skinnable": true
13050    },
13051    "aui-form-builder-page-manager": {
13052        "requires": [
13053            "aui-pagination",
13054            "aui-popover",
13055            "aui-tabview",
13056            "base",
13057            "event-valuechange",
13058            "node-base"
13059        ],
13060        "skinnable": true
13061    },
13062    "aui-form-builder-settings-modal": {
13063        "requires": [
13064            "aui-classnamemanager",
13065            "aui-modal",
13066            "base",
13067            "node-base"
13068        ],
13069        "skinnable": true
13070    },
13071    "aui-form-combobox-deprecated": {
13072        "requires": [
13073            "aui-form-textarea-deprecated",
13074            "aui-toolbar"
13075        ],
13076        "skinnable": true
13077    },
13078    "aui-form-deprecated": {
13079        "use": [
13080            "aui-form-base-deprecated",
13081            "aui-form-combobox-deprecated",
13082            "aui-form-field-deprecated",
13083            "aui-form-select-deprecated",
13084            "aui-form-textarea-deprecated",
13085            "aui-form-textfield-deprecated"
13086        ]
13087    },
13088    "aui-form-field": {
13089        "requires": [
13090            "aui-classnamemanager",
13091            "aui-node-base",
13092            "base-build"
13093        ],
13094        "skinnable": true
13095    },
13096    "aui-form-field-choice": {
13097        "requires": [
13098            "aui-form-field-required"
13099        ],
13100        "skinnable": true
13101    },
13102    "aui-form-field-deprecated": {
13103        "requires": [
13104            "aui-base-deprecated",
13105            "aui-component"
13106        ]
13107    },
13108    "aui-form-field-required": {
13109        "requires": [
13110            "aui-form-field"
13111        ]
13112    },
13113    "aui-form-field-text": {
13114        "requires": [
13115            "aui-form-field-required"
13116        ],
13117        "skinnable": true
13118    },
13119    "aui-form-select-deprecated": {
13120        "requires": [
13121            "aui-form-field-deprecated"
13122        ]
13123    },
13124    "aui-form-textarea-deprecated": {
13125        "requires": [
13126            "node-pluginhost",
13127            "aui-autosize-deprecated",
13128            "aui-form-textfield-deprecated"
13129        ]
13130    },
13131    "aui-form-textfield-deprecated": {
13132        "requires": [
13133            "aui-form-field-deprecated"
13134        ]
13135    },
13136    "aui-form-validator": {
13137        "requires": [
13138            "escape",
13139            "selector-css3",
13140            "node-event-delegate",
13141            "aui-node",
13142            "aui-component",
13143            "aui-event-input"
13144        ]
13145    },
13146    "aui-hsv-palette": {
13147        "requires": [
13148            "aui-classnamemanager",
13149            "aui-widget-cssclass",
13150            "aui-widget-toggle",
13151            "aui-event-input",
13152            "base-build",
13153            "clickable-rail",
13154            "color-hsv",
13155            "dd-constrain",
13156            "slider",
13157            "widget"
13158        ],
13159        "skinnable": true
13160    },
13161    "aui-hsva-palette": {
13162        "requires": [
13163            "aui-hsv-palette"
13164        ],
13165        "skinnable": true
13166    },
13167    "aui-hsva-palette-modal": {
13168        "requires": [
13169            "aui-hsva-palette",
13170            "aui-modal"
13171        ],
13172        "skinnable": true
13173    },
13174    "aui-image-cropper": {
13175        "requires": [
13176            "resize-base",
13177            "resize-constrain",
13178            "dd-constrain",
13179            "aui-node-base",
13180            "aui-component"
13181        ],
13182        "skinnable": true
13183    },
13184    "aui-image-viewer": {
13185        "requires": [
13186            "widget",
13187            "widget-modality",
13188            "widget-position",
13189            "widget-position-align",
13190            "widget-position-constrain",
13191            "widget-stack",
13192            "widget-stdmod",
13193            "aui-event",
13194            "aui-image-viewer-base",
13195            "aui-image-viewer-multiple",
13196            "aui-image-viewer-slideshow",
13197            "aui-node-base",
13198            "aui-widget-cssclass",
13199            "aui-widget-toggle"
13200        ],
13201        "skinnable": true
13202    },
13203    "aui-image-viewer-base": {
13204        "requires": [
13205            "anim",
13206            "aui-aria",
13207            "aui-classnamemanager",
13208            "aui-node",
13209            "aui-widget-responsive",
13210            "base-build",
13211            "imageloader",
13212            "node-base",
13213            "widget",
13214            "widget-stack"
13215        ],
13216        "skinnable": true
13217    },
13218    "aui-image-viewer-media": {
13219        "requires": [
13220            "plugin",
13221            "aui-component",
13222            "aui-image-viewer"
13223        ]
13224    },
13225    "aui-image-viewer-multiple": {
13226        "requires": [
13227            "base-build",
13228            "node-base",
13229            "aui-classnamemanager",
13230            "aui-image-viewer-base"
13231        ],
13232        "skinnable": true
13233    },
13234    "aui-image-viewer-multiple-swipe": {
13235        "condition": {
13236            "name": "aui-image-viewer-multiple-swipe",
13237            "trigger": "aui-image-viewer-multiple",
13238            "ua": "touchEnabled"
13239        },
13240        "requires": [
13241            "aui-image-viewer-multiple",
13242            "aui-image-viewer-swipe"
13243        ]
13244    },
13245    "aui-image-viewer-slideshow": {
13246        "requires": [
13247            "node",
13248            "aui-classnamemanager"
13249        ]
13250    },
13251    "aui-image-viewer-swipe": {
13252        "condition": {
13253            "name": "aui-image-viewer-swipe",
13254            "trigger": "aui-image-viewer-base",
13255            "ua": "touchEnabled"
13256        },
13257        "requires": [
13258            "event-resize",
13259            "aui-image-viewer-base",
13260            "aui-widget-swipe"
13261        ]
13262    },
13263    "aui-input-text-control-deprecated": {
13264        "requires": [
13265            "aui-base-deprecated",
13266            "aui-datasource-control-base-deprecated",
13267            "aui-form-combobox-deprecated"
13268        ]
13269    },
13270    "aui-io": {
13271        "use": [
13272            "aui-io-request"
13273        ]
13274    },
13275    "aui-io-deprecated": {
13276        "use": [
13277            "aui-io-request",
13278            "aui-io-plugin-deprecated"
13279        ]
13280    },
13281    "aui-io-plugin-deprecated": {
13282        "requires": [
13283            "aui-overlay-base-deprecated",
13284            "aui-parse-content",
13285            "aui-io-request",
13286            "aui-loading-mask-deprecated"
13287        ]
13288    },
13289    "aui-io-request": {
13290        "requires": [
13291            "io-base",
13292            "json",
13293            "plugin",
13294            "querystring-stringify",
13295            "aui-component"
13296        ]
13297    },
13298    "aui-io-request-deprecated": {
13299        "requires": [
13300            "io-base",
13301            "json",
13302            "plugin",
13303            "querystring-stringify",
13304            "aui-base-deprecated"
13305        ]
13306    },
13307    "aui-layout": {
13308        "requires": [
13309            "aui-layout-col",
13310            "aui-layout-row",
13311            "aui-node-base",
13312            "base-build",
13313            "datatype-number-parse",
13314            "event-resize"
13315        ]
13316    },
13317    "aui-layout-builder": {
13318        "requires": [
13319            "aui-classnamemanager",
13320            "aui-layout",
13321            "aui-layout-builder-add-col",
13322            "aui-layout-builder-add-row",
13323            "aui-layout-builder-move",
13324            "aui-layout-builder-remove-row",
13325            "aui-layout-builder-resize-col",
13326            "aui-node-base",
13327            "base-build",
13328            "node-event-delegate",
13329            "node-screen",
13330            "node-style"
13331        ]
13332    },
13333    "aui-layout-builder-add-col": {
13334        "requires": [
13335            "event-key",
13336            "node-base"
13337        ],
13338        "skinnable": true
13339    },
13340    "aui-layout-builder-add-row": {
13341        "requires": [
13342            "aui-node-base",
13343            "base-build",
13344            "node-scroll-info"
13345        ],
13346        "skinnable": true
13347    },
13348    "aui-layout-builder-move": {
13349        "requires": [
13350            "aui-node-base",
13351            "base-build"
13352        ],
13353        "skinnable": true
13354    },
13355    "aui-layout-builder-remove-row": {
13356        "requires": [
13357            "aui-node-base",
13358            "base-build"
13359        ],
13360        "skinnable": true
13361    },
13362    "aui-layout-builder-resize-col": {
13363        "requires": [
13364            "dd-constrain",
13365            "dd-delegate",
13366            "dd-drop-plugin",
13367            "dd-proxy",
13368            "event-mouseenter",
13369            "node-base"
13370        ],
13371        "skinnable": true
13372    },
13373    "aui-layout-col": {
13374        "requires": [
13375            "aui-classnamemanager",
13376            "aui-node-base",
13377            "base-build"
13378        ],
13379        "skinnable": true
13380    },
13381    "aui-layout-row": {
13382        "requires": [
13383            "array-invoke",
13384            "aui-node-base",
13385            "base-build"
13386        ],
13387        "skinnable": true
13388    },
13389    "aui-linkedset": {
13390        "requires": [
13391            "aui-set"
13392        ]
13393    },
13394    "aui-live-search-deprecated": {
13395        "requires": [
13396            "aui-base-deprecated"
13397        ]
13398    },
13399    "aui-loading-mask-deprecated": {
13400        "requires": [
13401            "plugin",
13402            "aui-overlay-mask-deprecated"
13403        ],
13404        "skinnable": true
13405    },
13406    "aui-map": {
13407        "requires": [
13408            "base-build"
13409        ]
13410    },
13411    "aui-menu": {
13412        "requires": [
13413            "base-build",
13414            "event-mouseenter",
13415            "event-resize",
13416            "widget",
13417            "widget-position",
13418            "widget-position-align",
13419            "widget-position-constrain",
13420            "widget-stack",
13421            "aui-classnamemanager",
13422            "aui-debounce",
13423            "aui-dropdown",
13424            "aui-menu-item"
13425        ],
13426        "skinnable": true
13427    },
13428    "aui-menu-item": {
13429        "requires": [
13430            "base-build",
13431            "node-base",
13432            "aui-classnamemanager",
13433            "aui-node",
13434            "aui-widget-shortcut"
13435        ]
13436    },
13437    "aui-messaging": {
13438        "requires": [
13439            "querystring",
13440            "aui-timer"
13441        ]
13442    },
13443    "aui-modal": {
13444        "requires": [
13445            "widget",
13446            "widget-autohide",
13447            "widget-buttons",
13448            "widget-modality",
13449            "widget-position",
13450            "widget-position-align",
13451            "widget-position-constrain",
13452            "widget-stack",
13453            "widget-stdmod",
13454            "dd-plugin",
13455            "dd-constrain",
13456            "timers",
13457            "aui-classnamemanager",
13458            "aui-widget-cssclass",
13459            "aui-widget-toggle",
13460            "aui-widget-toolbars"
13461        ],
13462        "skinnable": true
13463    },
13464    "aui-modal-resize": {
13465        "condition": {
13466            "name": "aui-modal-resize",
13467            "test": function(A) {
13468    return !A.UA.mobile;
13469},
13470            "trigger": "aui-modal"
13471        },
13472        "requires": [
13473            "aui-modal",
13474            "resize-plugin"
13475        ]
13476    },
13477    "aui-node": {
13478        "use": [
13479            "aui-node-base"
13480        ]
13481    },
13482    "aui-node-accessible": {
13483        "requires": [
13484            "aui-node-base",
13485            "event-custom-base"
13486        ]
13487    },
13488    "aui-node-base": {
13489        "requires": [
13490            "array-extras",
13491            "aui-base-lang",
13492            "aui-classnamemanager",
13493            "aui-debounce",
13494            "node"
13495        ]
13496    },
13497    "aui-node-html5": {
13498        "condition": {
13499            "name": "aui-node-html5",
13500            "trigger": "aui-node",
13501            "ua": "ie"
13502        },
13503        "requires": [
13504            "collection",
13505            "aui-node-base"
13506        ]
13507    },
13508    "aui-options-data-editor": {
13509        "requires": [
13510            "aui-data-editor",
13511            "dd-constrain",
13512            "dd-delegate",
13513            "dd-drop-plugin",
13514            "dd-proxy",
13515            "event-valuechange",
13516            "node-event-delegate"
13517        ],
13518        "skinnable": true
13519    },
13520    "aui-overlay-base-deprecated": {
13521        "requires": [
13522            "widget-position",
13523            "widget-stack",
13524            "widget-position-align",
13525            "widget-position-constrain",
13526            "widget-stdmod",
13527            "aui-component"
13528        ]
13529    },
13530    "aui-overlay-context-deprecated": {
13531        "requires": [
13532            "aui-overlay-manager-deprecated",
13533            "aui-delayed-task-deprecated",
13534            "aui-aria"
13535        ]
13536    },
13537    "aui-overlay-context-panel-deprecated": {
13538        "requires": [
13539            "anim",
13540            "aui-overlay-context-deprecated"
13541        ],
13542        "skinnable": true
13543    },
13544    "aui-overlay-deprecated": {
13545        "use": [
13546            "aui-overlay-base-deprecated",
13547            "aui-overlay-context-deprecated",
13548            "aui-overlay-context-panel-deprecated",
13549            "aui-overlay-manager-deprecated",
13550            "aui-overlay-mask-deprecated"
13551        ]
13552    },
13553    "aui-overlay-manager-deprecated": {
13554        "requires": [
13555            "overlay",
13556            "plugin",
13557            "aui-base-deprecated",
13558            "aui-overlay-base-deprecated"
13559        ]
13560    },
13561    "aui-overlay-mask-deprecated": {
13562        "requires": [
13563            "event-resize",
13564            "aui-base-deprecated",
13565            "aui-overlay-base-deprecated"
13566        ],
13567        "skinnable": true
13568    },
13569    "aui-pagination": {
13570        "requires": [
13571            "node-event-delegate",
13572            "aui-node",
13573            "aui-component",
13574            "widget-htmlparser"
13575        ],
13576        "skinnable": true
13577    },
13578    "aui-palette": {
13579        "requires": [
13580            "base-build",
13581            "event-hover",
13582            "widget",
13583            "aui-classnamemanager",
13584            "aui-base",
13585            "aui-widget-cssclass",
13586            "aui-widget-toggle"
13587        ],
13588        "skinnable": true
13589    },
13590    "aui-parse-content": {
13591        "requires": [
13592            "async-queue",
13593            "plugin",
13594            "io-base",
13595            "aui-component",
13596            "aui-node-base"
13597        ]
13598    },
13599    "aui-popover": {
13600        "requires": [
13601            "event-resize",
13602            "widget",
13603            "widget-autohide",
13604            "widget-buttons",
13605            "widget-modality",
13606            "widget-position",
13607            "widget-position-align",
13608            "widget-position-constrain",
13609            "widget-stack",
13610            "widget-stdmod",
13611            "aui-classnamemanager",
13612            "aui-widget-cssclass",
13613            "aui-widget-toggle",
13614            "aui-widget-toolbars",
13615            "aui-widget-transition",
13616            "aui-widget-trigger",
13617            "aui-widget-position-align-suggestion",
13618            "aui-component",
13619            "aui-node-base"
13620        ],
13621        "skinnable": true
13622    },
13623    "aui-progressbar": {
13624        "requires": [
13625            "aui-node",
13626            "aui-component",
13627            "aui-aria"
13628        ],
13629        "skinnable": true
13630    },
13631    "aui-promise": {
13632        "requires": [
13633            "array-invoke",
13634            "promise",
13635            "oop"
13636        ]
13637    },
13638    "aui-property-builder": {
13639        "requires": [
13640            "dd",
13641            "collection",
13642            "aui-property-builder-available-field",
13643            "aui-property-builder-field-support",
13644            "aui-property-builder-settings",
13645            "aui-tabview"
13646        ],
13647        "skinnable": true
13648    },
13649    "aui-property-builder-available-field": {
13650        "requires": [
13651            "base",
13652            "aui-component",
13653            "aui-node"
13654        ]
13655    },
13656    "aui-property-builder-field-support": {},
13657    "aui-property-builder-settings": {
13658        "requires": [
13659            "aui-tabview",
13660            "aui-datatable-property-list"
13661        ]
13662    },
13663    "aui-radio-group-data-editor": {
13664        "requires": [
13665            "aui-data-editor",
13666            "node-event-delegate"
13667        ],
13668        "skinnable": true
13669    },
13670    "aui-rating": {
13671        "use": [
13672            "aui-rating-base",
13673            "aui-rating-thumb"
13674        ]
13675    },
13676    "aui-rating-base": {
13677        "requires": [
13678            "aui-component",
13679            "aui-node-base",
13680            "widget-htmlparser",
13681            "widget-uievents"
13682        ],
13683        "skinnable": true
13684    },
13685    "aui-rating-thumb": {
13686        "requires": [
13687            "aui-rating-base"
13688        ]
13689    },
13690    "aui-resize-base-deprecated": {
13691        "requires": [
13692            "dd-drag",
13693            "dd-delegate",
13694            "dd-drop",
13695            "aui-base-deprecated"
13696        ],
13697        "skinnable": true
13698    },
13699    "aui-resize-constrain-deprecated": {
13700        "requires": [
13701            "dd-constrain",
13702            "plugin",
13703            "aui-resize-base-deprecated"
13704        ]
13705    },
13706    "aui-resize-deprecated": {
13707        "skinnable": true,
13708        "use": [
13709            "aui-resize-base-deprecated",
13710            "aui-resize-constrain-deprecated"
13711        ]
13712    },
13713    "aui-scale-data-editor": {
13714        "requires": [
13715            "aui-classnamemanager",
13716            "aui-data-editor",
13717            "event-valuechange"
13718        ]
13719    },
13720    "aui-scheduler": {
13721        "use": [
13722            "event-gestures",
13723            "aui-scheduler-base",
13724            "aui-scheduler-event-recorder",
13725            "aui-scheduler-view-agenda",
13726            "aui-scheduler-view-day",
13727            "aui-scheduler-view-month",
13728            "aui-scheduler-view-table-dd",
13729            "aui-scheduler-view-table",
13730            "aui-scheduler-view-week",
13731            "aui-viewport"
13732        ]
13733    },
13734    "aui-scheduler-base": {
13735        "requires": [
13736            "model",
13737            "model-list",
13738            "widget-stdmod",
13739            "color-hsl",
13740            "aui-event-base",
13741            "aui-node-base",
13742            "aui-component",
13743            "aui-datatype",
13744            "aui-button",
13745            "node-focusmanager"
13746        ],
13747        "skinnable": true
13748    },
13749    "aui-scheduler-event-recorder": {
13750        "requires": [
13751            "querystring",
13752            "io-form",
13753            "overlay",
13754            "aui-scheduler-base",
13755            "aui-popover"
13756        ],
13757        "skinnable": true
13758    },
13759    "aui-scheduler-touch": {
13760        "condition": {
13761            "name": "aui-scheduler-touch",
13762            "trigger": "aui-scheduler",
13763            "ua": "touchEnabled"
13764        },
13765        "requires": [
13766            "base-build",
13767            "aui-scheduler"
13768        ],
13769        "skinnable": true
13770    },
13771    "aui-scheduler-view-agenda": {
13772        "requires": [
13773            "aui-scheduler-base"
13774        ],
13775        "skinnable": true
13776    },
13777    "aui-scheduler-view-day": {
13778        "requires": [
13779            "dd-drag",
13780            "dd-delegate",
13781            "dd-drop",
13782            "dd-constrain",
13783            "aui-scheduler-view-table"
13784        ],
13785        "skinnable": true
13786    },
13787    "aui-scheduler-view-month": {
13788        "requires": [
13789            "aui-scheduler-view-table"
13790        ],
13791        "skinnable": true
13792    },
13793    "aui-scheduler-view-table": {
13794        "requires": [
13795            "overlay",
13796            "aui-scheduler-base"
13797        ],
13798        "skinnable": true
13799    },
13800    "aui-scheduler-view-table-dd": {
13801        "requires": [
13802            "dd-drag",
13803            "dd-delegate",
13804            "dd-drop",
13805            "aui-scheduler-view-table"
13806        ]
13807    },
13808    "aui-scheduler-view-week": {
13809        "requires": [
13810            "aui-scheduler-view-day"
13811        ],
13812        "skinnable": true
13813    },
13814    "aui-scroller-deprecated": {
13815        "requires": [
13816            "event-mouseenter",
13817            "aui-base-deprecated",
13818            "aui-simple-anim-deprecated"
13819        ],
13820        "skinnable": true
13821    },
13822    "aui-scrollspy": {
13823        "requires": [
13824            "base-build",
13825            "node-screen",
13826            "aui-classnamemanager"
13827        ]
13828    },
13829    "aui-search": {
13830        "use": [
13831            "aui-search-tst"
13832        ]
13833    },
13834    "aui-search-tst": {
13835        "requires": [
13836            "aui-component"
13837        ]
13838    },
13839    "aui-selector": {
13840        "requires": [
13841            "selector-css3",
13842            "aui-classnamemanager"
13843        ]
13844    },
13845    "aui-set": {
13846        "requires": [
13847            "aui-map"
13848        ]
13849    },
13850    "aui-simple-anim-deprecated": {
13851        "requires": [
13852            "aui-base-deprecated"
13853        ]
13854    },
13855    "aui-skin-deprecated": {
13856        "type": "css"
13857    },
13858    "aui-sortable": {
13859        "use": [
13860            "aui-sortable-layout",
13861            "aui-sortable-list"
13862        ]
13863    },
13864    "aui-sortable-layout": {
13865        "requires": [
13866            "dd-delegate",
13867            "dd-drag",
13868            "dd-drop",
13869            "dd-proxy",
13870            "aui-node",
13871            "aui-component"
13872        ],
13873        "skinnable": true
13874    },
13875    "aui-sortable-list": {
13876        "requires": [
13877            "dd-drag",
13878            "dd-drop",
13879            "dd-proxy",
13880            "dd-scroll",
13881            "aui-node",
13882            "aui-component"
13883        ]
13884    },
13885    "aui-state-interaction-deprecated": {
13886        "requires": [
13887            "aui-base-deprecated",
13888            "plugin"
13889        ]
13890    },
13891    "aui-surface": {
13892        "use": [
13893            "aui-surface-app",
13894            "aui-surface-screen"
13895        ]
13896    },
13897    "aui-surface-app": {
13898        "requires": [
13899            "event-delegate",
13900            "node-event-html5",
13901            "aui-surface-base",
13902            "aui-surface-screen",
13903            "aui-surface-screen-route"
13904        ]
13905    },
13906    "aui-surface-base": {
13907        "requires": [
13908            "base-build",
13909            "node-style",
13910            "timers",
13911            "aui-debounce",
13912            "aui-promise",
13913            "aui-parse-content"
13914        ]
13915    },
13916    "aui-surface-screen": {
13917        "requires": [
13918            "base-build"
13919        ]
13920    },
13921    "aui-surface-screen-html": {
13922        "requires": [
13923            "aui-base",
13924            "aui-io-request",
13925            "aui-promise",
13926         
13926   "aui-surface-screen",
13927            "aui-url"
13928        ]
13929    },
13930    "aui-surface-screen-route": {
13931        "requires": [
13932            "base-build"
13933        ]
13934    },
13935    "aui-swf-deprecated": {
13936        "requires": [
13937            "querystring-parse-simple",
13938            "querystring-stringify-simple",
13939            "aui-base-deprecated"
13940        ]
13941    },
13942    "aui-tabs-data-editor": {
13943        "requires": [
13944            "aui-data-editor",
13945            "aui-tabview"
13946        ]
13947    },
13948    "aui-tabview": {
13949        "requires": [
13950            "selector-css3",
13951            "tabview",
13952            "aui-component",
13953            "aui-widget-css"
13954        ],
13955        "skinnable": true
13956    },
13957    "aui-template-deprecated": {
13958        "requires": [
13959            "aui-base-deprecated"
13960        ]
13961    },
13962    "aui-text-data-editor": {
13963        "requires": [
13964            "aui-data-editor",
13965            "event-valuechange"
13966        ],
13967        "skinnable": true
13968    },
13969    "aui-text-data-unicode": {
13970        "requires": [
13971            "text"
13972        ]
13973    },
13974    "aui-text-unicode": {
13975        "requires": [
13976            "aui-text-data-unicode"
13977        ]
13978    },
13979    "aui-textboxlist-deprecated": {
13980        "requires": [
13981            "anim-node-plugin",
13982            "aui-autocomplete-deprecated",
13983            "aui-button-item-deprecated",
13984            "aui-data-set-deprecated",
13985            "escape",
13986            "node-focusmanager"
13987        ],
13988        "skinnable": true
13989    },
13990    "aui-timepicker": {
13991        "requires": [
13992            "autocomplete",
13993            "aui-datepicker-delegate",
13994            "aui-datepicker-popover"
13995        ],
13996        "skinnable": true
13997    },
13998    "aui-timepicker-native": {
13999        "requires": [
14000            "base",
14001            "base-build",
14002            "aui-node-base",
14003            "aui-datepicker-delegate",
14004            "aui-datepicker-native"
14005        ]
14006    },
14007    "aui-timer": {
14008        "requires": [
14009            "oop"
14010        ]
14011    },
14012    "aui-toggler": {
14013        "use": [
14014            "aui-toggler-base",
14015            "aui-toggler-delegate"
14016        ]
14017    },
14018    "aui-toggler-accessibility": {
14019        "requires": [
14020            "aui-toggler-base"
14021        ]
14022    },
14023    "aui-toggler-base": {
14024        "requires": [
14025            "transition",
14026            "aui-selector",
14027            "aui-event-base",
14028            "aui-node",
14029            "aui-component",
14030            "event-tap"
14031        ],
14032        "skinnable": true
14033    },
14034    "aui-toggler-delegate": {
14035        "requires": [
14036            "array-invoke",
14037            "node-event-delegate",
14038            "aui-toggler-base"
14039        ]
14040    },
14041    "aui-toolbar": {
14042        "requires": [
14043            "arraylist",
14044            "arraylist-add",
14045            "aui-component",
14046            "aui-button-core"
14047        ]
14048    },
14049    "aui-tooltip": {
14050        "use": [
14051            "aui-tooltip-base",
14052            "aui-tooltip-delegate"
14053        ]
14054    },
14055    "aui-tooltip-base": {
14056        "requires": [
14057            "aui-aria",
14058            "aui-classnamemanager",
14059            "aui-component",
14060            "aui-debounce",
14061            "aui-node-base",
14062            "aui-widget-cssclass",
14063            "aui-widget-toggle",
14064            "aui-widget-transition",
14065            "aui-widget-trigger",
14066            "aui-widget-position-align-suggestion",
14067            "event-hover",
14068            "event-resize",
14069            "escape",
14070            "widget",
14071            "widget-autohide",
14072            "widget-position",
14073            "widget-position-align",
14074            "widget-position-constrain",
14075            "widget-stack",
14076            "widget-stdmod"
14077        ],
14078        "skinnable": true
14079    },
14080    "aui-tooltip-delegate": {
14081        "requires": [
14082            "aui-tooltip-base",
14083            "node-event-delegate"
14084        ]
14085    },
14086    "aui-tooltip-deprecated": {
14087        "requires": [
14088            "aui-overlay-context-panel-deprecated"
14089        ],
14090        "skinnable": true
14091    },
14092    "aui-tpl-snippets-base-deprecated": {
14093        "requires": [
14094            "aui-template-deprecated"
14095        ]
14096    },
14097    "aui-tpl-snippets-checkbox-deprecated": {
14098        "requires": [
14099            "aui-tpl-snippets-base-deprecated"
14100        ]
14101    },
14102    "aui-tpl-snippets-deprecated": {
14103        "use": [
14104            "aui-tpl-snippets-base-deprecated",
14105            "aui-tpl-snippets-checkbox-deprecated",
14106            "aui-tpl-snippets-input-deprecated",
14107            "aui-tpl-snippets-select-deprecated",
14108            "aui-tpl-snippets-textarea-deprecated"
14109        ]
14110    },
14111    "aui-tpl-snippets-input-deprecated": {
14112        "requires": [
14113            "aui-tpl-snippets-base-deprecated"
14114        ]
14115    },
14116    "aui-tpl-snippets-select-deprecated": {
14117        "requires": [
14118            "aui-tpl-snippets-base-deprecated"
14119        ]
14120    },
14121    "aui-tpl-snippets-textarea-deprecated": {
14122        "requires": [
14123            "aui-tpl-snippets-base-deprecated"
14124        ]
14125    },
14126    "aui-tree": {
14127        "use": [
14128            "aui-tree-data",
14129            "aui-tree-io",
14130            "aui-tree-node",
14131            "aui-tree-paginator",
14132            "aui-tree-view"
14133        ]
14134    },
14135    "aui-tree-data": {
14136        "requires": [
14137            "aui-base-core",
14138            "aui-base-lang",
14139            "aui-node-base",
14140            "aui-timer",
14141            "aui-component"
14142        ]
14143    },
14144    "aui-tree-io": {
14145        "requires": [
14146            "aui-component",
14147            "aui-io"
14148        ]
14149    },
14150    "aui-tree-node": {
14151        "requires": [
14152            "json",
14153            "querystring-stringify",
14154            "aui-tree-data",
14155            "aui-tree-io",
14156            "aui-tree-paginator",
14157            "event-key"
14158        ]
14159    },
14160    "aui-tree-paginator": {
14161        "requires": [
14162            "yui-base"
14163        ]
14164    },
14165    "aui-tree-view": {
14166        "requires": [
14167            "dd-delegate",
14168            "dd-proxy",
14169            "widget",
14170            "aui-tree-node",
14171            "aui-tree-paginator",
14172            "aui-tree-io"
14173        ],
14174        "skinnable": true
14175    },
14176    "aui-undo-redo": {
14177        "requires": [
14178            "aui-base",
14179            "base",
14180            "base-build",
14181            "event-key",
14182            "promise"
14183        ]
14184    },
14185    "aui-url": {
14186        "requires": [
14187            "oop",
14188            "querystring-parse",
14189            "querystring-stringify"
14190        ]
14191    },
14192    "aui-video": {
14193        "requires": [
14194            "event-resize",
14195            "node-event-html5",
14196            "querystring-stringify-simple",
14197            "aui-aria",
14198            "aui-node",
14199            "aui-component",
14200            "aui-debounce"
14201        ],
14202        "skinnable": true
14203    },
14204    "aui-viewport": {
14205        "requires": [
14206            "aui-node",
14207            "aui-component"
14208        ]
14209    },
14210    "aui-widget": {
14211        "use": [
14212            "aui-widget-cssclass",
14213            "aui-widget-toolbars"
14214        ]
14215    },
14216    "aui-widget-core": {
14217        "use": [
14218            "aui-widget-cssclass"
14219        ]
14220    },
14221    "aui-widget-cssclass": {
14222        "requires": [
14223            "widget-base"
14224        ]
14225    },
14226    "aui-widget-position-align-suggestion": {
14227        "requires": [
14228            "widget-position-align",
14229            "widget-stdmod"
14230        ]
14231    },
14232    "aui-widget-responsive": {
14233        "requires": [
14234            "event-resize",
14235            "widget-base"
14236        ]
14237    },
14238    "aui-widget-shortcut": {
14239        "requires": [
14240            "base"
14241        ]
14242    },
14243    "aui-widget-swipe": {
14244        "requires": [
14245            "classnamemanager",
14246            "scrollview-base",
14247            "scrollview-paginator",
14248            "timers"
14249        ]
14250    },
14251    "aui-widget-toggle": {},
14252    "aui-widget-toolbars": {
14253        "requires": [
14254            "widget-stdmod",
14255            "aui-toolbar"
14256        ]
14257    },
14258    "aui-widget-transition": {
14259        "requires": [
14260            "transition"
14261        ]
14262    },
14263    "aui-widget-trigger": {
14264        "requires": [
14265            "node"
14266        ]
14267    }
14268});
14269YUI.Env[Y.version].md5 = 'd7c627eb00edd6b6f054d8f6e7147480';
14270/*
14271 * Alloy JavaScript Library
14272 * http://alloy.liferay.com/
14273 *
14274 * Copyright (c) 2010 Liferay Inc.
14275 * http://alloy.liferay.com/LICENSE.txt
14276 *
14277 * Nate Cavanaugh ([email protected])
14278 * Eduardo Lundgren ([email protected])
14279 *
14280 * Attribution/Third-party licenses
14281 * http://alloy.liferay.com/ATTRIBUTION.txt
14282 */
14283
14284// Simple version of
14285// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
14286
14287A.UA.edge = (function() {
14288    var edgeVersion = A.UA.userAgent.match(/Edge\/(.[0-9.]+)/);
14289
14290    if (edgeVersion) {
14291        return edgeVersion[1];
14292    }
14293
14294    return 0;
14295})();
14296
14297A.supportsDOMEvent = function(domNode, eventName) {
14298    eventName = 'on' + eventName;
14299
14300    if (!(eventName in domNode)) {
14301        if (!domNode.setAttribute) {
14302            domNode = A.config.doc.createElement('div');
14303        }
14304
14305        if (domNode.setAttribute) {
14306            domNode.setAttribute(eventName, '');
14307            return (typeof domNode[eventName] === 'function');
14308        }
14309    }
14310
14311    domNode = null;
14312
14313    return true;
14314};
14315(function() {
14316    var slice = Array.prototype.slice;
14317
14318    YUI.prototype.ready = function() {
14319        var instance = this,
14320            xargs = arguments,
14321            index = xargs.length - 1,
14322            modules = slice.call(arguments, 0, index);
14323
14324        modules.unshift('event-base');
14325        modules.push(function(instance) {
14326            var args = arguments;
14327
14328            instance.on('domready', function() {
14329                xargs[index].apply(this, args);
14330            });
14331        });
14332        instance.use.apply(instance, modules);
14333    };
14334}());
14335
14336
14337}, '3.1.0-deprecated.70');
14338YUI.add('aui', function (A, NAME) {}, '3.1.0-deprecated.70');
14339YUI.Env.core.push.apply(YUI.Env.core, ["aui-base-core"]);
14340YUI.add('aui-base-html5-shiv', function (A, NAME) {
14341
14342A.HTML5_ELEMENTS = [
14343    'abbr',
14344    'article',
14345    'aside',
14346    'audio',
14347    'canvas',
14348    'command',
14349    'datalist',
14350    'details',
14351    'figure',
14352    'figcaption',
14353    'footer',
14354    'header',
14355    'hgroup',
14356    'keygen',
14357    'mark',
14358    'meter',
14359    'nav',
14360    'output',
14361    'progress',
14362    'section',
14363    'source',
14364    'summary',
14365    'time',
14366    'video'
14367];
14368
14369A.html5shiv = function(frag) {
14370    var DOC = frag || A.config.doc;
14371
14372    if (A.UA.ie && DOC && DOC.createElement) {
14373        var elements = A.HTML5_ELEMENTS,
14374            length = elements.length;
14375
14376        while (length--) {
14377            DOC.createElement(elements[length]);
14378        }
14379    }
14380
14381    return frag;
14382};
14383
14384
14385}, '3.1.0-deprecated.70');
14386
14387function _typeof(obj) { 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); }
14388
14389/**
14390 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
14391 *
14392 * This library is free software; you can redistribute it and/or modify it under
14393 * the terms of the GNU Lesser General Public License as published by the Free
14394 * Software Foundation; either version 2.1 of the License, or (at your option)
14395 * any later version.
14396 *
14397 * This library is distributed in the hope that it will be useful, but WITHOUT
14398 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14399 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14400 * details.
14401 */
14402YUI.add('liferay-browser-selectors', function (A) {
14403  var REGEX_VERSION_DOT = /\./g;
14404  var YUI3_JS_ENABLED = 'yui3-js-enabled';
14405
14406  var parseVersionNumber = function parseVersionNumber(str) {
14407    var count = 0;
14408    return parseFloat(str.replace(REGEX_VERSION_DOT, function () {
14409      return count++ == 1 ? '' : '.';
14410    }));
14411  };
14412
14413  var DEFAULTS_VERSION = ['0', '0'];
14414
14415  var getVersion = function getVersion(regex, userAgent) {
14416    var version = (userAgent.match(regex) || DEFAULTS_VERSION)[1];
14417    return parseVersionNumber(version);
14418  };
14419
14420  var BROWSERS = ['ie', 'opera', 'chrome', 'edge', 'aol', 'camino', 'firefox', 'flock', 'mozilla', 'netscape', 'icab', 'konqueror', 'safari'];
14421  var MAP_OS_SELECTORS = {
14422    macintosh: 'mac',
14423    windows: 'win'
14424  };
14425  var nav = navigator;
14426  var CONFIG = A.config;
14427  var DOC = CONFIG.doc;
14428  var userAgent = nav.userAgent;
14429  var UA = A.UA;
14430  var OS = UA.os;
14431  var UAX = {
14432    agent: userAgent,
14433    aol: 0,
14434    browser: 0,
14435    camino: 0,
14436    firefox: 0,
14437    flock: 0,
14438    icab: 0,
14439    konqueror: 0,
14440    mozilla: 0,
14441    netscape: 0,
14442    safari: 0
14443  };
14444  UAX.mac = OS == 'macintosh';
14445  UAX.rhino = OS == 'rhino';
14446  UAX.win = OS == 'windows';
14447  var BrowserSelectors = {
14448    getSelectors: function getSelectors() {
14449      // The methods in this if block only run once across all instances
14450      if (!UA.selectors) {
14451        if (userAgent.indexOf('Edge') !== -1) {
14452          UAX.edge = getVersion(/Edge\/([^\s]*)/, userAgent);
14453        }
14454
14455        if (UA.ie) {
14456          UAX.aol = getVersion(/America Online Browser ([^\s]*);/, userAgent);
14457          var docMode = DOC.documentMode;
14458
14459          if (docMode) {
14460            UA.browser = UA.ie;
14461            UA.ie = docMode;
14462          }
14463        } else if (UA.gecko) {
14464          UAX.netscape = getVersion(/(Netscape|Navigator)\/([^\s]*)/, userAgent);
14465          UAX.flock = getVersion(/Flock\/([^\s]*)/, userAgent);
14466          UAX.camino = getVersion(/Camino\/([^\s]*)/, userAgent);
14467          UAX.firefox = getVersion(/Firefox\/([^\s]*)/, userAgent);
14468        } else if (UA.webkit) {
14469          UAX.safari = getVersion(/Version\/([^\s]*) Safari/, userAgent);
14470        } else {
14471          UAX.icab = getVersion(/iCab(?:\/|\s)?([^\s]*)/, userAgent);
14472          UAX.konqueror = getVersion(/Konqueror\/([^\s]*)/, userAgent);
14473        }
14474
14475        if (!UAX.win && !UAX.mac) {
14476          var linux = /Linux/.test(userAgent);
14477          var sun = /Solaris|SunOS/.test(userAgent);
14478
14479          if (linux) {
14480            UA.os = 'linux';
14481            UAX.linux = linux;
14482          } else if (sun) {
14483            UA.os = 'sun';
14484            UAX.sun = sun;
14485          }
14486        }
14487
14488        var touch = UA.touchEnabled;
14489        UAX.touch = touch;
14490        UAX.touchMobile = touch && !!UA.mobile;
14491        A.mix(UA, UAX);
14492        var browserList = [];
14493        var versionMajor = 0;
14494        var browser;
14495        var uaVersionMajor;
14496        var uaVersionMinor;
14497        var version;
14498        var versionObj = {
14499          major: versionMajor,
14500          string: ''
14501        };
14502        var i = BROWSERS.length;
14503
14504        while (i--) {
14505          browser = BROWSERS[i];
14506          version = UA[browser];
14507
14508          if (version > 0) {
14509            versionMajor = parseInt(version, 10);
14510            uaVersionMajor = browser + versionMajor;
14511            uaVersionMinor = browser + version;
14512
14513            if (String(version).indexOf('.') > -1) {
14514              uaVersionMinor = uaVersionMinor.replace(/\.(\d).*/, '-$1');
14515            } else {
14516              uaVersionMinor += '-0';
14517            }
14518
14519            browserList.push(browser, uaVersionMajor, uaVersionMinor);
14520            versionObj.string = browser + '';
14521            versionObj.major = versionMajor;
14522          }
14523        }
14524
14525        UA.version = versionObj;
14526        UA.renderer = '';
14527
14528        if (UA.ie) {
14529          UA.renderer = 'trident';
14530        } else if (UA.edge) {
14531          UA.renderer = 'edgeHTML';
14532        } else if (UA.gecko) {
14533          UA.renderer = 'gecko';
14534        } else if (UA.webkit) {
14535          UA.renderer = 'webkit';
14536        } else if (UA.opera) {
14537          UA.renderer = 'presto';
14538        }
14539
14540        A.UA = UA;
14541        /*
14542         * Browser selectors
14543         */
14544
14545        var selectors = [UA.renderer, 'js'].concat(browserList);
14546        var osSelector = MAP_OS_SELECTORS[UA.os] || UA.os;
14547        selectors.push(osSelector);
14548
14549        if (UA.mobile) {
14550          selectors.push('mobile');
14551        }
14552
14553        if (UA.secure) {
14554          selectors.push('secure');
14555        }
14556
14557        if (UA.touch) {
14558          selectors.push('touch');
14559        }
14560
14561        UA.selectors = selectors.join(' ');
14562        var svg;
14563        var vml;
14564        vml = !(svg = !!(CONFIG.win.SVGAngle || DOC.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1')));
14565
14566        if (vml) {
14567          var behaviorObj;
14568          var div = DOC.createElement('div');
14569          div.innerHTML = '<v:shape adj="1"/>';
14570          behaviorObj = div.firstChild;
14571          behaviorObj.style.behavior = 'url(#default#VML)';
14572
14573          if (!(behaviorObj && _typeof(behaviorObj.adj) == 'object')) {
14574            vml = false;
14575          }
14576
14577          div = null;
14578        }
14579
14580        YUI._VML = vml;
14581        YUI._SVG = svg;
14582        UA.vml = YUI._VML;
14583        UA.svg = YUI._SVG;
14584      }
14585
14586      return UA.selectors;
14587    },
14588    run: function run() {
14589      var documentElement = DOC.documentElement;
14590      var selectors = this.getSelectors();
14591      UA.dir = documentElement.getAttribute('dir') || 'ltr';
14592
14593      if (documentElement.className.indexOf(UA.dir) === -1) {
14594        selectors += ' ' + UA.dir;
14595      }
14596
14597      if (documentElement.className.indexOf(YUI3_JS_ENABLED) === -1 && selectors.indexOf(YUI3_JS_ENABLED) === -1) {
14598        selectors += ' ' + YUI3_JS_ENABLED;
14599      }
14600
14601      documentElement.className += ' ' + selectors;
14602    }
14603  };
14604  Liferay.BrowserSelectors = BrowserSelectors;
14605}, '', {
14606  requires: ['yui-base']
14607});
14608//# sourceMappingURL=browser_selectors.js.map
14609/**
14610 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
14611 *
14612 * This library is free software; you can redistribute it and/or modify it under
14613 * the terms of the GNU Lesser General Public License as published by the Free
14614 * Software Foundation; either version 2.1 of the License, or (at your option)
14615 * any later version.
14616 *
14617 * This library is distributed in the hope that it will be useful, but WITHOUT
14618 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14619 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14620 * details.
14621 */
14622(function () {
14623  var LiferayAUI = Liferay.AUI;
14624  var COMBINE = LiferayAUI.getCombine();
14625  var CORE_MODULES = YUI.Env.core;
14626  var INPUT_EL = document.createElement('input');
14627  var PATH_EDITOR_CKEDITOR = LiferayAUI.getEditorCKEditorPath();
14628  var PATH_JAVASCRIPT = LiferayAUI.getJavaScriptRootPath();
14629  var SUPPORTS_INPUT_SELECTION = typeof INPUT_EL.selectionStart === 'number' && typeof INPUT_EL.selectionEnd === 'number';
14630
14631  var testHistory = function testHistory(A) {
14632    var WIN = A.config.win;
14633    var HISTORY = WIN.history;
14634    return HISTORY && HISTORY.pushState && HISTORY.replaceState && ('onpopstate' in WIN || A.UA.gecko >= 2);
14635  };
14636
14637  window.YUI_config = {
14638    base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/aui/',
14639    combine: COMBINE,
14640    comboBase: LiferayAUI.getComboPath(),
14641    filter: Liferay.AUI.getFilter(),
14642    groups: {
14643      editor: {
14644        base: PATH_EDITOR_CKEDITOR,
14645        combine: COMBINE,
14646        modules: {
14647          'inline-editor-ckeditor': {
14648            path: 'ckeditor/main.js'
14649          }
14650        },
14651        root: PATH_EDITOR_CKEDITOR
14652      },
14653      liferay: {
14654        base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/liferay/',
14655        combine: COMBINE,
14656        filter: Liferay.AUI.getFilterConfig(),
14657        modules: {
14658          'liferay-address': {
14659            path: 'address.js',
14660            requires: []
14661          },
14662          'liferay-alert': {
14663            path: 'alert.js',
14664            requires: ['aui-alert', 'aui-component', 'event-mouseenter', 'liferay-portlet-base', 'timers']
14665          },
14666          'liferay-asset-addon-entry-selector': {
14667            path: 'asset_addon_entry_selector.js',
14668            requires: ['aui-component', 'liferay-portlet-base', 'liferay-util-window']
14669          },
14670          'liferay-asset-categories-selector': {
14671            path: 'asset_categories_selector.js',
14672            requires: ['aui-tree', 'liferay-asset-tags-selector']
14673          },
14674          'liferay-asset-tags-selector': {
14675            path: 'asset_tags_selector.js',
14676            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']
14677          },
14678          'liferay-auto-fields': {
14679            path: 'auto_fields.js',
14680            requires: ['aui-base', 'aui-data-set-deprecated', 'aui-parse-content', 'base', 'liferay-undo-manager', 'sortable']
14681          },
14682          'liferay-autocomplete-input': {
14683            path: 'autocomplete_input.js',
14684            requires: ['aui-base', 'autocomplete', 'autocomplete-filters', 'autocomplete-highlighters']
14685          },
14686          'liferay-autocomplete-input-caretindex': {
14687            condition: {
14688              name: 'liferay-autocomplete-input-caretindex',
14689              test: function test() {
14690                return SUPPORTS_INPUT_SELECTION;
14691              },
14692              trigger: 'liferay-autocomplete-textarea'
14693            },
14694            path: 'autocomplete_input_caretindex.js',
14695            requires: ['liferay-autocomplete-textarea']
14696          },
14697          'liferay-autocomplete-input-caretindex-sel': {
14698            condition: {
14699              name: 'liferay-autocomplete-input-caretindex-sel',
14700              test: function test() {
14701                return !SUPPORTS_INPUT_SELECTION;
14702              },
14703              trigger: 'liferay-autocomplete-textarea'
14704            },
14705            path: 'autocomplete_input_caretindex_sel.js',
14706            requires: ['liferay-autocomplete-textarea']
14707          },
14708          'liferay-autocomplete-input-caretoffset': {
14709            condition: {
14710              name: 'liferay-autocomplete-input-caretoffset',
14711              test: function test(A) {
14712                return !(A.UA.ie && A.UA.ie < 9);
14713              },
14714              trigger: 'liferay-autocomplete-textarea'
14715            },
14716            path: 'autocomplete_input_caretoffset.js',
14717            requires: ['liferay-autocomplete-textarea']
14718          },
14719          'liferay-autocomplete-input-caretoffset-sel': {
14720            condition: {
14721              name: 'liferay-autocomplete-input-caretoffset-sel',
14722              test: function test(A) {
14723                return A.UA.ie && A.UA.ie < 9;
14724              },
14725              trigger: 'liferay-autocomplete-textarea'
14726            },
14727            path: 'autocomplete_input_caretoffset_sel.js',
14728            requires: ['liferay-autocomplete-textarea']
14729          },
14730          'liferay-autocomplete-textarea': {
14731            path: 'autocomplete_textarea.js',
14732            requires: ['liferay-autocomplete-input']
14733          },
14734          'liferay-browser-selectors': {
14735            path: 'browser_selectors.js',
14736            requires: ['yui-base']
14737          },
14738          'liferay-cover-cropper': {
14739            path: 'cover_cropper.js',
14740            requires: ['aui-base', 'dd-constrain', 'dd-drag', 'plugin']
14741          },
14742          'liferay-crop-region': {
14743            path: 'crop_region.js',
14744            requires: ['aui-base']
14745          },
14746          'liferay-dd-proxy': {
14747            path: 'dd_proxy.js',
14748            requires: ['dd-proxy']
14749          },
14750          'liferay-dynamic-select': {
14751            path: 'dynamic_select.js',
14752            requires: ['aui-base']
14753          },
14754          'liferay-form': {
14755            path: 'form.js',
14756            requires: ['aui-base', 'aui-form-validator']
14757          },
14758          'liferay-form-placeholders': {
14759            condition: {
14760              name: 'liferay-form-placeholders',
14761              test: function test() {
14762                return !('placeholder' in INPUT_EL);
14763              },
14764              trigger: 'liferay-form'
14765            },
14766            path: 'form_placeholders.js',
14767            requires: ['liferay-form', 'plugin']
14768          },
14769          'liferay-fullscreen-source-editor': {
14770            path: 'fullscreen_source_editor.js',
14771            requires: ['liferay-source-editor']
14772          },
14773          'liferay-history': {
14774            path: 'history.js',
14775            requires: ['history-hash', 'querystring-parse-simple']
14776          },
14777          'liferay-history-html5': {
14778            condition: {
14779              name: 'liferay-history-html5',
14780              test: testHistory,
14781              trigger: 'liferay-history'
14782            },
14783            path: 'history_html5.js',
14784            requires: ['history-html5', 'liferay-history', 'querystring-stringify-simple']
14785          },
14786          'liferay-history-manager': {
14787            path: 'history_manager.js',
14788            requires: ['liferay-history']
14789          },
14790          'liferay-hudcrumbs': {
14791            path: 'hudcrumbs.js',
14792            requires: ['aui-base', 'aui-debounce', 'event-resize']
14793          },
14794          'liferay-icon': {
14795            path: 'icon.js',
14796            requires: ['aui-base']
14797          },
14798          'liferay-inline-editor-base': {
14799            path: 'inline_editor_base.js',
14800            requires: ['aui-base', 'aui-overlay-base-deprecated']
14801          },
14802          'liferay-input-localized': {
14803            path: 'input_localized.js',
14804            requires: ['aui-base', 'aui-component', 'aui-event-input', 'aui-palette', 'aui-set', 'portal-available-languages']
14805          },
14806          'liferay-input-move-boxes': {
14807            path: 'input_move_boxes.js',
14808            plugins: {
14809              'liferay-input-move-boxes-touch': {
14810                condition: {
14811                  name: 'liferay-input-move-boxes-touch',
14812                  trigger: 'liferay-input-move-boxes',
14813                  ua: 'touchMobile'
14814                }
14815              }
14816            },
14817            requires: ['aui-base', 'aui-toolbar']
14818          },
14819          'liferay-input-move-boxes-touch': {
14820            path: 'input_move_boxes_touch.js',
14821            requires: ['aui-base', 'aui-template-deprecated', 'liferay-input-move-boxes', 'sortable']
14822          },
14823          'liferay-item-selector-dialog': {
14824            path: 'item_selector_dialog.js',
14825            requires: ['aui-component']
14826          },
14827          'liferay-item-selector-repository-entry-browser': {
14828            path: 'item_selector_repository_entry_browser.js',
14829            requires: ['liferay-item-selector-uploader', 'liferay-item-viewer', 'liferay-notice', 'liferay-portlet-base']
14830          },
14831          'liferay-item-selector-uploader': {
14832            path: 'item_selector_uploader.js',
14833            requires: ['aui-base', 'aui-progressbar', 'liferay-portlet-base', 'uploader']
14834          },
14835          'liferay-item-selector-url': {
14836            path: 'item_selector_url.js',
14837            requires: ['aui-event-input', 'liferay-item-viewer', 'liferay-portlet-base']
14838          },
14839          'liferay-item-viewer': {
14840            path: 'item_viewer.js',
14841            requires: ['aui-component', 'aui-image-viewer', 'liferay-portlet-url']
14842          },
14843          'liferay-language': {
14844            path: 'language.js'
14845          },
14846          'liferay-layout': {
14847            path: 'layout.js'
14848          },
14849          'liferay-layout-column': {
14850            path: 'layout_column.js',
14851            requires: ['aui-sortable-layout', 'dd']
14852          },
14853          'liferay-list-view': {
14854            path: 'list_view.js',
14855            requires: ['aui-base', 'transition']
14856          },
14857          'liferay-logo-editor': {
14858            path: 'logo_editor.js',
14859            requires: ['aui-image-cropper', 'liferay-alert', 'liferay-portlet-base']
14860          },
14861          'liferay-logo-selector': {
14862            path: 'logo_selector.js',
14863            requires: ['aui-base']
14864          },
14865          'liferay-menu': {
14866            path: 'menu.js',
14867            requires: ['aui-debounce', 'aui-node']
14868          },
14869          'liferay-menu-filter': {
14870            path: 'menu_filter.js',
14871            requires: ['autocomplete-base', 'autocomplete-filters', 'autocomplete-highlighters']
14872          },
14873          'liferay-menu-toggle': {
14874            path: 'menu_toggle.js',
14875            requires: ['aui-node', 'event-outside', 'event-tap', 'liferay-menu-filter']
14876          },
14877          'liferay-message': {
14878            path: 'message.js',
14879            requires: ['aui-base']
14880          },
14881          'liferay-navigation': {
14882            path: 'navigation.js',
14883            requires: ['aui-component', 'event-mouseenter']
14884          },
14885          'liferay-navigation-interaction': {
14886            path: 'navigation_interaction.js',
14887            plugins: {
14888              'liferay-navigation-interaction-touch': {
14889                condition: {
14890                  name: 'liferay-navigation-interaction-touch',
14891                  trigger: 'liferay-navigation-interaction',
14892                  ua: 'touch'
14893                }
14894              }
14895            },
14896            requires: ['aui-base', 'aui-component', 'event-mouseenter', 'node-focusmanager', 'plugin']
14897          },
14898          'liferay-navigation-interaction-touch': {
14899            path: 'navigation_interaction_touch.js',
14900            requires: ['event-tap', 'event-touch', 'liferay-navigation-interaction']
14901          },
14902          'liferay-node': {
14903            path: 'node.js',
14904            requires: ['dom-base']
14905          },
14906          'liferay-notice': {
14907            path: 'notice.js',
14908            requires: ['aui-base', 'transition']
14909          },
14910          'liferay-notification': {
14911            path: 'notification.js',
14912            requires: ['liferay-alert']
14913          },
14914          'liferay-pagination': {
14915            path: 'pagination.js',
14916            requires: ['aui-pagination']
14917          },
14918          'liferay-panel-search': {
14919            path: 'panel_search.js',
14920            requires: ['aui-base', 'liferay-search-filter']
14921          },
14922          'liferay-poller': {
14923            path: 'poller.js',
14924            requires: ['aui-base', 'json']
14925          },
14926          'liferay-portlet-base': {
14927            path: 'portlet_base.js',
14928            requires: ['aui-base']
14929          },
14930          'liferay-portlet-url': {
14931            path: 'portlet_url.js',
14932            requires: ['aui-base']
14933          },
14934          'liferay-preview': {
14935            path: 'preview.js',
14936            requires: ['aui-base', 'aui-overlay-mask-deprecated', 'aui-toolbar', 'liferay-widget-zindex']
14937          },
14938          'liferay-progress': {
14939            path: 'progress.js',
14940            requires: ['aui-progressbar']
14941          },
14942          'liferay-ratings': {
14943            path: 'ratings.js',
14944            requires: ['aui-rating']
14945          },
14946          'liferay-resize-rtl': {
14947            condition: {
14948              test: function test() {
14949                return document.documentElement.dir === 'rtl';
14950              },
14951              trigger: 'resize-base'
14952            },
14953            path: 'resize_rtl.js'
14954          },
14955          'liferay-restore-entry': {
14956            path: 'restore_entry.js',
14957            requires: ['aui-io-plugin-deprecated', 'aui-modal', 'liferay-portlet-base']
14958          },
14959          'liferay-search-container': {
14960            path: 'search_container.js',
14961            requires: ['aui-base', 'aui-datatable-core']
14962          },
14963          'liferay-search-container-move': {
14964            path: 'search_container_move.js',
14965            requires: ['aui-component', 'dd-constrain', 'dd-delegate', 'dd-drag', 'dd-drop', 'dd-proxy', 'plugin']
14966          },
14967          'liferay-search-container-select': {
14968            path: 'search_container_select.js',
14969            requires: ['aui-component', 'aui-url', 'plugin']
14970          },
14971          'liferay-search-filter': {
14972            path: 'search_filter.js',
14973            requires: ['aui-base', 'autocomplete-base', 'autocomplete-filters']
14974          },
14975          'liferay-service-datasource': {
14976            path: 'service_datasource.js',
14977            requires: ['aui-base', 'datasource-local']
14978          },
14979          'liferay-session': {
14980            path: 'session.js',
14981            requires: ['aui-timer', 'cookie', 'liferay-notification']
14982          },
14983          'liferay-sign-in-modal': {
14984            path: 'sign_in_modal.js',
14985            requires: ['aui-base', 'aui-component', 'aui-parse-content', 'liferay-form', 'liferay-portlet-url', 'liferay-util-window', 'plugin']
14986          },
14987          'liferay-social-bookmarks': {
14988            path: 'social_bookmarks.js',
14989            requires: ['aui-component', 'aui-node']
14990          },
14991          'liferay-sortable': {
14992            path: 'sortable.js',
14993            requires: ['liferay-dd-proxy', 'sortable']
14994          },
14995          'liferay-source-editor': {
14996            path: 'source_editor.js',
14997            requires: ['aui-ace-editor']
14998          },
14999          'liferay-storage-formatter': {
15000            path: 'storage_formatter.js',
15001            requires: ['aui-base', 'datatype-number-format']
15002          },
15003          'liferay-store': {
15004            path: 'store.js'
15005          },
15006          'liferay-toggler-interaction': {
15007            path: 'toggler_interaction.js',
15008            requires: ['liferay-toggler-key-filter']
15009          },
15010          'liferay-toggler-key-filter': {
15011            path: 'toggler_key_filter.js',
15012            requires: ['aui-event-base']
15013          },
15014          'liferay-token-list': {
15015            path: 'token_list.js',
15016            requires: ['aui-base', 'aui-template-deprecated']
15017          },
15018          'liferay-translation-manager': {
15019            path: 'translation_manager.js',
15020            requires: ['aui-base']
15021          },
15022          'liferay-undo-manager': {
15023            path: 'undo_manager.js',
15024            requires: ['aui-data-set-deprecated', 'base']
15025          },
15026          'liferay-upload': {
15027            path: 'upload.js',
15028            requires: ['aui-template-deprecated', 'collection', 'liferay-portlet-base', 'uploader']
15029          },
15030          'liferay-util-window': {
15031            path: 'util_window.js',
15032            requires: ['aui-dialog-iframe-deprecated', 'aui-modal', 'aui-url', 'event-resize', 'liferay-widget-zindex']
15033          },
15034          'liferay-widget-size-animation-plugin': {
15035            path: 'widget_size_animation_plugin.js',
15036            requires: ['anim-easing', 'plugin', 'widget']
15037          },
15038          'liferay-widget-zindex': {
15039            path: 'widget_zindex.js',
15040            requires: ['aui-modal', 'plugin']
15041          },
15042          'liferay-xml-formatter': {
15043            path: 'xml_formatter.js',
15044            requires: ['aui-base']
15045          }
15046        },
15047        root: PATH_JAVASCRIPT + '/liferay/'
15048      },
15049      misc: {
15050        base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/misc/',
15051        combine: COMBINE,
15052        modules: {
15053          swfobject: {
15054            path: 'swfobject.js'
15055          },
15056          swfupload: {
15057            path: 'swfupload/swfupload.js'
15058          }
15059        },
15060        root: PATH_JAVASCRIPT + '/misc/'
15061      },
15062      portal: {
15063        base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/liferay/',
15064        combine: false,
15065        modules: {
15066          'portal-available-languages': {
15067            path: LiferayAUI.getAvailableLangPath(),
15068            requires: ['liferay-language']
15069          }
15070        },
15071        root: PATH_JAVASCRIPT + '/liferay/'
15072      }
15073    },
15074    insertBefore: 'liferayPortalCSS',
15075    lang: themeDisplay.getBCP47LanguageId(),
15076    root: PATH_JAVASCRIPT + '/aui/',
15077    useBrowserConsole: false
15078  };
15079  CORE_MODULES.push('liferay-browser-selectors');
15080})();
15081//# sourceMappingURL=modules.js.map
15082/**
15083 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
15084 *
15085 * This library is free software; you can redistribute it and/or modify it under
15086 * the terms of the GNU Lesser General Public License as published by the Free
15087 * Software Foundation; either version 2.1 of the License, or (at your option)
15088 * any later version.
15089 *
15090 * This library is distributed in the hope that it will be useful, but WITHOUT
15091 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15092 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15093 * details.
15094 */
15095(function () {
15096  var ALLOY = YUI();
15097
15098  if (ALLOY.html5shiv) {
15099    ALLOY.html5shiv();
15100  }
15101
15102  var originalUse = ALLOY.use;
15103
15104  ALLOY.use = function () {
15105    var args = Array.prototype.slice.call(arguments, 0);
15106    var currentURL = Liferay.currentURL;
15107    var originalCallback = args[args.length - 1];
15108
15109    if (typeof originalCallback === 'function') {
15110      args[args.length - 1] = function () {
15111        if (Liferay.currentURL === currentURL) {
15112          originalCallback.apply(this, arguments);
15113        }
15114      };
15115    }
15116
15117    return originalUse.apply(this, args);
15118  };
15119
15120  window.AUI = function () {
15121    return ALLOY;
15122  };
15123
15124  ALLOY.mix(AUI, YUI);
15125  AUI.$ = window.jQuery;
15126  AUI._ = window._;
15127})();
15128//# sourceMappingURL=aui_sandbox.js.map
15129!function(root, factory) {
15130    false && "function" == typeof define && define.amd ? // AMD. Register as an anonymous module unless amdModuleId is set
15131    define([], function() {
15132        return root.svg4everybody = factory();
15133    }) : "object" == typeof module && module.exports ? // Node. Does not work with strict CommonJS, but
15134    // only CommonJS-like environments that support module.exports,
15135    // like Node.
15136    module.exports = factory() : root.svg4everybody = factory();
15137}(this, function() {
15138    /*! svg4everybody v2.1.9 | github.com/jonathantneal/svg4everybody */
15139    function embed(parent, svg, target) {
15140        // if the target exists
15141        if (target) {
15142            // create a document fragment to hold the contents of the target
15143            var fragment = document.createDocumentFragment(), viewB
vendor: 6,434 bytes, lines 15143-15275
15143ox = !svg.hasAttribute("viewBox") && target.getAttribute("viewBox");
15144            // conditionally set the viewBox on the svg
15145            viewBox && svg.setAttribute("viewBox", viewBox);
15146            // copy the contents of the clone into the fragment
15147            for (// clone the target
15148            var clone = target.cloneNode(!0); clone.childNodes.length; ) {
15149                fragment.appendChild(clone.firstChild);
15150            }
15151            // append the fragment into the svg
15152            parent.appendChild(fragment);
15153        }
15154    }
15155    function loadreadystatechange(xhr) {
15156        // listen to changes in the request
15157        xhr.onreadystatechange = function() {
15158            // if the request is ready
15159            if (4 === xhr.readyState) {
15160                // get the cached html document
15161                var cachedDocument = xhr._cachedDocument;
15162                // ensure the cached html document based on the xhr response
15163                cachedDocument || (cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(""), 
15164                cachedDocument.body.innerHTML = xhr.responseText, xhr._cachedTarget = {}), // clear the xhr embeds list and embed each item
15165                xhr._embeds.splice(0).map(function(item) {
15166                    // get the cached target
15167                    var target = xhr._cachedTarget[item.id];
15168                    // ensure the cached target
15169                    target || (target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id)), 
15170                    // embed the target into the svg
15171                    embed(item.parent, item.svg, target);
15172                });
15173            }
15174        }, // test the ready state change immediately
15175        xhr.onreadystatechange();
15176    }
15177    function svg4everybody(rawopts) {
15178        function oninterval() {
15179            // while the index exists in the live <use> collection
15180            for (// get the cached <use> index
15181            var index = 0; index < uses.length; ) {
15182                // get the current <use>
15183                var use = uses[index], parent = use.parentNode, svg = getSVGAncestor(parent), src = use.getAttribute("xlink:href") || use.getAttribute("href");
15184                if (!src && opts.attributeName && (src = use.getAttribute(opts.attributeName)), 
15185                svg && src) {
15186                    if (polyfill) {
15187                        if (!opts.validate || opts.validate(src, svg, use)) {
15188                            // remove the <use> element
15189                            parent.removeChild(use);
15190                            // parse the src and get the url and id
15191                            var srcSplit = src.split("#"), url = srcSplit.shift(), id = srcSplit.join("#");
15192                            // if the link is external
15193                            if (url.length) {
15194                                // get the cached xhr request
15195                                var xhr = requests[url];
15196                                // ensure the xhr request exists
15197                                xhr || (xhr = requests[url] = new XMLHttpRequest(), xhr.open("GET", url), xhr.send(), 
15198                                xhr._embeds = []), // add the svg and id as an item to the xhr embeds list
15199                                xhr._embeds.push({
15200                                    parent: parent,
15201                                    svg: svg,
15202                                    id: id
15203                                }), // prepare the xhr ready state change event
15204                                loadreadystatechange(xhr);
15205                            } else {
15206                                // embed the local id into the svg
15207                                embed(parent, svg, document.getElementById(id));
15208                            }
15209                        } else {
15210                            // increase the index when the previous value was not "valid"
15211                            ++index, ++numberOfSvgUseElementsToBypass;
15212                        }
15213                    }
15214                } else {
15215                    // increase the index when the previous value was not "valid"
15216                    ++index;
15217                }
15218            }
15219            // continue the interval
15220            (!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) && requestAnimationFrame(oninterval, 67);
15221        }
15222        var polyfill, opts = Object(rawopts), newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/, webkitUA = /\bAppleWebKit\/(\d+)\b/, olderEdgeUA = /\bEdge\/12\.(\d+)\b/, edgeUA = /\bEdge\/.(\d+)\b/, inIframe = window.top !== window.self;
15223        polyfill = "polyfill" in opts ? opts.polyfill : newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe;
15224        // create xhr requests object
15225        var requests = {}, requestAnimationFrame = window.requestAnimationFrame || setTimeout, uses = document.getElementsByTagName("use"), numberOfSvgUseElementsToBypass = 0;
15226        // conditionally start the interval if the polyfill is active
15227        polyfill && oninterval();
15228    }
15229    function getSVGAncestor(node) {
15230        for (var svg = node; "svg" !== svg.nodeName.toLowerCase() && (svg = svg.parentNode); ) {}
15231        return svg;
15232    }
15233    return svg4everybody;
15234});
15235YUI.add('arraylist-add', function (Y, NAME) {
15236
15237/**
15238 * Collection utilities beyond what is provided in the YUI core
15239 * @module collection
15240 * @submodule arraylist-add
15241 * @deprecated Use ModelList or a custom ArrayList subclass
15242 */
15243
15244/*
15245 * Adds methods add and remove to Y.ArrayList
15246 */
15247Y.mix(Y.ArrayList.prototype, {
15248
15249    /**
15250     * Add a single item to the ArrayList.  Does not prevent duplicates.
15251     *
15252     * @method add
15253     * @param { mixed } item Item presumably of the same type as others in the
15254     *                       ArrayList.
15255     * @param {Number} index (Optional.)  Number representing the position at
15256     * which the item should be inserted.
15257     * @return {ArrayList} the instance.
15258     * @for ArrayList
15259     * @deprecated Use ModelList or a custom ArrayList subclass
15260     * @chainable
15261     */
15262    add: function(item, index) {
15263        var items = this._items;
15264
15265        if (Y.Lang.isNumber(index)) {
15266            items.splice(index, 0, item);
15267        }
15268        else {
15269            items.push(item);
15270        }
15271
15272        return this;
15273    },
15274
15275    /**
15276     * Removes first or all occurrences of an item to the ArrayList.  If a
15277     * comparator is not provided, uses itemsAreEqual method to determine
15278     * matches.
15279     *
15280     * @method remove
15281     * @param { mixed } needle Item to find and remove from the list.
15282     * @param { Boolean } all If true, remove all occurrences.
15283     * @param { Function } comparator optional a/b function to test equivalence.
15284     * @return {ArrayList} the instance.
15285     * @for ArrayList
15286     * @deprecated Use ModelList or a custom ArrayList subclass
15287     * @chainable
15288     */
15289    remove: function(needle, all, comparator) {
15290        comparator = comparator || this.itemsAreEqual;
15291
15292        for (var i = this._items.length - 1; i >= 0; --i) {
15293            if (comparator.call(this, needle, this.item(i))) {
15294                this._items.splice(i, 1);
15295                if (!all) {
15296                    break;
15297                }
15298            }
15299        }
15300
15301        return this;
15302    },
15303
15304    /**
15305     * Default comparator for items stored in this list.  Used by remove().
15306     *
15307     * @method itemsAreEqual
15308     * @param { mixed } a item to test equivalence with.
15309     * @param { mixed } b other item to test equivalance.
15310     * @return { Boolean } true if items are deemed equivalent.
15311     * @for ArrayList
15312     * @deprecated Use ModelList or a custom ArrayList subclass
15313     */
15314    itemsAreEqual: function(a, b) {
15315        return a === b;
15316    }
15317
15318});
15319
15320
15321}, 'patched-v3.18.1', {"requires": ["arraylist"]});
15322
15323YUI.add('arraylist-filter', function (Y, NAME) {
15324
15325/**
15326 * Collection utilities beyond what is provided in the YUI core
15327 * @module collection
15328 * @submodule arraylist-filter
15329 * @deprecated Use ModelList or a custom subclass implementation
15330 */
15331
15332/*
15333 * Adds filter method to ArrayList prototype
15334 */
15335Y.mix(Y.ArrayList.prototype, {
15336
15337    /**
15338     * <p>Create a new ArrayList (or augmenting class instance) from a subset
15339     * of items as determined by the boolean function passed as the
15340     * argument.  The original ArrayList is unchanged.</p>
15341     *
15342     * <p>The validator signature is <code>validator( item )</code>.</p>
15343     *
15344     * @method filter
15345     * @param { Function } validator Boolean function to determine in or out.
15346     * @return { ArrayList } New instance based on who passed the validator.
15347     * @for ArrayList
15348     * @deprecated Use ModelList or a custom subclass implementation
15349     */
15350    filter: function(validator) {
15351        var items = [];
15352
15353        Y.Array.each(this._items, function(item, i) {
15354            item = this.item(i);
15355
15356            if (validator(item)) {
15357                items.push(item);
15358            }
15359        }, this);
15360
15361        return new this.constructor(items);
15362    }
15363
15364});
15365
15366
15367}, 'patched-v3.18.1', {"requires": ["arraylist"]});
15368
15369YUI.add('arraylist', function (Y, NAME) {
15370
15371/**
15372 * Collection utilities beyond what is provided in the YUI core
15373 * @module collection
15374 * @submodule arraylist
15375 */
15376
15377var YArray      = Y.Array,
15378    YArray_each = YArray.each,
15379    ArrayListProto;
15380
15381/**
15382 * Generic ArrayList class for managing lists of items and iterating operations
15383 * over them.  The targeted use for this class is for augmentation onto a
15384 * class that is responsible for managing multiple instances of another class
15385 * (e.g. NodeList for Nodes).  The recommended use is to augment your class with
15386 * ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
15387 * items on the list's API.
15388 *
15389 * The default implementation creates immutable lists, but mutability can be
15390 * provided via the arraylist-add submodule or by implementing mutation methods
15391 * directly on the augmented class's prototype.
15392 *
15393 * @class ArrayList
15394 * @constructor
15395 * @param items { Array } array of items this list will be responsible for
15396 */
15397function ArrayList( items ) {
15398    if ( items !== undefined ) {
15399        this._items = Y.Lang.isArray( items ) ? items : YArray( items );
15400    } else {
15401        // ||= to support lazy initialization from augment
15402        this._items = this._items || [];
15403    }
15404}
15405
15406ArrayListProto = {
15407    /**
15408     * Get an item by index from the list.  Override this method if managing a
15409     * list of objects that have a different public representation (e.g. Node
15410     * instances vs DOM nodes).  The iteration methods that accept a user
15411     * function will use this method for access list items for operation.
15412     *
15413     * @method item
15414     * @param i { Integer } index to fetch
15415     * @return { mixed } the item at the requested index
15416     */
15417    item: function ( i ) {
15418        return this._items[i];
15419    },
15420
15421    /**
15422     * <p>Execute a function on each item of the list, optionally providing a
15423     * custom execution context.  Default context is the item.</p>
15424     *
15425     * <p>The callback signature is <code>callback( item, index )</code>.</p>
15426     *
15427     * @method each
15428     * @param fn { Function } the function to execute
15429     * @param context { mixed } optional override 'this' in the function
15430     * @return { ArrayList } this instance
15431     * @chainable
15432     */
15433    each: function ( fn, context ) {
15434        YArray_each( this._items, function ( item, i ) {
15435            item = this.item( i );
15436
15437            fn.call( context || item, item, i, this );
15438        }, this);
15439
15440        return this;
15441    },
15442
15443    /**
15444     * <p>Execute a function on each item of the list, optionally providing a
15445     * custom execution context.  Default context is the item.</p>
15446     *
15447     * <p>The callback signature is <code>callback( item, index )</code>.</p>
15448     *
15449     * <p>Unlike <code>each</code>, if the callback returns true, the
15450     * iteration will stop.</p>
15451     *
15452     * @method some
15453     * @param fn { Function } the function to execute
15454     * @param context { mixed } optional override 'this' in the function
15455     * @return { Boolean } True if the function returned true on an item
15456     */
15457    some: function ( fn, context ) {
15458        return YArray.some( this._items, function ( item, i ) {
15459            item = this.item( i );
15460
15461            return fn.call( context || item, item, i, this );
15462        }, this);
15463    },
15464
15465    /**
15466     * Finds the first index of the needle in the managed array of items.
15467     *
15468     * @method indexOf
15469     * @param needle { mixed } The item to search for
15470     * @return { Integer } Array index if found.  Otherwise -1
15471     */
15472    indexOf: function ( needle ) {
15473        return YArray.indexOf( this._items, needle );
15474    },
15475
15476    /**
15477     * How many items are in this list?
15478     *
15479     * @method size
15480     * @return { Integer } Number of items in the list
15481     */
15482    size: function () {
15483        return this._items.length;
15484    },
15485
15486    /**
15487     * Is this instance managing any items?
15488     *
15489     * @method isEmpty
15490     * @return { Boolean } true if 1 or more items are being managed
15491     */
15492    isEmpty: function () {
15493        return !this.size();
15494    },
15495
15496    /**
15497     * Provides an array-like representation for JSON.stringify.
15498     *
15499     * @method toJSON
15500     * @return { Array } an array representation of the ArrayList
15501     */
15502    toJSON: function () {
15503        return this._items;
15504    }
15505};
15506// Default implementation does not distinguish between public and private
15507// item getter
15508/**
15509 * Protected method for optimizations that may be appropriate for API
15510 * mirroring. Similar in functionality to <code>item</code>, but is used by
15511 * methods added with <code>ArrayList.addMethod()</code>.
15512 *
15513 * @method _item
15514 * @protected
15515 * @param i { Integer } Index of item to fetch
15516 * @return { mixed } The item appropriate for pass through API methods
15517 */
15518ArrayListProto._item = ArrayListProto.item;
15519
15520// Mixed onto existing proto to preserve constructor NOT being an own property.
15521// This has bitten me when composing classes by enumerating, copying prototypes.
15522Y.mix(ArrayList.prototype, ArrayListProto);
15523
15524Y.mix( ArrayList, {
15525
15526    /**
15527     * <p>Adds a pass through method to dest (typically the prototype of a list
15528     * class) that calls the named method on each item in the list with
15529     * whatever parameters are passed in.  Allows for API indirection via list
15530     * instances.</p>
15531     *
15532     * <p>Accepts a single string name or an array of string names.</p>
15533     *
15534     * <pre><code>list.each( function ( item ) {
15535     *     item.methodName( 1, 2, 3 );
15536     * } );
15537     * // becomes
15538     * list.methodName( 1, 2, 3 );</code></pre>
15539     *
15540     * <p>Additionally, the pass through methods use the item retrieved by the
15541     * <code>_item</code> method in case there is any special behavior that is
15542     * appropriate for API mirroring.</p>
15543     *
15544     * <p>If the iterated method returns a value, the return value from the
15545     * added method will be an array of values with each value being at the
15546     * corresponding index for that item.  If the iterated method does not
15547     * return a value, the added method will be chainable.
15548     *
15549     * @method addMethod
15550     * @static
15551     * @param dest {Object} Object or prototype to receive the iterator method
15552     * @param name {String|String[]} Name of method of methods to create
15553     */
15554    addMethod: function ( dest, names ) {
15555
15556        names = YArray( names );
15557
15558        YArray_each( names, function ( name ) {
15559            dest[ name ] = function () {
15560                var args = YArray( arguments, 0, true ),
15561                    ret  = [];
15562
15563                YArray_each( this._items, function ( item, i ) {
15564                    item = this._item( i );
15565
15566                    var result = item[ name ].apply( item, args );
15567
15568                    if ( result !== undefined && result !== item ) {
15569                        ret[i] = result;
15570                    }
15571                }, this);
15572
15573                return ret.length ? ret : this;
15574            };
15575        } );
15576    }
15577} );
15578
15579Y.ArrayList = ArrayList;
15580
15581
15582}, 'patched-v3.18.1', {"requires": ["yui-base"]});
15583
15584YUI.add('array-extras', function (Y, NAME) {
15585
15586/**
15587Adds additional utility methods to the `Y.Array` class.
15588
15589@module collection
15590@submodule array-extras
15591**/
15592
15593var A          = Y.Array,
15594    L          = Y.Lang,
15595    ArrayProto = Array.prototype;
15596
15597/**
15598Returns the index of the last item in the array that contains the specified
15599value, or `-1` if the value isn't found.
15600
15601@method lastIndexOf
15602@param {Array} a Array to search in.
15603@param {Any} val Value to search for.
15604@param {Number} [fromIndex] Index at which to start searching backwards.
15605  Defaults to the array's length - 1. If negative, it will be taken as an offset
15606  from the end of the array. If the calculated index is less than 0, the array
15607  will not be searched and `-1` will be returned.
15608@return {Number} Index of the item that contains the value, or `-1` if not
15609  found.
15610@static
15611@for Array
15612**/
15613A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ?
15614    function(a, val, fromIndex) {
15615        // An undefined fromIndex is still considered a value by some (all?)
15616        // native implementations, so we can't pass it unless it's actually
15617        // specified.
15618        return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) :
15619                a.lastIndexOf(val);
15620    } :
15621    function(a, val, fromIndex) {
15622        var len = a.length,
15623            i   = len - 1;
15624
15625        if (fromIndex || fromIndex === 0) {
15626            i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len);
15627        }
15628
15629        if (i > -1 && len > 0) {
15630            for (; i > -1; --i) {
15631                if (i in a && a[i] === val) {
15632                    return i;
15633                }
15634            }
15635        }
15636
15637        return -1;
15638    };
15639
15640/**
15641Returns a copy of the input array with duplicate items removed.
15642
15643Note: If the input array only contains strings, the `Y.Array.dedupe()` method is
15644a much faster alternative.
15645
15646@method unique
15647@param {Array} array Array to dedupe.
15648@param {Function} [testFn] Custom function to use to test the equality of two
15649    values. A truthy return value indicates that the values are equal. A falsy
15650    return value indicates that the values are not equal.
15651
15652    @param {Any} testFn.a First value to compare.
15653    @param {Any} testFn.b Second value to compare.
15654    @param {Number} testFn.index Index of the current item in the original
15655        array.
15656    @param {Array} testFn.array The original array.
15657    @return {Boolean} _true_ if the items are equal, _false_ otherwise.
15658
15659@return {Array} Copy of the input array with duplicate items removed.
15660@static
15661**/
15662A.unique = function (array, testFn) {
15663    var i       = 0,
15664        len     = array.length,
15665        results = [],
15666        j, result, resultLen, value;
15667
15668    // Note the label here. It's used to jump out of the inner loop when a value
15669    // is not unique.
15670    outerLoop: for (; i < len; i++) {
15671        value = array[i];
15672
15673        // For each value in the input array, iterate through the result array
15674        // and check for uniqueness against each result value.
15675        for (j = 0, resultLen = results.length; j < resultLen; j++) {
15676            result = results[j];
15677
15678            // If the test function returns true or there's no test function and
15679            // the value equals the current result item, stop iterating over the
15680            // results and continue to the next value in the input array.
15681            if (testFn) {
15682                if (testFn.call(array, value, result, i, array)) {
15683                    continue outerLoop;
15684                }
15685            } else if (value === result) {
15686                continue outerLoop;
15687            }
15688        }
15689
15690        // If we get this far, that means the current value is not already in
15691        // the result array, so add it.
15692        results.push(value);
15693    }
15694
15695    return results;
15696};
15697
15698/**
15699Executes the supplied function on each item in the array. Returns a new array
15700containing the items for which the supplied function returned a truthy value.
15701
15702@method filter
15703@param {Array} a Array to filter.
15704@param {Function} f Function to execute on each item.
15705@param {Object} [o] Optional context object.
15706@return {Array} Array of items for which the supplied function returned a
15707  truthy value (empty if it never returned a truthy value).
15708@static
15709*/
15710A.filter = L._isNative(ArrayProto.filter) ?
15711    function(a, f, o) {
15712        return ArrayProto.filter.call(a, f, o);
15713    } :
15714    function(a, f, o) {
15715        var i       = 0,
15716            len     = a.length,
15717            results = [],
15718            item;
15719
15720        for (; i < len; ++i) {
15721            if (i in a) {
15722                item = a[i];
15723
15724                if (f.call(o, item, i, a)) {
15725                    results.push(item);
15726                }
15727            }
15728        }
15729
15730        return results;
15731    };
15732
15733/**
15734The inverse of `Array.filter()`. Executes the supplied function on each item.
15735Returns a new array containing the items for which the supplied function
15736returned `false`.
15737
15738@method reject
15739@param {Array} a the array to iterate.
15740@param {Function} f the function to execute on each item.
15741@param {object} [o] Optional context object.
15742@return {Array} The items for which the supplied function returned `false`.
15743@static
15744*/
15745A.reject = function(a, f, o) {
15746    return A.filter(a, function(item, i, a) {
15747        return !f.call(o, item, i, a);
15748    });
15749};
15750
15751/**
15752Executes the supplied function on each item in the array. Iteration stops if the
15753supplied function does not return a truthy value.
15754
15755@method every
15756@param {Array} a the array to iterate.
15757@param {Function} f the function to execute on each item.
15758@param {Object} [o] Optional context object.
15759@return {Boolean} `true` if every item in the array returns `true` from the
15760  supplied function, `false` otherwise.
15761@static
15762*/
15763A.every = L._isNative(ArrayProto.every) ?
15764    function(a, f, o) {
15765        return ArrayProto.every.call(a, f, o);
15766    } :
15767    function(a, f, o) {
15768        for (var i = 0, l = a.length; i < l; ++i) {
15769            if (i in a && !f.call(o, a[i], i, a)) {
15770                return false;
15771            }
15772        }
15773
15774        return true;
15775    };
15776
15777/**
15778Executes the supplied function on each item in the array and returns a new array
15779containing all the values returned by the supplied function.
15780
15781@example
15782
15783    // Convert an array of numbers into an array of strings.
15784    Y.Array.map([1, 2, 3, 4], function (item) {
15785      return '' + item;
15786    });
15787    // => ['1', '2', '3', '4']
15788
15789@method map
15790@param {Array} a the array to iterate.
15791@param {Function} f the function to execute on each item.
15792@param {object} [o] Optional context object.
15793@return {Array} A new array containing the return value of the supplied function
15794  for each item in the original array.
15795@static
15796*/
15797A.map = L._isNative(ArrayProto.map) ?
15798    function(a, f, o) {
15799        return ArrayProto.map.call(a, f, o);
15800    } :
15801    function(a, f, o) {
15802        var i       = 0,
15803            len     = a.length,
15804            results = ArrayProto.concat.call(a);
15805
15806        for (; i < len; ++i) {
15807            if (i in a) {
15808                results[i] = f.call(o, a[i], i, a);
15809            }
15810        }
15811
15812        return results;
15813    };
15814
15815
15816/**
15817Executes the supplied function on each item in the array, "folding" the array
15818into a single value.
15819
15820@method reduce
15821@param {Array} a Array to iterate.
15822@param {Any} init Initial value to start with.
15823@param {Function} f Function to execute on each item. This function should
15824  update and return the value of the computation. It will receive the following
15825  arguments:
15826    @param {Any} f.previousValue Value returned from the previous iteration,
15827      or the initial value if this is the first iteration.
15828    @param {Any} f.currentValue Value of the current item being iterated.
15829    @param {Number} f.index Index of the current item.
15830    @param {Array} f.array Array being iterated.
15831@param {Object} [o] Optional context object.
15832@return {Any} Final result from iteratively applying the given function to each
15833  element in the array.
15834@static
15835*/
15836A.reduce = L._isNative(ArrayProto.reduce) ?
15837    function(a, init, f, o) {
15838        // ES5 Array.reduce doesn't support a thisObject, so we need to
15839        // implement it manually.
15840        return ArrayProto.reduce.call(a, function(init, item, i, a) {
15841            return f.call(o, init, item, i, a);
15842        }, init);
15843    } :
15844    function(a, init, f, o) {
15845        var i      = 0,
15846            len    = a.length,
15847            result = init;
15848
15849        for (; i < len; ++i) {
15850            if (i in a) {
15851                result = f.call(o, result, a[i], i, a);
15852            }
15853        }
15854
15855        return result;
15856    };
15857
15858/**
15859Executes the supplied function on each item in the array, searching for the
15860first item that matches the supplied function.
15861
15862@method find
15863@param {Array} a the array to search.
15864@param {Function} f the function to execute on each item. Iteration is stopped
15865  as soon as this function returns `true`.
15866@param {Object} [o] Optional context object.
15867@return {Object} the first item that the supplied function returns `true` for,
15868  or `null` if it never returns `true`.
15869@static
15870*/
15871A.find = function(a, f, o) {
15872    for (var i = 0, l = a.length; i < l; i++) {
15873        if (i in a && f.call(o, a[i], i, a)) {
15874            return a[i];
15875        }
15876    }
15877    return null;
15878};
15879
15880/**
15881Iterates over an array, returning a new array of all the elements that match the
15882supplied regular expression.
15883
15884@method grep
15885@param {Array} a Array to iterate over.
15886@param {RegExp} pattern Regular expression to test against each item.
15887@return {Array} All the items in the array that produce a match against the
15888  supplied regular expression. If no items match, an empty array is returned.
15889@static
15890*/
15891A.grep = function(a, pattern) {
15892    return A.filter(a, function(item, index) {
15893        return pattern.test(item);
15894    });
15895};
15896
15897/**
15898Partitions an array into two new arrays, one with the items for which the
15899supplied function returns `true`, and one with the items for which the function
15900returns `false`.
15901
15902@method partition
15903@param {Array} a Array to iterate over.
15904@param {Function} f Function to execute for each item in the array. It will
15905  receive the following arguments:
15906    @param {Any} f.item Current item.
15907    @param {Number} f.index Index of the current item.
15908    @param {Array} f.array The array being iterated.
15909@param {Object} [o] Optional execution context.
15910@return {Object} An object with two properties: `matches` and `rejects`. Each is
15911  an array containing the items that were selected or rejected by the test
15912  function (or an empty array if none).
15913@static
15914*/
15915A.partition = function(a, f, o) {
15916    var results = {
15917        matches: [],
15918        rejects: []
15919    };
15920
15921    A.each(a, function(item, index) {
15922        var set = f.call(o, item, index, a) ? results.matches : results.rejects;
15923        set.push(item);
15924    });
15925
15926    return results;
15927};
15928
15929/**
15930Creates an array of arrays by pairing the corresponding elements of two arrays
15931together into a new array.
15932
15933@method zip
15934@param {Array} a Array to iterate over.
15935@param {Array} a2 Another array whose values will be paired with values of the
15936  first array.
15937@return {Array} An array of arrays formed by pairing each element of the first
15938  array with an item in the second array having the corresponding index.
15939@static
15940*/
15941A.zip = function(a, a2) {
15942    var results = [];
15943    A.each(a, function(item, index) {
15944        results.push([item, a2[index]]);
15945    });
15946    return results;
15947};
15948
15949/**
15950Flattens an array of nested arrays at any abitrary depth into a single, flat
15951array.
15952
15953@method flatten
15954@param {Array} a Array with nested arrays to flatten.
15955@return {Array} An array whose nested arrays have been flattened.
15956@static
15957@since 3.7.0
15958**/
15959A.flatten = function(a) {
15960    var result = [],
15961        i, len, val;
15962
15963    // Always return an array.
15964    if (!a) {
15965        return result;
15966    }
15967
15968    for (i = 0, len = a.length; i < len; ++i) {
15969        val = a[i];
15970
15971        if (L.isArray(val)) {
15972            // Recusively flattens any nested arrays.
15973            result.push.apply(result, A.flatten(val));
15974        } else {
15975            result.push(val);
15976        }
15977    }
15978
15979    return result;
15980};
15981
15982
15983}, 'patched-v3.18.1', {"requires": ["yui-base"]});
15984
15985YUI.add('array-invoke', function (Y, NAME) {
15986
15987/**
15988@module collection
15989@submodule array-invoke
15990*/
15991
15992/**
15993Executes a named method on each item in an array of objects. Items in the array
15994that do not have a function by that name will be skipped.
15995
15996@example
15997
15998    Y.Array.invoke(arrayOfDrags, 'plug', Y.Plugin.DDProxy);
15999
16000@method invoke
16001@param {Array} items Array of objects supporting the named method.
16002@param {String} name the name of the method to execute on each item.
16003@param {Any} [args*] Any number of additional args are passed as parameters to
16004  the execution of the named method.
16005@return {Array} All return values, indexed according to the item index.
16006@static
16007@for Array
16008**/
16009Y.Array.invoke = function(items, name) {
16010    var args = Y.Array(arguments, 2, true),
16011        isFunction = Y.Lang.isFunction,
16012        ret = [];
16013
16014    Y.Array.each(Y.Array(items), function(item, i) {
16015        if (item && isFunction(item[name])) {
16016            ret[i] = item[name].apply(item, args);
16017        }
16018    });
16019
16020    return ret;
16021};
16022
16023
16024}, 'patched-v3.18.1', {"requires": ["yui-base"]});
16025
16026YUI.add('attribute-base', function (Y, NAME) {
16027
16028    /**
16029     * The attribute module provides an augmentable Attribute implementation, which
16030     * adds configurable attributes and attribute change events to the class being
16031     * augmented. It also provides a State class, which is used internally by Attribute,
16032     * but can also be used independently to provide a name/property/value data structure to
16033     * store state.
16034     *
16035     * @module attribute
16036     */
16037
16038    /**
16039     * The attribute-base submodule provides core attribute handling support, with everything
16040     * aside from complex attribute handling in the provider's constructor.
16041     *
16042     * @module attribute
16043     * @submodule attribute-base
16044     */
16045
16046    /**
16047     * <p>
16048     * Attribute provides configurable attribute support along with attribute change events. It is designed to be
16049     * augmented on to a host class, and provides the host with the ability to configure attributes to store and retrieve state,
16050     * along with attribute change events.
16051     * </p>
16052     * <p>For example, attributes added to the host can be configured:</p>
16053     * <ul>
16054     *     <li>As read only.</li>
16055     *     <li>As write once.</li>
16056     *     <li>With a setter function, which can be used to manipulate
16057     *     values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li>
16058     *     <li>With a getter function, which can be used to manipulate stored values,
16059     *     before they are returned by Attribute's <a href="#method_get">get</a> method.</li>
16060     *     <li>With a validator function, to validate values before they are stored.</li>
16061     * </ul>
16062     *
16063     * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration
16064     * options available for attributes.</p>
16065     *
16066     * <p><strong>NOTE:</strong> Most implementations will be better off extending the <a href="Base.html">Base</a> class,
16067     * instead of augmenting Attribute directly. Base augments Attribute and will handle the initial configuration
16068     * of attributes for derived classes, accounting for values passed into the constructor.</p>
16069     *
16070     * @class Attribute
16071     * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
16072     *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
16073     * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
16074     *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
16075     * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
16076     * @uses AttributeCore
16077     * @uses AttributeObservable
16078     * @uses EventTarget
16079     * @uses AttributeExtras
16080     */
16081    function Attribute() {
16082        Y.AttributeCore.apply(this, arguments);
16083        Y.AttributeObservable.apply(this, arguments);
16084        Y.AttributeExtras.apply(this, arguments);
16085    }
16086
16087    Y.mix(Attribute, Y.AttributeCore, false, null, 1);
16088    Y.mix(Attribute, Y.AttributeExtras, false, null, 1);
16089
16090    // Needs to be `true`, to overwrite methods from AttributeCore
16091    Y.mix(Attribute, Y.AttributeObservable, true, null, 1);
16092
16093    /**
16094     * <p>The value to return from an attribute setter in order to prevent the set from going through.</p>
16095     *
16096     * <p>You can return this value from your setter if you wish to combine validator and setter
16097     * functionality into a single setter function, which either returns the massaged value to be stored or
16098     * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p>
16099     *
16100     * @property INVALID_VALUE
16101     * @type Object
16102     * @static
16103     * @final
16104     */
16105    Attribute.INVALID_VALUE = Y.AttributeCore.INVALID_VALUE;
16106
16107    /**
16108     * The list of properties which can be configured for
16109     * each attribute (e.g. setter, getter, writeOnce etc.).
16110     *
16111     * This property is used internally as a whitelist for faster
16112     * Y.mix operations.
16113     *
16114     * @property _ATTR_CFG
16115     * @type Array
16116     * @static
16117     * @protected
16118     */
16119    Attribute._ATTR_CFG = Y.AttributeCore._ATTR_CFG.concat(Y.AttributeObservable._ATTR_CFG);
16120
16121    /**
16122     * Utility method to protect an attribute configuration hash, by merging the
16123     * entire object and the individual attr config objects.
16124     *
16125     * @method protectAttrs
16126     * @static
16127     * @param {Object} attrs A hash of attribute to configuration object pairs.
16128     * @return {Object} A protected version of the `attrs` argument.
16129     */
16130    Attribute.protectAttrs = Y.AttributeCore.protectAttrs;
16131
16132    Y.Attribute = Attribute;
16133
16134
16135}, 'patched-v3.18.1', {"requires": ["attribute-core", "attribute-observable", "attribute-extras"]});
16136
16137YUI.add('attribute-complex', function (Y, NAME) {
16138
16139    /**
16140     * Adds support for attribute providers to handle complex attributes in the constructor
16141     *
16142     * @module attribute
16143     * @submodule attribute-complex
16144     * @for Attribute
16145     * @deprecated AttributeComplex's overrides are now part of AttributeCore.
16146     */
16147
16148    var Attribute = Y.Attribute;
16149
16150    Attribute.Complex = function() {};
16151    Attribute.Complex.prototype = {
16152
16153        /**
16154         * Utility method to split out simple attribute name/value pairs ("x")
16155         * from complex attribute name/value pairs ("x.y.z"), so that complex
16156         * attributes can be keyed by the top level attribute name.
16157         *
16158         * @method _normAttrVals
16159         * @param {Object} valueHash An object with attribute name/value pairs
16160         *
16161         * @return {Object} An object literal with 2 properties - "simple" and "complex",
16162         * containing simple and complex attribute values respectively keyed
16163         * by the top level attribute name, or null, if valueHash is falsey.
16164         *
16165         * @private
16166         */
16167        _normAttrVals : Attribute.prototype._normAttrVals,
16168
16169        /**
16170         * Returns the initial value of the given attribute from
16171         * either the default configuration provided, or the
16172         * over-ridden value if it exists in the set of initValues
16173         * provided and the attribute is not read-only.
16174         *
16175         * @param {String} attr The name of the attribute
16176         * @param {Object} cfg The attribute configuration object
16177         * @param {Object}
16177 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
16178         *
16179         * @return {Any} The initial value of the attribute.
16180         *
16181         * @method _getAttrInitVal
16182         * @private
16183         */
16184        _getAttrInitVal : Attribute.prototype._getAttrInitVal
16185
16186    };
16187
16188    // Consistency with the rest of the Attribute addons for now.
16189    Y.AttributeComplex = Attribute.Complex;
16190
16191
16192}, 'patched-v3.18.1', {"requires": ["attribute-base"]});
16193
16194YUI.add('attribute-core', function (Y, NAME) {
16195
16196    /**
16197     * The State class maintains state for a collection of named items, with
16198     * a varying number of properties defined.
16199     *
16200     * It avoids the need to create a separate class for the item, and separate instances
16201     * of these classes for each item, by storing the state in a 2 level hash table,
16202     * improving performance when the number of items is likely to be large.
16203     *
16204     * @constructor
16205     * @class State
16206     */
16207    Y.State = function() {
16208        /**
16209         * Hash of attributes
16210         * @property data
16211         */
16212        this.data = {};
16213    };
16214
16215    Y.State.prototype = {
16216
16217        /**
16218         * Adds a property to an item.
16219         *
16220         * @method add
16221         * @param name {String} The name of the item.
16222         * @param key {String} The name of the property.
16223         * @param val {Any} The value of the property.
16224         */
16225        add: function(name, key, val) {
16226            var item = this.data[name];
16227
16228            if (!item) {
16229                item = this.data[name] = {};
16230            }
16231
16232            item[key] = val;
16233        },
16234
16235        /**
16236         * Adds multiple properties to an item.
16237         *
16238         * @method addAll
16239         * @param name {String} The name of the item.
16240         * @param obj {Object} A hash of property/value pairs.
16241         */
16242        addAll: function(name, obj) {
16243            var item = this.data[name],
16244                key;
16245
16246            if (!item) {
16247                item = this.data[name] = {};
16248            }
16249
16250            for (key in obj) {
16251                if (obj.hasOwnProperty(key)) {
16252                    item[key] = obj[key];
16253                }
16254            }
16255        },
16256
16257        /**
16258         * Removes a property from an item.
16259         *
16260         * @method remove
16261         * @param name {String} The name of the item.
16262         * @param key {String} The property to remove.
16263         */
16264        remove: function(name, key) {
16265            var item = this.data[name];
16266
16267            if (item) {
16268                delete item[key];
16269            }
16270        },
16271
16272        /**
16273         * Removes multiple properties from an item, or removes the item completely.
16274         *
16275         * @method removeAll
16276         * @param name {String} The name of the item.
16277         * @param obj {Object|Array} Collection of properties to delete. If not provided, the entire item is removed.
16278         */
16279        removeAll: function(name, obj) {
16280            var data;
16281
16282            if (!obj) {
16283                data = this.data;
16284
16285                if (name in data) {
16286                    delete data[name];
16287                }
16288            } else {
16289                Y.each(obj, function(value, key) {
16290                    this.remove(name, typeof key === 'string' ? key : value);
16291                }, this);
16292            }
16293        },
16294
16295        /**
16296         * For a given item, returns the value of the property requested, or undefined if not found.
16297         *
16298         * @method get
16299         * @param name {String} The name of the item
16300         * @param key {String} Optional. The property value to retrieve.
16301         * @return {Any} The value of the supplied property.
16302         */
16303        get: function(name, key) {
16304            var item = this.data[name];
16305
16306            if (item) {
16307                return item[key];
16308            }
16309        },
16310
16311        /**
16312         * For the given item, returns an object with all of the
16313         * item's property/value pairs. By default the object returned
16314         * is a shallow copy of the stored data, but passing in true
16315         * as the second parameter will return a reference to the stored
16316         * data.
16317         *
16318         * @method getAll
16319         * @param name {String} The name of the item
16320         * @param reference {boolean} true, if you want a reference to the stored
16321         * object
16322         * @return {Object} An object with property/value pairs for the item.
16323         */
16324        getAll : function(name, reference) {
16325            var item = this.data[name],
16326                key, obj;
16327
16328            if (reference) {
16329                obj = item;
16330            } else if (item) {
16331                obj = {};
16332
16333                for (key in item) {
16334                    if (item.hasOwnProperty(key)) {
16335                        obj[key] = item[key];
16336                    }
16337                }
16338            }
16339
16340            return obj;
16341        }
16342    };
16343    /*For log lines*/
16344    /*jshint maxlen:200*/
16345
16346    /**
16347     * The attribute module provides an augmentable Attribute implementation, which
16348     * adds configurable attributes and attribute change events to the class being
16349     * augmented. It also provides a State class, which is used internally by Attribute,
16350     * but can also be used independently to provide a name/property/value data structure to
16351     * store state.
16352     *
16353     * @module attribute
16354     */
16355
16356    /**
16357     * The attribute-core submodule provides the lightest level of attribute handling support
16358     * without Attribute change events, or lesser used methods such as reset(), modifyAttrs(),
16359     * and removeAttr().
16360     *
16361     * @module attribute
16362     * @submodule attribute-core
16363     */
16364    var O = Y.Object,
16365        Lang = Y.Lang,
16366
16367        DOT = ".",
16368
16369        // Externally configurable props
16370        GETTER = "getter",
16371        SETTER = "setter",
16372        READ_ONLY = "readOnly",
16373        WRITE_ONCE = "writeOnce",
16374        INIT_ONLY = "initOnly",
16375        VALIDATOR = "validator",
16376        VALUE = "value",
16377        VALUE_FN = "valueFn",
16378        LAZY_ADD = "lazyAdd",
16379
16380        // Used for internal state management
16381        ADDED = "added",
16382        BYPASS_PROXY = "_bypassProxy",
16383        INIT_VALUE = "initValue",
16384        LAZY = "lazy",
16385
16386        INVALID_VALUE;
16387
16388    /**
16389     * <p>
16390     * AttributeCore provides the lightest level of configurable attribute support. It is designed to be
16391     * augmented on to a host class, and provides the host with the ability to configure
16392     * attributes to store and retrieve state, <strong>but without support for attribute change events</strong>.
16393     * </p>
16394     * <p>For example, attributes added to the host can be configured:</p>
16395     * <ul>
16396     *     <li>As read only.</li>
16397     *     <li>As write once.</li>
16398     *     <li>With a setter function, which can be used to manipulate
16399     *     values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li>
16400     *     <li>With a getter function, which can be used to manipulate stored values,
16401     *     before they are returned by Attribute's <a href="#method_get">get</a> method.</li>
16402     *     <li>With a validator function, to validate values before they are stored.</li>
16403     * </ul>
16404     *
16405     * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration
16406     * options available for attributes.</p>
16407     *
16408     * <p>Object/Classes based on AttributeCore can augment <a href="AttributeObservable.html">AttributeObservable</a>
16409     * (with true for overwrite) and <a href="AttributeExtras.html">AttributeExtras</a> to add attribute event and
16410     * additional, less commonly used attribute methods, such as `modifyAttr`, `removeAttr` and `reset`.</p>
16411     *
16412     * @class AttributeCore
16413     * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
16414     *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
16415     * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
16416     *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
16417     * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
16418     */
16419    function AttributeCore(attrs, values, lazy) {
16420        // HACK: Fix #2531929
16421        // 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.
16422        // Too late in the release cycle to do anything about the core problem.
16423        // 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).
16424        this._yuievt = null;
16425
16426        this._initAttrHost(attrs, values, lazy);
16427    }
16428
16429    /**
16430     * <p>The value to return from an attribute setter in order to prevent the set from going through.</p>
16431     *
16432     * <p>You can return this value from your setter if you wish to combine validator and setter
16433     * functionality into a single setter function, which either returns the massaged value to be stored or
16434     * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p>
16435     *
16436     * @property INVALID_VALUE
16437     * @type Object
16438     * @static
16439     * @final
16440     */
16441    AttributeCore.INVALID_VALUE = {};
16442    INVALID_VALUE = AttributeCore.INVALID_VALUE;
16443
16444    /**
16445     * The list of properties which can be configured for
16446     * each attribute (e.g. setter, getter, writeOnce etc.).
16447     *
16448     * This property is used internally as a whitelist for faster
16449     * Y.mix operations.
16450     *
16451     * @property _ATTR_CFG
16452     * @type Array
16453     * @static
16454     * @protected
16455     */
16456    AttributeCore._ATTR_CFG = [SETTER, GETTER, VALIDATOR, VALUE, VALUE_FN, WRITE_ONCE, READ_ONLY, LAZY_ADD, BYPASS_PROXY];
16457
16458    /**
16459     * Utility method to protect an attribute configuration hash, by merging the
16460     * entire object and the individual attr config objects.
16461     *
16462     * @method protectAttrs
16463     * @static
16464     * @param {Object} attrs A hash of attribute to configuration object pairs.
16465     * @return {Object} A protected version of the `attrs` argument.
16466     */
16467    AttributeCore.protectAttrs = function (attrs) {
16468        if (attrs) {
16469            attrs = Y.merge(attrs);
16470            for (var attr in attrs) {
16471                if (attrs.hasOwnProperty(attr)) {
16472                    attrs[attr] = Y.merge(attrs[attr]);
16473                }
16474            }
16475        }
16476
16477        return attrs;
16478    };
16479
16480    AttributeCore.prototype = {
16481
16482        /**
16483         * Constructor logic for attributes. Initializes the host state, and sets up the inital attributes passed to the
16484         * constructor.
16485         *
16486         * @method _initAttrHost
16487         * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
16488         *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
16489         * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
16490         *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
16491         * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
16492         * @private
16493         */
16494        _initAttrHost : function(attrs, values, lazy) {
16495            this._state = new Y.State();
16496            this._initAttrs(attrs, values, lazy);
16497        },
16498
16499        /**
16500         * <p>
16501         * Adds an attribute with the provided configuration to the host object.
16502         * </p>
16503         * <p>
16504         * The config argument object supports the following properties:
16505         * </p>
16506         *
16507         * <dl>
16508         *    <dt>value &#60;Any&#62;</dt>
16509         *    <dd>The initial value to set on the attribute</dd>
16510         *
16511         *    <dt>valueFn &#60;Function | String&#62;</dt>
16512         *    <dd>
16513         *    <p>A function, which will return the initial value to set on the attribute. This is useful
16514         *    for cases where the attribute configuration is defined statically, but needs to
16515         *    reference the host instance ("this") to obtain an initial value. If both the value and valueFn properties are defined,
16516         *    the value returned by the valueFn has precedence over the value property, unless it returns undefined, in which
16517         *    case the value property is used.</p>
16518         *
16519         *    <p>valueFn can also be set to a string, representing the name of the instance method to be used to retrieve the value.</p>
16520         *    </dd>
16521         *
16522         *    <dt>readOnly &#60;boolean&#62;</dt>
16523         *    <dd>Whether or not the attribute is read only. Attributes having readOnly set to true
16524         *        cannot be modified by invoking the set method.</dd>
16525         *
16526         *    <dt>writeOnce &#60;boolean&#62; or &#60;string&#62;</dt>
16527         *    <dd>
16528         *        Whether or not the attribute is "write once". Attributes having writeOnce set to true,
16529         *        can only have their values set once, be it through the default configuration,
16530         *        constructor configuration arguments, or by invoking set.
16531         *        <p>The writeOnce attribute can also be set to the string "initOnly",
16532         *         in which case the attribute can only be set during initialization
16533         *        (when used with Base, this means it can only be set during construction)</p>
16534         *    </dd>
16535         *
16536         *    <dt>setter &#60;Function | String&#62;</dt>
16537         *    <dd>
16538         *    <p>The setter function used to massage or normalize the value passed to the set method for the attribute.
16539         *    The value returned by the setter will be the final stored value. Returning
16540         *    <a href="#property_Attribute.INVALID_VALUE">Attribute.INVALID_VALUE</a>, from the setter will prevent
16541         *    the value from being stored.
16542         *    </p>
16543         *
16544         *    <p>setter can also be set to a string, representing the name of the instance method to be used as the setter function.</p>
16545         *    </dd>
16546         *
16547         *    <dt>getter &#60;Function | String&#62;</dt>
16548         *    <dd>
16549         *    <p>
16550         *    The getter function used to massage or normalize the value returned by the get method for the attribute.
16551         *    The value returned by the getter function is the value which will be returned to the user when they
16552         *    invoke get.
16553         *    </p>
16554         *
16555         *    <p>getter can also be set to a string, representing the name of the instance method to be used as the getter function.</p>
16556         *    </dd>
16557         *
16558         *    <dt>validator &#60;Function | String&#62;</dt>
16559         *    <dd>
16560         *    <p>
16561         *    The validator function invoked prior to setting the stored value. Returning
16562         *    false from the validator function will prevent the value from being stored.
16563         *    </p>
16564         *
16565         *    <p>validator can also be set to a string, representing the name of the instance method to be used as the validator function.</p>
16566         *    </dd>
16567         *
16568         *    <dt>lazyAdd &#60;boolean&#62;</dt>
16569         *    <dd>Whether or not to delay initialization of the attribute until the first call to get/set it.
16570         *    This flag can be used to over-ride lazy initialization on a per attribute basis, when adding multiple attributes through
16571         *    the <a href="#method_addAttrs">addAttrs</a> method.</dd>
16572         *
16573         * </dl>
16574         *
16575         * <p>The setter, getter and validator are invoked with the value and name passed in as the first and second arguments, and with
16576         * the context ("this") set to the host object.</p>
16577         *
16578         * <p>Configuration properties outside of the list mentioned above are considered private properties used internally by attribute,
16579         * and are not intended for public use.</p>
16580         *
16581         * @method addAttr
16582         *
16583         * @param {String} name The name of the attribute.
16584         * @param {Object} config An object with attribute configuration property/value pairs, specifying the configuration for the attribute.
16585         *
16586         * <p>
16587         * <strong>NOTE:</strong> The configuration object is modified when adding an attribute, so if you need
16588         * to protect the original values, you will need to merge the object.
16589         * </p>
16590         *
16591         * @param {boolean} lazy (optional) Whether or not to add this attribute lazily (on the first call to get/set).
16592         *
16593         * @return {Object} A reference to the host object.
16594         *
16595         * @chainable
16596         */
16597        addAttr : function(name, config, lazy) {
16598
16599
16600            var host = this, // help compression
16601                state = host._state,
16602                data = state.data,
16603                value,
16604                added,
16605                hasValue;
16606
16607            config = config || {};
16608
16609            if (LAZY_ADD in config) {
16610                lazy = config[LAZY_ADD];
16611            }
16612
16613            added = state.get(name, ADDED);
16614
16615            if (lazy && !added) {
16616                state.data[name] = {
16617                    lazy : config,
16618                    added : true
16619                };
16620            } else {
16621
16622
16623                if (!added || config.isLazyAdd) {
16624
16625                    hasValue = (VALUE in config);
16626
16627
16628                    if (hasValue) {
16629
16630                        // We'll go through set, don't want to set value in config directly
16631
16632                        // PERF TODO: VALIDATE: See if setting this to undefined is sufficient. We use to delete before.
16633                        // In certain code paths/use cases, undefined may not be the same as not present.
16634                        // If not, we can set it to some known fixed value (like INVALID_VALUE, say INITIALIZING_VALUE) for performance,
16635                        // to avoid a delete which seems to help a lot.
16636
16637                        value = config.value;
16638                        config.value = undefined;
16639                    }
16640
16641                    config.added = true;
16642                    config.initializing = true;
16643
16644                    data[name] = config;
16645
16646                    if (hasValue) {
16647                        // Go through set, so that raw values get normalized/validated
16648                        host.set(name, value);
16649                    }
16650
16651                    config.initializing = false;
16652                }
16653            }
16654
16655            return host;
16656        },
16657
16658        /**
16659         * Checks if the given attribute has been added to the host
16660         *
16661         * @method attrAdded
16662         * @param {String} name The name of the attribute to check.
16663         * @return {boolean} true if an attribute with the given name has been added, false if it hasn't.
16664         *         This method will return true for lazily added attributes.
16665         */
16666        attrAdded: function(name) {
16667            return !!(this._state.get(name, ADDED));
16668        },
16669
16670        /**
16671         * Returns the current value of the attribute. If the attribute
16672         * has been configured with a 'getter' function, this method will delegate
16673         * to the 'getter' to obtain the value of the attribute.
16674         *
16675         * @method get
16676         *
16677         * @param {String} name The name of the attribute. If the value of the attribute is an Object,
16678         * dot notation can be used to obtain the value of a property of the object (e.g. <code>get("x.y.z")</code>)
16679         *
16680         * @return {Any} The value of the attribute
16681         */
16682        get : function(name) {
16683            return this._getAttr(name);
16684        },
16685
16686        /**
16687         * Checks whether or not the attribute is one which has been
16688         * added lazily and still requires initialization.
16689         *
16690         * @method _isLazyAttr
16691         * @private
16692         * @param {String} name The name of the attribute
16693         * @return {boolean} true if it's a lazily added attribute, false otherwise.
16694         */
16695        _isLazyAttr: function(name) {
16696            return this._state.get(name, LAZY);
16697        },
16698
16699        /**
16700         * Finishes initializing an attribute which has been lazily added.
16701         *
16702         * @method _addLazyAttr
16703         * @private
16704         * @param {Object} name The name of the attribute
16705         * @param {Object} [lazyCfg] Optional config hash for the attribute. This is added for performance
16706         * along the critical path, where the calling method has already obtained lazy config from state.
16707         */
16708        _addLazyAttr: function(name, lazyCfg) {
16709            var state = this._state;
16710
16711            lazyCfg = lazyCfg || state.get(name, LAZY);
16712
16713            if (lazyCfg) {
16714
16715                // PERF TODO: For App's id override, otherwise wouldn't be
16716                // needed. It expects to find it in the cfg for it's
16717                // addAttr override. Would like to remove, once App override is
16718                // removed.
16719                state.data[name].lazy = undefined;
16720
16721                lazyCfg.isLazyAdd = true;
16722
16723                this.addAttr(name, lazyCfg);
16724            }
16725        },
16726
16727        /**
16728         * Sets the value of an attribute.
16729         *
16730         * @method set
16731         * @chainable
16732         *
16733         * @param {String} name The name of the attribute. If the
16734         * current value of the attribute is an Object, dot notation can be used
16735         * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
16736         * @param {Any} value The value to set the attribute to.
16737         * @param {Object} [opts] Optional data providing the circumstances for the change.
16738         * @return {Object} A reference to the host object.
16739         */
16740        set : function(name, val, opts) {
16741            return this._setAttr(name, val, opts);
16742        },
16743
16744        /**
16745         * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
16746         *
16747         * @method _set
16748         * @protected
16749         * @chainable
16750         *
16751         * @param {String} name The name of the attribute.
16752         * @param {Any} val The value to set the attribute to.
16753         * @param {Object} [opts] Optional data providing the circumstances for the change.
16754         * @return {Object} A reference to the host object.
16755         */
16756        _set : function(name, val, opts) {
16757            return this._setAttr(name, val, opts, true);
16758        },
16759
16760        /**
16761         * Provides the common implementation for the public set and protected _set methods.
16762         *
16763         * See <a href="#method_set">set</a> for argument details.
16764         *
16765         * @method _setAttr
16766         * @protected
16767         * @chainable
16768         *
16769         * @param {String} name The name of the attribute.
16770         * @param {Any} value The value to set the attribute to.
16771         * @param {Object} [opts] Optional data providing the circumstances for the change.
16772         * @param {boolean} force If true, allows the caller to set values for
16773         * readOnly or writeOnce attributes which have already been set.
16774         *
16775         * @return {Object} A reference to the host object.
16776         */
16777        _setAttr : function(name, val, opts, force)  {
16778            var allowSet = true,
16779                state = this._state,
16780                stateProxy = this._stateProxy,
16781                tCfgs = this._tCfgs,
16782                cfg,
16783                initialSet,
16784                strPath,
16785                path,
16786                currVal,
16787                writeOnce,
16788                initializing;
16789
16790            if (name.indexOf(DOT) !== -1) {
16791                strPath = name;
16792
16793                path = name.split(DOT);
16794                name = path.shift();
16795            }
16796
16797            // On Demand - Should be rare - handles out of order valueFn, setter, getter references
16798            if (tCfgs && tCfgs[name]) {
16799                this._addOutOfOrder(name, tCfgs[name]);
16800            }
16801
16802            cfg = state.data[name] || {};
16803
16804            if (cfg.lazy) {
16805                cfg = cfg.lazy;
16806                this._addLazyAttr(name, cfg);
16807            }
16808
16809            initialSet = (cfg.value === undefined);
16810
16811            if (stateProxy && name in stateProxy && !cfg._bypassProxy) {
16812                // 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?
16813                initialSet = false;
16814            }
16815
16816            writeOnce = cfg.writeOnce;
16817            initializing = cfg.initializing;
16818
16819            if (!initialSet && !force) {
16820
16821                if (writeOnce) {
16822                    allowSet = false;
16823                }
16824
16825                if (cfg.readOnly) {
16826                    allowSet = false;
16827                }
16828            }
16829
16830            if (!initializing && !force && writeOnce === INIT_ONLY) {
16831                allowSet = false;
16832            }
16833
16834            if (allowSet) {
16835                // Don't need currVal if initialSet (might fail in custom getter if it always expects a non-undefined/non-null value)
16836                if (!initialSet) {
16837                    currVal =  this.get(name);
16838                }
16839
16840                if (path) {
16841                    var copyVal = [currVal].reduce(
16842                        function(retVal, currVal) {
16843                            Object.keys(currVal).forEach(
16844                                function(item) {
16845                                    retVal[item] = currVal[item];
16846                                }
16847                            );
16848                        return retVal;
16849                        },
16850                        {}
16851                    );
16852
16853                    var pathNode = copyVal;
16854                    var leafIdx = path.length - 1;
16855
16856                    for (var i = 0; i < leafIdx && pathNode; i++) {
16857                        pathNode = pathNode[path[i]];
16858                    }
16859
16860                    if (pathNode) {
16861                        delete pathNode[path[leafIdx]];
16862                    }
16863
16864                    val = O.setValue(Y.clone(copyVal), path, val);
16865
16866                    if (val === undefined) {
16867                        allowSet = false;
16868                    }
16869                }
16870
16871                if (allowSet) {
16872                    if (!this._fireAttrChange || initializing) {
16873                        this._setAttrVal(name, strPath, currVal, val, opts, cfg);
16874                    } else {
16875                        // HACK - no real reason core needs to know about _fireAttrChange, but
16876                        // it adds fn hops if we want to break it out. Not sure it's worth it for this critical path
16877                        this._fireAttrChange(name, strPath, currVal, val, opts, cfg);
16878                    }
16879                }
16880            }
16881
16882            return this;
16883        },
16884
16885        /**
16886         * Utility method used by get/set to add attributes
16887         * encountered out of order when calling addAttrs().
16888         *
16889         * For example, if:
16890         *
16891         *     this.addAttrs({
16892         *          foo: {
16893         *              setter: function() {
16894         *                 // make sure this bar is available when foo is added
16895         *                 this.get("bar");
16896         *              }
16897         *          },
16898         *          bar: {
16899         *              value: ...
16900         *          }
16901         *     });
16902         *
16903         * @method _addOutOfOrder
16904         * @private
16905         * @param name {String} attribute name
16906         * @param cfg {Object} attribute configuration
16907         */
16908        _addOutOfOrder : function(name, cfg) {
16909
16910            var attrs = {};
16911            attrs[name] = cfg;
16912
16913            delete this._tCfgs[name];
16914
16915            // TODO: The original code went through addAttrs, so
16916            // sticking with it for this pass. Seems like we could
16917            // just jump straight to _addAttr() and get some perf
16918            // improvement.
16919            this._addAttrs(attrs, this._tVals);
16920        },
16921
16922        /**
16923         * Provides the common implementation for the public get method,
16924         * allowing Attribute hosts to over-ride either method.
16925         *
16926         * See <a href="#method_get">get</a> for argument details.
16927         *
16928         * @method _getAttr
16929         * @protected
16930         * @chainable
16931         *
16932         * @param {String} name The name of the attribute.
16933         * @return {Any} The value of the attribute.
16934         */
16935        _getAttr : function(name) {
16936            var fullName = name,
16937                tCfgs = this._tCfgs,
16938                path,
16939                getter,
16940                val,
16941                attrCfg;
16942
16943            if (name.indexOf(DOT) !== -1) {
16944                path = name.split(DOT);
16945                name = path.shift();
16946            }
16947
16948            // On Demand - Should be rare - handles out of
16949            // order valueFn, setter, getter references
16950            if (tCfgs && tCfgs[name]) {
16951                this._addOutOfOrder(name, tCfgs[name]);
16952            }
16953
16954            attrCfg = this._state.data[name] || {};
16955
16956            // Lazy Init
16957            if (attrCfg.lazy) {
16958                attrCfg = attrCfg.lazy;
16959                this._addLazyAttr(name, attrCfg);
16960            }
16961
16962            val = this._getStateVal(name, attrCfg);
16963
16964            getter = attrCfg.getter;
16965
16966            if (getter && !getter.call) {
16967                getter = this[getter];
16968            }
16969
16970            val = (getter) ? getter.call(this, val, fullName) : val;
16971            val = (path) ? O.getValue(val, path) : val;
16972
16973            return val;
16974        },
16975
16976        /**
16977         * Gets the stored value for the attribute, from either the
16978         * internal state object, or the state proxy if it exits
16979         *
16980         * @method _getStateVal
16981         * @private
16982         * @param {String} name The name of the attribute
16983         * @param {Object} [cfg] Optional config hash for the attribute. This is added for performance along the critical path,
16984         * where the calling method has already obtained the config from state.
16985         *
16986         * @return {Any} The stored value of the attribute
16987         */
16988        _getStateVal : function(name, cfg) {
16989            var stateProxy = this._stateProxy;
16990
16991            if (!cfg) {
16992                cfg = this._state.getAll(name) || {};
16993            }
16994
16995            return (stateProxy && (name in stateProxy) && !(cfg._bypassProxy)) ? stateProxy[name] : cfg.value;
16996        },
16997
16998        /**
16999         * Sets the stored value for the attribute, in either the
17000         * internal state object, or the state proxy if it exits
17001         *
17002         * @method _setStateVal
17003         * @private
17004         * @param {String} name The name of the attribute
17005         * @param {Any} value The value of the attribute
17006         */
17007        _setStateVal : function(name, value) {
17008            var stateProxy = this._stateProxy;
17009            if (stateProxy && (name in stateProxy) && !this._state.get(name, BYPASS_PROXY)) {
17010                stateProxy[name] = value;
17011            } else {
17012                this._state.add(name, VALUE, value);
17013            }
17014        },
17015
17016        /**
17017         * Updates the stored value of the attribute in the privately held State object,
17018         * if validation and setter passes.
17019         *
17020         * @method _setAttrVal
17021         * @private
17022         * @param {String} attrName The attribute name.
17023         * @param {String} subAttrName The sub-attribute name, if setting a sub-attribute property ("x.y.z").
17024         * @param {Any} prevVal The currently stored value of the attribute.
17025         * @param {Any} newVal The value which is going to be stored.
17026         * @param {Object} [opts] Optional data providing the circumstances for the change.
17027         * @param {Object} [attrCfg] Optional config hash for the attribute. This is added for performance along the critical path,
17028         * where the calling method has already obtained the config from state.
17029         *
17030         * @return {Boolean} true if the new attribute value was stored, false if not.
17031         */
17032        _setAttrVal : function(attrName, subAttrName, prevVal, newVal, opts, attrCfg) {
17033
17034            var host = this,
17035                allowSet = true,
17036                cfg = attrCfg || this._state.data[attrName] || {},
17037                validator = cfg.validator,
17038                setter = cfg.setter,
17039                initializing = cfg.initializing,
17040                prevRawVal = this._getStateVal(attrName, cfg),
17041                name = subAttrName || attrName,
17042                retVal,
17043                valid;
17044
17045            if (validator) {
17046                if (!validator.call) {
17047                    // Assume string - trying to keep critical path tight, so avoiding Lang check
17048                    validator = this[validator];
17049                }
17050                if (validator) {
17051                    valid = validator.call(host, newVal, name, opts);
17052
17053                    if (!valid && initializing) {
17054                        newVal = cfg.defaultValue;
17055                        valid = true; // Assume it's valid, for perf.
17056                    }
17057                }
17058            }
17059
17060            if (!validator || valid) {
17061                if (setter) {
17062                    if (!setter.call) {
17063                        // Assume string - trying to keep critical path tight, so avoiding Lang check
17064                        setter = this[setter];
17065                    }
17066                    if (setter) {
17067                        retVal = setter.call(host, newVal, name, opts);
17068
17069                        if (retVal === INVALID_VALUE) {
17070                            if (initializing) {
17071                                newVal = cfg.defaultValue;
17072                            } else {
17073                                allowSet = false;
17074                            }
17075                        } else if (retVal !== undefined){
17076                            newVal = retVal;
17077                        }
17078                    }
17079                }
17080
17081                if (allowSet) {
17082                    if(!subAttrName && (newVal === prevRawVal) && !Lang.isObject(newVal)) {
17083                        allowSet = false;
17084                    } else {
17085                        // Store value
17086                        if (!(INIT_VALUE in cfg)) {
17087                            cfg.initValue = newVal;
17088                        }
17089                        host._setStateVal(attrName, newVal);
17090                    }
17091                }
17092
17093            } else {
17094                allowSet = false;
17095            }
17096
17097            return allowSet;
17098        },
17099
17100        /**
17101         * Sets multiple attribute values.
17102         *
17103         * @method setAttrs
17104         * @param {Object} attrs  An object with attributes name/value pairs.
17105         * @param {Object} [opts] Optional data providing the circumstances for the change.
17106         * @return {Object} A reference to the host object.
17107         * @chainable
17108         */
17109        setAttrs : function(attrs, opts) {
17110            return this._setAttrs(attrs, opts);
17111        },
17112
17113        /**
17114         * Implementation behind the public setAttrs method, to set multiple attribute values.
17115         *
17116         * @method _setAttrs
17117         * @protected
17118         * @param {Object} attrs  An object with attributes name/value pairs.
17119         * @param {Object} [opts] Optional data providing the circumstances for the change
17120         * @return {Object} A reference to the host object.
17121         * @chainable
17122         */
17123        _setAttrs : function(attrs, opts) {
17124            var attr;
17125            for (attr in attrs) {
17126                if ( attrs.hasOwnProperty(attr) ) {
17127                    this.set(attr, attrs[attr], opts);
17128                }
17129            }
17130            return this;
17131        },
17132
17133        /**
17134         * Gets multiple attribute values.
17135         *
17136         * @method getAttrs
17137         * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are
17138         * returned. If set to true, all attributes modified from their initial values are returned.
17139         * @return {Object} An object with attribute name/value pairs.
17140         */
17141        getAttrs : function(attrs) {
17142            return this._getAttrs(attrs);
17143        },
17144
17145        /**
17146         * Implementation behind the public getAttrs method, to get multiple attribute values.
17147         *
17148         * @method _getAttrs
17149         * @protected
17150         * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are
17151         * returned. If set to true, all attributes modified from their initial values are returned.
17152         * @return {Object} An object with attribute name/value pairs.
17153         */
17154        _getAttrs : function(attrs) {
17155            var obj = {},
17156                attr, i, len,
17157                modifiedOnly = (attrs === true);
17158
17159            // TODO - figure out how to get all "added"
17160            if (!attrs || modifiedOnly) {
17161                attrs = O.keys(this._state.data);
17162            }
17163
17164            for (i = 0, len = attrs.length; i < len; i++) {
17165                attr = attrs[i];
17166
17167                if (!modifiedOnly || this._getStateVal(attr) != this._state.get(attr, INIT_VALUE)) {
17168                    // Go through get, to honor cloning/normalization
17169                    obj[attr] = this.get(attr);
17170                }
17171            }
17172
17173            return obj;
17174        },
17175
17176        /**
17177         * Configures a group of attributes, and sets initial values.
17178         *
17179         * <p>
17180         * <strong>NOTE:</strong> This method does not isolate the configuration object by merging/cloning.
17181         * The caller is responsible for merging/cloning the configuration object if required.
17182         * </p>
17183         *
17184         * @method addAttrs
17185         * @chainable
17186         *
17187         * @param {Object} cfgs An object with attribute name/configuration pairs.
17188         * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply.
17189         * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only.
17190         * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set.
17191         * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration.
17192         * See <a href="#method_addAttr">addAttr</a>.
17193         *
17194         * @return {Object} A reference to the host object.
17195         */
17196        addAttrs : function(cfgs, values, lazy) {
17197            if (cfgs) {
17198                this._tCfgs = cfgs;
17199                this._tVals = (values) ? this._normAttrVals(values) : null;
17200                this._addAttrs(cfgs, this._tVals, lazy);
17201                this._tCfgs = this._tVals = null;
17202            }
17203
17204            return this;
17205        },
17206
17207        /**
17208         * Implementation behind the public addAttrs method.
17209         *
17210         * This method is invoked directly by get if it encounters a scenario
17211         * in which an attribute's valueFn attempts to obtain the
17212         * value an attribute in the same group of attributes, which has not yet
17213         * been added (on demand initialization).
17214         *
17215         * @method _addAttrs
17216         * @private
17217         * @param {Object} cfgs An object with attribute name/configuration pairs.
17218         * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply.
17219         * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only.
17220         * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set.
17221         * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration.
17222         * See <a href="#method_addAttr">addAttr</a>.
17223         */
17224        _addAttrs : function(cfgs, values, lazy) {
17225            var tCfgs = this._tCfgs,
17226                tVals = this._tVals,
17227                attr,
17228                attrCfg,
17229                value;
17230
17231            for (attr in cfgs) {
17232                if (cfgs.hasOwnProperty(attr)) {
17233
17234                    // Not Merging. Caller is responsible for isolating configs
17235                    attrCfg = cfgs[attr];
17236                    attrCfg.defaultValue = attrCfg.value;
17237
17238                    // Handle simple, complex and user values, accounting for read-only
17239                    value = this._getAttrInitVal(attr, attrCfg, tVals);
17240
17241                    if (value !== undefined) {
17242                        attrCfg.value = value;
17243                    }
17244
17245                    if (tCfgs[attr]) {
17246                        tCfgs[attr] = undefined;
17247                    }
17248
17249                    this.addAttr(attr, attrCfg, lazy);
17250                }
17251            }
17252        },
17253
17254        /**
17255         * Utility method to protect an attribute configuration
17256         * hash, by merging the entire object and the individual
17257         * attr config objects.
17258         *
17259         * @method _protectAttrs
17260         * @protected
17261         * @param {Object} attrs A hash of attribute to configuration object pairs.
17262         * @return {Object} A protected version of the attrs argument.
17263         * @deprecated Use `AttributeCore.protectAttrs()` or
17264         *   `Attribute.protectAttrs()` which are the same static utility method.
17265         */
17266        _protectAttrs : AttributeCore.protectAttrs,
17267
17268        /**
17269         * Utility method to normalize attribute values. The base implementation
17270         * simply merges the hash to protect the original.
17271         *
17272         * @method _normAttrVals
17273         * @param {Object} valueHash An object with attribute name/value pairs
17274         *
17275         * @return {Object} An object literal with 2 properties - "simple" and "complex",
17276         * containing simple and complex attribute values respectively keyed
17277         * by the top level attribute name, or null, if valueHash is falsey.
17278         *
17279         * @private
17280         */
17281        _normAttrVals : function(valueHash) {
17282            var vals,
17283                subvals,
17284                path,
17285                attr,
17286                v, k;
17287
17288            if (!valueHash) {
17289                return null;
17290            }
17291
17292            vals = {};
17293
17294            for (k in valueHash) {
17295                if (valueHash.hasOwnProperty(k)) {
17296                    if (k.indexOf(DOT) !== -1) {
17297                        path = k.split(DOT);
17298                        attr = path.shift();
17299
17300                        subvals = subvals || {};
17301
17302                        v = subvals[attr] = subvals[attr] || [];
17303                        v[v.length] = {
17304                            path : path,
17305                            value: valueHash[k]
17306                        };
17307                    } else {
17308                        vals[k] = valueHash[k];
17309                    }
17310                }
17311            }
17312
17313            return { simple:vals, complex:subvals };
17314        },
17315
17316        /**
17317         * Returns the initial value of the given attribute from
17318         * either the default configuration provided, or the
17319         * over-ridden value if it exists in the set of initValues
17320         * provided and the attribute is not read-only.
17321         *
17322         * @param {String} attr The name of the attribute
17323         * @param {Object} cfg The attribute configuration object
17324         * @param {Object}
17324 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
17325         *
17326         * @return {Any} The initial value of the attribute.
17327         *
17328         * @method _getAttrInitVal
17329         * @private
17330         */
17331        _getAttrInitVal : function(attr, cfg, initValues) {
17332            var val = cfg.value,
17333                valFn = cfg.valueFn,
17334                tmpVal,
17335                initValSet = false,
17336                readOnly = cfg.readOnly,
17337                simple,
17338                complex,
17339                i,
17340                l,
17341                path,
17342                subval,
17343                subvals;
17344
17345            if (!readOnly && initValues) {
17346                // Simple Attributes
17347                simple = initValues.simple;
17348                if (simple && simple.hasOwnProperty(attr)) {
17349                    val = simple[attr];
17350                    initValSet = true;
17351                }
17352            }
17353
17354            if (valFn && !initValSet) {
17355                if (!valFn.call) {
17356                    valFn = this[valFn];
17357                }
17358                if (valFn) {
17359                    tmpVal = valFn.call(this, attr);
17360                    val = tmpVal;
17361                }
17362            }
17363
17364            if (!readOnly && initValues) {
17365
17366                // Complex Attributes (complex values applied, after simple, in case both are set)
17367                complex = initValues.complex;
17368
17369                if (complex && complex.hasOwnProperty(attr) && (val !== undefined) && (val !== null)) {
17370                    subvals = complex[attr];
17371                    for (i = 0, l = subvals.length; i < l; ++i) {
17372                        path = subvals[i].path;
17373                        subval = subvals[i].value;
17374                        O.setValue(val, path, subval);
17375                    }
17376                }
17377            }
17378
17379            return val;
17380        },
17381
17382        /**
17383         * Utility method to set up initial attributes defined during construction,
17384         * either through the constructor.ATTRS property, or explicitly passed in.
17385         *
17386         * @method _initAttrs
17387         * @protected
17388         * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
17389         *        These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
17390         * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
17391         *        These are not merged/cloned. The caller is responsible for isolating user provided values if required.
17392         * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
17393         */
17394        _initAttrs : function(attrs, values, lazy) {
17395            // ATTRS support for Node, which is not Base based
17396            attrs = attrs || this.constructor.ATTRS;
17397
17398            var Base = Y.Base,
17399                BaseCore = Y.BaseCore,
17400                baseInst = (Base && Y.instanceOf(this, Base)),
17401                baseCoreInst = (!baseInst && BaseCore && Y.instanceOf(this, BaseCore));
17402
17403            if (attrs && !baseInst && !baseCoreInst) {
17404                this.addAttrs(Y.AttributeCore.protectAttrs(attrs), values, lazy);
17405            }
17406        }
17407    };
17408
17409    Y.AttributeCore = AttributeCore;
17410
17411
17412}, 'patched-v3.18.1', {"requires": ["oop"]});
17413
17414YUI.add('attribute-observable', function (Y, NAME) {
17415
17416    /*For log lines*/
17417    /*jshint maxlen:200*/
17418
17419
17420    /**
17421     * The attribute module provides an augmentable Attribute implementation, which
17422     * adds configurable attributes and attribute change events to the class being
17423     * augmented. It also provides a State class, which is used internally by Attribute,
17424     * but can also be used independently to provide a name/property/value data structure to
17425     * store state.
17426     *
17427     * @module attribute
17428     */
17429
17430    /**
17431     * The `attribute-observable` submodule provides augmentable attribute change event support
17432     * for AttributeCore based implementations.
17433     *
17434     * @module attribute
17435     * @submodule attribute-observable
17436     */
17437    var EventTarget = Y.EventTarget,
17438
17439        CHANGE = "Change",
17440        BROADCAST = "broadcast";
17441
17442    /**
17443     * Provides an augmentable implementation of attribute change events for
17444     * AttributeCore.
17445     *
17446     * @class AttributeObservable
17447     * @extensionfor AttributeCore
17448     * @uses EventTarget
17449     */
17450    function AttributeObservable() {
17451        // Perf tweak - avoid creating event literals if not required.
17452        this._ATTR_E_FACADE = {};
17453
17454        EventTarget.call(this, {emitFacade:true});
17455    }
17456
17457    AttributeObservable._ATTR_CFG = [BROADCAST];
17458
17459    AttributeObservable.prototype = {
17460
17461        /**
17462         * Sets the value of an attribute.
17463         *
17464         * @method set
17465         * @chainable
17466         *
17467         * @param {String} name The name of the attribute. If the
17468         * current value of the attribute is an Object, dot notation can be used
17469         * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
17470         *
17471         * @param {Any} value The value to set the attribute to.
17472         *
17473         * @param {Object} opts (Optional) Optional event data to be mixed into
17474         * the event facade passed to subscribers of the attribute's change event. This
17475         * can be used as a flexible way to identify the source of a call to set, allowing
17476         * the developer to distinguish between set called internally by the host, vs.
17477         * set called externally by the application developer.
17478         *
17479         * @return {Object} A reference to the host object.
17480         */
17481        set : function(name, val, opts) {
17482            return this._setAttr(name, val, opts);
17483        },
17484
17485        /**
17486         * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
17487         *
17488         * @method _set
17489         * @protected
17490         * @chainable
17491         *
17492         * @param {String} name The name of the attribute.
17493         * @param {Any} val The value to set the attribute to.
17494         * @param {Object} opts (Optional) Optional event data to be mixed into
17495         * the event facade passed to subscribers of the attribute's change event.
17496         * @return {Object} A reference to the host object.
17497         */
17498        _set : function(name, val, opts) {
17499            return this._setAttr(name, val, opts, true);
17500        },
17501
17502        /**
17503         * Sets multiple attribute values.
17504         *
17505         * @method setAttrs
17506         * @param {Object} attrs  An object with attributes name/value pairs.
17507         * @param {Object} opts  Properties to mix into the event payload. These are shared and mixed into each set
17508         * @return {Object} A reference to the host object.
17509         * @chainable
17510         */
17511        setAttrs : function(attrs, opts) {
17512            return this._setAttrs(attrs, opts);
17513        },
17514
17515        /**
17516         * Implementation behind the public setAttrs method, to set multiple attribute values.
17517         *
17518         * @method _setAttrs
17519         * @protected
17520         * @param {Object} attrs  An object with attributes name/value pairs.
17521         * @param {Object} opts  Properties to mix into the event payload. These are shared and mixed into each set
17522         * @return {Object} A reference to the host object.
17523         * @chainable
17524         */
17525        _setAttrs : function(attrs, opts) {
17526            var attr;
17527            for (attr in attrs) {
17528                if ( attrs.hasOwnProperty(attr) ) {
17529                    this.set(attr, attrs[attr], opts);
17530                }
17531            }
17532            return this;
17533        },
17534
17535        /**
17536         * Utility method to help setup the event payload and fire the attribute change event.
17537         *
17538         * @method _fireAttrChange
17539         * @private
17540         * @param {String} attrName The name of the attribute
17541         * @param {String} subAttrName The full path of the property being changed,
17542         * if this is a sub-attribute value being change. Otherwise null.
17543         * @param {Any} currVal The current value of the attribute
17544         * @param {Any} newVal The new value of the attribute
17545         * @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
17546         * @param {Object} [cfg] The attribute config stored in State, if already available.
17547         */
17548        _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
17549            var host = this,
17550                eventName = this._getFullType(attrName + CHANGE),
17551                state = host._state,
17552                facade,
17553                broadcast,
17554                e;
17555
17556            if (!cfg) {
17557                cfg = state.data[attrName] || {};
17558            }
17559
17560            if (!cfg.published) {
17561
17562                // PERF: Using lower level _publish() for
17563                // critical path performance
17564                e = host._publish(eventName);
17565
17566                e.emitFacade = true;
17567                e.defaultTargetOnly = true;
17568                e.defaultFn = host._defAttrChangeFn;
17569
17570                broadcast = cfg.broadcast;
17571                if (broadcast !== undefined) {
17572                    e.broadcast = broadcast;
17573                }
17574
17575                cfg.published = true;
17576            }
17577
17578            if (opts) {
17579                facade = Y.merge(opts);
17580                facade._attrOpts = opts;
17581            } else {
17582                facade = host._ATTR_E_FACADE;
17583            }
17584
17585            // Not using the single object signature for fire({type:..., newVal:...}), since
17586            // we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
17587
17588            facade.attrName = attrName;
17589            facade.subAttrName = subAttrName;
17590            facade.prevVal = currVal;
17591            facade.newVal = newVal;
17592
17593            if (host._hasPotentialSubscribers(eventName)) {
17594                host.fire(eventName, facade);
17595            } else {
17596                this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
17597            }
17598        },
17599
17600        /**
17601         * Default function for attribute change events.
17602         *
17603         * @private
17604         * @method _defAttrChangeFn
17605         * @param {EventFacade} e The event object for attribute change events.
17606         * @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not
17607         */
17608        _defAttrChangeFn : function(e, eventFastPath) {
17609
17610            var opts = e._attrOpts;
17611            if (opts) {
17612                delete e._attrOpts;
17613            }
17614
17615            if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) {
17616
17617
17618                if (!eventFastPath) {
17619                    // Prevent "after" listeners from being invoked since nothing changed.
17620                    e.stopImmediatePropagation();
17621                }
17622
17623            } else {
17624                if (!eventFastPath) {
17625                    e.newVal = this.get(e.attrName);
17626                }
17627            }
17628        }
17629    };
17630
17631    // Basic prototype augment - no lazy constructor invocation.
17632    Y.mix(AttributeObservable, EventTarget, false, null, 1);
17633
17634    Y.AttributeObservable = AttributeObservable;
17635
17636    /**
17637    The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now
17638    an alias for the `AttributeObservable` class extension. Use that class
17639    extnesion instead. This alias will be removed in a future version of YUI.
17640
17641    @class AttributeEvents
17642    @uses EventTarget
17643    @deprecated Use `AttributeObservable` instead.
17644    @see AttributeObservable
17645    **/
17646    Y.AttributeEvents = AttributeObservable;
17647
17648
17649}, 'patched-v3.18.1', {"requires": ["event-custom"]});
17650
17651YUI.add('attribute-extras', function (Y, NAME) {
17652
17653    /**
17654     * The attribute module provides an augmentable Attribute implementation, which
17655     * adds configurable attributes and attribute change events to the class being
17656     * augmented. It also provides a State class, which is used internally by Attribute,
17657     * but can also be used independently to provide a name/property/value data structure to
17658     * store state.
17659     *
17660     * @module attribute
17661     */
17662
17663    /**
17664     * The attribute-extras submodule provides less commonly used attribute methods, and can
17665     * be augmented/mixed into an implemention which used attribute-core.
17666     *
17667     * @module attribute
17668     * @submodule attribute-extras
17669     */
17670    var BROADCAST = "broadcast",
17671        PUBLISHED = "published",
17672        INIT_VALUE = "initValue",
17673
17674        MODIFIABLE = {
17675            readOnly:1,
17676            writeOnce:1,
17677            getter:1,
17678            broadcast:1
17679        };
17680
17681    /**
17682     * A augmentable implementation for AttributeCore, providing less frequently used
17683     * methods for Attribute management such as modifyAttrs(), removeAttr and reset()
17684     *
17685     * @class AttributeExtras
17686     * @extensionfor AttributeCore
17687     */
17688    function AttributeExtras() {}
17689
17690    AttributeExtras.prototype = {
17691
17692        /**
17693         * Updates the configuration of an attribute which has already been added.
17694         * <p>
17695         * The properties which can be modified through this interface are limited
17696         * to the following subset of attributes, which can be safely modified
17697         * after a value has already been set on the attribute:
17698         * </p>
17699         * <dl>
17700         *  <dt>readOnly;</dt>
17701         *  <dt>writeOnce;</dt>
17702         *  <dt>broadcast; and</dt>
17703         *  <dt>getter.</dt>
17704         * </dl>
17705         * <p>
17706         * Note: New attributes cannot be added using this interface. New attributes must be
17707         * added using {{#crossLink "AttributeCore/addAttr:method"}}addAttr{{/crossLink}}, or an
17708         * appropriate manner for a class which utilises Attributes (e.g. the
17709         * {{#crossLink "Base/ATTRS:property"}}ATTRS{{/crossLink}} property in
17710         * {{#crossLink "Base"}}Base{{/crossLink}}).
17711         * </p>
17712         * @method modifyAttr
17713         * @param {String} name The name of the attribute whose configuration is to be updated.
17714         * @param {Object} config An object with configuration property/value pairs, specifying the configuration properties to modify.
17715         */
17716        modifyAttr: function(name, config) {
17717            var host = this, // help compression
17718                prop, state;
17719
17720            if (host.attrAdded(name)) {
17721
17722                if (host._isLazyAttr(name)) {
17723                    host._addLazyAttr(name);
17724                }
17725
17726                state = host._state;
17727                for (prop in config) {
17728                    if (MODIFIABLE[prop] && config.hasOwnProperty(prop)) {
17729                        state.add(name, prop, config[prop]);
17730
17731                        // If we reconfigured broadcast, need to republish
17732                        if (prop === BROADCAST) {
17733                            state.remove(name, PUBLISHED);
17734                        }
17735                    }
17736                }
17737            } else {
17738            }
17739        },
17740
17741        /**
17742         * Removes an attribute from the host object
17743         *
17744         * @method removeAttr
17745         * @param {String} name The name of the attribute to be removed.
17746         */
17747        removeAttr: function(name) {
17748            this._state.removeAll(name);
17749        },
17750
17751        /**
17752         * Resets the attribute (or all attributes) to its initial value, as long as
17753         * the attribute is not readOnly, or writeOnce.
17754         *
17755         * @method reset
17756         * @param {String} name Optional. The name of the attribute to reset.  If omitted, all attributes are reset.
17757         * @return {Object} A reference to the host object.
17758         * @chainable
17759         */
17760        reset : function(name) {
17761            var host = this;  // help compression
17762
17763            if (name) {
17764                if (host._isLazyAttr(name)) {
17765                    host._addLazyAttr(name);
17766                }
17767                host.set(name, host._state.get(name, INIT_VALUE));
17768            } else {
17769                Y.Object.each(host._state.data, function(v, n) {
17770                    host.reset(n);
17771                });
17772            }
17773            return host;
17774        },
17775
17776        /**
17777         * Returns an object with the configuration properties (and value)
17778         * for the given attribute. If attrName is not provided, returns the
17779         * configuration properties for all attributes.
17780         *
17781         * @method _getAttrCfg
17782         * @protected
17783         * @param {String} name Optional. The attribute name. If not provided, the method will return the configuration for all attributes.
17784         * @return {Object} The configuration properties for the given attribute, or all attributes.
17785         */
17786        _getAttrCfg : function(name) {
17787            var o,
17788                state = this._state;
17789
17790            if (name) {
17791                o = state.getAll(name) || {};
17792            } else {
17793                o = {};
17794                Y.each(state.data, function(v, n) {
17795                    o[n] = state.getAll(n);
17796                });
17797            }
17798
17799            return o;
17800        }
17801    };
17802
17803    Y.AttributeExtras = AttributeExtras;
17804
17805
17806}, 'patched-v3.18.1', {"requires": ["oop"]});
17807
17808YUI.add('base-base', function (Y, NAME) {
17809
17810    /**
17811     * The base module provides the Base class, which objects requiring attribute and custom event support can extend.
17812     * The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides
17813     * plugin support and also provides the BaseCore.build method which provides a way to build custom classes using extensions.
17814     *
17815     * @module base
17816     */
17817
17818    /**
17819     * The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
17820     * and without the extension support provided by BaseCore.build.
17821     *
17822     * @module base
17823     * @submodule base-base
17824     */
17825
17826    var AttributeCore   = Y.AttributeCore,
17827        AttributeExtras = Y.AttributeExtras,
17828        BaseCore        = Y.BaseCore,
17829        BaseObservable  = Y.BaseObservable;
17830
17831    /**
17832     * <p>
17833     * A base class which objects requiring attributes and custom event support can
17834     * extend. Base also handles the chaining of initializer and destructor methods across
17835     * the hierarchy as part of object construction and destruction. Additionally, attributes configured
17836     * through the static <a href="#property_ATTRS">ATTRS</a> property for each class
17837     * in the hierarchy will be initialized by Base.
17838     * </p>
17839     *
17840     * <p>
17841     * **NOTE:** Prior to version 3.11.0, ATTRS would get added a class at a time. That is,
17842     * Base would loop through each class in the hierarchy, and add the class' ATTRS, and
17843     * then call it's initializer, and move on to the subclass' ATTRS and initializer. As of
17844     * 3.11.0, ATTRS from all classes in the hierarchy are added in one `addAttrs` call before
17845     * any initializers are called. This fixes subtle edge-case issues with subclass ATTRS overriding
17846     * superclass `setter`, `getter` or `valueFn` definitions and being unable to get/set attributes
17847     * defined by the subclass. This order of operation change may impact `setter`, `getter` or `valueFn`
17848     * code which expects a superclass' initializer to have run. This is expected to be rare, but to support
17849     * it, Base supports a `_preAddAttrs()`, method hook (same signature as `addAttrs`). Components can
17850     * implement this method on their prototype for edge cases which do require finer control over
17851     * the order in which attributes are added (see widget-htmlparser).
17852     * </p>
17853     *
17854     * <p>
17855     * The static <a href="#property_NAME">NAME</a> property of each class extending
17856     * from Base will be used as the identifier for the class, and is used by Base to prefix
17857     * all events fired by instances of that class.
17858     * </p>
17859     *
17860     * @class Base
17861     * @constructor
17862     * @uses BaseCore
17863     * @uses BaseObservable
17864     * @uses AttributeCore
17865     * @uses AttributeObservable
17866     * @uses AttributeExtras
17867     * @uses EventTarget
17868     *
17869     * @param {Object} config Object with configuration property name/value pairs. The object can be
17870     * used to provide default values for the objects published attributes.
17871     *
17872     * <p>
17873     * The config object can also contain the following non-attribute properties, providing a convenient
17874     * way to configure events listeners and plugins for the instance, as part of the constructor call:
17875     * </p>
17876     *
17877     * <dl>
17878     *   <dt>on</dt>
17879     *   <dd>An event name to listener function map, to register event listeners for the "on" moment of the event.
17880     *       A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd>
17881     *   <dt>after</dt>
17882     *   <dd>An event name to listener function map, to register event listeners for the "after" moment of the event.
17883     *       A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd>
17884     *   <dt>bubbleTargets</dt>
17885     *   <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance.
17886     *       A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd>
17887     *   <dt>plugins</dt>
17888     *   <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details).
17889     *       A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd>
17890     * </dl>
17891     */
17892    function Base() {
17893        BaseCore.apply(this, arguments);
17894        BaseObservable.apply(this, arguments);
17895        AttributeExtras.apply(this, arguments);
17896    }
17897
17898    /**
17899     * The list of properties which can be configured for
17900     * each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
17901     *
17902     * @property _ATTR_CFG
17903     * @type Array
17904     * @static
17905     * @private
17906     */
17907    Base._ATTR_CFG = BaseCore._ATTR_CFG.concat(BaseObservable._ATTR_CFG);
17908
17909    /**
17910     * The array of non-attribute configuration properties supported by this class.
17911     *
17912     * `Base` supports "on", "after", "plugins" and "bubbleTargets" properties,
17913     * which are not set up as attributes.
17914     *
17915     * This property is primarily required so that when
17916     * <a href="#property__allowAdHocAttrs">`_allowAdHocAttrs`</a> is enabled by
17917     * a class, non-attribute configurations don't get added as ad-hoc attributes.
17918     *
17919     * @property _NON_ATTRS_CFG
17920     * @type Array
17921     * @static
17922     * @private
17923     */
17924    Base._NON_ATTRS_CFG = BaseCore._NON_ATTRS_CFG.concat(BaseObservable._NON_ATTRS_CFG);
17925
17926    /**
17927     * <p>
17928     * The string to be used to identify instances of
17929     * this class, for example in prefixing events.
17930     * </p>
17931     * <p>
17932     * Classes extending Base, should define their own
17933     * static NAME property, which should be camelCase by
17934     * convention (e.g. MyClass.NAME = "myClass";).
17935     * </p>
17936     * @property NAME
17937     * @type String
17938     * @static
17939     */
17940    Base.NAME = 'base';
17941
17942    /**
17943     * The default set of attributes which will be available for instances of this class, and
17944     * their configuration. In addition to the configuration properties listed by
17945     * Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
17946     * can also be configured with a "cloneDefaultValue" property, which defines how the statically
17947     * defined value field should be protected ("shallow", "deep" and false are supported values).
17948     *
17949     * By default if the value is an object literal or an array it will be "shallow" cloned, to
17950     * protect the default value.
17951     *
17952     * @property ATTRS
17953     * @type Object
17954     * @static
17955     */
17956    Base.ATTRS = AttributeCore.protectAttrs(BaseCore.ATTRS);
17957
17958    /**
17959    Provides a way to safely modify a `Y.Base` subclass' static `ATTRS` after
17960    the class has been defined or created.
17961
17962    Base-based classes cache information about the class hierarchy in order to
17963    efficiently create instances. This cache includes includes the aggregated
17964    `ATTRS` configs. If the static `ATTRS` configs need to be modified after the
17965    class has been defined or create, then use this method which will make sure
17966    to clear any cached data before making any modifications.
17967
17968    @method modifyAttrs
17969    @param {Function} [ctor] The constructor function whose `ATTRS` should be
17970        modified. If a `ctor` function is not specified, then `this` is assumed
17971        to be the constructor which hosts the `ATTRS`.
17972    @param {Object} configs The collection of `ATTRS` configs to mix with the
17973        existing attribute configurations.
17974    @static
17975    @since 3.10.0
17976    **/
17977    Base.modifyAttrs = BaseCore.modifyAttrs;
17978
17979    Y.mix(Base, BaseCore, false, null, 1);
17980    Y.mix(Base, AttributeExtras, false, null, 1);
17981
17982    // Needs to be `true`, to overwrite methods from `BaseCore`.
17983    Y.mix(Base, BaseObservable, true, null, 1);
17984
17985    // Fix constructor
17986    Base.prototype.constructor = Base;
17987
17988    Y.Base = Base;
17989
17990
17991}, 'patched-v3.18.1', {"requires": ["attribute-base", "base-core", "base-observable"]});
17992
17993YUI.add('base-pluginhost', function (Y, NAME) {
17994
17995    /**
17996     * The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
17997     * Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
17998     *
17999     * @module base
18000     * @submodule base-pluginhost
18001     * @for Base
18002     */
18003
18004    var Base = Y.Base,
18005        PluginHost = Y.Plugin.Host;
18006
18007    Y.mix(Base, PluginHost, false, null, 1);
18008
18009    /**
18010     * Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
18011     * method for argument and return value details.
18012     *
18013     * @method plug
18014     * @static
18015     */
18016    Base.plug = PluginHost.plug;
18017
18018    /**
18019     * Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
18020     * aliased method for argument and return value details.
18021     *
18022     * @method unplug
18023     * @static
18024     */
18025    Base.unplug = PluginHost.unplug;
18026
18027
18028}, 'patched-v3.18.1', {"requires": ["base-base", "pluginhost"]});
18029
18030YUI.add('classnamemanager', function (Y, NAME) {
18031
18032/**
18033* Contains a singleton (ClassNameManager) that enables easy creation and caching of
18034* prefixed class names.
18035* @module classnamemanager
18036*/
18037
18038/**
18039 * A singleton class providing:
18040 *
18041 * <ul>
18042 *    <li>Easy creation of prefixed class names</li>
18043 *    <li>Caching of previously created class names for improved performance.</li>
18044 * </ul>
18045 *
18046 * @class ClassNameManager
18047 * @static
18048 */
18049
18050// String constants
18051var CLASS_NAME_PREFIX = 'classNamePrefix',
18052	CLASS_NAME_DELIMITER = 'classNameDelimiter',
18053    CONFIG = Y.config;
18054
18055// Global config
18056
18057/**
18058 * Configuration property indicating the prefix for all CSS class names in this YUI instance.
18059 *
18060 * @property classNamePrefix
18061 * @type {String}
18062 * @default "yui"
18063 * @static
18064 */
18065CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui3';
18066
18067/**
18068 * Configuration property indicating the delimiter used to compose all CSS class names in
18069 * this YUI instance.
18070 *
18071 * @property classNameDelimiter
18072 * @type {String}
18073 * @default "-"
18074 * @static
18075 */
18076CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-';
18077
18078Y.ClassNameManager = function () {
18079
18080	var sPrefix    = CONFIG[CLASS_NAME_PREFIX],
18081		sDelimiter = CONFIG[CLASS_NAME_DELIMITER];
18082
18083	return {
18084
18085		/**
18086		 * Returns a class name prefixed with the value of the
18087		 * <code>Y.config.classNamePrefix</code> attribute + the provided strings.
18088		 * Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the
18089		 * provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar
18090		 *
18091		 * @method getClassName
18092		 * @param {String} [classnameSection*] one or more classname sections to be joined
18093		 * @param {Boolean} skipPrefix If set to true, the classname will not be prefixed with the default Y.config.classNameDelimiter value.
18094		 */
18095		getClassName: Y.cached(function () {
18096
18097            var args = Y.Array(arguments);
18098
18099            if (args[args.length-1] !== true) {
18100                args.unshift(sPrefix);
18101            } else {
18102                args.pop();
18103            }
18104
18105			return args.join(sDelimiter);
18106		})
18107
18108	};
18109
18110}();
18111
18112
18113}, 'patched-v3.18.1', {"requires": ["yui-base"]});
18114
18115YUI.add('datatype-xml-format', function (Y, NAME) {
18116
18117/**
18118 * The Number Utility provides type-conversion and string-formatting
18119 * convenience methods for Numbers.
18120 *
18121 * @module datatype-xml
18122 * @submodule datatype-xml-format
18123 */
18124
18125/**
18126 * XML provides a set of utility functions to operate against XML documents.
18127 *
18128 * @class XML
18129 * @static
18130 */
18131var LANG = Y.Lang;
18132
18133Y.mix(Y.namespace("XML"), {
18134    /**
18135     * Converts data to type XMLDocument.
18136     *
18137     * @method format
18138     * @param data {XMLDocument} Data to convert.
18139     * @return {String} String.
18140     */
18141    format: function(data) {
18142        try {
18143            if(!LANG.isUndefined(data.getXml)) {
18144                return data.getXml();
18145            }
18146
18147            if(!LANG.isUndefined(XMLSerializer)) {
18148                return (new XMLSerializer()).serializeToString(data);
18149            }
18150        }
18151        catch(e) {
18152            if(data && data.xml) {
18153                return data.xml;
18154            }
18155            else {
18156                return (LANG.isValue(data) && data.toString) ? data.toString() : "";
18157            }
18158        }
18159    }
18160});
18161
18162Y.namespace("DataType");
18163Y.DataType.XML = Y.XML;
18164
18165
18166}, 'patched-v3.18.1');
18167
18168YUI.add('datatype-xml-parse', function (Y, NAME) {
18169
18170/**
18171 * Parse XML submodule.
18172 *
18173 * @module datatype-xml
18174 * @submodule datatype-xml-parse
18175 * @for XML
18176 */
18177
18178Y.mix(Y.namespace("XML"), {
18179    /**
18180     * Converts data to type XMLDocument.
18181     *
18182     * @method parse
18183     * @param data {String} Data to convert.
18184     * @return {XMLDocument} XML Document.
18185     */
18186    parse: function(data) {
18187        var xmlDoc = null, win;
18188        if (typeof data === "string") {
18189            win = Y.config.win;
18190            if (win.ActiveXObject !== undefined) {
18191                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
18192                xmlDoc.async = false;
18193                xmlDoc.loadXML(data);
18194            } else if (win.DOMParser !== undefined) {
18195                xmlDoc = new DOMParser().parseFromString(data, "text/xml");
18196            } else if (win.Windows !== undefined) {
18197                xmlDoc = new Windows.Data.Xml.Dom.XmlDocument();
18198                xmlDoc.loadXml(data);
18199            }
18200        }
18201
18202        if (xmlDoc === null || xmlDoc.documentElement === null || xmlDoc.documentElement.nodeName === "parsererror") {
18203        }
18204
18205        return xmlDoc;
18206    }
18207});
18208
18209// Add Parsers shortcut
18210Y.namespace("Parsers").xml = Y.XML.parse;
18211
18212Y.namespace("DataType");
18213Y.DataType.XML = Y.XML;
18214
18215
18216}, 'patched-v3.18.1');
18217
18218YUI.add('dom-base', function (Y, NAME) {
18219
18220/**
18221* @for DOM
18222* @module dom
18223*/
18224var documentElement = Y.config.doc.documentElement,
18225    Y_DOM = Y.DOM,
18226    TAG_NAME = 'tagName',
18227    OWNER_DOCUMENT = 'ownerDocument',
18228    EMPTY_STRING = '',
18229    addFeature = Y.Features.add,
18230    testFeature = Y.Features.test;
18231
18232Y.mix(Y_DOM, {
18233    /**
18234     * Returns the text content of the HTMLElement.
18235     * @method getText
18236     * @param {HTMLElement} element The html element.
18237     * @return {String} The text content of the element (includes text of any descending elements).
18238     */
18239    getText: (documentElement.textContent !== undefined) ?
18240        function(element) {
18241            var ret = '';
18242            if (element) {
18243                ret = element.textContent;
18244            }
18245            return ret || '';
18246        } : function(element) {
18247            var ret = '';
18248            if (element) {
18249                ret = element.innerText || element.nodeValue; // might be a textNode
18250            }
18251            return ret || '';
18252        },
18253
18254    /**
18255     * Sets the text content of the HTMLElement.
18256     * @method setText
18257     * @param {HTMLElement} element The html element.
18258     * @param {String} content The content to add.
18259     */
18260    setText: (documentElement.textContent !== undefined) ?
18261        function(element, content) {
18262            if (element) {
18263                element.textContent = content;
18264            }
18265        } : function(element, content) {
18266            if ('innerText' in element) {
18267                element.innerText = content;
18268            } else if ('nodeValue' in element) {
18269                element.nodeValue = content;
18270            }
18271    },
18272
18273    CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
18274        'for': 'htmlFor',
18275        'class': 'className'
18276    } : { // w3c
18277        'htmlFor': 'for',
18278        'className': 'class'
18279    },
18280
18281    /**
18282     * Provides a normalized attribute interface.
18283     * @method setAttribute
18284     * @param {HTMLElement} el The target element for the attribute.
18285     * @param {String} attr The attribute to set.
18286     * @param {String} val The value of the attribute.
18287     */
18288    setAttribute: function(el, attr, val, ieAttr) {
18289        if (el && attr && el.setAttribute) {
18290            attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
18291            el.setAttribute(attr, val, ieAttr);
18292        }
18293    },
18294
18295
18296    /**
18297     * Provides a normalized attribute interface.
18298     * @method getAttribute
18299     * @param {HTMLElement} el The target element for the attribute.
18300     * @param {String} attr The attribute to get.
18301     * @return {String} The current value of the attribute.
18302     */
18303    getAttribute: function(el, attr, ieAttr) {
18304        ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
18305        var ret = '';
18306        if (el && attr && el.getAttribute) {
18307            attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
18308            // BUTTON value issue for IE < 8
18309            ret = (el.tagName === "BUTTON" && attr === 'value') ? Y_DOM.getValue(el) : el.getAttribute(attr, ieAttr);
18310
18311            if (ret === null) {
18312                ret = ''; // per DOM spec
18313            }
18314        }
18315        return ret;
18316    },
18317
18318    VALUE_SETTERS: {},
18319
18320    VALUE_GETTERS: {},
18321
18322    getValue: function(node) {
18323        var ret = '', // TODO: return null?
18324            getter;
18325
18326        if (node && node[TAG_NAME]) {
18327            getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
18328
18329            if (getter) {
18330                ret = getter(node);
18331            } else {
18332                ret = node.value;
18333            }
18334        }
18335
18336        // workaround for IE8 JSON stringify bug
18337        // which converts empty string values to null
18338        if (ret === EMPTY_STRING) {
18339            ret = EMPTY_STRING; // for real
18340        }
18341
18342        return (typeof ret === 'string') ? ret : '';
18343    },
18344
18345    setValue: function(node, val) {
18346        var setter;
18347
18348        if (node && node[TAG_NAME]) {
18349            setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
18350            val = (val === null) ? '' : val;
18351            if (setter) {
18352                setter(node, val);
18353            } else {
18354                node.value = val;
18355            }
18356        }
18357    },
18358
18359    creators: {}
18360});
18361
18362addFeature('value-set', 'select', {
18363    test: function() {
18364        var node = Y.config.doc.createElement('select');
18365        node.innerHTML = '<option>1</option><option>2</option>';
18366        node.value = '2';
18367        return (node.value && node.value === '2');
18368    }
18369});
18370
18371if (!testFeature('value-set', 'select')) {
18372    Y_DOM.VALUE_SETTERS.select = function(node, val) {
18373        for (var i = 0, options = node.getElementsByTagName('option'), option;
18374                option = options[i++];) {
18375            if (Y_DOM.getValue(option) === val) {
18376                option.selected = true;
18377                //Y_DOM.setAttribute(option, 'selected', 'selected');
18378                break;
18379            }
18380        }
18381    };
18382}
18383
18384Y.mix(Y_DOM.VALUE_GETTERS, {
18385    button: function(node) {
18386        return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
18387    }
18388});
18389
18390Y.mix(Y_DOM.VALUE_SETTERS, {
18391    // IE: node.value changes the button text, which should be handled via innerHTML
18392    button: function(node, val) {
18393        var attr = node.attributes.value;
18394        if (!attr) {
18395            attr = node[OWNER_DOCUMENT].createAttribute('value');
18396            node.setAttributeNode(attr);
18397        }
18398
18399        attr.value = val;
18400    }
18401});
18402
18403
18404Y.mix(Y_DOM.VALUE_GETTERS, {
18405    option: function(node) {
18406        var attrs = node.attributes;
18407        return (attrs.value && attrs.value.specified) ? node.value : node.text;
18408    },
18409
18410    select: function(node) {
18411        var val = node.value,
18412            options = node.options;
18413
18414        if (options && options.length) {
18415            // TODO: implement multipe select
18416            if (node.multiple) {
18417            } else if (node.selectedIndex > -1) {
18418                val = Y_DOM.getValue(options[node.selectedIndex]);
18419            }
18420        }
18421
18422        return val;
18423    }
18424});
18425var addClass, hasClass, removeClass;
18426
18427Y.mix(Y.DOM, {
18428    /**
18429     * Determines whether a DOM element has the given className.
18430     * @method hasClass
18431     * @for DOM
18432     * @param {HTMLElement} element The DOM element.
18433     * @param {String} className the class name to search for
18434     * @return {Boolean} Whether or not the element has the given class.
18435     */
18436    hasClass: function(node, className) {
18437        var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
18438        return re.test(node.className);
18439    },
18440
18441    /**
18442     * Adds a class name to a given DOM element.
18443     * @method addClass
18444     * @for DOM
18445     * @param {HTMLElement} element The DOM element.
18446     * @param {String} className the class name to add to the class attribute
18447     */
18448    addClass: function(node, className) {
18449        if (!Y.DOM.hasClass(node, className)) { // skip if already present
18450            node.className = Y.Lang.trim([node.className, className].join(' '));
18451        }
18452    },
18453
18454    /**
18455     * Removes a class name from a given element.
18456     * @method removeClass
18457     * @for DOM
18458     * @param {HTMLElement} element The DOM element.
18459     * @param {String} className the class name to remove from the class attribute
18460     */
18461    removeClass: function(node, className) {
18462        if (className && hasClass(node, className)) {
18463            node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' +
18464                            className + '(?:\\s+|$)'), ' '));
18465
18466            if ( hasClass(node, className) ) { // in case of multiple adjacent
18467                removeClass(node, className);
18468            }
18469        }
18470    },
18471
18472    /**
18473     * Replace a class with another class for a given element.
18474     * If no oldClassName is present, the newClassName is simply added.
18475     * @method replaceClass
18476     * @for DOM
18477     * @param {HTMLElement} element The DOM element
18478     * @param {String} oldClassName the class name to be replaced
18479     * @param {String} newClassName the class name that will be replacing the old class name
18480     */
18481    replaceClass: function(node, oldC, newC) {
18482        removeClass(node, oldC); // remove first in case oldC === newC
18483        addClass(node, newC);
18484    },
18485
18486    /**
18487     * If the className exists on the node it is removed, if it doesn't exist it is added.
18488     * @method toggleClass
18489     * @for DOM
18490     * @param {HTMLElement} element The DOM element
18491     * @param {String} className the class name to be toggled
18492     * @param {Boolean} addClass optional boolean to indicate whether class
18493     * should be added or removed regardless of current state
18494     */
18495    toggleClass: function(node, className, force) {
18496        var add = (force !== undefined) ? force :
18497                !(hasClass(node, className));
18498
18499        if (add) {
18500            addClass(node, className);
18501        } else {
18502            removeClass(node, className);
18503        }
18504    }
18505});
18506
18507hasClass = Y.DOM.hasClass;
18508removeClass = Y.DOM.removeClass;
18509addClass = Y.DOM.addClass;
18510
18511var re_tag = /<([a-z]+)/i,
18512
18513    Y_DOM = Y.DOM,
18514
18515    addFeature = Y.Features.add,
18516    testFeature = Y.Features.test,
18517
18518    creators = {},
18519
18520    createFromDIV = function(html, tag) {
18521        var div = Y.config.doc.createElement('div'),
18522            ret = true;
18523
18524        div.innerHTML = html;
18525        if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) {
18526            ret = false;
18527        }
18528
18529        return ret;
18530    },
18531
18532    re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
18533
18534    TABLE_OPEN = '<table>',
18535    TABLE_CLOSE = '</table>',
18536
18537    selectedIndex;
18538
18539Y.mix(Y.DOM, {
18540    _fragClones: {},
18541
18542    _create: function(html, doc, tag) {
18543        tag = tag || 'div';
18544
18545        var frag = Y_DOM._fragClones[tag];
18546        if (frag) {
18547            frag = frag.cloneNode(false);
18548        } else {
18549            frag = Y_DOM._fragClones[tag] = doc.createElement(tag);
18550        }
18551        frag.innerHTML = html;
18552        return frag;
18553    },
18554
18555    _children: function(node, tag) {
18556            var i = 0,
18557            children = node.children,
18558            childNodes,
18559            hasComments,
18560            child;
18561
18562        if (children && children.tags) { // use tags filter when possible
18563            if (tag) {
18564                children = node.children.tags(tag);
18565            } else { // IE leaks comments into children
18566                hasComments = children.tags('!').length;
18567            }
18568        }
18569
18570        if (!children || (!children.tags && tag) || hasComments) {
18571            childNodes = children || node.childNodes;
18572            children = [];
18573            while ((child = childNodes[i++])) {
18574                if (child.nodeType === 1) {
18575                    if (!tag || tag === child.tagName) {
18576                        children.push(child);
18577                    }
18578                }
18579            }
18580        }
18581
18582        return children || [];
18583    },
18584
18585    /**
18586     * Creates a new dom node using the provided markup string.
18587     * @method create
18588     * @param {String} html The markup used to create the element
18589     * @param {HTMLDocument} doc An optional document context
18590     * @return {HTMLElement|DocumentFragment} returns a single HTMLElement
18591     * when creating one node, and a documentFragment when creating
18592     * multiple nodes.
18593     */
18594    create: function(html, doc) {
18595        if (typeof html === 'string') {
18596            html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
18597
18598        }
18599
18600        doc = doc || Y.config.doc;
18601        var m = re_tag.exec(html),
18602            create = Y_DOM._create,
18603            custom = creators,
18604            ret = null,
18605            creator, tag, node, nodes;
18606
18607        if (html != undefined) { // not undefined or null
18608            if (m && m[1]) {
18609                creator = custom[m[1].toLowerCase()];
18610                if (typeof creator === 'function') {
18611                    create = creator;
18612                } else {
18613                    tag = creator;
18614                }
18615            }
18616
18617            node = create(html, doc, tag);
18618            nodes = node.childNodes;
18619
18620            if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
18621                ret = node.removeChild(nodes[0]);
18622            } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected)
18623                selectedIndex = node.selectedIndex;
18624
18625                if (nodes.length === 2) {
18626                    ret = nodes[0].nextSibling;
18627                } else {
18628                    node.removeChild(nodes[0]);
18629                    ret = Y_DOM._nl2frag(nodes, doc);
18630                }
18631            } else { // return multiple nodes as a fragment
18632                 ret = Y_DOM._nl2frag(nodes, doc);
18633            }
18634
18635        }
18636
18637        return ret;
18638    },
18639
18640    _nl2frag: function(nodes, doc) {
18641        var ret = null,
18642            i, len;
18643
18644        if (nodes && (nodes.push || nodes.item) && nodes[0]) {
18645            doc = doc || nodes[0].ownerDocument;
18646            ret = doc.createDocumentFragment();
18647
18648            if (nodes.item) { // convert live list to static array
18649                nodes = Y.Array(nodes, 0, true);
18650            }
18651
18652            for (i = 0, len = nodes.length; i < len; i++) {
18653                ret.appendChild(nodes[i]);
18654            }
18655        } // else inline with log for minification
18656        return ret;
18657    },
18658
18659    /**
18660     * Inserts content in a node at the given location
18661     * @method addHTML
18662     * @param {HTMLElement} node The node to insert into
18663     * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted
18664     * @param {HTMLElement} where Where to insert the content
18665     * If no "where" is given, content is appended to the node
18666     * Possible values for "where"
18667     * <dl>
18668     * <dt>HTMLElement</dt>
18669     * <dd>The element to insert before</dd>
18670     * <dt>"replace"</dt>
18671     * <dd>Replaces the existing HTML</dd>
18672     * <dt>"before"</dt>
18673     * <dd>Inserts before the existing HTML</dd>
18674     * <dt>"before"</dt>
18675     * <dd>Inserts content before the node</dd>
18676     * <dt>"after"</dt>
18677     * <dd>Inserts content after the node</dd>
18678     * </dl>
18679     */
18680    addHTML: function(node, content, where) {
18681        var nodeParent = node.parentNode,
18682            i = 0,
18683            item,
18684            ret = content,
18685            newNode;
18686
18687
18688        if (content != undefined) { // not null or undefined (maybe 0)
18689            if (content.nodeType) { // DOM node, just add it
18690                newNode = content;
18691            } else if (typeof content == 'string' || typeof content == 'number') {
18692                ret = newNode = Y_DOM.create(content);
18693            } else if (content[0] && content[0].nodeType) { // array or collection
18694                newNode = Y.config.doc.createDocumentFragment();
18695                while ((item = content[i++])) {
18696                    newNode.appendChild(item); // append to fragment for insertion
18697                }
18698            }
18699        }
18700
18701        if (where) {
18702            if (newNode && where.parentNode) { // insert regardless of relationship to node
18703                where.parentNode.insertBefore(newNode, where);
18704            } else {
18705                switch (where) {
18706                    case 'replace':
18707                        while (node.firstChild) {
18708                            node.removeChild(node.firstChild);
18709                        }
18710                        if (newNode) { // allow empty content to clear node
18711                            node.appendChild(newNode);
18712                        }
18713                        break;
18714                    case 'before':
18715                        if (newNode) {
18716                            nodeParent.insertBefore(newNode, node);
18717                        }
18718                        break;
18719                    case 'after':
18720                        if (newNode) {
18721                            if (node.nextSibling) { // IE errors if refNo
18721de is null
18722                                nodeParent.insertBefore(newNode, node.nextSibling);
18723                            } else {
18724                                nodeParent.appendChild(newNode);
18725                            }
18726                        }
18727                        break;
18728                    default:
18729                        if (newNode) {
18730                            node.appendChild(newNode);
18731                        }
18732                }
18733            }
18734        } else if (newNode) {
18735            node.appendChild(newNode);
18736        }
18737
18738        // `select` elements are the only elements with `selectedIndex`.
18739        // Don't grab the dummy `option` element's `selectedIndex`.
18740        if (node.nodeName == "SELECT" && selectedIndex > 0) {
18741            node.selectedIndex = selectedIndex - 1;
18742        }
18743
18744        return ret;
18745    },
18746
18747    wrap: function(node, html) {
18748        var parent = (html && html.nodeType) ? html : Y.DOM.create(html),
18749            nodes = parent.getElementsByTagName('*');
18750
18751        if (nodes.length) {
18752            parent = nodes[nodes.length - 1];
18753        }
18754
18755        if (node.parentNode) {
18756            node.parentNode.replaceChild(parent, node);
18757        }
18758        parent.appendChild(node);
18759    },
18760
18761    unwrap: function(node) {
18762        var parent = node.parentNode,
18763            lastChild = parent.lastChild,
18764            next = node,
18765            grandparent;
18766
18767        if (parent) {
18768            grandparent = parent.parentNode;
18769            if (grandparent) {
18770                node = parent.firstChild;
18771                while (node !== lastChild) {
18772                    next = node.nextSibling;
18773                    grandparent.insertBefore(node, parent);
18774                    node = next;
18775                }
18776                grandparent.replaceChild(lastChild, parent);
18777            } else {
18778                parent.removeChild(node);
18779            }
18780        }
18781    }
18782});
18783
18784addFeature('innerhtml', 'table', {
18785    test: function() {
18786        var node = Y.config.doc.createElement('table');
18787        try {
18788            node.innerHTML = '<tbody></tbody>';
18789        } catch(e) {
18790            return false;
18791        }
18792        return (node.firstChild && node.firstChild.nodeName === 'TBODY');
18793    }
18794});
18795
18796addFeature('innerhtml-div', 'tr', {
18797    test: function() {
18798        return createFromDIV('<tr></tr>', 'tr');
18799    }
18800});
18801
18802addFeature('innerhtml-div', 'script', {
18803    test: function() {
18804        return createFromDIV('<script></script>', 'script');
18805    }
18806});
18807
18808if (!testFeature('innerhtml', 'table')) {
18809    // TODO: thead/tfoot with nested tbody
18810        // IE adds TBODY when creating TABLE elements (which may share this impl)
18811    creators.tbody = function(html, doc) {
18812        var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc),
18813            tb = Y.DOM._children(frag, 'tbody')[0];
18814
18815        if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
18816            tb.parentNode.removeChild(tb); // strip extraneous tbody
18817        }
18818        return frag;
18819    };
18820}
18821
18822if (!testFeature('innerhtml-div', 'script')) {
18823    creators.script = function(html, doc) {
18824        var frag = doc.createElement('div');
18825
18826        frag.innerHTML = '-' + html;
18827        frag.removeChild(frag.firstChild);
18828        return frag;
18829    };
18830
18831    creators.link = creators.style = creators.script;
18832}
18833
18834if (!testFeature('innerhtml-div', 'tr')) {
18835    Y.mix(creators, {
18836        option: function(html, doc) {
18837            return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc);
18838        },
18839
18840        tr: function(html, doc) {
18841            return Y_DOM.create('<tbody>' + html + '</tbody>', doc);
18842        },
18843
18844        td: function(html, doc) {
18845            return Y_DOM.create('<tr>' + html + '</tr>', doc);
18846        },
18847
18848        col: function(html, doc) {
18849            return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc);
18850        },
18851
18852        tbody: 'table'
18853    });
18854
18855    Y.mix(creators, {
18856        legend: 'fieldset',
18857        th: creators.td,
18858        thead: creators.tbody,
18859        tfoot: creators.tbody,
18860        caption: creators.tbody,
18861        colgroup: creators.tbody,
18862        optgroup: creators.option
18863    });
18864}
18865
18866Y_DOM.creators = creators;
18867Y.mix(Y.DOM, {
18868    /**
18869     * Sets the width of the element to the given size, regardless
18870     * of box model, border, padding, etc.
18871     * @method setWidth
18872     * @param {HTMLElement} element The DOM element.
18873     * @param {String|Number} size The pixel height to size to
18874     */
18875
18876    setWidth: function(node, size) {
18877        Y.DOM._setSize(node, 'width', size);
18878    },
18879
18880    /**
18881     * Sets the height of the element to the given size, regardless
18882     * of box model, border, padding, etc.
18883     * @method setHeight
18884     * @param {HTMLElement} element The DOM element.
18885     * @param {String|Number} size The pixel height to size to
18886     */
18887
18888    setHeight: function(node, size) {
18889        Y.DOM._setSize(node, 'height', size);
18890    },
18891
18892    _setSize: function(node, prop, val) {
18893        val = (val > 0) ? val : 0;
18894        var size = 0;
18895
18896        node.style[prop] = val + 'px';
18897        size = (prop === 'height') ? node.offsetHeight : node.offsetWidth;
18898
18899        if (size > val) {
18900            val = val - (size - val);
18901
18902            if (val < 0) {
18903                val = 0;
18904            }
18905
18906            node.style[prop] = val + 'px';
18907        }
18908    }
18909});
18910
18911
18912}, 'patched-v3.18.1', {"requires": ["dom-core"]});
18913
18914YUI.add('dom-core', function (Y, NAME) {
18915
18916var NODE_TYPE = 'nodeType',
18917    OWNER_DOCUMENT = 'ownerDocument',
18918    DOCUMENT_ELEMENT = 'documentElement',
18919    DEFAULT_VIEW = 'defaultView',
18920    PARENT_WINDOW = 'parentWindow',
18921    TAG_NAME = 'tagName',
18922    PARENT_NODE = 'parentNode',
18923    PREVIOUS_SIBLING = 'previousSibling',
18924    NEXT_SIBLING = 'nextSibling',
18925    CONTAINS = 'contains',
18926    COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
18927    EMPTY_ARRAY = [],
18928
18929    // IE < 8 throws on node.contains(textNode)
18930    supportsContainsTextNode = (function() {
18931        var node = Y.config.doc.createElement('div'),
18932            textNode = node.appendChild(Y.config.doc.createTextNode('')),
18933            result = false;
18934
18935        try {
18936            result = node.contains(textNode);
18937        } catch(e) {}
18938
18939        return result;
18940    })(),
18941
18942/**
18943 * The DOM utility provides a cross-browser abtraction layer
18944 * normalizing DOM tasks, and adds extra helper functionality
18945 * for other common tasks.
18946 * @module dom
18947 * @main dom
18948 * @submodule dom-base
18949 * @for DOM
18950 *
18951 */
18952
18953/**
18954 * Provides DOM helper methods.
18955 * @class DOM
18956 *
18957 */
18958
18959Y_DOM = {
18960    /**
18961     * Returns the HTMLElement with the given ID (Wrapper for document.getElementById).
18962     * @method byId
18963     * @param {String} id the id attribute
18964     * @param {Object} doc optional The document to search. Defaults to current document
18965     * @return {HTMLElement | null} The HTMLElement with the id, or null if none found.
18966     */
18967    byId: function(id, doc) {
18968        // handle dupe IDs and IE name collision
18969        return Y_DOM.allById(id, doc)[0] || null;
18970    },
18971
18972    getId: function(node) {
18973        var id;
18974        // HTMLElement returned from FORM when INPUT name === "id"
18975        // IE < 8: HTMLCollection returned when INPUT id === "id"
18976        // via both getAttribute and form.id
18977        if (node.id && !node.id.tagName && !node.id.item) {
18978            id = node.id;
18979        } else if (node.attributes && node.attributes.id) {
18980            id = node.attributes.id.value;
18981        }
18982
18983        return id;
18984    },
18985
18986    setId: function(node, id) {
18987        if (node.setAttribute) {
18988            node.setAttribute('id', id);
18989        } else {
18990            node.id = id;
18991        }
18992    },
18993
18994    /*
18995     * Finds the ancestor of the element.
18996     * @method ancestor
18997     * @param {HTMLElement} element The html element.
18998     * @param {Function} fn optional An optional boolean test to apply.
18999     * The optional function is passed the current DOM node being tested as its only argument.
19000     * If no function is given, the parentNode is returned.
19001     * @param {Boolean} testSelf optional Whether or not to include the element in the scan
19002     * @return {HTMLElement | null} The matching DOM node or null if none found.
19003     */
19004    ancestor: function(element, fn, testSelf, stopFn) {
19005        var ret = null;
19006        if (testSelf) {
19007            ret = (!fn || fn(element)) ? element : null;
19008
19009        }
19010        return ret || Y_DOM.elementByAxis(element, PARENT_NODE, fn, null, stopFn);
19011    },
19012
19013    /*
19014     * Finds the ancestors of the element.
19015     * @method ancestors
19016     * @param {HTMLElement} element The html element.
19017     * @param {Function} fn optional An optional boolean test to apply.
19018     * The optional function is passed the current DOM node being tested as its only argument.
19019     * If no function is given, all ancestors are returned.
19020     * @param {Boolean} testSelf optional Whether or not to include the element in the scan
19021     * @return {Array} An array containing all matching DOM nodes.
19022     */
19023    ancestors: function(element, fn, testSelf, stopFn) {
19024        var ancestor = element,
19025            ret = [];
19026
19027        while ((ancestor = Y_DOM.ancestor(ancestor, fn, testSelf, stopFn))) {
19028            testSelf = false;
19029            if (ancestor) {
19030                ret.unshift(ancestor);
19031
19032                if (stopFn && stopFn(ancestor)) {
19033                    return ret;
19034                }
19035            }
19036        }
19037
19038        return ret;
19039    },
19040
19041    /**
19042     * Searches the element by the given axis for the first matching element.
19043     * @method elementByAxis
19044     * @param {HTMLElement} element The html element.
19045     * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling).
19046     * @param {Function} [fn] An optional boolean test to apply.
19047     * @param {Boolean} [all] Whether text nodes as well as element nodes should be returned, or
19048     * just element nodes will be returned(default)
19049     * The optional function is passed the current HTMLElement being tested as its only argument.
19050     * If no function is given, the first element is returned.
19051     * @return {HTMLElement | null} The matching element or null if none found.
19052     */
19053    elementByAxis: function(element, axis, fn, all, stopAt) {
19054        while (element && (element = element[axis])) { // NOTE: assignment
19055                if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) {
19056                    return element;
19057                }
19058
19059                if (stopAt && stopAt(element)) {
19060                    return null;
19061                }
19062        }
19063        return null;
19064    },
19065
19066    /**
19067     * Determines whether or not one HTMLElement is or contains another HTMLElement.
19068     * @method contains
19069     * @param {HTMLElement} element The containing html element.
19070     * @param {HTMLElement} needle The html element that may be contained.
19071     * @return {Boolean} Whether or not the element is or contains the needle.
19072     */
19073    contains: function(element, needle) {
19074        var ret = false;
19075
19076        if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
19077            ret = false;
19078        } else if (element[CONTAINS] &&
19079                // IE < 8 throws on node.contains(textNode) so fall back to brute.
19080                // Falling back for other nodeTypes as well.
19081                (needle[NODE_TYPE] === 1 || supportsContainsTextNode)) {
19082                ret = element[CONTAINS](needle);
19083        } else if (element[COMPARE_DOCUMENT_POSITION]) {
19084            // Match contains behavior (node.contains(node) === true).
19085            // Needed for Firefox < 4.
19086            if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
19087                ret = true;
19088            }
19089        } else {
19090            ret = Y_DOM._bruteContains(element, needle);
19091        }
19092
19093        return ret;
19094    },
19095
19096    /**
19097     * Determines whether or not the HTMLElement is part of the document.
19098     * @method inDoc
19099     * @param {HTMLElement} element The containing html element.
19100     * @param {HTMLElement} doc optional The document to check.
19101     * @return {Boolean} Whether or not the element is attached to the document.
19102     */
19103    inDoc: function(element, doc) {
19104        var ret = false,
19105            rootNode;
19106
19107        if (element && element.nodeType) {
19108            (doc) || (doc = element[OWNER_DOCUMENT]);
19109
19110            rootNode = doc[DOCUMENT_ELEMENT];
19111
19112            // contains only works with HTML_ELEMENT
19113            if (rootNode && rootNode.contains && element.tagName) {
19114                ret = rootNode.contains(element);
19115            } else {
19116                ret = Y_DOM.contains(rootNode, element);
19117            }
19118        }
19119
19120        return ret;
19121
19122    },
19123
19124   allById: function(id, root) {
19125        root = root || Y.config.doc;
19126        var nodes = [],
19127            ret = [],
19128            i,
19129            node;
19130
19131        if (root.querySelectorAll) {
19132            ret = root.querySelectorAll('[id="' + id + '"]');
19133        } else if (root.all) {
19134            nodes = root.all(id);
19135
19136            if (nodes) {
19137                // root.all may return HTMLElement or HTMLCollection.
19138                // some elements are also HTMLCollection (FORM, SELECT).
19139                if (nodes.nodeName) {
19140                    if (nodes.id === id) { // avoid false positive on name
19141                        ret.push(nodes);
19142                        nodes = EMPTY_ARRAY; // done, no need to filter
19143                    } else { //  prep for filtering
19144                        nodes = [nodes];
19145                    }
19146                }
19147
19148                if (nodes.length) {
19149                    // filter out matches on node.name
19150                    // and element.id as reference to element with id === 'id'
19151                    for (i = 0; node = nodes[i++];) {
19152                        if (node.id === id  ||
19153                                (node.attributes && node.attributes.id &&
19154                                node.attributes.id.value === id)) {
19155                            ret.push(node);
19156                        }
19157                    }
19158                }
19159            }
19160        } else {
19161            ret = [Y_DOM._getDoc(root).getElementById(id)];
19162        }
19163
19164        return ret;
19165   },
19166
19167
19168    isWindow: function(obj) {
19169        return !!(obj && obj.scrollTo && obj.document);
19170    },
19171
19172    _removeChildNodes: function(node) {
19173        while (node.firstChild) {
19174            node.removeChild(node.firstChild);
19175        }
19176    },
19177
19178    siblings: function(node, fn) {
19179        var nodes = [],
19180            sibling = node;
19181
19182        while ((sibling = sibling[PREVIOUS_SIBLING])) {
19183            if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
19184                nodes.unshift(sibling);
19185            }
19186        }
19187
19188        sibling = node;
19189        while ((sibling = sibling[NEXT_SIBLING])) {
19190            if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
19191                nodes.push(sibling);
19192            }
19193        }
19194
19195        return nodes;
19196    },
19197
19198    /**
19199     * Brute force version of contains.
19200     * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc).
19201     * @method _bruteContains
19202     * @private
19203     * @param {HTMLElement} element The containing html element.
19204     * @param {HTMLElement} needle The html element that may be contained.
19205     * @return {Boolean} Whether or not the element is or contains the needle.
19206     */
19207    _bruteContains: function(element, needle) {
19208        while (needle) {
19209            if (element === needle) {
19210                return true;
19211            }
19212            needle = needle.parentNode;
19213        }
19214        return false;
19215    },
19216
19217// TODO: move to Lang?
19218    /**
19219     * Memoizes dynamic regular expressions to boost runtime performance.
19220     * @method _getRegExp
19221     * @private
19222     * @param {String} str The string to convert to a regular expression.
19223     * @param {String} flags optional An optinal string of flags.
19224     * @return {RegExp} An instance of RegExp
19225     */
19226    _getRegExp: function(str, flags) {
19227        flags = flags || '';
19228        Y_DOM._regexCache = Y_DOM._regexCache || {};
19229        if (!Y_DOM._regexCache[str + flags]) {
19230            Y_DOM._regexCache[str + flags] = new RegExp(str, flags);
19231        }
19232        return Y_DOM._regexCache[str + flags];
19233    },
19234
19235// TODO: make getDoc/Win true privates?
19236    /**
19237     * returns the appropriate document.
19238     * @method _getDoc
19239     * @private
19240     * @param {HTMLElement} element optional Target element.
19241     * @return {Object} The document for the given element or the default document.
19242     */
19243    _getDoc: function(element) {
19244        var doc = Y.config.doc;
19245        if (element) {
19246            doc = (element[NODE_TYPE] === 9) ? element : // element === document
19247                element[OWNER_DOCUMENT] || // element === DOM node
19248                element.document || // element === window
19249                Y.config.doc; // default
19250        }
19251
19252        return doc;
19253    },
19254
19255    /**
19256     * returns the appropriate window.
19257     * @method _getWin
19258     * @private
19259     * @param {HTMLElement} element optional Target element.
19260     * @return {Object} The window for the given element or the default window.
19261     */
19262    _getWin: function(element) {
19263        var doc = Y_DOM._getDoc(element);
19264        return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win;
19265    },
19266
19267    _batch: function(nodes, fn, arg1, arg2, arg3, etc) {
19268        fn = (typeof fn === 'string') ? Y_DOM[fn] : fn;
19269        var result,
19270            i = 0,
19271            node,
19272            ret;
19273
19274        if (fn && nodes) {
19275            while ((node = nodes[i++])) {
19276                result = result = fn.call(Y_DOM, node, arg1, arg2, arg3, etc);
19277                if (typeof result !== 'undefined') {
19278                    (ret) || (ret = []);
19279                    ret.push(result);
19280                }
19281            }
19282        }
19283
19284        return (typeof ret !== 'undefined') ? ret : nodes;
19285    },
19286
19287    generateID: function(el) {
19288        var id = el.id;
19289
19290        if (!id) {
19291            id = Y.stamp(el);
19292            el.id = id;
19293        }
19294
19295        return id;
19296    }
19297};
19298
19299
19300Y.DOM = Y_DOM;
19301
19302
19303}, 'patched-v3.18.1', {"requires": ["oop", "features"]});
19304
19305YUI.add('dom-screen', function (Y, NAME) {
19306
19307(function(Y) {
19308
19309/**
19310 * Adds position and region management functionality to DOM.
19311 * @module dom
19312 * @submodule dom-screen
19313 * @for DOM
19314 */
19315
19316var DOCUMENT_ELEMENT = 'documentElement',
19317    COMPAT_MODE = 'compatMode',
19318    POSITION = 'position',
19319    FIXED = 'fixed',
19320    RELATIVE = 'relative',
19321    LEFT = 'left',
19322    TOP = 'top',
19323    _BACK_COMPAT = 'BackCompat',
19324    MEDIUM = 'medium',
19325    BORDER_LEFT_WIDTH = 'borderLeftWidth',
19326    BORDER_TOP_WIDTH = 'borderTopWidth',
19327    GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
19328    GET_COMPUTED_STYLE = 'getComputedStyle',
19329
19330    Y_DOM = Y.DOM,
19331
19332    // TODO: how about thead/tbody/tfoot/tr?
19333    // TODO: does caption matter?
19334    RE_TABLE = /^t(?:able|d|h)$/i,
19335
19336    SCROLL_NODE;
19337
19338if (Y.UA.ie) {
19339    if (Y.config.doc[COMPAT_MODE] !== 'BackCompat') {
19340        SCROLL_NODE = DOCUMENT_ELEMENT;
19341    } else {
19342        SCROLL_NODE = 'body';
19343    }
19344}
19345
19346Y.mix(Y_DOM, {
19347    /**
19348     * Returns the inner height of the viewport (exludes scrollbar).
19349     * @method winHeight
19350     * @return {Number} The current height of the viewport.
19351     */
19352    winHeight: function(node) {
19353        var h = Y_DOM._getWinSize(node).height;
19354        return h;
19355    },
19356
19357    /**
19358     * Returns the inner width of the viewport (exludes scrollbar).
19359     * @method winWidth
19360     * @return {Number} The current width of the viewport.
19361     */
19362    winWidth: function(node) {
19363        var w = Y_DOM._getWinSize(node).width;
19364        return w;
19365    },
19366
19367    /**
19368     * Document height
19369     * @method docHeight
19370     * @return {Number} The current height of the document.
19371     */
19372    docHeight:  function(node) {
19373        var h = Y_DOM._getDocSize(node).height;
19374        return Math.max(h, Y_DOM._getWinSize(node).height);
19375    },
19376
19377    /**
19378     * Document width
19379     * @method docWidth
19380     * @return {Number} The current width of the document.
19381     */
19382    docWidth:  function(node) {
19383        var w = Y_DOM._getDocSize(node).width;
19384        return Math.max(w, Y_DOM._getWinSize(node).width);
19385    },
19386
19387    /**
19388     * Amount page has been scroll horizontally
19389     * @method docScrollX
19390     * @return {Number} The current amount the screen is scrolled horizontally.
19391     */
19392    docScrollX: function(node, doc) {
19393        doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
19394        var dv = doc.defaultView,
19395            pageOffset = (dv) ? dv.pageXOffset : 0;
19396        return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset);
19397    },
19398
19399    /**
19400     * Amount page has been scroll vertically
19401     * @method docScrollY
19402     * @return {Number} The current amount the screen is scrolled vertically.
19403     */
19404    docScrollY:  function(node, doc) {
19405        doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
19406        var dv = doc.defaultView,
19407            pageOffset = (dv) ? dv.pageYOffset : 0;
19408        return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset);
19409    },
19410
19411    /**
19412     * Gets the current position of an element based on page coordinates.
19413     * Element must be part of the DOM tree to have page coordinates
19414     * (display:none or elements not appended return false).
19415     * @method getXY
19416     * @param element The target element
19417     * @return {Array} The XY position of the element
19418
19419     TODO: test inDocument/display?
19420     */
19421    getXY: function() {
19422        if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) {
19423            return function(node) {
19424                var xy = null,
19425                    scrollLeft,
19426                    scrollTop,
19427                    mode,
19428                    box,
19429                    offX,
19430                    offY,
19431                    doc,
19432                    win,
19433                    inDoc,
19434                    rootNode;
19435
19436                if (node && node.tagName) {
19437                    doc = node.ownerDocument;
19438                    mode = doc[COMPAT_MODE];
19439
19440                    if (mode !== _BACK_COMPAT) {
19441                        rootNode = doc[DOCUMENT_ELEMENT];
19442                    } else {
19443                        rootNode = doc.body;
19444                    }
19445
19446                    // inline inDoc check for perf
19447                    if (rootNode.contains) {
19448                        inDoc = rootNode.contains(node);
19449                    } else {
19450                        inDoc = Y.DOM.contains(rootNode, node);
19451                    }
19452
19453                    if (inDoc) {
19454                        win = doc.defaultView;
19455
19456                        // inline scroll calc for perf
19457                        if (win && 'pageXOffset' in win) {
19458                            scrollLeft = win.pageXOffset;
19459                            scrollTop = win.pageYOffset;
19460                        } else {
19461                            scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc);
19462                            scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc);
19463                        }
19464
19465                        if (Y.UA.ie) { // IE < 8, quirks, or compatMode
19466                            if (!doc.documentMode || doc.documentMode < 8 || mode === _BACK_COMPAT) {
19467                                offX = rootNode.clientLeft;
19468                                offY = rootNode.clientTop;
19469                            }
19470                        }
19471                        box = node[GET_BOUNDING_CLIENT_RECT]();
19472                        xy = [box.left, box.top];
19473
19474                        if (offX || offY) {
19475                                xy[0] -= offX;
19476                                xy[1] -= offY;
19477
19478                        }
19479                        if ((scrollTop || scrollLeft)) {
19480                            if (!Y.UA.ios || (Y.UA.ios >= 4.2)) {
19481                                xy[0] += scrollLeft;
19482                                xy[1] += scrollTop;
19483                            }
19484
19485                        }
19486                    } else {
19487                        xy = Y_DOM._getOffset(node);
19488                    }
19489                }
19490                return xy;
19491            };
19492        } else {
19493            return function(node) { // manually calculate by crawling up offsetParents
19494                //Calculate the Top and Left border sizes (assumes pixels)
19495                var xy = null,
19496                    doc,
19497                    parentNode,
19498                    bCheck,
19499                    scrollTop,
19500                    scrollLeft;
19501
19502                if (node) {
19503                    if (Y_DOM.inDoc(node)) {
19504                        xy = [node.offsetLeft, node.offsetTop];
19505                        doc = node.ownerDocument;
19506                        parentNode = node;
19507                        // TODO: refactor with !! or just falsey
19508                        bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false);
19509
19510                        // TODO: worth refactoring for TOP/LEFT only?
19511                        while ((parentNode = parentNode.offsetParent)) {
19512                            xy[0] += parentNode.offsetLeft;
19513                            xy[1] += parentNode.offsetTop;
19514                            if (bCheck) {
19515                                xy = Y_DOM._calcBorders(parentNode, xy);
19516                            }
19517                        }
19518
19519                        // account for any scrolled ancestors
19520                        if (Y_DOM.getStyle(node, POSITION) != FIXED) {
19521                            parentNode = node;
19522
19523                            while ((parentNode = parentNode.parentNode)) {
19524                                scrollTop = parentNode.scrollTop;
19525                                scrollLeft = parentNode.scrollLeft;
19526
19527                                //Firefox does something funky with borders when overflow is not visible.
19528                                if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) {
19529                                        xy = Y_DOM._calcBorders(parentNode, xy);
19530                                }
19531
19532
19533                                if (scrollTop || scrollLeft) {
19534                                    xy[0] -= scrollLeft;
19535                                    xy[1] -= scrollTop;
19536                                }
19537                            }
19538                            xy[0] += Y_DOM.docScrollX(node, doc);
19539                            xy[1] += Y_DOM.docScrollY(node, doc);
19540
19541                        } else {
19542                            //Fix FIXED position -- add scrollbars
19543                            xy[0] += Y_DOM.docScrollX(node, doc);
19544                            xy[1] += Y_DOM.docScrollY(node, doc);
19545                        }
19546                    } else {
19547                        xy = Y_DOM._getOffset(node);
19548                    }
19549                }
19550
19551                return xy;
19552            };
19553        }
19554    }(),// NOTE: Executing for loadtime branching
19555
19556    /**
19557    Gets the width of vertical scrollbars on overflowed containers in the body
19558    content.
19559
19560    @method getScrollbarWidth
19561    @return {Number} Pixel width of a scrollbar in the current browser
19562    **/
19563    getScrollbarWidth: Y.cached(function () {
19564        var doc      = Y.config.doc,
19565            testNode = doc.createElement('div'),
19566            body     = doc.getElementsByTagName('body')[0],
19567            // 0.1 because cached doesn't support falsy refetch values
19568            width    = 0.1;
19569
19570        if (body) {
19571            testNode.style.cssText = "position:absolute;visibility:hidden;overflow:scroll;width:20px;";
19572            testNode.appendChild(doc.createElement('p')).style.height = '1px';
19573            body.insertBefore(testNode, body.firstChild);
19574            width = testNode.offsetWidth - testNode.clientWidth;
19575
19576            body.removeChild(testNode);
19577        }
19578
19579        return width;
19580    }, null, 0.1),
19581
19582    /**
19583     * Gets the current X position of an element based on page coordinates.
19584     * Element must be part of the DOM tree to have page coordinates
19585     * (display:none or elements not appended return false).
19586     * @method getX
19587     * @param element The target element
19588     * @return {Number} The X position of the element
19589     */
19590
19591    getX: function(node) {
19592        return Y_DOM.getXY(node)[0];
19593    },
19594
19595    /**
19596     * Gets the current Y position of an element based on page coordinates.
19597     * Element must be part of the DOM tree to have page coordinates
19598     * (display:none or elements not appended return false).
19599     * @method getY
19600     * @param element The target element
19601     * @return {Number} The Y position of the element
19602     */
19603
19604    getY: function(node) {
19605        return Y_DOM.getXY(node)[1];
19606    },
19607
19608    /**
19609     * Set the position of an html element in page coordinates.
19610     * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
19611     * @method setXY
19612     * @param element The target element
19613     * @param {Array} xy Contains X & Y values for new position (coordinates are page-based)
19614     * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
19615     */
19616    setXY: function(node, xy, noRetry) {
19617        var setStyle = Y_DOM.setStyle,
19618            pos,
19619            delta,
19620            newXY,
19621            currentXY,
19622            offsetDir,
19623            dir,
19624            x;
19625
19626        if (node && xy) {
19627            pos = Y_DOM.getStyle(node, POSITION);
19628
19629            offsetDir = Y_DOM.OFFSET_XY;
19630
19631            if (!offsetDir) {
19632                dir = Y_DOM.getComputedStyle(node, 'direction');
19633
19634                offsetDir = (dir === 'rtl' ? 'right' : LEFT);
19635            }
19636
19637            delta = Y_DOM._getOffset(node, offsetDir);
19638            if (pos == 'static') { // default to relative
19639                pos = RELATIVE;
19640                setStyle(node, POSITION, pos);
19641            }
19642            currentXY = Y_DOM._getDirXY(node, offsetDir);
19643
19644            x = xy[0];
19645
19646            if (offsetDir === 'right') {
19647                x = Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10));
19648
19649                if (!delta[0] && !noRetry) {
19650                    noRetry = false;
19651                }
19652            }
19653
19654            if (x !== null) {
19655                setStyle(node, offsetDir, x - currentXY[0] + delta[0] + 'px');
19656            }
19657
19658            if (xy[1] !== null) {
19659                setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px');
19660            }
19661
19662            if (!noRetry) {
19663                newXY = Y_DOM.getXY(node);
19664                if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) {
19665                    Y_DOM.setXY(node, xy, true);
19666                }
19667            }
19668
19669        } else {
19670        }
19671    },
19672
19673    /**
19674     * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
19675     * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
19676     * @method setX
19677     * @param element The target element
19678     * @param {Number} x The X values for new position (coordinates are page-based)
19679     */
19680    setX: function(node, x) {
19681        return Y_DOM.setXY(node, [x, null]);
19682    },
19683
19684    /**
19685     * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
19686     * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
19687     * @method setY
19688     * @param element The target element
19689     * @param {Number} y The Y values for new position (coordinates are page-based)
19690     */
19691    setY: function(node, y) {
19692        return Y_DOM.setXY(node, [null, y]);
19693    },
19694
19695    /**
19696     * @method swapXY
19697     * @description Swap the xy position with another node
19698     * @param {Node} node The node to swap with
19699     * @param {Node} otherNode The other node to swap with
19700     * @return {Node}
19701     */
19702    swapXY: function(node, otherNode) {
19703        var xy = Y_DOM.getXY(node);
19704        Y_DOM.setXY(node, Y_DOM.getXY(otherNode));
19705        Y_DOM.setXY(otherNode, xy);
19706    },
19707
19708    _calcBorders: function(node, xy2) {
19709        var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0,
19710            l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0;
19711        if (Y.UA.gecko) {
19712            if (RE_TABLE.test(node.tagName)) {
19713                t = 0;
19714                l = 0;
19715            }
19716        }
19717        xy2[0] += l;
19718        xy2[1] += t;
19719        return xy2;
19720    },
19721
19722    _getWinSize: function(node, doc) {
19723        doc  = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc;
19724        var win = doc.defaultView || doc.parentWindow,
19725            mode = doc[COMPAT_MODE],
19726            h = win.innerHeight,
19727            w = win.innerWidth,
19728            root = doc[DOCUMENT_ELEMENT];
19729
19730        if ( mode && !Y.UA.opera ) { // IE, Gecko
19731            if (mode != 'CSS1Compat') { // Quirks
19732                root = doc.body;
19733            }
19734            h = root.clientHeight;
19735            w = root.clientWidth;
19736        }
19737        return { height: h, width: w };
19738    },
19739
19740    _getDocSize: function(node) {
19741        var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc,
19742            root = doc[DOCUMENT_ELEMENT];
19743
19744        if (doc[COMPAT_MODE] != 'CSS1Compat') {
19745            root = doc.body;
19746        }
19747
19748        return { height: root.scrollHeight, width: root.scrollWidth };
19749    },
19750
19751    _getDirXY: function(node, dir) {
19752        var xy = Y_DOM.getXY(node);
19753
19754        if (dir === 'right') {
19755            xy[0] = (Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10)));
19756        }
19757
19758        return xy;
19759    }
19760});
19761
19762})(Y);
19763(function(Y) {
19764var TOP = 'top',
19765    RIGHT = 'right',
19766    BOTTOM = 'bottom',
19767    LEFT = 'left',
19768
19769    getOffsets = function(r1, r2) {
19770        var t = Math.max(r1[TOP], r2[TOP]),
19771            r = Math.min(r1[RIGHT], r2[RIGHT]),
19772            b = Math.min(r1[BOTTOM], r2[BOTTOM]),
19773            l = Math.max(r1[LEFT], r2[LEFT]),
19774            ret = {};
19775
19776        ret[TOP] = t;
19777        ret[RIGHT] = r;
19778        ret[BOTTOM] = b;
19779        ret[LEFT] = l;
19780        return ret;
19781    },
19782
19783    DOM = Y.DOM;
19784
19785Y.mix(DOM, {
19786    /**
19787     * Returns an Object literal containing the following about this element: (top, right, bottom, left)
19788     * @for DOM
19789     * @method region
19790     * @param {HTMLElement} element The DOM element.
19791     * @return {Object} Object literal containing the following about this element: (top, right, bottom, left)
19792     */
19793    region: function(node) {
19794        var xy = DOM.getXY(node),
19795            ret = false;
19796
19797        if (node && xy) {
19798            ret = DOM._getRegion(
19799                xy[1], // top
19800                xy[0] + node.offsetWidth, // right
19801                xy[1] + node.offsetHeight, // bottom
19802                xy[0] // left
19803            );
19804        }
19805
19806        return ret;
19807    },
19808
19809    /**
19810     * Find the intersect information for the passed nodes.
19811     * @method intersect
19812     * @for DOM
19813     * @param {HTMLElement} element The first element
19814     * @param {HTMLElement | Object} element2 The element or region to check the interect with
19815     * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance e.g. DragDrop)
19816     * @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion)
19817     */
19818    intersect: function(node, node2, altRegion) {
19819        var r = altRegion || DOM.region(node), region = {},
19820            n = node2,
19821            off;
19822
19823        if (n.tagName) {
19824            region = DOM.region(n);
19825        } else if (Y.Lang.isObject(node2)) {
19826            region = node2;
19827        } else {
19828            return false;
19829        }
19830
19831        off = getOffsets(region, r);
19832        return {
19833            top: off[TOP],
19834            right: off[RIGHT],
19835            bottom: off[BOTTOM],
19836            left: off[LEFT],
19837            area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])),
19838            yoff: ((off[BOTTOM] - off[TOP])),
19839            xoff: (off[RIGHT] - off[LEFT]),
19840            inRegion: DOM.inRegion(node, node2, false, altRegion)
19841        };
19842
19843    },
19844    /**
19845     * Check if any part of this node is in the passed region
19846     * @method inRegion
19847     * @for DOM
19848     * @param {Object} node The node to get the region from
19849     * @param {Object} node2 The second node to get the region from or an Object literal of the region
19850     * @param {Boolean} all Should all of the node be inside the region
19851     * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop)
19852     * @return {Boolean} True if in region, false if not.
19853     */
19854    inRegion: function(node, node2, all, altRegion) {
19855        var region = {},
19856            r = altRegion || DOM.region(node),
19857            n = node2,
19858            off;
19859
19860        if (n.tagName) {
19861            region = DOM.region(n);
19862        } else if (Y.Lang.isObject(node2)) {
19863            region = node2;
19864        } else {
19865            return false;
19866        }
19867
19868        if (all) {
19869            return (
19870                r[LEFT]   >= region[LEFT]   &&
19871                r[RIGHT]  <= region[RIGHT]  &&
19872                r[TOP]    >= region[TOP]    &&
19873                r[BOTTOM] <= region[BOTTOM]  );
19874        } else {
19875            off = getOffsets(region, r);
19876            if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) {
19877                return true;
19878            } else {
19879                return false;
19880            }
19881
19882        }
19883    },
19884
19885    /**
19886     * Check if any part of this element is in the viewport
19887     * @method inViewportRegion
19888     * @for DOM
19889     * @param {HTMLElement} element The DOM element.
19890     * @param {Boolean} all Should all of the node be inside the region
19891     * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop)
19892     * @return {Boolean} True if in region, false if not.
19893     */
19894    inViewportRegion: function(node, all, altRegion) {
19895        return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion);
19896
19897    },
19898
19899    _getRegion: function(t, r, b, l) {
19900        var region = {};
19901
19902        region[TOP] = region[1] = t;
19903        region[LEFT] = region[0] = l;
19904        region[BOTTOM] = b;
19905        region[RIGHT] = r;
19906        region.width = region[RIGHT] - region[LEFT];
19907        region.height = region[BOTTOM] - region[TOP];
19908
19909        return region;
19910    },
19911
19912    /**
19913     * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left)
19914     * @method viewportRegion
19915     * @for DOM
19916     * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left)
19917     */
19918    viewportRegion: function(node) {
19919        node = node || Y.config.doc.documentElement;
19920        var ret = false,
19921            scrollX,
19922            scrollY;
19923
19924        if (node) {
19925            scrollX = DOM.docScrollX(node);
19926            scrollY = DOM.docScrollY(node);
19927
19928            ret = DOM._getRegion(scrollY, // top
19929                DOM.winWidth(node) + scrollX, // right
19930                scrollY + DOM.winHeight(node), // bottom
19931                scrollX); // left
19932        }
19933
19934        return ret;
19935    }
19936});
19937})(Y);
19938
19939
19940}, 'patched-v3.18.1', {"requires": ["dom-base", "dom-style"]});
19941
19942YUI.add('dom-style', function (Y, NAME) {
19943
19944/**
19945 * Add style management functionality to DOM.
19946 * @module dom
19947 * @submodule dom-style
19948 * @for DOM
19949 */
19950
19951var DOCUMENT_ELEMENT = 'documentElement',
19952    DEFAULT_VIEW = 'defaultView',
19953    OWNER_DOCUMENT = 'ownerDocument',
19954    STYLE = 'style',
19955    FLOAT = 'float',
19956    CSS_FLOAT = 'cssFloat',
19957    STYLE_FLOAT = 'styleFloat',
19958    TRANSPARENT = 'transparent',
19959    GET_COMPUTED_STYLE = 'getComputedStyle',
19960    GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
19961
19962    DOCUMENT = Y.config.doc,
19963
19964    Y_DOM = Y.DOM,
19965
19966    TRANSFORM,
19967    TRANSFORMORIGIN,
19968    VENDOR_TRANSFORM = [
19969        'WebkitTransform',
19970        'MozTransform',
19971        'OTransform',
19972        'msTransform',
19973        'transform'
19974    ],
19975
19976    re_unit = /width|height|top|left|right|bottom|margin|padding/i;
19977
19978Y.Array.each(VENDOR_TRANSFORM, function(val) {
19979    if (val in DOCUMENT[DOCUMENT_ELEMENT].style) {
19980        TRANSFORM = val;
19981        TRANSFORMORIGIN = val + "Origin";
19982    }
19983});
19984
19985Y.mix(Y_DOM, {
19986    DEFAULT_UNIT: 'px',
19987
19988    CUSTOM_STYLES: {
19989    },
19990
19991
19992    /**
19993     * Sets a style property for a given element.
19994     * @method setStyle
19995     * @param {HTMLElement} node The HTMLElement to apply the style to.
19996     * @param {String} att The style property to set.
19997     * @param {String|Number} val The value.
19998     * @param {Object} [style] The style node. Defaults to `node.style`.
19999     */
20000    setStyle: function(node, att, val, style) {
20001        style = style || node.style;
20002        var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES;
20003
20004        if (style) {
20005            if (val === null || val === '') { // normalize unsetting
20006                val = '';
20007            } else if (!isNaN(Number(val)) && re_unit.test(att)) { // number values may need a unit
20008                val += Y_DOM.DEFAULT_UNIT;
20009            }
20010
20011            if (att in CUSTOM_STYLES) {
20012                if (CUSTOM_STYLES[att].set) {
20013                    CUSTOM_STYLES[att].set(node, val, style);
20014                    return; // NOTE: return
20015                } else if (typeof CUSTOM_STYLES[att] === 'string') {
20016                    att = CUSTOM_STYLES[att];
20017                }
20018            } else if (att === '') { // unset inline styles
20019                att = 'cssText';
20020                val = '';
20021            }
20022            style[att] = val;
20023        }
20024    },
20025
20026    /**
20027     * Returns the current style value for the given property.
20028     * @method getStyle
20029     * @param {HTMLElement} node The HTMLElement to get the style from.
20030     * @param {String} att The style property to get.
20031     * @param {Object} [style] The style node. Defaults to `node.style`.
20032     */
20033    getStyle: function(node, att, style) {
20034        style = style || node.style;
20035        var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES,
20036            val = '';
20037
20038        if (style) {
20039            if (att in CUSTOM_STYLES) {
20040                if (CUSTOM_STYLES[att].get) {
20041                    return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
20042                } else if (typeof CUSTOM_STYLES[att] === 'string') {
20043                    att = CUSTOM_STYLES[att];
20044                }
20045            }
20046            val = style[att];
20047            if (val === '') { // TODO: is empty string sufficient?
20048                val = Y_DOM[GET_COMPUTED_STYLE](node, att);
20049            }
20050        }
20051
20052        return val;
20053    },
20054
20055    /**
20056     * Sets multiple style properties.
20057     * @method setStyles
20058     * @param {HTMLElement} node The HTMLElement to apply the styles to.
20059     * @param {Object} hash An object literal of property:value pairs.
20060     */
20061    setStyles: function(node, hash) {
20062        var style = node.style;
20063        Y.each(hash, function(v, n) {
20064            Y_DOM.setStyle(node, n, v, style);
20065        }, Y_DOM);
20066    },
20067
20068    /**
20069     * Returns the computed style for the given node.
20070     * @method getComputedStyle
20071     * @param {HTMLElement} node The HTMLElement to get the style from.
20072     * @param {String} att The style property to get.
20073     * @return {String} The computed value of the style property.
20074     */
20075    getComputedStyle: function(node, att) {
20076        var val = '',
20077            doc = node[OWNER_DOCUMENT],
20078            computed;
20079
20080        if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) {
20081            computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null);
20082            if (computed) { // FF may be null in some cases (ticket #2530548)
20083                val = computed[att];
20084            }
20085        }
20086        return val;
20087    }
20088});
20089
20090// normalize reserved word float alternatives ("cssFloat" or "styleFloat")
20091if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== undefined) {
20092    Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
20093} else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== undefined) {
20094    Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
20095}
20096
20097// safari converts transparent to rgba(), others use "transparent"
20098if (Y.UA.webkit) {
20099    Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
20100        var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
20101            val = view[GET_COMPUTED_STYLE](node, '')[att];
20102
20103        if (val === 'rgba(0, 0, 0, 0)') {
20104            val = TRANSPARENT;
20105        }
20106
20107        return val;
20108    };
20109
20110}
20111
20112Y.DOM._getAttrOffset = function(node, attr) {
20113    var val = Y.DOM[GET_COMPUTED_STYLE](node, attr),
20114        offsetParent = node.offsetParent,
20115        position,
20116        parentOffset,
20117        offset;
20118
20119    if (val === 'auto') {
20120        position = Y.DOM.getStyle(node, 'position');
20121        if (position === 'static' || position === 'relative') {
20122            val = 0;
20123        } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) {
20124            parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr];
20125            offset = node[GET_BOUNDING_CLIENT_RECT]()[attr];
20126            if (attr === 'left' || attr === 'top') {
20127                val = offset - parentOffset;
20128            } else {
20129                val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr];
20130            }
20131        }
20132    }
20133
20134    return val;
20135};
20136
20137Y.DOM._getOffset = function(node, dir) {
20138    var pos,
20139        xy = null,
20140        offset = {
20141            left: 'offsetLeft',
20142            right: 'offsetRight'
20143        },
20144        margins = {
20145            left: 'marginLeft',
20146            right: 'marginRight'
20147        },
20148        margin;
20149
20150    dir = dir || 'left';
20151
20152    if (node) {
20153        pos = Y_DOM.getStyle(node, 'position');
20154        margin = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, margins[dir]), 10);
20155        xy = [
20156            parseInt(Y_DOM[GET_COMPUTED_STYLE](node, dir), 10),
20157            parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10)
20158        ];
20159
20160        if ( isNaN(xy[0]) ) { // in case of 'auto'
20161            xy[0] = parseInt(Y_DOM.getStyle(node, dir), 10); // try inline
20162            if ( isNaN(xy[0]) ) { // default to offset value
20163                xy[0] = (pos === 'relative') ? 0 : (node[offset[dir]] - margin) || 0;
20164            }
20165        }
20166
20167        if ( isNaN(xy[1]) ) { // in case of 'auto'
20168            xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline
20169            if ( isNaN(xy[1]) ) { // default to offset value
20170                xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0;
20171            }
20172        }
20173    }
20174
20175    return xy;
20176
20177};
20178
20179if (TRANSFORM) {
20180    Y_DOM.CUSTOM_STYLES.transform = {
20181        set: function(node, val, style) {
20182            style[TRANSFORM] = val;
20183        },
20184
20185        get: function(node) {
20186            return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM);
20187        }
20188    };
20189
20190    Y_DOM.CUSTOM_STYLES.transformOrigin = {
20191        set: function(node, val, style) {
20192            style[TRANSFORMORIGIN] = val;
20193        },
20194
20195        get: function(node) {
20196            return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORMORIGIN);
20197        }
20198    };
20199}
20200
20201
20202}, 'patched-v3.18.1', {"requires": ["dom-base"]});
20203
20204YUI.add('event-base', function (Y, NAME) {
20205
20206/*
20207 * DOM event listener abstraction layer
20208 * @module event
20209 * @submodule event-base
20210 */
20211
20212/**
20213 * The domready event fires at the moment the browser's DOM is
20214 * usable. In most cases, this is before images are fully
20215 * downloaded, allowing you to provide a more responsive user
20216 * interface.
20217 *
20218 * In YUI 3, domready subscribers will be notified immediately if
20219 * that moment has already passed when the subscription is created.
20220 *
20221 * One exception is if the yui.js file is dynamically injected into
20222 * the page.  If this is done, you must tell the YUI instance that
20223 * you did this in order for DOMReady (and window load events) to
20224 * fire normally.  That configuration option is 'injected' -- set
20225 * it to true if the yui.js script is not included inline.
20226 *
20227 * This method is part of the 'event-ready' module, which is a
20228 * submodule of 'event'.
20229 *
20230 * @event domready
20231 * @for YUI
20232 */
20233Y.publish('domready', {
20234    fireOnce: true,
20235    async: true
20236});
20237
20238if (YUI.Env.DOMReady) {
20239    Y.fire('domready');
20240} else {
20241    Y.Do.before(function() { Y.fire('domready'); }, YUI.Env, '_ready');
20242}
20243
20244/**
20245 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
20246 * events.
20247 * @module event
20248 * @submodule event-base
20249 */
20250
20251/**
20252 * Wraps a DOM event, properties requiring browser abstraction are
20253 * fixed here.  Provids a security layer when required.
20254 * @class DOMEventFacade
20255 * @param ev {Event} the DOM event
20256 * @param currentTarget {HTMLElement} the element the listener was attached to
20257 * @param wrapper {CustomEvent} the custom event wrapper for this DOM event
20258 */
20259
20260    var ua = Y.UA,
20261
20262    EMPTY = {},
20263
20264    /**
20265     * webkit key remapping required for Safari < 3.1
20266     * @property webkitKeymap
20267     * @private
20268     */
20269    webkitKeymap = {
20270        63232: 38, // up
20271        63233: 40, // down
20272        63234: 37, // left
20273        63235: 39, // right
20274        63276: 33, // page up
20275        63277: 34, // page down
20276        25:     9, // SHIFT-TAB (Safari provides a different key code in
20277                   // this case, even though the shiftKey modifier is set)
20278        63272: 46, // delete
20279        63273: 36, // home
20280        63275: 35  // end
20281    },
20282
20283    /**
20284     * Returns a wrapped node.  Intended to be used on event targets,
20285     * so it will return the node's parent if the target is a text
20286     * node.
20287     *
20288     * If accessing a property of the node throws an error, this is
20289     * probably the anonymous div wrapper Gecko adds inside text
20290     * nodes.  This likely will only occur when attempting to access
20291     * the relatedTarget.  In this case, we now return null because
20292     * the anonymous div is completely useless and we do not know
20293     * what the related target was because we can't even get to
20294     * the element's parent node.
20295     *
20296     * @method resolve
20297     * @private
20298     */
20299    resolve = function(n) {
20300        if (!n) {
20301            return n;
20302        }
20303        try {
20304            if (n && 3 == n.nodeType) {
20305                n = n.parentNode;
20306            }
20307        } catch(e) {
20308            return null;
20309        }
20310
20311        return Y.one(n);
20312    },
20313
20314    DOMEventFacade = function(ev, currentTarget, wrapper) {
20315        this._event = ev;
20316        this._currentTarget = currentTarget;
20317        this._wrapper = wrapper || EMPTY;
20318
20319        // if not lazy init
20320        this.init();
20321    };
20322
20323Y.extend(DOMEventFacade, Object, {
20324
20325    init: function() {
20326
20327        var e = this._event,
20328            overrides = this._wrapper.overrides,
20329            x = e.pageX,
20330            y = e.pageY,
20331            c,
20332            currentTarget = this._currentTarget;
20333
20334        this.altKey   = e.altKey;
20335        this.ctrlKey  = e.ctrlKey;
20336        this.metaKey  = e.metaKey;
20337        this.shiftKey = e.shiftKey;
20338        this.type     = (overrides && overrides.type) || e.type;
20339        this.clientX  = e.clientX;
20340        this.clientY  = e.clientY;
20341
20342        this.pageX = x;
20343        this.pageY = y;
20344
20345        // charCode is unknown in keyup, keydown. keyCode is unknown in keypress.
20346        // FF 3.6 - 8+? pass 0 for keyCode in keypress events.
20347        // Webkit, FF 3.6-8+?, and IE9+? pass 0 for charCode in keydown, keyup.
20348        // Webkit and IE9+? duplicate charCode in keyCode.
20349        // Opera never sets charCode, always keyCode (though with the charCode).
20350        // IE6-8 don't set charCode or which.
20351        // All browsers other than IE6-8 set which=keyCode in keydown, keyup, and
20352        // which=charCode in keypress.
20353        //
20354        // Moral of the story: (e.which || e.keyCode) will always return the
20355        // known code for that key event phase. e.keyCode is often different in
20356        // keypress from keydown and keyup.
20357        c = e.keyCode || e.charCode;
20358
20359        if (ua.webkit && (c in webkitKeymap)) {
20360            c = webkitKeymap[c];
20361        }
20362
20363        this.keyCode = c;
20364        this.charCode = c;
20365        // Fill in e.which for IE - implementers should always use this over
20366        // e.keyCode or e.charCode.
20367        this.which = e.which || e.charCode || c;
20368        // this.button = e.button;
20369        this.button = this.which;
20370
20371        this.target = resolve(e.target);
20372        this.currentTarget = resolve(currentTarget);
20373        this.relatedTarget = resolve(e.relatedTarget);
20374
20375        if (e.type == "mousewheel" || e.type == "DOMMouseScroll") {
20376            this.wheelDelta = (e.detail) ? (e.detail * -1) : Math.round(e.wheelDelta / 80) || ((e.wheelDelta < 0) ? -1 : 1);
20377        }
20378
20379        if (this._touch) {
20380            this._touch(e, currentTarget, this._wrapper);
20381        }
20382    },
20383
20384    stopPropagation: function() {
20385        this._event.stopPropagation();
20386        this._wrapper.stopped = 1;
20387        this.stopped = 1;
20388    },
20389
20390    stopImmediatePropagation: function() {
20391        var e = this._event;
20392        if (e.stopImmediatePropagation) {
20393            e.stopImmediatePropagation();
20394        } else {
20395            this.stopPropagation();
20396        }
20397        this._wrapper.stopped = 2;
20398        this.stopped = 2;
20399    },
20400
20401    preventDefault: function(returnValue) {
20402        var e = this._event;
20403        e.preventDefault();
20404        if (returnValue) {
20405            e.returnValue = returnValue;
20406        }
20407        this._wrapper.prevented = 1;
20408        this.prevented = 1;
20409    },
20410
20411    halt: function(immediate) {
20412        if (immediate) {
20413            this.stopImmediatePropagation();
20414        } else {
20415            this.stopPropagation();
20416        }
20417
20418        this.preventDefault();
20419    }
20420
20421});
20422
20423DOMEventFacade.resolve = resolve;
20424Y.DOM2EventFacade = DOMEventFacade;
20425Y.DOMEventFacade = DOMEventFacade;
20426
20427    /**
20428     * The native event
20429     * @property _event
20430     * @type {DOMEvent}
20431     * @private
20432     */
20433
20434    /**
20435    The name of the event (e.g. "click")
20436
20437    @property type
20438    @type {String}
20439    **/
20440
20441    /**
20442    `true` if the "alt" or "option" key is pressed.
20443
20444    @property altKey
20445    @type {Boolean}
20446    **/
20447
20448    /**
20449    `true` if the shift key is pressed.
20450
20451    @property shiftKey
20452    @type {Boolean}
20453    **/
20454
20455    /**
20456    `true` if the "Windows" key on a Windows keyboard, "command" key on an
20457    Apple keyboard, or "meta" key on other keyboards is pressed.
20458
20459    @property metaKey
20460    @type {Boolean}
20461    **/
20462
20463    /**
20464    `true` if the "Ctrl" or "control" key is pressed.
20465
20466    @property ctrlKey
20467    @type {Boolean}
20468    **/
20469
20470    /**
20471     * The X location of the event on the page (including scroll)
20472     * @property pageX
20473     * @type {Number}
20474     */
20475
20476    /**
20477     * The Y location of the event on the page (including scroll)
20478     * @property pageY
20479     * @type {Number}
20480     */
20481
20482    /**
20483     * The X location of the event in the viewport
20484     * @property clientX
20485     * @type {Number}
20486     */
20487
20488    /**
20489     * The Y location of the event in the viewport
20490     * @property clientY
20491     * @type {Number}
20492     */
20493
20494    /**
20495     * The keyCode for key events.  Uses charCode if keyCode is not available
20496     * @property keyCode
20497     * @type {Number}
20498     */
20499
20500    /**
20501     * The charCode for key events.  Same as keyCode
20502     * @property charCode
20503     * @type {Number}
20504     */
20505
20506    /**
20507     * The button that was pushed. 1 for left click, 2 for middle click, 3 for
20508     * right click.  This is only reliably populated on `mouseup` events.
20509     * @property button
20510     * @type {Number}
20511     */
20512
20513    /**
20514     * The button that was pushed.  Same as button.
20515     * @property which
20516     * @type {Number}
20517     */
20518
20519    /**
20520     * Node reference for the targeted element
20521     * @property target
20522     * @type {Node}
20523     */
20524
20525    /**
20526     * Node reference for the element that the listener was attached to.
20527     * @property currentTarget
20528     * @type {Node}
20529     */
20530
20531    /**
20532     * Node reference to the relatedTarget
20533     * @property relatedTarget
20534     * @type {Node}
20535     */
20536
20537    /**
20538     * Number representing the direction and velocity of the movement of the mousewheel.
20539     * Negative is down, the higher the number, the faster.  Applies to the mousewheel event.
20540     * @property wheelDelta
20541     * @type {Number}
20542     */
20543
20544    /**
20545     * Stops the propagation to the next bubble target
20546     * @method stopPropagation
20547     */
20548
20549    /**
20550     * Stops the propagation to the next bubble target and
20551     * prevents any additional listeners from being exectued
20552     * on the current target.
20553     * @method stopImmediatePropagation
20554     */
20555
20556    /**
20557     * Prevents the event's default behavior
20558     * @method preventDefault
20559     * @param returnValue {string} sets the returnValue of the event to this value
20560     * (rather than the default false value).  This can be used to add a customized
20561     * confirmation query to the beforeunload event).
20562     */
20563
20564    /**
20565     * Stops the event propagation and prevents the default
20566     * event behavior.
20567     * @method halt
20568     * @param immediate {boolean} if true additional listeners
20569     * on the current target will not be executed
20570     */
20571(function() {
20572
20573/**
20574 * The event utility provides functions to add and remove event listeners,
20575 * event cleansing.  It also tries to automatically remove listeners it
20576 * registers during the unload event.
20577 * @module event
20578 * @main event
20579 * @submodule event-base
20580 */
20581
20582/**
20583 * The event utility provides functions to add and remove event listeners,
20584 * event cleansing.  It also tries to automatically remove listeners it
20585 * registers during the unload event.
20586 *
20587 * @class Event
20588 * @static
20589 */
20590
20591Y.Env.evt.dom_wrappers = {};
20592Y.Env.evt.dom_map = {};
20593
20594var _eventenv = Y.Env.evt,
20595    config = Y.config,
20596    win = config.win,
20597    add = YUI.Env.add,
20598    remove = YUI.Env.remove,
20599
20600    onLoad = function() {
20601        YUI.Env.windowLoaded = true;
20602        Y.Event._load();
20603        remove(win, "load", onLoad);
20604    },
20605
20606    onUnload = function() {
20607        Y.Event._unload();
20608    },
20609
20610    EVENT_READY = 'domready',
20611
20612    COMPAT_ARG = '~yui|2|compat~',
20613
20614    shouldIterate = function(o) {
20615        try {
20616            // TODO: See if there's a more performant way to return true early on this, for the common case
20617            return (o && typeof o !== "string" && Y.Lang.isNumber(o.length) && !o.tagName && !Y.DOM.isWindow(o));
20618        } catch(ex) {
20619            return false;
20620        }
20621    },
20622
20623    // aliases to support DOM event subscription clean up when the last
20624    // subscriber is detached. deleteAndClean overrides the DOM event's wrapper
20625    // CustomEvent _delete method.
20626    _ceProtoDelete = Y.CustomEvent.prototype._delete,
20627    _deleteAndClean = function(s) {
20628        var ret = _ceProtoDelete.apply(this, arguments);
20629
20630        if (!this.hasSubs()) {
20631            Y.Event._clean(this);
20632        }
20633
20634        return ret;
20635    },
20636
20637Event = function() {
20638
20639    /**
20640     * True after the onload event has fired
20641     * @property _loadComplete
20642     * @type boolean
20643     * @static
20644     * @private
20645     */
20646    var _loadComplete =  false,
20647
20648    /**
20649     * The number of times to poll after window.onload.  This number is
20650     * increased if additional late-bound handlers are requested after
20651     * the page load.
20652     * @property _retryCount
20653     * @static
20654     * @private
20655     */
20656    _retryCount = 0,
20657
20658    /**
20659     * onAvailable listeners
20660     * @property _avail
20661     * @static
20662     * @private
20663     */
20664    _avail = [],
20665
20666    /**
20667     * Custom event wrappers for DOM events.  Key is
20668     * 'event:' + Element uid stamp + event type
20669     * @property _wrappers
20670     * @type CustomEvent
20671     * @static
20672     * @private
20673     */
20674    _wrappers = _eventenv.dom_wrappers,
20675
20676    _windowLoadKey = null,
20677
20678    /**
20679     * Custom event wrapper map DOM events.  Key is
20680     * Element uid stamp.  Each item is a hash of custom event
20681     * wrappers as provided in the _wrappers collection.  This
20682     * provides the infrastructure for getListeners.
20683     * @property _el_events
20684     * @static
20685     * @private
20686     */
20687    _el_events = _eventenv.dom_map;
20688
20689    return {
20690
20691        /**
20692         * The number of times we should look for elements that are not
20693         * in the DOM at the time the event is requested after the document
20694         * has been loaded.  The default is 1000@amp;40 ms, so it will poll
20695         * for 40 seconds or until all outstanding handlers are bound
20696         * (whichever comes first).
20697         * @property POLL_RETRYS
20698         * @type int
20699         * @static
20700         * @final
20701         */
20702        POLL_RETRYS: 1000,
20703
20704        /**
20705         * The poll interval in milliseconds
20706         * @property POLL_INTERVAL
20707         * @type int
20708         * @static
20709         * @final
20710         */
20711        POLL_INTERVAL: 40,
20712
20713        /**
20714         * addListener/removeListener can throw errors in unexpected scenarios.
20715         * These errors are suppressed, the method returns false, and this property
20716         * is set
20717         * @property lastError
20718         * @static
20719         * @type Error
20720         */
20721        lastError: null,
20722
20723
20724        /**
20725         * poll handle
20726         * @property _interval
20727         * @static
20728         * @private
20729         */
20730        _interval: null,
20731
20732        /**
20733         * document readystate poll handle
20734         * @property _dri
20735         * @static
20736         * @private
20737         */
20738         _dri: null,
20739
20740        /**
20741         * True when the document is initially usable
20742         * @property DOMReady
20743         * @type boolean
20744         * @static
20745         */
20746        DOMReady: false,
20747
20748        /**
20749         * @method startInterval
20750         * @static
20751         * @private
20752         */
20753        startInterval: function() {
20754            if (!Event._interval) {
20755Event._interval = setInterval(Event._poll, Event.POLL_INTERVAL);
20756            }
20757        },
20758
20759        /**
20760         * Executes the supplied callback when the item with the supplied
20761         * id is found.  This is meant to be used to execute behavior as
20762         * soon as possible as the page loads.  If you use this after the
20763         * initial page load it will poll for a fixed time for the element.
20764         * The number of times it will poll and the frequency are
20765         * configurable.  By default it will poll for 10 seconds.
20766         *
20767         * <p>The callback is executed with a single parameter:
20768         * the custom object parameter, if provided.</p>
20769         *
20770         * @method onAvailable
20771         *
20772         * @param {string||string[]}   id the id of the element, or an array
20773         * of ids to look for.
20774         * @param {function} fn what to execute when the element is found.
20775         * @param {object}   p_obj an optional object to be passed back as
20776         *                   a parameter to fn.
20777         * @param {boolean|object}  p_override If set to true, fn will execute
20778         *                   in the context of p_obj, if set to an object it
20779         *                   will execute in the context of that object
20780         * @param checkContent {boolean} check child node readiness (onContentReady)
20781         * @static
20782         * @deprecated Use Y.on("available")
20783         */
20784        // @TODO fix arguments
20785        onAvailable: function(id, fn, p_obj, p_override, checkContent, compat) {
20786
20787            var a = Y.Array(id), i, availHandle;
20788
20789            for (i=0; i<a.length; i=i+1) {
20790                _avail.push({
20791                    id:         a[i],
20792                    fn:         fn,
20793                    obj:        p_obj,
20794                    override:   p_override,
20795                    checkReady: checkContent,
20796                    compat:     compat
20797                });
20798            }
20799            _retryCount = this.POLL_RETRYS;
20800
20801            // We want the first test to be immediate, but async
20802            setTimeout(Event._poll, 0);
20803
20804            availHandle = new Y.EventHandle({
20805
20806                _delete: function() {
20807                    // set by the event system for lazy DOM listeners
20808                    if (availHandle.handle) {
20809                        availHandle.handle.detach();
20810                        return;
20811                    }
20812
20813                    var i, j;
20814
20815                    // otherwise try to remove the onAvailable listener(s)
20816                    for (i = 0; i < a.length; i++) {
20817                        for (j = 0; j < _avail.length; j++) {
20818                            if (a[i] === _avail[j].id) {
20819                                _avail.splice(j, 1);
20820                            }
20821                        }
20822                    }
20823                }
20824
20825            });
20826
20827            return availHandle;
20828        },
20829
20830        /**
20831         * Works the same way as onAvailable, but additionally checks the
20832         * state of sibling elements to determine if the content of the
20833         * available element is safe to modify.
20834         *
20835         * <p>The callback is executed with a single parameter:
20836         * the custom object parameter, if provided.</p>
20837         *
20838         * @method onContentReady
20839         *
20840         * @param {string}   id the id of the element to look for.
20841         * @param {function} fn what to execute when the element is ready.
20842         * @param {object}   obj an optional object to be passed back as
20843         *                   a parameter to fn.
20844         * @param {boolean|object}  override If set to true, fn will execute
20845         *                   in the context of p_obj.  If an object, fn will
20846         *                   exectute in the context of that object
20847         *
20848         * @static
20849         * @deprecated Use Y.on("contentready")
20850         */
20851        // @TODO fix arguments
20852        onContentReady: function(id, fn, obj, override, compat) {
20853            return Event.onAvailable(id, fn, obj, override, true, compat);
20854        },
20855
20856        /**
20857         * Adds an event listener
20858         *
20859         * @method attach
20860         *
20861         * @param {String}   type     The type of event to append
20862         * @param {Function} fn        The method the event invokes
20863         * @param {String|HTMLElement|Array|NodeList} el An id, an element
20864         *  reference, or a collection of ids and/or elements to assign the
20865         *  listener to.
20866         * @param {Object}   context optional context object
20867         * @param {Boolean|object}  args 0..n arguments to pass to the callback
20868         * @return {EventHandle} an object to that can be used to detach the listener
20869         *
20870         * @static
20871         */
20872
20873        attach: function(type, fn, el, context) {
20874            return Event._attach(Y.Array(arguments, 0, true));
20875        },
20876
20877        _createWrapper: function (el, type, capture, compat, facade) {
20878
20879            var cewrapper,
20880                ek  = Y.stamp(el),
20881                key = 'event:' + ek + type;
20882
20883            if (false === facade) {
20884                key += 'native';
20885            }
20886            if (capture) {
20887                key += 'capture';
20888            }
20889
20890
20891            cewrapper = _wrappers[key];
20892
20893
20894            if (!cewrapper) {
20895                // create CE wrapper
20896                cewrapper = Y.publish(key, {
20897                    silent: true,
20898                    bubbles: false,
20899                    emitFacade:false,
20900                    contextFn: function() {
20901                        if (compat) {
20902                            return cewrapper.el;
20903                        } else {
20904                            cewrapper.nodeRef = cewrapper.nodeRef || Y.one(cewrapper.el);
20905                            return cewrapper.nodeRef;
20906                        }
20907                    }
20908                });
20909
20910                cewrapper.overrides = {};
20911
20912                // for later removeListener calls
20913                cewrapper.el = el;
20914                cewrapper.key = key;
20915                cewrapper.domkey = ek;
20916                cewrapper.type = type;
20917                cewrapper.fn = function(e) {
20918                    cewrapper.fire(Event.getEvent(e, el, (compat || (false === facade))));
20919                };
20920                cewrapper.capture = capture;
20921
20922                if (el == win && type == "load") {
20923                    // window load happens once
20924                    cewrapper.fireOnce = true;
20925                    _windowLoadKey = key;
20926                }
20927                cewrapper._delete = _deleteAndClean;
20928
20929                _wrappers[key] = cewrapper;
20930                _el_events[ek] = _el_events[ek] || {};
20931                _el_events[ek][key] = cewrapper;
20932
20933                add(el, type, cewrapper.fn, capture);
20934            }
20935
20936            return cewrapper;
20937
20938        },
20939
20940        _attach: function(args, conf) {
20941
20942            var compat,
20943                handles, oEl, cewrapper, context,
20944                fireNow = false, ret,
20945                type = args[0],
20946                fn = args[1],
20947                el = args[2] || win,
20948                facade = conf && conf.facade,
20949                capture = conf && conf.capture,
20950                overrides = conf && conf.overrides;
20951
20952            if (args[args.length-1] === COMPAT_ARG) {
20953                compat = true;
20954            }
20955
20956            if (!fn || !fn.call) {
20957                return false;
20958            }
20959
20960            // The el argument can be an array of elements or element ids.
20961            if (shouldIterate(el)) {
20962
20963                handles=[];
20964
20965                Y.each(el, function(v, k) {
20966                    args[2] = v;
20967                    handles.push(Event._attach(args.slice(), conf));
20968                });
20969
20970                // return (handles.length === 1) ? handles[0] : handles;
20971                return new Y.EventHandle(handles);
20972
20973            // If the el argument is a string, we assume it is
20974            // actually the id of the element.  If the page is loaded
20975            // we convert el to the actual element, otherwise we
20976            // defer attaching the event until the element is
20977            // ready
20978            } else if (Y.Lang.isString(el)) {
20979
20980                // oEl = (compat) ? Y.DOM.byId(el) : Y.Selector.query(el);
20981
20982                if (compat) {
20983                    oEl = Y.DOM.byId(el);
20984                } else {
20985
20986                    oEl = Y.Selector.query(el);
20987
20988                    switch (oEl.length) {
20989                        case 0:
20990                            oEl = null;
20991                            break;
20992                        case 1:
20993                            oEl = oEl[0];
20994                            break;
20995                        default:
20996                            args[2] = oEl;
20997                            return Event._attach(args, conf);
20998                    }
20999                }
21000
21001                if (oEl) {
21002
21003                    el = oEl;
21004
21005                // Not found = defer adding the event until the element is available
21006                } else {
21007
21008                    ret = Event.onAvailable(el, function() {
21009
21010                        ret.handle = Event._attach(args, conf);
21011
21012                    }, Event, true, false, compat);
21013
21014                    return ret;
21015
21016                }
21017            }
21018
21019            // Element should be an html element or node
21020            if (!el) {
21021                return false;
21022            }
21023
21024            if (Y.Node && Y.instanceOf(el, Y.Node)) {
21025                el = Y.Node.getDOMNode(el);
21026            }
21027
21028            cewrapper = Event._createWrapper(el, type, capture, compat, facade);
21029            if (overrides) {
21030                Y.mix(cewrapper.overrides, overrides);
21031            }
21032
21033            if (el == win && type == "load") {
21034
21035                // if the load is complete, fire immediately.
21036                // all subscribers, including the current one
21037                // will be notified.
21038                if (YUI.Env.windowLoaded) {
21039                    fireNow = true;
21040                }
21041            }
21042
21043            if (compat) {
21044                args.pop();
21045            }
21046
21047            context = args[3];
21048
21049            // set context to the Node if not specified
21050            // ret = cewrapper.on.apply(cewrapper, trimmedArgs);
21051            ret = cewrapper._on(fn, context, (args.length > 4) ? args.slice(4) : null);
21052
21053            if (fireNow) {
21054                cewrapper.fire();
21055            }
21056
21057            return ret;
21058
21059        },
21060
21061        /**
21062         * Removes an event listener.  Supports the signature the event was bound
21063         * with, but the preferred way to remove listeners is using the handle
21064         * that is returned when using Y.on
21065         *
21066         * @method detach
21067         *
21068         * @param {String} type the type of event to remove.
21069         * @param {Function} fn the method the event invokes.  If fn is
21070         * undefined, then all event handlers for the type of event are
21071         * removed.
21072         * @param {String|HTMLElement|Array|NodeList|EventHandle} el An
21073         * event handle, an id, an element reference, or a collection
21074         * of ids and/or elements to remove the listener from.
21075         * @return {boolean} true if the unbind was successful, false otherwise.
21076         * @static
21077         */
21078        detach: function(type, fn, el, obj) {
21079
21080            var args=Y.Array(arguments, 0, true), compat, l, ok, i,
21081                id, ce;
21082
21083            if (args[args.length-1] === COMPAT_ARG) {
21084                compat = true;
21085                // args.pop();
21086            }
21087
21088            if (type && type.detach) {
21089                return type.detach();
21090            }
21091
21092            // The el argument can be a string
21093            if (typeof el == "string") {
21094
21095                // el = (compat) ? Y.DOM.byId(el) : Y.all(el);
21096                if (compat) {
21097                    el = Y.DOM.byId(el);
21098                } else {
21099                    el = Y.Selector.query(el);
21100                    l = el.length;
21101                    if (l < 1) {
21102                        el = null;
21103                    } else if (l == 1) {
21104                        el = el[0];
21105                    }
21106                }
21107                // return Event.detach.apply(Event, args);
21108            }
21109
21110            if (!el) {
21111                return false;
21112            }
21113
21114            if (el.detach) {
21115                args.splice(2, 1);
21116                return el.detach.apply(el, args);
21117            // The el argument can be an array of elements or element ids.
21118            } else if (shouldIterate(el)) {
21119                ok = true;
21120                for (i=0, l=el.length; i<l; ++i) {
21121                    args[2] = el[i];
21122                    ok = ( Y.Event.detach.apply(Y.Event, args) && ok );
21123                }
21124
21125                return ok;
21126            }
21127
21128            if (!type || !fn || !fn.call) {
21129                return Event.purgeElement(el, false, type);
21130            }
21131
21132            id = 'event:' + Y.stamp(el) + type;
21133            ce = _wrappers[id];
21134
21135            if (ce) {
21136                return ce.detach(fn);
21137            } else {
21138                return false;
21139            }
21140
21141        },
21142
21143        /**
21144         * Finds the event in the window object, the caller's arguments, or
21145         * in the arguments of another method in the callstack.  This is
21146         * executed automatically for events registered through the event
21147         * manager, so the implementer should not normally need to execute
21148         * this function at all.
21149         * @method getEvent
21150         * @param {Event} e the event parameter from the handler
21151         * @param {HTMLElement} el the element the listener was attached to
21152         * @return {Event} the event
21153         * @static
21154         */
21155        getEvent: function(e, el, noFacade) {
21156            var ev = e || win.event;
21157
21158            return (noFacade) ? ev :
21159                new Y.DOMEventFacade(ev, el, _wrappers['event:' + Y.stamp(el) + e.type]);
21160        },
21161
21162        /**
21163         * Generates an unique ID for the element if it does not already
21164         * have one.
21165         * @method generateId
21166         * @param el the element to create the id for
21167         * @return {string} the resulting id of the element
21168         * @static
21169         */
21170        generateId: function(el) {
21171            return Y.DOM.generateID(el);
21172        },
21173
21174        /**
21175         * We want to be able to use getElementsByTagName as a collection
21176         * to attach a group of events to.  Unfortunately, different
21177         * browsers return different types of collections.  This function
21178         * tests to determine if the object is array-like.  It will also
21179         * fail if the object is an array, but is empty.
21180         * @method _isValidCollection
21181         * @param o the object to test
21182         * @return {boolean} true if the object is array-like and populated
21183         * @deprecated was not meant to be used directly
21184         * @static
21185         * @private
21186         */
21187        _isValidCollection: shouldIterate,
21188
21189        /**
21190         * hook up any deferred listeners
21191         * @method _load
21192         * @static
21193         * @private
21194         */
21195        _load: function(e) {
21196            if (!_loadComplete) {
21197                _loadComplete = true;
21198
21199                // Just in case DOMReady did not go off for some reason
21200                // E._ready();
21201                if (Y.fire) {
21202                    Y.fire(EVENT_READY);
21203                }
21204
21205                // Available elements may not have been detected before the
21206                // window load event fires. Try to find them now so that the
21207                // the user is more likely to get the onAvailable notifications
21208                // before the window load notification
21209                Event._poll();
21210            }
21211        },
21212
21213        /**
21214         * Polling function that runs before the onload event fires,
21215         * attempting to attach to DOM Nodes as soon as they are
21216         * available
21217         * @method _poll
21218         * @static
21219         * @private
21220         */
21221        _poll: function() {
21222            if (Event.locked) {
21223                return;
21224            }
21225
21226            if (Y.UA.ie && !YUI.Env.DOMReady) {
21227                // Hold off if DOMReady has not fired and check current
21228                // readyState to protect against the IE operation aborted
21229                // issue.
21230                Event.startInterval();
21231                return;
21232            }
21233
21234            Event.locked = true;
21235
21236            // keep trying until after the page is loaded.  We need to
21237            // check the page load state prior to trying to bind the
21238            // elements so that we can be certain all elements have been
21239            // tested appropriately
21240            var i, len, item, el, notAvail, executeItem,
21241                tryAgain = !_loadComplete;
21242
21243            if (!tryAgain) {
21244                tryAgain = (_retryCount > 0);
21245            }
21246
21247            // onAvailable
21248            notAvail = [];
21249
21250            executeItem = function (el, item) {
21251                var context, ov = item.override;
21252                try {
21253                    if (item.compat) {
21254                        if (item.override) {
21255                            if (ov === true) {
21256                                context = item.obj;
21257                            } else {
21258                                context = ov;
21259                            }
21260                        } else {
21261                            context = el;
21262                        }
21263                        item.fn.call(context, item.obj);
21264                    } else {
21265                        context = item.obj || Y.one(el);
21266                        item.fn.apply(context, (Y.Lang.isArray(ov)) ? ov : []);
21267                    }
21268                } catch (e) {
21269                }
21270            };
21271
21272            // onAvailable
21273            for (i=0,len=_avail.length; i<len; ++i) {
21274                item = _avail[i];
21275                if (item && !item.checkReady) {
21276
21277                    // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id);
21278                    el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true);
21279
21280                    if (el) {
21281                        executeItem(el, item);
21282                        _avail[i] = null;
21283                    } else {
21284                        notAvail.push(item);
21285                    }
21286                }
21287            }
21288
21289            // onContentReady
21290            for (i=0,len=_avail.length; i<len; ++i) {
21291                item = _avail[i];
21292                if (item && item.checkReady) {
21293
21294                    // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id);
21295                    el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true);
21296
21297                    if (el) {
21298                        // The element is available, but not necessarily ready
21299                        // @todo should we test parentNode.nextSibling?
21300                        if (_loadComplete || (el.get && el.get('nextSibling')) || el.nextSibling) {
21301                            executeItem(el, item);
21302                            _avail[i] = null;
21303                        }
21304                    } else {
21305                        notAvail.push(item);
21306                    }
21307                }
21308            }
21309
21310            _retryCount = (notAvail.length === 0) ? 0 : _retryCount - 1;
21311
21312            if (tryAgain) {
21313                // we may need to strip the nulled out items here
21314                Event.startInterval();
21315            } else {
21316                clearInterval(Event._interval);
21317                Event._interval = null;
21318            }
21319
21320            Event.locked = false;
21321
21322            return;
21323
21324        },
21325
21326        /**
21327         * Removes all listeners attached to the given element via addListener.
21328         * Optionally, the node's children can also be purged.
21329         * Optionally, you can specify a specific type of event to remove.
21330         * @method purgeElement
21331         * @param {HTMLElement} el the element to purge
21332         * @param {boolean} recurse recursively purge this element's children
21333         * as well.  Use with caution.
21334         * @param {string} type optional type of listener to purge. If
21335         * left out, all listeners will be removed
21336         * @static
21337         */
21338        purgeElement: function(el, recurse, type) {
21339            // var oEl = (Y.Lang.isString(el)) ? Y.one(el) : el,
21340            var oEl = (Y.Lang.isString(el)) ?  Y.Selector.query(el, null, true) : el,
21341                lis = Event.getListeners(oEl, type), i, len, children, child;
21342
21343            if (recurse && oEl) {
21344                lis = lis || [];
21345                children = Y.Selector.query('*', oEl);
21346                len = children.length;
21347                for (i = 0; i < len; ++i) {
21348                    child = Event.getListeners(children[i], type);
21349                    if (child) {
21350                        lis = lis.concat(child);
21351                    }
21352                }
21353            }
21354
21355            if (lis) {
21356                for (i = 0, len = lis.length; i < len; ++i) {
21357                    lis[i].detachAll();
21358                }
21359            }
21360
21361        },
21362
21363        /**
21364         * Removes all object references and the DOM proxy subscription for
21365         * a given event for a DOM node.
21366         *
21367         * @method _clean
21368         * @param wrapper {CustomEvent} Custom event proxy for the DOM
21369         *                  subscription
21370         * @private
21371         * @static
21372         * @since 3.4.0
21373         */
21374        _clean: function (wrapper) {
21375            var key    = wrapper.key,
21376                domkey = wrapper.domkey;
21377
21378            remove(wrapper.el, wrapper.type, wrapper.fn, wrapper.capture);
21379            delete _wrappers[key];
21380            delete Y._yuievt.events[key];
21381            if (_el_events[domkey]) {
21382                delete _el_events[domkey][key];
21383                if (!Y.Object.size(_el_events[domkey])) {
21384                    delete _el_events[domkey];
21385                }
21386            }
21387        },
21388
21389        /**
21390         * Returns all listeners attached to the given element via addListener.
21391         * Optionally, you can specify a specific type of event to return.
21392         * @method getListeners
21393         * @param el {HTMLElement|string} the element or element id to inspect
21394         * @param type {string} optional type of listener to return. If
21395         * left out, all listeners will be returned
21396         * @return {CustomEvent} the custom event wrapper for the DOM event(s)
21397         * @static
21398         */
21399        getListeners: function(el, type) {
21400            var ek = Y.stamp(el, true), evts = _el_events[ek],
21401                results=[] , key = (type) ? 'event:' + ek + type : null,
21402                adapters = _eventenv.plugins;
21403
21404            if (!evts) {
21405                return null;
21406            }
21407
21408            if (key) {
21409                // look for synthetic events
21410                if (adapters[type] && adapters[type].eventDef) {
21411                    key += '_synth';
21412                }
21413
21414                if (evts[key]) {
21415                    results.push(evts[key]);
21416                }
21417
21418                // get native events as well
21419                key += 'native';
21420                if (evts[key]) {
21421                    results.push(evts[key]);
21422                }
21423
21424            } else {
21425                Y.each(evts, function(v, k) {
21426                    results.push(v);
21427                });
21428            }
21429
21430            return (results.length) ? results : null;
21431        },
21432
21433        /**
21434         * Removes all listeners registered by pe.event.  Called
21435         * automatically during the unload event.
21436         * @method _unload
21437         * @static
21438         * @private
21439         */
21440        _unload: function(e) {
21441            Y.each(_wrappers, function(v, k) {
21442                if (v.type == 'unload') {
21443                    v.fire(e);
21444                }
21445                v.detachAll();
21446            });
21447            remove(win, "unload", onUnload);
21448        },
21449
21450        /**
21451         * Adds a DOM event directly without the caching, cleanup, context adj, etc
21452         *
21453         * @method nativeAdd
21454         * @param {HTMLElement} el      the element to bind the handler to
21455         * @param {string}      type   the type of event handler
21456         * @param {function}    fn      the callback to invoke
21457         * @param {Boolean}      capture capture or bubble phase
21458         * @static
21459         * @private
21460         */
21461        nativeAdd: add,
21462
21463        /**
21464         * Basic remove listener
21465         *
21466         * @method nativeRemove
21467         * @param {HTMLElement} el      the element to bind the handler to
21468         * @param {string}      type   the type of event handler
21469         * @param {function}    fn      the callback to invoke
21470         * @param {Boolean}      capture capture or bubble phase
21471         * @static
21472         * @private
21473         */
21474        nativeRemove: remove
21475    };
21476
21477}();
21478
21479Y.Event = Event;
21480
21481if (config.injected || YUI.Env.windowLoaded) {
21482    onLoad();
21483} else {
21484    add(win, "load", onLoad);
21485}
21486
21487// Process onAvailable/onContentReady items when when the DOM is ready in IE
21488if (Y.UA.ie) {
21489    Y.on(EVENT_READY, Event._poll);
21490
21491    // In IE6 and below, detach event handlers when the page is unloaded in
21492    // order to try and prevent cross-page memory leaks. This isn't done in
21493    // other browsers because a) it's not necessary, and b) it breaks the
21494    // back/forward cache.
21495    if (Y.UA.ie < 7) {
21496        try {
21497            add(win, "unload", onUnload);
21498        } catch(e) {
21499        }
21500    }
21501}
21502
21503Event.Custom = Y.CustomEvent;
21504Event.Subscriber = Y.Subscriber;
21505Event.Target = Y.EventTarget;
21506Event.Handle = Y.EventHandle;
21507Event.Facade = Y.EventFacade;
21508
21509Event._poll();
21510
21511}());
21512
21513/**
21514 * DOM event listener abstraction layer
21515 * @module event
21516 * @submodule event-base
21517 */
21518
21519/**
21520 * Executes the callback as soon as the specified element
21521 * is detected in the DOM.  This function expects a selector
21522 * string for the element(s) to detect.  If you already have
21523 * an element reference, you don't need this event.
21524 * @event available
21525 * @param type {string} 'available'
21526 * @param fn {function} the callback function to execute.
21527 * @param el {string} an selector for the element(s) to attach
21528 * @param context optional argument that specifies what 'this' refers to.
21529 * @param args* 0..n additional arguments to pass on to the callback function.
21530 * These arguments will be added after the event object.
21531 * @return {EventHandle} the detach handle
21532 * @for YUI
21533 */
21534Y.Env.evt.plugins.available = {
21535    on: function(type, fn, id, o) {
21536        var a = arguments.length > 4 ?  Y.Array(arguments, 4, true) : null;
21537        return Y.Event.onAvailable.call(Y.Event, id, fn, o, a);
21538    }
21539};
21540
21541/**
21542 * Executes the callback as soon as the specified element
21543 * is detected in the DOM with a nextSibling property
21544 * (indicating that the element's children are available).
21545 * This function expects a selector
21546 * string for the element(s) to detect.  If you already have
21547 * an element reference, you don't need this event.
21548 * @event contentready
21549 * @param type {string} 'contentready'
21550 * @param fn {function} the callback function to execute.
21551 * @param el {string} an selector for the element(s) to attach.
21552 * @param context optional argument that specifies what 'this' refers to.
21553 * @param args* 0..n additional arguments to pass on to the callback function.
21554 * These arguments will be added after the event object.
21555 * @return {EventHandle} the detach handle
21556 * @for YUI
21557 */
21558Y.Env.evt.plugins.contentready = {
21559    on: function(type, fn, id, o) {
21560        var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null;
21561        return Y.Event.onContentReady.call(Y.Event, id, fn, o, a);
21562    }
21563};
21564
21565
21566}, 'patched-v3.18.1', {"requires": ["event-custom-base"]});
21567
21568YUI.add('event-custom-base', function (Y, NAME) {
21569
21570/**
21571 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
21572 * events.
21573 * @module event-custom
21574 */
21575
21576Y.Env.evt = {
21577    handles: {},
21578    plugins: {}
21579};
21580
21581/**
21582 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
21583 * events.
21584 * @module event-custom
21585 * @submodule event-custom-base
21586 */
21587
21588/**
21589 * Allows for the insertion of methods that are executed before or after
21590 * a specified method
21591 * @class Do
21592 * @static
21593 */
21594
21595var DO_BEFORE = 0,
21596    DO_AFTER = 1,
21597
21598DO = {
21599
21600    /**
21601     * Cache of objects touched by the utility
21602     * @property objs
21603     * @static
21604     * @deprecated Since 3.6.0. The `_yuiaop` property on the AOP'd object
21605     * replaces the role of this property, but is considered to be private, and
21606     * is only mentioned to provide a migration path.
21607     *
21608     * If you have a use case which warrants migration to the _yuiaop property,
21609     * please file a ticket to let us know what it's used for and we can see if
21610     * we need to expose hooks for that functionality more formally.
21611     */
21612    objs: null,
21613
21614    /**
21615     * <p>Execute the supplied method before the specified function.  Wrapping
21616     * function may optionally return an instance of the following classes to
21617     * further alter runtime behavior:</p>
21618     * <dl>
21619     *     <dt></code>Y.Do.Halt(message, returnValue)</code></dt>
21620     *         <dd>Immediatly stop execution and return
21621     *         <code>returnValue</code>.  No other wrapping functions will be
21622     *         executed.</dd>
21623     *     <dt></code>Y.Do.AlterArgs(message, newArgArray)</code></dt>
21624     *         <dd>Replace the arguments that the original function will be
21625     *         called with.</dd>
21626     *     <dt></code>Y.Do.Prevent(message)</code></dt>
21627     *         <dd>Don't execute the wrapped function.  Other before phase
21628     *         wrappers will be executed.</dd>
21629     * </dl>
21630     *
21631     * @method before
21632     * @param fn {Function} the function to execute
21633     * @param obj the object hosting the method to displace
21634     * @param sFn {string} the name of the method to displace
21635     * @param c The execution context for fn
21636     * @param arg* {mixed} 0..n additional arguments to supply to the subscriber
21637     * when the event fires.
21638     * @return {EventHandle} handle for the subscription
21639     * @static
21640     */
21641    before: function(fn, obj, sFn, c) {
21642        var f = fn, a;
21643        if (c) {
21644            a = [fn, c].concat(Y.Array(arguments, 4, true));
21645            f = Y.rbind.apply(Y, a);
21646        }
21647
21648        return this._inject(DO_BEFORE, f, obj, sFn);
21649    },
21650
21651    /**
21652     * <p>Execute the supplied method after the specified function.  Wrapping
21653     * function may optionally return an instance of the following classes to
21654     * further alter runtime behavior:</p>
21655     * <dl>
21656     *     <dt></code>Y.Do.Halt(message, returnValue)</code></dt>
21657     *         <dd>Immediatly stop execution and return
21658     *         <code>returnValue</code>.  No other wrapping functions will be
21659     *         executed.</dd>
21660     *     <dt></code>Y.Do.AlterReturn(message, returnValue)</code></dt>
21661     *         <dd>Return <code>returnValue</code> instead of the wrapped
21662     *         method's original return value.  This can be further altered by
21663     *         other after phase wrappers.</dd>
21664     * </dl>
21665     *
21666     * <p>The static properties <code>Y.Do.originalRetVal</code> and
21667     * <code>Y.Do.currentRetVal</code> will be populated for reference.</p>
21668     *
21669     * @method after
21670     * @param fn {Function} the function to execute
21671     * @param obj the object hosting the method to displace
21672     * @param sFn {string} the name of the method to displace
21673     * @param c The execution context for fn
21674     * @param arg* {mixed} 0..n additional arguments to supply to the subscriber
21675     * @return {EventHandle} handle for the subscription
21676     * @static
21677     */
21678    after: function(fn, obj, sFn, c) {
21679        var f = fn, a;
21680        if (c) {
21681            a = [fn, c].concat(Y.Array(arguments, 4, true));
21682            f = Y.rbind.apply(Y, a);
21683        }
21684
21685        return this._inject(DO_AFTER, f, obj, sFn);
21686    },
21687
21688    /**
21689     * Execute the supplied method before or after the specified function.
21690     * Used by <code>before</code> and <code>after</code>.
21691     *
21692     * @method _inject
21693     * @param when {string} before or after
21694     * @param fn {Function} the function to execute
21695     * @param obj the object hosting the method to displace
21696     * @param sFn {string} the name of the method to displace
21697     * @param c The execution context for fn
21698     * @return {EventHandle} handle for the subscription
21699     * @private
21700     * @static
21701     */
21702    _inject: function(when, fn, obj, sFn) {
21703        // object id
21704        var id = Y.stamp(obj), o, sid;
21705
21706        if (!obj._yuiaop) {
21707            // create a map entry for the obj if it doesn't exist, to hold overridden methods
21708            obj._yuiaop = {};
21709        }
21710
21711        o = obj._yuiaop;
21712
21713        if (!o[sFn]) {
21714            // create a map entry for the method if it doesn't exist
21715            o[sFn] = new Y.Do.Method(obj, sFn);
21716
21717            // re-route the method to our wrapper
21718            obj[sFn] = function() {
21719                return o[sFn].exec.apply(o[sFn], arguments);
21720            };
21721        }
21722
21723        // subscriber id
21724        sid = id + Y.stamp(fn) + sFn;
21725
21726        // register the callback
21727        o[sFn].register(sid, fn, when);
21728
21729        return new Y.EventHandle(o[sFn], sid);
21730    },
21731
21732    /**
21733     * Detach a before or after subscription.
21734     *
21735     * @method detach
21736     * @param handle {EventHandle} the subscription handle
21737     * @static
21738     */
21739    detach: function(handle) {
21740        if (handle.detach) {
21741            handle.detach();
21742        }
21743    }
21744};
21745
21746Y.Do = DO;
21747
21748//////////////////////////////////////////////////////////////////////////
21749
21750/**
21751 * Contains the return value from the wrapped method, accessible
21752 * by 'after' event listeners.
21753 *
21754 * @property originalRetVal
21755 * @static
21756 * @since 3.2.0
21757 */
21758
21759/**
21760 * Contains the current state of the return value, consumable by
21761 * 'after' event listeners, and updated if an after subscriber
21762 * changes the return value generated by the wrapped function.
21763 *
21764 * @property currentRetVal
21765 * @static
21766 * @since 3.2.0
21767 */
21768
21769//////////////////////////////////////////////////////////////////////////
21770
21771/**
21772 * Wrapper for a displaced method with aop enabled
21773 * @class Do.Method
21774 * @constructor
21775 * @param obj The object to operate on
21776 * @param sFn The name of the method to displace
21777 */
21778DO.Method = function(obj, sFn) {
21779    this.obj = obj;
21780    this.methodName = sFn;
21781    this.method = obj[sFn];
21782    this.before = {};
21783    this.after = {};
21784};
21785
21786/**
21787 * Register a aop subscriber
21788 * @method register
21789 * @param sid {string} the subscriber id
21790 * @param fn {Function} the function to execute
21791 * @param when {string} when to execute the function
21792 */
21793DO.Method.prototype.register = function (sid, fn, when) {
21794    if (when) {
21795        this.after[sid] = fn;
21796    } else {
21797        this.before[sid] = fn;
21798    }
21799};
21800
21801/**
21802 * Unregister a aop subscriber
21803 * @method delete
21804 * @param sid {string} the subscriber id
21805 * @param fn {Function} the function to execute
21806 * @param when {string} when to execute the function
21807 */
21808DO.Method.prototype._delete = function (sid) {
21809    delete this.before[sid];
21810    delete this.after[sid];
21811};
21812
21813/**
21814 * <p>Execute the wrapped method.  All arguments are passed into the wrapping
21815 * functions.  If any of the before wrappers return an instance of
21816 * <code>Y.Do.Halt</code> or <code>Y.Do.Prevent</code>, neither the wrapped
21817 * function nor any after phase subscribers will be executed.</p>
21818 *
21819 * <p>The return value will be the return value of the wrapped function or one
21820 * provided by a wrapper function via an instance of <code>Y.Do.Halt</code> or
21821 * <code>Y.Do.AlterReturn</code>.
21822 *
21823 * @method exec
21824 * @param arg* {any} Arguments are passed to the wrapping and wrapped functions
21825 * @return {any} Return value of wrapped function unless overwritten (see above)
21826 */
21827DO.Method.prototype.exec = function () {
21828
21829    var args = Y.Array(arguments, 0, true),
21830        i, ret, newRet,
21831        bf = this.before,
21832        af = this.after,
21833        prevented = false;
21834
21835    // execute before
21836    for (i in bf) {
21837        if (bf.hasOwnProperty(i)) {
21838            ret = bf[i].apply(this.obj, args);
21839            if (ret) {
21840                switch (ret.constructor) {
21841                    case DO.Halt:
21842                        return ret.retVal;
21843                    case DO.AlterArgs:
21844                        args = ret.newArgs;
21845                        break;
21846                    case DO.Prevent:
21847                        prevented = true;
21848                        break;
21849                    default:
21850                }
21851            }
21852        }
21853    }
21854
21855    // execute method
21856    if (!prevented) {
21857        ret = this.method.apply(this.obj, args);
21858    }
21859
21860    DO.originalRetVal = ret;
21861    DO.currentRetVal = ret;
21862
21863    // execute after methods.
21864    for (i in af) {
21865        if (af.hasOwnProperty(i)) {
21866            newRet = af[i].apply(this.obj, args);
21867            // Stop processing if a Halt object is returned
21868            if (newRet && newRet.constructor === DO.Halt) {
21869                return newRet.retVal;
21870            // Check for a new return value
21871            } else if (newRet && newRet.constructor === DO.AlterReturn) {
21872                ret = newRet.newRetVal;
21873                // Update the static retval state
21874                DO.currentRetVal = ret;
21875            }
21876        }
21877    }
21878
21879    return ret;
21880};
21881
21882//////////////////////////////////////////////////////////////////////////
21883
21884/**
21885 * Return an AlterArgs object when you want to change the arguments that
21886 * were passed into the function.  Useful for Do.before subscribers.  An
21887 * example would be a service that scrubs out illegal characters prior to
21888 * executing the core business logic.
21889 * @class Do.AlterArgs
21890 * @constructor
21891 * @param msg {String} (optional) Explanation of the altered return value
21892 * @param newArgs {Array} Call parameters to be used for the original method
21893 *                        instead of the arguments originally passed in.
21894 */
21895DO.AlterArgs = function(msg, newArgs) {
21896    this.msg = msg;
21897    this.newArgs = newArgs;
21898};
21899
21900/**
21901 * Return an AlterReturn object when you want to change the result returned
21902 * from the core method to the caller.  Useful for Do.after subscribers.
21903 * @class Do.AlterReturn
21904 * @constructor
21905 * @param msg {String} (optional) Explanation of the altered return value
21906 * @param newRetVal {any} Return value passed to code that invoked the wrapped
21907 *                      function.
21908 */
21909DO.AlterReturn = function(msg, newRetVal) {
21910    this.msg = msg;
21911    this.newRetVal = newRetVal;
21912};
21913
21914/**
21915 * Return a Halt object when you want to terminate the execution
21916 * of all subsequent subscribers as well as the wrapped method
21917 * if it has not exectued yet.  Useful for Do.before subscribers.
21918 * @class Do.Halt
21919 * @constructor
21920 * @param msg {String} (optional) Explanation of why the termination was done
21921 * @param retVal {any} Return value passed to code that invoked the wrapped
21922 *                      function.
21923 */
21924DO.Halt = function(msg, retVal) {
21925    this.msg = msg;
21926    this.retVal = retVal;
21927};
21928
21929/**
21930 * Return a Prevent object when you want to prevent the wrapped function
21931 * from executing, but want the remaining listeners to execute.  Useful
21932 * for Do.before subscribers.
21933 * @class Do.Prevent
21934 * @constructor
21935 * @param msg {String} (optional) Explanation of why the termination was done
21936 */
21937DO.Prevent = function(msg) {
21938    this.msg = msg;
21939};
21940
21941/**
21942 * Return an Error object when you want to terminate the execution
21943 * of all subsequent method calls.
21944 * @class Do.Error
21945 * @constructor
21946 * @param msg {String} (optional) Explanation of the altered return value
21947 * @param retVal {any} Return value passed to code that invoked the wrapped
21948 *                      function.
21949 * @deprecated use Y.Do.Halt or Y.Do.Prevent
21950 */
21951DO.Error = DO.Halt;
21952
21953
21954//////////////////////////////////////////////////////////////////////////
21955
21956/**
21957 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
21958 * events.
21959 * @module event-custom
21960 * @submodule event-custom-base
21961 */
21962
21963
21964// var onsubscribeType = "_event:onsub",
21965var YArray = Y.Array,
21966
21967    AFTER = 'after',
21968    CONFIGS = [
21969        'broadcast',
21970        'monitored',
21971        'bubbles',
21972        'context',
21973        'contextFn',
21974        'currentTarget',
21975        'defaultFn',
21976        'defaultTargetOnly',
21977        'details',
21978        'emitFacade',
21979        'fireOnce',
21980        'async',
21981        'host',
21982        'preventable',
21983        'preventedFn',
21984        'queuable',
21985        'silent',
21986        'stoppedFn',
21987        'target',
21988        'type'
21989    ],
21990
21991    CONFIGS_HASH = YArray.hash(CONFIGS),
21992
21993    nativeSlice = Array.prototype.slice,
21994
21995    YUI3_SIGNATURE = 9,
21996    YUI_LOG = 'yui:log',
21997
21998    mixConfigs = function(r, s, ov) {
21999        var p;
22000
22001        for (p in s) {
22002            if (CONFIGS_HASH[p] && (ov || !(p in r))) {
22003                r[p] = s[p];
22004            }
22005        }
22006
22007        return r;
22008    };
22009
22010/**
22011 * The CustomEvent class lets you define events for your application
22012 * that can be subscribed to by one or more independent component.
22013 *
22014 * @param {String} type The type of event, which is passed to the callback
22015 * when the event fires.
22016 * @param {object} defaults configuration object.
22017 * @class CustomEvent
22018 * @constructor
22019 */
22020
22021 /**
22022 * The type of event, returned to subscribers when the event fires
22023 * @property type
22024 * @type string
22025 */
22026
22027/**
22028 * By default all custom events are logged in the debug build, set silent
22029 * to true to disable debug outpu for this event.
22030 * @property silent
22031 * @type boolean
22032 */
22033
22034Y.CustomEvent = function(type, defaults) {
22035
22036    this._kds = Y.CustomEvent.keepDeprecatedSubs;
22037
22038    this.id = Y.guid();
22039
22040    this.type = type;
22041    this.silent = this.logSystem = (type === YUI_LOG);
22042
22043    if (this._kds) {
22044        /**
22045         * The subscribers to this event
22046         * @property subscribers
22047         * @type Subscriber {}
22048         * @deprecated
22049         */
22050
22051        /**
22052         * 'After' subscribers
22053         * @property afters
22054         * @type Subscriber {}
22055         * @deprecated
22056         */
22057        this.subscribers = {};
22058        this.afters = {};
22059    }
22060
22061    if (defaults) {
22062        mixConfigs(this, defaults, true);
22063    }
22064};
22065
22066/**
22067 * Static flag to enable population of the <a href="#property_subscribers">`subscribers`</a>
22068 * and  <a href="#property_subscribers">`afters`</a> properties held on a `CustomEvent` instance.
22069 *
22070 * These properties were changed to private properties (`_subscribers` and `_afters`), and
22071 * converted from objects to arrays for performance reasons.
22072 *
22073 * Setting this property to true will populate the deprecated `subscribers` and `afters`
22074 * properties for people who may be using them (which is expected to be rare). There will
22075 * be a performance hit, compared to the new array based implementation.
22076 *
22077 * If you are using these deprecated properties for a use case which the public API
22078 * does not support, please file an enhancement request, and we can provide an alternate
22079 * public implementation which doesn't have the performance cost required to maintiain the
22080 * properties as objects.
22081 *
22082 * @property keepDeprecatedSubs
22083 * @static
22084 * @for CustomEvent
22085 * @type boolean
22086 * @default false
22087 * @deprecated
22088 */
22089Y.CustomEvent.keepDeprecatedSubs = false;
22090
22091Y.CustomEvent.mixConfigs = mixConfigs;
22092
22093Y.CustomEvent.prototype = {
22094
22095    constructor: Y.CustomEvent,
22096
22097    /**
22098     * Monitor when an event is attached or detached.
22099     *
22100     * @property monitored
22101     * @type boolean
22102     */
22103
22104    /**
22105     * If 0, this event does not broadcast.  If 1, the YUI instance is notified
22106     * every time this event fires.  If 2, the YUI instance and the YUI global
22107     * (if event is enabled on the global) are notified every time this event
22108     * fires.
22109     * @property broadcast
22110     * @type int
22111     */
22112
22113    /**
22114     * Specifies whether this event should be queued when the host is actively
22115     * processing an event.  This will effect exectution order of the callbacks
22116     * for the various events.
22117     * @property queuable
22118     * @type boolean
22119     * @default false
22120     */
22121
22122    /**
22123     * This event has fired if true
22124     *
22125     * @property fired
22126     * @type boolean
22127     * @default false;
22128     */
22129
22130    /**
22131     * An array containing the arguments the custom event
22132     * was last fired with.
22133     * @property firedWith
22134     * @type Array
22135     */
22136
22137    /**
22138     * This event should only fire one time if true, and if
22139     * it has fired, any new subscribers should be notified
22140     * immediately.
22141     *
22142     * @property fireOnce
22143     * @type boolean
22144     * @default false;
22145     */
22146
22147    /**
22148     * fireOnce listeners will fire syncronously unless async
22149     * is set to true
22150     * @property async
22151     * @type boolean
22152     * @default false
22153     */
22154
22155    /**
22156     * Flag for stopPropagation that is modified during fire()
22157     * 1 means to stop propagation to bubble targets.  2 means
22158     * to also stop additional subscribers on this target.
22159     * @property stopped
22160     * @type int
22161     */
22162
22163    /**
22164     * Flag for preventDefault that is modified during fire().
22165     * if it is not 0, the default behavior for this event
22166     * @property prevented
22167     * @type int
22168     */
22169
22170    /**
22171     * Specifies the host for this custom event.  This is used
22172     * to enable event bubbling
22173     * @property host
22174     * @type EventTarget
22175     */
22176
22177    /**
22178     * The default function to execute after event listeners
22179     * have fire, but only if the default action was not
22180     * prevented.
22181     * @property defaultFn
22182     * @type Function
22183     */
22184
22185    /**
22186     * Flag for the default function to execute only if the
22187     * firing event is the current target. This happens only
22188     * when using custom event delegation and setting the
22189     * flag to `true` mimics the behavior of event delegation
22190     * in the DOM.
22191     *
22192     * @property defaultTargetOnly
22193     * @type Boolean
22194     * @default false
22195     */
22196
22197    /**
22198     * The function to execute if a subscriber calls
22199     * stopPropagation or stopImmediatePropagation
22200     * @property stoppedFn
22201     * @type Function
22202     */
22203
22204    /**
22205     * The function to execute if a subscriber calls
22206     * preventDefault
22207     * @property preventedFn
22208     * @type Function
22209     */
22210
22211    /**
22212     * The subscribers to this event
22213     * @property _subscribers
22214     * @type Subscriber []
22215     * @private
22216     */
22217
22218    /**
22219     * 'After' subscribers
22220     * @property _afters
22221     * @type Subscriber []
22222     * @private
22223     */
22224
22225    /**
22226     * If set to true, the custom event will deliver an EventFacade object
22227     * that is similar to a DOM event object.
22228     * @property emitFacade
22229     * @type boolean
22230     * @default false
22231     */
22232
22233    /**
22234     * Supports multiple options for listener signatures in order to
22235     * port YUI 2 apps.
22236     * @property signature
22237     * @type int
22238     * @default 9
22239     */
22240    signature : YUI3_SIGNATURE,
22241
22242    /**
22243     * The context the the event will fire from by default.  Defaults to the YUI
22244     * instance.
22245     * @property context
22246     * @type object
22247     */
22248    context : Y,
22249
22250    /**
22251     * Specifies whether or not this event's default function
22252     * can be cancelled by a subscriber by executing preventDefault()
22253     * on the event facade
22254     * @property preventable
22255     * @type boolean
22256     * @default true
22257     */
22258    preventable : true,
22259
22260    /**
22261     * Specifies whether or not a subscriber can stop the event propagation
22262     * via stopPropagation(), stopImmediatePropagation(), or halt()
22263     *
22264     * Events can only bubble if emitFacade is true.
22265     *
22266     * @property bubbles
22267     * @type boolean
22268     * @default true
22269     */
22270    bubbles : true,
22271
22272    /**
22273     * Returns the number of subscribers for this event as the sum of the on()
22274     * subscribers and after() subscribers.
22275     *
22276     * @method hasSubs
22277     * @return Number
22278     */
22279    hasSubs: function(when) {
22280        var s = 0,
22281            a = 0,
22282            subs = this._subscribers,
22283            afters = this._afters,
22284            sib = this.sibling;
22285
22286        if (subs) {
22287            s = subs.length;
22288        }
22289
22290        if (afters) {
22291            a = afters.length;
22292        }
22293
22294        if (sib) {
22295            subs = sib._subscribers;
22296            afters = sib._afters;
22297
22298            if (subs) {
22299                s += subs.length;
22300            }
22301
22302            if (afters) {
22303                a += afters.length;
22304            }
22305        }
22306
22307        if (when) {
22308            return (when === 'after') ? a : s;
22309        }
22310
22311        return (s + a);
22312    },
22313
22314    /**
22315     * Monitor the event state for the subscribed event.  The first parameter
22316     * is what should be monitored, the rest are the normal parameters when
22317     * subscribing to an event.
22318     * @method monitor
22319     * @param what {string} what to monitor ('detach', 'attach', 'publish').
22320     * @return {EventHandle} return value from the monitor event subscription.
22321     */
22322    monitor: function(what) {
22323        this.monitored = true;
22324        var type = this.id + '|' + this.type + '_' + what,
22325            args = nativeSlice.call(arguments, 0);
22326        args[0] = type;
22327        return this.host.on.apply(this.host, args);
22328    },
22329
22330    /**
22331     * Get all of the subscribers to this event and any sibling event
22332     * @method getSubs
22333     * @return {Array} first item is the on subscribers, second the after.
22334     */
22335    getSubs: function() {
22336
22337        var sibling = this.sibling,
22338            subs = this._subscribers,
22339            afters = this._afters,
22340            siblingSubs,
22341            siblingAfters;
22342
22343        if (sibling) {
22344            siblingSubs = sibling._subscribers;
22345            siblingAfters = sibling._afters;
22346        }
22347
22348        if (siblingSubs) {
22349            if (subs) {
22350                subs = subs.concat(siblingSubs);
22351            } else {
22352                subs = siblingSubs.concat();
22353            }
22354        } else {
22355            if (subs) {
22356                subs = subs.concat();
22357            } else {
22358                subs = [];
22359            }
22360        }
22361
22362        if (siblingAfters) {
22363            if (afters) {
22364                afters = afters.concat(siblingAfters);
22365            } else {
22366                afters = siblingAfters.concat();
22367            }
22368        } else {
22369            if (afters) {
22370                afters = afters.concat();
22371            } else {
22372                afters = [];
22373            }
22374        }
22375
22376        return [subs, afters];
22377    },
22378
22379    /**
22380     * Apply configuration properties.  Only applies the CONFIG whitelist
22381     * @method applyConfig
22382     * @param o hash of properties to apply.
22383     * @param force {boolean} if true, properties that exist on the event
22384     * will be overwritten.
22385     */
22386    applyConfig: function(o, force) {
22387        mixConfigs(this, o, force);
22388    },
22389
22390    /**
22391     * Create the Subscription for subscribing function, context, and bound
22392     * arguments.  If this is a fireOnce event, the subscriber is immediately
22393     * notified.
22394     *
22395     * @method _on
22396     * @param fn {Function} Subscription callback
22397     * @param [context] {Object} Override `this` in the callback
22398     * @param [args] {Array} bound arguments that will be passed to the callback after the arguments generated by fire()
22399     * @param [when] {String} "after" to slot into after subscribers
22400     * @return {EventHandle}
22401     * @protected
22402     */
22403    _on: function(fn, context, args, when) {
22404
22405
22406        var s = new Y.Subscriber(fn, context, args, when),
22407            firedWith;
22408
22409        if (this.fireOnce && this.fired) {
22410
22411            firedWith = this.firedWith;
22412
22413            // It's a little ugly for this to know about facades,
22414            // but given the current breakup, not much choice without
22415            // moving a whole lot of stuff around.
22416            if (this.emitFacade && this._addFacadeToArgs) {
22417                this._addFacadeToArgs(firedWith);
22418            }
22419
22420            if (this.async) {
22421                setTimeout(Y.bind(this._notify, this, s, firedWith), 0);
22422            } else {
22423                this._notify(s, firedWith);
22424            }
22425        }
22426
22427        if (when === AFTER) {
22428            if (!this._afters) {
22429                this._afters = [];
22430            }
22431            this._afters.push(s);
22432        } else {
22433            if (!this._subscribers) {
22434                this._subscribers = [];
22435            }
22436            this._subscribers.push(s);
22437        }
22438
22439        if (this._kds) {
22440            if (when === AFTER) {
22441                this.afters[s.id] = s;
22442            } else {
22443                this.subscribers[s.id] = s;
22444            }
22445        }
22446
22447        return new Y.EventHandle(this, s);
22448    },
22449
22450    /**
22451     * Listen for this event
22452     * @method subscribe
22453     * @param {Function} fn The function to execute.
22454     * @return {EventHandle} Unsubscribe handle.
22455     * @deprecated use on.
22456     */
22457    subscribe: function(fn, context) {
22458        var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
22459        return this._on(fn, context, a, true);
22460    },
22461
22462    /**
22463     * Listen for this event
22464     * @method on
22465     * @param {Function} fn The function to execute.
22466     * @param {object} context optional execution context.
22467     * @param {mixed} arg* 0..n additional arguments to supply to the subscriber
22468     * when the event fires.
22469     * @return {EventHandle} An object with a detach method to detch the handler(s).
22470     */
22471    on: function(fn, context) {
22472        var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
22473
22474        if (this.monitored && this.host) {
22475            this.host._monitor('attach', this, {
22476                args: arguments
22477            });
22478        }
22479        return this._on(fn, context, a, true);
22480    },
22481
22482    /**
22483     * Listen for this event after the normal subscribers have been notified and
22484     * the default behavior has been applied.  If a normal subscriber prevents the
22485     * default behavior, it also prevents after listeners from firing.
22486     * @method after
22487     * @param {Function} fn The function to execute.
22488     * @param {object} context optional execution context.
22489     * @param {mixed} arg* 0..n additional arguments to supply to the subscriber
22490     * when the event fires.
22491     * @return {EventHandle} handle Unsubscribe handle.
22492     */
22493    after: function(fn, context) {
22494        var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
22495        return this._on(fn, context, a, AFTER);
22496    },
22497
22498    /**
22499     * Detach listeners.
22500     * @method detach
22501     * @param {Function} fn  The subscribed function to remove, if not supplied
22502     *                       all will be removed.
22503     * @param {Object}   context The context object passed to subscribe.
22504     * @return {Number} returns the number of subscribers unsubscribed.
22505     */
22506    detach: function(fn, context) {
22507        // unsubscribe handle
22508        if (fn && fn.detach) {
22509            return fn.detach();
22510        }
22511
22512        var i, s,
22513            found = 0,
22514            subs = this._subscribers,
22515            afters = this._afters;
22516
22517        if (subs) {
22518            for (i = subs.length; i >= 0; i--) {
22519                s = subs[i];
22520                if (s && (!fn || fn === s.fn)) {
22521                    this._delete(s, subs, i);
22522                    found++;
22523                }
22524            }
22525        }
22526
22527        if (afters) {
22528            for (i = afters.length; i >= 0; i--) {
22529                s = afters[i];
22530                if (s && (!fn || fn === s.fn)) {
22531                    this._delete(s, afters, i);
22532                    found++;
22533                }
22534            }
22535        }
22536
22537        return found;
22538    },
22539
22540    /**
22541     * Detach listeners.
22542     * @method unsubscribe
22543     * @param {Function} fn  The subscribed function to remove, if not supplied
22544     *                       all will be removed.
22545     * @param {Object}   context The context object passed to subscribe.
22546     * @return {int|undefined} returns the number of subscribers unsubscribed.
22547     * @deprecated use detach.
22548     */
22549    unsubscribe: function() {
22550        return this.detach.apply(this, arguments);
22551    },
22552
22553    /**
22554     * Notify a single subscriber
22555     * @method _notify
22556     * @param {Subscriber} s the subscriber.
22557     * @param {Array} args the arguments array to apply to the listener.
22558     * @protected
22559     */
22560    _notify: function(s, args, ef) {
22561
22562
22563        var ret;
22564
22565        ret = s.notify(args, this);
22566
22567        if (false === ret || this.stopped > 1) {
22568            return false;
22569        }
22570
22571        return true;
22572    },
22573
22574    /**
22575     * Logger abstraction to centralize the application of the silent flag
22576     * @method log
22577     * @param {string} msg message to log.
22578     * @param {string} cat log category.
22579     */
22580    log: function(msg, cat) {
22581    },
22582
22583    /**
22584     * Notifies the subscribers.  The callback functions will be executed
22585     * from the context specified when the event was created, and with the
22586     * following parameters:
22587     *   <ul>
22588     *   <li>The type of event</li>
22589     *   <li>All of the arguments fire() was executed with as an array</li>
22590     *   <li>The custom object (if any) that was passed into the subscribe()
22591     *       method</li>
22592     *   </ul>
22593     * @method fire
22594     * @param {Object*} arguments an arbitrary set of parameters to pass to
22595     *                            the handler.
22596     * @return {boolean} false if one of the subscribers returned false,
22597     *                   true otherwise.
22598     *
22599     */
22600    fire: function() {
22601
22602        // push is the fastest way to go from arguments to arrays
22603        // for most browsers currently
22604        // http://jsperf.com/push-vs-concat-vs-slice/2
22605
22606        var args = [];
22607        args.push.apply(args, arguments);
22608
22609        return this._fire(args);
22610    },
22611
22612    /**
22613     * Private internal implementation for `fire`, which is can be used directly by
22614     * `EventTarget` and other event module classes which have already converted from
22615     * an `arguments` list to an array, to avoid the repeated overhead.
22616     *
22617     * @method _fire
22618     * @private
22619     * @param {Array} args The array of arguments passed to be passed to handlers.
22620     * @return {boolean} false if one of the subscribers returned false, true otherwise.
22621     */
22622    _fire: function(args) {
22623
22624        if (this.fireOnce && this.fired) {
22625            return true;
22626        } else {
22627
22628            // this doesn't happen if the event isn't published
22629            // this.host._monitor('fire', this.type, args);
22630
22631            this.fired = true;
22632
22633            if (this.fireOnce) {
22634                this.firedWith = args;
22635            }
22636
22637            if (this.emitFacade) {
22638                return this.fireComplex(args);
22639            } else {
22640                return this.fireSimple(args);
22641            }
22642        }
22643    },
22644
22645    /**
22646     * Set up for notifying subscribers of non-emitFacade events.
22647     *
22648     * @method fireSimple
22649     * @param args {Array} Arguments passed to fire()
22650     * @return Boolean false if a subscriber returned false
22651     * @protected
22652     */
22653    fireSimple: function(args) {
22654        this.stopped = 0;
22655        this.prevented = 0;
22656        if (this.hasSubs()) {
22657            var subs = this.getSubs();
22658            this._procSubs(subs[0], args);
22659            this._procSubs(subs[1], args);
22660        }
22661        if (this.broadcast) {
22662            this._broadcast(args);
22663        }
22664        return this.stopped ? false : true;
22665    },
22666
22667    // Requires the event-custom-complex module for full funcitonality.
22668    fireComplex: function(args) {
22669        args[0] = args[0] || {};
22670        return this.fireSimple(args);
22671    },
22672
22673    /**
22674     * Notifies a list of subscribers.
22675     *
22676     * @method _procSubs
22677     * @param subs {Array} List of subscribers
22678     * @param args {Array} Arguments passed to fire()
22679     * @param ef {}
22680     * @return Boolean false if a subscriber returns false or stops the event
22681     *              propagation via e.stopPropagation(),
22682     *              e.stopImmediatePropagation(), or e.halt()
22683     * @private
22684     */
22685    _procSubs: function(subs, args, ef) {
22686        var s, i, l;
22687
22688        for (i = 0, l = subs.length; i < l; i++) {
22689            s = subs[i];
22690            if (s && s.fn) {
22691                if (false === this._notify(s, args, ef)) {
22692                    this.stopped = 2;
22693                }
22694                if (this.stopped === 2) {
22695                    return false;
22696                }
22697            }
22698        }
22699
22700        return true;
22701    },
22702
22703    /**
22704     * Notifies the YUI instance if the event is configured with broadcast = 1,
22705     * and both the YUI instance and Y.Global if configured with broadcast = 2.
22706     *
22707     * @method _broadcast
22708     * @param args {Array} Arguments sent to fire()
22709     * @private
22710     */
22711    _broadcast: function(args) {
22712        if (!this.stopped && this.broadcast) {
22713
22714            var a = args.concat();
22715            a.unshift(this.type);
22716
22717            if (this.host !== Y) {
22718                Y.fire.apply(Y, a);
22719            }
22720
22721            if (this.broadcast === 2) {
22722                Y.Global.fire.apply(Y.Global, a);
22723            }
22724        }
22725    },
22726
22727    /**
22728     * Removes all listeners
22729     * @method unsubscribeAll
22730     * @return {Number} The number of listeners unsubscribed.
22731     * @deprecated use detachAll.
22732     */
22733    unsubscribeAll: function() {
22734        return this.detachAll.apply(this, arguments);
22735    },
22736
22737    /**
22738     * Removes all listeners
22739     * @method detachAll
22740     * @return {Number} The number of listeners unsubscribed.
22741     */
22742    detachAll: function() {
22743        return this.detach();
22744    },
22745
22746    /**
22747     * Deletes the subscriber from the internal store of on() and after()
22748     * subscribers.
22749     *
22750     * @method _delete
22751     * @param s subscriber object.
22752     * @param subs (optional) on or after subscriber array
22753     * @param index (optional) The index found.
22754     * @private
22755     */
22756    _delete: function(s, subs, i) {
22757        var when = s._when;
22758
22759        if (!subs) {
22760            subs = (when === AFTER) ? this._afters : this._subscribers;
22761        }
22762
22763        if (subs) {
22764            i = YArray.indexOf(subs, s, 0);
22765
22766            if (s && subs[i] === s) {
22767                subs.splice(i, 1);
22768            }
22769        }
22770
22771        if (this._kds) {
22772            if (when === AFTER) {
22773                delete this.afters[s.id];
22774            } else {
22775                delete this.subscribers[s.id];
22776            }
22777        }
22778
22779        if (this.monitored && this.host) {
22780            this.host._monitor('detach', this, {
22781                ce: this,
22782                sub: s
22783            });
22784        }
22785
22786        if (s) {
22787            s.deleted = true;
22788        }
22789    }
22790};
22791/**
22792 * Stores the subscriber information to be used when the event fires.
22793 * @param {Function} fn       The wrapped function to execute.
22794 * @param {Object}   context  The value of the keyword 'this' in the listener.
22795 * @param {Array} args*       0..n additional arguments to supply the listener.
22796 *
22797 * @class Subscriber
22798 * @constructor
22799 */
22800Y.Subscriber = function(fn, context, args, when) {
22801
22802    /**
22803     * The callback that will be execute when the event fires
22804     * This is wrapped by Y.rbind if obj was supplied.
22805     * @property fn
22806     * @type Function
22807     */
22808    this.fn = fn;
22809
22810    /**
22811     * Optional 'this' keyword for the listener
22812     * @property context
22813     * @type Object
22814     */
22815    this.context = context;
22816
22817    /**
22818     * Unique subscriber id
22819     * @property id
22820     * @type String
22821     */
22822    this.id = Y.guid();
22823
22824    /**
22825     * Additional arguments to propagate to the subscriber
22826     * @property args
22827     * @type Array
22828     */
22829    this.args = args;
22830
22831    this._when = when;
22832
22833    /**
22834     * Custom events for a given fire transaction.
22835     * @property events
22836     * @type {EventTarget}
22837     */
22838    // this.events = null;
22839
22840    /**
22841     * This listener only reacts to the event once
22842     * @property once
22843     */
22844    // this.once = false;
22845
22846};
22847
22848Y.Subscriber.prototype = {
22849    constructor: Y.Subscriber,
22850
22851    _notify: function(c, args, ce) {
22852        if (this.deleted && !this.postponed) {
22853            if (this.postponed) {
22854                delete this.fn;
22855                delete this.context;
22856            } else {
22857                delete this.postponed;
22858                return null;
22859            }
22860        }
22861        var a = this.args, ret;
22862        switch (ce.signature) {
22863            case 0:
22864                ret = this.fn.call(c, ce.type, args, c);
22865                break;
22866            case 1:
22867                ret = this.fn.call(c, args[0] || null, c);
22868                break;
22869            default:
22870                if (a || args) {
22871                    args = args || [];
22872                    a = (a) ? args.concat(a) : args;
22873                    ret = this.fn.apply(c, a);
22874                } else {
22875                    ret = this.fn.call(c);
22876                }
22877        }
22878
22879        if (this.once) {
22880            ce._delete(this);
22881        }
22882
22883        return ret;
22884    },
22885
22886    /**
22887     * Executes the subscriber.
22888     * @method notify
22889     * @param args {Array} Arguments array for the subscriber.
22890     * @param ce {CustomEvent} The custom event that sent the notification.
22891     */
22892    notify: function(args, ce) {
22893        var c = this.context,
22894            ret = true;
22895
22896        if (!c) {
22897            c = (ce.contextFn) ? ce.contextFn() : ce.context;
22898        }
22899
22900        // only catch errors if we will not re-throw them.
22901        if (Y.config && Y.config.throwFail) {
22902            ret = this._notify(c, args, ce);
22903        } else {
22904            try {
22905                ret = this._notify(c, args, ce);
22906            } catch (e) {
22907                Y.error(this + ' failed: ' + e.message, e);
22908            }
22909        }
22910
22911        return ret;
22912    },
22913
22914    /**
22915     * Returns true if the fn and obj match this objects properties.
22916     * Used by the unsubscribe method to match the right subscriber.
22917     *
22918     * @method contains
22919     * @param {Function} fn the function to execute.
22920     * @param {Object} context optional 'this' keyword for the listener.
22921     * @return {boolean} true if the supplied arguments match this
22922     *                   subscriber's signature.
22923     */
22924    contains: function(fn, context) {
22925        if (context) {
22926            return ((this.fn === fn) && this.context === context);
22927        } else {
22928            return (this.fn === fn);
22929        }
22930    },
22931
22932    valueOf : function() {
22933        return this.id;
22934    }
22935
22936};
22937/**
22938 * Return value from all subscribe operations
22939 * @class EventHandle
22940 * @constructor
22941 * @param {CustomEvent} evt the custom event.
22942 * @param {Subscriber} sub the subscriber.
22943 */
22944Y.EventHandle = function(evt, sub) {
22945
22946    /**
22947     * The custom event
22948     *
22949     * @property evt
22950     * @type CustomEvent
22951     */
22952    this.evt = evt;
22953
22954    /**
22955     * The subscriber object
22956     *
22957     * @property sub
22958     * @type Subscriber
22959     */
22960    this.sub = sub;
22961};
22962
22963Y.EventHandle.prototype = {
22964    batch: function(f, c) {
22965        f.call(c || this, this);
22966        if (Y.Lang.isArray(this.evt)) {
22967            Y.Array.each(this.evt, function(h) {
22968                h.batch.call(c || h, f);
22969            });
22970        }
22971    },
22972
22973    /**
22974     * Detaches this subscriber
22975     * @method detach
22976     * @return {Number} the number of detached listeners
22977     */
22978    detach: function() {
22979        var evt = this.evt, detached = 0, i;
22980        if (evt) {
22981            if (Y.Lang.isArray(evt)) {
22982                for (i = 0; i < evt.length; i++) {
22983                    detached += evt[i].detach();
22984                }
22985            } else {
22986                evt._delete(this.sub);
22987                detached = 1;
22988            }
22989
22990        }
22991
22992        return detached;
22993    },
22994
22995    /**
22996     * Monitor the event state for the subscribed event.  The first parameter
22997     * is what should be monitored, the rest are the normal parameters when
22998     * subscribing to an event.
22999     * @method monitor
23000     * @param what {string} what to monitor ('attach', 'detach', 'publish').
23001     * @return {EventHandle} return value from the monitor event subscription.
23002     */
23003    monitor: function(what) {
23004        return this.evt.monitor.apply(this.evt, arguments);
23005    }
23006};
23007
23008/**
23009 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
23010 * events.
23011 * @module event-custom
23012 * @submodule event-custom-base
23013 */
23014
23015/**
23016 * EventTarget provides the implementation for any object to
23017 * publish, subscribe and fire to custom events, and also
23018 * alows other EventTargets to target the object with events
23019 * sourced from the other object.
23020 * EventTarget is designed to be used with Y.augment to wrap
23021 * EventCustom in an interface that allows events to be listened to
23022 * and fired by name.  This makes it possible for implementing code to
23023 * subscribe to an event that either has not been created yet, or will
23024 * not be created at all.
23025 * @class EventTarget
23026 * @param opts a configuration object
23027 * @config emitFacade {boolean} if true, all events will emit event
23028 * facade payloads by default (default false)
23029 * @config prefix {String} the prefix to apply to non-prefixed event names
23030 */
23031
23032var L = Y.Lang,
23033    PREFIX_DELIMITER = ':',
23034    CATEGORY_DELIMITER = '|',
23035    AFTER_PREFIX = '~AFTER~',
23036    WILD_TYPE_RE = /(.*?)(:)(.*?)/,
23037
23038    _wildType = Y.cached(function(type) {
23039        return type.replace(WILD_TYPE_RE, "*$2$3");
23040    }),
23041
23042    /**
23043     * If the instance has a prefix attribute and the
23044     * event type is not prefixed, the instance prefix is
23045     * applied to the supplied type.
23046     * @method _getType
23047     * @private
23048     */
23049    _getType = function(type, pre) {
23050
23051        if (!pre || (typeof type !== "string") || type.indexOf(PREFIX_DELIMITER) > -1) {
23052            return type;
23053        }
23054
23055        return pre + PREFIX_DELIMITER + type;
23056    },
23057
23058    /**
23059     * Returns an array with the detach key (if provided),
23060     * and the prefixed event name from _getType
23061     * Y.on('detachcategory| menu:click', fn)
23062     * @method _parseType
23063     * @private
23064     */
23065    _parseType = Y.cached(function(type, pre) {
23066
23067        var t = type, detachcategory, after, i;
23068
23069        if (!L.isString(t)) {
23070            return t;
23071        }
23072
23073        i = t.indexOf(AFTER_PREFIX);
23074
23075        if (i > -1) {
23076            after = true;
23077            t = t.substr(AFTER_PREFIX.length);
23078        }
23079
23080        i = t.indexOf(CATEGORY_DELIMITER);
23081
23082        if (i > -1) {
23083            detachcategory = t.substr(0, (i));
23084            t = t.substr(i+1);
23085            if (t === '*') {
23086                t = null;
23087            }
23088        }
23089
23090        // detach category, full type with instance prefix, is this an after listener, short type
23091        return [detachcategory, (pre) ? _getType(t, pre) : t, after, t];
23092    }),
23093
23094    ET = function(opts) {
23095
23096        var etState = this._yuievt,
23097            etConfig;
23098
23099        if (!etState) {
23100            etState = this._yuievt = {
23101                events: {},    // PERF: Not much point instantiating lazily. We're bound to have events
23102                targets: null, // PERF: Instantiate lazily, if user actually adds target,
23103                config: {
23104                    host: this,
23105                    context: this
23106                },
23107                chain: Y.config.chain
23108            };
23109        }
23110
23111        etConfig = etState.config;
23112
23113        if (opts) {
23114            mixConfigs(etConfig, opts, true);
23115
23116            if (opts.chain !== undefined) {
23117                etState.chain = opts.chain;
23118            }
23119
23120            if (opts.prefix) {
23121                etConfig.prefix = opts.prefix;
23122            }
23123        }
23124    };
23125
23126ET.prototype = {
23127
23128    constructor: ET,
23129
23130    /**
23131     * Listen to a custom event hosted by this object one time.
23132     * This is the equivalent to <code>on</code> except the
23133     * listener is immediatelly detached when it is executed.
23134     * @method once
23135     * @param {String} type The name of the event
23136     * @param {Function} fn The callback to execute in response to the event
23137     * @param {Object} [context] Override `this` object in callback
23138     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23139     * @return {EventHandle} A subscription handle capable of detaching the
23140     *                       subscription
23141     */
23142    once: function() {
23143        var handle = this.on.apply(this, arguments);
23144        handle.batch(function(hand) {
23145            if (hand.sub) {
23146                hand.sub.once = true;
23147            }
23148        });
23149        return handle;
23150    },
23151
23152    /**
23153     * Listen to a custom event hosted by this object one time.
23154     * This is the equivalent to <code>after</code> except the
23155     * listener is immediatelly detached when it is executed.
23156     * @method onceAfter
23157     * @param {String} type The name of the event
23158     * @param {Function} fn The callback to execute in response to the event
23159     * @param {Object} [context] Override `this` object in callback
23160     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23161     * @return {EventHandle} A subscription handle capable of detaching that
23162     *                       subscription
23163     */
23164    onceAfter: function() {
23165        var handle = this.after.apply(this, arguments);
23166        handle.batch(function(hand) {
23167            if (hand.sub) {
23168                hand.sub.once = true;
23169            }
23170        });
23171        return handle;
23172    },
23173
23174    /**
23175     * Takes the type parameter passed to 'on' and parses out the
23176     * various pieces that could be included in the type.  If the
23177     * event type is passed without a prefix, it will be expanded
23178     * to include the prefix one is supplied or the event target
23179     * is configured with a default prefix.
23180     * @method parseType
23181     * @param {String} type the type
23182     * @param {String} [pre] The prefix. Defaults to this._yuievt.config.prefix
23183     * @since 3.3.0
23184     * @return {Array} an array containing:
23185     *  * the detach category, if supplied,
23186     *  * the prefixed event type,
23187     *  * whether or not this is an after listener,
23188     *  * the supplied event type
23189     */
23190    parseType: function(type, pre) {
23191        return _parseType(type, pre || this._yuievt.config.prefix);
23192    },
23193
23194    /**
23195     * Subscribe a callback function to a custom event fired by this object or
23196     * from an object that bubbles its events to this object.
23197     *
23198     *      this.on("change", this._onChange, this);
23199     *
23200     * Callback functions for events published with `emitFacade = true` will
23201     * receive an `EventFacade` as the first argument (typically named "e").
23202     * These callbacks can then call `e.preventDefault()` to disable the
23203     * behavior published to that event's `defaultFn`.  See the `EventFacade`
23204     * API for all available properties and methods. Subscribers to
23205     * non-`emitFacade` events will receive the arguments passed to `fire()`
23206     * after the event name.
23207     *
23208     * To subscribe to multiple events at once, pass an object as the first
23209     * argument, where the key:value pairs correspond to the eventName:callback.
23210     *
23211     *      this.on({
23212     *          "attrChange" : this._onAttrChange,
23213     *          "change"     : this._onChange
23214     *      });
23215     *
23216     * You can also pass an array of event names as the first argument to
23217     * subscribe to all listed events with the same callback.
23218     *
23219     *      this.on([ "change", "attrChange" ], this._onChange);
23220     *
23221     * Returning `false` from a callback is supported as an alternative to
23222     * calling `e.preventDefault(); e.stopPropagation();`.  However, it is
23223     * recommended to use the event methods whenever possible.
23224     *
23225     * @method on
23226     * @param {String} type The name of the event
23227     * @param {Function} fn The callback to execute in response to the event
23228     * @param {Object} [context] Override `this` object in callback
23229     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23230     * @return {EventHandle} A subscription handle capable of detaching that
23231     *                       subscription
23232     */
23233    on: function(type, fn, context) {
23234
23235        var yuievt = this._yuievt,
23236            parts = _parseType(type, yuievt.config.prefix), f, c, args, ret, ce,
23237            detachcategory, handle, store = Y.Env.evt.handles, after, adapt, shorttype,
23238            Node = Y.Node, n, domevent, isArr;
23239
23240        // full name, args, detachcategory, after
23241        this._monitor('attach', parts[1], {
23242            args: arguments,
23243            category: parts[0],
23244            after: parts[2]
23245        });
23246
23247        if (L.isObject(type)) {
23248
23249            if (L.isFunction(type)) {
23250                return Y.Do.before.apply(Y.Do, arguments);
23251            }
23252
23253            f = fn;
23254            c = context;
23255            args = nativeSlice.call(arguments, 0);
23256            ret = [];
23257
23258            if (L.isArray(type)) {
23259                isArr = true;
23260            }
23261
23262            after = type._after;
23263            delete type._after;
23264
23265            Y.each(type, function(v, k) {
23266
23267                if (L.isObject(v)) {
23268                    f = v.fn || ((L.isFunction(v)) ? v : f);
23269                    c = v.context || c;
23270                }
23271
23272                var nv = (after) ? AFTER_PREFIX : '';
23273
23274                args[0] = nv + ((isArr) ? v : k);
23275                args[1] = f;
23276                args[2] = c;
23277
23278                ret.push(this.on.apply(this, args));
23279
23280            }, this);
23281
23282            return (yuievt.chain) ? this : new Y.EventHandle(ret);
23283        }
23284
23285        detachcategory = parts[0];
23286        after = parts[2];
23287        shorttype = parts[3];
23288
23289        // extra redirection so we catch adaptor events too.  take a look at this.
23290        if (Node && Y.instanceOf(this, Node) && (shorttype in Node.DOM_EVENTS)) {
23291            args = nativeSlice.call(arguments, 0);
23292            args.splice(2, 0, Node.getDOMNode(this));
23293            return Y.on.apply(Y, args);
23294        }
23295
23296        type = parts[1];
23297
23298        if (Y.instanceOf(this, YUI)) {
23299
23300            adapt = Y.Env.evt.plugins[type];
23301            args  = nativeSlice.call(arguments, 0);
23302            args[0] = shorttype;
23303
23304            if (Node) {
23305                n = args[2];
23306
23307                if (Y.instanceOf(n, Y.NodeList)) {
23308                    n = Y.NodeList.getDOMNodes(n);
23309                } else if (Y.instanceOf(n, Node)) {
23310                    n = Node.getDOMNode(n);
23311                }
23312
23313                domevent = (shorttype in Node.DOM_EVENTS);
23314
23315                // Captures both DOM events and event plugins.
23316                if (domevent) {
23317                    args[2] = n;
23318                }
23319            }
23320
23321            // check for the existance of an event adaptor
23322            if (adapt) {
23323                handle = adapt.on.apply(Y, args);
23324            } else if ((!type) || domevent) {
23325                handle = Y.Event._attach(args);
23326            }
23327
23328        }
23329
23330        if (!handle) {
23331            ce = yuievt.events[type] || this.publish(type);
23332            handle = ce._on(fn, context, (arguments.length > 3) ? nativeSlice.call(arguments, 3) : null, (after) ? 'after' : true);
23333
23334            // TODO: More robust regex, accounting for category
23335            if (type.indexOf("*:") !== -1) {
23336                this._hasSiblings = true;
23337            }
23338        }
23339
23340        if (detachcategory) {
23341            store[detachcategory] = store[detachcategory] || {};
23342            store[detachcategory][type] = store[detachcategory][type] || [];
23343            store[detachcategory][type].push(handle);
23344        }
23345
23346        return (yuievt.chain) ? this : handle;
23347
23348    },
23349
23350    /**
23351     * subscribe to an event
23352     * @method subscribe
23353     * @deprecated use on
23354     */
23355    subscribe: function() {
23356        return this.on.apply(this, arguments);
23357    },
23358
23359    /**
23360     * Detach one or more listeners the from the specified event
23361     * @method detach
23362     * @param type {string|Object}   Either the handle to the subscriber or the
23363     *                        type of event.  If the type
23364     *                        is not specified, it will attempt to remove
23365     *                        the listener from all hosted events.
23366     * @param fn   {Function} The subscribed function to unsubscribe, if not
23367     *                          supplied, all subscribers will be removed.
23368     * @param context  {Object}   The custom object passed to subscribe.  This is
23369     *                        optional, but if supplied will be used to
23370     *                        disambiguate multiple listeners that are the same
23371     *                        (e.g., you subscribe many object using a function
23372     *                        that lives on the prototype)
23373     * @return {EventTarget} the host
23374     */
23375    detach: function(type, fn, context) {
23376
23377        var evts = this._yuievt.events,
23378            i,
23379            Node = Y.Node,
23380            isNode = Node && (Y.instanceOf(this, Node));
23381
23382        // detachAll disabled on the Y instance.
23383        if (!type && (this !== Y)) {
23384            for (i in evts) {
23385                if (evts.hasOwnProperty(i)) {
23386                    evts[i].detach(fn, context);
23387                }
23388            }
23389            if (isNode) {
23390                Y.Event.purgeElement(Node.getDOMNode(this));
23391            }
23392
23393            return this;
23394        }
23395
23396        var parts = _parseType(type, this._yuievt.config.prefix),
23397        detachcategory = L.isArray(parts) ? parts[0] : null,
23398        shorttype = (parts) ? parts[3] : null,
23399        adapt, store = Y.Env.evt.handles, detachhost, cat, args,
23400        ce,
23401
23402        keyDetacher = function(lcat, ltype, host) {
23403            var handles = lcat[ltype], ce, i;
23404            if (handles) {
23405                for (i = handles.length - 1; i >= 0; --i) {
23406                    ce = handles[i].evt;
23407                    if (ce.host === host || ce.el === host) {
23408                        handles[i].detach();
23409                    }
23410                }
23411            }
23412        };
23413
23414        if (detachcategory) {
23415
23416            cat = store[detachcategory];
23417            type = parts[1];
23418            detachhost = (isNode) ? Y.Node.getDOMNode(this) : this;
23419
23420            if (cat) {
23421                if (type) {
23422                    keyDetacher(cat, type, detachhost);
23423                } else {
23424                    for (i in cat) {
23425                        if (cat.hasOwnProperty(i)) {
23426                            keyDetacher(cat, i, detachhost);
23427                        }
23428                    }
23429                }
23430
23431                return this;
23432            }
23433
23434        // If this is an event handle, use it to detach
23435        } else if (L.isObject(type) && type.detach) {
23436            type.detach();
23437            return this;
23438        // extra redirection so we catch adaptor events too.  take a look at this.
23439        } else if (isNode && ((!shorttype) || (shorttype in Node.DOM_EVENTS))) {
23440            args = nativeSlice.call(arguments, 0);
23441            args[2] = Node.getDOMNode(this);
23442            Y.detach.apply(Y, args);
23443            return this;
23444        }
23445
23446        adapt = Y.Env.evt.plugins[shorttype];
23447
23448        // The YUI instance handles DOM events and adaptors
23449        if (Y.instanceOf(this, YUI)) {
23450            args = nativeSlice.call(arguments, 0);
23451            // use the adaptor specific detach code if
23452            if (adapt && adapt.detach) {
23453                adapt.detach.apply(Y, args);
23454                return this;
23455            // DOM event fork
23456            } else if (!type || (!adapt && Node && (type in Node.DOM_EVENTS))) {
23457                args[0] = type;
23458                Y.Event.detach.apply(Y.Event, args);
23459                return this;
23460            }
23461        }
23462
23463        // ce = evts[type];
23464        ce = evts[parts[1]];
23465        if (ce) {
23466            ce.detach(fn, context);
23467        }
23468
23469        return this;
23470    },
23471
23472    /**
23473     * detach a listener
23474     * @method unsubscribe
23475     * @deprecated use detach
23476     */
23477    unsubscribe: function() {
23478        return this.detach.apply(this, arguments);
23479    },
23480
23481    /**
23482     * Removes all listeners from the specified event.  If the event type
23483     * is not specified, all listeners from all hosted custom events will
23484     * be removed.
23485     * @method detachAll
23486     * @param type {String}   The type, or name of the event
23487     */
23488    detachAll: function(type) {
23489        return this.detach(type);
23490    },
23491
23492    /**
23493     * Removes all listeners from the specified event.  If the event type
23494     * is not specified, all listeners from all hosted custom events will
23495     * be removed.
23496     * @method unsubscribeAll
23497     * @param type {String}   The type, or name of the event
23498     * @deprecated use detachAll
23499     */
23500    unsubscribeAll: function() {
23501        return this.detachAll.apply(this, arguments);
23502    },
23503
23504    /**
23505     * Creates a new custom event of the specified type.  If a custom event
23506     * by that name already exists, it will not be re-created.  In either
23507     * case the custom event is returned.
23508     *
23509     * @method publish
23510     *
23511     * @param type {String} the type, or name of the event
23512     * @param opts {object} optional config params.  Valid properties are:
23513     * @param [opts.broadcast=false] {Boolean} whether or not the YUI instance and YUI global
23514     *      are notified when the event is fired.
23515     * @param [opts.bubbles=true] {Boolean} Whether or not this event bubbles. Events can
23516     *      only bubble if `emitFacade` is true.
23517     * @param [opts.context=this] {Object} the default execution context for the listeners.
23518     * @param [opts.defaultFn] {Function} the default function to execute when this event
23519     *      fires if preventDefault was not called.
23520     * @param [opts.emitFacade=false] {Boolean} whether or not this event emits a facade.
23521     * @param [opts.prefix] {String} the prefix for this targets events, e.g., 'menu' in 'menu:click'.
23522     * @param [opts.fireOnce=false] {Boolean} if an event is configured to fire once,
23523     *      new subscribers after the fire will be notified immediately.
23524     * @param [opts.async=false] {Boolean} fireOnce event listeners will fire synchronously
23525     *      if the event has already fired unless `async` is `true`.
23526     * @param [opts.preventable=true] {Boolean} whether or not `preventDefault()` has an effect.
23527     * @param [opts.preventedFn] {Function} a function that is executed when `preventDefault()` is called.
23528     * @param [opts.queuable=false] {Boolean} whether or not this event can be queued during bubbling.
23529     * @param [opts.silent] {Boolean} if silent is true, debug messages are not provided for this event.
23530     * @param [opts.stoppedFn] {Function} a function that is executed when stopPropagation is called.
23531     * @param [opts.monitored] {Boolean} specifies whether or not this event should send notifications about
23532     *      when the event has been attached, detached, or published.
23533     * @param [opts.type] {String} the event type (valid option if not provided as the first parameter to publish).
23534     *
23535     * @return {CustomEvent} the custom event
23536     *
23537     */
23538    publish: function(type, opts) {
23539
23540        var ret,
23541            etState = this._yuievt,
23542            etConfig = etState.config,
23543            pre = etConfig.prefix;
23544
23545        if (typeof type === "string")  {
23546            if (pre) {
23547                type = _getType(type, pre);
23548            }
23549            ret = this._publish(type, etConfig, opts);
23550        } else {
23551            ret = {};
23552
23553            Y.each(type, function(v, k) {
23554                if (pre) {
23555                    k = _getType(k, pre);
23556                }
23557                ret[k] = this._publish(k, etConfig, v || opts);
23558            }, this);
23559
23560        }
23561
23562        return ret;
23563    },
23564
23565    /**
23566     * Returns the fully qualified type, given a short type string.
23567     * That is, returns "foo:bar" when given "bar" if "foo" is the configured prefix.
23568     *
23569     * NOTE: This method, unlike _getType, does no checking of the value passed in, and
23570     * is designed to be used with the low level _publish() method, for critical path
23571     * implementations which need to fast-track publish for performance reasons.
23572     *
23573     * @method _getFullType
23574     * @private
23575     * @param {String} type The short type to prefix
23576     * @return {String} The prefixed type, if a prefix is set, otherwise the type passed in
23577     */
23578    _getFullType : function(type) {
23579
23580        var pre = this._yuievt.config.prefix;
23581
23582        if (pre) {
23583            return pre + PREFIX_DELIMITER + type;
23584        } else {
23585            return type;
23586        }
23587    },
23588
23589    /**
23590     * The low level event publish implementation. It expects all the massaging to have been done
23591     * outside of this method. e.g. the `type` to `fullType` conversion. It's designed to be a fast
23592     * path publish, which can be used by critical code paths to improve performance.
23593     *
23594     * @method _publish
23595     * @private
23596     * @param {String} fullType The prefixed type of the event to publish.
23597     * @param {Object} etOpts The EventTarget specific configuration to mix into the published event.
23598     * @param {Object} ceOpts The publish specific configuration to mix into the published event.
23599     * @return {CustomEvent} The published event. If called without `etOpts` or `ceOpts`, this will
23600     * be the default `CustomEvent` instance, and can be configured independently.
23601     */
23602    _publish : function(fullType, etOpts, ceOpts) {
23603
23604        var ce,
23605            etState = this._yuievt,
23606            etConfig = etState.config,
23607            host = etConfig.host,
23608            context = etConfig.context,
23609            events = etState.events;
23610
23611        ce = events[fullType];
23612
23613        // PERF: Hate to pull the check out of monitor, but trying to keep critical path tight.
23614        if ((etConfig.monitored && !ce) || (ce && ce.monitored)) {
23615            this._monitor('publish', fullType, {
23616                args: arguments
23617            });
23618        }
23619
23620        if (!ce) {
23621            // Publish event
23622            ce = events[fullType] = new Y.CustomEvent(fullType, etOpts);
23623
23624            if (!etOpts) {
23625                ce.host = host;
23626                ce.context = context;
23627            }
23628        }
23629
23630        if (ceOpts) {
23631            mixConfigs(ce, ceOpts, true);
23632        }
23633
23634        return ce;
23635    },
23636
23637    /**
23638     * This is the entry point for the event monitoring system.
23639     * You can monitor 'attach', 'detach', 'fire', and 'publish'.
23640     * When configured, these events generate an event.  click ->
23641     * click_attach, click_detach, click_publish -- these can
23642     * be subscribed to like other events to monitor the event
23643     * system.  Inividual published events can have monitoring
23644     * turned on or off (publish can't be turned off before it
23645     * it published) by setting the events 'monitor' config.
23646     *
23647     * @method _monitor
23648     * @param what {String} 'attach', 'detach', 'fire', or 'publish'
23649     * @param eventType {String|CustomEvent} The prefixed name of the event being monitored, or the CustomEvent object.
23650     * @param o {Object} Information about the event interaction, such as
23651     *                  fire() args, subscription category, publish config
23652     * @private
23653     */
23654    _monitor: function(what, eventType, o) {
23655        var monitorevt, ce, type;
23656
23657        if (eventType) {
23658            if (typeof eventType === "string") {
23659                type = eventType;
23660                ce = this.getEvent(eventType, true);
23661            } else {
23662                ce = eventType;
23663                type = eventType.type;
23664            }
23665
23666            if ((this._yuievt.config.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) {
23667                monitorevt = type + '_' + what;
23668                o.monitored = what;
23669                this.fire.call(this, monitorevt, o);
23670            }
23671        }
23672    },
23673
23674    /**
23675     * Fire a custom event by name.  The callback functions will be executed
23676     * from the context specified when the event was created, and with the
23677     * following parameters.
23678     *
23679     * The first argument is the event type, and any additional arguments are
23680     * passed to the listeners as parameters.  If the first of these is an
23681     * object literal, and the event is configured to emit an event facade,
23682     * that object is mixed into the event facade and the facade is provided
23683     * in place of the original object.
23684     *
23685     * If the custom event object hasn't been created, then the event hasn't
23686     * been published and it has no subscribers.  For performance sake, we
23687     * immediate exit in this case.  This means the event won't bubble, so
23688     * if the intention is that a bubble target be notified, the event must
23689     * be published on this object first.
23690     *
23691     * @method fire
23692     * @param type {String|Object} The type of the event, or an object that contains
23693     * a 'type' property.
23694     * @param arguments {Object*} an arbitrary set of parameters to pass to
23695     * the handler.  If the first of these is an object literal and the event is
23696     * configured to emit an event facade, the event facade will replace that
23697     * parameter after the properties the object literal contains are copied to
23698     * the event facade.
23699     * @return {Boolean} True if the whole lifecycle of the event went through,
23700     * false if at any point the event propagation was halted.
23701     */
23702    fire: function(type) {
23703
23704        var typeIncluded = (typeof type === "string"),
23705            argCount = arguments.length,
23706            t = type,
23707            yuievt = this._yuievt,
23708            etConfig = yuievt.config,
23709            pre = etConfig.prefix,
23710            ret,
23711            ce,
23712            ce2,
23713            args;
23714
23715        if (typeIncluded && argCount <= 3) {
23716
23717            // PERF: Try to avoid slice/iteration for the common signatures
23718
23719            // Most common
23720            if (argCount === 2) {
23721                args = [arguments[1]]; // fire("foo", {})
23722            } else if (argCount === 3) {
23723                args = [arguments[1], arguments[2]]; // fire("foo", {}, opts)
23724            } else {
23725                args = []; // fire("foo")
23726            }
23727
23728        } else {
23729            args = nativeSlice.call(arguments, ((typeIncluded) ? 1 : 0));
23730        }
23731
23732        if (!typeIncluded) {
23733            t = (type && type.type);
23734        }
23735
23736        if (pre) {
23737            t = _getType(t, pre);
23738        }
23739
23740        ce = yuievt.events[t];
23741
23742        if (this._hasSiblings) {
23743            ce2 = this.getSibling(t, ce);
23744
23745            if (ce2 && !ce) {
23746                ce = this.publish(t);
23747            }
23748        }
23749
23750        // PERF: trying to avoid function call, since this is a critical path
23751        if ((etConfig.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) {
23752            this._monitor('fire', (ce || t), {
23753                args: args
23754            });
23755        }
23756
23757        // this event has not been published or subscribed to
23758        if (!ce) {
23759            if (yuievt.hasTargets) {
23760                return this.bubble({ type: t }, args, this);
23761            }
23762
23763            // otherwise there is nothing to be done
23764            ret = true;
23765        } else {
23766
23767            if (ce2) {
23768                ce.sibling = ce2;
23769            }
23770
23771            ret = ce._fire(args);
23772        }
23773
23774        return (yuievt.chain) ? this : ret;
23775    },
23776
23777    getSibling: function(type, ce) {
23778        var ce2;
23779
23780        // delegate to *:type events if there are subscribers
23781        if (type.indexOf(PREFIX_DELIMITER) > -1) {
23782            type = _wildType(type);
23783            ce2 = this.getEvent(type, true);
23784            if (ce2) {
23785                ce2.applyConfig(ce);
23786                ce2.bubbles = false;
23787                ce2.broadcast = 0;
23788            }
23789        }
23790
23791        return ce2;
23792    },
23793
23794    /**
23795     * Returns the custom event of the provided type has been created, a
23796     * falsy value otherwise
23797     * @method getEvent
23798     * @param type {String} the type, or name of the event
23799     * @param prefixed {String} if true, the type is prefixed already
23800     * @return {CustomEvent} the custom event or null
23801     */
23802    getEvent: function(type, prefixed) {
23803        var pre, e;
23804
23805        if (!prefixed) {
23806            pre = this._yuievt.config.prefix;
23807            type = (pre) ? _getType(type, pre) : type;
23808        }
23809        e = this._yuievt.events;
23810        return e[type] || null;
23811    },
23812
23813    /**
23814     * Subscribe to a custom event hosted by this object.  The
23815     * supplied callback will execute after any listeners add
23816     * via the subscribe method, and after the default function,
23817     * if configured for the event, has executed.
23818     *
23819     * @method after
23820     * @param {String} type The name of the event
23821     * @param {Function} fn The callback to execute in response to the event
23822     * @param {Object} [context] Override `this` object in callback
23823     * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23824     * @return {EventHandle} A subscription handle capable of detaching the
23825     *                       subscription
23826     */
23827    after: function(type, fn) {
23828
23829        var a = nativeSlice.call(arguments, 0);
23830
23831        switch (L.type(type)) {
23832            case 'function':
23833                return Y.Do.after.apply(Y.Do, arguments);
23834            case 'array':
23835            //     YArray.each(a[0], function(v) {
23836            //         v = AFTER_PREFIX + v;
23837            //     });
23838            //     break;
23839            case 'object':
23840                a[0]._after = true;
23841                break;
23842            default:
23843                a[0] = AFTER_PREFIX + type;
23844        }
23845
23846        return this.on.apply(this, a);
23847
23848    },
23849
23850    /**
23851     * Executes the callback before a DOM event, custom event
23852     * or method.  If the first argument is a function, it
23853     * is assumed the target is a method.  For DOM and custom
23854     * events, this is an alias for Y.on.
23855     *
23856     * For DOM and custom events:
23857     * type, callback, context, 0-n arguments
23858     *
23859     * For methods:
23860     * callback, object (method host), methodName, context, 0-n arguments
23861     *
23862     * @method before
23863     * @return detach handle
23864     */
23865    before: function() {
23866        return this.on.apply(this, arguments);
23867    }
23868
23869};
23870
23871Y.EventTarget = ET;
23872
23873// make Y an event target
23874Y.mix(Y, ET.prototype);
23875ET.call(Y, { bubbles: false });
23876
23877YUI.Env.globalEvents = YUI.Env.globalEvents || new ET();
23878
23879/**
23880 * Hosts YUI page level events.  This is where events bubble to
23881 * when the broadcast config is set to 2.  This property is
23882 * only available if the custom event module is loaded.
23883 * @property Global
23884 * @type EventTarget
23885 * @for YUI
23886 */
23887Y.Global = YUI.Env.globalEvents;
23888
23889// @TODO implement a global namespace function on Y.Global?
23890
23891/**
23892`Y.on()` can do many things:
23893
23894<ul>
23895    <li>Subscribe to custom events `publish`ed and `fire`d from Y</li>
23896    <li>Subscribe to custom events `publish`ed with `broadcast` 1 or 2 and
23897        `fire`d from any object in the YUI instance sandbox</li>
23898    <li>Subscribe to DOM events</li>
23899    <li>Subscribe to the execution of a method on any object, effectively
23900    treating that method as an event</li>
23901</ul>
23902
23903For custom event subscriptions, pass the custom event name as the first argument
23904and callback as the second. The `this` object in the callback will be `Y` unless
23905an override is passed as the third argument.
23906
23907    Y.on('io:complete', function () {
23908        Y.MyApp.updateStatus('Transaction complete');
23909    });
23910
23911To subscribe to DOM events, pass the name of a DOM event as the first argument
23912and a CSS selector string as the third argument after the callback function.
23913Alternately, the third argument can be a `Node`, `NodeList`, `HTMLElement`,
23914array, or simply omitted (the default is the `window` object).
23915
23916    Y.on('click', function (e) {
23917        e.preventDefault();
23918
23919        // proceed with ajax form submission
23920        var url = this.get('action');
23921        ...
23922    }, '#my-form');
23923
23924The `this` object in DOM event callbacks will be the `Node` targeted by the CSS
23925selector or other identifier.
23926
23927`on()` subscribers for DOM events or custom events `publish`ed with a
23928`defaultFn` can prevent the default behavior with `e.preventDefault()` from the
23929event object passed as the first parameter to the subscription callback.
23930
23931To subscribe to the execution of an object method, pass arguments corresponding to the call signature for
23932<a href="../classes/Do.html#methods_before">`Y.Do.before(...)`</a>.
23933
23934NOTE: The formal parameter list below is for events, not for function
23935injection.  See `Y.Do.before` for that signature.
23936
23937@method on
23938@param {String} type DOM or custom event name
23939@param {Function} fn The callback to execute in response to the event
23940@param {Object} [context] Override `this` object in callback
23941@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23942@return {EventHandle} A subscription handle capable of detaching the
23943                      subscription
23944@see Do.before
23945@for YUI
23946**/
23947
23948/**
23949Listen for an event one time.  Equivalent to `on()`, except that
23950the listener is immediately detached when executed.
23951
23952See the <a href="#methods_on">`on()` method</a> for additional subscription
23953options.
23954
23955@see on
23956@method once
23957@param {String} type DOM or custom event name
23958@param {Function} fn The callback to execute in response to the event
23959@param {Object} [context] Override `this` object in callback
23960@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23961@return {EventHandle} A subscription handle capable of detaching the
23962                      subscription
23963@for YUI
23964**/
23965
23966/**
23967Listen for an event one time.  Equivalent to `once()`, except, like `after()`,
23968the subscription callback executes after all `on()` subscribers and the event's
23969`defaultFn` (if configured) have executed.  Like `after()` if any `on()` phase
23970subscriber calls `e.preventDefault()`, neither the `defaultFn` nor the `after()`
23971subscribers will execute.
23972
23973The listener is immediately detached when executed.
23974
23975See the <a href="#methods_on">`on()` method</a> for additional subscription
23976options.
23977
23978@see once
23979@method onceAfter
23980@param {String} type The custom event name
23981@param {Function} fn The callback to execute in response to the event
23982@param {Object} [context] Override `this` object in callback
23983@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
23984@return {EventHandle} A subscription handle capable of detaching the
23985                      subscription
23986@for YUI
23987**/
23988
23989/**
23990Like `on()`, this method creates a subscription to a custom event or to the
23991execution of a method on an object.
23992
23993For events, `after()` subscribers are executed after the event's
23994`defaultFn` unless `e.preventDefault()` was called from an `on()` subscriber.
23995
23996See the <a href="#methods_on">`on()` method</a> for additional subscription
23997options.
23998
23999NOTE: The subscription signature shown is for events, not for function
24000injection.  See <a href="../classes/Do.html#methods_after">`Y.Do.after`</a>
24001for that signature.
24002
24003@see on
24004@see Do.after
24005@method after
24006@param {String} type The custom event name
24007@param {Function} fn The callback to execute in response to the event
24008@param {Object} [context] Override `this` object in callback
24009@param {Any} [args*] 0..n additional arguments to supply to the subscriber
24010@return {EventHandle} A subscription handle capable of detaching the
24011                      subscription
24012@for YUI
24013**/
24014
24015
24016}, 'patched-v3.18.1', {"requires": ["oop"]});
24017
24018YUI.add('event-custom-complex', function (Y, NAME) {
24019
24020
24021/**
24022 * Adds event facades, preventable default behavior, and bubbling.
24023 * events.
24024 * @module event-custom
24025 * @submodule event-custom-complex
24026 */
24027
24028var FACADE,
24029    FACADE_KEYS,
24030    YObject = Y.Object,
24031    key,
24032    EMPTY = {},
24033    CEProto = Y.CustomEvent.prototype,
24034    ETProto = Y.EventTarget.prototype,
24035
24036    mixFacadeProps = function(facade, payload) {
24037        var p;
24038
24039        for (p in payload) {
24040            if (!(FACADE_KEYS.hasOwnProperty(p))) {
24041                facade[p] = payload[p];
24042            }
24043        }
24044    };
24045
24046/**
24047 * Wraps and protects a custom event for use when emitFacade is set to true.
24048 * Requires the event-custom-complex module
24049 * @class EventFacade
24050 * @param e {Event} the custom event
24051 * @param currentTarget {HTMLElement} the element the listener was attached to
24052 */
24053
24054Y.EventFacade = function(e, currentTarget) {
24055
24056    if (!e) {
24057        e = EMPTY;
24058    }
24059
24060    this._event = e;
24061
24062    /**
24063     * The arguments passed to fire
24064     * @property details
24065     * @type Array
24066     */
24067    this.details = e.details;
24068
24069    /**
24070     * The event type, this can be overridden by the fire() payload
24071     * @property type
24072     * @type string
24073     */
24074    this.type = e.type;
24075
24076    /**
24077     * The real event type
24078     * @property _type
24079     * @type string
24080     * @private
24081     */
24082    this._type = e.type;
24083
24084    //////////////////////////////////////////////////////
24085
24086    /**
24087     * Node reference for the targeted eventtarget
24088     * @property target
24089     * @type Node
24090     */
24091    this.target = e.target;
24092
24093    /**
24094     * Node reference for the element that the listener was attached to.
24095     * @property currentTarget
24096     * @type Node
24097     */
24098    this.currentTarget = currentTarget;
24099
24100    /**
24101     * Node reference to the relatedTarget
24102     * @property relatedTarget
24103     * @type Node
24104     */
24105    this.relatedTarget = e.relatedTarget;
24106
24107};
24108
24109Y.mix(Y.EventFacade.prototype, {
24110
24111    /**
24112     * Stops the propagation to the next bubble target
24113     * @method stopPropagation
24114     */
24115    stopPropagation: function() {
24116        this._event.stopPropagation();
24117        this.stopped = 1;
24118    },
24119
24120    /**
24121     * Stops the propagation to the next bubble target and
24122     * prevents any additional listeners from being exectued
24123     * on the current target.
24124     * @method stopImmediatePropagation
24125     */
24126    stopImmediatePropagation: function() {
24127        this._event.stopImmediatePropagation();
24128        this.stopped = 2;
24129    },
24130
24131    /**
24132     * Prevents the event's default behavior
24133     * @method preventDefault
24134     */
24135    preventDefault: function() {
24136        this._event.preventDefault();
24137        this.prevented = 1;
24138    },
24139
24140    /**
24141     * Stops the event propagation and prevents the default
24142     * event behavior.
24143     * @method halt
24144     * @param immediate {boolean} if true additional listeners
24145     * on the current target will not be executed
24146     */
24147    halt: function(immediate) {
24148        this._event.halt(immediate);
24149        this.prevented = 1;
24150        this.stopped = (immediate) ? 2 : 1;
24151    }
24152
24153});
24154
24155CEProto.fireComplex = function(args) {
24156
24157    var es,
24158        ef,
24159        q,
24160        queue,
24161        ce,
24162        ret = true,
24163        events,
24164        subs,
24165        ons,
24166        afters,
24167        afterQueue,
24168        postponed,
24169        prevented,
24170        preventedFn,
24171        defaultFn,
24172        self = this,
24173        host = self.host || self,
24174        next,
24175        oldbubble,
24176        stack = self.stack,
24177        yuievt = host._yuievt,
24178        hasPotentialSubscribers;
24179
24180    if (stack) {
24181
24182        // queue this event if the current item in the queue bubbles
24183        if (self.queuable && self.type !== stack.next.type) {
24184
24185            if (!stack.queue) {
24186                stack.queue = [];
24187            }
24188            stack.queue.push([self, args]);
24189
24190            return true;
24191        }
24192    }
24193
24194    hasPotentialSubscribers = self.hasSubs() || yuievt.hasTargets || self.broadcast;
24195
24196    self.target = self.target || host;
24197    self.currentTarget = host;
24198
24199    self.details = args.concat();
24200
24201    if (hasPotentialSubscribers) {
24202
24203        es = stack || {
24204
24205           id: self.id, // id of the first event in the stack
24206           next: self,
24207           silent: self.silent,
24208           stopped: 0,
24209           prevented: 0,
24210           bubbling: null,
24211           type: self.type,
24212           // defaultFnQueue: new Y.Queue(),
24213           defaultTargetOnly: self.defaultTargetOnly
24214
24215        };
24216
24217        subs = self.getSubs();
24218        ons = subs[0];
24219        afters = subs[1];
24220
24221        self.stopped = (self.type !== es.type) ? 0 : es.stopped;
24222        self.prevented = (self.type !== es.type) ? 0 : es.prevented;
24223
24224        if (self.stoppedFn) {
24225            // PERF TODO: Can we replace with callback, like preventedFn. Look into history
24226            events = new Y.EventTarget({
24227                fireOnce: true,
24228                context: host
24229            });
24230            self.events = events;
24231            events.on('stopped', self.stoppedFn);
24232        }
24233
24234
24235        self._facade = null; // kill facade to eliminate stale properties
24236
24237        ef = self._createFacade(args);
24238
24239        if (ons) {
24240            self._procSubs(ons, args, ef);
24241        }
24242
24243        // bubble if this is hosted in an event target and propagation has not been stopped
24244        if (self.bubbles && host.bubble && !self.stopped) {
24245            oldbubble = es.bubbling;
24246
24247            es.bubbling = self.type;
24248
24249            if (es.type !== self.type) {
24250                es.stopped = 0;
24251                es.prevented = 0;
24252            }
24253
24254            ret = host.bubble(self, args, null, es);
24255
24256            self.stopped = Math.max(self.stopped, es.stopped);
24257            self.prevented = Math.max(self.prevented, es.prevented);
24258
24259            es.bubbling = oldbubble;
24260        }
24261
24262        prevented = self.prevented;
24263
24264        if (prevented) {
24265            preventedFn = self.preventedFn;
24266            if (preventedFn) {
24267                preventedFn.apply(host, args);
24268            }
24269        } else {
24270            defaultFn = self.defaultFn;
24271
24272            if (defaultFn && ((!self.defaultTargetOnly && !es.defaultTargetOnly) || host === ef.target)) {
24273                defaultFn.apply(host, args);
24274            }
24275        }
24276
24277        // broadcast listeners are fired as discreet events on the
24278        // YUI instance and potentially the YUI global.
24279        if (self.broadcast) {
24280            self._broadcast(args);
24281        }
24282
24283        if (afters && !self.prevented && self.stopped < 2) {
24284
24285            // Queue the after
24286            afterQueue = es.afterQueue;
24287
24288            if (es.id === self.id || self.type !== yuievt.bubbling) {
24289
24290                self._procSubs(afters, args, ef);
24291
24292                if (afterQueue) {
24293                    while ((next = afterQueue.last())) {
24294                        next();
24295                    }
24296                }
24297            } else {
24298                postponed = afters;
24299
24300                if (es.execDefaultCnt) {
24301                    postponed = Y.merge(postponed);
24302
24303                    Y.each(postponed, function(s) {
24304                        s.postponed = true;
24305                    });
24306                }
24307
24308                if (!afterQueue) {
24309                    es.afterQueue = new Y.Queue();
24310                }
24311
24312                es.afterQueue.add(function() {
24313                    self._procSubs(postponed, args, ef);
24314                });
24315            }
24316
24317        }
24318
24319        self.target = null;
24320
24321        if (es.id === self.id) {
24322
24323            queue = es.queue;
24324
24325            if (queue) {
24326                while (queue.length) {
24327                    q = queue.pop();
24328                    ce = q[0];
24329                    // set up stack to allow the next item to be processed
24330                    es.next = ce;
24331                    ce._fire(q[1]);
24332                }
24333            }
24334
24335            self.stack = null;
24336        }
24337
24338        ret = !(self.stopped);
24339
24340        if (self.type !== yuievt.bubbling) {
24341            es.stopped = 0;
24342            es.prevented = 0;
24343            self.stopped = 0;
24344            self.prevented = 0;
24345        }
24346
24347    } else {
24348        defaultFn = self.defaultFn;
24349
24350        if(defaultFn) {
24351            ef = self._createFacade(args);
24352
24353            if ((!self.defaultTargetOnly) || (host === ef.target)) {
24354                defaultFn.apply(host, args);
24355            }
24356        }
24357    }
24358
24359    // Kill the cached facade to free up memory.
24360    // Otherwise we have the facade from the last fire, sitting around forever.
24361    self._facade = null;
24362
24363    return ret;
24364};
24365
24366/**
24367 * @method _hasPotentialSubscribers
24368 * @for CustomEvent
24369 * @private
24370 * @return {boolean} Whether the event has potential subscribers or not
24371 */
24372CEProto._hasPotentialSubscribers = function() {
24373    return this.hasSubs() || this.host._yuievt.hasTargets || this.broadcast;
24374};
24375
24376/**
24377 * Internal utility method to create a new facade instance and
24378 * insert it into the fire argument list, accounting for any payload
24379 * merging which needs to happen.
24380 *
24381 * This used to be called `_getFacade`, but the name seemed inappropriate
24382 * when it was used without a need for the return value.
24383 *
24384 * @method _createFacade
24385 * @private
24386 * @param fireArgs {Array} The arguments passed to "fire", which need to be
24387 * shifted (and potentially merged) when the facade is added.
24388 * @return {EventFacade} The event facade created.
24389 */
24390
24391// TODO: Remove (private) _getFacade alias, once synthetic.js is updated.
24392CEProto._createFacade = CEProto._getFacade = function(fireArgs) {
24393
24394    var userArgs = this.details,
24395        firstArg = userArgs && userArgs[0],
24396        firstArgIsObj = (firstArg && (typeof firstArg === "object")),
24397        ef = this._facade;
24398
24399    if (!ef) {
24400        ef = new Y.EventFacade(this, this.currentTarget);
24401    }
24402
24403    if (firstArgIsObj) {
24404        // protect the event facade properties
24405        mixFacadeProps(ef, firstArg);
24406
24407        // Allow the event type to be faked http://yuilibrary.com/projects/yui3/ticket/2528376
24408        if (firstArg.type) {
24409            ef.type = firstArg.type;
24410        }
24411
24412        if (fireArgs) {
24413            fireArgs[0] = ef;
24414        }
24415    } else {
24416        if (fireArgs) {
24417            fireArgs.unshift(ef);
24418        }
24419    }
24420
24421    // update the details field with the arguments
24422    ef.details = this.details;
24423
24424    // use the original target when the event bubbled to this target
24425    ef.target = this.originalTarget || this.target;
24426
24427    ef.currentTarget = this.currentTarget;
24428    ef.stopped = 0;
24429    ef.prevented = 0;
24430
24431    this._facade = ef;
24432
24433    return this._facade;
24434};
24435
24436/**
24437 * Utility method to manipulate the args array passed in, to add the event facade,
24438 * if it's not already the first arg.
24439 *
24440 * @method _addFacadeToArgs
24441 * @private
24442 * @param {Array} The arguments to manipulate
24443 */
24444CEProto._addFacadeToArgs = function(args) {
24445    var e = args[0];
24446
24447    // Trying not to use instanceof, just to avoid potential cross Y edge case issues.
24448    if (!(e && e.halt && e.stopImmediatePropagation && e.stopPropagation && e._event)) {
24449        this._createFacade(args);
24450    }
24451};
24452
24453/**
24454 * Stop propagation to bubble targets
24455 * @for CustomEvent
24456 * @method stopPropagation
24457 */
24458CEProto.stopPropagation = function() {
24459    this.stopped = 1;
24460    if (this.stack) {
24461        this.stack.stopped = 1;
24462    }
24463    if (this.events) {
24464        this.events.fire('stopped', this);
24465    }
24466};
24467
24468/**
24469 * Stops propagation to bubble targets, and prevents any remaining
24470 * subscribers on the current target from executing.
24471 * @method stopImmediatePropagation
24472 */
24473CEProto.stopImmediatePropagation = function() {
24474    this.stopped = 2;
24475    if (this.stack) {
24476        this.stack.stopped = 2;
24477    }
24478    if (this.events) {
24479        this.events.fire('stopped', this);
24480    }
24481};
24482
24483/**
24484 * Prevents the execution of this event's defaultFn
24485 * @method preventDefault
24486 */
24487CEProto.preventDefault = function() {
24488    if (this.preventable) {
24489        this.prevented = 1;
24490        if (this.stack) {
24491            this.stack.prevented = 1;
24492        }
24493    }
24494};
24495
24496/**
24497 * Stops the event propagation and prevents the default
24498 * event behavior.
24499 * @method halt
24500 * @param immediate {boolean} if true additional listeners
24501 * on the current target will not be executed
24502 */
24503CEProto.halt = function(immediate) {
24504    if (immediate) {
24505        this.stopImmediatePropagation();
24506    } else {
24507        this.stopPropagation();
24508    }
24509    this.preventDefault();
24510};
24511
24512/**
24513 * Registers another EventTarget as a bubble target.  Bubble order
24514 * is determined by the order registered.  Multiple targets can
24515 * be specified.
24516 *
24517 * Events can only bubble if emitFacade is true.
24518 *
24519 * Included in the event-custom-complex submodule.
24520 *
24521 * @method addTarget
24522 * @chainable
24523 * @param o {EventTarget} the target to add
24524 * @for EventTarget
24525 */
24526ETProto.addTarget = function(o) {
24527    var etState = this._yuievt;
24528
24529    if (!etState.targets) {
24530        etState.targets = {};
24531    }
24532
24533    etState.targets[Y.stamp(o)] = o;
24534    etState.hasTargets = true;
24535
24536    return this;
24537};
24538
24539/**
24540 * Returns an array of bubble targets for this object.
24541 * @method getTargets
24542 * @return EventTarget[]
24543 */
24544ETProto.getTargets = function() {
24545    var targets = this._yuievt.targets;
24546    return targets ? YObject.values(targets) : [];
24547};
24548
24549/**
24550 * Removes a bubble target
24551 * @method removeTarget
24552 * @chainable
24553 * @param o {EventTarget} the target to remove
24554 * @for EventTarget
24555 */
24556ETProto.removeTarget = function(o) {
24557    var targets = this._yuievt.targets;
24558
24559    if (targets) {
24560        delete targets[Y.stamp(o, true)];
24561
24562        if (YObject.size(targets) === 0) {
24563            this._yuievt.hasTargets = false;
24564        }
24565    }
24566
24567    return this;
24568};
24569
24570/**
24571 * Propagate an event.  Requires the event-custom-complex module.
24572 * @method bubble
24573 * @param evt {CustomEvent} the custom event to propagate
24574 * @return {boolean} the aggregated return value from Event.Custom.fire
24575 * @for EventTarget
24576 */
24577ETProto.bubble = function(evt, args, target, es) {
24578
24579    var targs = this._yuievt.targets,
24580        ret = true,
24581        t,
24582        ce,
24583        i,
24584        bc,
24585        ce2,
24586        type = evt && evt.type,
24587        originalTarget = target || (evt && evt.target) || this,
24588        oldbubble;
24589
24590    if (!evt || ((!evt.stopped) && targs)) {
24591
24592        for (i in targs) {
24593            if (targs.hasOwnProperty(i)) {
24594
24595                t = targs[i];
24596
24597                ce = t._yuievt.events[type];
24598
24599                if (t._hasSiblings) {
24600                    ce2 = t.getSibling(type, ce);
24601                }
24602
24603                if (ce2 && !ce) {
24604                    ce = t.publish(type);
24605                }
24606
24607                oldbubble = t._yuievt.bubbling;
24608                t._yuievt.bubbling = type;
24609
24610                // if this event was not published on the bubble target,
24611                // continue propagating the event.
24612                if (!ce) {
24613                    if (t._yuievt.hasTargets) {
24614                        t.bubble(evt, args, originalTarget, es);
24615                    }
24616                } else {
24617
24618                    if (ce2) {
24619                        ce.sibling = ce2;
24620                    }
24621
24622                    // set the original target to that the target payload on the facade is correct.
24623                    ce.target = originalTarget;
24624                    ce.originalTarget = originalTarget;
24625                    ce.currentTarget = t;
24626                    bc = ce.broadcast;
24627                    ce.broadcast = false;
24628
24629                    // default publish may not have emitFacade true -- that
24630                    // shouldn't be what the implementer meant to do
24631                    ce.emitFacade = true;
24632
24633                    ce.stack = es;
24634
24635                    // TODO: See what's getting in the way of changing this to use
24636                    // the more performant ce._fire(args || evt.details || []).
24637
24638                    // Something in Widget Parent/Child tests is not happy if we
24639                    // change it - maybe evt.details related?
24640                    ret = ret && ce.fire.apply(ce, args || evt.details || []);
24641
24642                    ce.broadcast = bc;
24643                    ce.originalTarget = null;
24644
24645                    // stopPropagation() was called
24646                    if (ce.stopped) {
24647                        break;
24648                    }
24649                }
24650
24651                t._yuievt.bubbling = oldbubble;
24652            }
24653        }
24654    }
24655
24656    return ret;
24657};
24658
24659/**
24660 * @method _hasPotentialSubscribers
24661 * @for EventTarget
24662 * @private
24663 * @param {String} fullType The fully prefixed type name
24664 * @return {boolean} Whether the event has potential subscribers or not
24665 */
24666ETProto._hasPotentialSubscribers = function(fullType) {
24667
24668    var etState = this._yuievt,
24669        e = etState.events[fullType];
24670
24671    if (e) {
24672        return e.hasSubs() || etState.hasTargets  || e.broadcast;
24673    } else {
24674        return false;
24675    }
24676};
24677
24678FACADE = new Y.EventFacade();
24679FACADE_KEYS = {};
24680
24681// Flatten whitelist
24682for (key in FACADE) {
24683    FACADE_KEYS[key] = true;
24684}
24685
24686
24687}, 'patched-v3.18.1', {"requires": ["event-custom-base"]});
24688
24689YUI.add('event-delegate', function (Y, NAME) {
24690
24691/**
24692 * Adds event delegation support to the library.
24693 *
24694 * @module event
24695 * @submodule event-delegate
24696 */
24697
24698var toArray          = Y.Array,
24699    YLang            = Y.Lang,
24700    isString         = YLang.isString,
24701    isObject         = YLang.isObject,
24702    isArray          = YLang.isArray,
24703    selectorTest     = Y.Selector.test,
24704    detachCategories = Y.Env.evt.handles;
24705
24706/**
24707 * <p>Sets up event delegation on a container element.  The delegated event
24708 * will use a supplied selector or filtering function to test if the event
24709 * references at least one node that should trigger the subscription
24710 * callback.</p>
24711 *
24712 * <p>Selector string filters will trigger the callback if the event originated
24713 * from a node that matches it or is contained in a node that matches it.
24714 * Function filters are called for each Node up the parent axis to the
24715 * subscribing container node, and receive at each level the Node and the event
24716 * object.  The function should return true (or a truthy value) if that Node
24717 * should trigger the subscription callback.  Note, it is possible for filters
24718 * to match multiple Nodes for a single event.  In this case, the delegate
24719 * callback will be executed for each matching Node.</p>
24720 *
24721 * <p>For each matching Node, the callback will be executed with its 'this'
24722 * object set to the Node matched by the filter (unless a specific context was
24723 * provided during subscription), and the provided event's
24724 * <code>currentTarget</code> will also be set to the matching Node.  The
24725 * containing Node from which the subscription was originally made can be
24726 * referenced as <code>e.container</code>.
24727 *
24728 * @method delegate
24729 * @param type {String} the event type to delegate
24730 * @param fn {Function} the callback function to execute.  This function
24731 *              will be provided the event object for the delegated event.
24732 * @param el {String|node} the element that is the delegation container
24733 * @param filter {string|Function} a selector that must match the target of the
24734 *              event or a function to test target and its parents for a match
24735 * @param context optional argument that specifies what 'this' refers to.
24736 * @param args* 0..n additional arguments to pass on to the callback function.
24737 *              These arguments will be added after the event object.
24738 * @return {EventHandle} the detach handle
24739 * @static
24740 * @for Event
24741 */
24742function delegate(type, fn, el, filter) {
24743    var args     = toArray(arguments, 0, true),
24744        query    = isString(el) ? el : null,
24745        typeBits, synth, container, categories, cat, i, len, handles, handle;
24746
24747    // Support Y.delegate({ click: fnA, key: fnB }, el, filter, ...);
24748    // and Y.delegate(['click', 'key'], fn, el, filter, ...);
24749    if (isObject(type)) {
24750        handles = [];
24751
24752        if (isArray(type)) {
24753            for (i = 0, len = type.length; i < len; ++i) {
24754                args[0] = type[i];
24755                handles.push(Y.delegate.apply(Y, args));
24756            }
24757        } else {
24758            // Y.delegate({'click', fn}, el, filter) =>
24759            // Y.delegate('click', fn, el, filter)
24760            args.unshift(null); // one arg becomes two; need to make space
24761
24762            for (i in type) {
24763                if (type.hasOwnProperty(i)) {
24764                    args[0] = i;
24765                    args[1] = type[i];
24766                    handles.push(Y.delegate.apply(Y, args));
24767                }
24768            }
24769        }
24770
24771        return new Y.EventHandle(handles);
24772    }
24773
24774    typeBits = type.split(/\|/);
24775
24776    if (typeBits.length > 1) {
24777        cat  = typeBits.shift();
24778        args[0] = type = typeBits.shift();
24779    }
24780
24781    synth = Y.Node.DOM_EVENTS[type];
24782
24783    if (isObject(synth) && synth.delegate) {
24784        handle = synth.delegate.apply(synth, arguments);
24785    }
24786
24787    if (!handle) {
24788        if (!type || !fn || !el || !filter) {
24789            return;
24790        }
24791
24792        container = (query) ? Y.Selector.query(query, null, true) : el;
24793
24794        if (!container && isString(el)) {
24795            handle = Y.on('available', function () {
24796                Y.mix(handle, Y.delegate.apply(Y, args), true);
24797            }, el);
24798        }
24799
24800        if (!handle && container) {
24801            args.splice(2, 2, container); // remove the filter
24802
24803            handle = Y.Event._attach(args, { facade: false });
24804            handle.sub.filter  = filter;
24805            handle.sub._notify = delegate.notifySub;
24806        }
24807    }
24808
24809    if (handle && cat) {
24810        categories = detachCategories[cat]  || (detachCategories[cat] = {});
24811        categories = categories[type] || (categories[type] = []);
24812        categories.push(handle);
24813    }
24814
24815    return handle;
24816}
24817
24818/**
24819Overrides the <code>_notify</code> method on the normal DOM subscription to
24820inject the filtering logic and only proceed in the case of a match.
24821
24822This method is hosted as a private property of the `delegate` method
24823(e.g. `Y.delegate.notifySub`)
24824
24825@method notifySub
24826@param thisObj {Object} default 'this' object for the callback
24827@param args {Array} arguments passed to the event's <code>fire()</code>
24828@param ce {CustomEvent} the custom event managing the DOM subscriptions for
24829             the subscribed event on the subscribing node.
24830@return {Boolean} false if the event was stopped
24831@private
24832@static
24833@since 3.2.0
24834**/
24835delegate.notifySub = function (thisObj, args, ce) {
24836    // Preserve args for other subscribers
24837    args = args.slice();
24838    if (this.args) {
24839        args.push.apply(args, this.args);
24840    }
24841
24842    // Only notify subs if the event occurred on a targeted element
24843    var currentTarget = delegate._applyFilter(this.filter, args, ce),
24844        //container     = e.currentTarget,
24845        e, i, len, ret;
24846
24847    if (currentTarget) {
24848        // Support multiple matches up the the container subtree
24849        currentTarget = toArray(currentTarget);
24850
24851        // The second arg is the currentTarget, but we'll be reusing this
24852        // facade, replacing the currentTarget for each use, so it doesn't
24853        // matter what element we seed it with.
24854        e = args[0] = new Y.DOMEventFacade(args[0], ce.el, ce);
24855
24856        e.container = Y.one(ce.el);
24857
24858        for (i = 0, len = currentTarget.length; i < len && !e.stopped; ++i) {
24859            e.currentTarget = Y.one(currentTarget[i]);
24860
24861            ret = this.fn.apply(this.context || e.currentTarget, args);
24862
24863            if (ret === false) { // stop further notifications
24864                break;
24865            }
24866        }
24867
24868        return ret;
24869    }
24870};
24871
24872/**
24873Compiles a selector string into a filter function to identify whether
24874Nodes along the parent axis of an event's target should trigger event
24875notification.
24876
24877This function is memoized, so previously compiled filter functions are
24878returned if the same selector string is provided.
24879
24880This function may be useful when defining synthetic events for delegate
24881handling.
24882
24883Hosted as a property of the `delegate` method (e.g. `Y.delegate.compileFilter`).
24884
24885@method compileFilter
24886@param selector {String} the selector string to base the filtration on
24887@return {Function}
24888@since 3.2.0
24889@static
24890**/
24891delegate.compileFilter = Y.cached(function (selector) {
24892    return function (target, e) {
24893        return selectorTest(target._node, selector,
24894            (e.currentTarget === e.target) ? null : e.currentTarget._node);
24895    };
24896});
24897
24898/**
24899Regex to test for disabled elements during filtering. This is only relevant to
24900IE to normalize behavior with other browsers, which swallow events that occur
24901to disabled elements. IE fires the event from the parent element instead of the
24902original target, though it does preserve `event.srcElement` as the disabled
24903element. IE also supports disabled on `<a>`, but the event still bubbles, so it
24904acts more like `e.preventDefault()` plus styling. That issue is not handled here
24905because other browsers fire the event on the `<a>`, so delegate is supported in
24906both cases.
24907
24908@property _disabledRE
24909@type {RegExp}
24910@protected
24911@since 3.8.1
24912**/
24913delegate._disabledRE = /^(?:button|input|select|textarea)$/i;
24914
24915/**
24916Walks up the parent axis of an event's target, and tests each element
24917against a supplied filter function.  If any Nodes, including the container,
24918satisfy the filter, the delegated callback will be triggered for each.
24919
24920Hosted as a protected property of the `delegate` method (e.g.
24921`Y.delegate._applyFilter`).
24922
24923@method _applyFilter
24924@param filter {Function} boolean function to test for inclusion in event
24925                 notification
24926@param args {Array} the arguments that would be passed to subscribers
24927@param ce   {CustomEvent} the DOM event wrapper
24928@return {Node|Node[]|undefined} The Node or Nodes that satisfy the filter
24929@protected
24930**/
24931delegate._applyFilter = function (filter, args, ce) {
24932    var e         = args[0],
24933        container = ce.el, // facadeless events in IE, have no e.currentTarget
24934        target    = e.target || e.srcElement,
24935        match     = [],
24936        isContainer = false;
24937
24938    // Resolve text nodes to their containing element
24939    if (target.nodeType === 3) {
24940        target = target.parentNode;
24941    }
24942
24943    // For IE. IE propagates events from the parent element of disabled
24944    // elements, where other browsers swallow the event entirely. To normalize
24945    // this in IE, filtering for matching elements should abort if the target
24946    // is a disabled form control.
24947    if (target.disabled && delegate._disabledRE.test(target.nodeName)) {
24948        return match;
24949    }
24950
24951    // passing target as the first arg rather than leaving well enough alone
24952    // making 'this' in the filter function refer to the target.  This is to
24953    // support bound filter functions.
24954    args.unshift(target);
24955
24956    if (isString(filter)) {
24957        while (target) {
24958            isContainer = (target === container);
24959            if (selectorTest(target, filter, (isContainer ? null: container))) {
24960                match.push(target);
24961            }
24962
24963            if (isContainer) {
24964                break;
24965            }
24966
24967            target = target.parentNode;
24968        }
24969    } else {
24970        // filter functions are implementer code and should receive wrappers
24971        args[0] = Y.one(target);
24972        args[1] = new Y.DOMEventFacade(e, container, ce);
24973
24974        while (target) {
24975            // filter(target, e, extra args...) - this === target
24976            if (filter.apply(args[0], args)) {
24977                match.push(target);
24978            }
24979
24980            if (target === container) {
24981                break;
24982            }
24983
24984            target = target.parentNode;
24985            args[0] = Y.one(target);
24986        }
24987        args[1] = e; // restore the raw DOM event
24988    }
24989
24990    if (match.length <= 1) {
24991        match = match[0]; // single match or undefined
24992    }
24993
24994    // remove the target
24995    args.shift();
24996
24997    return match;
24998};
24999
25000/**
25001 * Sets up event delegation on a container element.  The delegated event
25002 * will use a supplied filter to test if the callback should be executed.
25003 * This filter can be either a selector string or a function that returns
25004 * a Node to use as the currentTarget for the event.
25005 *
25006 * The event object for the delegated event is supplied to the callback
25007 * function.  It is modified slightly in order to support all properties
25008 * that may be needed for event delegation.  'currentTarget' is set to
25009 * the element that matched the selector string filter or the Node returned
25010 * from the filter function.  'container' is set to the element that the
25011 * listener is delegated from (this normally would be the 'currentTarget').
25012 *
25013 * Filter functions will be called with the arguments that would be passed to
25014 * the callback function, including the event object as the first parameter.
25015 * The function should return false (or a falsey value) if the success criteria
25016 * aren't met, and the Node to use as the event's currentTarget and 'this'
25017 * object if they are.
25018 *
25019 * @method delegate
25020 * @param type {string} the event type to delegate
25021 * @param fn {function} the callback function to execute.  This function
25022 * will be provided the event object for the delegated event.
25023 * @param el {string|node} the element that is the delegation container
25024 * @param filter {string|function} a selector that must match the target of the
25025 * event or a function that returns a Node or false.
25026 * @param context optional argument that specifies what 'this' refers to.
25027 * @param args* 0..n additional arguments to pass on to the callback function.
25028 * These arguments will be added after the event object.
25029 * @return {EventHandle} the detach handle
25030 * @for YUI
25031 */
25032Y.delegate = Y.Event.delegate = delegate;
25033
25034
25035}, 'patched-v3.18.1', {"requires": ["node-base"]});
25036
25037YUI.add('event-focus', function (Y, NAME) {
25038
25039/**
25040 * Adds bubbling and delegation support to DOM events focus and blur.
25041 *
25042 * @module event
25043 * @submodule event-focus
25044 */
25045var Event    = Y.Event,
25046
25047    YLang    = Y.Lang,
25048
25049    isString = YLang.isString,
25050
25051    arrayIndex = Y.Array.indexOf,
25052
25053    useActivate = (function() {
25054
25055        // Changing the structure of this test, so that it doesn't use inline JS in HTML,
25056        // which throws an exception in Win8 packaged apps, due to additional security restrictions:
25057        // http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences
25058
25059        var supported = false,
25060            doc = Y.config.doc,
25061            p;
25062
25063        if (doc) {
25064
25065            p = doc.createElement("p");
25066            p.setAttribute("onbeforeactivate", ";");
25067
25068            // onbeforeactivate is a function in IE8+.
25069            // onbeforeactivate is a string in IE6,7 (unfortunate, otherwise we could have just checked for function below).
25070            // onbeforeactivate is a function in IE10, in a Win8 App environment (no exception running the test).
25071
25072            // onbeforeactivate is undefined in Webkit/Gecko.
25073            // onbeforeactivate is a function in Webkit/Gecko if it's a supported event (e.g. onclick).
25074
25075            supported = (p.onbeforeactivate !== undefined);
25076        }
25077
25078        return supported;
25079    }());
25080
25081function define(type, proxy, directEvent) {
25082    var nodeDataKey = '_' + type + 'Notifiers';
25083
25084    Y.Event.define(type, {
25085
25086        _useActivate : useActivate,
25087
25088        _attach: function (el, notifier, delegate) {
25089            if (Y.DOM.isWindow(el)) {
25090                return Event._attach([type, function (e) {
25091                    notifier.fire(e);
25092                }, el]);
25093            } else {
25094                return Event._attach(
25095                    [proxy, this._proxy, el, this, notifier, delegate],
25096                    { capture: true });
25097            }
25098        },
25099
25100        _proxy: function (e, notifier, delegate) {
25101            var target        = e.target,
25102                currentTarget = e.currentTarget,
25103                notifiers     = target.getData(nodeDataKey),
25104                yuid          = Y.stamp(currentTarget._node),
25105                defer         = (useActivate || target !== currentTarget),
25106                directSub;
25107
25108            notifier.currentTarget = (delegate) ? target : currentTarget;
25109            notifier.container     = (delegate) ? currentTarget : null;
25110
25111            // Maintain a list to handle subscriptions from nested
25112            // containers div#a>div#b>input #a.on(focus..) #b.on(focus..),
25113            // use one focus or blur subscription that fires notifiers from
25114            // #b then #a to emulate bubble sequence.
25115            if (!notifiers) {
25116                notifiers = {};
25117                target.setData(nodeDataKey, notifiers);
25118
25119                // only subscribe to the element's focus if the target is
25120                // not the current target (
25121                if (defer) {
25122                    directSub = Event._attach(
25123                        [directEvent, this._notify, target._node]).sub;
25124                    directSub.once = true;
25125                }
25126            } else {
25127                // In old IE, defer is always true.  In capture-phase browsers,
25128                // The delegate subscriptions will be encountered first, which
25129                // will establish the notifiers data and direct subscription
25130                // on the node.  If there is also a direct subscription to the
25131                // node's focus/blur, it should not call _notify because the
25132                // direct subscription from the delegate sub(s) exists, which
25133                // will call _notify.  So this avoids _notify being called
25134                // twice, unnecessarily.
25135                defer = true;
25136            }
25137
25138            if (!notifiers[yuid]) {
25139                notifiers[yuid] = [];
25140            }
25141
25142            notifiers[yuid].push(notifier);
25143
25144            if (!defer) {
25145                this._notify(e);
25146            }
25147        },
25148
25149        _notify: function (e, container) {
25150            var currentTarget = e.currentTarget,
25151                notifierData  = currentTarget.getData(nodeDataKey),
25152                axisNodes     = currentTarget.ancestors(),
25153                doc           = currentTarget.get('ownerDocument'),
25154                delegates     = [],
25155                                // Used to escape loops when there are no more
25156                                // notifiers to consider
25157                count         = notifierData ?
25158                                    Y.Object.keys(notifierData).length :
25159                                    0,
25160                target, notifiers, notifier, yuid, match, tmp, i, len, sub, ret;
25161
25162            // clear the notifications list (mainly for delegation)
25163            currentTarget.clearData(nodeDataKey);
25164
25165            // Order the delegate subs by their placement in the parent axis
25166            axisNodes.push(currentTarget);
25167            // document.get('ownerDocument') returns null
25168            // which we'll use to prevent having duplicate Nodes in the list
25169            if (doc) {
25170                axisNodes.unshift(doc);
25171            }
25172
25173            // ancestors() returns the Nodes from top to bottom
25174            axisNodes._nodes.reverse();
25175
25176            if (count) {
25177                // Store the count for step 2
25178                tmp = count;
25179                axisNodes.some(function (node) {
25180                    var yuid      = Y.stamp(node),
25181                        notifiers = notifierData[yuid],
25182                        i, len;
25183
25184                    if (notifiers) {
25185                        count--;
25186                        for (i = 0, len = notifiers.length; i < len; ++i) {
25187                            if (notifiers[i].handle.sub.filter) {
25188                                delegates.push(notifiers[i]);
25189                            }
25190                        }
25191                    }
25192
25193                    return !count;
25194                });
25195                count = tmp;
25196            }
25197
25198            // Walk up the parent axis, notifying direct subscriptions and
25199            // testing delegate filters.
25200            while (count && (target = axisNodes.shift())) {
25201                yuid = Y.stamp(target);
25202
25203                notifiers = notifierData[yuid];
25204
25205                if (notifiers) {
25206                    for (i = 0, len = notifiers.length; i < len; ++i) {
25207                        notifier = notifiers[i];
25208                        sub      = notifier.handle.sub;
25209                        match    = true;
25210
25211                        e.currentTarget = target;
25212
25213                        if (sub.filter) {
25214                            match = sub.filter.apply(target,
25215                                [target, e].concat(sub.args || []));
25216
25217                            // No longer necessary to test against this
25218                            // delegate subscription for the nodes along
25219                            // the parent axis.
25220                            delegates.splice(
25221                                arrayIndex(delegates, notifier), 1);
25222                        }
25223
25224                        if (match) {
25225                            // undefined for direct subs
25226                            e.container = notifier.container;
25227                            ret = notifier.fire(e);
25228                        }
25229
25230                        if (ret === false || e.stopped === 2) {
25231                            break;
25232                        }
25233                    }
25234
25235                    delete notifiers[yuid];
25236                    count--;
25237                }
25238
25239                if (e.stopped !== 2) {
25240                    // delegates come after subs targeting this specific node
25241                    // because they would not normally report until they'd
25242                    // bubbled to the container node.
25243                    for (i = 0, len = delegates.length; i < len; ++i) {
25244                        notifier = delegates[i];
25245                        sub = notifier.handle.sub;
25246
25247                        if (sub.filter.apply(target,
25248                            [target, e].concat(sub.args || []))) {
25249
25250                            e.container = notifier.container;
25251                            e.currentTarget = target;
25252                            ret = notifier.fire(e);
25253                        }
25254
25255                        if (ret === false || e.stopped === 2 ||
25256                            // If e.stopPropagation() is called, notify any
25257                            // delegate subs from the same container, but break
25258                            // once the container changes. This emulates
25259                            // delegate() behavior for events like 'click' which
25260                            // won't notify delegates higher up the parent axis.
25261                            (e.stopped && delegates[i+1] &&
25262                             delegates[i+1].container !== notifier.container)) {
25263                            break;
25264                        }
25265                    }
25266                }
25267
25268                if (e.stopped) {
25269                    break;
25270                }
25271            }
25272        },
25273
25274        on: function (node, sub, notifier) {
25275            sub.handle = this._attach(node._node, notifier);
25276        },
25277
25278        detach: function (node, sub) {
25279            sub.handle.detach();
25280        },
25281
25282        delegate: function (node, sub, notifier, filter) {
25283            if (isString(filter)) {
25284                sub.filter = function (target) {
25285                    return Y.Selector.test(target._node, filter,
25286                        node === target ? null : node._node);
25287                };
25288            }
25289
25290            sub.handle = this._attach(node._node, notifier, true);
25291        },
25292
25293        detachDelegate: function (node, sub) {
25294            sub.handle.detach();
25295        }
25296    }, true);
25297}
25298
25299// For IE, we need to defer to focusin rather than focus because
25300// `el.focus(); doSomething();` executes el.onbeforeactivate, el.onactivate,
25301// el.onfocusin, doSomething, then el.onfocus.  All others support capture
25302// phase focus, which executes before doSomething.  To guarantee consistent
25303// behavior for this use case, IE's direct subscriptions are made against
25304// focusin so subscribers will be notified before js following el.focus() is
25305// executed.
25306if (useActivate) {
25307    //     name     capture phase       direct subscription
25308    define("focus", "beforeactivate",   "focusin");
25309    define("blur",  "beforedeactivate", "focusout");
25310} else {
25311    define("focus", "focus", "focus");
25312    define("blur",  "blur",  "blur");
25313}
25314
25315
25316}, 'patched-v3.18.1', {"requires": ["event-synthetic"]});
25317
25318YUI.add('event-hover', function (Y, NAME) {
25319
25320/**
25321 * Adds support for a "hover" event.  The event provides a convenience wrapper
25322 * for subscribing separately to mouseenter and mouseleave.  The signature for
25323 * subscribing to the event is</p>
25324 *
25325 * <pre><code>node.on("hover", overFn, outFn);
25326 * node.delegate("hover", overFn, outFn, ".filterSelector");
25327 * Y.on("hover", overFn, outFn, ".targetSelector");
25328 * Y.delegate("hover", overFn, outFn, "#container", ".filterSelector");
25329 * </code></pre>
25330 *
25331 * <p>Additionally, for compatibility with a more typical subscription
25332 * signature, the following are also supported:</p>
25333 *
25334 * <pre><code>Y.on("hover", overFn, ".targetSelector", outFn);
25335 * Y.delegate("hover", overFn, "#container", outFn, ".filterSelector");
25336 * </code></pre>
25337 *
25338 * @module event
25339 * @submodule event-hover
25340 */
25341var isFunction = Y.Lang.isFunction,
25342    noop = function () {},
25343    conf = {
25344        processArgs: function (args) {
25345            // Y.delegate('hover', over, out, '#container', '.filter')
25346            // comes in as ['hover', over, out, '#container', '.filter'], but
25347            // node.delegate('hover', over, out, '.filter')
25348            // comes in as ['hover', over, containerEl, out, '.filter']
25349            var i = isFunction(args[2]) ? 2 : 3;
25350
25351            return (isFunction(args[i])) ? args.splice(i,1)[0] : noop;
25352        },
25353
25354        on: function (node, sub, notifier, filter) {
25355            var args = (sub.args) ? sub.args.slice() : [];
25356
25357            args.unshift(null);
25358
25359            sub._detach = node[(filter) ? "delegate" : "on"]({
25360                mouseenter: function (e) {
25361                    e.phase = 'over';
25362                    notifier.fire(e);
25363                },
25364                mouseleave: function (e) {
25365                    var thisObj = sub.context || this;
25366
25367                    args[0] = e;
25368
25369                    e.type = 'hover';
25370                    e.phase = 'out';
25371                    sub._extra.apply(thisObj, args);
25372                }
25373            }, filter);
25374        },
25375
25376        detach: function (node, sub, notifier) {
25377            sub._detach.detach();
25378        }
25379    };
25380
25381conf.delegate = conf.on;
25382conf.detachDelegate = conf.detach;
25383
25384Y.Event.define("hover", conf);
25385
25386
25387}, 'patched-v3.18.1', {"requires": ["event-mouseenter"]});
25388
25389YUI.add('event-key', function (Y, NAME) {
25390
25391/**
25392 * Functionality to listen for one or more specific key combinations.
25393 * @module event
25394 * @submodule event-key
25395 */
25396
25397var ALT      = "+alt",
25398    CTRL     = "+ctrl",
25399    META     = "+meta",
25400    SHIFT    = "+shift",
25401
25402    trim     = Y.Lang.trim,
25403
25404    eventDef = {
25405        KEY_MAP: {
25406            enter    : 13,
25407            space    : 32,
25408            esc      : 27,
25409            backspace: 8,
25410            tab      : 9,
25411            pageup   : 33,
25412            pagedown : 34
25413        },
25414
25415        _typeRE: /^(up|down|press):/,
25416        _keysRE: /^(?:up|down|press):|\+(alt|ctrl|meta|shift)/g,
25417
25418        processArgs: function (args) {
25419            var spec = args.splice(3,1)[0],
25420                mods = Y.Array.hash(spec.match(/\+(?:alt|ctrl|meta|shift)\b/g) || []),
25421                config = {
25422                    type: this._typeRE.test(spec) ? RegExp.$1 : null,
25423                    mods: mods,
25424                    keys: null
25425                },
25426                // strip type and modifiers from spec, leaving only keyCodes
25427                bits = spec.replace(this._keysRE, ''),
25428                chr, uc, lc, i;
25429
25430            if (bits) {
25431                bits = bits.split(',');
25432
25433                config.keys = {};
25434
25435                // FIXME: need to support '65,esc' => keypress, keydown
25436                for (i = bits.length - 1; i >= 0; --i) {
25437                    chr = trim(bits[i]);
25438
25439                    // catch sloppy filters, trailing commas, etc 'a,,'
25440                    if (!chr) {
25441                        continue;
25442                    }
25443
25444                    // non-numerics are single characters or key names
25445                    if (+chr == chr) {
25446                        config.keys[chr] = mods;
25447                    } else {
25448                        lc = chr.toLowerCase();
25449
25450                        if (this.KEY_MAP[lc]) {
25451                            config.keys[this.KEY_MAP[lc]] = mods;
25452                            // FIXME: '65,enter' defaults keydown for both
25453                            if (!config.type) {
25454                                config.type = "down"; // safest
25455                            }
25456                        } else {
25457                            // FIXME: Character mapping only works for keypress
25458                            // events. Otherwise, it uses String.fromCharCode()
25459                            // from the keyCode, which is wrong.
25460                            chr = chr.charAt(0);
25461                            uc  = chr.toUpperCase();
25462
25463                            if (mods["+shift"]) {
25464                                chr = uc;
25465                            }
25466
25467                            // FIXME: stupid assumption that
25468                            // the keycode of the lower case == the
25469                            // charCode of the upper case
25470                            // a (key:65,char:97), A (key:65,char:65)
25471                            config.keys[chr.charCodeAt(0)] =
25472                                (chr === uc) ?
25473                                    // upper case chars get +shift free
25474                                    Y.merge(mods, { "+shift": true }) :
25475                                    mods;
25476                        }
25477                    }
25478                }
25479            }
25480
25481            if (!config.type) {
25482                config.type = "press";
25483            }
25484
25485            return config;
25486        },
25487
25488        on: function (node, sub, notifier, filter) {
25489            var spec   = sub._extra,
25490                type   = "key" + spec.type,
25491                keys   = spec.keys,
25492                method = (filter) ? "delegate" : "on";
25493
25494            // Note: without specifying any keyCodes, this becomes a
25495            // horribly inefficient alias for 'keydown' (et al), but I
25496            // can't abort this subscription for a simple
25497            // Y.on('keypress', ...);
25498            // Please use keyCodes or just subscribe directly to keydown,
25499            // keyup, or keypress
25500            sub._detach = node[method](type, function (e) {
25501                var key = keys ? keys[e.which] : spec.mods;
25502
25503                if (key &&
25504                    (!key[ALT]   || (key[ALT]   && e.altKey)) &&
25505                    (!key[CTRL]  || (key[CTRL]  && e.ctrlKey)) &&
25506                    (!key[META]  || (key[META]  && e.metaKey)) &&
25507                    (!key[SHIFT] || (key[SHIFT] && e.shiftKey)))
25508                {
25509                    notifier.fire(e);
25510                }
25511            }, filter);
25512        },
25513
25514        detach: function (node, sub, notifier) {
25515            sub._detach.detach();
25516        }
25517    };
25518
25519eventDef.delegate = eventDef.on;
25520eventDef.detachDelegate = eventDef.detach;
25521
25522/**
25523 * <p>Add a key listener.  The listener will only be notified if the
25524 * keystroke detected meets the supplied specification.  The
25525 * specification is a string that is defined as:</p>
25526 *
25527 * <dl>
25528 *   <dt>spec</dt>
25529 *   <dd><code>[{type}:]{code}[,{code}]*</code></dd>
25530 *   <dt>type</dt>
25531 *   <dd><code>"down", "up", or "press"</code></dd>
25532 *   <dt>code</dt>
25533 *   <dd><code>{keyCode|character|keyName}[+{modifier}]*</code></dd>
25534 *   <dt>modifier</dt>
25535 *   <dd><code>"shift", "ctrl", "alt", or "meta"</code></dd>
25536 *   <dt>keyName</dt>
25537 *   <dd><code>"enter", "space", "backspace", "esc", "tab", "pageup", or "pagedown"</code></dd>
25538 * </dl>
25539 *
25540 * <p>Examples:</p>
25541 * <ul>
25542 *   <li><code>Y.on("key", callback, "press:12,65+shift+ctrl", "#my-input");</code></li>
25543 *   <li><code>Y.delegate("key", preventSubmit, "#forms", "enter", "input[type=text]");</code></li>
25544 *   <li><code>Y.one("doc").on("key", viNav, "j,k,l,;");</code></li>
25545 * </ul>
25546 *
25547 * @event key
25548 * @for YUI
25549 * @param type {string} 'key'
25550 * @param fn {function} the function to execute
25551 * @param id {string|HTMLElement|collection}
25551 the element(s) to bind
25552 * @param spec {string} the keyCode and modifier specification
25553 * @param o optional context object
25554 * @param args 0..n additional arguments to provide to the listener.
25555 * @return {Event.Handle} the detach handle
25556 */
25557Y.Event.define('key', eventDef, true);
25558
25559
25560}, 'patched-v3.18.1', {"requires": ["event-synthetic"]});
25561
25562YUI.add('event-mouseenter', function (Y, NAME) {
25563
25564/**
25565 * <p>Adds subscription and delegation support for mouseenter and mouseleave
25566 * events.  Unlike mouseover and mouseout, these events aren't fired from child
25567 * elements of a subscribed node.</p>
25568 *
25569 * <p>This avoids receiving three mouseover notifications from a setup like</p>
25570 *
25571 * <pre><code>div#container > p > a[href]</code></pre>
25572 *
25573 * <p>where</p>
25574 *
25575 * <pre><code>Y.one('#container').on('mouseover', callback)</code></pre>
25576 *
25577 * <p>When the mouse moves over the link, one mouseover event is fired from
25578 * #container, then when the mouse moves over the p, another mouseover event is
25579 * fired and bubbles to #container, causing a second notification, and finally
25580 * when the mouse moves over the link, a third mouseover event is fired and
25581 * bubbles to #container for a third notification.</p>
25582 *
25583 * <p>By contrast, using mouseenter instead of mouseover, the callback would be
25584 * executed only once when the mouse moves over #container.</p>
25585 *
25586 * @module event
25587 * @submodule event-mouseenter
25588 */
25589
25590var domEventProxies = Y.Env.evt.dom_wrappers,
25591    contains = Y.DOM.contains,
25592    toArray = Y.Array,
25593    noop = function () {},
25594
25595    config = {
25596        proxyType: "mouseover",
25597        relProperty: "fromElement",
25598
25599        _notify: function (e, property, notifier) {
25600            var el = this._node,
25601                related = e.relatedTarget || e[property];
25602
25603            if (el !== related && !contains(el, related)) {
25604                notifier.fire(new Y.DOMEventFacade(e, el,
25605                    domEventProxies['event:' + Y.stamp(el) + e.type]));
25606            }
25607        },
25608
25609        on: function (node, sub, notifier) {
25610            var el = Y.Node.getDOMNode(node),
25611                args = [
25612                    this.proxyType,
25613                    this._notify,
25614                    el,
25615                    null,
25616                    this.relProperty,
25617                    notifier];
25618
25619            sub.handle = Y.Event._attach(args, { facade: false });
25620            // node.on(this.proxyType, notify, null, notifier);
25621        },
25622
25623        detach: function (node, sub) {
25624            sub.handle.detach();
25625        },
25626
25627        delegate: function (node, sub, notifier, filter) {
25628            var el = Y.Node.getDOMNode(node),
25629                args = [
25630                    this.proxyType,
25631                    noop,
25632                    el,
25633                    null,
25634                    notifier
25635                ];
25636
25637            sub.handle = Y.Event._attach(args, { facade: false });
25638            sub.handle.sub.filter = filter;
25639            sub.handle.sub.relProperty = this.relProperty;
25640            sub.handle.sub._notify = this._filterNotify;
25641        },
25642
25643        _filterNotify: function (thisObj, args, ce) {
25644            args = args.slice();
25645            if (this.args) {
25646                args.push.apply(args, this.args);
25647            }
25648
25649            var currentTarget = Y.delegate._applyFilter(this.filter, args, ce),
25650                related = args[0].relatedTarget || args[0][this.relProperty],
25651                e, i, len, ret, ct;
25652
25653            if (currentTarget) {
25654                currentTarget = toArray(currentTarget);
25655
25656                for (i = 0, len = currentTarget.length && (!e || !e.stopped); i < len; ++i) {
25657                    ct = currentTarget[0];
25658                    if (!contains(ct, related)) {
25659                        if (!e) {
25660                            e = new Y.DOMEventFacade(args[0], ct, ce);
25661                            e.container = Y.one(ce.el);
25662                        }
25663                        e.currentTarget = Y.one(ct);
25664
25665                        // TODO: where is notifier? args? this.notifier?
25666                        ret = args[1].fire(e);
25667
25668                        if (ret === false) {
25669                            break;
25670                        }
25671                    }
25672                }
25673            }
25674
25675            return ret;
25676        },
25677
25678        detachDelegate: function (node, sub) {
25679            sub.handle.detach();
25680        }
25681    };
25682
25683Y.Event.define("mouseenter", config, true);
25684Y.Event.define("mouseleave", Y.merge(config, {
25685    proxyType: "mouseout",
25686    relProperty: "toElement"
25687}), true);
25688
25689
25690}, 'patched-v3.18.1', {"requires": ["event-synthetic"]});
25691
25692YUI.add('event-mousewheel', function (Y, NAME) {
25693
25694/**
25695 * Adds mousewheel event support
25696 * @module event
25697 * @submodule event-mousewheel
25698 */
25699var DOM_MOUSE_SCROLL = 'DOMMouseScroll',
25700    fixArgs = function(args) {
25701        var a = Y.Array(args, 0, true), target;
25702        if (Y.UA.gecko) {
25703            a[0] = DOM_MOUSE_SCROLL;
25704            target = Y.config.win;
25705        } else {
25706            target = Y.config.doc;
25707        }
25708
25709        if (a.length < 3) {
25710            a[2] = target;
25711        } else {
25712            a.splice(2, 0, target);
25713        }
25714
25715        return a;
25716    };
25717
25718/**
25719 * Mousewheel event.  This listener is automatically attached to the
25720 * correct target, so one should not be supplied.  Mouse wheel
25721 * direction and velocity is stored in the 'wheelDelta' field.
25722 * @event mousewheel
25723 * @param type {string} 'mousewheel'
25724 * @param fn {function} the callback to execute
25725 * @param context optional context object
25726 * @param args 0..n additional arguments to provide to the listener.
25727 * @return {EventHandle} the detach handle
25728 * @for YUI
25729 */
25730Y.Env.evt.plugins.mousewheel = {
25731    on: function() {
25732        return Y.Event._attach(fixArgs(arguments));
25733    },
25734
25735    detach: function() {
25736        return Y.Event.detach.apply(Y.Event, fixArgs(arguments));
25737    }
25738};
25739
25740
25741}, 'patched-v3.18.1', {"requires": ["node-base"]});
25742

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.