[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/yui/ -> yui.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  /**
   9  The YUI module contains the components required for building the YUI seed file.
  10  This includes the script loading mechanism, a simple queue, and the core
  11  utilities for the library.
  12  
  13  @module yui
  14  @main yui
  15  @submodule yui-base
  16  **/
  17  
  18  /*jshint eqeqeq: false*/
  19  if (typeof YUI != 'undefined') {
  20      YUI._YUI = YUI;
  21  }
  22  
  23  /**
  24  The YUI global namespace object. This is the constructor for all YUI instances.
  25  
  26  This is a self-instantiable factory function, meaning you don't need to precede
  27  it with the `new` operator. You can invoke it directly like this:
  28  
  29      YUI().use('*', function (Y) {
  30          // Y is a new YUI instance.
  31      });
  32  
  33  But it also works like this:
  34  
  35      var Y = YUI();
  36  
  37  The `YUI` constructor accepts an optional config object, like this:
  38  
  39      YUI({
  40          debug: true,
  41          combine: false
  42      }).use('node', function (Y) {
  43          // Y.Node is ready to use.
  44      });
  45  
  46  See the API docs for the <a href="config.html">Config</a> class for the complete
  47  list of supported configuration properties accepted by the YUI constuctor.
  48  
  49  If a global `YUI` object is already defined, the existing YUI object will not be
  50  overwritten, to ensure that defined namespaces are preserved.
  51  
  52  Each YUI instance has full custom event support, but only if the event system is
  53  available.
  54  
  55  @class YUI
  56  @uses EventTarget
  57  @constructor
  58  @global
  59  @param {Object} [config]* Zero or more optional configuration objects. Config
  60      values are stored in the `Y.config` property. See the
  61      <a href="config.html">Config</a> docs for the list of supported properties.
  62  **/
  63  
  64      /*global YUI*/
  65      /*global YUI_config*/
  66      var YUI = function() {
  67          var i = 0,
  68              Y = this,
  69              args = arguments,
  70              l = args.length,
  71              instanceOf = function(o, type) {
  72                  return (o && o.hasOwnProperty && (o instanceof type));
  73              },
  74              gconf = (typeof YUI_config !== 'undefined') && YUI_config;
  75  
  76          if (!(instanceOf(Y, YUI))) {
  77              Y = new YUI();
  78          } else {
  79              // set up the core environment
  80              Y._init();
  81  
  82              /**
  83              Master configuration that might span multiple contexts in a non-
  84              browser environment. It is applied first to all instances in all
  85              contexts.
  86  
  87              @example
  88  
  89                  YUI.GlobalConfig = {
  90                      filter: 'debug'
  91                  };
  92  
  93                  YUI().use('node', function (Y) {
  94                      // debug files used here
  95                  });
  96  
  97                  YUI({
  98                      filter: 'min'
  99                  }).use('node', function (Y) {
 100                      // min files used here
 101                  });
 102  
 103              @property {Object} GlobalConfig
 104              @global
 105              @static
 106              **/
 107              if (YUI.GlobalConfig) {
 108                  Y.applyConfig(YUI.GlobalConfig);
 109              }
 110  
 111              /**
 112              Page-level config applied to all YUI instances created on the
 113              current page. This is applied after `YUI.GlobalConfig` and before
 114              any instance-level configuration.
 115  
 116              @example
 117  
 118                  // Single global var to include before YUI seed file
 119                  YUI_config = {
 120                      filter: 'debug'
 121                  };
 122  
 123                  YUI().use('node', function (Y) {
 124                      // debug files used here
 125                  });
 126  
 127                  YUI({
 128                      filter: 'min'
 129                  }).use('node', function (Y) {
 130                      // min files used here
 131                  });
 132  
 133              @property {Object} YUI_config
 134              @global
 135              **/
 136              if (gconf) {
 137                  Y.applyConfig(gconf);
 138              }
 139  
 140              // bind the specified additional modules for this instance
 141              if (!l) {
 142                  Y._setup();
 143              }
 144          }
 145  
 146          if (l) {
 147              // Each instance can accept one or more configuration objects.
 148              // These are applied after YUI.GlobalConfig and YUI_Config,
 149              // overriding values set in those config files if there is a
 150              // matching property.
 151              for (; i < l; i++) {
 152                  Y.applyConfig(args[i]);
 153              }
 154  
 155              Y._setup();
 156          }
 157  
 158          Y.instanceOf = instanceOf;
 159  
 160          return Y;
 161      };
 162  
 163  (function() {
 164  
 165      var proto, prop,
 166          VERSION = '3.17.2',
 167          PERIOD = '.',
 168          BASE = 'http://yui.yahooapis.com/',
 169          /*
 170              These CSS class names can't be generated by
 171              getClassName since it is not available at the
 172              time they are being used.
 173          */
 174          DOC_LABEL = 'yui3-js-enabled',
 175          CSS_STAMP_EL = 'yui3-css-stamp',
 176          NOOP = function() {},
 177          SLICE = Array.prototype.slice,
 178          APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
 179                            'io.xdrResponse': 1,   // can call. this should
 180                            'SWF.eventHandler': 1 }, // be done at build time
 181          hasWin = (typeof window != 'undefined'),
 182          win = (hasWin) ? window : null,
 183          doc = (hasWin) ? win.document : null,
 184          docEl = doc && doc.documentElement,
 185          docClass = docEl && docEl.className,
 186          instances = {},
 187          time = new Date().getTime(),
 188          add = function(el, type, fn, capture) {
 189              if (el && el.addEventListener) {
 190                  el.addEventListener(type, fn, capture);
 191              } else if (el && el.attachEvent) {
 192                  el.attachEvent('on' + type, fn);
 193              }
 194          },
 195          remove = function(el, type, fn, capture) {
 196              if (el && el.removeEventListener) {
 197                  // this can throw an uncaught exception in FF
 198                  try {
 199                      el.removeEventListener(type, fn, capture);
 200                  } catch (ex) {}
 201              } else if (el && el.detachEvent) {
 202                  el.detachEvent('on' + type, fn);
 203              }
 204          },
 205          handleReady = function() {
 206              YUI.Env.DOMReady = true;
 207              if (hasWin) {
 208                  remove(doc, 'DOMContentLoaded', handleReady);
 209              }        
 210          },
 211          handleLoad = function() {
 212              YUI.Env.windowLoaded = true;
 213              YUI.Env.DOMReady = true;
 214              if (hasWin) {
 215                  remove(window, 'load', handleLoad);
 216              }
 217          },
 218          getLoader = function(Y, o) {
 219              var loader = Y.Env._loader,
 220                  lCore = [ 'loader-base' ],
 221                  G_ENV = YUI.Env,
 222                  mods = G_ENV.mods;
 223  
 224              if (loader) {
 225                  //loader._config(Y.config);
 226                  loader.ignoreRegistered = false;
 227                  loader.onEnd = null;
 228                  loader.data = null;
 229                  loader.required = [];
 230                  loader.loadType = null;
 231              } else {
 232                  loader = new Y.Loader(Y.config);
 233                  Y.Env._loader = loader;
 234              }
 235              if (mods && mods.loader) {
 236                  lCore = [].concat(lCore, YUI.Env.loaderExtras);
 237              }
 238              YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
 239  
 240              return loader;
 241          },
 242  
 243          clobber = function(r, s) {
 244              for (var i in s) {
 245                  if (s.hasOwnProperty(i)) {
 246                      r[i] = s[i];
 247                  }
 248              }
 249          },
 250  
 251          ALREADY_DONE = { success: true };
 252  
 253  //  Stamp the documentElement (HTML) with a class of "yui-loaded" to
 254  //  enable styles that need to key off of JS being enabled.
 255  if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
 256      if (docClass) {
 257          docClass += ' ';
 258      }
 259      docClass += DOC_LABEL;
 260      docEl.className = docClass;
 261  }
 262  
 263  if (VERSION.indexOf('@') > -1) {
 264      VERSION = '3.5.0'; // dev time hack for cdn test
 265  }
 266  
 267  proto = {
 268      /**
 269      Applies a new configuration object to the config of this YUI instance. This
 270      will merge new group/module definitions, and will also update the loader
 271      cache if necessary. Updating `Y.config` directly will not update the cache.
 272  
 273      @method applyConfig
 274      @param {Object} o the configuration object.
 275      @since 3.2.0
 276      **/
 277      applyConfig: function(o) {
 278  
 279          o = o || NOOP;
 280  
 281          var attr,
 282              name,
 283              // detail,
 284              config = this.config,
 285              mods = config.modules,
 286              groups = config.groups,
 287              aliases = config.aliases,
 288              loader = this.Env._loader;
 289  
 290          for (name in o) {
 291              if (o.hasOwnProperty(name)) {
 292                  attr = o[name];
 293                  if (mods && name == 'modules') {
 294                      clobber(mods, attr);
 295                  } else if (aliases && name == 'aliases') {
 296                      clobber(aliases, attr);
 297                  } else if (groups && name == 'groups') {
 298                      clobber(groups, attr);
 299                  } else if (name == 'win') {
 300                      config[name] = (attr && attr.contentWindow) || attr;
 301                      config.doc = config[name] ? config[name].document : null;
 302                  } else if (name == '_yuid') {
 303                      // preserve the guid
 304                  } else {
 305                      config[name] = attr;
 306                  }
 307              }
 308          }
 309  
 310          if (loader) {
 311              loader._config(o);
 312          }
 313  
 314      },
 315  
 316      /**
 317      Old way to apply a config to this instance (calls `applyConfig` under the
 318      hood).
 319  
 320      @private
 321      @method _config
 322      @param {Object} o The config to apply
 323      **/
 324      _config: function(o) {
 325          this.applyConfig(o);
 326      },
 327  
 328      /**
 329      Initializes this YUI instance.
 330  
 331      @private
 332      @method _init
 333      **/
 334      _init: function() {
 335          var filter, el,
 336              Y = this,
 337              G_ENV = YUI.Env,
 338              Env = Y.Env,
 339              prop;
 340  
 341          /**
 342          The version number of this YUI instance.
 343  
 344          This value is typically updated by a script when a YUI release is built,
 345          so it may not reflect the correct version number when YUI is run from
 346          the development source tree.
 347  
 348          @property {String} version
 349          **/
 350          Y.version = VERSION;
 351  
 352          if (!Env) {
 353              Y.Env = {
 354                  core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'],
 355                  loaderExtras: ['loader-rollup', 'loader-yui3'],
 356                  mods: {}, // flat module map
 357                  versions: {}, // version module map
 358                  base: BASE,
 359                  cdn: BASE + VERSION + '/build/',
 360                  // bootstrapped: false,
 361                  _idx: 0,
 362                  _used: {},
 363                  _attached: {},
 364                  _exported: {},
 365                  _missed: [],
 366                  _yidx: 0,
 367                  _uidx: 0,
 368                  _guidp: 'y',
 369                  _loaded: {},
 370                  // serviced: {},
 371                  // Regex in English:
 372                  // I'll start at the \b(yui).
 373                  // 1. Look in the test string for "yui" or
 374                  //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
 375                  //    can't match "foyui" or "i_heart_yui". This can be anywhere in the string.
 376                  // 2. After #1 must come a forward slash followed by the string matched in #1, so
 377                  //    "yui-base/yui-base" or "yui-pants/yui-pants".
 378                  // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
 379                  //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
 380                  // 4. This is followed by ".js", so "yui/yui.js".
 381                  // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
 382                  //    then capture the junk between the LAST "&" and the string in 1-4.  So
 383                  //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
 384                  //    will capture "3.3.0/build/"
 385                  //
 386                  // Regex Exploded:
 387                  // (?:\?             Find a ?
 388                  //   (?:[^&]*&)      followed by 0..n characters followed by an &
 389                  //   *               in fact, find as many sets of characters followed by a & as you can
 390                  //   ([^&]*)         capture the stuff after the last & in \1
 391                  // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
 392                  // \b(               after a word break find either the string
 393                  //    yui(?:-\w+)?   "yui" optionally followed by a -, then more characters
 394                  // )                 and store the yui-* string in \2
 395                  // \/\2              then comes a / followed by the yui-* string in \2
 396                  // (?:-(min|debug))? optionally followed by "-min" or "-debug"
 397                  // .js               and ending in ".js"
 398                  _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
 399                  parseBasePath: function(src, pattern) {
 400                      var match = src.match(pattern),
 401                          path, filter;
 402  
 403                      if (match) {
 404                          path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
 405  
 406                          // this is to set up the path to the loader.  The file
 407                          // filter for loader should match the yui include.
 408                          filter = match[3];
 409  
 410                          // extract correct path for mixed combo urls
 411                          // http://yuilibrary.com/projects/yui3/ticket/2528423
 412                          if (match[1]) {
 413                              path += '?' + match[1];
 414                          }
 415                          path = {
 416                              filter: filter,
 417                              path: path
 418                          };
 419                      }
 420                      return path;
 421                  },
 422                  getBase: G_ENV && G_ENV.getBase ||
 423                          function(pattern) {
 424                              var nodes = (doc && doc.getElementsByTagName('script')) || [],
 425                                  path = Env.cdn, parsed,
 426                                  i, len, src;
 427  
 428                              for (i = 0, len = nodes.length; i < len; ++i) {
 429                                  src = nodes[i].src;
 430                                  if (src) {
 431                                      parsed = Y.Env.parseBasePath(src, pattern);
 432                                      if (parsed) {
 433                                          filter = parsed.filter;
 434                                          path = parsed.path;
 435                                          break;
 436                                      }
 437                                  }
 438                              }
 439  
 440                              // use CDN default
 441                              return path;
 442                          }
 443  
 444              };
 445  
 446              Env = Y.Env;
 447  
 448              Env._loaded[VERSION] = {};
 449  
 450              if (G_ENV && Y !== YUI) {
 451                  Env._yidx = ++G_ENV._yidx;
 452                  Env._guidp = ('yui_' + VERSION + '_' +
 453                               Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
 454              } else if (YUI._YUI) {
 455  
 456                  G_ENV = YUI._YUI.Env;
 457                  Env._yidx += G_ENV._yidx;
 458                  Env._uidx += G_ENV._uidx;
 459  
 460                  for (prop in G_ENV) {
 461                      if (!(prop in Env)) {
 462                          Env[prop] = G_ENV[prop];
 463                      }
 464                  }
 465  
 466                  delete YUI._YUI;
 467              }
 468  
 469              Y.id = Y.stamp(Y);
 470              instances[Y.id] = Y;
 471  
 472          }
 473  
 474          Y.constructor = YUI;
 475  
 476          // configuration defaults
 477          Y.config = Y.config || {
 478              bootstrap: true,
 479              cacheUse: true,
 480              debug: true,
 481              doc: doc,
 482              fetchCSS: true,
 483              throwFail: true,
 484              useBrowserConsole: true,
 485              useNativeES5: true,
 486              win: win,
 487              global: Function('return this')()
 488          };
 489  
 490          //Register the CSS stamp element
 491          if (doc && !doc.getElementById(CSS_STAMP_EL)) {
 492              el = doc.createElement('div');
 493              el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
 494              YUI.Env.cssStampEl = el.firstChild;
 495              if (doc.body) {
 496                  doc.body.appendChild(YUI.Env.cssStampEl);
 497              } else {
 498                  docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
 499              }
 500          } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
 501              YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
 502          }
 503  
 504          Y.config.lang = Y.config.lang || 'en-US';
 505  
 506          Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
 507  
 508          if (!filter || (!('mindebug').indexOf(filter))) {
 509              filter = 'min';
 510          }
 511          filter = (filter) ? '-' + filter : filter;
 512          Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
 513  
 514      },
 515  
 516      /**
 517      Finishes the instance setup. Attaches whatever YUI modules were defined
 518      at the time that this instance was created.
 519  
 520      @method _setup
 521      @private
 522      **/
 523      _setup: function() {
 524          var i, Y = this,
 525              core = [],
 526              mods = YUI.Env.mods,
 527              extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
 528  
 529          for (i = 0; i < extras.length; i++) {
 530              if (mods[extras[i]]) {
 531                  core.push(extras[i]);
 532              }
 533          }
 534  
 535          Y._attach(['yui-base']);
 536          Y._attach(core);
 537  
 538          if (Y.Loader) {
 539              getLoader(Y);
 540          }
 541  
 542      },
 543  
 544      /**
 545      Executes the named method on the specified YUI instance if that method is
 546      whitelisted.
 547  
 548      @method applyTo
 549      @param {String} id YUI instance id.
 550      @param {String} method Name of the method to execute. For example:
 551          'Object.keys'.
 552      @param {Array} args Arguments to apply to the method.
 553      @return {Mixed} Return value from the applied method, or `null` if the
 554          specified instance was not found or the method was not whitelisted.
 555      **/
 556      applyTo: function(id, method, args) {
 557          if (!(method in APPLY_TO_AUTH)) {
 558              this.log(method + ': applyTo not allowed', 'warn', 'yui');
 559              return null;
 560          }
 561  
 562          var instance = instances[id], nest, m, i;
 563          if (instance) {
 564              nest = method.split('.');
 565              m = instance;
 566              for (i = 0; i < nest.length; i = i + 1) {
 567                  m = m[nest[i]];
 568                  if (!m) {
 569                      this.log('applyTo not found: ' + method, 'warn', 'yui');
 570                  }
 571              }
 572              return m && m.apply(instance, args);
 573          }
 574  
 575          return null;
 576      },
 577  
 578  /**
 579  Registers a YUI module and makes it available for use in a `YUI().use()` call or
 580  as a dependency for other modules.
 581  
 582  The easiest way to create a first-class YUI module is to use
 583  <a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
 584  tool.
 585  
 586  Shifter will automatically wrap your module code in a `YUI.add()` call along
 587  with any configuration info required for the module.
 588  
 589  @example
 590  
 591      YUI.add('davglass', function (Y) {
 592          Y.davglass = function () {
 593          };
 594      }, '3.4.0', {
 595          requires: ['harley-davidson', 'mt-dew']
 596      });
 597  
 598  @method add
 599  @param {String} name Module name.
 600  @param {Function} fn Function containing module code. This function will be
 601      executed whenever the module is attached to a specific YUI instance.
 602  
 603      @param {YUI} fn.Y The YUI instance to which this module is attached.
 604      @param {String} fn.name Name of the module
 605  
 606  @param {String} version Module version number. This is currently used only for
 607      informational purposes, and is not used internally by YUI.
 608  
 609  @param {Object} [details] Module config.
 610      @param {Array} [details.requires] Array of other module names that must be
 611          attached before this module can be attached.
 612      @param {Array} [details.optional] Array of optional module names that should
 613          be attached before this module is attached if they've already been
 614          loaded. If the `loadOptional` YUI option is `true`, optional modules
 615          that have not yet been loaded will be loaded just as if they were hard
 616          requirements.
 617      @param {Array} [details.use] Array of module names that are included within
 618          or otherwise provided by this module, and which should be attached
 619          automatically when this module is attached. This makes it possible to
 620          create "virtual rollup" modules that simply attach a collection of other
 621          modules or submodules.
 622  
 623  @return {YUI} This YUI instance.
 624  **/
 625      add: function(name, fn, version, details) {
 626          details = details || {};
 627          var env = YUI.Env,
 628              mod = {
 629                  name: name,
 630                  fn: fn,
 631                  version: version,
 632                  details: details
 633              },
 634              //Instance hash so we don't apply it to the same instance twice
 635              applied = {},
 636              loader, inst, modInfo,
 637              i, versions = env.versions;
 638  
 639          env.mods[name] = mod;
 640          versions[version] = versions[version] || {};
 641          versions[version][name] = mod;
 642  
 643          for (i in instances) {
 644              if (instances.hasOwnProperty(i)) {
 645                  inst = instances[i];
 646                  if (!applied[inst.id]) {
 647                      applied[inst.id] = true;
 648                      loader = inst.Env._loader;
 649                      if (loader) {
 650                          modInfo = loader.getModuleInfo(name);
 651                          if (!modInfo || modInfo.temp) {
 652                              loader.addModule(details, name);
 653                          }
 654                      }
 655                  }
 656              }
 657          }
 658  
 659          return this;
 660      },
 661  
 662      /**
 663      Executes the callback function associated with each required module,
 664      attaching the module to this YUI instance.
 665  
 666      @method _attach
 667      @param {Array} r The array of modules to attach
 668      @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
 669          is not attached.
 670      @private
 671      **/
 672      _attach: function(r, moot) {
 673          var i, name, mod, details, req, use, after,
 674              mods = YUI.Env.mods,
 675              aliases = YUI.Env.aliases,
 676              Y = this, j,
 677              cache = YUI.Env._renderedMods,
 678              loader = Y.Env._loader,
 679              done = Y.Env._attached,
 680              exported = Y.Env._exported,
 681              len = r.length, loader, def, go,
 682              c = [],
 683              modArgs, esCompat, reqlen, modInfo,
 684              condition,
 685              __exports__, __imports__;
 686  
 687          //Check for conditional modules (in a second+ instance) and add their requirements
 688          //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
 689          for (i = 0; i < len; i++) {
 690              name = r[i];
 691              mod = mods[name];
 692              c.push(name);
 693              if (loader && loader.conditions[name]) {
 694                  for (j in loader.conditions[name]) {
 695                      if (loader.conditions[name].hasOwnProperty(j)) {
 696                          def = loader.conditions[name][j];
 697                          go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
 698                          if (go) {
 699                              c.push(def.name);
 700                          }
 701                      }
 702                  }
 703              }
 704          }
 705          r = c;
 706          len = r.length;
 707  
 708          for (i = 0; i < len; i++) {
 709              if (!done[r[i]]) {
 710                  name = r[i];
 711                  mod = mods[name];
 712  
 713                  if (aliases && aliases[name] && !mod) {
 714                      Y._attach(aliases[name]);
 715                      continue;
 716                  }
 717                  if (!mod) {
 718                      modInfo = loader && loader.getModuleInfo(name);
 719                      if (modInfo) {
 720                          mod = modInfo;
 721                          moot = true;
 722                      }
 723  
 724  
 725                      //if (!loader || !loader.moduleInfo[name]) {
 726                      //if ((!loader || !loader.moduleInfo[name]) && !moot) {
 727                      if (!moot && name) {
 728                          if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
 729                              Y.Env._missed.push(name);
 730                              Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
 731                              Y.message('NOT loaded: ' + name, 'warn', 'yui');
 732                          }
 733                      }
 734                  } else {
 735                      done[name] = true;
 736                      //Don't like this, but in case a mod was asked for once, then we fetch it
 737                      //We need to remove it from the missed list ^davglass
 738                      for (j = 0; j < Y.Env._missed.length; j++) {
 739                          if (Y.Env._missed[j] === name) {
 740                              Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
 741                              Y.Env._missed.splice(j, 1);
 742                          }
 743                      }
 744  
 745                      // Optional dependencies normally work by modifying the
 746                      // dependency list of a module. If the dependency's test
 747                      // passes it is added to the list. If not, it's not loaded.
 748                      // This following check ensures that optional dependencies
 749                      // are not attached when they were already loaded into the
 750                      // page (when bundling for example)
 751                      if (loader && !loader._canBeAttached(name)) {
 752                          return true;
 753                      }
 754  
 755                      /*
 756                          If it's a temp module, we need to redo it's requirements if it's already loaded
 757                          since it may have been loaded by another instance and it's dependencies might
 758                          have been redefined inside the fetched file.
 759                      */
 760                      if (loader && cache && cache[name] && cache[name].temp) {
 761                          loader.getRequires(cache[name]);
 762                          req = [];
 763                          modInfo = loader.getModuleInfo(name);
 764                          for (j in modInfo.expanded_map) {
 765                              if (modInfo.expanded_map.hasOwnProperty(j)) {
 766                                  req.push(j);
 767                              }
 768                          }
 769                          Y._attach(req);
 770                      }
 771  
 772                      details = mod.details;
 773                      req = details.requires;
 774                      esCompat = details.es;
 775                      use = details.use;
 776                      after = details.after;
 777                      //Force Intl load if there is a language (Loader logic) @todo fix this shit
 778                      if (details.lang) {
 779                          req = req || [];
 780                          req.unshift('intl');
 781                      }
 782  
 783                      if (req) {
 784                          reqlen = req.length;
 785                          for (j = 0; j < reqlen; j++) {
 786                              if (!done[req[j]]) {
 787                                  if (!Y._attach(req)) {
 788                                      return false;
 789                                  }
 790                                  break;
 791                              }
 792                          }
 793                      }
 794  
 795                      if (after) {
 796                          for (j = 0; j < after.length; j++) {
 797                              if (!done[after[j]]) {
 798                                  if (!Y._attach(after, true)) {
 799                                      return false;
 800                                  }
 801                                  break;
 802                              }
 803                          }
 804                      }
 805  
 806                      if (mod.fn) {
 807                          modArgs = [Y, name];
 808                          if (esCompat) {
 809                              __imports__ = {};
 810                              __exports__ = {};
 811                              // passing `exports` and `imports` onto the module function
 812                              modArgs.push(__imports__, __exports__);
 813                              if (req) {
 814                                  reqlen = req.length;
 815                                  for (j = 0; j < reqlen; j++) {
 816                                      __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y;
 817                                  }
 818                              }
 819                          }
 820                          if (Y.config.throwFail) {
 821                              __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
 822                          } else {
 823                              try {
 824                                  __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
 825                              } catch (e) {
 826                                  Y.error('Attach error: ' + name, e, name);
 827                                  return false;
 828                              }
 829                          }
 830                          if (esCompat) {
 831                              // store the `exports` in case others `es` modules requires it
 832                              exported[name] = __exports__;
 833  
 834                              // If an ES module is conditionally loaded and set
 835                              // to be used "instead" another module, replace the
 836                              // trigger module's content with the conditionally
 837                              // loaded one so the values returned by require()
 838                              // still makes sense
 839                              condition = mod.details.condition;
 840                              if (condition && condition.when === 'instead') {
 841                                  exported[condition.trigger] = __exports__;
 842                              }
 843                          }
 844                      }
 845  
 846                      if (use) {
 847                          for (j = 0; j < use.length; j++) {
 848                              if (!done[use[j]]) {
 849                                  if (!Y._attach(use)) {
 850                                      return false;
 851                                  }
 852                                  break;
 853                              }
 854                          }
 855                      }
 856  
 857  
 858  
 859                  }
 860              }
 861          }
 862  
 863          return true;
 864      },
 865  
 866      /**
 867      Delays the `use` callback until another event has taken place such as
 868      `window.onload`, `domready`, `contentready`, or `available`.
 869  
 870      @private
 871      @method _delayCallback
 872      @param {Function} cb The original `use` callback.
 873      @param {String|Object} until Either an event name ('load', 'domready', etc.)
 874          or an object containing event/args keys for contentready/available.
 875      @return {Function}
 876      **/
 877      _delayCallback: function(cb, until) {
 878  
 879          var Y = this,
 880              mod = ['event-base'];
 881  
 882          until = (Y.Lang.isObject(until) ? until : { event: until });
 883  
 884          if (until.event === 'load') {
 885              mod.push('event-synthetic');
 886          }
 887  
 888          return function() {
 889              var args = arguments;
 890              Y._use(mod, function() {
 891                  Y.on(until.event, function() {
 892                      args[1].delayUntil = until.event;
 893                      cb.apply(Y, args);
 894                  }, until.args);
 895              });
 896          };
 897      },
 898  
 899      /**
 900      Attaches one or more modules to this YUI instance. When this is executed,
 901      the requirements of the desired modules are analyzed, and one of several
 902      things can happen:
 903  
 904  
 905        * All required modules have already been loaded, and just need to be
 906          attached to this YUI instance. In this case, the `use()` callback will
 907          be executed synchronously after the modules are attached.
 908  
 909        * One or more modules have not yet been loaded, or the Get utility is not
 910          available, or the `bootstrap` config option is `false`. In this case,
 911          a warning is issued indicating that modules are missing, but all
 912          available modules will still be attached and the `use()` callback will
 913          be executed synchronously.
 914  
 915        * One or more modules are missing and the Loader is not available but the
 916          Get utility is, and `bootstrap` is not `false`. In this case, the Get
 917          utility will be used to load the Loader, and we will then proceed to
 918          the following state:
 919  
 920        * One or more modules are missing and the Loader is available. In this
 921          case, the Loader will be used to resolve the dependency tree for the
 922          missing modules and load them and their dependencies. When the Loader is
 923          finished loading modules, the `use()` callback will be executed
 924          asynchronously.
 925  
 926      @example
 927  
 928          // Loads and attaches dd and its dependencies.
 929          YUI().use('dd', function (Y) {
 930              // ...
 931          });
 932  
 933          // Loads and attaches dd and node as well as all of their dependencies.
 934          YUI().use(['dd', 'node'], function (Y) {
 935              // ...
 936          });
 937  
 938          // Attaches all modules that have already been loaded.
 939          YUI().use('*', function (Y) {
 940              // ...
 941          });
 942  
 943          // Attaches a gallery module.
 944          YUI().use('gallery-yql', function (Y) {
 945              // ...
 946          });
 947  
 948          // Attaches a YUI 2in3 module.
 949          YUI().use('yui2-datatable', function (Y) {
 950              // ...
 951          });
 952  
 953      @method use
 954      @param {String|Array} modules* One or more module names to attach.
 955      @param {Function} [callback] Callback function to be executed once all
 956          specified modules and their dependencies have been attached.
 957      @param {YUI} callback.Y The YUI instance created for this sandbox.
 958      @param {Object} callback.status Object containing `success`, `msg` and
 959          `data` properties.
 960      @chainable
 961      **/
 962      use: function() {
 963          var args = SLICE.call(arguments, 0),
 964              callback = args[args.length - 1],
 965              Y = this,
 966              i = 0,
 967              name,
 968              Env = Y.Env,
 969              provisioned = true;
 970  
 971          // The last argument supplied to use can be a load complete callback
 972          if (Y.Lang.isFunction(callback)) {
 973              args.pop();
 974              if (Y.config.delayUntil) {
 975                  callback = Y._delayCallback(callback, Y.config.delayUntil);
 976              }
 977          } else {
 978              callback = null;
 979          }
 980          if (Y.Lang.isArray(args[0])) {
 981              args = args[0];
 982          }
 983  
 984          if (Y.config.cacheUse) {
 985              while ((name = args[i++])) {
 986                  if (!Env._attached[name]) {
 987                      provisioned = false;
 988                      break;
 989                  }
 990              }
 991  
 992              if (provisioned) {
 993                  if (args.length) {
 994                  }
 995                  Y._notify(callback, ALREADY_DONE, args);
 996                  return Y;
 997              }
 998          }
 999  
1000          if (Y._loading) {
1001              Y._useQueue = Y._useQueue || new Y.Queue();
1002              Y._useQueue.add([args, callback]);
1003          } else {
1004              Y._use(args, function(Y, response) {
1005                  Y._notify(callback, response, args);
1006              });
1007          }
1008  
1009          return Y;
1010      },
1011  
1012      /**
1013      Sugar for loading both legacy and ES6-based YUI modules.
1014  
1015      @method require
1016      @param {String} [modules*] List of module names to import or a single
1017          module name.
1018      @param {Function} callback Callback that gets called once all the modules
1019          were loaded. Each parameter of the callback is the export value of the
1020          corresponding module in the list. If the module is a legacy YUI module,
1021          the YUI instance is used instead of the module exports.
1022      @example
1023      ```
1024      YUI().require(['es6-set'], function (Y, imports) {
1025          var Set = imports.Set,
1026              set = new Set();
1027      });
1028      ```
1029      **/
1030      require: function () {
1031          var args = SLICE.call(arguments),
1032              callback;
1033  
1034          if (typeof args[args.length - 1] === 'function') {
1035              callback = args.pop();
1036  
1037              // only add the callback if one was provided
1038              // YUI().require('foo'); is valid
1039              args.push(function (Y) {
1040                  var i, length = args.length,
1041                      exported = Y.Env._exported,
1042                      __imports__ = {};
1043  
1044                  // Get only the imports requested as arguments
1045                  for (i = 0; i < length; i++) {
1046                      if (exported.hasOwnProperty(args[i])) {
1047                          __imports__[args[i]] = exported[args[i]];
1048                      }
1049                  }
1050  
1051                  // Using `undefined` because:
1052                  // - Using `Y.config.global` would force the value of `this` to be
1053                  //   the global object even in strict mode
1054                  // - Using `Y` goes against the goal of moving away from a shared
1055                  //   object and start thinking in terms of imported and exported
1056                  //   objects
1057                  callback.call(undefined, Y, __imports__);
1058              });
1059          }
1060          // Do not return the Y object. This makes it hard to follow this
1061          // traditional pattern:
1062          //   var Y = YUI().use(...);
1063          // This is a good idea in the light of ES6 modules, to avoid working
1064          // in the global scope.
1065          // This also leaves the door open for returning a promise, once the
1066          // YUI loader is based on the ES6 loader which uses
1067          // loader.import(...).then(...)
1068          this.use.apply(this, args);
1069      },
1070  
1071      /**
1072      Handles Loader notifications about attachment/load errors.
1073  
1074      @method _notify
1075      @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
1076      @param {Object} response Response returned from Loader.
1077      @param {Array} args Arguments passed from Loader.
1078      @private
1079      **/
1080      _notify: function(callback, response, args) {
1081          if (!response.success && this.config.loadErrorFn) {
1082              this.config.loadErrorFn.call(this, this, callback, response, args);
1083          } else if (callback) {
1084              if (this.Env._missed && this.Env._missed.length) {
1085                  response.msg = 'Missing modules: ' + this.Env._missed.join();
1086                  response.success = false;
1087              }
1088              if (this.config.throwFail) {
1089                  callback(this, response);
1090              } else {
1091                  try {
1092                      callback(this, response);
1093                  } catch (e) {
1094                      this.error('use callback error', e, args);
1095                  }
1096              }
1097          }
1098      },
1099  
1100      /**
1101      Called from the `use` method queue to ensure that only one set of loading
1102      logic is performed at a time.
1103  
1104      @method _use
1105      @param {String} args* One or more modules to attach.
1106      @param {Function} [callback] Function to call once all required modules have
1107          been attached.
1108      @private
1109      **/
1110      _use: function(args, callback) {
1111  
1112          if (!this.Array) {
1113              this._attach(['yui-base']);
1114          }
1115  
1116          var len, loader, handleBoot,
1117              Y = this,
1118              G_ENV = YUI.Env,
1119              mods = G_ENV.mods,
1120              Env = Y.Env,
1121              used = Env._used,
1122              aliases = G_ENV.aliases,
1123              queue = G_ENV._loaderQueue,
1124              firstArg = args[0],
1125              YArray = Y.Array,
1126              config = Y.config,
1127              boot = config.bootstrap,
1128              missing = [],
1129              i,
1130              r = [],
1131              ret = true,
1132              fetchCSS = config.fetchCSS,
1133              process = function(names, skip) {
1134  
1135                  var i = 0, a = [], name, len, m, req, use;
1136  
1137                  if (!names.length) {
1138                      return;
1139                  }
1140  
1141                  if (aliases) {
1142                      len = names.length;
1143                      for (i = 0; i < len; i++) {
1144                          if (aliases[names[i]] && !mods[names[i]]) {
1145                              a = [].concat(a, aliases[names[i]]);
1146                          } else {
1147                              a.push(names[i]);
1148                          }
1149                      }
1150                      names = a;
1151                  }
1152  
1153                  len = names.length;
1154  
1155                  for (i = 0; i < len; i++) {
1156                      name = names[i];
1157                      if (!skip) {
1158                          r.push(name);
1159                      }
1160  
1161                      // only attach a module once
1162                      if (used[name]) {
1163                          continue;
1164                      }
1165  
1166                      m = mods[name];
1167                      req = null;
1168                      use = null;
1169  
1170                      if (m) {
1171                          used[name] = true;
1172                          req = m.details.requires;
1173                          use = m.details.use;
1174                      } else {
1175                          // CSS files don't register themselves, see if it has
1176                          // been loaded
1177                          if (!G_ENV._loaded[VERSION][name]) {
1178                              missing.push(name);
1179                          } else {
1180                              used[name] = true; // probably css
1181                          }
1182                      }
1183  
1184                      // make sure requirements are attached
1185                      if (req && req.length) {
1186                          process(req);
1187                      }
1188  
1189                      // make sure we grab the submodule dependencies too
1190                      if (use && use.length) {
1191                          process(use, 1);
1192                      }
1193                  }
1194  
1195              },
1196  
1197              handleLoader = function(fromLoader) {
1198                  var response = fromLoader || {
1199                          success: true,
1200                          msg: 'not dynamic'
1201                      },
1202                      redo, origMissing,
1203                      ret = true,
1204                      data = response.data;
1205  
1206                  Y._loading = false;
1207  
1208                  if (data) {
1209                      origMissing = missing;
1210                      missing = [];
1211                      r = [];
1212                      process(data);
1213                      redo = missing.length;
1214                      if (redo) {
1215                          if ([].concat(missing).sort().join() ==
1216                                  origMissing.sort().join()) {
1217                              redo = false;
1218                          }
1219                      }
1220                  }
1221  
1222                  if (redo && data) {
1223                      Y._loading = true;
1224                      Y._use(missing, function() {
1225                          if (Y._attach(data)) {
1226                              Y._notify(callback, response, data);
1227                          }
1228                      });
1229                  } else {
1230                      if (data) {
1231                          ret = Y._attach(data);
1232                      }
1233                      if (ret) {
1234                          Y._notify(callback, response, args);
1235                      }
1236                  }
1237  
1238                  if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1239                      Y._use.apply(Y, Y._useQueue.next());
1240                  }
1241  
1242              };
1243  
1244  
1245          // YUI().use('*'); // bind everything available
1246          if (firstArg === '*') {
1247              args = [];
1248              for (i in mods) {
1249                  if (mods.hasOwnProperty(i)) {
1250                      args.push(i);
1251                  }
1252              }
1253              ret = Y._attach(args);
1254              if (ret) {
1255                  handleLoader();
1256              }
1257              return Y;
1258          }
1259  
1260          if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1261              Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1262          }
1263  
1264  
1265          // use loader to expand dependencies and sort the
1266          // requirements if it is available.
1267          if (boot && Y.Loader && args.length) {
1268              loader = getLoader(Y);
1269              loader.require(args);
1270              loader.ignoreRegistered = true;
1271              loader._boot = true;
1272              loader.calculate(null, (fetchCSS) ? null : 'js');
1273              args = loader.sorted;
1274              loader._boot = false;
1275          }
1276  
1277          process(args);
1278  
1279          len = missing.length;
1280  
1281  
1282          if (len) {
1283              missing = YArray.dedupe(missing);
1284              len = missing.length;
1285          }
1286  
1287  
1288          // dynamic load
1289          if (boot && len && Y.Loader) {
1290              Y._loading = true;
1291              loader = getLoader(Y);
1292              loader.onEnd = handleLoader;
1293              loader.context = Y;
1294              loader.data = args;
1295              loader.ignoreRegistered = false;
1296              loader.require(missing);
1297              loader.insert(null, (fetchCSS) ? null : 'js');
1298  
1299          } else if (boot && len && Y.Get && !Env.bootstrapped) {
1300  
1301              Y._loading = true;
1302  
1303              handleBoot = function() {
1304                  Y._loading = false;
1305                  queue.running = false;
1306                  Env.bootstrapped = true;
1307                  G_ENV._bootstrapping = false;
1308                  if (Y._attach(['loader'])) {
1309                      Y._use(args, callback);
1310                  }
1311              };
1312  
1313              if (G_ENV._bootstrapping) {
1314                  queue.add(handleBoot);
1315              } else {
1316                  G_ENV._bootstrapping = true;
1317                  Y.Get.script(config.base + config.loaderPath, {
1318                      onEnd: handleBoot
1319                  });
1320              }
1321  
1322          } else {
1323              ret = Y._attach(args);
1324              if (ret) {
1325                  handleLoader();
1326              }
1327          }
1328  
1329          return Y;
1330      },
1331  
1332  
1333      /**
1334      Utility method for safely creating namespaces if they don't already exist.
1335      May be called statically on the YUI global object or as a method on a YUI
1336      instance.
1337  
1338      When called statically, a namespace will be created on the YUI global
1339      object:
1340  
1341          // Create `YUI.your.namespace.here` as nested objects, preserving any
1342          // objects that already exist instead of overwriting them.
1343          YUI.namespace('your.namespace.here');
1344  
1345      When called as a method on a YUI instance, a namespace will be created on
1346      that instance:
1347  
1348          // Creates `Y.property.package`.
1349          Y.namespace('property.package');
1350  
1351      Dots in the input string cause `namespace` to create nested objects for each
1352      token. If any part of the requested namespace already exists, the current
1353      object will be left in place and will not be overwritten. This allows
1354      multiple calls to `namespace` to preserve existing namespaced properties.
1355  
1356      If the first token in the namespace string is "YAHOO", that token is
1357      discarded. This is legacy behavior for backwards compatibility with YUI 2.
1358  
1359      Be careful with namespace tokens. Reserved words may work in some browsers
1360      and not others. For instance, the following will fail in some browsers
1361      because the supported version of JavaScript reserves the word "long":
1362  
1363          Y.namespace('really.long.nested.namespace');
1364  
1365      Note: If you pass multiple arguments to create multiple namespaces, only the
1366      last one created is returned from this function.
1367  
1368      @method namespace
1369      @param {String} namespace* One or more namespaces to create.
1370      @return {Object} Reference to the last namespace object created.
1371      **/
1372      namespace: function() {
1373          var a = arguments, o, i = 0, j, d, arg;
1374  
1375          for (; i < a.length; i++) {
1376              o = this; //Reset base object per argument or it will get reused from the last
1377              arg = a[i];
1378              if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1379                  d = arg.split(PERIOD);
1380                  for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1381                      o[d[j]] = o[d[j]] || {};
1382                      o = o[d[j]];
1383                  }
1384              } else {
1385                  o[arg] = o[arg] || {};
1386                  o = o[arg]; //Reset base object to the new object so it's returned
1387              }
1388          }
1389          return o;
1390      },
1391  
1392      // this is replaced if the log module is included
1393      log: NOOP,
1394      message: NOOP,
1395      // this is replaced if the dump module is included
1396      dump: function (o) { return ''+o; },
1397  
1398      /**
1399      Reports an error.
1400  
1401      The reporting mechanism is controlled by the `throwFail` configuration
1402      attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1403      truthy, a JS exception is thrown.
1404  
1405      If an `errorFn` is specified in the config it must return `true` to indicate
1406      that the exception was handled and keep it from being thrown.
1407  
1408      @method error
1409      @param {String} msg Error message.
1410      @param {Error|String} [e] JavaScript error object or an error string.
1411      @param {String} [src] Source of the error (such as the name of the module in
1412          which the error occurred).
1413      @chainable
1414      **/
1415      error: function(msg, e, src) {
1416          //TODO Add check for window.onerror here
1417  
1418          var Y = this, ret;
1419  
1420          if (Y.config.errorFn) {
1421              ret = Y.config.errorFn.apply(Y, arguments);
1422          }
1423  
1424          if (!ret) {
1425              throw (e || new Error(msg));
1426          } else {
1427              Y.message(msg, 'error', ''+src); // don't scrub this one
1428          }
1429  
1430          return Y;
1431      },
1432  
1433      /**
1434      Generates an id string that is unique among all YUI instances in this
1435      execution context.
1436  
1437      @method guid
1438      @param {String} [pre] Prefix.
1439      @return {String} Unique id.
1440      **/
1441      guid: function(pre) {
1442          var id = this.Env._guidp + '_' + (++this.Env._uidx);
1443          return (pre) ? (pre + id) : id;
1444      },
1445  
1446      /**
1447      Returns a unique id associated with the given object and (if *readOnly* is
1448      falsy) stamps the object with that id so it can be identified in the future.
1449  
1450      Stamping an object involves adding a `_yuid` property to it that contains
1451      the object's id. One exception to this is that in Internet Explorer, DOM
1452      nodes have a `uniqueID` property that contains a browser-generated unique
1453      id, which will be used instead of a YUI-generated id when available.
1454  
1455      @method stamp
1456      @param {Object} o Object to stamp.
1457      @param {Boolean} readOnly If truthy and the given object has not already
1458          been stamped, the object will not be modified and `null` will be
1459          returned.
1460      @return {String} Object's unique id, or `null` if *readOnly* was truthy and
1461          the given object was not already stamped.
1462      **/
1463      stamp: function(o, readOnly) {
1464          var uid;
1465          if (!o) {
1466              return o;
1467          }
1468  
1469          // IE generates its own unique ID for dom nodes
1470          // The uniqueID property of a document node returns a new ID
1471          if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1472              uid = o.uniqueID;
1473          } else {
1474              uid = (typeof o === 'string') ? o : o._yuid;
1475          }
1476  
1477          if (!uid) {
1478              uid = this.guid();
1479              if (!readOnly) {
1480                  try {
1481                      o._yuid = uid;
1482                  } catch (e) {
1483                      uid = null;
1484                  }
1485              }
1486          }
1487          return uid;
1488      },
1489  
1490      /**
1491      Destroys this YUI instance.
1492  
1493      @method destroy
1494      @since 3.3.0
1495      **/
1496      destroy: function() {
1497          var Y = this;
1498          if (Y.Event) {
1499              Y.Event._unload();
1500          }
1501          delete instances[Y.id];
1502          delete Y.Env;
1503          delete Y.config;
1504      }
1505  
1506      /**
1507      Safe `instanceof` wrapper that works around a memory leak in IE when the
1508      object being tested is `window` or `document`.
1509  
1510      Unless you are testing objects that may be `window` or `document`, you
1511      should use the native `instanceof` operator instead of this method.
1512  
1513      @method instanceOf
1514      @param {Object} o Object to check.
1515      @param {Object} type Class to check against.
1516      @since 3.3.0
1517      **/
1518  };
1519  
1520      YUI.prototype = proto;
1521  
1522      // inheritance utilities are not available yet
1523      for (prop in proto) {
1524          if (proto.hasOwnProperty(prop)) {
1525              YUI[prop] = proto[prop];
1526          }
1527      }
1528  
1529      /**
1530      Applies a configuration to all YUI instances in this execution context.
1531  
1532      The main use case for this method is in "mashups" where several third-party
1533      scripts need to write to a global YUI config, but cannot share a single
1534      centrally-managed config object. This way they can all call
1535      `YUI.applyConfig({})` instead of overwriting the single global config.
1536  
1537      @example
1538  
1539          YUI.applyConfig({
1540              modules: {
1541                  davglass: {
1542                      fullpath: './davglass.js'
1543                  }
1544              }
1545          });
1546  
1547          YUI.applyConfig({
1548              modules: {
1549                  foo: {
1550                      fullpath: './foo.js'
1551                  }
1552              }
1553          });
1554  
1555          YUI().use('davglass', function (Y) {
1556              // Module davglass will be available here.
1557          });
1558  
1559      @method applyConfig
1560      @param {Object} o Configuration object to apply.
1561      @static
1562      @since 3.5.0
1563      **/
1564      YUI.applyConfig = function(o) {
1565          if (!o) {
1566              return;
1567          }
1568          //If there is a GlobalConfig, apply it first to set the defaults
1569          if (YUI.GlobalConfig) {
1570              this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1571          }
1572          //Apply this config to it
1573          this.prototype.applyConfig.call(this, o);
1574          //Reset GlobalConfig to the combined config
1575          YUI.GlobalConfig = this.config;
1576      };
1577  
1578      // set up the environment
1579      YUI._init();
1580  
1581      if (hasWin) {
1582          add(doc, 'DOMContentLoaded', handleReady);
1583  
1584          // add a window load event at load time so we can capture
1585          // the case where it fires before dynamic loading is
1586          // complete.
1587          add(window, 'load', handleLoad);
1588      } else {
1589          handleReady();
1590          handleLoad();
1591      }
1592  
1593      YUI.Env.add = add;
1594      YUI.Env.remove = remove;
1595  
1596      /*global exports*/
1597      // Support the CommonJS method for exporting our single global
1598      if (typeof exports == 'object') {
1599          exports.YUI = YUI;
1600          /**
1601          * Set a method to be called when `Get.script` is called in Node.js
1602          * `Get` will open the file, then pass it's content and it's path
1603          * to this method before attaching it. Commonly used for code coverage
1604          * instrumentation. <strong>Calling this multiple times will only
1605          * attach the last hook method</strong>. This method is only
1606          * available in Node.js.
1607          * @method setLoadHook
1608          * @static
1609          * @param {Function} fn The function to set
1610          * @param {String} fn.data The content of the file
1611          * @param {String} fn.path The file path of the file
1612          */
1613          YUI.setLoadHook = function(fn) {
1614              YUI._getLoadHook = fn;
1615          };
1616          /**
1617          * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1618          * @method _getLoadHook
1619          * @private
1620          * @param {String} data The content of the file
1621          * @param {String} path The file path of the file
1622          */
1623          YUI._getLoadHook = null;
1624      }
1625  
1626      YUI.Env[VERSION] = {};
1627  }());
1628  
1629  
1630  /**
1631  Config object that contains all of the configuration options for
1632  this `YUI` instance.
1633  
1634  This object is supplied by the implementer when instantiating YUI. Some
1635  properties have default values if they are not supplied by the implementer.
1636  
1637  This object should not be updated directly because some values are cached. Use
1638  `applyConfig()` to update the config object on a YUI instance that has already
1639  been configured.
1640  
1641  @class config
1642  @static
1643  **/
1644  
1645  /**
1646  If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1647  if they're needed to load additional dependencies and aren't already available.
1648  
1649  Setting this to `false` will prevent YUI from automatically loading the Loader
1650  and module metadata, so you will need to manually ensure that they're available
1651  or handle dependency resolution yourself.
1652  
1653  @property {Boolean} bootstrap
1654  @default true
1655  **/
1656  
1657  /**
1658  
1659  @property {Object} filters
1660  **/
1661  
1662  /**
1663  If `true`, YUI will use a combo handler to load multiple modules in as few
1664  requests as possible.
1665  
1666  The YUI CDN (which YUI uses by default) supports combo handling, but other
1667  servers may not. If the server from which you're loading YUI does not support
1668  combo handling, set this to `false`.
1669  
1670  Providing a value for the `base` config property will cause `combine` to default
1671  to `false` instead of `true`.
1672  
1673  @property {Boolean} combine
1674  @default true
1675  */
1676  
1677  /**
1678  Array of module names that should never be dynamically loaded.
1679  
1680  @property {String[]} ignore
1681  **/
1682  
1683  /**
1684  Array of module names that should always be loaded when required, even if
1685  already present on the page.
1686  
1687  @property {String[]} force
1688  **/
1689  
1690  /**
1691  DOM element or id that should be used as the insertion point for dynamically
1692  added `<script>` and `<link>` nodes.
1693  
1694  @property {HTMLElement|String} insertBefore
1695  **/
1696  
1697  /**
1698  Object hash containing attributes to add to dynamically added `<script>` nodes.
1699  
1700  @property {Object} jsAttributes
1701  **/
1702  
1703  /**
1704  Object hash containing attributes to add to dynamically added `<link>` nodes.
1705  
1706  @property {Object} cssAttributes
1707  **/
1708  
1709  /**
1710  Timeout in milliseconds before a dynamic JS or CSS request will be considered a
1711  failure. If not set, no timeout will be enforced.
1712  
1713  @property {Number} timeout
1714  **/
1715  
1716  /**
1717  A hash of module definitions to add to the list of available YUI modules. These
1718  modules can then be dynamically loaded via the `use()` method.
1719  
1720  This is a hash in which keys are module names and values are objects containing
1721  module metadata.
1722  
1723  See `Loader.addModule()` for the supported module metadata fields. Also see
1724  `groups`, which provides a way to configure the base and combo spec for a set of
1725  modules.
1726  
1727  @example
1728  
1729      modules: {
1730          mymod1: {
1731              requires: ['node'],
1732              fullpath: '/mymod1/mymod1.js'
1733          },
1734  
1735          mymod2: {
1736              requires: ['mymod1'],
1737              fullpath: '/mymod2/mymod2.js'
1738          },
1739  
1740          mymod3: '/js/mymod3.js',
1741          mycssmod: '/css/mycssmod.css'
1742      }
1743  
1744  @property {Object} modules
1745  **/
1746  
1747  /**
1748  Aliases are dynamic groups of modules that can be used as shortcuts.
1749  
1750  @example
1751  
1752      YUI({
1753          aliases: {
1754              davglass: [ 'node', 'yql', 'dd' ],
1755              mine: [ 'davglass', 'autocomplete']
1756          }
1757      }).use('mine', function (Y) {
1758          // Node, YQL, DD & AutoComplete available here.
1759      });
1760  
1761  @property {Object} aliases
1762  **/
1763  
1764  /**
1765  A hash of module group definitions.
1766  
1767  For each group you can specify a list of modules and the base path and
1768  combo spec to use when dynamically loading the modules.
1769  
1770  @example
1771  
1772      groups: {
1773          yui2: {
1774              // specify whether or not this group has a combo service
1775              combine: true,
1776  
1777              // The comboSeperator to use with this group's combo handler
1778              comboSep: ';',
1779  
1780              // The maxURLLength for this server
1781              maxURLLength: 500,
1782  
1783              // the base path for non-combo paths
1784              base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1785  
1786              // the path to the combo service
1787              comboBase: 'http://yui.yahooapis.com/combo?',
1788  
1789              // a fragment to prepend to the path attribute when
1790              // when building combo urls
1791              root: '2.8.0r4/build/',
1792  
1793              // the module definitions
1794              modules:  {
1795                  yui2_yde: {
1796                      path: "yahoo-dom-event/yahoo-dom-event.js"
1797                  },
1798                  yui2_anim: {
1799                      path: "animation/animation.js",
1800                      requires: ['yui2_yde']
1801                  }
1802              }
1803          }
1804      }
1805  
1806  @property {Object} groups
1807  **/
1808  
1809  /**
1810  Path to the Loader JS file, relative to the `base` path.
1811  
1812  This is used to dynamically bootstrap the Loader when it's needed and isn't yet
1813  available.
1814  
1815  @property {String} loaderPath
1816  @default "loader/loader-min.js"
1817  **/
1818  
1819  /**
1820  If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
1821  `false` to prevent YUI from loading any CSS, or set it to the string `"force"`
1822  to force CSS dependencies to be loaded even if their associated JS modules are
1823  already loaded.
1824  
1825  @property {Boolean|String} fetchCSS
1826  @default true
1827  **/
1828  
1829  /**
1830  Default gallery version used to build gallery module urls.
1831  
1832  @property {String} gallery
1833  @since 3.1.0
1834  **/
1835  
1836  /**
1837  Default YUI 2 version used to build YUI 2 module urls.
1838  
1839  This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
1840  `2in3` config for pulling different revisions of the wrapped YUI 2 modules.
1841  
1842  @property {String} yui2
1843  @default "2.9.0"
1844  @since 3.1.0
1845  **/
1846  
1847  /**
1848  Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
1849  
1850  @property {String} 2in3
1851  @default "4"
1852  @since 3.1.0
1853  **/
1854  
1855  /**
1856  Alternate console log function that should be used in environments without a
1857  supported native console. This function is executed with the YUI instance as its
1858  `this` object.
1859  
1860  @property {Function} logFn
1861  @since 3.1.0
1862  **/
1863  
1864  /**
1865  The minimum log level to log messages for. Log levels are defined
1866  incrementally. Messages greater than or equal to the level specified will
1867  be shown. All others will be discarded. The order of log levels in
1868  increasing priority is:
1869  
1870      debug
1871      info
1872      warn
1873      error
1874  
1875  @property {String} logLevel
1876  @default 'debug'
1877  @since 3.10.0
1878  **/
1879  
1880  /**
1881  Callback to execute when `Y.error()` is called. It receives the error message
1882  and a JavaScript error object if one was provided.
1883  
1884  This function is executed with the YUI instance as its `this` object.
1885  
1886  Returning `true` from this function will prevent an exception from being thrown.
1887  
1888  @property {Function} errorFn
1889  @param {String} errorFn.msg Error message
1890  @param {Object} [errorFn.err] Error object (if one was provided).
1891  @since 3.2.0
1892  **/
1893  
1894  /**
1895  A callback to execute when Loader fails to load one or more resources.
1896  
1897  This could be because of a script load failure. It could also be because a
1898  module fails to register itself when the `requireRegistration` config is `true`.
1899  
1900  If this function is defined, the `use()` callback will only be called when the
1901  loader succeeds. Otherwise, `use()` will always executes unless there was a
1902  JavaScript error when attaching a module.
1903  
1904  @property {Function} loadErrorFn
1905  @since 3.3.0
1906  **/
1907  
1908  /**
1909  If `true`, Loader will expect all loaded scripts to be first-class YUI modules
1910  that register themselves with the YUI global, and will trigger a failure if a
1911  loaded script does not register a YUI module.
1912  
1913  @property {Boolean} requireRegistration
1914  @default false
1915  @since 3.3.0
1916  **/
1917  
1918  /**
1919  Cache serviced use() requests.
1920  
1921  @property {Boolean} cacheUse
1922  @default true
1923  @since 3.3.0
1924  @deprecated No longer used.
1925  **/
1926  
1927  /**
1928  Whether or not YUI should use native ES5 functionality when available for
1929  features like `Y.Array.each()`, `Y.Object()`, etc.
1930  
1931  When `false`, YUI will always use its own fallback implementations instead of
1932  relying on ES5 functionality, even when ES5 functionality is available.
1933  
1934  @property {Boolean} useNativeES5
1935  @default true
1936  @since 3.5.0
1937  **/
1938  
1939  /**
1940   * Leverage native JSON stringify if the browser has a native
1941   * implementation.  In general, this is a good idea.  See the Known Issues
1942   * section in the JSON user guide for caveats.  The default value is true
1943   * for browsers with native JSON support.
1944   *
1945   * @property useNativeJSONStringify
1946   * @type Boolean
1947   * @default true
1948   * @since 3.8.0
1949   */
1950  
1951   /**
1952   * Leverage native JSON parse if the browser has a native implementation.
1953   * In general, this is a good idea.  See the Known Issues section in the
1954   * JSON user guide for caveats.  The default value is true for browsers with
1955   * native JSON support.
1956   *
1957   * @property useNativeJSONParse
1958   * @type Boolean
1959   * @default true
1960   * @since 3.8.0
1961   */
1962  
1963  /**
1964  Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
1965  
1966  @property {Object|String} delayUntil
1967  @since 3.6.0
1968  @example
1969  
1970  You can use `load` or `domready` strings by default:
1971  
1972      YUI({
1973          delayUntil: 'domready'
1974      }, function (Y) {
1975          // This will not execute until 'domeready' occurs.
1976      });
1977  
1978  Or you can delay until a node is available (with `available` or `contentready`):
1979  
1980      YUI({
1981          delayUntil: {
1982              event: 'available',
1983              args : '#foo'
1984          }
1985      }, function (Y) {
1986          // This will not execute until a node matching the selector "#foo" is
1987          // available in the DOM.
1988      });
1989  
1990  **/
1991  YUI.add('yui-base', function (Y, NAME) {
1992  
1993  /*
1994   * YUI stub
1995   * @module yui
1996   * @submodule yui-base
1997   */
1998  /**
1999   * The YUI module contains the components required for building the YUI
2000   * seed file.  This includes the script loading mechanism, a simple queue,
2001   * and the core utilities for the library.
2002   * @module yui
2003   * @submodule yui-base
2004   */
2005  
2006  /**
2007   * Provides core language utilites and extensions used throughout YUI.
2008   *
2009   * @class Lang
2010   * @static
2011   */
2012  
2013  var L = Y.Lang || (Y.Lang = {}),
2014  
2015  STRING_PROTO = String.prototype,
2016  TOSTRING     = Object.prototype.toString,
2017  
2018  TYPES = {
2019      'undefined'        : 'undefined',
2020      'number'           : 'number',
2021      'boolean'          : 'boolean',
2022      'string'           : 'string',
2023      '[object Function]': 'function',
2024      '[object RegExp]'  : 'regexp',
2025      '[object Array]'   : 'array',
2026      '[object Date]'    : 'date',
2027      '[object Error]'   : 'error'
2028  },
2029  
2030  SUBREGEX         = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
2031  
2032  WHITESPACE       = "\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",
2033  WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+",
2034  TRIM_LEFT_REGEX  = new RegExp("^" + WHITESPACE_CLASS),
2035  TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"),
2036  TRIMREGEX        = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"),
2037  
2038  NATIVE_FN_REGEX  = /\{\s*\[(?:native code|function)\]\s*\}/i;
2039  
2040  // -- Protected Methods --------------------------------------------------------
2041  
2042  /**
2043  Returns `true` if the given function appears to be implemented in native code,
2044  `false` otherwise. Will always return `false` -- even in ES5-capable browsers --
2045  if the `useNativeES5` YUI config option is set to `false`.
2046  
2047  This isn't guaranteed to be 100% accurate and won't work for anything other than
2048  functions, but it can be useful for determining whether a function like
2049  `Array.prototype.forEach` is native or a JS shim provided by another library.
2050  
2051  There's a great article by @kangax discussing certain flaws with this technique:
2052  <http://perfectionkills.com/detecting-built-in-host-methods/>
2053  
2054  While his points are valid, it's still possible to benefit from this function
2055  as long as it's used carefully and sparingly, and in such a way that false
2056  negatives have minimal consequences. It's used internally to avoid using
2057  potentially broken non-native ES5 shims that have been added to the page by
2058  other libraries.
2059  
2060  @method _isNative
2061  @param {Function} fn Function to test.
2062  @return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
2063  @static
2064  @protected
2065  @since 3.5.0
2066  **/
2067  L._isNative = function (fn) {
2068      return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
2069  };
2070  
2071  // -- Public Methods -----------------------------------------------------------
2072  
2073  /**
2074   * Determines whether or not the provided item is an array.
2075   *
2076   * Returns `false` for array-like collections such as the function `arguments`
2077   * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
2078   * test for an array-like collection.
2079   *
2080   * @method isArray
2081   * @param o The object to test.
2082   * @return {boolean} true if o is an array.
2083   * @static
2084   */
2085  L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
2086      return L.type(o) === 'array';
2087  };
2088  
2089  /**
2090   * Determines whether or not the provided item is a boolean.
2091   * @method isBoolean
2092   * @static
2093   * @param o The object to test.
2094   * @return {boolean} true if o is a boolean.
2095   */
2096  L.isBoolean = function(o) {
2097      return typeof o === 'boolean';
2098  };
2099  
2100  /**
2101   * Determines whether or not the supplied item is a date instance.
2102   * @method isDate
2103   * @static
2104   * @param o The object to test.
2105   * @return {boolean} true if o is a date.
2106   */
2107  L.isDate = function(o) {
2108      return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
2109  };
2110  
2111  /**
2112   * <p>
2113   * Determines whether or not the provided item is a function.
2114   * Note: Internet Explorer thinks certain functions are objects:
2115   * </p>
2116   *
2117   * <pre>
2118   * var obj = document.createElement("object");
2119   * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
2120   * &nbsp;
2121   * var input = document.createElement("input"); // append to body
2122   * Y.Lang.isFunction(input.focus) // reports false in IE
2123   * </pre>
2124   *
2125   * <p>
2126   * You will have to implement additional tests if these functions
2127   * matter to you.
2128   * </p>
2129   *
2130   * @method isFunction
2131   * @static
2132   * @param o The object to test.
2133   * @return {boolean} true if o is a function.
2134   */
2135  L.isFunction = function(o) {
2136      return L.type(o) === 'function';
2137  };
2138  
2139  /**
2140   * Determines whether or not the provided item is null.
2141   * @method isNull
2142   * @static
2143   * @param o The object to test.
2144   * @return {boolean} true if o is null.
2145   */
2146  L.isNull = function(o) {
2147      return o === null;
2148  };
2149  
2150  /**
2151   * Determines whether or not the provided item is a legal number.
2152   * @method isNumber
2153   * @static
2154   * @param o The object to test.
2155   * @return {boolean} true if o is a number.
2156   */
2157  L.isNumber = function(o) {
2158      return typeof o === 'number' && isFinite(o);
2159  };
2160  
2161  /**
2162   * Determines whether or not the provided item is of type object
2163   * or function. Note that arrays are also objects, so
2164   * <code>Y.Lang.isObject([]) === true</code>.
2165   * @method isObject
2166   * @static
2167   * @param o The object to test.
2168   * @param failfn {boolean} fail if the input is a function.
2169   * @return {boolean} true if o is an object.
2170   * @see isPlainObject
2171   */
2172  L.isObject = function(o, failfn) {
2173      var t = typeof o;
2174      return (o && (t === 'object' ||
2175          (!failfn && (t === 'function' || L.isFunction(o))))) || false;
2176  };
2177  
2178  /**
2179   * Determines whether or not the provided value is a regexp.
2180   * @method isRegExp
2181   * @static
2182   * @param value The value or object to test.
2183   * @return {boolean} true if value is a regexp.
2184   */
2185  L.isRegExp = function(value) {
2186      return L.type(value) === 'regexp';
2187  };
2188  
2189  /**
2190   * Determines whether or not the provided item is a string.
2191   * @method isString
2192   * @static
2193   * @param o The object to test.
2194   * @return {boolean} true if o is a string.
2195   */
2196  L.isString = function(o) {
2197      return typeof o === 'string';
2198  };
2199  
2200  /**
2201   * Determines whether or not the provided item is undefined.
2202   * @method isUndefined
2203   * @static
2204   * @param o The object to test.
2205   * @return {boolean} true if o is undefined.
2206   */
2207  L.isUndefined = function(o) {
2208      return typeof o === 'undefined';
2209  };
2210  
2211  /**
2212   * A convenience method for detecting a legitimate non-null value.
2213   * Returns false for null/undefined/NaN, true for other values,
2214   * including 0/false/''
2215   * @method isValue
2216   * @static
2217   * @param o The item to test.
2218   * @return {boolean} true if it is not null/undefined/NaN || false.
2219   */
2220  L.isValue = function(o) {
2221      var t = L.type(o);
2222  
2223      switch (t) {
2224          case 'number':
2225              return isFinite(o);
2226  
2227          case 'null': // fallthru
2228          case 'undefined':
2229              return false;
2230  
2231          default:
2232              return !!t;
2233      }
2234  };
2235  
2236  /**
2237   * Returns the current time in milliseconds.
2238   *
2239   * @method now
2240   * @return {Number} Current time in milliseconds.
2241   * @static
2242   * @since 3.3.0
2243   */
2244  L.now = Date.now || function () {
2245      return new Date().getTime();
2246  };
2247  
2248  /**
2249   * Performs `{placeholder}` substitution on a string. The object passed as the 
2250   * second parameter provides values to replace the `{placeholder}`s.
2251   * `{placeholder}` token names must match property names of the object. For example,
2252   * 
2253   *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });`
2254   *
2255   * `{placeholder}` tokens that are undefined on the object map will be left 
2256   * in tact (leaving unsightly `{placeholder}`'s in the output string). 
2257   *
2258   * @method sub
2259   * @param {string} s String to be modified.
2260   * @param {object} o Object containing replacement values.
2261   * @return {string} the substitute result.
2262   * @static
2263   * @since 3.2.0
2264   */
2265  L.sub = function(s, o) {
2266      return s.replace ? s.replace(SUBREGEX, function (match, key) {
2267          return L.isUndefined(o[key]) ? match : o[key];
2268      }) : s;
2269  };
2270  
2271  /**
2272   * Returns a string without any leading or trailing whitespace.  If
2273   * the input is not a string, the input will be returned untouched.
2274   * @method trim
2275   * @static
2276   * @param s {string} the string to trim.
2277   * @return {string} the trimmed string.
2278   */
2279  L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) {
2280      return s && s.trim ? s.trim() : s;
2281  } : function (s) {
2282      try {
2283          return s.replace(TRIMREGEX, '');
2284      } catch (e) {
2285          return s;
2286      }
2287  };
2288  
2289  /**
2290   * Returns a string without any leading whitespace.
2291   * @method trimLeft
2292   * @static
2293   * @param s {string} the string to trim.
2294   * @return {string} the trimmed string.
2295   */
2296  L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) {
2297      return s.trimLeft();
2298  } : function (s) {
2299      return s.replace(TRIM_LEFT_REGEX, '');
2300  };
2301  
2302  /**
2303   * Returns a string without any trailing whitespace.
2304   * @method trimRight
2305   * @static
2306   * @param s {string} the string to trim.
2307   * @return {string} the trimmed string.
2308   */
2309  L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) {
2310      return s.trimRight();
2311  } : function (s) {
2312      return s.replace(TRIM_RIGHT_REGEX, '');
2313  };
2314  
2315  /**
2316  Returns one of the following strings, representing the type of the item passed
2317  in:
2318  
2319   * "array"
2320   * "boolean"
2321   * "date"
2322   * "error"
2323   * "function"
2324   * "null"
2325   * "number"
2326   * "object"
2327   * "regexp"
2328   * "string"
2329   * "undefined"
2330  
2331  Known issues:
2332  
2333   * `typeof HTMLElementCollection` returns function in Safari, but
2334      `Y.Lang.type()` reports "object", which could be a good thing --
2335      but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2336  
2337  @method type
2338  @param o the item to test.
2339  @return {string} the detected type.
2340  @static
2341  **/
2342  L.type = function(o) {
2343      return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2344  };
2345  /**
2346  @module yui
2347  @submodule yui-base
2348  */
2349  
2350  var Lang   = Y.Lang,
2351      Native = Array.prototype,
2352  
2353      hasOwn = Object.prototype.hasOwnProperty;
2354  
2355  /**
2356  Provides utility methods for working with arrays. Additional array helpers can
2357  be found in the `collection` and `array-extras` modules.
2358  
2359  `Y.Array(thing)` returns a native array created from _thing_. Depending on
2360  _thing_'s type, one of the following will happen:
2361  
2362    * Arrays are returned unmodified unless a non-zero _startIndex_ is
2363      specified.
2364    * Array-like collections (see `Array.test()`) are converted to arrays.
2365    * For everything else, a new array is created with _thing_ as the sole
2366      item.
2367  
2368  Note: elements that are also collections, such as `<form>` and `<select>`
2369  elements, are not automatically converted to arrays. To force a conversion,
2370  pass `true` as the value of the _force_ parameter.
2371  
2372  @class Array
2373  @constructor
2374  @param {Any} thing The thing to arrayify.
2375  @param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2376    collection, a subset of items starting at the specified index will be
2377    returned.
2378  @param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2379    array-like collection no matter what.
2380  @return {Array} A native array created from _thing_, according to the rules
2381    described above.
2382  **/
2383  function YArray(thing, startIndex, force) {
2384      var len, result;
2385  
2386      /*jshint expr: true*/
2387      startIndex || (startIndex = 0);
2388  
2389      if (force || YArray.test(thing)) {
2390          // IE throws when trying to slice HTMLElement collections.
2391          try {
2392              return Native.slice.call(thing, startIndex);
2393          } catch (ex) {
2394              result = [];
2395  
2396              for (len = thing.length; startIndex < len; ++startIndex) {
2397                  result.push(thing[startIndex]);
2398              }
2399  
2400              return result;
2401          }
2402      }
2403  
2404      return [thing];
2405  }
2406  
2407  Y.Array = YArray;
2408  
2409  /**
2410  Dedupes an array of strings, returning an array that's guaranteed to contain
2411  only one copy of a given string.
2412  
2413  This method differs from `Array.unique()` in that it's optimized for use only
2414  with arrays consisting entirely of strings or entirely of numbers, whereas
2415  `unique` may be used with other value types (but is slower).
2416  
2417  Using `dedupe()` with values other than strings or numbers, or with arrays
2418  containing a mix of strings and numbers, may result in unexpected behavior.
2419  
2420  @method dedupe
2421  @param {String[]|Number[]} array Array of strings or numbers to dedupe.
2422  @return {Array} Copy of _array_ containing no duplicate values.
2423  @static
2424  @since 3.4.0
2425  **/
2426  YArray.dedupe = Lang._isNative(Object.create) ? function (array) {
2427      var hash    = Object.create(null),
2428          results = [],
2429          i, item, len;
2430  
2431      for (i = 0, len = array.length; i < len; ++i) {
2432          item = array[i];
2433  
2434          if (!hash[item]) {
2435              hash[item] = 1;
2436              results.push(item);
2437          }
2438      }
2439  
2440      return results;
2441  } : function (array) {
2442      var hash    = {},
2443          results = [],
2444          i, item, len;
2445  
2446      for (i = 0, len = array.length; i < len; ++i) {
2447          item = array[i];
2448  
2449          if (!hasOwn.call(hash, item)) {
2450              hash[item] = 1;
2451              results.push(item);
2452          }
2453      }
2454  
2455      return results;
2456  };
2457  
2458  /**
2459  Executes the supplied function on each item in the array. This method wraps
2460  the native ES5 `Array.forEach()` method if available.
2461  
2462  @method each
2463  @param {Array} array Array to iterate.
2464  @param {Function} fn Function to execute on each item in the array. The function
2465    will receive the following arguments:
2466      @param {Any} fn.item Current array item.
2467      @param {Number} fn.index Current array index.
2468      @param {Array} fn.array Array being iterated.
2469  @param {Object} [thisObj] `this` object to use when calling _fn_.
2470  @return {YUI} The YUI instance.
2471  @static
2472  **/
2473  YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2474      Native.forEach.call(array || [], fn, thisObj || Y);
2475      return Y;
2476  } : function (array, fn, thisObj) {
2477      for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2478          if (i in array) {
2479              fn.call(thisObj || Y, array[i], i, array);
2480          }
2481      }
2482  
2483      return Y;
2484  };
2485  
2486  /**
2487  Alias for `each()`.
2488  
2489  @method forEach
2490  @static
2491  **/
2492  
2493  /**
2494  Returns an object using the first array as keys and the second as values. If
2495  the second array is not provided, or if it doesn't contain the same number of
2496  values as the first array, then `true` will be used in place of the missing
2497  values.
2498  
2499  @example
2500  
2501      Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2502      // => {a: 'foo', b: 'bar', c: true}
2503  
2504  @method hash
2505  @param {String[]} keys Array of strings to use as keys.
2506  @param {Array} [values] Array to use as values.
2507  @return {Object} Hash using the first array as keys and the second as values.
2508  @static
2509  **/
2510  YArray.hash = function (keys, values) {
2511      var hash = {},
2512          vlen = (values && values.length) || 0,
2513          i, len;
2514  
2515      for (i = 0, len = keys.length; i < len; ++i) {
2516          if (i in keys) {
2517              hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2518          }
2519      }
2520  
2521      return hash;
2522  };
2523  
2524  /**
2525  Returns the index of the first item in the array that's equal (using a strict
2526  equality check) to the specified _value_, or `-1` if the value isn't found.
2527  
2528  This method wraps the native ES5 `Array.indexOf()` method if available.
2529  
2530  @method indexOf
2531  @param {Array} array Array to search.
2532  @param {Any} value Value to search for.
2533  @param {Number} [from=0] The index at which to begin the search.
2534  @return {Number} Index of the item strictly equal to _value_, or `-1` if not
2535      found.
2536  @static
2537  **/
2538  YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2539      return Native.indexOf.call(array, value, from);
2540  } : function (array, value, from) {
2541      // http://es5.github.com/#x15.4.4.14
2542      var len = array.length;
2543  
2544      from = +from || 0;
2545      from = (from > 0 || -1) * Math.floor(Math.abs(from));
2546  
2547      if (from < 0) {
2548          from += len;
2549  
2550          if (from < 0) {
2551              from = 0;
2552          }
2553      }
2554  
2555      for (; from < len; ++from) {
2556          if (from in array && array[from] === value) {
2557              return from;
2558          }
2559      }
2560  
2561      return -1;
2562  };
2563  
2564  /**
2565  Numeric sort convenience function.
2566  
2567  The native `Array.prototype.sort()` function converts values to strings and
2568  sorts them in lexicographic order, which is unsuitable for sorting numeric
2569  values. Provide `Array.numericSort` as a custom sort function when you want
2570  to sort values in numeric order.
2571  
2572  @example
2573  
2574      [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2575      // => [4, 8, 15, 16, 23, 42]
2576  
2577  @method numericSort
2578  @param {Number} a First value to compare.
2579  @param {Number} b Second value to compare.
2580  @return {Number} Difference between _a_ and _b_.
2581  @static
2582  **/
2583  YArray.numericSort = function (a, b) {
2584      return a - b;
2585  };
2586  
2587  /**
2588  Executes the supplied function on each item in the array. Returning a truthy
2589  value from the function will stop the processing of remaining items.
2590  
2591  @method some
2592  @param {Array} array Array to iterate over.
2593  @param {Function} fn Function to execute on each item. The function will receive
2594    the following arguments:
2595      @param {Any} fn.value Current array item.
2596      @param {Number} fn.index Current array index.
2597      @param {Array} fn.array Array being iterated over.
2598  @param {Object} [thisObj] `this` object to use when calling _fn_.
2599  @return {Boolean} `true` if the function returns a truthy value on any of the
2600    items in the array; `false` otherwise.
2601  @static
2602  **/
2603  YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2604      return Native.some.call(array, fn, thisObj);
2605  } : function (array, fn, thisObj) {
2606      for (var i = 0, len = array.length; i < len; ++i) {
2607          if (i in array && fn.call(thisObj, array[i], i, array)) {
2608              return true;
2609          }
2610      }
2611  
2612      return false;
2613  };
2614  
2615  /**
2616  Evaluates _obj_ to determine if it's an array, an array-like collection, or
2617  something else. This is useful when working with the function `arguments`
2618  collection and `HTMLElement` collections.
2619  
2620  Note: This implementation doesn't consider elements that are also
2621  collections, such as `<form>` and `<select>`, to be array-like.
2622  
2623  @method test
2624  @param {Object} obj Object to test.
2625  @return {Number} A number indicating the results of the test:
2626  
2627    * 0: Neither an array nor an array-like collection.
2628    * 1: Real array.
2629    * 2: Array-like collection.
2630  
2631  @static
2632  **/
2633  YArray.test = function (obj) {
2634      var result = 0;
2635  
2636      if (Lang.isArray(obj)) {
2637          result = 1;
2638      } else if (Lang.isObject(obj)) {
2639          try {
2640              // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2641              // or functions without apply/call (Safari
2642              // HTMLElementCollection bug).
2643              if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2644                  result = 2;
2645              }
2646          } catch (ex) {}
2647      }
2648  
2649      return result;
2650  };
2651  /**
2652   * The YUI module contains the components required for building the YUI
2653   * seed file.  This includes the script loading mechanism, a simple queue,
2654   * and the core utilities for the library.
2655   * @module yui
2656   * @submodule yui-base
2657   */
2658  
2659  /**
2660   * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
2661   * removed using next().
2662   *
2663   * @class Queue
2664   * @constructor
2665   * @param {MIXED} item* 0..n items to seed the queue.
2666   */
2667  function Queue() {
2668      this._init();
2669      this.add.apply(this, arguments);
2670  }
2671  
2672  Queue.prototype = {
2673      /**
2674       * Initialize the queue
2675       *
2676       * @method _init
2677       * @protected
2678       */
2679      _init: function() {
2680          /**
2681           * The collection of enqueued items
2682           *
2683           * @property _q
2684           * @type Array
2685           * @protected
2686           */
2687          this._q = [];
2688      },
2689  
2690      /**
2691       * Get the next item in the queue. FIFO support
2692       *
2693       * @method next
2694       * @return {MIXED} the next item in the queue.
2695       */
2696      next: function() {
2697          return this._q.shift();
2698      },
2699  
2700      /**
2701       * Get the last in the queue. LIFO support.
2702       *
2703       * @method last
2704       * @return {MIXED} the last item in the queue.
2705       */
2706      last: function() {
2707          return this._q.pop();
2708      },
2709  
2710      /**
2711       * Add 0..n items to the end of the queue.
2712       *
2713       * @method add
2714       * @param {MIXED} item* 0..n items.
2715       * @return {object} this queue.
2716       */
2717      add: function() {
2718          this._q.push.apply(this._q, arguments);
2719  
2720          return this;
2721      },
2722  
2723      /**
2724       * Returns the current number of queued items.
2725       *
2726       * @method size
2727       * @return {Number} The size.
2728       */
2729      size: function() {
2730          return this._q.length;
2731      }
2732  };
2733  
2734  Y.Queue = Queue;
2735  
2736  YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2737  
2738  /**
2739  The YUI module contains the components required for building the YUI seed file.
2740  This includes the script loading mechanism, a simple queue, and the core
2741  utilities for the library.
2742  
2743  @module yui
2744  @submodule yui-base
2745  **/
2746  
2747  var CACHED_DELIMITER = '__',
2748  
2749      hasOwn   = Object.prototype.hasOwnProperty,
2750      isObject = Y.Lang.isObject;
2751  
2752  /**
2753  Returns a wrapper for a function which caches the return value of that function,
2754  keyed off of the combined string representation of the argument values provided
2755  when the wrapper is called.
2756  
2757  Calling this function again with the same arguments will return the cached value
2758  rather than executing the wrapped function.
2759  
2760  Note that since the cache is keyed off of the string representation of arguments
2761  passed to the wrapper function, arguments that aren't strings and don't provide
2762  a meaningful `toString()` method may result in unexpected caching behavior. For
2763  example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2764  string `[object Object]` when used as a cache key.
2765  
2766  @method cached
2767  @param {Function} source The function to memoize.
2768  @param {Object} [cache={}] Object in which to store cached values. You may seed
2769    this object with pre-existing cached values if desired.
2770  @param {any} [refetch] If supplied, this value is compared with the cached value
2771    using a `==` comparison. If the values are equal, the wrapped function is
2772    executed again even though a cached value exists.
2773  @return {Function} Wrapped function.
2774  @for YUI
2775  **/
2776  Y.cached = function (source, cache, refetch) {
2777      /*jshint expr: true*/
2778      cache || (cache = {});
2779  
2780      return function (arg) {
2781          var key = arguments.length > 1 ?
2782                  Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2783                  String(arg);
2784  
2785          /*jshint eqeqeq: false*/
2786          if (!(key in cache) || (refetch && cache[key] == refetch)) {
2787              cache[key] = source.apply(source, arguments);
2788          }
2789  
2790          return cache[key];
2791      };
2792  };
2793  
2794  /**
2795  Returns the `location` object from the window/frame in which this YUI instance
2796  operates, or `undefined` when executing in a non-browser environment
2797  (e.g. Node.js).
2798  
2799  It is _not_ recommended to hold references to the `window.location` object
2800  outside of the scope of a function in which its properties are being accessed or
2801  its methods are being called. This is because of a nasty bug/issue that exists
2802  in both Safari and MobileSafari browsers:
2803  [WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
2804  
2805  @method getLocation
2806  @return {location} The `location` object from the window/frame in which this YUI
2807      instance operates.
2808  @since 3.5.0
2809  **/
2810  Y.getLocation = function () {
2811      // It is safer to look this up every time because yui-base is attached to a
2812      // YUI instance before a user's config is applied; i.e. `Y.config.win` does
2813      // not point the correct window object when this file is loaded.
2814      var win = Y.config.win;
2815  
2816      // It is not safe to hold a reference to the `location` object outside the
2817      // scope in which it is being used. The WebKit engine used in Safari and
2818      // MobileSafari will "disconnect" the `location` object from the `window`
2819      // when a page is restored from back/forward history cache.
2820      return win && win.location;
2821  };
2822  
2823  /**
2824  Returns a new object containing all of the properties of all the supplied
2825  objects. The properties from later objects will overwrite those in earlier
2826  objects.
2827  
2828  Passing in a single object will create a shallow copy of it. For a deep copy,
2829  use `clone()`.
2830  
2831  @method merge
2832  @param {Object} objects* One or more objects to merge.
2833  @return {Object} A new merged object.
2834  **/
2835  Y.merge = function () {
2836      var i      = 0,
2837          len    = arguments.length,
2838          result = {},
2839          key,
2840          obj;
2841  
2842      for (; i < len; ++i) {
2843          obj = arguments[i];
2844  
2845          for (key in obj) {
2846              if (hasOwn.call(obj, key)) {
2847                  result[key] = obj[key];
2848              }
2849          }
2850      }
2851  
2852      return result;
2853  };
2854  
2855  /**
2856  Mixes _supplier_'s properties into _receiver_.
2857  
2858  Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2859  shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2860  unless the _merge_ parameter is `true`.
2861  
2862  In the default mode (0), only properties the supplier owns are copied (prototype
2863  properties are not copied). The following copying modes are available:
2864  
2865    * `0`: _Default_. Object to object.
2866    * `1`: Prototype to prototype.
2867    * `2`: Prototype to prototype and object to object.
2868    * `3`: Prototype to object.
2869    * `4`: Object to prototype.
2870  
2871  @method mix
2872  @param {Function|Object} receiver The object or function to receive the mixed
2873    properties.
2874  @param {Function|Object} supplier The object or function supplying the
2875    properties to be mixed.
2876  @param {Boolean} [overwrite=false] If `true`, properties that already exist
2877    on the receiver will be overwritten with properties from the supplier.
2878  @param {String[]} [whitelist] An array of property names to copy. If
2879    specified, only the whitelisted properties will be copied, and all others
2880    will be ignored.
2881  @param {Number} [mode=0] Mix mode to use. See above for available modes.
2882  @param {Boolean} [merge=false] If `true`, objects and arrays that already
2883    exist on the receiver will have the corresponding object/array from the
2884    supplier merged into them, rather than being skipped or overwritten. When
2885    both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2886  @return {Function|Object|YUI} The receiver, or the YUI instance if the
2887    specified receiver is falsy.
2888  **/
2889  Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2890      var alwaysOverwrite, exists, from, i, key, len, to;
2891  
2892      // If no supplier is given, we return the receiver. If no receiver is given,
2893      // we return Y. Returning Y doesn't make much sense to me, but it's
2894      // grandfathered in for backcompat reasons.
2895      if (!receiver || !supplier) {
2896          return receiver || Y;
2897      }
2898  
2899      if (mode) {
2900          // In mode 2 (prototype to prototype and object to object), we recurse
2901          // once to do the proto to proto mix. The object to object mix will be
2902          // handled later on.
2903          if (mode === 2) {
2904              Y.mix(receiver.prototype, supplier.prototype, overwrite,
2905                      whitelist, 0, merge);
2906          }
2907  
2908          // Depending on which mode is specified, we may be copying from or to
2909          // the prototypes of the supplier and receiver.
2910          from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
2911          to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
2912  
2913          // If either the supplier or receiver doesn't actually have a
2914          // prototype property, then we could end up with an undefined `from`
2915          // or `to`. If that happens, we abort and return the receiver.
2916          if (!from || !to) {
2917              return receiver;
2918          }
2919      } else {
2920          from = supplier;
2921          to   = receiver;
2922      }
2923  
2924      // If `overwrite` is truthy and `merge` is falsy, then we can skip a
2925      // property existence check on each iteration and save some time.
2926      alwaysOverwrite = overwrite && !merge;
2927  
2928      if (whitelist) {
2929          for (i = 0, len = whitelist.length; i < len; ++i) {
2930              key = whitelist[i];
2931  
2932              // We call `Object.prototype.hasOwnProperty` instead of calling
2933              // `hasOwnProperty` on the object itself, since the object's
2934              // `hasOwnProperty` method may have been overridden or removed.
2935              // Also, some native objects don't implement a `hasOwnProperty`
2936              // method.
2937              if (!hasOwn.call(from, key)) {
2938                  continue;
2939              }
2940  
2941              // The `key in to` check here is (sadly) intentional for backwards
2942              // compatibility reasons. It prevents undesired shadowing of
2943              // prototype members on `to`.
2944              exists = alwaysOverwrite ? false : key in to;
2945  
2946              if (merge && exists && isObject(to[key], true)
2947                      && isObject(from[key], true)) {
2948                  // If we're in merge mode, and the key is present on both
2949                  // objects, and the value on both objects is either an object or
2950                  // an array (but not a function), then we recurse to merge the
2951                  // `from` value into the `to` value instead of overwriting it.
2952                  //
2953                  // Note: It's intentional that the whitelist isn't passed to the
2954                  // recursive call here. This is legacy behavior that lots of
2955                  // code still depends on.
2956                  Y.mix(to[key], from[key], overwrite, null, 0, merge);
2957              } else if (overwrite || !exists) {
2958                  // We're not in merge mode, so we'll only copy the `from` value
2959                  // to the `to` value if we're in overwrite mode or if the
2960                  // current key doesn't exist on the `to` object.
2961                  to[key] = from[key];
2962              }
2963          }
2964      } else {
2965          for (key in from) {
2966              // The code duplication here is for runtime performance reasons.
2967              // Combining whitelist and non-whitelist operations into a single
2968              // loop or breaking the shared logic out into a function both result
2969              // in worse performance, and Y.mix is critical enough that the byte
2970              // tradeoff is worth it.
2971              if (!hasOwn.call(from, key)) {
2972                  continue;
2973              }
2974  
2975              // The `key in to` check here is (sadly) intentional for backwards
2976              // compatibility reasons. It prevents undesired shadowing of
2977              // prototype members on `to`.
2978              exists = alwaysOverwrite ? false : key in to;
2979  
2980              if (merge && exists && isObject(to[key], true)
2981                      && isObject(from[key], true)) {
2982                  Y.mix(to[key], from[key], overwrite, null, 0, merge);
2983              } else if (overwrite || !exists) {
2984                  to[key] = from[key];
2985              }
2986          }
2987  
2988          // If this is an IE browser with the JScript enumeration bug, force
2989          // enumeration of the buggy properties by making a recursive call with
2990          // the buggy properties as the whitelist.
2991          if (Y.Object._hasEnumBug) {
2992              Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
2993          }
2994      }
2995  
2996      return receiver;
2997  };
2998  /**
2999   * The YUI module contains the components required for building the YUI
3000   * seed file.  This includes the script loading mechanism, a simple queue,
3001   * and the core utilities for the library.
3002   * @module yui
3003   * @submodule yui-base
3004   */
3005  
3006  /**
3007   * Adds utilities to the YUI instance for working with objects.
3008   *
3009   * @class Object
3010   */
3011  
3012  var Lang   = Y.Lang,
3013      hasOwn = Object.prototype.hasOwnProperty,
3014  
3015      UNDEFINED, // <-- Note the comma. We're still declaring vars.
3016  
3017  /**
3018   * Returns a new object that uses _obj_ as its prototype. This method wraps the
3019   * native ES5 `Object.create()` method if available, but doesn't currently
3020   * pass through `Object.create()`'s second argument (properties) in order to
3021   * ensure compatibility with older browsers.
3022   *
3023   * @method ()
3024   * @param {Object} obj Prototype object.
3025   * @return {Object} New object using _obj_ as its prototype.
3026   * @static
3027   */
3028  O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
3029      // We currently wrap the native Object.create instead of simply aliasing it
3030      // to ensure consistency with our fallback shim, which currently doesn't
3031      // support Object.create()'s second argument (properties). Once we have a
3032      // safe fallback for the properties arg, we can stop wrapping
3033      // Object.create().
3034      return Object.create(obj);
3035  } : (function () {
3036      // Reusable constructor function for the Object.create() shim.
3037      function F() {}
3038  
3039      // The actual shim.
3040      return function (obj) {
3041          F.prototype = obj;
3042          return new F();
3043      };
3044  }()),
3045  
3046  /**
3047   * Property names that IE doesn't enumerate in for..in loops, even when they
3048   * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
3049   * manually enumerate these properties.
3050   *
3051   * @property _forceEnum
3052   * @type String[]
3053   * @protected
3054   * @static
3055   */
3056  forceEnum = O._forceEnum = [
3057      'hasOwnProperty',
3058      'isPrototypeOf',
3059      'propertyIsEnumerable',
3060      'toString',
3061      'toLocaleString',
3062      'valueOf'
3063  ],
3064  
3065  /**
3066   * `true` if this browser has the JScript enumeration bug that prevents
3067   * enumeration of the properties named in the `_forceEnum` array, `false`
3068   * otherwise.
3069   *
3070   * See:
3071   *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
3072   *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
3073   *
3074   * @property _hasEnumBug
3075   * @type Boolean
3076   * @protected
3077   * @static
3078   */
3079  hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
3080  
3081  /**
3082   * `true` if this browser incorrectly considers the `prototype` property of
3083   * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x.
3084   *
3085   * @property _hasProtoEnumBug
3086   * @type Boolean
3087   * @protected
3088   * @static
3089   */
3090  hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
3091  
3092  /**
3093   * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
3094   * exists only on _obj_'s prototype. This is essentially a safer version of
3095   * `obj.hasOwnProperty()`.
3096   *
3097   * @method owns
3098   * @param {Object} obj Object to test.
3099   * @param {String} key Property name to look for.
3100   * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3101   * @static
3102   */
3103  owns = O.owns = function (obj, key) {
3104      return !!obj && hasOwn.call(obj, key);
3105  }; // <-- End of var declarations.
3106  
3107  /**
3108   * Alias for `owns()`.
3109   *
3110   * @method hasKey
3111   * @param {Object} obj Object to test.
3112   * @param {String} key Property name to look for.
3113   * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3114   * @static
3115   */
3116  O.hasKey = owns;
3117  
3118  /**
3119   * Returns an array containing the object's enumerable keys. Does not include
3120   * prototype keys or non-enumerable keys.
3121   *
3122   * Note that keys are returned in enumeration order (that is, in the same order
3123   * that they would be enumerated by a `for-in` loop), which may not be the same
3124   * as the order in which they were defined.
3125   *
3126   * This method is an alias for the native ES5 `Object.keys()` method if
3127   * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of
3128   * `Object.keys()` have an inconsistency as they consider `prototype` to be
3129   * enumerable, so a non-native shim is used to rectify the difference.
3130   *
3131   * @example
3132   *
3133   *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
3134   *     // => ['a', 'b', 'c']
3135   *
3136   * @method keys
3137   * @param {Object} obj An object.
3138   * @return {String[]} Array of keys.
3139   * @static
3140   */
3141  O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) {
3142      if (!Lang.isObject(obj)) {
3143          throw new TypeError('Object.keys called on a non-object');
3144      }
3145  
3146      var keys = [],
3147          i, key, len;
3148  
3149      if (hasProtoEnumBug && typeof obj === 'function') {
3150          for (key in obj) {
3151              if (owns(obj, key) && key !== 'prototype') {
3152                  keys.push(key);
3153              }
3154          }
3155      } else {
3156          for (key in obj) {
3157              if (owns(obj, key)) {
3158                  keys.push(key);
3159              }
3160          }
3161      }
3162  
3163      if (hasEnumBug) {
3164          for (i = 0, len = forceEnum.length; i < len; ++i) {
3165              key = forceEnum[i];
3166  
3167              if (owns(obj, key)) {
3168                  keys.push(key);
3169              }
3170          }
3171      }
3172  
3173      return keys;
3174  };
3175  
3176  /**
3177   * Returns an array containing the values of the object's enumerable keys.
3178   *
3179   * Note that values are returned in enumeration order (that is, in the same
3180   * order that they would be enumerated by a `for-in` loop), which may not be the
3181   * same as the order in which they were defined.
3182   *
3183   * @example
3184   *
3185   *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
3186   *     // => ['foo', 'bar', 'baz']
3187   *
3188   * @method values
3189   * @param {Object} obj An object.
3190   * @return {Array} Array of values.
3191   * @static
3192   */
3193  O.values = function (obj) {
3194      var keys   = O.keys(obj),
3195          i      = 0,
3196          len    = keys.length,
3197          values = [];
3198  
3199      for (; i < len; ++i) {
3200          values.push(obj[keys[i]]);
3201      }
3202  
3203      return values;
3204  };
3205  
3206  /**
3207   * Returns the number of enumerable keys owned by an object.
3208   *
3209   * @method size
3210   * @param {Object} obj An object.
3211   * @return {Number} The object's size.
3212   * @static
3213   */
3214  O.size = function (obj) {
3215      try {
3216          return O.keys(obj).length;
3217      } catch (ex) {
3218          return 0; // Legacy behavior for non-objects.
3219      }
3220  };
3221  
3222  /**
3223   * Returns `true` if the object owns an enumerable property with the specified
3224   * value.
3225   *
3226   * @method hasValue
3227   * @param {Object} obj An object.
3228   * @param {any} value The value to search for.
3229   * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
3230   * @static
3231   */
3232  O.hasValue = function (obj, value) {
3233      return Y.Array.indexOf(O.values(obj), value) > -1;
3234  };
3235  
3236  /**
3237   * Executes a function on each enumerable property in _obj_. The function
3238   * receives the value, the key, and the object itself as parameters (in that
3239   * order).
3240   *
3241   * By default, only properties owned by _obj_ are enumerated. To include
3242   * prototype properties, set the _proto_ parameter to `true`.
3243   *
3244   * @method each
3245   * @param {Object} obj Object to enumerate.
3246   * @param {Function} fn Function to execute on each enumerable property.
3247   *   @param {mixed} fn.value Value of the current property.
3248   *   @param {String} fn.key Key of the current property.
3249   *   @param {Object} fn.obj Object being enumerated.
3250   * @param {Object} [thisObj] `this` object to use when calling _fn_.
3251   * @param {Boolean} [proto=false] Include prototype properties.
3252   * @return {YUI} the YUI instance.
3253   * @chainable
3254   * @static
3255   */
3256  O.each = function (obj, fn, thisObj, proto) {
3257      var key;
3258  
3259      for (key in obj) {
3260          if (proto || owns(obj, key)) {
3261              fn.call(thisObj || Y, obj[key], key, obj);
3262          }
3263      }
3264  
3265      return Y;
3266  };
3267  
3268  /**
3269   * Executes a function on each enumerable property in _obj_, but halts if the
3270   * function returns a truthy value. The function receives the value, the key,
3271   * and the object itself as paramters (in that order).
3272   *
3273   * By default, only properties owned by _obj_ are enumerated. To include
3274   * prototype properties, set the _proto_ parameter to `true`.
3275   *
3276   * @method some
3277   * @param {Object} obj Object to enumerate.
3278   * @param {Function} fn Function to execute on each enumerable property.
3279   *   @param {mixed} fn.value Value of the current property.
3280   *   @param {String} fn.key Key of the current property.
3281   *   @param {Object} fn.obj Object being enumerated.
3282   * @param {Object} [thisObj] `this` object to use when calling _fn_.
3283   * @param {Boolean} [proto=false] Include prototype properties.
3284   * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3285   *   `false` otherwise.
3286   * @static
3287   */
3288  O.some = function (obj, fn, thisObj, proto) {
3289      var key;
3290  
3291      for (key in obj) {
3292          if (proto || owns(obj, key)) {
3293              if (fn.call(thisObj || Y, obj[key], key, obj)) {
3294                  return true;
3295              }
3296          }
3297      }
3298  
3299      return false;
3300  };
3301  
3302  /**
3303   * Retrieves the sub value at the provided path,
3304   * from the value object provided.
3305   *
3306   * @method getValue
3307   * @static
3308   * @param o The object from which to extract the property value.
3309   * @param path {Array} A path array, specifying the object traversal path
3310   * from which to obtain the sub value.
3311   * @return {Any} The value stored in the path, undefined if not found,
3312   * undefined if the source is not an object.  Returns the source object
3313   * if an empty path is provided.
3314   */
3315  O.getValue = function(o, path) {
3316      if (!Lang.isObject(o)) {
3317          return UNDEFINED;
3318      }
3319  
3320      var i,
3321          p = Y.Array(path),
3322          l = p.length;
3323  
3324      for (i = 0; o !== UNDEFINED && i < l; i++) {
3325          o = o[p[i]];
3326      }
3327  
3328      return o;
3329  };
3330  
3331  /**
3332   * Sets the sub-attribute value at the provided path on the
3333   * value object.  Returns the modified value object, or
3334   * undefined if the path is invalid.
3335   *
3336   * @method setValue
3337   * @static
3338   * @param o             The object on which to set the sub value.
3339   * @param path {Array}  A path array, specifying the object traversal path
3340   *                      at which to set the sub value.
3341   * @param val {Any}     The new value for the sub-attribute.
3342   * @return {Object}     The modified object, with the new sub value set, or
3343   *                      undefined, if the path was invalid.
3344   */
3345  O.setValue = function(o, path, val) {
3346      var i,
3347          p = Y.Array(path),
3348          leafIdx = p.length - 1,
3349          ref = o;
3350  
3351      if (leafIdx >= 0) {
3352          for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3353              ref = ref[p[i]];
3354          }
3355  
3356          if (ref !== UNDEFINED) {
3357              ref[p[i]] = val;
3358          } else {
3359              return UNDEFINED;
3360          }
3361      }
3362  
3363      return o;
3364  };
3365  
3366  /**
3367   * Returns `true` if the object has no enumerable properties of its own.
3368   *
3369   * @method isEmpty
3370   * @param {Object} obj An object.
3371   * @return {Boolean} `true` if the object is empty.
3372   * @static
3373   * @since 3.2.0
3374   */
3375  O.isEmpty = function (obj) {
3376      return !O.keys(Object(obj)).length;
3377  };
3378  /**
3379   * The YUI module contains the components required for building the YUI seed
3380   * file.  This includes the script loading mechanism, a simple queue, and the
3381   * core utilities for the library.
3382   * @module yui
3383   * @submodule yui-base
3384   */
3385  
3386  /**
3387   * YUI user agent detection.
3388   * Do not fork for a browser if it can be avoided.  Use feature detection when
3389   * you can.  Use the user agent as a last resort.  For all fields listed
3390   * as @type float, UA stores a version number for the browser engine,
3391   * 0 otherwise.  This value may or may not map to the version number of
3392   * the browser using the engine.  The value is presented as a float so
3393   * that it can easily be used for boolean evaluation as well as for
3394   * looking for a particular range of versions.  Because of this,
3395   * some of the granularity of the version info may be lost.  The fields that
3396   * are @type string default to null.  The API docs list the values that
3397   * these fields can have.
3398   * @class UA
3399   * @static
3400   */
3401  
3402  /**
3403  * Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
3404  * to populate `Y.UA`.
3405  *
3406  * @static
3407  * @method parseUA
3408  * @param {String} [subUA=navigator.userAgent] UA string to parse
3409  * @return {Object} The Y.UA object
3410  */
3411  YUI.Env.parseUA = function(subUA) {
3412  
3413      var numberify = function(s) {
3414              var c = 0;
3415              return parseFloat(s.replace(/\./g, function() {
3416                  return (c++ === 1) ? '' : '.';
3417              }));
3418          },
3419  
3420          win = Y.config.win,
3421  
3422          nav = win && win.navigator,
3423  
3424          o = {
3425  
3426          /**
3427           * Internet Explorer version number or 0.  Example: 6
3428           * @property ie
3429           * @type float
3430           * @static
3431           */
3432          ie: 0,
3433  
3434          /**
3435           * Opera version number or 0.  Example: 9.2
3436           * @property opera
3437           * @type float
3438           * @static
3439           */
3440          opera: 0,
3441  
3442          /**
3443           * Gecko engine revision number.  Will evaluate to 1 if Gecko
3444           * is detected but the revision could not be found. Other browsers
3445           * will be 0.  Example: 1.8
3446           * <pre>
3447           * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
3448           * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3449           * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3450           * Firefox 3.0   <-- 1.9
3451           * Firefox 3.5   <-- 1.91
3452           * </pre>
3453           * @property gecko
3454           * @type float
3455           * @static
3456           */
3457          gecko: 0,
3458  
3459          /**
3460           * AppleWebKit version.  KHTML browsers that are not WebKit browsers
3461           * will evaluate to 1, other browsers 0.  Example: 418.9
3462           * <pre>
3463           * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3464           *                                   latest available for Mac OSX 10.3.
3465           * Safari 2.0.2:         416     <-- hasOwnProperty introduced
3466           * Safari 2.0.4:         418     <-- preventDefault fixed
3467           * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3468           *                                   different versions of webkit
3469           * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
3470           *                                   updated, but not updated
3471           *                                   to the latest patch.
3472           * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
3473           * SVG and many major issues fixed).
3474           * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
3475           * update from 2.x via the 10.4.11 OS patch.
3476           * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
3477           *                                   yahoo.com user agent hack removed.
3478           * </pre>
3479           * http://en.wikipedia.org/wiki/Safari_version_history
3480           * @property webkit
3481           * @type float
3482           * @static
3483           */
3484          webkit: 0,
3485  
3486          /**
3487           * Safari will be detected as webkit, but this property will also
3488           * be populated with the Safari version number
3489           * @property safari
3490           * @type float
3491           * @static
3492           */
3493          safari: 0,
3494  
3495          /**
3496           * Chrome will be detected as webkit, but this property will also
3497           * be populated with the Chrome version number
3498           * @property chrome
3499           * @type float
3500           * @static
3501           */
3502          chrome: 0,
3503  
3504          /**
3505           * The mobile property will be set to a string containing any relevant
3506           * user agent information when a modern mobile browser is detected.
3507           * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3508           * devices with the WebKit-based browser, and Opera Mini.
3509           * @property mobile
3510           * @type string
3511           * @default null
3512           * @static
3513           */
3514          mobile: null,
3515  
3516          /**
3517           * Adobe AIR version number or 0.  Only populated if webkit is detected.
3518           * Example: 1.0
3519           * @property air
3520           * @type float
3521           */
3522          air: 0,
3523          /**
3524           * PhantomJS version number or 0.  Only populated if webkit is detected.
3525           * Example: 1.0
3526           * @property phantomjs
3527           * @type float
3528           */
3529          phantomjs: 0,
3530          /**
3531           * Detects Apple iPad's OS version
3532           * @property ipad
3533           * @type float
3534           * @static
3535           */
3536          ipad: 0,
3537          /**
3538           * Detects Apple iPhone's OS version
3539           * @property iphone
3540           * @type float
3541           * @static
3542           */
3543          iphone: 0,
3544          /**
3545           * Detects Apples iPod's OS version
3546           * @property ipod
3547           * @type float
3548           * @static
3549           */
3550          ipod: 0,
3551          /**
3552           * General truthy check for iPad, iPhone or iPod
3553           * @property ios
3554           * @type Boolean
3555           * @default null
3556           * @static
3557           */
3558          ios: null,
3559          /**
3560           * Detects Googles Android OS version
3561           * @property android
3562           * @type float
3563           * @static
3564           */
3565          android: 0,
3566          /**
3567           * Detects Kindle Silk
3568           * @property silk
3569           * @type float
3570           * @static
3571           */
3572          silk: 0,
3573          /**
3574           * Detects Ubuntu version
3575           * @property ubuntu
3576           * @type float
3577           * @static
3578           */
3579          ubuntu: 0,
3580          /**
3581           * Detects Kindle Silk Acceleration
3582           * @property accel
3583           * @type Boolean
3584           * @static
3585           */
3586          accel: false,
3587          /**
3588           * Detects Palms WebOS version
3589           * @property webos
3590           * @type float
3591           * @static
3592           */
3593          webos: 0,
3594  
3595          /**
3596           * Google Caja version number or 0.
3597           * @property caja
3598           * @type float
3599           */
3600          caja: nav && nav.cajaVersion,
3601  
3602          /**
3603           * Set to true if the page appears to be in SSL
3604           * @property secure
3605           * @type boolean
3606           * @static
3607           */
3608          secure: false,
3609  
3610          /**
3611           * The operating system.  Currently only detecting windows or macintosh
3612           * @property os
3613           * @type string
3614           * @default null
3615           * @static
3616           */
3617          os: null,
3618  
3619          /**
3620           * The Nodejs Version
3621           * @property nodejs
3622           * @type float
3623           * @default 0
3624           * @static
3625           */
3626          nodejs: 0,
3627          /**
3628          * Window8/IE10 Application host environment
3629          * @property winjs
3630          * @type Boolean
3631          * @static
3632          */
3633          winjs: !!((typeof Windows !== "undefined") && Windows.System),
3634          /**
3635          * Are touch/msPointer events available on this device
3636          * @property touchEnabled
3637          * @type Boolean
3638          * @static
3639          */
3640          touchEnabled: false
3641      },
3642  
3643      ua = subUA || nav && nav.userAgent,
3644  
3645      loc = win && win.location,
3646  
3647      href = loc && loc.href,
3648  
3649      m;
3650  
3651      /**
3652      * The User Agent string that was parsed
3653      * @property userAgent
3654      * @type String
3655      * @static
3656      */
3657      o.userAgent = ua;
3658  
3659  
3660      o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3661  
3662      if (ua) {
3663  
3664          if ((/windows|win32/i).test(ua)) {
3665              o.os = 'windows';
3666          } else if ((/macintosh|mac_powerpc/i).test(ua)) {
3667              o.os = 'macintosh';
3668          } else if ((/android/i).test(ua)) {
3669              o.os = 'android';
3670          } else if ((/symbos/i).test(ua)) {
3671              o.os = 'symbos';
3672          } else if ((/linux/i).test(ua)) {
3673              o.os = 'linux';
3674          } else if ((/rhino/i).test(ua)) {
3675              o.os = 'rhino';
3676          }
3677  
3678          // Modern KHTML browsers should qualify as Safari X-Grade
3679          if ((/KHTML/).test(ua)) {
3680              o.webkit = 1;
3681          }
3682          if ((/IEMobile|XBLWP7/).test(ua)) {
3683              o.mobile = 'windows';
3684          }
3685          if ((/Fennec/).test(ua)) {
3686              o.mobile = 'gecko';
3687          }
3688          // Modern WebKit browsers are at least X-Grade
3689          m = ua.match(/AppleWebKit\/([^\s]*)/);
3690          if (m && m[1]) {
3691              o.webkit = numberify(m[1]);
3692              o.safari = o.webkit;
3693  
3694              if (/PhantomJS/.test(ua)) {
3695                  m = ua.match(/PhantomJS\/([^\s]*)/);
3696                  if (m && m[1]) {
3697                      o.phantomjs = numberify(m[1]);
3698                  }
3699              }
3700  
3701              // Mobile browser check
3702              if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3703                  o.mobile = 'Apple'; // iPhone or iPod Touch
3704  
3705                  m = ua.match(/OS ([^\s]*)/);
3706                  if (m && m[1]) {
3707                      m = numberify(m[1].replace('_', '.'));
3708                  }
3709                  o.ios = m;
3710                  o.os = 'ios';
3711                  o.ipad = o.ipod = o.iphone = 0;
3712  
3713                  m = ua.match(/iPad|iPod|iPhone/);
3714                  if (m && m[0]) {
3715                      o[m[0].toLowerCase()] = o.ios;
3716                  }
3717              } else {
3718                  m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3719                  if (m) {
3720                      // Nokia N-series, webOS, ex: NokiaN95
3721                      o.mobile = m[0];
3722                  }
3723                  if (/webOS/.test(ua)) {
3724                      o.mobile = 'WebOS';
3725                      m = ua.match(/webOS\/([^\s]*);/);
3726                      if (m && m[1]) {
3727                          o.webos = numberify(m[1]);
3728                      }
3729                  }
3730                  if (/ Android/.test(ua)) {
3731                      if (/Mobile/.test(ua)) {
3732                          o.mobile = 'Android';
3733                      }
3734                      m = ua.match(/Android ([^\s]*);/);
3735                      if (m && m[1]) {
3736                          o.android = numberify(m[1]);
3737                      }
3738  
3739                  }
3740                  if (/Silk/.test(ua)) {
3741                      m = ua.match(/Silk\/([^\s]*)/);
3742                      if (m && m[1]) {
3743                          o.silk = numberify(m[1]);
3744                      }
3745                      if (!o.android) {
3746                          o.android = 2.34; //Hack for desktop mode in Kindle
3747                          o.os = 'Android';
3748                      }
3749                      if (/Accelerated=true/.test(ua)) {
3750                          o.accel = true;
3751                      }
3752                  }
3753              }
3754  
3755              m = ua.match(/OPR\/(\d+\.\d+)/);
3756  
3757              if (m && m[1]) {
3758                  // Opera 15+ with Blink (pretends to be both Chrome and Safari)
3759                  o.opera = numberify(m[1]);
3760              } else {
3761                  m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
3762  
3763                  if (m && m[1] && m[2]) {
3764                      o.chrome = numberify(m[2]); // Chrome
3765                      o.safari = 0; //Reset safari back to 0
3766                      if (m[1] === 'CrMo') {
3767                          o.mobile = 'chrome';
3768                      }
3769                  } else {
3770                      m = ua.match(/AdobeAIR\/([^\s]*)/);
3771                      if (m) {
3772                          o.air = m[0]; // Adobe AIR 1.0 or better
3773                      }
3774                  }
3775              }
3776          }
3777  
3778          m = ua.match(/Ubuntu\ (\d+\.\d+)/);
3779          if (m && m[1]) {
3780  
3781              o.os = 'linux';
3782              o.ubuntu = numberify(m[1]);
3783  
3784              m = ua.match(/\ WebKit\/([^\s]*)/);
3785              if (m && m[1]) {
3786                  o.webkit = numberify(m[1]);
3787              }
3788              m = ua.match(/\ Chromium\/([^\s]*)/);
3789              if (m && m[1]) {
3790                  o.chrome = numberify(m[1]);
3791              }
3792              if (/ Mobile$/.test(ua)) {
3793                  o.mobile = 'Ubuntu';
3794              }
3795          }
3796  
3797          if (!o.webkit) { // not webkit
3798  // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3799              if (/Opera/.test(ua)) {
3800                  m = ua.match(/Opera[\s\/]([^\s]*)/);
3801                  if (m && m[1]) {
3802                      o.opera = numberify(m[1]);
3803                  }
3804                  m = ua.match(/Version\/([^\s]*)/);
3805                  if (m && m[1]) {
3806                      o.opera = numberify(m[1]); // opera 10+
3807                  }
3808  
3809                  if (/Opera Mobi/.test(ua)) {
3810                      o.mobile = 'opera';
3811                      m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
3812                      if (m && m[1]) {
3813                          o.opera = numberify(m[1]);
3814                      }
3815                  }
3816                  m = ua.match(/Opera Mini[^;]*/);
3817  
3818                  if (m) {
3819                      o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3820                  }
3821              } else { // not opera or webkit
3822                  m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);
3823  
3824                  if (m && (m[1] || m[2])) {
3825                      o.ie = numberify(m[1] || m[2]);
3826                  } else { // not opera, webkit, or ie
3827                      m = ua.match(/Gecko\/([^\s]*)/);
3828  
3829                      if (m) {
3830                          o.gecko = 1; // Gecko detected, look for revision
3831                          m = ua.match(/rv:([^\s\)]*)/);
3832                          if (m && m[1]) {
3833                              o.gecko = numberify(m[1]);
3834                              if (/Mobile|Tablet/.test(ua)) {
3835                                  o.mobile = "ffos";
3836                              }
3837                          }
3838                      }
3839                  }
3840              }
3841          }
3842      }
3843  
3844      //Check for known properties to tell if touch events are enabled on this device or if
3845      //the number of MSPointer touchpoints on this device is greater than 0.
3846      if (win && nav && !(o.chrome && o.chrome < 6)) {
3847          o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
3848      }
3849  
3850      //It was a parsed UA, do not assign the global value.
3851      if (!subUA) {
3852  
3853          if (typeof process === 'object') {
3854  
3855              if (process.versions && process.versions.node) {
3856                  //NodeJS
3857                  o.os = process.platform;
3858                  o.nodejs = numberify(process.versions.node);
3859              }
3860          }
3861  
3862          YUI.Env.UA = o;
3863  
3864      }
3865  
3866      return o;
3867  };
3868  
3869  
3870  Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3871  
3872  /**
3873  Performs a simple comparison between two version numbers, accounting for
3874  standard versioning logic such as the fact that "535.8" is a lower version than
3875  "535.24", even though a simple numerical comparison would indicate that it's
3876  greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
3877  considered equivalent.
3878  
3879  Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
3880  1 if _a_ is higher than _b_.
3881  
3882  Versions may be numbers or strings containing numbers and dots. For example,
3883  both `535` and `"535.8.10"` are acceptable. A version string containing
3884  non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
3885  
3886  @method compareVersions
3887  @param {Number|String} a First version number to compare.
3888  @param {Number|String} b Second version number to compare.
3889  @return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
3890      higher than _b_.
3891  **/
3892  Y.UA.compareVersions = function (a, b) {
3893      var aPart, aParts, bPart, bParts, i, len;
3894  
3895      if (a === b) {
3896          return 0;
3897      }
3898  
3899      aParts = (a + '').split('.');
3900      bParts = (b + '').split('.');
3901  
3902      for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
3903          aPart = parseInt(aParts[i], 10);
3904          bPart = parseInt(bParts[i], 10);
3905  
3906          /*jshint expr: true*/
3907          isNaN(aPart) && (aPart = 0);
3908          isNaN(bPart) && (bPart = 0);
3909  
3910          if (aPart < bPart) {
3911              return -1;
3912          }
3913  
3914          if (aPart > bPart) {
3915              return 1;
3916          }
3917      }
3918  
3919      return 0;
3920  };
3921  YUI.Env.aliases = {
3922      "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
3923      "anim-shape-transform": ["anim-shape"],
3924      "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"],
3925      "attribute": ["attribute-base","attribute-complex"],
3926      "attribute-events": ["attribute-observable"],
3927      "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
3928      "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
3929      "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
3930      "base": ["base-base","base-pluginhost","base-build"],
3931      "cache": ["cache-base","cache-offline","cache-plugin"],
3932      "charts": ["charts-base"],
3933      "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
3934      "color": ["color-base","color-hsl","color-harmony"],
3935      "controller": ["router"],
3936      "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
3937      "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
3938      "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
3939      "datatype": ["datatype-date","datatype-number","datatype-xml"],
3940      "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
3941      "datatype-number": ["datatype-number-parse","datatype-number-format"],
3942      "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
3943      "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
3944      "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
3945      "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
3946      "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"],
3947      "event-custom": ["event-custom-base","event-custom-complex"],
3948      "event-gestures": ["event-flick","event-move"],
3949      "handlebars": ["handlebars-compiler"],
3950      "highlight": ["highlight-base","highlight-accentfold"],
3951      "history": ["history-base","history-hash","history-html5"],
3952      "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
3953      "json": ["json-parse","json-stringify"],
3954      "loader": ["loader-base","loader-rollup","loader-yui3"],
3955      "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
3956      "pluginhost": ["pluginhost-base","pluginhost-config"],
3957      "querystring": ["querystring-parse","querystring-stringify"],
3958      "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
3959      "resize": ["resize-base","resize-proxy","resize-constrain"],
3960      "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
3961      "template": ["template-base","template-micro"],
3962      "text": ["text-accentfold","text-wordbreak"],
3963      "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
3964  };
3965  
3966  
3967  }, '3.17.2', {
3968      "use": [
3969          "yui-base",
3970          "get",
3971          "features",
3972          "intl-base",
3973          "yui-log",
3974          "yui-later",
3975          "loader-base",
3976          "loader-rollup",
3977          "loader-yui3"
3978      ]
3979  });
3980  YUI.add('get', function (Y, NAME) {
3981  
3982  /*jslint boss:true, expr:true, laxbreak: true */
3983  
3984  /**
3985  Provides dynamic loading of remote JavaScript and CSS resources.
3986  
3987  @module get
3988  @class Get
3989  @static
3990  **/
3991  
3992  var Lang = Y.Lang,
3993  
3994      CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
3995  
3996      Get, Transaction;
3997  
3998  Y.Get = Get = {
3999      // -- Public Properties ----------------------------------------------------
4000  
4001      /**
4002      Default options for CSS requests. Options specified here will override
4003      global defaults for CSS requests.
4004  
4005      See the `options` property for all available options.
4006  
4007      @property cssOptions
4008      @type Object
4009      @static
4010      @since 3.5.0
4011      **/
4012      cssOptions: {
4013          attributes: {
4014              rel: 'stylesheet'
4015          },
4016  
4017          doc         : Y.config.linkDoc || Y.config.doc,
4018          pollInterval: 50
4019      },
4020  
4021      /**
4022      Default options for JS requests. Options specified here will override global
4023      defaults for JS requests.
4024  
4025      See the `options` property for all available options.
4026  
4027      @property jsOptions
4028      @type Object
4029      @static
4030      @since 3.5.0
4031      **/
4032      jsOptions: {
4033          autopurge: true,
4034          doc      : Y.config.scriptDoc || Y.config.doc
4035      },
4036  
4037      /**
4038      Default options to use for all requests.
4039  
4040      Note that while all available options are documented here for ease of
4041      discovery, some options (like callback functions) only make sense at the
4042      transaction level.
4043  
4044      Callback functions specified via the options object or the `options`
4045      parameter of the `css()`, `js()`, or `load()` methods will receive the
4046      transaction object as a parameter. See `Y.Get.Transaction` for details on
4047      the properties and methods available on transactions.
4048  
4049      @static
4050      @since 3.5.0
4051      @property {Object} options
4052  
4053      @property {Boolean} [options.async=false] Whether or not to load scripts
4054          asynchronously, meaning they're requested in parallel and execution
4055          order is not guaranteed. Has no effect on CSS, since CSS is always
4056          loaded asynchronously.
4057  
4058      @property {Object} [options.attributes] HTML attribute name/value pairs that
4059          should be added to inserted nodes. By default, the `charset` attribute
4060          will be set to "utf-8" and nodes will be given an auto-generated `id`
4061          attribute, but you can override these with your own values if desired.
4062  
4063      @property {Boolean} [options.autopurge] Whether or not to automatically
4064          purge inserted nodes after the purge threshold is reached. This is
4065          `true` by default for JavaScript, but `false` for CSS since purging a
4066          CSS node will also remove any styling applied by the referenced file.
4067  
4068      @property {Object} [options.context] `this` object to use when calling
4069          callback functions. Defaults to the transaction object.
4070  
4071      @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
4072          callbacks.
4073  
4074      @property {Document} [options.doc] Document into which nodes should be
4075          inserted. By default, the current document is used.
4076  
4077      @property {HTMLElement|String} [options.insertBefore] HTML element or id
4078          string of an element before which all generated nodes should be
4079          inserted. If not specified, Get will automatically determine the best
4080          place to insert nodes for maximum compatibility.
4081  
4082      @property {Function} [options.onEnd] Callback to execute after a transaction
4083          is complete, regardless of whether it succeeded or failed.
4084  
4085      @property {Function} [options.onFailure] Callback to execute after a
4086          transaction fails, times out, or is aborted.
4087  
4088      @property {Function} [options.onProgress] Callback to execute after each
4089          individual request in a transaction either succeeds or fails.
4090  
4091      @property {Function} [options.onSuccess] Callback to execute after a
4092          transaction completes successfully with no errors. Note that in browsers
4093          that don't support the `error` event on CSS `<link>` nodes, a failed CSS
4094          request may still be reported as a success because in these browsers
4095          it can be difficult or impossible to distinguish between success and
4096          failure for CSS resources.
4097  
4098      @property {Function} [options.onTimeout] Callback to execute after a
4099          transaction times out.
4100  
4101      @property {Number} [options.pollInterval=50] Polling interval (in
4102          milliseconds) for detecting CSS load completion in browsers that don't
4103          support the `load` event on `<link>` nodes. This isn't used for
4104          JavaScript.
4105  
4106      @property {Number} [options.purgethreshold=20] Number of nodes to insert
4107          before triggering an automatic purge when `autopurge` is `true`.
4108  
4109      @property {Number} [options.timeout] Number of milliseconds to wait before
4110          aborting a transaction. When a timeout occurs, the `onTimeout` callback
4111          is called, followed by `onFailure` and finally `onEnd`. By default,
4112          there is no timeout.
4113  
4114      @property {String} [options.type] Resource type ("css" or "js"). This option
4115          is set automatically by the `css()` and `js()` functions and will be
4116          ignored there, but may be useful when using the `load()` function. If
4117          not specified, the type will be inferred from the URL, defaulting to
4118          "js" if the URL doesn't contain a recognizable file extension.
4119      **/
4120      options: {
4121          attributes: {
4122              charset: 'utf-8'
4123          },
4124  
4125          purgethreshold: 20
4126      },
4127  
4128      // -- Protected Properties -------------------------------------------------
4129  
4130      /**
4131      Regex that matches a CSS URL. Used to guess the file type when it's not
4132      specified.
4133  
4134      @property REGEX_CSS
4135      @type RegExp
4136      @final
4137      @protected
4138      @static
4139      @since 3.5.0
4140      **/
4141      REGEX_CSS: /\.css(?:[?;].*)?$/i,
4142  
4143      /**
4144      Regex that matches a JS URL. Used to guess the file type when it's not
4145      specified.
4146  
4147      @property REGEX_JS
4148      @type RegExp
4149      @final
4150      @protected
4151      @static
4152      @since 3.5.0
4153      **/
4154      REGEX_JS : /\.js(?:[?;].*)?$/i,
4155  
4156      /**
4157      Contains information about the current environment, such as what script and
4158      link injection features it supports.
4159  
4160      This object is created and populated the first time the `_getEnv()` method
4161      is called.
4162  
4163      @property _env
4164      @type Object
4165      @protected
4166      @static
4167      @since 3.5.0
4168      **/
4169  
4170      /**
4171      Mapping of document _yuid strings to <head> or <base> node references so we
4172      don't have to look the node up each time we want to insert a request node.
4173  
4174      @property _insertCache
4175      @type Object
4176      @protected
4177      @static
4178      @since 3.5.0
4179      **/
4180      _insertCache: {},
4181  
4182      /**
4183      Information about the currently pending transaction, if any.
4184  
4185      This is actually an object with two properties: `callback`, containing the
4186      optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
4187      containing the actual transaction instance.
4188  
4189      @property _pending
4190      @type Object
4191      @protected
4192      @static
4193      @since 3.5.0
4194      **/
4195      _pending: null,
4196  
4197      /**
4198      HTML nodes eligible to be purged next time autopurge is triggered.
4199  
4200      @property _purgeNodes
4201      @type HTMLElement[]
4202      @protected
4203      @static
4204      @since 3.5.0
4205      **/
4206      _purgeNodes: [],
4207  
4208      /**
4209      Queued transactions and associated callbacks.
4210  
4211      @property _queue
4212      @type Object[]
4213      @protected
4214      @static
4215      @since 3.5.0
4216      **/
4217      _queue: [],
4218  
4219      // -- Public Methods -------------------------------------------------------
4220  
4221      /**
4222      Aborts the specified transaction.
4223  
4224      This will cause the transaction's `onFailure` callback to be called and
4225      will prevent any new script and link nodes from being added to the document,
4226      but any resources that have already been requested will continue loading
4227      (there's no safe way to prevent this, unfortunately).
4228  
4229      *Note:* This method is deprecated as of 3.5.0, and will be removed in a
4230      future version of YUI. Use the transaction-level `abort()` method instead.
4231  
4232      @method abort
4233      @param {Get.Transaction} transaction Transaction to abort.
4234      @deprecated Use the `abort()` method on the transaction instead.
4235      @static
4236      **/
4237      abort: function (transaction) {
4238          var i, id, item, len, pending;
4239  
4240  
4241          if (!transaction.abort) {
4242              id          = transaction;
4243              pending     = this._pending;
4244              transaction = null;
4245  
4246              if (pending && pending.transaction.id === id) {
4247                  transaction   = pending.transaction;
4248                  this._pending = null;
4249              } else {
4250                  for (i = 0, len = this._queue.length; i < len; ++i) {
4251                      item = this._queue[i].transaction;
4252  
4253                      if (item.id === id) {
4254                          transaction = item;
4255                          this._queue.splice(i, 1);
4256                          break;
4257                      }
4258                  }
4259              }
4260          }
4261  
4262          transaction && transaction.abort();
4263      },
4264  
4265      /**
4266      Loads one or more CSS files.
4267  
4268      The _urls_ parameter may be provided as a URL string, a request object,
4269      or an array of URL strings and/or request objects.
4270  
4271      A request object is just an object that contains a `url` property and zero
4272      or more options that should apply specifically to that request.
4273      Request-specific options take priority over transaction-level options and
4274      default options.
4275  
4276      URLs may be relative or absolute, and do not have to have the same origin
4277      as the current page.
4278  
4279      The `options` parameter may be omitted completely and a callback passed in
4280      its place, if desired.
4281  
4282      @example
4283  
4284          // Load a single CSS file and log a message on completion.
4285          Y.Get.css('foo.css', function (err) {
4286              if (err) {
4287              } else {
4288              }
4289          });
4290  
4291          // Load multiple CSS files and log a message when all have finished
4292          // loading.
4293          var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
4294  
4295          Y.Get.css(urls, function (err) {
4296              if (err) {
4297              } else {
4298              }
4299          });
4300  
4301          // Specify transaction-level options, which will apply to all requests
4302          // within the transaction.
4303          Y.Get.css(urls, {
4304              attributes: {'class': 'my-css'},
4305              timeout   : 5000
4306          });
4307  
4308          // Specify per-request options, which override transaction-level and
4309          // default options.
4310          Y.Get.css([
4311              {url: 'foo.css', attributes: {id: 'foo'}},
4312              {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4313          ]);
4314  
4315      @method css
4316      @param {String|Object|Array} urls URL string, request object, or array
4317          of URLs and/or request objects to load.
4318      @param {Object} [options] Options for this transaction. See the
4319          `Y.Get.options` property for a complete list of available options.
4320      @param {Function} [callback] Callback function to be called on completion.
4321          This is a general callback and will be called before any more granular
4322          callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4323          object.
4324  
4325          @param {Array|null} callback.err Array of errors that occurred during
4326              the transaction, or `null` on success.
4327          @param {Get.Transaction} callback.transaction Transaction object.
4328  
4329      @return {Get.Transaction} Transaction object.
4330      @static
4331      **/
4332      css: function (urls, options, callback) {
4333          return this._load('css', urls, options, callback);
4334      },
4335  
4336      /**
4337      Loads one or more JavaScript resources.
4338  
4339      The _urls_ parameter may be provided as a URL string, a request object,
4340      or an array of URL strings and/or request objects.
4341  
4342      A request object is just an object that contains a `url` property and zero
4343      or more options that should apply specifically to that request.
4344      Request-specific options take priority over transaction-level options and
4345      default options.
4346  
4347      URLs may be relative or absolute, and do not have to have the same origin
4348      as the current page.
4349  
4350      The `options` parameter may be omitted completely and a callback passed in
4351      its place, if desired.
4352  
4353      Scripts will be executed in the order they're specified unless the `async`
4354      option is `true`, in which case they'll be loaded in parallel and executed
4355      in whatever order they finish loading.
4356  
4357      @example
4358  
4359          // Load a single JS file and log a message on completion.
4360          Y.Get.js('foo.js', function (err) {
4361              if (err) {
4362              } else {
4363              }
4364          });
4365  
4366          // Load multiple JS files, execute them in order, and log a message when
4367          // all have finished loading.
4368          var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4369  
4370          Y.Get.js(urls, function (err) {
4371              if (err) {
4372              } else {
4373              }
4374          });
4375  
4376          // Specify transaction-level options, which will apply to all requests
4377          // within the transaction.
4378          Y.Get.js(urls, {
4379              attributes: {'class': 'my-js'},
4380              timeout   : 5000
4381          });
4382  
4383          // Specify per-request options, which override transaction-level and
4384          // default options.
4385          Y.Get.js([
4386              {url: 'foo.js', attributes: {id: 'foo'}},
4387              {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4388          ]);
4389  
4390      @method js
4391      @param {String|Object|Array} urls URL string, request object, or array
4392          of URLs and/or request objects to load.
4393      @param {Object} [options] Options for this transaction. See the
4394          `Y.Get.options` property for a complete list of available options.
4395      @param {Function} [callback] Callback function to be called on completion.
4396          This is a general callback and will be called before any more granular
4397          callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4398          object.
4399  
4400          @param {Array|null} callback.err Array of errors that occurred during
4401              the transaction, or `null` on success.
4402          @param {Get.Transaction} callback.transaction Transaction object.
4403  
4404      @return {Get.Transaction} Transaction object.
4405      @since 3.5.0
4406      @static
4407      **/
4408      js: function (urls, options, callback) {
4409          return this._load('js', urls, options, callback);
4410      },
4411  
4412      /**
4413      Loads one or more CSS and/or JavaScript resources in the same transaction.
4414  
4415      Use this method when you want to load both CSS and JavaScript in a single
4416      transaction and be notified when all requested URLs have finished loading,
4417      regardless of type.
4418  
4419      Behavior and options are the same as for the `css()` and `js()` methods. If
4420      a resource type isn't specified in per-request options or transaction-level
4421      options, Get will guess the file type based on the URL's extension (`.css`
4422      or `.js`, with or without a following query string). If the file type can't
4423      be guessed from the URL, a warning will be logged and Get will assume the
4424      URL is a JavaScript resource.
4425  
4426      @example
4427  
4428          // Load both CSS and JS files in a single transaction, and log a message
4429          // when all files have finished loading.
4430          Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4431              if (err) {
4432              } else {
4433              }
4434          });
4435  
4436      @method load
4437      @param {String|Object|Array} urls URL string, request object, or array
4438          of URLs and/or request objects to load.
4439      @param {Object} [options] Options for this transaction. See the
4440          `Y.Get.options` property for a complete list of available options.
4441      @param {Function} [callback] Callback function to be called on completion.
4442          This is a general callback and will be called before any more granular
4443          callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4444          object.
4445  
4446          @param {Array|null} err Array of errors that occurred during the
4447              transaction, or `null` on success.
4448          @param {Get.Transaction} Transaction object.
4449  
4450      @return {Get.Transaction} Transaction object.
4451      @since 3.5.0
4452      @static
4453      **/
4454      load: function (urls, options, callback) {
4455          return this._load(null, urls, options, callback);
4456      },
4457  
4458      // -- Protected Methods ----------------------------------------------------
4459  
4460      /**
4461      Triggers an automatic purge if the purge threshold has been reached.
4462  
4463      @method _autoPurge
4464      @param {Number} threshold Purge threshold to use, in milliseconds.
4465      @protected
4466      @since 3.5.0
4467      @static
4468      **/
4469      _autoPurge: function (threshold) {
4470          if (threshold && this._purgeNodes.length >= threshold) {
4471              this._purge(this._purgeNodes);
4472          }
4473      },
4474  
4475      /**
4476      Populates the `_env` property with information about the current
4477      environment.
4478  
4479      @method _getEnv
4480      @return {Object} Environment information.
4481      @protected
4482      @since 3.5.0
4483      @static
4484      **/
4485      _getEnv: function () {
4486          var doc = Y.config.doc,
4487              ua  = Y.UA;
4488  
4489          // Note: some of these checks require browser sniffs since it's not
4490          // feasible to load test files on every pageview just to perform a
4491          // feature test. I'm sorry if this makes you sad.
4492          return (this._env = {
4493  
4494              // True if this is a browser that supports disabling async mode on
4495              // dynamically created script nodes. See
4496              // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4497  
4498              // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4499              // because it is async by default, and allows you to disable async by setting it to false
4500              async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4501  
4502              // True if this browser fires an event when a dynamically injected
4503              // link node fails to load. This is currently true for Firefox 9+
4504              // and WebKit 535.24+
4505              cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4506  
4507              // True if this browser fires an event when a dynamically injected
4508              // link node finishes loading. This is currently true for IE, Opera,
4509              // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4510              // DOM 0 "onload" event, but not "load". All versions of IE fire
4511              // "onload".
4512              // davglass: Seems that Chrome on Android needs this to be false.
4513              cssLoad: (
4514                      (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4515                      ua.compareVersions(ua.webkit, 535.24) >= 0
4516                  ) && !(ua.chrome && ua.chrome <= 18),
4517  
4518              // True if this browser preserves script execution order while
4519              // loading scripts in parallel as long as the script node's `async`
4520              // attribute is set to false to explicitly disable async execution.
4521              preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4522          });
4523      },
4524  
4525      _getTransaction: function (urls, options) {
4526          var requests = [],
4527              i, len, req, url;
4528  
4529          if (!Lang.isArray(urls)) {
4530              urls = [urls];
4531          }
4532  
4533          options = Y.merge(this.options, options);
4534  
4535          // Clone the attributes object so we don't end up modifying it by ref.
4536          options.attributes = Y.merge(this.options.attributes,
4537                  options.attributes);
4538  
4539          for (i = 0, len = urls.length; i < len; ++i) {
4540              url = urls[i];
4541              req = {attributes: {}};
4542  
4543              // If `url` is a string, we create a URL object for it, then mix in
4544              // global options and request-specific options. If it's an object
4545              // with a "url" property, we assume it's a request object containing
4546              // URL-specific options.
4547              if (typeof url === 'string') {
4548                  req.url = url;
4549              } else if (url.url) {
4550                  // URL-specific options override both global defaults and
4551                  // request-specific options.
4552                  Y.mix(req, url, false, null, 0, true);
4553                  url = url.url; // Make url a string so we can use it later.
4554              } else {
4555                  continue;
4556              }
4557  
4558              Y.mix(req, options, false, null, 0, true);
4559  
4560              // If we didn't get an explicit type for this URL either in the
4561              // request options or the URL-specific options, try to determine
4562              // one from the file extension.
4563              if (!req.type) {
4564                  if (this.REGEX_CSS.test(url)) {
4565                      req.type = 'css';
4566                  } else {
4567                      if (!this.REGEX_JS.test(url)) {
4568                      }
4569  
4570                      req.type = 'js';
4571                  }
4572              }
4573  
4574              // Mix in type-specific default options, but don't overwrite any
4575              // options that have already been set.
4576              Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4577                  false, null, 0, true);
4578  
4579              // Give the node an id attribute if it doesn't already have one.
4580              req.attributes.id || (req.attributes.id = Y.guid());
4581  
4582              // Backcompat for <3.5.0 behavior.
4583              if (req.win) {
4584                  req.doc = req.win.document;
4585              } else {
4586                  req.win = req.doc.defaultView || req.doc.parentWindow;
4587              }
4588  
4589              if (req.charset) {
4590                  req.attributes.charset = req.charset;
4591              }
4592  
4593              requests.push(req);
4594          }
4595  
4596          return new Transaction(requests, options);
4597      },
4598  
4599      _load: function (type, urls, options, callback) {
4600          var transaction;
4601  
4602          // Allow callback as third param.
4603          if (typeof options === 'function') {
4604              callback = options;
4605              options  = {};
4606          }
4607  
4608          options || (options = {});
4609          options.type = type;
4610  
4611          options._onFinish = Get._onTransactionFinish;
4612  
4613          if (!this._env) {
4614              this._getEnv();
4615          }
4616  
4617          transaction = this._getTransaction(urls, options);
4618  
4619          this._queue.push({
4620              callback   : callback,
4621              transaction: transaction
4622          });
4623  
4624          this._next();
4625  
4626          return transaction;
4627      },
4628  
4629      _onTransactionFinish : function() {
4630          Get._pending = null;
4631          Get._next();
4632      },
4633  
4634      _next: function () {
4635          var item;
4636  
4637          if (this._pending) {
4638              return;
4639          }
4640  
4641          item = this._queue.shift();
4642  
4643          if (item) {
4644              this._pending = item;
4645              item.transaction.execute(item.callback);
4646          }
4647      },
4648  
4649      _purge: function (nodes) {
4650          var purgeNodes    = this._purgeNodes,
4651              isTransaction = nodes !== purgeNodes,
4652              index, node;
4653  
4654          while (node = nodes.pop()) { // assignment
4655              // Don't purge nodes that haven't finished loading (or errored out),
4656              // since this can hang the transaction.
4657              if (!node._yuiget_finished) {
4658                  continue;
4659              }
4660  
4661              node.parentNode && node.parentNode.removeChild(node);
4662  
4663              // If this is a transaction-level purge and this node also exists in
4664              // the Get-level _purgeNodes array, we need to remove it from
4665              // _purgeNodes to avoid creating a memory leak. The indexOf lookup
4666              // sucks, but until we get WeakMaps, this is the least troublesome
4667              // way to do this (we can't just hold onto node ids because they may
4668              // not be in the same document).
4669              if (isTransaction) {
4670                  index = Y.Array.indexOf(purgeNodes, node);
4671  
4672                  if (index > -1) {
4673                      purgeNodes.splice(index, 1);
4674                  }
4675              }
4676          }
4677      }
4678  };
4679  
4680  /**
4681  Alias for `js()`.
4682  
4683  @method script
4684  @static
4685  **/
4686  Get.script = Get.js;
4687  
4688  /**
4689  Represents a Get transaction, which may contain requests for one or more JS or
4690  CSS files.
4691  
4692  This class should not be instantiated manually. Instances will be created and
4693  returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4694  
4695  @class Get.Transaction
4696  @constructor
4697  @since 3.5.0
4698  **/
4699  Get.Transaction = Transaction = function (requests, options) {
4700      var self = this;
4701  
4702      self.id       = Transaction._lastId += 1;
4703      self.data     = options.data;
4704      self.errors   = [];
4705      self.nodes    = [];
4706      self.options  = options;
4707      self.requests = requests;
4708  
4709      self._callbacks = []; // callbacks to call after execution finishes
4710      self._queue     = [];
4711      self._reqsWaiting   = 0;
4712  
4713      // Deprecated pre-3.5.0 properties.
4714      self.tId = self.id; // Use `id` instead.
4715      self.win = options.win || Y.config.win;
4716  };
4717  
4718  /**
4719  Arbitrary data object associated with this transaction.
4720  
4721  This object comes from the options passed to `Get.css()`, `Get.js()`, or
4722  `Get.load()`, and will be `undefined` if no data object was specified.
4723  
4724  @property {Object} data
4725  **/
4726  
4727  /**
4728  Array of errors that have occurred during this transaction, if any. Each error
4729  object has the following properties:
4730  `errors.error`: Error message.
4731  `errors.request`: Request object related to the error.
4732  
4733  @since 3.5.0
4734  @property {Object[]} errors
4735  **/
4736  
4737  /**
4738  Numeric id for this transaction, unique among all transactions within the same
4739  YUI sandbox in the current pageview.
4740  
4741  @property {Number} id
4742  @since 3.5.0
4743  **/
4744  
4745  /**
4746  HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
4747  during the current transaction.
4748  
4749  @property {HTMLElement[]} nodes
4750  **/
4751  
4752  /**
4753  Options associated with this transaction.
4754  
4755  See `Get.options` for the full list of available options.
4756  
4757  @property {Object} options
4758  @since 3.5.0
4759  **/
4760  
4761  /**
4762  Request objects contained in this transaction. Each request object represents
4763  one CSS or JS URL that will be (or has been) requested and loaded into the page.
4764  
4765  @property {Object} requests
4766  @since 3.5.0
4767  **/
4768  
4769  /**
4770  Id of the most recent transaction.
4771  
4772  @property _lastId
4773  @type Number
4774  @protected
4775  @static
4776  **/
4777  Transaction._lastId = 0;
4778  
4779  Transaction.prototype = {
4780      // -- Public Properties ----------------------------------------------------
4781  
4782      /**
4783      Current state of this transaction. One of "new", "executing", or "done".
4784  
4785      @property _state
4786      @type String
4787      @protected
4788      **/
4789      _state: 'new', // "new", "executing", or "done"
4790  
4791      // -- Public Methods -------------------------------------------------------
4792  
4793      /**
4794      Aborts this transaction.
4795  
4796      This will cause the transaction's `onFailure` callback to be called and
4797      will prevent any new script and link nodes from being added to the document,
4798      but any resources that have already been requested will continue loading
4799      (there's no safe way to prevent this, unfortunately).
4800  
4801      @method abort
4802      @param {String} [msg="Aborted."] Optional message to use in the `errors`
4803          array describing why the transaction was aborted.
4804      **/
4805      abort: function (msg) {
4806          this._pending    = null;
4807          this._pendingCSS = null;
4808          this._pollTimer  = clearTimeout(this._pollTimer);
4809          this._queue      = [];
4810          this._reqsWaiting    = 0;
4811  
4812          this.errors.push({error: msg || 'Aborted'});
4813          this._finish();
4814      },
4815  
4816      /**
4817      Begins execting the transaction.
4818  
4819      There's usually no reason to call this manually, since Get will call it
4820      automatically when other pending transactions have finished. If you really
4821      want to execute your transaction before Get does, you can, but be aware that
4822      this transaction's scripts may end up executing before the scripts in other
4823      pending transactions.
4824  
4825      If the transaction is already executing, the specified callback (if any)
4826      will be queued and called after execution finishes. If the transaction has
4827      already finished, the callback will be called immediately (the transaction
4828      will not be executed again).
4829  
4830      @method execute
4831      @param {Function} callback Callback function to execute after all requests
4832          in the transaction are complete, or after the transaction is aborted.
4833      **/
4834      execute: function (callback) {
4835          var self     = this,
4836              requests = self.requests,
4837              state    = self._state,
4838              i, len, queue, req;
4839  
4840          if (state === 'done') {
4841              callback && callback(self.errors.length ? self.errors : null, self);
4842              return;
4843          } else {
4844              callback && self._callbacks.push(callback);
4845  
4846              if (state === 'executing') {
4847                  return;
4848              }
4849          }
4850  
4851          self._state = 'executing';
4852          self._queue = queue = [];
4853  
4854          if (self.options.timeout) {
4855              self._timeout = setTimeout(function () {
4856                  self.abort('Timeout');
4857              }, self.options.timeout);
4858          }
4859  
4860          self._reqsWaiting = requests.length;
4861  
4862          for (i = 0, len = requests.length; i < len; ++i) {
4863              req = requests[i];
4864  
4865              if (req.async || req.type === 'css') {
4866                  // No need to queue CSS or fully async JS.
4867                  self._insert(req);
4868              } else {
4869                  queue.push(req);
4870              }
4871          }
4872  
4873          self._next();
4874      },
4875  
4876      /**
4877      Manually purges any `<script>` or `<link>` nodes this transaction has
4878      created.
4879  
4880      Be careful when purging a transaction that contains CSS requests, since
4881      removing `<link>` nodes will also remove any styles they applied.
4882  
4883      @method purge
4884      **/
4885      purge: function () {
4886          Get._purge(this.nodes);
4887      },
4888  
4889      // -- Protected Methods ----------------------------------------------------
4890      _createNode: function (name, attrs, doc) {
4891          var node = doc.createElement(name),
4892              attr, testEl;
4893  
4894          if (!CUSTOM_ATTRS) {
4895              // IE6 and IE7 expect property names rather than attribute names for
4896              // certain attributes. Rather than sniffing, we do a quick feature
4897              // test the first time _createNode() runs to determine whether we
4898              // need to provide a workaround.
4899              testEl = doc.createElement('div');
4900              testEl.setAttribute('class', 'a');
4901  
4902              CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
4903                  'for'  : 'htmlFor',
4904                  'class': 'className'
4905              };
4906          }
4907  
4908          for (attr in attrs) {
4909              if (attrs.hasOwnProperty(attr)) {
4910                  node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
4911              }
4912          }
4913  
4914          return node;
4915      },
4916  
4917      _finish: function () {
4918          var errors  = this.errors.length ? this.errors : null,
4919              options = this.options,
4920              thisObj = options.context || this,
4921              data, i, len;
4922  
4923          if (this._state === 'done') {
4924              return;
4925          }
4926  
4927          this._state = 'done';
4928  
4929          for (i = 0, len = this._callbacks.length; i < len; ++i) {
4930              this._callbacks[i].call(thisObj, errors, this);
4931          }
4932  
4933          data = this._getEventData();
4934  
4935          if (errors) {
4936              if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
4937                  options.onTimeout.call(thisObj, data);
4938              }
4939  
4940              if (options.onFailure) {
4941                  options.onFailure.call(thisObj, data);
4942              }
4943          } else if (options.onSuccess) {
4944              options.onSuccess.call(thisObj, data);
4945          }
4946  
4947          if (options.onEnd) {
4948              options.onEnd.call(thisObj, data);
4949          }
4950  
4951          if (options._onFinish) {
4952              options._onFinish();
4953          }
4954      },
4955  
4956      _getEventData: function (req) {
4957          if (req) {
4958              // This merge is necessary for backcompat. I hate it.
4959              return Y.merge(this, {
4960                  abort  : this.abort, // have to copy these because the prototype isn't preserved
4961                  purge  : this.purge,
4962                  request: req,
4963                  url    : req.url,
4964                  win    : req.win
4965              });
4966          } else {
4967              return this;
4968          }
4969      },
4970  
4971      _getInsertBefore: function (req) {
4972          var doc = req.doc,
4973              el  = req.insertBefore,
4974              cache, docStamp;
4975  
4976          if (el) {
4977              return typeof el === 'string' ? doc.getElementById(el) : el;
4978          }
4979  
4980          cache    = Get._insertCache;
4981          docStamp = Y.stamp(doc);
4982  
4983          if ((el = cache[docStamp])) { // assignment
4984              return el;
4985          }
4986  
4987          // Inserting before a <base> tag apparently works around an IE bug
4988          // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
4989          // bug that is, exactly. Better safe than sorry?
4990          if ((el = doc.getElementsByTagName('base')[0])) { // assignment
4991              return (cache[docStamp] = el);
4992          }
4993  
4994          // Look for a <head> element.
4995          el = doc.head || doc.getElementsByTagName('head')[0];
4996  
4997          if (el) {
4998              // Create a marker node at the end of <head> to use as an insertion
4999              // point. Inserting before this node will ensure that all our CSS
5000              // gets inserted in the correct order, to maintain style precedence.
5001              el.appendChild(doc.createTextNode(''));
5002              return (cache[docStamp] = el.lastChild);
5003          }
5004  
5005          // If all else fails, just insert before the first script node on the
5006          // page, which is virtually guaranteed to exist.
5007          return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
5008      },
5009  
5010      _insert: function (req) {
5011          var env          = Get._env,
5012              insertBefore = this._getInsertBefore(req),
5013              isScript     = req.type === 'js',
5014              node         = req.node,
5015              self         = this,
5016              ua           = Y.UA,
5017              cssTimeout, nodeType;
5018  
5019          if (!node) {
5020              if (isScript) {
5021                  nodeType = 'script';
5022              } else if (!env.cssLoad && ua.gecko) {
5023                  nodeType = 'style';
5024              } else {
5025                  nodeType = 'link';
5026              }
5027  
5028              node = req.node = this._createNode(nodeType, req.attributes,
5029                  req.doc);
5030          }
5031  
5032          function onError() {
5033              self._progress('Failed to load ' + req.url, req);
5034          }
5035  
5036          function onLoad() {
5037              if (cssTimeout) {
5038                  clearTimeout(cssTimeout);
5039              }
5040  
5041              self._progress(null, req);
5042          }
5043  
5044          // Deal with script asynchronicity.
5045          if (isScript) {
5046              node.setAttribute('src', req.url);
5047  
5048              if (req.async) {
5049                  // Explicitly indicate that we want the browser to execute this
5050                  // script asynchronously. This is necessary for older browsers
5051                  // like Firefox <4.
5052                  node.async = true;
5053              } else {
5054                  if (env.async) {
5055                      // This browser treats injected scripts as async by default
5056                      // (standard HTML5 behavior) but asynchronous loading isn't
5057                      // desired, so tell the browser not to mark this script as
5058                      // async.
5059                      node.async = false;
5060                  }
5061  
5062                  // If this browser doesn't preserve script execution order based
5063                  // on insertion order, we'll need to avoid inserting other
5064                  // scripts until this one finishes loading.
5065                  if (!env.preservesScriptOrder) {
5066                      this._pending = req;
5067                  }
5068              }
5069          } else {
5070              if (!env.cssLoad && ua.gecko) {
5071                  // In Firefox <9, we can import the requested URL into a <style>
5072                  // node and poll for the existence of node.sheet.cssRules. This
5073                  // gives us a reliable way to determine CSS load completion that
5074                  // also works for cross-domain stylesheets.
5075                  //
5076                  // Props to Zach Leatherman for calling my attention to this
5077                  // technique.
5078                  node.innerHTML = (req.attributes.charset ?
5079                      '@charset "' + req.attributes.charset + '";' : '') +
5080                      '@import "' + req.url + '";';
5081              } else {
5082                  node.setAttribute('href', req.url);
5083              }
5084          }
5085  
5086          // Inject the node.
5087          if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
5088              // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
5089              node.onreadystatechange = function () {
5090                  if (/loaded|complete/.test(node.readyState)) {
5091                      node.onreadystatechange = null;
5092                      onLoad();
5093                  }
5094              };
5095          } else if (!isScript && !env.cssLoad) {
5096              // CSS on Firefox <9 or WebKit.
5097              this._poll(req);
5098          } else {
5099              // Script or CSS on everything else. Using DOM 0 events because that
5100              // evens the playing field with older IEs.
5101  
5102              if (ua.ie >= 10) {
5103  
5104                  // We currently need to introduce a timeout for IE10, since it
5105                  // calls onerror/onload synchronously for 304s - messing up existing
5106                  // program flow.
5107  
5108                  // Remove this block if the following bug gets fixed by GA
5109                  /*jshint maxlen: 1500 */
5110                  // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
5111                  node.onerror = function() { setTimeout(onError, 0); };
5112                  node.onload  = function() { setTimeout(onLoad, 0); };
5113              } else {
5114                  node.onerror = onError;
5115                  node.onload  = onLoad;
5116              }
5117  
5118              // If this browser doesn't fire an event when CSS fails to load,
5119              // fail after a timeout to avoid blocking the transaction queue.
5120              if (!env.cssFail && !isScript) {
5121                  cssTimeout = setTimeout(onError, req.timeout || 3000);
5122              }
5123          }
5124  
5125          this.nodes.push(node);
5126          insertBefore.parentNode.insertBefore(node, insertBefore);
5127      },
5128  
5129      _next: function () {
5130          if (this._pending) {
5131              return;
5132          }
5133  
5134          // If there are requests in the queue, insert the next queued request.
5135          // Otherwise, if we're waiting on already-inserted requests to finish,
5136          // wait longer. If there are no queued requests and we're not waiting
5137          // for anything to load, then we're done!
5138          if (this._queue.length) {
5139              this._insert(this._queue.shift());
5140          } else if (!this._reqsWaiting) {
5141              this._finish();
5142          }
5143      },
5144  
5145      _poll: function (newReq) {
5146          var self       = this,
5147              pendingCSS = self._pendingCSS,
5148              isWebKit   = Y.UA.webkit,
5149              i, hasRules, j, nodeHref, req, sheets;
5150  
5151          if (newReq) {
5152              pendingCSS || (pendingCSS = self._pendingCSS = []);
5153              pendingCSS.push(newReq);
5154  
5155              if (self._pollTimer) {
5156                  // A poll timeout is already pending, so no need to create a
5157                  // new one.
5158                  return;
5159              }
5160          }
5161  
5162          self._pollTimer = null;
5163  
5164          // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
5165          // will still be treated as a success. There's no good workaround for
5166          // this.
5167  
5168          for (i = 0; i < pendingCSS.length; ++i) {
5169              req = pendingCSS[i];
5170  
5171              if (isWebKit) {
5172                  // Look for a stylesheet matching the pending URL.
5173                  sheets   = req.doc.styleSheets;
5174                  j        = sheets.length;
5175                  nodeHref = req.node.href;
5176  
5177                  while (--j >= 0) {
5178                      if (sheets[j].href === nodeHref) {
5179                          pendingCSS.splice(i, 1);
5180                          i -= 1;
5181                          self._progress(null, req);
5182                          break;
5183                      }
5184                  }
5185              } else {
5186                  // Many thanks to Zach Leatherman for calling my attention to
5187                  // the @import-based cross-domain technique used here, and to
5188                  // Oleg Slobodskoi for an earlier same-domain implementation.
5189                  //
5190                  // See Zach's blog for more details:
5191                  // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
5192                  try {
5193                      // We don't really need to store this value since we never
5194                      // use it again, but if we don't store it, Closure Compiler
5195                      // assumes the code is useless and removes it.
5196                      hasRules = !!req.node.sheet.cssRules;
5197  
5198                      // If we get here, the stylesheet has loaded.
5199                      pendingCSS.splice(i, 1);
5200                      i -= 1;
5201                      self._progress(null, req);
5202                  } catch (ex) {
5203                      // An exception means the stylesheet is still loading.
5204                  }
5205              }
5206          }
5207  
5208          if (pendingCSS.length) {
5209              self._pollTimer = setTimeout(function () {
5210                  self._poll.call(self);
5211              }, self.options.pollInterval);
5212          }
5213      },
5214  
5215      _progress: function (err, req) {
5216          var options = this.options;
5217  
5218          if (err) {
5219              req.error = err;
5220  
5221              this.errors.push({
5222                  error  : err,
5223                  request: req
5224              });
5225  
5226          }
5227  
5228          req.node._yuiget_finished = req.finished = true;
5229  
5230          if (options.onProgress) {
5231              options.onProgress.call(options.context || this,
5232                  this._getEventData(req));
5233          }
5234  
5235          if (req.autopurge) {
5236              // Pre-3.5.0 Get always excludes the most recent node from an
5237              // autopurge. I find this odd, but I'm keeping that behavior for
5238              // the sake of backcompat.
5239              Get._autoPurge(this.options.purgethreshold);
5240              Get._purgeNodes.push(req.node);
5241          }
5242  
5243          if (this._pending === req) {
5244              this._pending = null;
5245          }
5246  
5247          this._reqsWaiting -= 1;
5248  
5249          this._next();
5250      }
5251  };
5252  
5253  
5254  }, '3.17.2', {"requires": ["yui-base"]});
5255  YUI.add('features', function (Y, NAME) {
5256  
5257  var feature_tests = {};
5258  
5259  /**
5260  Contains the core of YUI's feature test architecture.
5261  @module features
5262  */
5263  
5264  /**
5265  * Feature detection
5266  * @class Features
5267  * @static
5268  */
5269  
5270  Y.mix(Y.namespace('Features'), {
5271  
5272      /**
5273      * Object hash of all registered feature tests
5274      * @property tests
5275      * @type Object
5276      */
5277      tests: feature_tests,
5278  
5279      /**
5280      * Add a test to the system
5281      *
5282      *   ```
5283      *   Y.Features.add("load", "1", {});
5284      *   ```
5285      *
5286      * @method add
5287      * @param {String} cat The category, right now only 'load' is supported
5288      * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
5289      * @param {Object} o Object containing test properties
5290      * @param {String} o.name The name of the test
5291      * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
5292      * @param {String} o.trigger The module that triggers this test.
5293      */
5294      add: function(cat, name, o) {
5295          feature_tests[cat] = feature_tests[cat] || {};
5296          feature_tests[cat][name] = o;
5297      },
5298      /**
5299      * Execute all tests of a given category and return the serialized results
5300      *
5301      *   ```
5302      *   caps=1:1;2:1;3:0
5303      *   ```
5304      * @method all
5305      * @param {String} cat The category to execute
5306      * @param {Array} args The arguments to pass to the test function
5307      * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
5308      */
5309      all: function(cat, args) {
5310          var cat_o = feature_tests[cat],
5311              // results = {};
5312              result = [];
5313          if (cat_o) {
5314              Y.Object.each(cat_o, function(v, k) {
5315                  result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
5316              });
5317          }
5318  
5319          return (result.length) ? result.join(';') : '';
5320      },
5321      /**
5322      * Run a specific test and return a Boolean response.
5323      *
5324      *   ```
5325      *   Y.Features.test("load", "1");
5326      *   ```
5327      *
5328      * @method test
5329      * @param {String} cat The category of the test to run
5330      * @param {String} name The name of the test to run
5331      * @param {Array} args The arguments to pass to the test function
5332      * @return {Boolean} True or false if the test passed/failed.
5333      */
5334      test: function(cat, name, args) {
5335          args = args || [];
5336          var result, ua, test,
5337              cat_o = feature_tests[cat],
5338              feature = cat_o && cat_o[name];
5339  
5340          if (!feature) {
5341          } else {
5342  
5343              result = feature.result;
5344  
5345              if (Y.Lang.isUndefined(result)) {
5346  
5347                  ua = feature.ua;
5348                  if (ua) {
5349                      result = (Y.UA[ua]);
5350                  }
5351  
5352                  test = feature.test;
5353                  if (test && ((!ua) || result)) {
5354                      result = test.apply(Y, args);
5355                  }
5356  
5357                  feature.result = result;
5358              }
5359          }
5360  
5361          return result;
5362      }
5363  });
5364  
5365  // Y.Features.add("load", "1", {});
5366  // Y.Features.test("load", "1");
5367  // caps=1:1;2:0;3:1;
5368  
5369  /* This file is auto-generated by (yogi.js loader --mix --yes) */
5370  /*jshint maxlen:900, eqeqeq: false */
5371  var add = Y.Features.add;
5372  // app-transitions-native
5373  add('load', '0', {
5374      "name": "app-transitions-native",
5375      "test": function (Y) {
5376      var doc  = Y.config.doc,
5377          node = doc ? doc.documentElement : null;
5378  
5379      if (node && node.style) {
5380          return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5381      }
5382  
5383      return false;
5384  },
5385      "trigger": "app-transitions"
5386  });
5387  // autocomplete-list-keys
5388  add('load', '1', {
5389      "name": "autocomplete-list-keys",
5390      "test": function (Y) {
5391      // Only add keyboard support to autocomplete-list if this doesn't appear to
5392      // be an iOS or Android-based mobile device.
5393      //
5394      // There's currently no feasible way to actually detect whether a device has
5395      // a hardware keyboard, so this sniff will have to do. It can easily be
5396      // overridden by manually loading the autocomplete-list-keys module.
5397      //
5398      // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5399      // doesn't fire the keyboard events used by AutoCompleteList, so there's
5400      // no point loading the -keys module even when a bluetooth keyboard may be
5401      // available.
5402      return !(Y.UA.ios || Y.UA.android);
5403  },
5404      "trigger": "autocomplete-list"
5405  });
5406  // dd-gestures
5407  add('load', '2', {
5408      "name": "dd-gestures",
5409      "trigger": "dd-drag",
5410      "ua": "touchEnabled"
5411  });
5412  // dom-style-ie
5413  add('load', '3', {
5414      "name": "dom-style-ie",
5415      "test": function (Y) {
5416  
5417      var testFeature = Y.Features.test,
5418          addFeature = Y.Features.add,
5419          WINDOW = Y.config.win,
5420          DOCUMENT = Y.config.doc,
5421          DOCUMENT_ELEMENT = 'documentElement',
5422          ret = false;
5423  
5424      addFeature('style', 'computedStyle', {
5425          test: function() {
5426              return WINDOW && 'getComputedStyle' in WINDOW;
5427          }
5428      });
5429  
5430      addFeature('style', 'opacity', {
5431          test: function() {
5432              return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5433          }
5434      });
5435  
5436      ret =  (!testFeature('style', 'opacity') &&
5437              !testFeature('style', 'computedStyle'));
5438  
5439      return ret;
5440  },
5441      "trigger": "dom-style"
5442  });
5443  // editor-para-ie
5444  add('load', '4', {
5445      "name": "editor-para-ie",
5446      "trigger": "editor-para",
5447      "ua": "ie",
5448      "when": "instead"
5449  });
5450  // event-base-ie
5451  add('load', '5', {
5452      "name": "event-base-ie",
5453      "test": function(Y) {
5454      var imp = Y.config.doc && Y.config.doc.implementation;
5455      return (imp && (!imp.hasFeature('Events', '2.0')));
5456  },
5457      "trigger": "node-base"
5458  });
5459  // graphics-canvas
5460  add('load', '6', {
5461      "name": "graphics-canvas",
5462      "test": function(Y) {
5463      var DOCUMENT = Y.config.doc,
5464          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5465          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5466          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5467      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5468  },
5469      "trigger": "graphics"
5470  });
5471  // graphics-canvas-default
5472  add('load', '7', {
5473      "name": "graphics-canvas-default",
5474      "test": function(Y) {
5475      var DOCUMENT = Y.config.doc,
5476          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5477          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5478          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5479      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5480  },
5481      "trigger": "graphics"
5482  });
5483  // graphics-svg
5484  add('load', '8', {
5485      "name": "graphics-svg",
5486      "test": function(Y) {
5487      var DOCUMENT = Y.config.doc,
5488          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5489          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5490          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5491      
5492      return svg && (useSVG || !canvas);
5493  },
5494      "trigger": "graphics"
5495  });
5496  // graphics-svg-default
5497  add('load', '9', {
5498      "name": "graphics-svg-default",
5499      "test": function(Y) {
5500      var DOCUMENT = Y.config.doc,
5501          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5502          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5503          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5504      
5505      return svg && (useSVG || !canvas);
5506  },
5507      "trigger": "graphics"
5508  });
5509  // graphics-vml
5510  add('load', '10', {
5511      "name": "graphics-vml",
5512      "test": function(Y) {
5513      var DOCUMENT = Y.config.doc,
5514          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5515      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5516  },
5517      "trigger": "graphics"
5518  });
5519  // graphics-vml-default
5520  add('load', '11', {
5521      "name": "graphics-vml-default",
5522      "test": function(Y) {
5523      var DOCUMENT = Y.config.doc,
5524          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5525      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5526  },
5527      "trigger": "graphics"
5528  });
5529  // history-hash-ie
5530  add('load', '12', {
5531      "name": "history-hash-ie",
5532      "test": function (Y) {
5533      var docMode = Y.config.doc && Y.config.doc.documentMode;
5534  
5535      return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5536              !docMode || docMode < 8);
5537  },
5538      "trigger": "history-hash"
5539  });
5540  // io-nodejs
5541  add('load', '13', {
5542      "name": "io-nodejs",
5543      "trigger": "io-base",
5544      "ua": "nodejs"
5545  });
5546  // json-parse-shim
5547  add('load', '14', {
5548      "name": "json-parse-shim",
5549      "test": function (Y) {
5550      var _JSON = Y.config.global.JSON,
5551          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5552          nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5553  
5554      function workingNative( k, v ) {
5555          return k === "ok" ? true : v;
5556      }
5557      
5558      // Double check basic functionality.  This is mainly to catch early broken
5559      // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5560      if ( nativeSupport ) {
5561          try {
5562              nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5563          }
5564          catch ( e ) {
5565              nativeSupport = false;
5566          }
5567      }
5568  
5569      return !nativeSupport;
5570  },
5571      "trigger": "json-parse"
5572  });
5573  // json-stringify-shim
5574  add('load', '15', {
5575      "name": "json-stringify-shim",
5576      "test": function (Y) {
5577      var _JSON = Y.config.global.JSON,
5578          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5579          nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5580  
5581      // Double check basic native functionality.  This is primarily to catch broken
5582      // early JSON API implementations in Firefox 3.1 beta1 and beta2.
5583      if ( nativeSupport ) {
5584          try {
5585              nativeSupport = ( '0' === Native.stringify(0) );
5586          } catch ( e ) {
5587              nativeSupport = false;
5588          }
5589      }
5590  
5591  
5592      return !nativeSupport;
5593  },
5594      "trigger": "json-stringify"
5595  });
5596  // scrollview-base-ie
5597  add('load', '16', {
5598      "name": "scrollview-base-ie",
5599      "trigger": "scrollview-base",
5600      "ua": "ie"
5601  });
5602  // selector-css2
5603  add('load', '17', {
5604      "name": "selector-css2",
5605      "test": function (Y) {
5606      var DOCUMENT = Y.config.doc,
5607          ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5608  
5609      return ret;
5610  },
5611      "trigger": "selector"
5612  });
5613  // transition-timer
5614  add('load', '18', {
5615      "name": "transition-timer",
5616      "test": function (Y) {
5617      var DOCUMENT = Y.config.doc,
5618          node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5619          ret = true;
5620  
5621      if (node && node.style) {
5622          ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5623      }
5624  
5625      return ret;
5626  },
5627      "trigger": "transition"
5628  });
5629  // widget-base-ie
5630  add('load', '19', {
5631      "name": "widget-base-ie",
5632      "trigger": "widget-base",
5633      "ua": "ie"
5634  });
5635  // yql-jsonp
5636  add('load', '20', {
5637      "name": "yql-jsonp",
5638      "test": function (Y) {
5639      /* Only load the JSONP module when not in nodejs or winjs
5640      TODO Make the winjs module a CORS module
5641      */
5642      return (!Y.UA.nodejs && !Y.UA.winjs);
5643  },
5644      "trigger": "yql"
5645  });
5646  // yql-nodejs
5647  add('load', '21', {
5648      "name": "yql-nodejs",
5649      "trigger": "yql",
5650      "ua": "nodejs"
5651  });
5652  // yql-winjs
5653  add('load', '22', {
5654      "name": "yql-winjs",
5655      "trigger": "yql",
5656      "ua": "winjs"
5657  });
5658  
5659  }, '3.17.2', {"requires": ["yui-base"]});
5660  YUI.add('intl-base', function (Y, NAME) {
5661  
5662  /**
5663   * The Intl utility provides a central location for managing sets of
5664   * localized resources (strings and formatting patterns).
5665   *
5666   * @class Intl
5667   * @uses EventTarget
5668   * @static
5669   */
5670  
5671  var SPLIT_REGEX = /[, ]/;
5672  
5673  Y.mix(Y.namespace('Intl'), {
5674  
5675   /**
5676      * Returns the language among those available that
5677      * best matches the preferred language list, using the Lookup
5678      * algorithm of BCP 47.
5679      * If none of the available languages meets the user's preferences,
5680      * then "" is returned.
5681      * Extended language ranges are not supported.
5682      *
5683      * @method lookupBestLang
5684      * @param {String[] | String} preferredLanguages The list of preferred
5685      * languages in descending preference order, represented as BCP 47
5686      * language tags. A string array or a comma-separated list.
5687      * @param {String[]} availableLanguages The list of languages
5688      * that the application supports, represented as BCP 47 language
5689      * tags.
5690      *
5691      * @return {String} The available language that best matches the
5692      * preferred language list, or "".
5693      * @since 3.1.0
5694      */
5695      lookupBestLang: function(preferredLanguages, availableLanguages) {
5696  
5697          var i, language, result, index;
5698  
5699          // check whether the list of available languages contains language;
5700          // if so return it
5701          function scan(language) {
5702              var i;
5703              for (i = 0; i < availableLanguages.length; i += 1) {
5704                  if (language.toLowerCase() ===
5705                              availableLanguages[i].toLowerCase()) {
5706                      return availableLanguages[i];
5707                  }
5708              }
5709          }
5710  
5711          if (Y.Lang.isString(preferredLanguages)) {
5712              preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5713          }
5714  
5715          for (i = 0; i < preferredLanguages.length; i += 1) {
5716              language = preferredLanguages[i];
5717              if (!language || language === '*') {
5718                  continue;
5719              }
5720              // check the fallback sequence for one language
5721              while (language.length > 0) {
5722                  result = scan(language);
5723                  if (result) {
5724                      return result;
5725                  } else {
5726                      index = language.lastIndexOf('-');
5727                      if (index >= 0) {
5728                          language = language.substring(0, index);
5729                          // one-character subtags get cut along with the
5730                          // following subtag
5731                          if (index >= 2 && language.charAt(index - 2) === '-') {
5732                              language = language.substring(0, index - 2);
5733                          }
5734                      } else {
5735                          // nothing available for this language
5736                          break;
5737                      }
5738                  }
5739              }
5740          }
5741  
5742          return '';
5743      }
5744  });
5745  
5746  
5747  }, '3.17.2', {"requires": ["yui-base"]});
5748  YUI.add('yui-log', function (Y, NAME) {
5749  
5750  /**
5751   * Provides console log capability and exposes a custom event for
5752   * console implementations. This module is a `core` YUI module,
5753   * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
5754   *
5755   * @module yui
5756   * @submodule yui-log
5757   */
5758  
5759  var INSTANCE = Y,
5760      LOGEVENT = 'yui:log',
5761      UNDEFINED = 'undefined',
5762      LEVELS = { debug: 1,
5763                 info: 2,
5764                 warn: 4,
5765                 error: 8 };
5766  
5767  /**
5768   * If the 'debug' config is true, a 'yui:log' event will be
5769   * dispatched, which the Console widget and anything else
5770   * can consume.  If the 'useBrowserConsole' config is true, it will
5771   * write to the browser console if available.  YUI-specific log
5772   * messages will only be present in the -debug versions of the
5773   * JS files.  The build system is supposed to remove log statements
5774   * from the raw and minified versions of the files.
5775   *
5776   * @method log
5777   * @for YUI
5778   * @param  {String}  msg  The message to log.
5779   * @param  {String}  cat  The log category for the message.  Default
5780   *                        categories are "info", "warn", "error", "debug".
5781   *                        Custom categories can be used as well. (opt).
5782   * @param  {String}  src  The source of the the message (opt).
5783   * @param  {boolean} silent If true, the log event won't fire.
5784   * @return {YUI}      YUI instance.
5785   */
5786  INSTANCE.log = function(msg, cat, src, silent) {
5787      var bail, excl, incl, m, f, minlevel,
5788          Y = INSTANCE,
5789          c = Y.config,
5790          publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
5791      // suppress log message if the config is off or the event stack
5792      // or the event call stack contains a consumer of the yui:log event
5793      if (c.debug) {
5794          // apply source filters
5795          src = src || "";
5796          if (typeof src !== "undefined") {
5797              excl = c.logExclude;
5798              incl = c.logInclude;
5799              if (incl && !(src in incl)) {
5800                  bail = 1;
5801              } else if (incl && (src in incl)) {
5802                  bail = !incl[src];
5803              } else if (excl && (src in excl)) {
5804                  bail = excl[src];
5805              }
5806  
5807              // Set a default category of info if the category was not defined.
5808              if ((typeof cat === 'undefined')) {
5809                  cat = 'info';
5810              }
5811  
5812              // Determine the current minlevel as defined in configuration
5813              Y.config.logLevel = Y.config.logLevel || 'debug';
5814              minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
5815  
5816              if (cat in LEVELS && LEVELS[cat] < minlevel) {
5817                  // Skip this message if the we don't meet the defined minlevel
5818                  bail = 1;
5819              }
5820          }
5821          if (!bail) {
5822              if (c.useBrowserConsole) {
5823                  m = (src) ? src + ': ' + msg : msg;
5824                  if (Y.Lang.isFunction(c.logFn)) {
5825                      c.logFn.call(Y, msg, cat, src);
5826                  } else if (typeof console !== UNDEFINED && console.log) {
5827                      f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
5828                      console[f](m);
5829                  } else if (typeof opera !== UNDEFINED) {
5830                      opera.postError(m);
5831                  }
5832              }
5833  
5834              if (publisher && !silent) {
5835  
5836                  if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
5837                      publisher.publish(LOGEVENT, {
5838                          broadcast: 2
5839                      });
5840                  }
5841  
5842                  publisher.fire(LOGEVENT, {
5843                      msg: msg,
5844                      cat: cat,
5845                      src: src
5846                  });
5847              }
5848          }
5849      }
5850  
5851      return Y;
5852  };
5853  
5854  /**
5855   * Write a system message.  This message will be preserved in the
5856   * minified and raw versions of the YUI files, unlike log statements.
5857   * @method message
5858   * @for YUI
5859   * @param  {String}  msg  The message to log.
5860   * @param  {String}  cat  The log category for the message.  Default
5861   *                        categories are "info", "warn", "error", "debug".
5862   *                        Custom categories can be used as well. (opt).
5863   * @param  {String}  src  The source of the the message (opt).
5864   * @param  {boolean} silent If true, the log event won't fire.
5865   * @return {YUI}      YUI instance.
5866   */
5867  INSTANCE.message = function() {
5868      return INSTANCE.log.apply(INSTANCE, arguments);
5869  };
5870  
5871  
5872  }, '3.17.2', {"requires": ["yui-base"]});
5873  YUI.add('yui-later', function (Y, NAME) {
5874  
5875  /**
5876   * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
5877   * <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
5878   *
5879   * @module yui
5880   * @submodule yui-later
5881   */
5882  
5883  var NO_ARGS = [];
5884  
5885  /**
5886   * Executes the supplied function in the context of the supplied
5887   * object 'when' milliseconds later.  Executes the function a
5888   * single time unless periodic is set to true.
5889   * @for YUI
5890   * @method later
5891   * @param when {Number} the number of milliseconds to wait until the fn
5892   * is executed.
5893   * @param o the context object.
5894   * @param fn {Function|String} the function to execute or the name of
5895   * the method in the 'o' object to execute.
5896   * @param data [Array] data that is provided to the function.  This
5897   * accepts either a single item or an array.  If an array is provided,
5898   * the function is executed with one parameter for each array item.
5899   * If you need to pass a single array parameter, it needs to be wrapped
5900   * in an array [myarray].
5901   *
5902   * Note: native methods in IE may not have the call and apply methods.
5903   * In this case, it will work, but you are limited to four arguments.
5904   *
5905   * @param periodic {boolean} if true, executes continuously at supplied
5906   * interval until canceled.
5907   * @return {object} a timer object. Call the cancel() method on this
5908   * object to stop the timer.
5909   */
5910  Y.later = function(when, o, fn, data, periodic) {
5911      when = when || 0;
5912      data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
5913      o = o || Y.config.win || Y;
5914  
5915      var cancelled = false,
5916          method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
5917          wrapper = function() {
5918              // IE 8- may execute a setInterval callback one last time
5919              // after clearInterval was called, so in order to preserve
5920              // the cancel() === no more runny-run, we have to jump through
5921              // an extra hoop.
5922              if (!cancelled) {
5923                  if (!method.apply) {
5924                      method(data[0], data[1], data[2], data[3]);
5925                  } else {
5926                      method.apply(o, data || NO_ARGS);
5927                  }
5928              }
5929          },
5930          id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
5931  
5932      return {
5933          id: id,
5934          interval: periodic,
5935          cancel: function() {
5936              cancelled = true;
5937              if (this.interval) {
5938                  clearInterval(id);
5939              } else {
5940                  clearTimeout(id);
5941              }
5942          }
5943      };
5944  };
5945  
5946  Y.Lang.later = Y.later;
5947  
5948  
5949  
5950  }, '3.17.2', {"requires": ["yui-base"]});
5951  YUI.add('loader-base', function (Y, NAME) {
5952  
5953  /**
5954   * The YUI loader core
5955   * @module loader
5956   * @submodule loader-base
5957   */
5958  
5959  (function() {
5960      var VERSION = Y.version,
5961          BUILD = '/build/',
5962          ROOT = VERSION + '/',
5963          CDN_BASE = Y.Env.base,
5964          GALLERY_VERSION = 'gallery-2014.05.29-15-46',
5965          TNT = '2in3',
5966          TNT_VERSION = '4',
5967          YUI2_VERSION = '2.9.0',
5968          COMBO_BASE = CDN_BASE + 'combo?',
5969          META = {
5970              version: VERSION,
5971              root: ROOT,
5972              base: Y.Env.base,
5973              comboBase: COMBO_BASE,
5974              skin: {
5975                  defaultSkin: 'sam',
5976                  base: 'assets/skins/',
5977                  path: 'skin.css',
5978                  after: [
5979                      'cssreset',
5980                      'cssfonts',
5981                      'cssgrids',
5982                      'cssbase',
5983                      'cssreset-context',
5984                      'cssfonts-context'
5985                  ]
5986              },
5987              groups: {},
5988              patterns: {}
5989          },
5990          groups = META.groups,
5991          yui2Update = function(tnt, yui2, config) {
5992              var root = TNT + '.' +
5993                      (tnt || TNT_VERSION) + '/' +
5994                      (yui2 || YUI2_VERSION) + BUILD,
5995                  base = (config && config.base) ? config.base : CDN_BASE,
5996                  combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
5997  
5998              groups.yui2.base = base + root;
5999              groups.yui2.root = root;
6000              groups.yui2.comboBase = combo;
6001          },
6002          galleryUpdate = function(tag, config) {
6003              var root = (tag || GALLERY_VERSION) + BUILD,
6004                  base = (config && config.base) ? config.base : CDN_BASE,
6005                  combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6006  
6007              groups.gallery.base = base + root;
6008              groups.gallery.root = root;
6009              groups.gallery.comboBase = combo;
6010          };
6011  
6012  
6013      groups[VERSION] = {};
6014  
6015      groups.gallery = {
6016          ext: false,
6017          combine: true,
6018          comboBase: COMBO_BASE,
6019          update: galleryUpdate,
6020          patterns: {
6021              'gallery-': {},
6022              'lang/gallery-': {},
6023              'gallerycss-': {
6024                  type: 'css'
6025              }
6026          }
6027      };
6028  
6029      groups.yui2 = {
6030          combine: true,
6031          ext: false,
6032          comboBase: COMBO_BASE,
6033          update: yui2Update,
6034          patterns: {
6035              'yui2-': {
6036                  configFn: function(me) {
6037                      if (/-skin|reset|fonts|grids|base/.test(me.name)) {
6038                          me.type = 'css';
6039                          me.path = me.path.replace(/\.js/, '.css');
6040                          // this makes skins in builds earlier than
6041                          // 2.6.0 work as long as combine is false
6042                          me.path = me.path.replace(/\/yui2-skin/,
6043                                              '/assets/skins/sam/yui2-skin');
6044                      }
6045                  }
6046              }
6047          }
6048      };
6049  
6050      galleryUpdate();
6051      yui2Update();
6052  
6053      if (YUI.Env[VERSION]) {
6054          Y.mix(META, YUI.Env[VERSION], false, [
6055              'modules',
6056              'groups',
6057              'skin'
6058          ], 0, true);
6059      }
6060  
6061      YUI.Env[VERSION] = META;
6062  }());
6063  /*jslint forin: true, maxlen: 350 */
6064  
6065  /**
6066   * Loader dynamically loads script and css files.  It includes the dependency
6067   * information for the version of the library in use, and will automatically pull in
6068   * dependencies for the modules requested. It can also load the
6069   * files from the Yahoo! CDN, and it can utilize the combo service provided on
6070   * this network to reduce the number of http connections required to download
6071   * YUI files.
6072   *
6073   * @module loader
6074   * @main loader
6075   * @submodule loader-base
6076   */
6077  
6078  var NOT_FOUND = {},
6079      NO_REQUIREMENTS = [],
6080      MAX_URL_LENGTH = 1024,
6081      GLOBAL_ENV = YUI.Env,
6082      GLOBAL_LOADED = GLOBAL_ENV._loaded,
6083      CSS = 'css',
6084      JS = 'js',
6085      INTL = 'intl',
6086      DEFAULT_SKIN = 'sam',
6087      VERSION = Y.version,
6088      ROOT_LANG = '',
6089      YObject = Y.Object,
6090      oeach = YObject.each,
6091      yArray = Y.Array,
6092      _queue = GLOBAL_ENV._loaderQueue,
6093      META = GLOBAL_ENV[VERSION],
6094      SKIN_PREFIX = 'skin-',
6095      L = Y.Lang,
6096      ON_PAGE = GLOBAL_ENV.mods,
6097      modulekey,
6098      _path = function(dir, file, type, nomin) {
6099          var path = dir + '/' + file;
6100          if (!nomin) {
6101              path += '-min';
6102          }
6103          path += '.' + (type || CSS);
6104  
6105          return path;
6106      };
6107  
6108  
6109      if (!YUI.Env._cssLoaded) {
6110          YUI.Env._cssLoaded = {};
6111      }
6112  
6113  
6114  /**
6115   * The component metadata is stored in Y.Env.meta.
6116   * Part of the loader module.
6117   * @property meta
6118   * @for YUI
6119   */
6120  Y.Env.meta = META;
6121  
6122  /**
6123   * Loader dynamically loads script and css files.  It includes the dependency
6124   * info for the version of the library in use, and will automatically pull in
6125   * dependencies for the modules requested. It can load the
6126   * files from the Yahoo! CDN, and it can utilize the combo service provided on
6127   * this network to reduce the number of http connections required to download
6128   * YUI files. You can also specify an external, custom combo service to host
6129   * your modules as well.
6130  
6131          var Y = YUI();
6132          var loader = new Y.Loader({
6133              filter: 'debug',
6134              base: '../../',
6135              root: 'build/',
6136              combine: true,
6137              require: ['node', 'dd', 'console']
6138          });
6139          var out = loader.resolve(true);
6140  
6141   * If the Loader needs to be patched before it is used for the first time, it
6142   * should be done through the `doBeforeLoader` hook. Simply make the patch
6143   * available via configuration before YUI is loaded:
6144  
6145          YUI_config = YUI_config || {};
6146          YUI_config.doBeforeLoader = function (config) {
6147              var resolve = this.context.Loader.prototype.resolve;
6148              this.context.Loader.prototype.resolve = function () {
6149                  // do something here
6150                  return resolve.apply(this, arguments);
6151              };
6152          };
6153  
6154   * @constructor
6155   * @class Loader
6156   * @param {Object} config an optional set of configuration options.
6157   * @param {String} config.base The base dir which to fetch this module from
6158   * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?`
6159   * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/`
6160   * @param {String|Object} config.filter A filter to apply to result urls. <a href="#property_filter">See filter property</a>
6161   * @param {Object} config.filters Per-component filter specification.  If specified for a given component, this overrides the filter config.
6162   * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies
6163   * @param {Boolean} [config.async=true] Fetch files in async
6164   * @param {Array} config.ignore: A list of modules that should never be dynamically loaded
6165   * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page
6166   * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes
6167   * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes
6168   * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes
6169   * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes.  If not set, there is no timeout
6170   * @param {Object} config.context Execution context for all callbacks
6171   * @param {Function} config.onSuccess Callback for the 'success' event
6172   * @param {Function} config.onFailure Callback for the 'failure' event
6173   * @param {Function} config.onTimeout Callback for the 'timeout' event
6174   * @param {Function} config.onProgress Callback executed each time a script or css file is loaded
6175   * @param {Object} config.modules A list of module definitions.  See <a href="#method_addModule">Loader.addModule</a> for the supported module metadata
6176   * @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`.
6177   * @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.
6178   * @param {String} config.yui2 When using the 2in3 project, you can select the version of YUI 2 to use.  Valid 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.
6179   * @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.
6180   */
6181  Y.Loader = function(o) {
6182  
6183      var self = this;
6184  
6185      //Catch no config passed.
6186      o = o || {};
6187  
6188      modulekey = META.md5;
6189  
6190      /**
6191       * Internal callback to handle multiple internal insert() calls
6192       * so that css is inserted prior to js
6193       * @property _internalCallback
6194       * @private
6195       */
6196      // self._internalCallback = null;
6197  
6198      /**
6199       * Callback that will be executed when the loader is finished
6200       * with an insert
6201       * @method onSuccess
6202       * @type function
6203       */
6204      // self.onSuccess = null;
6205  
6206      /**
6207       * Callback that will be executed if there is a failure
6208       * @method onFailure
6209       * @type function
6210       */
6211      // self.onFailure = null;
6212  
6213      /**
6214       * Callback executed each time a script or css file is loaded
6215       * @method onProgress
6216       * @type function
6217       */
6218      // self.onProgress = null;
6219  
6220      /**
6221       * Callback that will be executed if a timeout occurs
6222       * @method onTimeout
6223       * @type function
6224       */
6225      // self.onTimeout = null;
6226  
6227      /**
6228       * The execution context for all callbacks
6229       * @property context
6230       * @default {YUI} the YUI instance
6231       */
6232      self.context = Y;
6233  
6234      // Hook that allows the patching of loader
6235      if (o.doBeforeLoader) {
6236          o.doBeforeLoader.apply(self, arguments);
6237      }
6238  
6239      /**
6240       * Data that is passed to all callbacks
6241       * @property data
6242       */
6243      // self.data = null;
6244  
6245      /**
6246       * Node reference or id where new nodes should be inserted before
6247       * @property insertBefore
6248       * @type string|HTMLElement
6249       */
6250      // self.insertBefore = null;
6251  
6252      /**
6253       * The charset attribute for inserted nodes
6254       * @property charset
6255       * @type string
6256       * @deprecated , use cssAttributes or jsAttributes.
6257       */
6258      // self.charset = null;
6259  
6260      /**
6261       * An object literal containing attributes to add to link nodes
6262       * @property cssAttributes
6263       * @type object
6264       */
6265      // self.cssAttributes = null;
6266  
6267      /**
6268       * An object literal containing attributes to add to script nodes
6269       * @property jsAttributes
6270       * @type object
6271       */
6272      // self.jsAttributes = null;
6273  
6274      /**
6275       * The base directory.
6276       * @property base
6277       * @type string
6278       * @default http://yui.yahooapis.com/[YUI VERSION]/build/
6279       */
6280      self.base = Y.Env.meta.base + Y.Env.meta.root;
6281  
6282      /**
6283       * Base path for the combo service
6284       * @property comboBase
6285       * @type string
6286       * @default http://yui.yahooapis.com/combo?
6287       */
6288      self.comboBase = Y.Env.meta.comboBase;
6289  
6290      /*
6291       * Base path for language packs.
6292       */
6293      // self.langBase = Y.Env.meta.langBase;
6294      // self.lang = "";
6295  
6296      /**
6297       * If configured, the loader will attempt to use the combo
6298       * service for YUI resources and configured external resources.
6299       * @property combine
6300       * @type boolean
6301       * @default true if a base dir isn't in the config
6302       */
6303      self.combine = o.base &&
6304          (o.base.indexOf(self.comboBase.substr(0, 20)) > -1);
6305  
6306      /**
6307      * The default seperator to use between files in a combo URL
6308      * @property comboSep
6309      * @type {String}
6310      * @default Ampersand
6311      */
6312      self.comboSep = '&';
6313      /**
6314       * Max url length for combo urls.  The default is 1024. This is the URL
6315       * limit for the Yahoo! hosted combo servers.  If consuming
6316       * a different combo service that has a different URL limit
6317       * it is possible to override this default by supplying
6318       * the maxURLLength config option.  The config option will
6319       * only take effect if lower than the default.
6320       *
6321       * @property maxURLLength
6322       * @type int
6323       */
6324      self.maxURLLength = MAX_URL_LENGTH;
6325  
6326      /**
6327       * Ignore modules registered on the YUI global
6328       * @property ignoreRegistered
6329       * @default false
6330       */
6331      self.ignoreRegistered = o.ignoreRegistered;
6332  
6333      /**
6334       * Root path to prepend to module path for the combo
6335       * service
6336       * @property root
6337       * @type string
6338       * @default [YUI VERSION]/build/
6339       */
6340      self.root = Y.Env.meta.root;
6341  
6342      /**
6343       * Timeout value in milliseconds.  If set, self value will be used by
6344       * the get utility.  the timeout event will fire if
6345       * a timeout occurs.
6346       * @property timeout
6347       * @type int
6348       */
6349      self.timeout = 0;
6350  
6351      /**
6352       * A list of modules that should not be loaded, even if
6353       * they turn up in the dependency tree
6354       * @property ignore
6355       * @type string[]
6356       */
6357      // self.ignore = null;
6358  
6359      /**
6360       * A list of modules that should always be loaded, even
6361       * if they have already been inserted into the page.
6362       * @property force
6363       * @type string[]
6364       */
6365      // self.force = null;
6366  
6367      self.forceMap = {};
6368  
6369      /**
6370       * Should we allow rollups
6371       * @property allowRollup
6372       * @type boolean
6373       * @default false
6374       */
6375      self.allowRollup = false;
6376  
6377      /**
6378       * A filter to apply to result urls.  This filter will modify the default
6379       * path for all modules.  The default path for the YUI library is the
6380       * minified version of the files (e.g., event-min.js).  The filter property
6381       * can be a predefined filter or a custom filter.  The valid predefined
6382       * filters are:
6383       * <dl>
6384       *  <dt>DEBUG</dt>
6385       *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
6386       *      This option will automatically include the Logger widget</dd>
6387       *  <dt>RAW</dt>
6388       *  <dd>Selects the non-minified version of the library (e.g., event.js).
6389       *  </dd>
6390       * </dl>
6391       * You can also define a custom filter, which must be an object literal
6392       * containing a search expression and a replace string:
6393       *
6394       *      myFilter: {
6395       *          'searchExp': "-min\\.js",
6396       *          'replaceStr': "-debug.js"
6397       *      }
6398       *
6399       * @property filter
6400       * @type string| {searchExp: string, replaceStr: string}
6401       */
6402      // self.filter = null;
6403  
6404      /**
6405       * per-component filter specification.  If specified for a given
6406       * component, this overrides the filter config.
6407       * @property filters
6408       * @type object
6409       */
6410      self.filters = {};
6411  
6412      /**
6413       * The list of requested modules
6414       * @property required
6415       * @type {string: boolean}
6416       */
6417      self.required = {};
6418  
6419      /**
6420       * If a module name is predefined when requested, it is checked againsts
6421       * the patterns provided in this property.  If there is a match, the
6422       * module is added with the default configuration.
6423       *
6424       * At the moment only supporting module prefixes, but anticipate
6425       * supporting at least regular expressions.
6426       * @property patterns
6427       * @type Object
6428       */
6429      // self.patterns = Y.merge(Y.Env.meta.patterns);
6430      self.patterns = {};
6431  
6432      /**
6433       * Internal loader instance metadata. Use accessor `getModuleInfo()` instead.
6434       */
6435      self.moduleInfo = {};
6436  
6437      self.groups = Y.merge(Y.Env.meta.groups);
6438  
6439      /**
6440       * Provides the information used to skin the skinnable components.
6441       * The following skin definition would result in 'skin1' and 'skin2'
6442       * being loaded for calendar (if calendar was requested), and
6443       * 'sam' for all other skinnable components:
6444       *
6445       *      skin: {
6446       *          // The default skin, which is automatically applied if not
6447       *          // overriden by a component-specific skin definition.
6448       *          // Change this in to apply a different skin globally
6449       *          defaultSkin: 'sam',
6450       *
6451       *          // This is combined with the loader base property to get
6452       *          // the default root directory for a skin. ex:
6453       *          // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
6454       *          base: 'assets/skins/',
6455       *
6456       *          // Any component-specific overrides can be specified here,
6457       *          // making it possible to load different skins for different
6458       *          // components.  It is possible to load more than one skin
6459       *          // for a given component as well.
6460       *          overrides: {
6461       *              calendar: ['skin1', 'skin2']
6462       *          }
6463       *      }
6464       * @property skin
6465       * @type {Object}
6466       */
6467      self.skin = Y.merge(Y.Env.meta.skin);
6468  
6469      /*
6470       * Map of conditional modules
6471       * @since 3.2.0
6472       */
6473      self.conditions = {};
6474  
6475      // map of modules with a hash of modules that meet the requirement
6476      // self.provides = {};
6477  
6478      self.config = o;
6479      self._internal = true;
6480  
6481      self._populateConditionsCache();
6482  
6483      /**
6484       * Set when beginning to compute the dependency tree.
6485       * Composed of what YUI reports to be loaded combined
6486       * with what has been loaded by any instance on the page
6487       * with the version number specified in the metadata.
6488       * @property loaded
6489       * @type {string: boolean}
6490       */
6491      self.loaded = GLOBAL_LOADED[VERSION];
6492  
6493  
6494      /**
6495      * Should Loader fetch scripts in `async`, defaults to `true`
6496      * @property async
6497      */
6498  
6499      self.async = true;
6500  
6501      self._inspectPage();
6502  
6503      self._internal = false;
6504  
6505      self._config(o);
6506  
6507      self.forceMap = (self.force) ? Y.Array.hash(self.force) : {};
6508  
6509      self.testresults = null;
6510  
6511      if (Y.config.tests) {
6512          self.testresults = Y.config.tests;
6513      }
6514  
6515      /**
6516       * List of rollup files found in the library metadata
6517       * @property rollups
6518       */
6519      // self.rollups = null;
6520  
6521      /**
6522       * Whether or not to load optional dependencies for
6523       * the requested modules
6524       * @property loadOptional
6525       * @type boolean
6526       * @default false
6527       */
6528      // self.loadOptional = false;
6529  
6530      /**
6531       * All of the derived dependencies in sorted order, which
6532       * will be populated when either calculate() or insert()
6533       * is called
6534       * @property sorted
6535       * @type string[]
6536       */
6537      self.sorted = [];
6538  
6539      /*
6540       * A list of modules to attach to the YUI instance when complete.
6541       * If not supplied, the sorted list of dependencies are applied.
6542       * @property attaching
6543       */
6544      // self.attaching = null;
6545  
6546      /**
6547       * Flag to indicate the dependency tree needs to be recomputed
6548       * if insert is called again.
6549       * @property dirty
6550       * @type boolean
6551       * @default true
6552       */
6553      self.dirty = true;
6554  
6555      /**
6556       * List of modules inserted by the utility
6557       * @property inserted
6558       * @type {string: boolean}
6559       */
6560      self.inserted = {};
6561  
6562      /**
6563       * List of skipped modules during insert() because the module
6564       * was not defined
6565       * @property skipped
6566       */
6567      self.skipped = {};
6568  
6569      // Y.on('yui:load', self.loadNext, self);
6570  
6571      self.tested = {};
6572  
6573      /*
6574       * Cached sorted calculate results
6575       * @property results
6576       * @since 3.2.0
6577       */
6578      //self.results = {};
6579  
6580      if (self.ignoreRegistered) {
6581          //Clear inpage already processed modules.
6582          self._resetModules();
6583      }
6584  
6585  };
6586  
6587  Y.Loader.prototype = {
6588      /**
6589      * Gets the module info from the local moduleInfo hash, or from the
6590      * default metadata and populate the local moduleInfo hash.
6591      * @method getModuleInfo
6592      * @param {string} name of the module
6593      * @public
6594      */
6595      getModuleInfo: function(name) {
6596  
6597          var m = this.moduleInfo[name],
6598              rawMetaModules, globalRenderedMods, internal, v;
6599  
6600          if (m) {
6601              return m;
6602          }
6603  
6604          rawMetaModules = META.modules;
6605          globalRenderedMods = GLOBAL_ENV._renderedMods;
6606          internal = this._internal;
6607  
6608          /*
6609          The logic here is:
6610  
6611          - if the `moduleInfo[name]` is avilable,
6612            then short circuit
6613          - otherwise, if the module is in the globalCache (cross Y instance),
6614            then port it from the global registry into `moduleInfo[name]`
6615          - otherwise, if the module has raw metadata (from meta modules)
6616            then add it to the global registry and to `moduleInfo[name]`
6617  
6618          */
6619          if (globalRenderedMods && globalRenderedMods.hasOwnProperty(name) && !this.ignoreRegistered) {
6620              this.moduleInfo[name] = Y.merge(globalRenderedMods[name]);
6621          } else {
6622              if (rawMetaModules.hasOwnProperty(name)) {
6623                  this._internal = true; // making sure that modules from raw data are marked as internal
6624                  v = this.addModule(rawMetaModules[name], name);
6625                  // Inspect the page for the CSS module and mark it as loaded.
6626                  if (v && v.type === CSS) {
6627                      if (this.isCSSLoaded(v.name, true)) {
6628                          this.loaded[v.name] = true;
6629                      }
6630                  }
6631                  this._internal = internal;
6632              }
6633          }
6634          return this.moduleInfo[name];
6635      },
6636      /**
6637      * Expand the names that are aliases to other modules.
6638      * @method _expandAliases
6639      * @param {string[]} list a module name or a list of names to be expanded
6640      * @private
6641      * @return {array}
6642      */
6643      _expandAliases: function(list) {
6644          var expanded = [],
6645              aliases = YUI.Env.aliases,
6646              i, name;
6647          list = Y.Array(list);
6648          for (i = 0; i < list.length; i += 1) {
6649              name = list[i];
6650              expanded.push.apply(expanded, aliases[name] ? aliases[name] : [name]);
6651          }
6652          return expanded;
6653      },
6654      /**
6655      * Populate the conditions cache from raw modules, this is necessary
6656      * because no other module will require a conditional module, instead
6657      * the condition has to be executed and then the module is analyzed
6658      * to be included in the final requirement list. Without this cache
6659      * conditional modules will be simply ignored.
6660      * @method _populateConditionsCache
6661      * @private
6662      */
6663      _populateConditionsCache: function() {
6664          var rawMetaModules = META.modules,
6665              cache = GLOBAL_ENV._conditions,
6666              i, j, t, trigger;
6667  
6668          // if we have conditions in cache and cache is enabled
6669          // we should port them to this loader instance
6670          if (cache && !this.ignoreRegistered) {
6671              for (i in cache) {
6672                  if (cache.hasOwnProperty(i)) {
6673                      this.conditions[i] = Y.merge(cache[i]);
6674                  }
6675              }
6676          } else {
6677              for (i in rawMetaModules) {
6678                  if (rawMetaModules.hasOwnProperty(i) && rawMetaModules[i].condition) {
6679                      t = this._expandAliases(rawMetaModules[i].condition.trigger);
6680                      for (j = 0; j < t.length; j += 1) {
6681                          trigger = t[j];
6682                          this.conditions[trigger] = this.conditions[trigger] || {};
6683                          this.conditions[trigger][rawMetaModules[i].name || i] = rawMetaModules[i].condition;
6684                      }
6685                  }
6686              }
6687              GLOBAL_ENV._conditions = this.conditions;
6688          }
6689      },
6690      /**
6691      * Reset modules in the module cache to a pre-processed state so additional
6692      * computations with a different skin or language will work as expected.
6693      * @method _resetModules
6694      * @private
6695      */
6696      _resetModules: function() {
6697          var self = this, i, o,
6698              mod, name, details;
6699          for (i in self.moduleInfo) {
6700              if (self.moduleInfo.hasOwnProperty(i) && self.moduleInfo[i]) {
6701                  mod = self.moduleInfo[i];
6702                  name = mod.name;
6703                  details  = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null);
6704  
6705                  if (details) {
6706                      self.moduleInfo[name]._reset = true;
6707                      self.moduleInfo[name].requires = details.requires || [];
6708                      self.moduleInfo[name].optional = details.optional || [];
6709                      self.moduleInfo[name].supersedes = details.supercedes || [];
6710                  }
6711  
6712                  if (mod.defaults) {
6713                      for (o in mod.defaults) {
6714                          if (mod.defaults.hasOwnProperty(o)) {
6715                              if (mod[o]) {
6716                                  mod[o] = mod.defaults[o];
6717                              }
6718                          }
6719                      }
6720                  }
6721                  mod.langCache = undefined;
6722                  mod.skinCache = undefined;
6723                  if (mod.skinnable) {
6724                      self._addSkin(self.skin.defaultSkin, mod.name);
6725                  }
6726              }
6727          }
6728      },
6729      /**
6730      Regex that matches a CSS URL. Used to guess the file type when it's not
6731      specified.
6732  
6733      @property REGEX_CSS
6734      @type RegExp
6735      @final
6736      @protected
6737      @since 3.5.0
6738      **/
6739      REGEX_CSS: /\.css(?:[?;].*)?$/i,
6740  
6741      /**
6742      * Default filters for raw and debug
6743      * @property FILTER_DEFS
6744      * @type Object
6745      * @final
6746      * @protected
6747      */
6748      FILTER_DEFS: {
6749          RAW: {
6750              'searchExp': '-min\\.js',
6751              'replaceStr': '.js'
6752          },
6753          DEBUG: {
6754              'searchExp': '-min\\.js',
6755              'replaceStr': '-debug.js'
6756          },
6757          COVERAGE: {
6758              'searchExp': '-min\\.js',
6759              'replaceStr': '-coverage.js'
6760          }
6761      },
6762      /*
6763      * Check the pages meta-data and cache the result.
6764      * @method _inspectPage
6765      * @private
6766      */
6767      _inspectPage: function() {
6768          var self = this, v, m, req, mr, i;
6769  
6770          for (i in ON_PAGE) {
6771              if (ON_PAGE.hasOwnProperty(i)) {
6772                  v = ON_PAGE[i];
6773                  if (v.details) {
6774                      m = self.getModuleInfo(v.name);
6775                      req = v.details.requires;
6776                      mr = m && m.requires;
6777  
6778                     if (m) {
6779                         if (!m._inspected && req && mr.length !== req.length) {
6780                             // console.log('deleting ' + m.name);
6781                             delete m.expanded;
6782                         }
6783                     } else {
6784                         m = self.addModule(v.details, i);
6785                     }
6786                     m._inspected = true;
6787                 }
6788              }
6789          }
6790      },
6791      /*
6792      * returns true if b is not loaded, and is required directly or by means of modules it supersedes.
6793      * @private
6794      * @method _requires
6795      * @param {String} mod1 The first module to compare
6796      * @param {String} mod2 The second module to compare
6797      */
6798     _requires: function(mod1, mod2) {
6799  
6800          var i, rm, after_map, s,
6801              m = this.getModuleInfo(mod1),
6802              other = this.getModuleInfo(mod2);
6803  
6804          if (!m || !other) {
6805              return false;
6806          }
6807  
6808          rm = m.expanded_map;
6809          after_map = m.after_map;
6810  
6811          // check if this module should be sorted after the other
6812          // do this first to short circut circular deps
6813          if (after_map && (mod2 in after_map)) {
6814              return true;
6815          }
6816  
6817          after_map = other.after_map;
6818  
6819          // and vis-versa
6820          if (after_map && (mod1 in after_map)) {
6821              return false;
6822          }
6823  
6824          // check if this module requires one the other supersedes
6825          s = other.supersedes;
6826          if (s) {
6827              for (i = 0; i < s.length; i++) {
6828                  if (this._requires(mod1, s[i])) {
6829                      return true;
6830                  }
6831              }
6832          }
6833  
6834          s = m.supersedes;
6835          if (s) {
6836              for (i = 0; i < s.length; i++) {
6837                  if (this._requires(mod2, s[i])) {
6838                      return false;
6839                  }
6840              }
6841          }
6842  
6843          // check if this module requires the other directly
6844          // if (r && yArray.indexOf(r, mod2) > -1) {
6845          if (rm && (mod2 in rm)) {
6846              return true;
6847          }
6848  
6849          // external css files should be sorted below yui css
6850          if (m.ext && m.type === CSS && !other.ext && other.type === CSS) {
6851              return true;
6852          }
6853  
6854          return false;
6855      },
6856      /**
6857      * Apply a new config to the Loader instance
6858      * @method _config
6859      * @private
6860      * @param {Object} o The new configuration
6861      */
6862      _config: function(o) {
6863          var i, j, val, a, f, group, groupName, self = this,
6864              mods = [], mod, modInfo;
6865          // apply config values
6866          if (o) {
6867              for (i in o) {
6868                  if (o.hasOwnProperty(i)) {
6869                      val = o[i];
6870                      //TODO This should be a case
6871                      if (i === 'require') {
6872                          self.require(val);
6873                      } else if (i === 'skin') {
6874                          //If the config.skin is a string, format to the expected object
6875                          if (typeof val === 'string') {
6876                              self.skin.defaultSkin = o.skin;
6877                              val = {
6878                                  defaultSkin: val
6879                              };
6880                          }
6881  
6882                          Y.mix(self.skin, val, true);
6883                      } else if (i === 'groups') {
6884                          for (j in val) {
6885                              if (val.hasOwnProperty(j)) {
6886                                  groupName = j;
6887                                  group = val[j];
6888                                  self.addGroup(group, groupName);
6889                                  if (group.aliases) {
6890                                      for (a in group.aliases) {
6891                                          if (group.aliases.hasOwnProperty(a)) {
6892                                              self.addAlias(group.aliases[a], a);
6893                                          }
6894                                      }
6895                                  }
6896                              }
6897                          }
6898  
6899                      } else if (i === 'modules') {
6900                          // add a hash of module definitions
6901                          for (j in val) {
6902                              if (val.hasOwnProperty(j)) {
6903                                  self.addModule(val[j], j);
6904                              }
6905                          }
6906                      } else if (i === 'aliases') {
6907                          for (j in val) {
6908                              if (val.hasOwnProperty(j)) {
6909                                  self.addAlias(val[j], j);
6910                              }
6911                          }
6912                      } else if (i === 'gallery') {
6913                          if (this.groups.gallery.update) {
6914                              this.groups.gallery.update(val, o);
6915                          }
6916                      } else if (i === 'yui2' || i === '2in3') {
6917                          if (this.groups.yui2.update) {
6918                              this.groups.yui2.update(o['2in3'], o.yui2, o);
6919                          }
6920                      } else {
6921                          self[i] = val;
6922                      }
6923                  }
6924              }
6925          }
6926  
6927          // fix filter
6928          f = self.filter;
6929  
6930          if (L.isString(f)) {
6931              f = f.toUpperCase();
6932              self.filterName = f;
6933              self.filter = self.FILTER_DEFS[f];
6934              if (f === 'DEBUG') {
6935                  self.require('yui-log', 'dump');
6936              }
6937          }
6938  
6939          if (self.filterName && self.coverage) {
6940              if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) {
6941                  for (i = 0; i < self.coverage.length; i++) {
6942                      mod = self.coverage[i];
6943                      modInfo = self.getModuleInfo(mod);
6944                      if (modInfo && modInfo.use) {
6945                          mods = mods.concat(modInfo.use);
6946                      } else {
6947                          mods.push(mod);
6948                      }
6949                  }
6950                  self.filters = self.filters || {};
6951                  Y.Array.each(mods, function(mod) {
6952                      self.filters[mod] = self.FILTER_DEFS.COVERAGE;
6953                  });
6954                  self.filterName = 'RAW';
6955                  self.filter = self.FILTER_DEFS[self.filterName];
6956              }
6957          }
6958  
6959      },
6960  
6961      /**
6962       * Returns the skin module name for the specified skin name.  If a
6963       * module name is supplied, the returned skin module name is
6964       * specific to the module passed in.
6965       * @method formatSkin
6966       * @param {string} skin the name of the skin.
6967       * @param {string} mod optional: the name of a module to skin.
6968       * @return {string} the full skin module name.
6969       */
6970      formatSkin: function(skin, mod) {
6971          var s = SKIN_PREFIX + skin;
6972          if (mod) {
6973              s = s + '-' + mod;
6974          }
6975  
6976          return s;
6977      },
6978  
6979      /**
6980       * Adds the skin def to the module info
6981       * @method _addSkin
6982       * @param {string} skin the name of the skin.
6983       * @param {string} mod the name of the module.
6984       * @param {string} parent parent module if this is a skin of a
6985       * submodule or plugin.
6986       * @return {string} the module name for the skin.
6987       * @private
6988       */
6989      _addSkin: function(skin, mod, parent) {
6990          var pkg, name, nmod,
6991              sinf = this.skin,
6992              mdef = mod && this.getModuleInfo(mod),
6993              ext = mdef && mdef.ext;
6994  
6995          // Add a module definition for the module-specific skin css
6996          if (mod) {
6997              name = this.formatSkin(skin, mod);
6998              if (!this.getModuleInfo(name)) {
6999                  pkg = mdef.pkg || mod;
7000                  nmod = {
7001                      skin: true,
7002                      name: name,
7003                      group: mdef.group,
7004                      type: 'css',
7005                      after: sinf.after,
7006                      path: (parent || pkg) + '/' + sinf.base + skin +
7007                            '/' + mod + '.css',
7008                      ext: ext
7009                  };
7010                  if (mdef.base) {
7011                      nmod.base = mdef.base;
7012                  }
7013                  if (mdef.configFn) {
7014                      nmod.configFn = mdef.configFn;
7015                  }
7016                  this.addModule(nmod, name);
7017  
7018              }
7019          }
7020  
7021          return name;
7022      },
7023      /**
7024      * Adds an alias module to the system
7025      * @method addAlias
7026      * @param {Array} use An array of modules that makes up this alias
7027      * @param {String} name The name of the alias
7028      * @example
7029      *       var loader = new Y.Loader({});
7030      *       loader.addAlias([ 'node', 'yql' ], 'davglass');
7031      *       loader.require(['davglass']);
7032      *       var out = loader.resolve(true);
7033      *
7034      *       //out.js will contain Node and YQL modules
7035      */
7036      addAlias: function(use, name) {
7037          YUI.Env.aliases[name] = use;
7038          this.addModule({
7039              name: name,
7040              use: use
7041          });
7042      },
7043      /**
7044       * Add a new module group
7045       * @method addGroup
7046       * @param {Object} config An object containing the group configuration data
7047       * @param {String} config.name required, the group name
7048       * @param {String} config.base The base directory for this module group
7049       * @param {String} config.root The root path to add to each combo resource path
7050       * @param {Boolean} config.combine Should the request be combined
7051       * @param {String} config.comboBase Combo service base path
7052       * @param {Object} config.modules The group of modules
7053       * @param {String} name the group name.
7054       * @example
7055       *      var loader = new Y.Loader({});
7056       *      loader.addGroup({
7057       *          name: 'davglass',
7058       *          combine: true,
7059       *          comboBase: '/combo?',
7060       *          root: '',
7061       *          modules: {
7062       *              //Module List here
7063       *          }
7064       *      }, 'davglass');
7065       */
7066      addGroup: function(o, name) {
7067          var mods = o.modules,
7068              self = this, i, v;
7069  
7070          name = name || o.name;
7071          o.name = name;
7072          self.groups[name] = o;
7073  
7074          if (o.patterns) {
7075              for (i in o.patterns) {
7076                  if (o.patterns.hasOwnProperty(i)) {
7077                      o.patterns[i].group = name;
7078                      self.patterns[i] = o.patterns[i];
7079                  }
7080              }
7081          }
7082  
7083          if (mods) {
7084              for (i in mods) {
7085                  if (mods.hasOwnProperty(i)) {
7086                      v = mods[i];
7087                      if (typeof v === 'string') {
7088                          v = { name: i, fullpath: v };
7089                      }
7090                      v.group = name;
7091                      self.addModule(v, i);
7092                  }
7093              }
7094          }
7095      },
7096  
7097      /**
7098       * Add a new module to the component metadata.
7099       * @method addModule
7100       * @param {Object} config An object containing the module data.
7101       * @param {String} config.name Required, the component name
7102       * @param {String} config.type Required, the component type (js or css)
7103       * @param {String} config.path Required, the path to the script from `base`
7104       * @param {Array} config.requires Array of modules required by this component
7105       * @param {Array} [config.optional] Array of optional modules for this component
7106       * @param {Array} [config.supersedes] Array of the modules this component replaces
7107       * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one
7108       * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array
7109       * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup
7110       * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path`
7111       * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in
7112       * @param {Object} [config.submodules] Hash of submodules
7113       * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration.
7114       * @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"]`
7115       * @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:
7116       * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load
7117       * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded.
7118       * @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"`.
7119       * @param {String} [config.condition.when] Specifies the load order of the conditional module
7120       *  with regard to the position of the trigger module.
7121       *  This should be one of three values: `before`, `after`, or `instead`.  The default is `after`.
7122       * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()`
7123       * @param {Function} [config.configFn] A function to exectute when configuring this module
7124       * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config.
7125       * @param {String[]} [config.optionalRequires] List of dependencies that
7126          may optionally be loaded by this loader. This is targeted mostly at
7127          polyfills, since they should not be in the list of requires because
7128          polyfills are assumed to be available in the global scope.
7129       * @param {Function} [config.test] Test to be called when this module is
7130          added as an optional dependency of another module. If the test function
7131          returns `false`, the module will be ignored and will not be attached to
7132          this YUI instance.
7133       * @param {String} [name] The module name, required if not in the module data.
7134       * @return {Object} the module definition or null if the object passed in did not provide all required attributes.
7135       */
7136      addModule: function(o, name) {
7137          name = name || o.name;
7138  
7139          if (typeof o === 'string') {
7140              o = { name: name, fullpath: o };
7141          }
7142  
7143  
7144          var subs, i, l, t, sup, s, smod, plugins, plug,
7145              j, langs, packName, supName, flatSup, flatLang, lang, ret,
7146              overrides, skinname, when, g, p,
7147              modInfo = this.moduleInfo[name],
7148              conditions = this.conditions, trigger;
7149  
7150          //Only merge this data if the temp flag is set
7151          //from an earlier pass from a pattern or else
7152          //an override module (YUI_config) can not be used to
7153          //replace a default module.
7154          if (modInfo && modInfo.temp) {
7155              //This catches temp modules loaded via a pattern
7156              // The module will be added twice, once from the pattern and
7157              // Once from the actual add call, this ensures that properties
7158              // that were added to the module the first time around (group: gallery)
7159              // are also added the second time around too.
7160              o = Y.merge(modInfo, o);
7161          }
7162  
7163          o.name = name;
7164  
7165          if (!o || !o.name) {
7166              return null;
7167          }
7168  
7169          if (!o.type) {
7170              //Always assume it's javascript unless the CSS pattern is matched.
7171              o.type = JS;
7172              p = o.path || o.fullpath;
7173              if (p && this.REGEX_CSS.test(p)) {
7174                  o.type = CSS;
7175              }
7176          }
7177  
7178          if (!o.path && !o.fullpath) {
7179              o.path = _path(name, name, o.type);
7180          }
7181          o.supersedes = o.supersedes || o.use;
7182  
7183          o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true;
7184  
7185          // Handle submodule logic
7186          subs = o.submodules;
7187  
7188          this.moduleInfo[name] = o;
7189  
7190          o.requires = o.requires || [];
7191  
7192          /*
7193          Only allowing the cascade of requires information, since
7194          optional and supersedes are far more fine grained than
7195          a blanket requires is.
7196          */
7197          if (this.requires) {
7198              for (i = 0; i < this.requires.length; i++) {
7199                  o.requires.push(this.requires[i]);
7200              }
7201          }
7202          if (o.group && this.groups && this.groups[o.group]) {
7203              g = this.groups[o.group];
7204              if (g.requires) {
7205                  for (i = 0; i < g.requires.length; i++) {
7206                      o.requires.push(g.requires[i]);
7207                  }
7208              }
7209          }
7210  
7211  
7212          if (!o.defaults) {
7213              o.defaults = {
7214                  requires: o.requires ? [].concat(o.requires) : null,
7215                  supersedes: o.supersedes ? [].concat(o.supersedes) : null,
7216                  optional: o.optional ? [].concat(o.optional) : null
7217              };
7218          }
7219  
7220          if (o.skinnable && o.ext && o.temp) {
7221              skinname = this._addSkin(this.skin.defaultSkin, name);
7222              o.requires.unshift(skinname);
7223          }
7224  
7225          if (o.requires.length) {
7226              o.requires = this.filterRequires(o.requires) || [];
7227          }
7228  
7229          if (!o.langPack && o.lang) {
7230              langs = yArray(o.lang);
7231              for (j = 0; j < langs.length; j++) {
7232                  lang = langs[j];
7233                  packName = this.getLangPackName(lang, name);
7234                  smod = this.getModuleInfo(packName);
7235                  if (!smod) {
7236                      smod = this._addLangPack(lang, o, packName);
7237                  }
7238              }
7239          }
7240  
7241  
7242          if (subs) {
7243              sup = o.supersedes || [];
7244              l = 0;
7245  
7246              for (i in subs) {
7247                  if (subs.hasOwnProperty(i)) {
7248                      s = subs[i];
7249  
7250                      s.path = s.path || _path(name, i, o.type);
7251                      s.pkg = name;
7252                      s.group = o.group;
7253  
7254                      if (s.supersedes) {
7255                          sup = sup.concat(s.supersedes);
7256                      }
7257  
7258                      smod = this.addModule(s, i);
7259                      sup.push(i);
7260  
7261                      if (smod.skinnable) {
7262                          o.skinnable = true;
7263                          overrides = this.skin.overrides;
7264                          if (overrides && overrides[i]) {
7265                              for (j = 0; j < overrides[i].length; j++) {
7266                                  skinname = this._addSkin(overrides[i][j],
7267                                           i, name);
7268                                  sup.push(skinname);
7269                              }
7270                          }
7271                          skinname = this._addSkin(this.skin.defaultSkin,
7272                                          i, name);
7273                          sup.push(skinname);
7274                      }
7275  
7276                      // looks like we are expected to work out the metadata
7277                      // for the parent module language packs from what is
7278                      // specified in the child modules.
7279                      if (s.lang && s.lang.length) {
7280  
7281                          langs = yArray(s.lang);
7282                          for (j = 0; j < langs.length; j++) {
7283                              lang = langs[j];
7284                              packName = this.getLangPackName(lang, name);
7285                              supName = this.getLangPackName(lang, i);
7286                              smod = this.getModuleInfo(packName);
7287  
7288                              if (!smod) {
7289                                  smod = this._addLangPack(lang, o, packName);
7290                              }
7291  
7292                              flatSup = flatSup || yArray.hash(smod.supersedes);
7293  
7294                              if (!(supName in flatSup)) {
7295                                  smod.supersedes.push(supName);
7296                              }
7297  
7298                              o.lang = o.lang || [];
7299  
7300                              flatLang = flatLang || yArray.hash(o.lang);
7301  
7302                              if (!(lang in flatLang)) {
7303                                  o.lang.push(lang);
7304                              }
7305  
7306  // Add rollup file, need to add to supersedes list too
7307  
7308                              // default packages
7309                              packName = this.getLangPackName(ROOT_LANG, name);
7310                              supName = this.getLangPackName(ROOT_LANG, i);
7311  
7312                              smod = this.getModuleInfo(packName);
7313  
7314                              if (!smod) {
7315                                  smod = this._addLangPack(lang, o, packName);
7316                              }
7317  
7318                              if (!(supName in flatSup)) {
7319                                  smod.supersedes.push(supName);
7320                              }
7321  
7322  // Add rollup file, need to add to supersedes list too
7323  
7324                          }
7325                      }
7326  
7327                      l++;
7328                  }
7329              }
7330              //o.supersedes = YObject.keys(yArray.hash(sup));
7331              o.supersedes = yArray.dedupe(sup);
7332              if (this.allowRollup) {
7333                  o.rollup = (l < 4) ? l : Math.min(l - 1, 4);
7334              }
7335          }
7336  
7337          plugins = o.plugins;
7338          if (plugins) {
7339              for (i in plugins) {
7340                  if (plugins.hasOwnProperty(i)) {
7341                      plug = plugins[i];
7342                      plug.pkg = name;
7343                      plug.path = plug.path || _path(name, i, o.type);
7344                      plug.requires = plug.requires || [];
7345                      plug.group = o.group;
7346                      this.addModule(plug, i);
7347                      if (o.skinnable) {
7348                          this._addSkin(this.skin.defaultSkin, i, name);
7349                      }
7350  
7351                  }
7352              }
7353          }
7354  
7355          if (o.condition) {
7356              t = this._expandAliases(o.condition.trigger);
7357              for (i = 0; i < t.length; i++) {
7358                  trigger = t[i];
7359                  when = o.condition.when;
7360                  conditions[trigger] = conditions[trigger] || {};
7361                  conditions[trigger][name] = o.condition;
7362                  // the 'when' attribute can be 'before', 'after', or 'instead'
7363                  // the default is after.
7364                  if (when && when !== 'after') {
7365                      if (when === 'instead') { // replace the trigger
7366                          o.supersedes = o.supersedes || [];
7367                          o.supersedes.push(trigger);
7368                      }
7369                      // before the trigger
7370                          // the trigger requires the conditional mod,
7371                          // so it should appear before the conditional
7372                          // mod if we do not intersede.
7373                  } else { // after the trigger
7374                      o.after = o.after || [];
7375                      o.after.push(trigger);
7376                  }
7377              }
7378          }
7379  
7380          if (o.supersedes) {
7381              o.supersedes = this.filterRequires(o.supersedes);
7382          }
7383  
7384          if (o.after) {
7385              o.after = this.filterRequires(o.after);
7386              o.after_map = yArray.hash(o.after);
7387          }
7388  
7389          // this.dirty = true;
7390  
7391          if (o.configFn) {
7392              ret = o.configFn(o);
7393              if (ret === false) {
7394                  delete this.moduleInfo[name];
7395                  delete GLOBAL_ENV._renderedMods[name];
7396                  o = null;
7397              }
7398          }
7399          //Add to global cache
7400          if (o) {
7401              if (!GLOBAL_ENV._renderedMods) {
7402                  GLOBAL_ENV._renderedMods = {};
7403              }
7404              GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o);
7405              GLOBAL_ENV._conditions = conditions;
7406          }
7407  
7408          return o;
7409      },
7410  
7411      /**
7412       * Add a requirement for one or more module
7413       * @method require
7414       * @param {string[] | string*} what the modules to load.
7415       */
7416      require: function(what) {
7417          var a = (typeof what === 'string') ? yArray(arguments) : what;
7418          this.dirty = true;
7419          this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a)));
7420  
7421          this._explodeRollups();
7422      },
7423      /**
7424      * Grab all the items that were asked for, check to see if the Loader
7425      * meta-data contains a "use" array. If it doesm remove the asked item and replace it with
7426      * the content of the "use".
7427      * This will make asking for: "dd"
7428      * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin"
7429      * @private
7430      * @method _explodeRollups
7431      */
7432      _explodeRollups: function() {
7433          var self = this, m, m2, i, a, v, len, len2,
7434          r = self.required;
7435  
7436          if (!self.allowRollup) {
7437              for (i in r) {
7438                  if (r.hasOwnProperty(i)) {
7439                      m = self.getModule(i);
7440                      if (m && m.use) {
7441                          len = m.use.length;
7442                          for (a = 0; a < len; a++) {
7443                              m2 = self.getModule(m.use[a]);
7444                              if (m2 && m2.use) {
7445                                  len2 = m2.use.length;
7446                                  for (v = 0; v < len2; v++) {
7447                                      r[m2.use[v]] = true;
7448                                  }
7449                              } else {
7450                                  r[m.use[a]] = true;
7451                              }
7452                          }
7453                      }
7454                  }
7455              }
7456              self.required = r;
7457          }
7458  
7459      },
7460      /**
7461      * Explodes the required array to remove aliases and replace them with real modules
7462      * @method filterRequires
7463      * @param {Array} r The original requires array
7464      * @return {Array} The new array of exploded requirements
7465      */
7466      filterRequires: function(r) {
7467          if (r) {
7468              if (!Y.Lang.isArray(r)) {
7469                  r = [r];
7470              }
7471              r = Y.Array(r);
7472              var c = [], i, mod, o, m;
7473  
7474              for (i = 0; i < r.length; i++) {
7475                  mod = this.getModule(r[i]);
7476                  if (mod && mod.use) {
7477                      for (o = 0; o < mod.use.length; o++) {
7478                          //Must walk the other modules in case a module is a rollup of rollups (datatype)
7479                          m = this.getModule(mod.use[o]);
7480                          if (m && m.use && (m.name !== mod.name)) {
7481                              c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use)));
7482                          } else {
7483                              c.push(mod.use[o]);
7484                          }
7485                      }
7486                  } else {
7487                      c.push(r[i]);
7488                  }
7489              }
7490              r = c;
7491          }
7492          return r;
7493      },
7494  
7495      /**
7496      Returns `true` if the module can be attached to the YUI instance. Runs
7497      the module's test if there is one and caches its result.
7498  
7499      @method _canBeAttached
7500      @param {String} module Name of the module to check.
7501      @return {Boolean} Result of the module's test if it has one, or `true`.
7502      **/
7503      _canBeAttached: function (m) {
7504          m = this.getModule(m);
7505          if (m && m.test) {
7506              if (!m.hasOwnProperty('_testResult')) {
7507                  m._testResult = m.test(Y);
7508              }
7509              return m._testResult;
7510          }
7511          // return `true` for modules not registered as Loader will know what
7512          // to do with them later on
7513          return true;
7514      },
7515  
7516      /**
7517       * Returns an object containing properties for all modules required
7518       * in order to load the requested module
7519       * @method getRequires
7520       * @param {object}  mod The module definition from moduleInfo.
7521       * @return {array} the expanded requirement list.
7522       */
7523      getRequires: function(mod) {
7524  
7525          if (!mod) {
7526              //console.log('returning no reqs for ' + mod.name);
7527              return NO_REQUIREMENTS;
7528          }
7529  
7530          if (mod._parsed) {
7531              //console.log('returning requires for ' + mod.name, mod.requires);
7532              return mod.expanded || NO_REQUIREMENTS;
7533          }
7534  
7535          //TODO add modue cache here out of scope..
7536  
7537          var i, m, j, length, add, packName, lang, testresults = this.testresults,
7538              name = mod.name, cond,
7539              adddef = ON_PAGE[name] && ON_PAGE[name].details,
7540              optReqs = mod.optionalRequires,
7541              d, go, def,
7542              r, old_mod,
7543              o, skinmod, skindef, skinpar, skinname,
7544              intl = mod.lang || mod.intl,
7545              ftests = Y.Features && Y.Features.tests.load,
7546              hash, reparse;
7547  
7548          // console.log(name);
7549  
7550          // pattern match leaves module stub that needs to be filled out
7551          if (mod.temp && adddef) {
7552              old_mod = mod;
7553              mod = this.addModule(adddef, name);
7554              mod.group = old_mod.group;
7555              mod.pkg = old_mod.pkg;
7556              delete mod.expanded;
7557          }
7558  
7559          // console.log('cache: ' + mod.langCache + ' == ' + this.lang);
7560  
7561          //If a skin or a lang is different, reparse..
7562          reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin));
7563  
7564          if (mod.expanded && !reparse) {
7565              return mod.expanded;
7566          }
7567  
7568          // Optional dependencies are dependencies that may or may not be
7569          // available.
7570          // This feature was designed specifically to be used when transpiling
7571          // ES6 modules, in order to use polyfills and regular scripts that define
7572          // global variables without having to import them since they should be
7573          // available in the global scope.
7574          if (optReqs) {
7575              for (i = 0, length = optReqs.length; i < length; i++) {
7576                  if (this._canBeAttached(optReqs[i])) {
7577                      mod.requires.push(optReqs[i]);
7578                  }
7579              }
7580          }
7581  
7582          d = [];
7583          hash = {};
7584          r = this.filterRequires(mod.requires);
7585          if (mod.lang) {
7586              //If a module has a lang attribute, auto add the intl requirement.
7587              d.unshift('intl');
7588              r.unshift('intl');
7589              intl = true;
7590          }
7591          o = this.filterRequires(mod.optional);
7592  
7593  
7594          mod._parsed = true;
7595          mod.langCache = this.lang;
7596          mod.skinCache = this.skin.defaultSkin;
7597  
7598          for (i = 0; i < r.length; i++) {
7599              if (!hash[r[i]]) {
7600                  d.push(r[i]);
7601                  hash[r[i]] = true;
7602                  m = this.getModule(r[i]);
7603                  if (m) {
7604                      add = this.getRequires(m);
7605                      intl = intl || (m.expanded_map &&
7606                          (INTL in m.expanded_map));
7607                      for (j = 0; j < add.length; j++) {
7608                          d.push(add[j]);
7609                      }
7610                  }
7611              }
7612          }
7613  
7614          // get the requirements from superseded modules, if any
7615          r = this.filterRequires(mod.supersedes);
7616          if (r) {
7617              for (i = 0; i < r.length; i++) {
7618                  if (!hash[r[i]]) {
7619                      // if this module has submodules, the requirements list is
7620                      // expanded to include the submodules.  This is so we can
7621                      // prevent dups when a submodule is already loaded and the
7622                      // parent is requested.
7623                      if (mod.submodules) {
7624                          d.push(r[i]);
7625                      }
7626  
7627                      hash[r[i]] = true;
7628                      m = this.getModule(r[i]);
7629  
7630                      if (m) {
7631                          add = this.getRequires(m);
7632                          intl = intl || (m.expanded_map &&
7633                              (INTL in m.expanded_map));
7634                          for (j = 0; j < add.length; j++) {
7635                              d.push(add[j]);
7636                          }
7637                      }
7638                  }
7639              }
7640          }
7641  
7642          if (o && this.loadOptional) {
7643              for (i = 0; i < o.length; i++) {
7644                  if (!hash[o[i]]) {
7645                      d.push(o[i]);
7646                      hash[o[i]] = true;
7647                      m = this.getModuleInfo(o[i]);
7648                      if (m) {
7649                          add = this.getRequires(m);
7650                          intl = intl || (m.expanded_map &&
7651                              (INTL in m.expanded_map));
7652                          for (j = 0; j < add.length; j++) {
7653                              d.push(add[j]);
7654                          }
7655                      }
7656                  }
7657              }
7658          }
7659  
7660          cond = this.conditions[name];
7661  
7662          if (cond) {
7663              //Set the module to not parsed since we have conditionals and this could change the dependency tree.
7664              mod._parsed = false;
7665              if (testresults && ftests) {
7666                  oeach(testresults, function(result, id) {
7667                      var condmod = ftests[id].name;
7668                      if (!hash[condmod] && ftests[id].trigger === name) {
7669                          if (result && ftests[id]) {
7670                              hash[condmod] = true;
7671                              d.push(condmod);
7672                          }
7673                      }
7674                  });
7675              } else {
7676                  for (i in cond) {
7677                      if (cond.hasOwnProperty(i)) {
7678                          if (!hash[i]) {
7679                              def = cond[i];
7680                              //first see if they've specfied a ua check
7681                              //then see if they've got a test fn & if it returns true
7682                              //otherwise just having a condition block is enough
7683                              go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) ||
7684                                          (def.test && def.test(Y, r)));
7685  
7686                              if (go) {
7687                                  hash[i] = true;
7688                                  d.push(i);
7689                                  m = this.getModule(i);
7690                                  if (m) {
7691                                      add = this.getRequires(m);
7692                                      for (j = 0; j < add.length; j++) {
7693                                          d.push(add[j]);
7694                                      }
7695  
7696                                  }
7697                              }
7698                          }
7699                      }
7700                  }
7701              }
7702          }
7703  
7704          // Create skin modules
7705          if (mod.skinnable) {
7706              skindef = this.skin.overrides;
7707              for (i in YUI.Env.aliases) {
7708                  if (YUI.Env.aliases.hasOwnProperty(i)) {
7709                      if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) {
7710                          skinpar = i;
7711                      }
7712                  }
7713              }
7714              if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) {
7715                  skinname = name;
7716                  if (skindef[skinpar]) {
7717                      skinname = skinpar;
7718                  }
7719                  for (i = 0; i < skindef[skinname].length; i++) {
7720                      skinmod = this._addSkin(skindef[skinname][i], name);
7721                      if (!this.isCSSLoaded(skinmod, this._boot)) {
7722                          d.push(skinmod);
7723                      }
7724                  }
7725              } else {
7726                  skinmod = this._addSkin(this.skin.defaultSkin, name);
7727                  if (!this.isCSSLoaded(skinmod, this._boot)) {
7728                      d.push(skinmod);
7729                  }
7730              }
7731          }
7732  
7733          mod._parsed = false;
7734  
7735          if (intl) {
7736  
7737              if (mod.lang && !mod.langPack && Y.Intl) {
7738                  lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang);
7739                  packName = this.getLangPackName(lang, name);
7740                  if (packName) {
7741                      d.unshift(packName);
7742                  }
7743              }
7744              d.unshift(INTL);
7745          }
7746  
7747          mod.expanded_map = yArray.hash(d);
7748  
7749          mod.expanded = YObject.keys(mod.expanded_map);
7750  
7751          return mod.expanded;
7752      },
7753      /**
7754      * Check to see if named css module is already loaded on the page
7755      * @method isCSSLoaded
7756      * @param {String} name The name of the css file
7757      * @param {Boolean} skip To skip the short-circuit for ignoreRegister
7758      * @return Boolean
7759      */
7760      isCSSLoaded: function(name, skip) {
7761          //TODO - Make this call a batching call with name being an array
7762          if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) {
7763              return false;
7764          }
7765          var el = YUI.Env.cssStampEl,
7766              ret = false,
7767              mod = YUI.Env._cssLoaded[name],
7768              style = el.currentStyle; //IE
7769  
7770  
7771          if (mod !== undefined) {
7772              return mod;
7773          }
7774  
7775          //Add the classname to the element
7776          el.className = name;
7777  
7778          if (!style) {
7779              style = Y.config.doc.defaultView.getComputedStyle(el, null);
7780          }
7781  
7782          if (style && style.display === 'none') {
7783              ret = true;
7784          }
7785  
7786  
7787          el.className = ''; //Reset the classname to ''
7788  
7789          YUI.Env._cssLoaded[name] = ret;
7790  
7791          return ret;
7792      },
7793  
7794      /**
7795       * Returns a hash of module names the supplied module satisfies.
7796       * @method getProvides
7797       * @param {string} name The name of the module.
7798       * @return {object} what this module provides.
7799       */
7800      getProvides: function(name) {
7801          var m = this.getModule(name), o, s;
7802              // supmap = this.provides;
7803  
7804          if (!m) {
7805              return NOT_FOUND;
7806          }
7807  
7808          if (m && !m.provides) {
7809              o = {};
7810              s = m.supersedes;
7811  
7812              if (s) {
7813                  yArray.each(s, function(v) {
7814                      Y.mix(o, this.getProvides(v));
7815                  }, this);
7816              }
7817  
7818              o[name] = true;
7819              m.provides = o;
7820  
7821          }
7822  
7823          return m.provides;
7824      },
7825  
7826      /**
7827       * Calculates the dependency tree, the result is stored in the sorted
7828       * property.
7829       * @method calculate
7830       * @param {object} o optional options object.
7831       * @param {string} type optional argument to prune modules.
7832       */
7833      calculate: function(o, type) {
7834          if (o || type || this.dirty) {
7835  
7836              if (o) {
7837                  this._config(o);
7838              }
7839  
7840              if (!this._init) {
7841                  this._setup();
7842              }
7843  
7844              this._explode();
7845  
7846              if (this.allowRollup) {
7847                  this._rollup();
7848              } else {
7849                  this._explodeRollups();
7850              }
7851              this._reduce();
7852              this._sort();
7853          }
7854      },
7855      /**
7856      * Creates a "psuedo" package for languages provided in the lang array
7857      * @method _addLangPack
7858      * @private
7859      * @param {String} lang The language to create
7860      * @param {Object} m The module definition to create the language pack around
7861      * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US)
7862      * @return {Object} The module definition
7863      */
7864      _addLangPack: function(lang, m, packName) {
7865          var name = m.name,
7866              packPath, conf,
7867              existing = this.getModuleInfo(packName);
7868  
7869          if (!existing) {
7870  
7871              packPath = _path((m.pkg || name), packName, JS, true);
7872  
7873              conf = {
7874                  path: packPath,
7875                  intl: true,
7876                  langPack: true,
7877                  ext: m.ext,
7878                  group: m.group,
7879                  supersedes: []
7880              };
7881              if (m.root) {
7882                  conf.root = m.root;
7883              }
7884              if (m.base) {
7885                  conf.base = m.base;
7886              }
7887  
7888              if (m.configFn) {
7889                  conf.configFn = m.configFn;
7890              }
7891  
7892              this.addModule(conf, packName);
7893  
7894              if (lang) {
7895                  Y.Env.lang = Y.Env.lang || {};
7896                  Y.Env.lang[lang] = Y.Env.lang[lang] || {};
7897                  Y.Env.lang[lang][name] = true;
7898              }
7899          }
7900  
7901          return this.getModuleInfo(packName);
7902      },
7903  
7904      /**
7905       * Investigates the current YUI configuration on the page.  By default,
7906       * modules already detected will not be loaded again unless a force
7907       * option is encountered.  Called by calculate()
7908       * @method _setup
7909       * @private
7910       */
7911      _setup: function() {
7912          var info = this.moduleInfo, name, i, j, m, l,
7913              packName;
7914  
7915          for (name in info) {
7916              if (info.hasOwnProperty(name)) {
7917                  m = info[name];
7918                  if (m) {
7919  
7920                      // remove dups
7921                      //m.requires = YObject.keys(yArray.hash(m.requires));
7922                      m.requires = yArray.dedupe(m.requires);
7923  
7924                      // Create lang pack modules
7925                      //if (m.lang && m.lang.length) {
7926                      if (m.lang) {
7927                          // Setup root package if the module has lang defined,
7928                          // it needs to provide a root language pack
7929                          packName = this.getLangPackName(ROOT_LANG, name);
7930                          this._addLangPack(null, m, packName);
7931                      }
7932  
7933                  }
7934              }
7935          }
7936  
7937  
7938          //l = Y.merge(this.inserted);
7939          l = {};
7940  
7941          // available modules
7942          if (!this.ignoreRegistered) {
7943              Y.mix(l, GLOBAL_ENV.mods);
7944          }
7945  
7946          // add the ignore list to the list of loaded packages
7947          if (this.ignore) {
7948              Y.mix(l, yArray.hash(this.ignore));
7949          }
7950  
7951          // expand the list to include superseded modules
7952          for (j in l) {
7953              if (l.hasOwnProperty(j)) {
7954                  Y.mix(l, this.getProvides(j));
7955              }
7956          }
7957  
7958          // remove modules on the force list from the loaded list
7959          if (this.force) {
7960              for (i = 0; i < this.force.length; i++) {
7961                  if (this.force[i] in l) {
7962                      delete l[this.force[i]];
7963                  }
7964              }
7965          }
7966  
7967          Y.mix(this.loaded, l);
7968  
7969          this._init = true;
7970      },
7971  
7972      /**
7973       * Builds a module name for a language pack
7974       * @method getLangPackName
7975       * @param {string} lang the language code.
7976       * @param {string} mname the module to build it for.
7977       * @return {string} the language pack module name.
7978       */
7979      getLangPackName: function(lang, mname) {
7980          return ('lang/' + mname + ((lang) ? '_' + lang : ''));
7981      },
7982      /**
7983       * Inspects the required modules list looking for additional
7984       * dependencies.  Expands the required list to include all
7985       * required modules.  Called by calculate()
7986       * @method _explode
7987       * @private
7988       */
7989      _explode: function() {
7990          //TODO Move done out of scope
7991          var r = this.required, m, reqs, done = {},
7992              self = this, name, expound;
7993  
7994          // the setup phase is over, all modules have been created
7995          self.dirty = false;
7996  
7997          self._explodeRollups();
7998          r = self.required;
7999  
8000          for (name in r) {
8001              if (r.hasOwnProperty(name)) {
8002                  if (!done[name]) {
8003                      done[name] = true;
8004                      m = self.getModule(name);
8005                      if (m) {
8006                          expound = m.expound;
8007  
8008                          if (expound) {
8009                              r[expound] = self.getModule(expound);
8010                              reqs = self.getRequires(r[expound]);
8011                              Y.mix(r, yArray.hash(reqs));
8012                          }
8013  
8014                          reqs = self.getRequires(m);
8015                          Y.mix(r, yArray.hash(reqs));
8016                      }
8017                  }
8018              }
8019          }
8020  
8021      },
8022      /**
8023      * The default method used to test a module against a pattern
8024      * @method _patternTest
8025      * @private
8026      * @param {String} mname The module being tested
8027      * @param {String} pname The pattern to match
8028      */
8029      _patternTest: function(mname, pname) {
8030          return (mname.indexOf(pname) > -1);
8031      },
8032      /**
8033      * Get's the loader meta data for the requested module
8034      * @method getModule
8035      * @param {String} mname The module name to get
8036      * @return {Object} The module metadata
8037      */
8038      getModule: function(mname) {
8039          //TODO: Remove name check - it's a quick hack to fix pattern WIP
8040          if (!mname) {
8041              return null;
8042          }
8043  
8044          var p, found, pname,
8045              m = this.getModuleInfo(mname),
8046              patterns = this.patterns;
8047  
8048          // check the patterns library to see if we should automatically add
8049          // the module with defaults
8050          if (!m || (m && m.ext)) {
8051              for (pname in patterns) {
8052                  if (patterns.hasOwnProperty(pname)) {
8053                      p = patterns[pname];
8054  
8055                      //There is no test method, create a default one that tests
8056                      // the pattern against the mod name
8057                      if (!p.test) {
8058                          p.test = this._patternTest;
8059                      }
8060  
8061                      if (p.test(mname, pname)) {
8062                          // use the metadata supplied for the pattern
8063                          // as the module definition.
8064                          found = p;
8065                          break;
8066                      }
8067                  }
8068              }
8069          }
8070  
8071          if (!m) {
8072              if (found) {
8073                  if (p.action) {
8074                      p.action.call(this, mname, pname);
8075                  } else {
8076                      // ext true or false?
8077                      m = this.addModule(Y.merge(found, {
8078                          test: void 0,
8079                          temp: true
8080                      }), mname);
8081                      if (found.configFn) {
8082                          m.configFn = found.configFn;
8083                      }
8084                  }
8085              }
8086          } else {
8087              if (found && m && found.configFn && !m.configFn) {
8088                  m.configFn = found.configFn;
8089                  m.configFn(m);
8090              }
8091          }
8092  
8093          return m;
8094      },
8095  
8096      // impl in rollup submodule
8097      _rollup: function() { },
8098  
8099      /**
8100       * Remove superceded modules and loaded modules.  Called by
8101       * calculate() after we have the mega list of all dependencies
8102       * @method _reduce
8103       * @return {object} the reduced dependency hash.
8104       * @private
8105       */
8106      _reduce: function(r) {
8107  
8108          r = r || this.required;
8109  
8110          var i, j, s, m, type = this.loadType,
8111          ignore = this.ignore ? yArray.hash(this.ignore) : false;
8112  
8113          for (i in r) {
8114              if (r.hasOwnProperty(i)) {
8115                  m = this.getModule(i);
8116                  // remove if already loaded
8117                  if (((this.loaded[i] || ON_PAGE[i]) &&
8118                          !this.forceMap[i] && !this.ignoreRegistered) ||
8119                          (type && m && m.type !== type)) {
8120                      delete r[i];
8121                  }
8122                  if (ignore && ignore[i]) {
8123                      delete r[i];
8124                  }
8125                  // remove anything this module supersedes
8126                  s = m && m.supersedes;
8127                  if (s) {
8128                      for (j = 0; j < s.length; j++) {
8129                          if (s[j] in r) {
8130                              delete r[s[j]];
8131                          }
8132                      }
8133                  }
8134              }
8135          }
8136  
8137          return r;
8138      },
8139      /**
8140      * Handles the queue when a module has been loaded for all cases
8141      * @method _finish
8142      * @private
8143      * @param {String} msg The message from Loader
8144      * @param {Boolean} success A boolean denoting success or failure
8145      */
8146      _finish: function(msg, success) {
8147  
8148          _queue.running = false;
8149  
8150          var onEnd = this.onEnd;
8151          if (onEnd) {
8152              onEnd.call(this.context, {
8153                  msg: msg,
8154                  data: this.data,
8155                  success: success
8156              });
8157          }
8158          this._continue();
8159      },
8160      /**
8161      * The default Loader onSuccess handler, calls this.onSuccess with a payload
8162      * @method _onSuccess
8163      * @private
8164      */
8165      _onSuccess: function() {
8166          var self = this, skipped = Y.merge(self.skipped), fn,
8167              failed = [], rreg = self.requireRegistration,
8168              success, msg, i, mod;
8169  
8170          for (i in skipped) {
8171              if (skipped.hasOwnProperty(i)) {
8172                  delete self.inserted[i];
8173              }
8174          }
8175  
8176          self.skipped = {};
8177  
8178          for (i in self.inserted) {
8179              if (self.inserted.hasOwnProperty(i)) {
8180                  mod = self.getModule(i);
8181                  if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) {
8182                      failed.push(i);
8183                  } else {
8184                      Y.mix(self.loaded, self.getProvides(i));
8185                  }
8186              }
8187          }
8188  
8189          fn = self.onSuccess;
8190          msg = (failed.length) ? 'notregistered' : 'success';
8191          success = !(failed.length);
8192          if (fn) {
8193              fn.call(self.context, {
8194                  msg: msg,
8195                  data: self.data,
8196                  success: success,
8197                  failed: failed,
8198                  skipped: skipped
8199              });
8200          }
8201          self._finish(msg, success);
8202      },
8203      /**
8204      * The default Loader onProgress handler, calls this.onProgress with a payload
8205      * @method _onProgress
8206      * @private
8207      */
8208      _onProgress: function(e) {
8209          var self = this, i;
8210          //set the internal cache to what just came in.
8211          if (e.data && e.data.length) {
8212              for (i = 0; i < e.data.length; i++) {
8213                  e.data[i] = self.getModule(e.data[i].name);
8214              }
8215          }
8216          if (self.onProgress) {
8217              self.onProgress.call(self.context, {
8218                  name: e.url,
8219                  data: e.data
8220              });
8221          }
8222      },
8223      /**
8224      * The default Loader onFailure handler, calls this.onFailure with a payload
8225      * @method _onFailure
8226      * @private
8227      */
8228      _onFailure: function(o) {
8229          var f = this.onFailure, msg = [], i = 0, len = o.errors.length;
8230  
8231          for (i; i < len; i++) {
8232              msg.push(o.errors[i].error);
8233          }
8234  
8235          msg = msg.join(',');
8236  
8237  
8238          if (f) {
8239              f.call(this.context, {
8240                  msg: msg,
8241                  data: this.data,
8242                  success: false
8243              });
8244          }
8245  
8246          this._finish(msg, false);
8247  
8248      },
8249  
8250      /**
8251      * The default Loader onTimeout handler, calls this.onTimeout with a payload
8252      * @method _onTimeout
8253      * @param {Get.Transaction} transaction The Transaction object from `Y.Get`
8254      * @private
8255      */
8256      _onTimeout: function(transaction) {
8257          var f = this.onTimeout;
8258          if (f) {
8259              f.call(this.context, {
8260                  msg: 'timeout',
8261                  data: this.data,
8262                  success: false,
8263                  transaction: transaction
8264              });
8265          }
8266      },
8267  
8268      /**
8269       * Sorts the dependency tree.  The last step of calculate()
8270       * @method _sort
8271       * @private
8272       */
8273      _sort: function() {
8274          var name,
8275  
8276              // Object containing module names.
8277              required = this.required,
8278  
8279              // Keep track of whether we've visited a module.
8280              visited = {};
8281  
8282          // Will contain modules names, in the correct order,
8283          // according to dependencies.
8284          this.sorted = [];
8285  
8286          for (name in required) {
8287              if (!visited[name] && required.hasOwnProperty(name)) {
8288                  this._visit(name, visited);
8289              }
8290          }
8291      },
8292  
8293      /**
8294       * Recursively visits the dependencies of the module name
8295       * passed in, and appends each module name to the `sorted` property.
8296       * @param {String} name The name of a module.
8297       * @param {Object} visited Keeps track of whether a module was visited.
8298       * @method _visit
8299       * @private
8300       */
8301      _visit: function (name, visited) {
8302          var required, condition, moduleInfo, dependency, dependencies,
8303              trigger, isAfter, i, l;
8304  
8305          visited[name] = true;
8306          required = this.required;
8307          moduleInfo = this.moduleInfo[name];
8308          condition = this.conditions[name] || {};
8309  
8310          if (moduleInfo) {
8311              // Recurse on each dependency of this module,
8312              // figuring out its dependencies, and so on.
8313              dependencies = moduleInfo.expanded || moduleInfo.requires;
8314  
8315              for (i = 0, l = dependencies.length; i < l; ++i) {
8316                  dependency = dependencies[i];
8317                  trigger = condition[dependency];
8318  
8319                  // We cannot process this dependency yet if it must
8320                  // appear after our current module.
8321                  isAfter = trigger && (!trigger.when || trigger.when === "after");
8322  
8323                  // Is this module name in the required list of modules,
8324                  // and have we not already visited it?
8325                  if (required[dependency] && !visited[dependency] && !isAfter) {
8326                      this._visit(dependency, visited);
8327                  }
8328              }
8329          }
8330  
8331          this.sorted.push(name);
8332      },
8333  
8334      /**
8335      * Handles the actual insertion of script/link tags
8336      * @method _insert
8337      * @private
8338      * @param {Object} source The YUI instance the request came from
8339      * @param {Object} o The metadata to include
8340      * @param {String} type JS or CSS
8341      * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta
8342      */
8343      _insert: function(source, o, type, skipcalc) {
8344  
8345  
8346          // restore the state at the time of the request
8347          if (source) {
8348              this._config(source);
8349          }
8350  
8351          // build the dependency list
8352          // don't include type so we can process CSS and script in
8353          // one pass when the type is not specified.
8354  
8355          var modules = this.resolve(!skipcalc),
8356              self = this, comp = 0, actions = 0,
8357              mods = {}, deps, complete;
8358  
8359          self._refetch = [];
8360  
8361          if (type) {
8362              //Filter out the opposite type and reset the array so the checks later work
8363              modules[((type === JS) ? CSS : JS)] = [];
8364          }
8365          if (!self.fetchCSS) {
8366              modules.css = [];
8367          }
8368          if (modules.js.length) {
8369              comp++;
8370          }
8371          if (modules.css.length) {
8372              comp++;
8373          }
8374  
8375          //console.log('Resolved Modules: ', modules);
8376  
8377          complete = function(d) {
8378              actions++;
8379              var errs = {}, i = 0, o = 0, u = '', fn,
8380                  modName, resMods;
8381  
8382              if (d && d.errors) {
8383                  for (i = 0; i < d.errors.length; i++) {
8384                      if (d.errors[i].request) {
8385                          u = d.errors[i].request.url;
8386                      } else {
8387                          u = d.errors[i];
8388                      }
8389                      errs[u] = u;
8390                  }
8391              }
8392  
8393              if (d && d.data && d.data.length && (d.type === 'success')) {
8394                  for (i = 0; i < d.data.length; i++) {
8395                      self.inserted[d.data[i].name] = true;
8396                      //If the external module has a skin or a lang, reprocess it
8397                      if (d.data[i].lang || d.data[i].skinnable) {
8398                          delete self.inserted[d.data[i].name];
8399                          self._refetch.push(d.data[i].name);
8400                      }
8401                  }
8402              }
8403  
8404              if (actions === comp) {
8405                  self._loading = null;
8406                  if (self._refetch.length) {
8407                      //Get the deps for the new meta-data and reprocess
8408                      for (i = 0; i < self._refetch.length; i++) {
8409                          deps = self.getRequires(self.getModule(self._refetch[i]));
8410                          for (o = 0; o < deps.length; o++) {
8411                              if (!self.inserted[deps[o]]) {
8412                                  //We wouldn't be to this point without the module being here
8413                                  mods[deps[o]] = deps[o];
8414                              }
8415                          }
8416                      }
8417                      mods = Y.Object.keys(mods);
8418                      if (mods.length) {
8419                          self.require(mods);
8420                          resMods = self.resolve(true);
8421                          if (resMods.cssMods.length) {
8422                              for (i=0; i <  resMods.cssMods.length; i++) {
8423                                  modName = resMods.cssMods[i].name;
8424                                  delete YUI.Env._cssLoaded[modName];
8425                                  if (self.isCSSLoaded(modName)) {
8426                                      self.inserted[modName] = true;
8427                                      delete self.required[modName];
8428                                  }
8429                              }
8430                              self.sorted = [];
8431                              self._sort();
8432                          }
8433                          d = null; //bail
8434                          self._insert(); //insert the new deps
8435                      }
8436                  }
8437                  if (d && d.fn) {
8438                      fn = d.fn;
8439                      delete d.fn;
8440                      fn.call(self, d);
8441                  }
8442              }
8443          };
8444  
8445          this._loading = true;
8446  
8447          if (!modules.js.length && !modules.css.length) {
8448              actions = -1;
8449              complete({
8450                  fn: self._onSuccess
8451              });
8452              return;
8453          }
8454  
8455  
8456          if (modules.css.length) { //Load CSS first
8457              Y.Get.css(modules.css, {
8458                  data: modules.cssMods,
8459                  attributes: self.cssAttributes,
8460                  insertBefore: self.insertBefore,
8461                  charset: self.charset,
8462                  timeout: self.timeout,
8463                  context: self,
8464                  onProgress: function(e) {
8465                      self._onProgress.call(self, e);
8466                  },
8467                  onTimeout: function(d) {
8468                      self._onTimeout.call(self, d);
8469                  },
8470                  onSuccess: function(d) {
8471                      d.type = 'success';
8472                      d.fn = self._onSuccess;
8473                      complete.call(self, d);
8474                  },
8475                  onFailure: function(d) {
8476                      d.type = 'failure';
8477                      d.fn = self._onFailure;
8478                      complete.call(self, d);
8479                  }
8480              });
8481          }
8482  
8483          if (modules.js.length) {
8484              Y.Get.js(modules.js, {
8485                  data: modules.jsMods,
8486                  insertBefore: self.insertBefore,
8487                  attributes: self.jsAttributes,
8488                  charset: self.charset,
8489                  timeout: self.timeout,
8490                  autopurge: false,
8491                  context: self,
8492                  async: self.async,
8493                  onProgress: function(e) {
8494                      self._onProgress.call(self, e);
8495                  },
8496                  onTimeout: function(d) {
8497                      self._onTimeout.call(self, d);
8498                  },
8499                  onSuccess: function(d) {
8500                      d.type = 'success';
8501                      d.fn = self._onSuccess;
8502                      complete.call(self, d);
8503                  },
8504                  onFailure: function(d) {
8505                      d.type = 'failure';
8506                      d.fn = self._onFailure;
8507                      complete.call(self, d);
8508                  }
8509              });
8510          }
8511      },
8512      /**
8513      * Once a loader operation is completely finished, process any additional queued items.
8514      * @method _continue
8515      * @private
8516      */
8517      _continue: function() {
8518          if (!(_queue.running) && _queue.size() > 0) {
8519              _queue.running = true;
8520              _queue.next()();
8521          }
8522      },
8523  
8524      /**
8525       * inserts the requested modules and their dependencies.
8526       * <code>type</code> can be "js" or "css".  Both script and
8527       * css are inserted if type is not provided.
8528       * @method insert
8529       * @param {object} o optional options object.
8530       * @param {string} type the type of dependency to insert.
8531       */
8532      insert: function(o, type, skipsort) {
8533          var self = this, copy = Y.merge(this);
8534          delete copy.require;
8535          delete copy.dirty;
8536          _queue.add(function() {
8537              self._insert(copy, o, type, skipsort);
8538          });
8539          this._continue();
8540      },
8541  
8542      /**
8543       * Executed every time a module is loaded, and if we are in a load
8544       * cycle, we attempt to load the next script.  Public so that it
8545       * is possible to call this if using a method other than
8546       * Y.register to determine when scripts are fully loaded
8547       * @method loadNext
8548       * @deprecated
8549       * @param {string} mname optional the name of the module that has
8550       * been loaded (which is usually why it is time to load the next
8551       * one).
8552       */
8553      loadNext: function() {
8554          return;
8555      },
8556  
8557      /**
8558       * Apply filter defined for this instance to a url/path
8559       * @method _filter
8560       * @param {string} u the string to filter.
8561       * @param {string} name the name of the module, if we are processing
8562       * a single module as opposed to a combined url.
8563       * @return {string} the filtered string.
8564       * @private
8565       */
8566      _filter: function(u, name, group) {
8567          var f = this.filter,
8568              hasFilter = name && (name in this.filters),
8569              modFilter = hasFilter && this.filters[name],
8570              groupName = group || (this.getModuleInfo(name) || {}).group || null;
8571  
8572          if (groupName && this.groups[groupName] && this.groups[groupName].filter) {
8573              modFilter = this.groups[groupName].filter;
8574              hasFilter = true;
8575          }
8576  
8577          if (u) {
8578              if (hasFilter) {
8579                  f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter;
8580              }
8581              if (f) {
8582                  u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr);
8583              }
8584          }
8585          return u;
8586      },
8587  
8588      /**
8589       * Generates the full url for a module
8590       * @method _url
8591       * @param {string} path the path fragment.
8592       * @param {String} name The name of the module
8593       * @param {String} [base] The base url to use. Defaults to self.base
8594       * @return {string} the full url.
8595       * @private
8596       */
8597      _url: function(path, name, base) {
8598          return this._filter((base || this.base || '') + path, name);
8599      },
8600      /**
8601      * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules.
8602      * @method resolve
8603      * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else
8604      * @param {Array} [sorted=loader.sorted] An override for the loader.sorted array
8605      * @return {Object} Object hash (js and css) of two arrays of file lists
8606      * @example This method can be used as an off-line dep calculator
8607      *
8608      *        var Y = YUI();
8609      *        var loader = new Y.Loader({
8610      *            filter: 'debug',
8611      *            base: '../../',
8612      *            root: 'build/',
8613      *            combine: true,
8614      *            require: ['node', 'dd', 'console']
8615      *        });
8616      *        var out = loader.resolve(true);
8617      *
8618      */
8619      resolve: function(calc, sorted) {
8620          var self     = this,
8621              resolved = { js: [], jsMods: [], css: [], cssMods: [] },
8622              addSingle;
8623  
8624          if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) {
8625              self._resetModules();
8626          }
8627  
8628          if (calc) {
8629              self.calculate();
8630          }
8631          sorted = sorted || self.sorted;
8632  
8633          addSingle = function(mod) {
8634              if (mod) {
8635                  var group = (mod.group && self.groups[mod.group]) || NOT_FOUND,
8636                      url;
8637  
8638                  //Always assume it's async
8639                  if (group.async === false) {
8640                      mod.async = group.async;
8641                  }
8642  
8643                  url = (mod.fullpath) ? self._filter(mod.fullpath, mod.name) :
8644                        self._url(mod.path, mod.name, group.base || mod.base);
8645  
8646                  if (mod.attributes || mod.async === false) {
8647                      url = {
8648                          url: url,
8649                          async: mod.async
8650                      };
8651                      if (mod.attributes) {
8652                          url.attributes = mod.attributes;
8653                      }
8654                  }
8655                  resolved[mod.type].push(url);
8656                  resolved[mod.type + 'Mods'].push(mod);
8657              } else {
8658              }
8659  
8660          };
8661  
8662          /*jslint vars: true */
8663          var inserted     = (self.ignoreRegistered) ? {} : self.inserted,
8664              comboSources = {},
8665              maxURLLength,
8666              comboMeta,
8667              comboBase,
8668              comboSep,
8669              group,
8670              mod,
8671              len,
8672              i;
8673          /*jslint vars: false */
8674  
8675          for (i = 0, len = sorted.length; i < len; i++) {
8676              mod = self.getModule(sorted[i]);
8677              if (!mod || inserted[mod.name]) {
8678                  continue;
8679              }
8680  
8681              group = self.groups[mod.group];
8682  
8683              comboBase = self.comboBase;
8684  
8685              if (group) {
8686                  if (!group.combine || mod.fullpath) {
8687                      //This is not a combo module, skip it and load it singly later.
8688                      addSingle(mod);
8689                      continue;
8690                  }
8691                  mod.combine = true;
8692  
8693                  if (typeof group.root === 'string') {
8694                      mod.root = group.root;
8695                  }
8696  
8697                  comboBase    = group.comboBase || comboBase;
8698                  comboSep     = group.comboSep;
8699                  maxURLLength = group.maxURLLength;
8700              } else {
8701                  if (!self.combine) {
8702                      //This is not a combo module, skip it and load it singly later.
8703                      addSingle(mod);
8704                      continue;
8705                  }
8706              }
8707  
8708              if (!mod.combine && mod.ext) {
8709                  addSingle(mod);
8710                  continue;
8711              }
8712  
8713              comboSources[comboBase] = comboSources[comboBase] ||
8714                  { js: [], jsMods: [], css: [], cssMods: [] };
8715  
8716              comboMeta               = comboSources[comboBase];
8717              comboMeta.group         = mod.group;
8718              comboMeta.comboSep      = comboSep || self.comboSep;
8719              comboMeta.maxURLLength  = maxURLLength || self.maxURLLength;
8720  
8721              comboMeta[mod.type + 'Mods'].push(mod);
8722          }
8723  
8724          // TODO: Refactor the encoding logic below into its own method.
8725  
8726          /*jslint vars: true */
8727          var fragSubset,
8728              modules,
8729              tmpBase,
8730              baseLen,
8731              frags,
8732              frag,
8733              type;
8734          /*jslint vars: false */
8735  
8736          for (comboBase in comboSources) {
8737              if (comboSources.hasOwnProperty(comboBase)) {
8738                  comboMeta    = comboSources[comboBase];
8739                  comboSep     = comboMeta.comboSep;
8740                  maxURLLength = comboMeta.maxURLLength;
8741                  for (type in comboMeta) {
8742                      if (type === JS || type === CSS) {
8743                          modules = comboMeta[type + 'Mods'];
8744                          frags = [];
8745                          for (i = 0, len = modules.length; i < len; i += 1) {
8746                              mod = modules[i];
8747                              frag = ((typeof mod.root === 'string') ? mod.root : self.root) + (mod.path || mod.fullpath);
8748                              frags.push(
8749                                  self._filter(frag, mod.name)
8750                              );
8751                          }
8752                          tmpBase = comboBase + frags.join(comboSep);
8753                          baseLen = tmpBase.length;
8754                          if (maxURLLength <= comboBase.length) {
8755                              maxURLLength = MAX_URL_LENGTH;
8756                          }
8757  
8758                          if (frags.length) {
8759                              if (baseLen > maxURLLength) {
8760                                  fragSubset = [];
8761                                  for (i = 0, len = frags.length; i < len; i++) {
8762                                      fragSubset.push(frags[i]);
8763                                      tmpBase = comboBase + fragSubset.join(comboSep);
8764  
8765                                      if (tmpBase.length > maxURLLength) {
8766                                          frag = fragSubset.pop();
8767                                          tmpBase = comboBase + fragSubset.join(comboSep);
8768                                          resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8769                                          fragSubset = [];
8770                                          if (frag) {
8771                                              fragSubset.push(frag);
8772                                          }
8773                                      }
8774                                  }
8775                                  if (fragSubset.length) {
8776                                      tmpBase = comboBase + fragSubset.join(comboSep);
8777                                      resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8778                                  }
8779                              } else {
8780                                  resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
8781                              }
8782                          }
8783                          resolved[type + 'Mods'] = resolved[type + 'Mods'].concat(modules);
8784                      }
8785                  }
8786              }
8787          }
8788  
8789          return resolved;
8790      },
8791  
8792      /**
8793      Shortcut to calculate, resolve and load all modules.
8794  
8795          var loader = new Y.Loader({
8796              ignoreRegistered: true,
8797              modules: {
8798                  mod: {
8799                      path: 'mod.js'
8800                  }
8801              },
8802              requires: [ 'mod' ]
8803          });
8804          loader.load(function() {
8805              console.log('All modules have loaded..');
8806          });
8807  
8808  
8809      @method load
8810      @param {Function} cb Executed after all load operations are complete
8811      */
8812      load: function(cb) {
8813          if (!cb) {
8814              return;
8815          }
8816          var self = this,
8817              out = self.resolve(true);
8818  
8819          self.data = out;
8820  
8821          self.onEnd = function() {
8822              cb.apply(self.context || self, arguments);
8823          };
8824  
8825          self.insert();
8826      }
8827  };
8828  
8829  
8830  
8831  }, '3.17.2', {"requires": ["get", "features"]});
8832  YUI.add('loader-rollup', function (Y, NAME) {
8833  
8834  /**
8835   * Optional automatic rollup logic for reducing http connections
8836   * when not using a combo service.
8837   * @module loader
8838   * @submodule rollup
8839   */
8840  
8841  /**
8842   * Look for rollup packages to determine if all of the modules a
8843   * rollup supersedes are required.  If so, include the rollup to
8844   * help reduce the total number of connections required.  Called
8845   * by calculate().  This is an optional feature, and requires the
8846   * appropriate submodule to function.
8847   * @method _rollup
8848   * @for Loader
8849   * @private
8850   */
8851  Y.Loader.prototype._rollup = function() {
8852      var i, j, m, s, r = this.required, roll,
8853          info = this.moduleInfo, rolled, c, smod;
8854  
8855      // find and cache rollup modules
8856      if (this.dirty || !this.rollups) {
8857          this.rollups = {};
8858          for (i in info) {
8859              if (info.hasOwnProperty(i)) {
8860                  m = this.getModule(i);
8861                  // if (m && m.rollup && m.supersedes) {
8862                  if (m && m.rollup) {
8863                      this.rollups[i] = m;
8864                  }
8865              }
8866          }
8867      }
8868  
8869      // make as many passes as needed to pick up rollup rollups
8870      for (;;) {
8871          rolled = false;
8872  
8873          // go through the rollup candidates
8874          for (i in this.rollups) {
8875              if (this.rollups.hasOwnProperty(i)) {
8876                  // there can be only one, unless forced
8877                  if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) {
8878                      m = this.getModule(i);
8879                      s = m.supersedes || [];
8880                      roll = false;
8881  
8882                      // @TODO remove continue
8883                      if (!m.rollup) {
8884                          continue;
8885                      }
8886  
8887                      c = 0;
8888  
8889                      // check the threshold
8890                      for (j = 0; j < s.length; j++) {
8891                          smod = info[s[j]];
8892  
8893                          // if the superseded module is loaded, we can't
8894                          // load the rollup unless it has been forced.
8895                          if (this.loaded[s[j]] && !this.forceMap[s[j]]) {
8896                              roll = false;
8897                              break;
8898                          // increment the counter if this module is required.
8899                          // if we are beyond the rollup threshold, we will
8900                          // use the rollup module
8901                          } else if (r[s[j]] && m.type === smod.type) {
8902                              c++;
8903                              roll = (c >= m.rollup);
8904                              if (roll) {
8905                                  break;
8906                              }
8907                          }
8908                      }
8909  
8910                      if (roll) {
8911                          // add the rollup
8912                          r[i] = true;
8913                          rolled = true;
8914  
8915                          // expand the rollup's dependencies
8916                          this.getRequires(m);
8917                      }
8918                  }
8919              }
8920          }
8921  
8922          // if we made it here w/o rolling up something, we are done
8923          if (!rolled) {
8924              break;
8925          }
8926      }
8927  };
8928  
8929  
8930  }, '3.17.2', {"requires": ["loader-base"]});
8931  YUI.add('loader-yui3', function (Y, NAME) {
8932  
8933  /* This file is auto-generated by (yogi.js loader --mix --yes) */
8934  
8935  /*jshint maxlen:900, eqeqeq: false */
8936  
8937  /**
8938   * YUI 3 module metadata
8939   * @module loader
8940   * @submodule loader-yui3
8941   */
8942  YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
8943  Y.mix(YUI.Env[Y.version].modules, {
8944      "align-plugin": {
8945          "requires": [
8946              "node-screen",
8947              "node-pluginhost"
8948          ]
8949      },
8950      "anim": {
8951          "use": [
8952              "anim-base",
8953              "anim-color",
8954              "anim-curve",
8955              "anim-easing",
8956              "anim-node-plugin",
8957              "anim-scroll",
8958              "anim-xy"
8959          ]
8960      },
8961      "anim-base": {
8962          "requires": [
8963              "base-base",
8964              "node-style",
8965              "color-base"
8966          ]
8967      },
8968      "anim-color": {
8969          "requires": [
8970              "anim-base"
8971          ]
8972      },
8973      "anim-curve": {
8974          "requires": [
8975              "anim-xy"
8976          ]
8977      },
8978      "anim-easing": {
8979          "requires": [
8980              "anim-base"
8981          ]
8982      },
8983      "anim-node-plugin": {
8984          "requires": [
8985              "node-pluginhost",
8986              "anim-base"
8987          ]
8988      },
8989      "anim-scroll": {
8990          "requires": [
8991              "anim-base"
8992          ]
8993      },
8994      "anim-shape": {
8995          "requires": [
8996              "anim-base",
8997              "anim-easing",
8998              "anim-color",
8999              "matrix"
9000          ]
9001      },
9002      "anim-shape-transform": {
9003          "use": [
9004              "anim-shape"
9005          ]
9006      },
9007      "anim-xy": {
9008          "requires": [
9009              "anim-base",
9010              "node-screen"
9011          ]
9012      },
9013      "app": {
9014          "use": [
9015              "app-base",
9016              "app-content",
9017              "app-transitions",
9018              "lazy-model-list",
9019              "model",
9020              "model-list",
9021              "model-sync-rest",
9022              "model-sync-local",
9023              "router",
9024              "view",
9025              "view-node-map"
9026          ]
9027      },
9028      "app-base": {
9029          "requires": [
9030              "classnamemanager",
9031              "pjax-base",
9032              "router",
9033              "view"
9034          ]
9035      },
9036      "app-content": {
9037          "requires": [
9038              "app-base",
9039              "pjax-content"
9040          ]
9041      },
9042      "app-transitions": {
9043          "requires": [
9044              "app-base"
9045          ]
9046      },
9047      "app-transitions-css": {
9048          "type": "css"
9049      },
9050      "app-transitions-native": {
9051          "condition": {
9052              "name": "app-transitions-native",
9053              "test": function (Y) {
9054      var doc  = Y.config.doc,
9055          node = doc ? doc.documentElement : null;
9056  
9057      if (node && node.style) {
9058          return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
9059      }
9060  
9061      return false;
9062  },
9063              "trigger": "app-transitions"
9064          },
9065          "requires": [
9066              "app-transitions",
9067              "app-transitions-css",
9068              "parallel",
9069              "transition"
9070          ]
9071      },
9072      "array-extras": {
9073          "requires": [
9074              "yui-base"
9075          ]
9076      },
9077      "array-invoke": {
9078          "requires": [
9079              "yui-base"
9080          ]
9081      },
9082      "arraylist": {
9083          "requires": [
9084              "yui-base"
9085          ]
9086      },
9087      "arraylist-add": {
9088          "requires": [
9089              "arraylist"
9090          ]
9091      },
9092      "arraylist-filter": {
9093          "requires": [
9094              "arraylist"
9095          ]
9096      },
9097      "arraysort": {
9098          "requires": [
9099              "yui-base"
9100          ]
9101      },
9102      "async-queue": {
9103          "requires": [
9104              "event-custom"
9105          ]
9106      },
9107      "attribute": {
9108          "use": [
9109              "attribute-base",
9110              "attribute-complex"
9111          ]
9112      },
9113      "attribute-base": {
9114          "requires": [
9115              "attribute-core",
9116              "attribute-observable",
9117              "attribute-extras"
9118          ]
9119      },
9120      "attribute-complex": {
9121          "requires": [
9122              "attribute-base"
9123          ]
9124      },
9125      "attribute-core": {
9126          "requires": [
9127              "oop"
9128          ]
9129      },
9130      "attribute-events": {
9131          "use": [
9132              "attribute-observable"
9133          ]
9134      },
9135      "attribute-extras": {
9136          "requires": [
9137              "oop"
9138          ]
9139      },
9140      "attribute-observable": {
9141          "requires": [
9142              "event-custom"
9143          ]
9144      },
9145      "autocomplete": {
9146          "use": [
9147              "autocomplete-base",
9148              "autocomplete-sources",
9149              "autocomplete-list",
9150              "autocomplete-plugin"
9151          ]
9152      },
9153      "autocomplete-base": {
9154          "optional": [
9155              "autocomplete-sources"
9156          ],
9157          "requires": [
9158              "array-extras",
9159              "base-build",
9160              "escape",
9161              "event-valuechange",
9162              "node-base"
9163          ]
9164      },
9165      "autocomplete-filters": {
9166          "requires": [
9167              "array-extras",
9168              "text-wordbreak"
9169          ]
9170      },
9171      "autocomplete-filters-accentfold": {
9172          "requires": [
9173              "array-extras",
9174              "text-accentfold",
9175              "text-wordbreak"
9176          ]
9177      },
9178      "autocomplete-highlighters": {
9179          "requires": [
9180              "array-extras",
9181              "highlight-base"
9182          ]
9183      },
9184      "autocomplete-highlighters-accentfold": {
9185          "requires": [
9186              "array-extras",
9187              "highlight-accentfold"
9188          ]
9189      },
9190      "autocomplete-list": {
9191          "after": [
9192              "autocomplete-sources"
9193          ],
9194          "lang": [
9195              "en",
9196              "es",
9197              "hu",
9198              "it"
9199          ],
9200          "requires": [
9201              "autocomplete-base",
9202              "event-resize",
9203              "node-screen",
9204              "selector-css3",
9205              "shim-plugin",
9206              "widget",
9207              "widget-position",
9208              "widget-position-align"
9209          ],
9210          "skinnable": true
9211      },
9212      "autocomplete-list-keys": {
9213          "condition": {
9214              "name": "autocomplete-list-keys",
9215              "test": function (Y) {
9216      // Only add keyboard support to autocomplete-list if this doesn't appear to
9217      // be an iOS or Android-based mobile device.
9218      //
9219      // There's currently no feasible way to actually detect whether a device has
9220      // a hardware keyboard, so this sniff will have to do. It can easily be
9221      // overridden by manually loading the autocomplete-list-keys module.
9222      //
9223      // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
9224      // doesn't fire the keyboard events used by AutoCompleteList, so there's
9225      // no point loading the -keys module even when a bluetooth keyboard may be
9226      // available.
9227      return !(Y.UA.ios || Y.UA.android);
9228  },
9229              "trigger": "autocomplete-list"
9230          },
9231          "requires": [
9232              "autocomplete-list",
9233              "base-build"
9234          ]
9235      },
9236      "autocomplete-plugin": {
9237          "requires": [
9238              "autocomplete-list",
9239              "node-pluginhost"
9240          ]
9241      },
9242      "autocomplete-sources": {
9243          "optional": [
9244              "io-base",
9245              "json-parse",
9246              "jsonp",
9247              "yql"
9248          ],
9249          "requires": [
9250              "autocomplete-base"
9251          ]
9252      },
9253      "axes": {
9254          "use": [
9255              "axis-numeric",
9256              "axis-category",
9257              "axis-time",
9258              "axis-stacked"
9259          ]
9260      },
9261      "axes-base": {
9262          "use": [
9263              "axis-numeric-base",
9264              "axis-category-base",
9265              "axis-time-base",
9266              "axis-stacked-base"
9267          ]
9268      },
9269      "axis": {
9270          "requires": [
9271              "dom",
9272              "widget",
9273              "widget-position",
9274              "widget-stack",
9275              "graphics",
9276              "axis-base"
9277          ]
9278      },
9279      "axis-base": {
9280          "requires": [
9281              "classnamemanager",
9282              "datatype-number",
9283              "datatype-date",
9284              "base",
9285              "event-custom"
9286          ]
9287      },
9288      "axis-category": {
9289          "requires": [
9290              "axis",
9291              "axis-category-base"
9292          ]
9293      },
9294      "axis-category-base": {
9295          "requires": [
9296              "axis-base"
9297          ]
9298      },
9299      "axis-numeric": {
9300          "requires": [
9301              "axis",
9302              "axis-numeric-base"
9303          ]
9304      },
9305      "axis-numeric-base": {
9306          "requires": [
9307              "axis-base"
9308          ]
9309      },
9310      "axis-stacked": {
9311          "requires": [
9312              "axis-numeric",
9313              "axis-stacked-base"
9314          ]
9315      },
9316      "axis-stacked-base": {
9317          "requires": [
9318              "axis-numeric-base"
9319          ]
9320      },
9321      "axis-time": {
9322          "requires": [
9323              "axis",
9324              "axis-time-base"
9325          ]
9326      },
9327      "axis-time-base": {
9328          "requires": [
9329              "axis-base"
9330          ]
9331      },
9332      "base": {
9333          "use": [
9334              "base-base",
9335              "base-pluginhost",
9336              "base-build"
9337          ]
9338      },
9339      "base-base": {
9340          "requires": [
9341              "attribute-base",
9342              "base-core",
9343              "base-observable"
9344          ]
9345      },
9346      "base-build": {
9347          "requires": [
9348              "base-base"
9349          ]
9350      },
9351      "base-core": {
9352          "requires": [
9353              "attribute-core"
9354          ]
9355      },
9356      "base-observable": {
9357          "requires": [
9358              "attribute-observable",
9359              "base-core"
9360          ]
9361      },
9362      "base-pluginhost": {
9363          "requires": [
9364              "base-base",
9365              "pluginhost"
9366          ]
9367      },
9368      "button": {
9369          "requires": [
9370              "button-core",
9371              "cssbutton",
9372              "widget"
9373          ]
9374      },
9375      "button-core": {
9376          "requires": [
9377              "attribute-core",
9378              "classnamemanager",
9379              "node-base",
9380              "escape"
9381          ]
9382      },
9383      "button-group": {
9384          "requires": [
9385              "button-plugin",
9386              "cssbutton",
9387              "widget"
9388          ]
9389      },
9390      "button-plugin": {
9391          "requires": [
9392              "button-core",
9393              "cssbutton",
9394              "node-pluginhost"
9395          ]
9396      },
9397      "cache": {
9398          "use": [
9399              "cache-base",
9400              "cache-offline",
9401              "cache-plugin"
9402          ]
9403      },
9404      "cache-base": {
9405          "requires": [
9406              "base"
9407          ]
9408      },
9409      "cache-offline": {
9410          "requires": [
9411              "cache-base",
9412              "json"
9413          ]
9414      },
9415      "cache-plugin": {
9416          "requires": [
9417              "plugin",
9418              "cache-base"
9419          ]
9420      },
9421      "calendar": {
9422          "requires": [
9423              "calendar-base",
9424              "calendarnavigator"
9425          ],
9426          "skinnable": true
9427      },
9428      "calendar-base": {
9429          "lang": [
9430              "de",
9431              "en",
9432              "es",
9433              "es-AR",
9434              "fr",
9435              "hu",
9436              "it",
9437              "ja",
9438              "nb-NO",
9439              "nl",
9440              "pt-BR",
9441              "ru",
9442              "zh-Hans",
9443              "zh-Hans-CN",
9444              "zh-Hant",
9445              "zh-Hant-HK",
9446              "zh-HANT-TW"
9447          ],
9448          "requires": [
9449              "widget",
9450              "datatype-date",
9451              "datatype-date-math",
9452              "cssgrids"
9453          ],
9454          "skinnable": true
9455      },
9456      "calendarnavigator": {
9457          "requires": [
9458              "plugin",
9459              "classnamemanager",
9460              "datatype-date",
9461              "node"
9462          ],
9463          "skinnable": true
9464      },
9465      "charts": {
9466          "use": [
9467              "charts-base"
9468          ]
9469      },
9470      "charts-base": {
9471          "requires": [
9472              "dom",
9473              "event-mouseenter",
9474              "event-touch",
9475              "graphics-group",
9476              "axes",
9477              "series-pie",
9478              "series-line",
9479              "series-marker",
9480              "series-area",
9481              "series-spline",
9482              "series-column",
9483              "series-bar",
9484              "series-areaspline",
9485              "series-combo",
9486              "series-combospline",
9487              "series-line-stacked",
9488              "series-marker-stacked",
9489              "series-area-stacked",
9490              "series-spline-stacked",
9491              "series-column-stacked",
9492              "series-bar-stacked",
9493              "series-areaspline-stacked",
9494              "series-combo-stacked",
9495              "series-combospline-stacked"
9496          ]
9497      },
9498      "charts-legend": {
9499          "requires": [
9500              "charts-base"
9501          ]
9502      },
9503      "classnamemanager": {
9504          "requires": [
9505              "yui-base"
9506          ]
9507      },
9508      "clickable-rail": {
9509          "requires": [
9510              "slider-base"
9511          ]
9512      },
9513      "collection": {
9514          "use": [
9515              "array-extras",
9516              "arraylist",
9517              "arraylist-add",
9518              "arraylist-filter",
9519              "array-invoke"
9520          ]
9521      },
9522      "color": {
9523          "use": [
9524              "color-base",
9525              "color-hsl",
9526              "color-harmony"
9527          ]
9528      },
9529      "color-base": {
9530          "requires": [
9531              "yui-base"
9532          ]
9533      },
9534      "color-harmony": {
9535          "requires": [
9536              "color-hsl"
9537          ]
9538      },
9539      "color-hsl": {
9540          "requires": [
9541              "color-base"
9542          ]
9543      },
9544      "color-hsv": {
9545          "requires": [
9546              "color-base"
9547          ]
9548      },
9549      "console": {
9550          "lang": [
9551              "en",
9552              "es",
9553              "hu",
9554              "it",
9555              "ja"
9556          ],
9557          "requires": [
9558              "yui-log",
9559              "widget"
9560          ],
9561          "skinnable": true
9562      },
9563      "console-filters": {
9564          "requires": [
9565              "plugin",
9566              "console"
9567          ],
9568          "skinnable": true
9569      },
9570      "content-editable": {
9571          "requires": [
9572              "node-base",
9573              "editor-selection",
9574              "stylesheet",
9575              "plugin"
9576          ]
9577      },
9578      "controller": {
9579          "use": [
9580              "router"
9581          ]
9582      },
9583      "cookie": {
9584          "requires": [
9585              "yui-base"
9586          ]
9587      },
9588      "createlink-base": {
9589          "requires": [
9590              "editor-base"
9591          ]
9592      },
9593      "cssbase": {
9594          "after": [
9595              "cssreset",
9596              "cssfonts",
9597              "cssgrids",
9598              "cssreset-context",
9599              "cssfonts-context",
9600              "cssgrids-context"
9601          ],
9602          "type": "css"
9603      },
9604      "cssbase-context": {
9605          "after": [
9606              "cssreset",
9607              "cssfonts",
9608              "cssgrids",
9609              "cssreset-context",
9610              "cssfonts-context",
9611              "cssgrids-context"
9612          ],
9613          "type": "css"
9614      },
9615      "cssbutton": {
9616          "type": "css"
9617      },
9618      "cssfonts": {
9619          "type": "css"
9620      },
9621      "cssfonts-context": {
9622          "type": "css"
9623      },
9624      "cssgrids": {
9625          "optional": [
9626              "cssnormalize"
9627          ],
9628          "type": "css"
9629      },
9630      "cssgrids-base": {
9631          "optional": [
9632              "cssnormalize"
9633          ],
9634          "type": "css"
9635      },
9636      "cssgrids-responsive": {
9637          "optional": [
9638              "cssnormalize"
9639          ],
9640          "requires": [
9641              "cssgrids",
9642              "cssgrids-responsive-base"
9643          ],
9644          "type": "css"
9645      },
9646      "cssgrids-units": {
9647          "optional": [
9648              "cssnormalize"
9649          ],
9650          "requires": [
9651              "cssgrids-base"
9652          ],
9653          "type": "css"
9654      },
9655      "cssnormalize": {
9656          "type": "css"
9657      },
9658      "cssnormalize-context": {
9659          "type": "css"
9660      },
9661      "cssreset": {
9662          "type": "css"
9663      },
9664      "cssreset-context": {
9665          "type": "css"
9666      },
9667      "dataschema": {
9668          "use": [
9669              "dataschema-base",
9670              "dataschema-json",
9671              "dataschema-xml",
9672              "dataschema-array",
9673              "dataschema-text"
9674          ]
9675      },
9676      "dataschema-array": {
9677          "requires": [
9678              "dataschema-base"
9679          ]
9680      },
9681      "dataschema-base": {
9682          "requires": [
9683              "base"
9684          ]
9685      },
9686      "dataschema-json": {
9687          "requires": [
9688              "dataschema-base",
9689              "json"
9690          ]
9691      },
9692      "dataschema-text": {
9693          "requires": [
9694              "dataschema-base"
9695          ]
9696      },
9697      "dataschema-xml": {
9698          "requires": [
9699              "dataschema-base"
9700          ]
9701      },
9702      "datasource": {
9703          "use": [
9704              "datasource-local",
9705              "datasource-io",
9706              "datasource-get",
9707              "datasource-function",
9708              "datasource-cache",
9709              "datasource-jsonschema",
9710              "datasource-xmlschema",
9711              "datasource-arrayschema",
9712              "datasource-textschema",
9713              "datasource-polling"
9714          ]
9715      },
9716      "datasource-arrayschema": {
9717          "requires": [
9718              "datasource-local",
9719              "plugin",
9720              "dataschema-array"
9721          ]
9722      },
9723      "datasource-cache": {
9724          "requires": [
9725              "datasource-local",
9726              "plugin",
9727              "cache-base"
9728          ]
9729      },
9730      "datasource-function": {
9731          "requires": [
9732              "datasource-local"
9733          ]
9734      },
9735      "datasource-get": {
9736          "requires": [
9737              "datasource-local",
9738              "get"
9739          ]
9740      },
9741      "datasource-io": {
9742          "requires": [
9743              "datasource-local",
9744              "io-base"
9745          ]
9746      },
9747      "datasource-jsonschema": {
9748          "requires": [
9749              "datasource-local",
9750              "plugin",
9751              "dataschema-json"
9752          ]
9753      },
9754      "datasource-local": {
9755          "requires": [
9756              "base"
9757          ]
9758      },
9759      "datasource-polling": {
9760          "requires": [
9761              "datasource-local"
9762          ]
9763      },
9764      "datasource-textschema": {
9765          "requires": [
9766              "datasource-local",
9767              "plugin",
9768              "dataschema-text"
9769          ]
9770      },
9771      "datasource-xmlschema": {
9772          "requires": [
9773              "datasource-local",
9774              "plugin",
9775              "datatype-xml",
9776              "dataschema-xml"
9777          ]
9778      },
9779      "datatable": {
9780          "use": [
9781              "datatable-core",
9782              "datatable-table",
9783              "datatable-head",
9784              "datatable-body",
9785              "datatable-base",
9786              "datatable-column-widths",
9787              "datatable-message",
9788              "datatable-mutable",
9789              "datatable-sort",
9790              "datatable-datasource"
9791          ]
9792      },
9793      "datatable-base": {
9794          "requires": [
9795              "datatable-core",
9796              "datatable-table",
9797              "datatable-head",
9798              "datatable-body",
9799              "base-build",
9800              "widget"
9801          ],
9802          "skinnable": true
9803      },
9804      "datatable-body": {
9805          "requires": [
9806              "datatable-core",
9807              "view",
9808              "classnamemanager"
9809          ]
9810      },
9811      "datatable-column-widths": {
9812          "requires": [
9813              "datatable-base"
9814          ]
9815      },
9816      "datatable-core": {
9817          "requires": [
9818              "escape",
9819              "model-list",
9820              "node-event-delegate"
9821          ]
9822      },
9823      "datatable-datasource": {
9824          "requires": [
9825              "datatable-base",
9826              "plugin",
9827              "datasource-local"
9828          ]
9829      },
9830      "datatable-foot": {
9831          "requires": [
9832              "datatable-core",
9833              "view"
9834          ]
9835      },
9836      "datatable-formatters": {
9837          "requires": [
9838              "datatable-body",
9839              "datatype-number-format",
9840              "datatype-date-format",
9841              "escape"
9842          ]
9843      },
9844      "datatable-head": {
9845          "requires": [
9846              "datatable-core",
9847              "view",
9848              "classnamemanager"
9849          ]
9850      },
9851      "datatable-highlight": {
9852          "requires": [
9853              "datatable-base",
9854              "event-hover"
9855          ],
9856          "skinnable": true
9857      },
9858      "datatable-keynav": {
9859          "requires": [
9860              "datatable-base"
9861          ]
9862      },
9863      "datatable-message": {
9864          "lang": [
9865              "en",
9866              "fr",
9867              "es",
9868              "hu",
9869              "it"
9870          ],
9871          "requires": [
9872              "datatable-base"
9873          ],
9874          "skinnable": true
9875      },
9876      "datatable-mutable": {
9877          "requires": [
9878              "datatable-base"
9879          ]
9880      },
9881      "datatable-paginator": {
9882          "lang": [
9883              "en",
9884              "fr"
9885          ],
9886          "requires": [
9887              "model",
9888              "view",
9889              "paginator-core",
9890              "datatable-foot",
9891              "datatable-paginator-templates"
9892          ],
9893          "skinnable": true
9894      },
9895      "datatable-paginator-templates": {
9896          "requires": [
9897              "template"
9898          ]
9899      },
9900      "datatable-scroll": {
9901          "requires": [
9902              "datatable-base",
9903              "datatable-column-widths",
9904              "dom-screen"
9905          ],
9906          "skinnable": true
9907      },
9908      "datatable-sort": {
9909          "lang": [
9910              "en",
9911              "fr",
9912              "es",
9913              "hu"
9914          ],
9915          "requires": [
9916              "datatable-base"
9917          ],
9918          "skinnable": true
9919      },
9920      "datatable-table": {
9921          "requires": [
9922              "datatable-core",
9923              "datatable-head",
9924              "datatable-body",
9925              "view",
9926              "classnamemanager"
9927          ]
9928      },
9929      "datatype": {
9930          "use": [
9931              "datatype-date",
9932              "datatype-number",
9933              "datatype-xml"
9934          ]
9935      },
9936      "datatype-date": {
9937          "use": [
9938              "datatype-date-parse",
9939              "datatype-date-format",
9940              "datatype-date-math"
9941          ]
9942      },
9943      "datatype-date-format": {
9944          "lang": [
9945              "ar",
9946              "ar-JO",
9947              "ca",
9948              "ca-ES",
9949              "da",
9950              "da-DK",
9951              "de",
9952              "de-AT",
9953              "de-DE",
9954              "el",
9955              "el-GR",
9956              "en",
9957              "en-AU",
9958              "en-CA",
9959              "en-GB",
9960              "en-IE",
9961              "en-IN",
9962              "en-JO",
9963              "en-MY",
9964              "en-NZ",
9965              "en-PH",
9966              "en-SG",
9967              "en-US",
9968              "es",
9969              "es-AR",
9970              "es-BO",
9971              "es-CL",
9972              "es-CO",
9973              "es-EC",
9974              "es-ES",
9975              "es-MX",
9976              "es-PE",
9977              "es-PY",
9978              "es-US",
9979              "es-UY",
9980              "es-VE",
9981              "fi",
9982              "fi-FI",
9983              "fr",
9984              "fr-BE",
9985              "fr-CA",
9986              "fr-FR",
9987              "hi",
9988              "hi-IN",
9989              "hu",
9990              "id",
9991              "id-ID",
9992              "it",
9993              "it-IT",
9994              "ja",
9995              "ja-JP",
9996              "ko",
9997              "ko-KR",
9998              "ms",
9999              "ms-MY",
10000              "nb",
10001              "nb-NO",
10002              "nl",
10003              "nl-BE",
10004              "nl-NL",
10005              "pl",
10006              "pl-PL",
10007              "pt",
10008              "pt-BR",
10009              "ro",
10010              "ro-RO",
10011              "ru",
10012              "ru-RU",
10013              "sv",
10014              "sv-SE",
10015              "th",
10016              "th-TH",
10017              "tr",
10018              "tr-TR",
10019              "vi",
10020              "vi-VN",
10021              "zh-Hans",
10022              "zh-Hans-CN",
10023              "zh-Hant",
10024              "zh-Hant-HK",
10025              "zh-Hant-TW"
10026          ]
10027      },
10028      "datatype-date-math": {
10029          "requires": [
10030              "yui-base"
10031          ]
10032      },
10033      "datatype-date-parse": {},
10034      "datatype-number": {
10035          "use": [
10036              "datatype-number-parse",
10037              "datatype-number-format"
10038          ]
10039      },
10040      "datatype-number-format": {},
10041      "datatype-number-parse": {
10042          "requires": [
10043              "escape"
10044          ]
10045      },
10046      "datatype-xml": {
10047          "use": [
10048              "datatype-xml-parse",
10049              "datatype-xml-format"
10050          ]
10051      },
10052      "datatype-xml-format": {},
10053      "datatype-xml-parse": {},
10054      "dd": {
10055          "use": [
10056              "dd-ddm-base",
10057              "dd-ddm",
10058              "dd-ddm-drop",
10059              "dd-drag",
10060              "dd-proxy",
10061              "dd-constrain",
10062              "dd-drop",
10063              "dd-scroll",
10064              "dd-delegate"
10065          ]
10066      },
10067      "dd-constrain": {
10068          "requires": [
10069              "dd-drag"
10070          ]
10071      },
10072      "dd-ddm": {
10073          "requires": [
10074              "dd-ddm-base",
10075              "event-resize"
10076          ]
10077      },
10078      "dd-ddm-base": {
10079          "requires": [
10080              "node",
10081              "base",
10082              "yui-throttle",
10083              "classnamemanager"
10084          ]
10085      },
10086      "dd-ddm-drop": {
10087          "requires": [
10088              "dd-ddm"
10089          ]
10090      },
10091      "dd-delegate": {
10092          "requires": [
10093              "dd-drag",
10094              "dd-drop-plugin",
10095              "event-mouseenter"
10096          ]
10097      },
10098      "dd-drag": {
10099          "requires": [
10100              "dd-ddm-base"
10101          ]
10102      },
10103      "dd-drop": {
10104          "requires": [
10105              "dd-drag",
10106              "dd-ddm-drop"
10107          ]
10108      },
10109      "dd-drop-plugin": {
10110          "requires": [
10111              "dd-drop"
10112          ]
10113      },
10114      "dd-gestures": {
10115          "condition": {
10116              "name": "dd-gestures",
10117              "trigger": "dd-drag",
10118              "ua": "touchEnabled"
10119          },
10120          "requires": [
10121              "dd-drag",
10122              "event-synthetic",
10123              "event-gestures"
10124          ]
10125      },
10126      "dd-plugin": {
10127          "optional": [
10128              "dd-constrain",
10129              "dd-proxy"
10130          ],
10131          "requires": [
10132              "dd-drag"
10133          ]
10134      },
10135      "dd-proxy": {
10136          "requires": [
10137              "dd-drag"
10138          ]
10139      },
10140      "dd-scroll": {
10141          "requires": [
10142              "dd-drag"
10143          ]
10144      },
10145      "dial": {
10146          "lang": [
10147              "en",
10148              "es",
10149              "hu"
10150          ],
10151          "requires": [
10152              "widget",
10153              "dd-drag",
10154              "event-mouseenter",
10155              "event-move",
10156              "event-key",
10157              "transition",
10158              "intl"
10159          ],
10160          "skinnable": true
10161      },
10162      "dom": {
10163          "use": [
10164              "dom-base",
10165              "dom-screen",
10166              "dom-style",
10167              "selector-native",
10168              "selector"
10169          ]
10170      },
10171      "dom-base": {
10172          "requires": [
10173              "dom-core"
10174          ]
10175      },
10176      "dom-core": {
10177          "requires": [
10178              "oop",
10179              "features"
10180          ]
10181      },
10182      "dom-screen": {
10183          "requires": [
10184              "dom-base",
10185              "dom-style"
10186          ]
10187      },
10188      "dom-style": {
10189          "requires": [
10190              "dom-base"
10191          ]
10192      },
10193      "dom-style-ie": {
10194          "condition": {
10195              "name": "dom-style-ie",
10196              "test": function (Y) {
10197  
10198      var testFeature = Y.Features.test,
10199          addFeature = Y.Features.add,
10200          WINDOW = Y.config.win,
10201          DOCUMENT = Y.config.doc,
10202          DOCUMENT_ELEMENT = 'documentElement',
10203          ret = false;
10204  
10205      addFeature('style', 'computedStyle', {
10206          test: function() {
10207              return WINDOW && 'getComputedStyle' in WINDOW;
10208          }
10209      });
10210  
10211      addFeature('style', 'opacity', {
10212          test: function() {
10213              return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
10214          }
10215      });
10216  
10217      ret =  (!testFeature('style', 'opacity') &&
10218              !testFeature('style', 'computedStyle'));
10219  
10220      return ret;
10221  },
10222              "trigger": "dom-style"
10223          },
10224          "requires": [
10225              "dom-style",
10226              "color-base"
10227          ]
10228      },
10229      "dump": {
10230          "requires": [
10231              "yui-base"
10232          ]
10233      },
10234      "editor": {
10235          "use": [
10236              "frame",
10237              "editor-selection",
10238              "exec-command",
10239              "editor-base",
10240              "editor-para",
10241              "editor-br",
10242              "editor-bidi",
10243              "editor-tab",
10244              "createlink-base"
10245          ]
10246      },
10247      "editor-base": {
10248          "requires": [
10249              "base",
10250              "frame",
10251              "node",
10252              "exec-command",
10253              "editor-selection"
10254          ]
10255      },
10256      "editor-bidi": {
10257          "requires": [
10258              "editor-base"
10259          ]
10260      },
10261      "editor-br": {
10262          "requires": [
10263              "editor-base"
10264          ]
10265      },
10266      "editor-inline": {
10267          "requires": [
10268              "editor-base",
10269              "content-editable"
10270          ]
10271      },
10272      "editor-lists": {
10273          "requires": [
10274              "editor-base"
10275          ]
10276      },
10277      "editor-para": {
10278          "requires": [
10279              "editor-para-base"
10280          ]
10281      },
10282      "editor-para-base": {
10283          "requires": [
10284              "editor-base"
10285          ]
10286      },
10287      "editor-para-ie": {
10288          "condition": {
10289              "name": "editor-para-ie",
10290              "trigger": "editor-para",
10291              "ua": "ie",
10292              "when": "instead"
10293          },
10294          "requires": [
10295              "editor-para-base"
10296          ]
10297      },
10298      "editor-selection": {
10299          "requires": [
10300              "node"
10301          ]
10302      },
10303      "editor-tab": {
10304          "requires": [
10305              "editor-base"
10306          ]
10307      },
10308      "escape": {
10309          "requires": [
10310              "yui-base"
10311          ]
10312      },
10313      "event": {
10314          "after": [
10315              "node-base"
10316          ],
10317          "use": [
10318              "event-base",
10319              "event-delegate",
10320              "event-synthetic",
10321              "event-mousewheel",
10322              "event-mouseenter",
10323              "event-key",
10324              "event-focus",
10325              "event-resize",
10326              "event-hover",
10327              "event-outside",
10328              "event-touch",
10329              "event-move",
10330              "event-flick",
10331              "event-valuechange",
10332              "event-tap"
10333          ]
10334      },
10335      "event-base": {
10336          "after": [
10337              "node-base"
10338          ],
10339          "requires": [
10340              "event-custom-base"
10341          ]
10342      },
10343      "event-base-ie": {
10344          "after": [
10345              "event-base"
10346          ],
10347          "condition": {
10348              "name": "event-base-ie",
10349              "test": function(Y) {
10350      var imp = Y.config.doc && Y.config.doc.implementation;
10351      return (imp && (!imp.hasFeature('Events', '2.0')));
10352  },
10353              "trigger": "node-base"
10354          },
10355          "requires": [
10356              "node-base"
10357          ]
10358      },
10359      "event-contextmenu": {
10360          "requires": [
10361              "event-synthetic",
10362              "dom-screen"
10363          ]
10364      },
10365      "event-custom": {
10366          "use": [
10367              "event-custom-base",
10368              "event-custom-complex"
10369          ]
10370      },
10371      "event-custom-base": {
10372          "requires": [
10373              "oop"
10374          ]
10375      },
10376      "event-custom-complex": {
10377          "requires": [
10378              "event-custom-base"
10379          ]
10380      },
10381      "event-delegate": {
10382          "requires": [
10383              "node-base"
10384          ]
10385      },
10386      "event-flick": {
10387          "requires": [
10388              "node-base",
10389              "event-touch",
10390              "event-synthetic"
10391          ]
10392      },
10393      "event-focus": {
10394          "requires": [
10395              "event-synthetic"
10396          ]
10397      },
10398      "event-gestures": {
10399          "use": [
10400              "event-flick",
10401              "event-move"
10402          ]
10403      },
10404      "event-hover": {
10405          "requires": [
10406              "event-mouseenter"
10407          ]
10408      },
10409      "event-key": {
10410          "requires": [
10411              "event-synthetic"
10412          ]
10413      },
10414      "event-mouseenter": {
10415          "requires": [
10416              "event-synthetic"
10417          ]
10418      },
10419      "event-mousewheel": {
10420          "requires": [
10421              "node-base"
10422          ]
10423      },
10424      "event-move": {
10425          "requires": [
10426              "node-base",
10427              "event-touch",
10428              "event-synthetic"
10429          ]
10430      },
10431      "event-outside": {
10432          "requires": [
10433              "event-synthetic"
10434          ]
10435      },
10436      "event-resize": {
10437          "requires": [
10438              "node-base",
10439              "event-synthetic"
10440          ]
10441      },
10442      "event-simulate": {
10443          "requires": [
10444              "event-base"
10445          ]
10446      },
10447      "event-synthetic": {
10448          "requires": [
10449              "node-base",
10450              "event-custom-complex"
10451          ]
10452      },
10453      "event-tap": {
10454          "requires": [
10455              "node-base",
10456              "event-base",
10457              "event-touch",
10458              "event-synthetic"
10459          ]
10460      },
10461      "event-touch": {
10462          "requires": [
10463              "node-base"
10464          ]
10465      },
10466      "event-valuechange": {
10467          "requires": [
10468              "event-focus",
10469              "event-synthetic"
10470          ]
10471      },
10472      "exec-command": {
10473          "requires": [
10474              "frame"
10475          ]
10476      },
10477      "features": {
10478          "requires": [
10479              "yui-base"
10480          ]
10481      },
10482      "file": {
10483          "requires": [
10484              "file-flash",
10485              "file-html5"
10486          ]
10487      },
10488      "file-flash": {
10489          "requires": [
10490              "base"
10491          ]
10492      },
10493      "file-html5": {
10494          "requires": [
10495              "base"
10496          ]
10497      },
10498      "frame": {
10499          "requires": [
10500              "base",
10501              "node",
10502              "plugin",
10503              "selector-css3",
10504              "yui-throttle"
10505          ]
10506      },
10507      "gesture-simulate": {
10508          "requires": [
10509              "async-queue",
10510              "event-simulate",
10511              "node-screen"
10512          ]
10513      },
10514      "get": {
10515          "requires": [
10516              "yui-base"
10517          ]
10518      },
10519      "graphics": {
10520          "requires": [
10521              "node",
10522              "event-custom",
10523              "pluginhost",
10524              "matrix",
10525              "classnamemanager"
10526          ]
10527      },
10528      "graphics-canvas": {
10529          "condition": {
10530              "name": "graphics-canvas",
10531              "test": function(Y) {
10532      var DOCUMENT = Y.config.doc,
10533          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10534          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10535          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10536      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10537  },
10538              "trigger": "graphics"
10539          },
10540          "requires": [
10541              "graphics",
10542              "color-base"
10543          ]
10544      },
10545      "graphics-canvas-default": {
10546          "condition": {
10547              "name": "graphics-canvas-default",
10548              "test": function(Y) {
10549      var DOCUMENT = Y.config.doc,
10550          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10551          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10552          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10553      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10554  },
10555              "trigger": "graphics"
10556          }
10557      },
10558      "graphics-group": {
10559          "requires": [
10560              "graphics"
10561          ]
10562      },
10563      "graphics-svg": {
10564          "condition": {
10565              "name": "graphics-svg",
10566              "test": function(Y) {
10567      var DOCUMENT = Y.config.doc,
10568          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10569          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10570          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10571      
10572      return svg && (useSVG || !canvas);
10573  },
10574              "trigger": "graphics"
10575          },
10576          "requires": [
10577              "graphics"
10578          ]
10579      },
10580      "graphics-svg-default": {
10581          "condition": {
10582              "name": "graphics-svg-default",
10583              "test": function(Y) {
10584      var DOCUMENT = Y.config.doc,
10585          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10586          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10587          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10588      
10589      return svg && (useSVG || !canvas);
10590  },
10591              "trigger": "graphics"
10592          }
10593      },
10594      "graphics-vml": {
10595          "condition": {
10596              "name": "graphics-vml",
10597              "test": function(Y) {
10598      var DOCUMENT = Y.config.doc,
10599          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10600      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10601  },
10602              "trigger": "graphics"
10603          },
10604          "requires": [
10605              "graphics",
10606              "color-base"
10607          ]
10608      },
10609      "graphics-vml-default": {
10610          "condition": {
10611              "name": "graphics-vml-default",
10612              "test": function(Y) {
10613      var DOCUMENT = Y.config.doc,
10614          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10615      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10616  },
10617              "trigger": "graphics"
10618          }
10619      },
10620      "handlebars": {
10621          "use": [
10622              "handlebars-compiler"
10623          ]
10624      },
10625      "handlebars-base": {
10626          "requires": []
10627      },
10628      "handlebars-compiler": {
10629          "requires": [
10630              "handlebars-base"
10631          ]
10632      },
10633      "highlight": {
10634          "use": [
10635              "highlight-base",
10636              "highlight-accentfold"
10637          ]
10638      },
10639      "highlight-accentfold": {
10640          "requires": [
10641              "highlight-base",
10642              "text-accentfold"
10643          ]
10644      },
10645      "highlight-base": {
10646          "requires": [
10647              "array-extras",
10648              "classnamemanager",
10649              "escape",
10650              "text-wordbreak"
10651          ]
10652      },
10653      "history": {
10654          "use": [
10655              "history-base",
10656              "history-hash",
10657              "history-html5"
10658          ]
10659      },
10660      "history-base": {
10661          "requires": [
10662              "event-custom-complex"
10663          ]
10664      },
10665      "history-hash": {
10666          "after": [
10667              "history-html5"
10668          ],
10669          "requires": [
10670              "event-synthetic",
10671              "history-base",
10672              "yui-later"
10673          ]
10674      },
10675      "history-hash-ie": {
10676          "condition": {
10677              "name": "history-hash-ie",
10678              "test": function (Y) {
10679      var docMode = Y.config.doc && Y.config.doc.documentMode;
10680  
10681      return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
10682              !docMode || docMode < 8);
10683  },
10684              "trigger": "history-hash"
10685          },
10686          "requires": [
10687              "history-hash",
10688              "node-base"
10689          ]
10690      },
10691      "history-html5": {
10692          "optional": [
10693              "json"
10694          ],
10695          "requires": [
10696              "event-base",
10697              "history-base",
10698              "node-base"
10699          ]
10700      },
10701      "imageloader": {
10702          "requires": [
10703              "base-base",
10704              "node-style",
10705              "node-screen"
10706          ]
10707      },
10708      "intl": {
10709          "requires": [
10710              "intl-base",
10711              "event-custom"
10712          ]
10713      },
10714      "intl-base": {
10715          "requires": [
10716              "yui-base"
10717          ]
10718      },
10719      "io": {
10720          "use": [
10721              "io-base",
10722              "io-xdr",
10723              "io-form",
10724              "io-upload-iframe",
10725              "io-queue"
10726          ]
10727      },
10728      "io-base": {
10729          "requires": [
10730              "event-custom-base",
10731              "querystring-stringify-simple"
10732          ]
10733      },
10734      "io-form": {
10735          "requires": [
10736              "io-base",
10737              "node-base"
10738          ]
10739      },
10740      "io-nodejs": {
10741          "condition": {
10742              "name": "io-nodejs",
10743              "trigger": "io-base",
10744              "ua": "nodejs"
10745          },
10746          "requires": [
10747              "io-base"
10748          ]
10749      },
10750      "io-queue": {
10751          "requires": [
10752              "io-base",
10753              "queue-promote"
10754          ]
10755      },
10756      "io-upload-iframe": {
10757          "requires": [
10758              "io-base",
10759              "node-base"
10760          ]
10761      },
10762      "io-xdr": {
10763          "requires": [
10764              "io-base",
10765              "datatype-xml-parse"
10766          ]
10767      },
10768      "json": {
10769          "use": [
10770              "json-parse",
10771              "json-stringify"
10772          ]
10773      },
10774      "json-parse": {
10775          "requires": [
10776              "yui-base"
10777          ]
10778      },
10779      "json-parse-shim": {
10780          "condition": {
10781              "name": "json-parse-shim",
10782              "test": function (Y) {
10783      var _JSON = Y.config.global.JSON,
10784          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
10785          nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
10786  
10787      function workingNative( k, v ) {
10788          return k === "ok" ? true : v;
10789      }
10790      
10791      // Double check basic functionality.  This is mainly to catch early broken
10792      // implementations of the JSON API in Firefox 3.1 beta1 and beta2
10793      if ( nativeSupport ) {
10794          try {
10795              nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
10796          }
10797          catch ( e ) {
10798              nativeSupport = false;
10799          }
10800      }
10801  
10802      return !nativeSupport;
10803  },
10804              "trigger": "json-parse"
10805          },
10806          "requires": [
10807              "json-parse"
10808          ]
10809      },
10810      "json-stringify": {
10811          "requires": [
10812              "yui-base"
10813          ]
10814      },
10815      "json-stringify-shim": {
10816          "condition": {
10817              "name": "json-stringify-shim",
10818              "test": function (Y) {
10819      var _JSON = Y.config.global.JSON,
10820          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
10821          nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
10822  
10823      // Double check basic native functionality.  This is primarily to catch broken
10824      // early JSON API implementations in Firefox 3.1 beta1 and beta2.
10825      if ( nativeSupport ) {
10826          try {
10827              nativeSupport = ( '0' === Native.stringify(0) );
10828          } catch ( e ) {
10829              nativeSupport = false;
10830          }
10831      }
10832  
10833  
10834      return !nativeSupport;
10835  },
10836              "trigger": "json-stringify"
10837          },
10838          "requires": [
10839              "json-stringify"
10840          ]
10841      },
10842      "jsonp": {
10843          "requires": [
10844              "get",
10845              "oop"
10846          ]
10847      },
10848      "jsonp-url": {
10849          "requires": [
10850              "jsonp"
10851          ]
10852      },
10853      "lazy-model-list": {
10854          "requires": [
10855              "model-list"
10856          ]
10857      },
10858      "loader": {
10859          "use": [
10860              "loader-base",
10861              "loader-rollup",
10862              "loader-yui3"
10863          ]
10864      },
10865      "loader-base": {
10866          "requires": [
10867              "get",
10868              "features"
10869          ]
10870      },
10871      "loader-rollup": {
10872          "requires": [
10873              "loader-base"
10874          ]
10875      },
10876      "loader-yui3": {
10877          "requires": [
10878              "loader-base"
10879          ]
10880      },
10881      "matrix": {
10882          "requires": [
10883              "yui-base"
10884          ]
10885      },
10886      "model": {
10887          "requires": [
10888              "base-build",
10889              "escape",
10890              "json-parse"
10891          ]
10892      },
10893      "model-list": {
10894          "requires": [
10895              "array-extras",
10896              "array-invoke",
10897              "arraylist",
10898              "base-build",
10899              "escape",
10900              "json-parse",
10901              "model"
10902          ]
10903      },
10904      "model-sync-local": {
10905          "requires": [
10906              "model",
10907              "json-stringify"
10908          ]
10909      },
10910      "model-sync-rest": {
10911          "requires": [
10912              "model",
10913              "io-base",
10914              "json-stringify"
10915          ]
10916      },
10917      "node": {
10918          "use": [
10919              "node-base",
10920              "node-event-delegate",
10921              "node-pluginhost",
10922              "node-screen",
10923              "node-style"
10924          ]
10925      },
10926      "node-base": {
10927          "requires": [
10928              "event-base",
10929              "node-core",
10930              "dom-base",
10931              "dom-style"
10932          ]
10933      },
10934      "node-core": {
10935          "requires": [
10936              "dom-core",
10937              "selector"
10938          ]
10939      },
10940      "node-event-delegate": {
10941          "requires": [
10942              "node-base",
10943              "event-delegate"
10944          ]
10945      },
10946      "node-event-html5": {
10947          "requires": [
10948              "node-base"
10949          ]
10950      },
10951      "node-event-simulate": {
10952          "requires": [
10953              "node-base",
10954              "event-simulate",
10955              "gesture-simulate"
10956          ]
10957      },
10958      "node-flick": {
10959          "requires": [
10960              "classnamemanager",
10961              "transition",
10962              "event-flick",
10963              "plugin"
10964          ],
10965          "skinnable": true
10966      },
10967      "node-focusmanager": {
10968          "requires": [
10969              "attribute",
10970              "node",
10971              "plugin",
10972              "node-event-simulate",
10973              "event-key",
10974              "event-focus"
10975          ]
10976      },
10977      "node-load": {
10978          "requires": [
10979              "node-base",
10980              "io-base"
10981          ]
10982      },
10983      "node-menunav": {
10984          "requires": [
10985              "node",
10986              "classnamemanager",
10987              "plugin",
10988              "node-focusmanager"
10989          ],
10990          "skinnable": true
10991      },
10992      "node-pluginhost": {
10993          "requires": [
10994              "node-base",
10995              "pluginhost"
10996          ]
10997      },
10998      "node-screen": {
10999          "requires": [
11000              "dom-screen",
11001              "node-base"
11002          ]
11003      },
11004      "node-scroll-info": {
11005          "requires": [
11006              "array-extras",
11007              "base-build",
11008              "event-resize",
11009              "node-pluginhost",
11010              "plugin",
11011              "selector"
11012          ]
11013      },
11014      "node-style": {
11015          "requires": [
11016              "dom-style",
11017              "node-base"
11018          ]
11019      },
11020      "oop": {
11021          "requires": [
11022              "yui-base"
11023          ]
11024      },
11025      "overlay": {
11026          "requires": [
11027              "widget",
11028              "widget-stdmod",
11029              "widget-position",
11030              "widget-position-align",
11031              "widget-stack",
11032              "widget-position-constrain"
11033          ],
11034          "skinnable": true
11035      },
11036      "paginator": {
11037          "requires": [
11038              "paginator-core"
11039          ]
11040      },
11041      "paginator-core": {
11042          "requires": [
11043              "base"
11044          ]
11045      },
11046      "paginator-url": {
11047          "requires": [
11048              "paginator"
11049          ]
11050      },
11051      "panel": {
11052          "requires": [
11053              "widget",
11054              "widget-autohide",
11055              "widget-buttons",
11056              "widget-modality",
11057              "widget-position",
11058              "widget-position-align",
11059              "widget-position-constrain",
11060              "widget-stack",
11061              "widget-stdmod"
11062          ],
11063          "skinnable": true
11064      },
11065      "parallel": {
11066          "requires": [
11067              "yui-base"
11068          ]
11069      },
11070      "pjax": {
11071          "requires": [
11072              "pjax-base",
11073              "pjax-content"
11074          ]
11075      },
11076      "pjax-base": {
11077          "requires": [
11078              "classnamemanager",
11079              "node-event-delegate",
11080              "router"
11081          ]
11082      },
11083      "pjax-content": {
11084          "requires": [
11085              "io-base",
11086              "node-base",
11087              "router"
11088          ]
11089      },
11090      "pjax-plugin": {
11091          "requires": [
11092              "node-pluginhost",
11093              "pjax",
11094              "plugin"
11095          ]
11096      },
11097      "plugin": {
11098          "requires": [
11099              "base-base"
11100          ]
11101      },
11102      "pluginhost": {
11103          "use": [
11104              "pluginhost-base",
11105              "pluginhost-config"
11106          ]
11107      },
11108      "pluginhost-base": {
11109          "requires": [
11110              "yui-base"
11111          ]
11112      },
11113      "pluginhost-config": {
11114          "requires": [
11115              "pluginhost-base"
11116          ]
11117      },
11118      "promise": {
11119          "requires": [
11120              "timers"
11121          ]
11122      },
11123      "querystring": {
11124          "use": [
11125              "querystring-parse",
11126              "querystring-stringify"
11127          ]
11128      },
11129      "querystring-parse": {
11130          "requires": [
11131              "yui-base",
11132              "array-extras"
11133          ]
11134      },
11135      "querystring-parse-simple": {
11136          "requires": [
11137              "yui-base"
11138          ]
11139      },
11140      "querystring-stringify": {
11141          "requires": [
11142              "yui-base"
11143          ]
11144      },
11145      "querystring-stringify-simple": {
11146          "requires": [
11147              "yui-base"
11148          ]
11149      },
11150      "queue-promote": {
11151          "requires": [
11152              "yui-base"
11153          ]
11154      },
11155      "range-slider": {
11156          "requires": [
11157              "slider-base",
11158              "slider-value-range",
11159              "clickable-rail"
11160          ]
11161      },
11162      "recordset": {
11163          "use": [
11164              "recordset-base",
11165              "recordset-sort",
11166              "recordset-filter",
11167              "recordset-indexer"
11168          ]
11169      },
11170      "recordset-base": {
11171          "requires": [
11172              "base",
11173              "arraylist"
11174          ]
11175      },
11176      "recordset-filter": {
11177          "requires": [
11178              "recordset-base",
11179              "array-extras",
11180              "plugin"
11181          ]
11182      },
11183      "recordset-indexer": {
11184          "requires": [
11185              "recordset-base",
11186              "plugin"
11187          ]
11188      },
11189      "recordset-sort": {
11190          "requires": [
11191              "arraysort",
11192              "recordset-base",
11193              "plugin"
11194          ]
11195      },
11196      "resize": {
11197          "use": [
11198              "resize-base",
11199              "resize-proxy",
11200              "resize-constrain"
11201          ]
11202      },
11203      "resize-base": {
11204          "requires": [
11205              "base",
11206              "widget",
11207              "event",
11208              "oop",
11209              "dd-drag",
11210              "dd-delegate",
11211              "dd-drop"
11212          ],
11213          "skinnable": true
11214      },
11215      "resize-constrain": {
11216          "requires": [
11217              "plugin",
11218              "resize-base"
11219          ]
11220      },
11221      "resize-plugin": {
11222          "optional": [
11223              "resize-constrain"
11224          ],
11225          "requires": [
11226              "resize-base",
11227              "plugin"
11228          ]
11229      },
11230      "resize-proxy": {
11231          "requires": [
11232              "plugin",
11233              "resize-base"
11234          ]
11235      },
11236      "router": {
11237          "optional": [
11238              "querystring-parse"
11239          ],
11240          "requires": [
11241              "array-extras",
11242              "base-build",
11243              "history"
11244          ]
11245      },
11246      "scrollview": {
11247          "requires": [
11248              "scrollview-base",
11249              "scrollview-scrollbars"
11250          ]
11251      },
11252      "scrollview-base": {
11253          "requires": [
11254              "widget",
11255              "event-gestures",
11256              "event-mousewheel",
11257              "transition"
11258          ],
11259          "skinnable": true
11260      },
11261      "scrollview-base-ie": {
11262          "condition": {
11263              "name": "scrollview-base-ie",
11264              "trigger": "scrollview-base",
11265              "ua": "ie"
11266          },
11267          "requires": [
11268              "scrollview-base"
11269          ]
11270      },
11271      "scrollview-list": {
11272          "requires": [
11273              "plugin",
11274              "classnamemanager"
11275          ],
11276          "skinnable": true
11277      },
11278      "scrollview-paginator": {
11279          "requires": [
11280              "plugin",
11281              "classnamemanager"
11282          ]
11283      },
11284      "scrollview-scrollbars": {
11285          "requires": [
11286              "classnamemanager",
11287              "transition",
11288              "plugin"
11289          ],
11290          "skinnable": true
11291      },
11292      "selector": {
11293          "requires": [
11294              "selector-native"
11295          ]
11296      },
11297      "selector-css2": {
11298          "condition": {
11299              "name": "selector-css2",
11300              "test": function (Y) {
11301      var DOCUMENT = Y.config.doc,
11302          ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
11303  
11304      return ret;
11305  },
11306              "trigger": "selector"
11307          },
11308          "requires": [
11309              "selector-native"
11310          ]
11311      },
11312      "selector-css3": {
11313          "requires": [
11314              "selector-native",
11315              "selector-css2"
11316          ]
11317      },
11318      "selector-native": {
11319          "requires": [
11320              "dom-base"
11321          ]
11322      },
11323      "series-area": {
11324          "requires": [
11325              "series-cartesian",
11326              "series-fill-util"
11327          ]
11328      },
11329      "series-area-stacked": {
11330          "requires": [
11331              "series-stacked",
11332              "series-area"
11333          ]
11334      },
11335      "series-areaspline": {
11336          "requires": [
11337              "series-area",
11338              "series-curve-util"
11339          ]
11340      },
11341      "series-areaspline-stacked": {
11342          "requires": [
11343              "series-stacked",
11344              "series-areaspline"
11345          ]
11346      },
11347      "series-bar": {
11348          "requires": [
11349              "series-marker",
11350              "series-histogram-base"
11351          ]
11352      },
11353      "series-bar-stacked": {
11354          "requires": [
11355              "series-stacked",
11356              "series-bar"
11357          ]
11358      },
11359      "series-base": {
11360          "requires": [
11361              "graphics",
11362              "axis-base"
11363          ]
11364      },
11365      "series-candlestick": {
11366          "requires": [
11367              "series-range"
11368          ]
11369      },
11370      "series-cartesian": {
11371          "requires": [
11372              "series-base"
11373          ]
11374      },
11375      "series-column": {
11376          "requires": [
11377              "series-marker",
11378              "series-histogram-base"
11379          ]
11380      },
11381      "series-column-stacked": {
11382          "requires": [
11383              "series-stacked",
11384              "series-column"
11385          ]
11386      },
11387      "series-combo": {
11388          "requires": [
11389              "series-cartesian",
11390              "series-line-util",
11391              "series-plot-util",
11392              "series-fill-util"
11393          ]
11394      },
11395      "series-combo-stacked": {
11396          "requires": [
11397              "series-stacked",
11398              "series-combo"
11399          ]
11400      },
11401      "series-combospline": {
11402          "requires": [
11403              "series-combo",
11404              "series-curve-util"
11405          ]
11406      },
11407      "series-combospline-stacked": {
11408          "requires": [
11409              "series-combo-stacked",
11410              "series-curve-util"
11411          ]
11412      },
11413      "series-curve-util": {},
11414      "series-fill-util": {},
11415      "series-histogram-base": {
11416          "requires": [
11417              "series-cartesian",
11418              "series-plot-util"
11419          ]
11420      },
11421      "series-line": {
11422          "requires": [
11423              "series-cartesian",
11424              "series-line-util"
11425          ]
11426      },
11427      "series-line-stacked": {
11428          "requires": [
11429              "series-stacked",
11430              "series-line"
11431          ]
11432      },
11433      "series-line-util": {},
11434      "series-marker": {
11435          "requires": [
11436              "series-cartesian",
11437              "series-plot-util"
11438          ]
11439      },
11440      "series-marker-stacked": {
11441          "requires": [
11442              "series-stacked",
11443              "series-marker"
11444          ]
11445      },
11446      "series-ohlc": {
11447          "requires": [
11448              "series-range"
11449          ]
11450      },
11451      "series-pie": {
11452          "requires": [
11453              "series-base",
11454              "series-plot-util"
11455          ]
11456      },
11457      "series-plot-util": {},
11458      "series-range": {
11459          "requires": [
11460              "series-cartesian"
11461          ]
11462      },
11463      "series-spline": {
11464          "requires": [
11465              "series-line",
11466              "series-curve-util"
11467          ]
11468      },
11469      "series-spline-stacked": {
11470          "requires": [
11471              "series-stacked",
11472              "series-spline"
11473          ]
11474      },
11475      "series-stacked": {
11476          "requires": [
11477              "axis-stacked"
11478          ]
11479      },
11480      "shim-plugin": {
11481          "requires": [
11482              "node-style",
11483              "node-pluginhost"
11484          ]
11485      },
11486      "slider": {
11487          "use": [
11488              "slider-base",
11489              "slider-value-range",
11490              "clickable-rail",
11491              "range-slider"
11492          ]
11493      },
11494      "slider-base": {
11495          "requires": [
11496              "widget",
11497              "dd-constrain",
11498              "event-key"
11499          ],
11500          "skinnable": true
11501      },
11502      "slider-value-range": {
11503          "requires": [
11504              "slider-base"
11505          ]
11506      },
11507      "sortable": {
11508          "requires": [
11509              "dd-delegate",
11510              "dd-drop-plugin",
11511              "dd-proxy"
11512          ]
11513      },
11514      "sortable-scroll": {
11515          "requires": [
11516              "dd-scroll",
11517              "sortable"
11518          ]
11519      },
11520      "stylesheet": {
11521          "requires": [
11522              "yui-base"
11523          ]
11524      },
11525      "substitute": {
11526          "optional": [
11527              "dump"
11528          ],
11529          "requires": [
11530              "yui-base"
11531          ]
11532      },
11533      "swf": {
11534          "requires": [
11535              "event-custom",
11536              "node",
11537              "swfdetect",
11538              "escape"
11539          ]
11540      },
11541      "swfdetect": {
11542          "requires": [
11543              "yui-base"
11544          ]
11545      },
11546      "tabview": {
11547          "requires": [
11548              "widget",
11549              "widget-parent",
11550              "widget-child",
11551              "tabview-base",
11552              "node-pluginhost",
11553              "node-focusmanager"
11554          ],
11555          "skinnable": true
11556      },
11557      "tabview-base": {
11558          "requires": [
11559              "node-event-delegate",
11560              "classnamemanager"
11561          ]
11562      },
11563      "tabview-plugin": {
11564          "requires": [
11565              "tabview-base"
11566          ]
11567      },
11568      "template": {
11569          "use": [
11570              "template-base",
11571              "template-micro"
11572          ]
11573      },
11574      "template-base": {
11575          "requires": [
11576              "yui-base"
11577          ]
11578      },
11579      "template-micro": {
11580          "requires": [
11581              "escape"
11582          ]
11583      },
11584      "test": {
11585          "requires": [
11586              "event-simulate",
11587              "event-custom",
11588              "json-stringify"
11589          ]
11590      },
11591      "test-console": {
11592          "requires": [
11593              "console-filters",
11594              "test",
11595              "array-extras"
11596          ],
11597          "skinnable": true
11598      },
11599      "text": {
11600          "use": [
11601              "text-accentfold",
11602              "text-wordbreak"
11603          ]
11604      },
11605      "text-accentfold": {
11606          "requires": [
11607              "array-extras",
11608              "text-data-accentfold"
11609          ]
11610      },
11611      "text-data-accentfold": {
11612          "requires": [
11613              "yui-base"
11614          ]
11615      },
11616      "text-data-wordbreak": {
11617          "requires": [
11618              "yui-base"
11619          ]
11620      },
11621      "text-wordbreak": {
11622          "requires": [
11623              "array-extras",
11624              "text-data-wordbreak"
11625          ]
11626      },
11627      "timers": {
11628          "requires": [
11629              "yui-base"
11630          ]
11631      },
11632      "transition": {
11633          "requires": [
11634              "node-style"
11635          ]
11636      },
11637      "transition-timer": {
11638          "condition": {
11639              "name": "transition-timer",
11640              "test": function (Y) {
11641      var DOCUMENT = Y.config.doc,
11642          node = (DOCUMENT) ? DOCUMENT.documentElement: null,
11643          ret = true;
11644  
11645      if (node && node.style) {
11646          ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
11647      }
11648  
11649      return ret;
11650  },
11651              "trigger": "transition"
11652          },
11653          "requires": [
11654              "transition"
11655          ]
11656      },
11657      "tree": {
11658          "requires": [
11659              "base-build",
11660              "tree-node"
11661          ]
11662      },
11663      "tree-labelable": {
11664          "requires": [
11665              "tree"
11666          ]
11667      },
11668      "tree-lazy": {
11669          "requires": [
11670              "base-pluginhost",
11671              "plugin",
11672              "tree"
11673          ]
11674      },
11675      "tree-node": {},
11676      "tree-openable": {
11677          "requires": [
11678              "tree"
11679          ]
11680      },
11681      "tree-selectable": {
11682          "requires": [
11683              "tree"
11684          ]
11685      },
11686      "tree-sortable": {
11687          "requires": [
11688              "tree"
11689          ]
11690      },
11691      "uploader": {
11692          "requires": [
11693              "uploader-html5",
11694              "uploader-flash"
11695          ]
11696      },
11697      "uploader-flash": {
11698          "requires": [
11699              "swfdetect",
11700              "escape",
11701              "widget",
11702              "base",
11703              "cssbutton",
11704              "node",
11705              "event-custom",
11706              "uploader-queue"
11707          ]
11708      },
11709      "uploader-html5": {
11710          "requires": [
11711              "widget",
11712              "node-event-simulate",
11713              "file-html5",
11714              "uploader-queue"
11715          ]
11716      },
11717      "uploader-queue": {
11718          "requires": [
11719              "base"
11720          ]
11721      },
11722      "view": {
11723          "requires": [
11724              "base-build",
11725              "node-event-delegate"
11726          ]
11727      },
11728      "view-node-map": {
11729          "requires": [
11730              "view"
11731          ]
11732      },
11733      "widget": {
11734          "use": [
11735              "widget-base",
11736              "widget-htmlparser",
11737              "widget-skin",
11738              "widget-uievents"
11739          ]
11740      },
11741      "widget-anim": {
11742          "requires": [
11743              "anim-base",
11744              "plugin",
11745              "widget"
11746          ]
11747      },
11748      "widget-autohide": {
11749          "requires": [
11750              "base-build",
11751              "event-key",
11752              "event-outside",
11753              "widget"
11754          ]
11755      },
11756      "widget-base": {
11757          "requires": [
11758              "attribute",
11759              "base-base",
11760              "base-pluginhost",
11761              "classnamemanager",
11762              "event-focus",
11763              "node-base",
11764              "node-style"
11765          ],
11766          "skinnable": true
11767      },
11768      "widget-base-ie": {
11769          "condition": {
11770              "name": "widget-base-ie",
11771              "trigger": "widget-base",
11772              "ua": "ie"
11773          },
11774          "requires": [
11775              "widget-base"
11776          ]
11777      },
11778      "widget-buttons": {
11779          "requires": [
11780              "button-plugin",
11781              "cssbutton",
11782              "widget-stdmod"
11783          ]
11784      },
11785      "widget-child": {
11786          "requires": [
11787              "base-build",
11788              "widget"
11789          ]
11790      },
11791      "widget-htmlparser": {
11792          "requires": [
11793              "widget-base"
11794          ]
11795      },
11796      "widget-modality": {
11797          "requires": [
11798              "base-build",
11799              "event-outside",
11800              "widget"
11801          ],
11802          "skinnable": true
11803      },
11804      "widget-parent": {
11805          "requires": [
11806              "arraylist",
11807              "base-build",
11808              "widget"
11809          ]
11810      },
11811      "widget-position": {
11812          "requires": [
11813              "base-build",
11814              "node-screen",
11815              "widget"
11816          ]
11817      },
11818      "widget-position-align": {
11819          "requires": [
11820              "widget-position"
11821          ]
11822      },
11823      "widget-position-constrain": {
11824          "requires": [
11825              "widget-position"
11826          ]
11827      },
11828      "widget-skin": {
11829          "requires": [
11830              "widget-base"
11831          ]
11832      },
11833      "widget-stack": {
11834          "requires": [
11835              "base-build",
11836              "widget"
11837          ],
11838          "skinnable": true
11839      },
11840      "widget-stdmod": {
11841          "requires": [
11842              "base-build",
11843              "widget"
11844          ]
11845      },
11846      "widget-uievents": {
11847          "requires": [
11848              "node-event-delegate",
11849              "widget-base"
11850          ]
11851      },
11852      "yql": {
11853          "requires": [
11854              "oop"
11855          ]
11856      },
11857      "yql-jsonp": {
11858          "condition": {
11859              "name": "yql-jsonp",
11860              "test": function (Y) {
11861      /* Only load the JSONP module when not in nodejs or winjs
11862      TODO Make the winjs module a CORS module
11863      */
11864      return (!Y.UA.nodejs && !Y.UA.winjs);
11865  },
11866              "trigger": "yql"
11867          },
11868          "requires": [
11869              "yql",
11870              "jsonp",
11871              "jsonp-url"
11872          ]
11873      },
11874      "yql-nodejs": {
11875          "condition": {
11876              "name": "yql-nodejs",
11877              "trigger": "yql",
11878              "ua": "nodejs"
11879          },
11880          "requires": [
11881              "yql"
11882          ]
11883      },
11884      "yql-winjs": {
11885          "condition": {
11886              "name": "yql-winjs",
11887              "trigger": "yql",
11888              "ua": "winjs"
11889          },
11890          "requires": [
11891              "yql"
11892          ]
11893      },
11894      "yui": {},
11895      "yui-base": {},
11896      "yui-later": {
11897          "requires": [
11898              "yui-base"
11899          ]
11900      },
11901      "yui-log": {
11902          "requires": [
11903              "yui-base"
11904          ]
11905      },
11906      "yui-throttle": {
11907          "requires": [
11908              "yui-base"
11909          ]
11910      }
11911  });
11912  YUI.Env[Y.version].md5 = '45357bb11eddf7fd0a89c0b756599df2';
11913  
11914  
11915  }, '3.17.2', {"requires": ["loader-base"]});
11916  YUI.add('yui', function (Y, NAME) {}, '3.17.2', {
11917      "use": [
11918          "yui-base",
11919          "get",
11920          "features",
11921          "intl-base",
11922          "yui-log",
11923          "yui-later",
11924          "loader-base",
11925          "loader-rollup",
11926          "loader-yui3"
11927      ]
11928  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1