<commit_before>var absURLRegEx = /^[^\/]+:\/\//;

function readMemberExpression(p, value) {
  var pParts = p.split('.');
  while (pParts.length)
    value = value[pParts.shift()];
  return value;
}

var baseURLCache = {};
function getBaseURLObj() {
  if (baseURLCache[this.baseURL])
    return baseURLCache[this.baseURL];

  // normalize baseURL if not already
  if (this.baseURL[this.baseURL.length - 1] != '/')
    this.baseURL += '/';

  var baseURL = new URL(this.baseURL, baseURI);

  this.baseURL = baseURL.href;

  return (baseURLCache[this.baseURL] = baseURL);
}

function getMapMatch(map, name) {
  var bestMatch, bestMatchLength = 0;

  for (var p in map) {
    if (name.substr(0, p.length) == p && (name.length == p.length || name[p.length] == '/')) {
      var curMatchLength = p.split('/').length;
      if (curMatchLength <= bestMatchLength)
        continue;
      bestMatch = p;
      bestMatchLength = curMatchLength;
    }
  }

  return bestMatch;
}

function setProduction(isProduction) {
  this.set('@system-env', this.newModule({
    browser: isBrowser,
    node: !!this._nodeRequire,
    production: isProduction
  }));
}

var baseURIObj = new URL(baseURI);

hookConstructor(function(constructor) {
  return function() {
    constructor.call(this);

    // support baseURL
    this.baseURL = baseURI.substr(0, baseURI.lastIndexOf('/') + 1);

    // support map and paths
    this.map = {};
    this.paths = {};

    // global behaviour flags
    this.warnings = false;
    this.defaultJSExtensions = false;
    this.globalEvaluationScope = true;
    this.pluginFirst = false;

    // by default load ".json" files as json
    // leading * meta doesn't need normalization
    // NB add this in next breaking release
    // this.meta['*.json'] = { format: 'json' };

    // Default settings for globalEvaluationScope:
    // Disabled for WebWorker, Chrome Extensions and jsdom
    if (isWorker
        || isBrowser && window.chrome && window.chrome.extension
        || isBrowser && navigator.userAgent.match(/^Node\.js/))
      this.globalEvaluationScope = false;

    // support the empty module, as a concept
    this.set('@empty', this.newModule({}));

    setProduction.call(this, false);
  };
});

// include the node require since we're overriding it
if (typeof require != 'undefined' && typeof process != 'undefined' && !process.browser)
  SystemJSLoader.prototype._nodeRequire = require;

var nodeCoreModules = ['assert', 'buffer', 'child_process', 'cluster', 'console', 'constants',
    'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'module', 'net', 'os', 'path',
    'process', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'sys', 'timers',
    'tls', 'tty', 'url', 'util', 'vm', 'zlib'];

/*
  Core SystemJS Normalization

  If a name is relative, we apply URL normalization to the page
  If a name is an absolute URL, we leave it as-is

  Plain names (neither of the above) run through the map and paths
  normalization phases.

  The paths normalization phase applies last (paths extension), which
  defines the `decanonicalize` function and normalizes everything into
  a URL.
 */
hook('normalize', function(normalize) {
  return function(name, parentName) {
    // first run map config
    if (name[0] != '.' && name[0] != '/' && !name.match(absURLRegEx)) {
      var mapMatch = getMapMatch(this.map, name);
      if (mapMatch)
        name = this.map[mapMatch] + name.substr(mapMatch.length);
    }

    // dynamically load node-core modules when requiring `@node/fs` for example
    if (name.substr(0, 6) == '@node/' && nodeCoreModules.indexOf(name.substr(6)) != -1) {
      if (!this._nodeRequire)
        throw new TypeError('Error loading ' + name + '. Can only load node core modules in Node.');
      this.set(name, this.newModule(getESModule(this._nodeRequire(name.substr(6)))));
    }

    // relative URL-normalization
    if (name[0] == '.' || name[0] == '/') {
      if (parentName)
        name = new URL(name, parentName.replace(/#/g, '%05')).href.replace(/%05/g, '#');
      else
        name = new URL(name, baseURIObj).href;
    }

    // if the module is in the registry already, use that
    if (this.has(name))
      return name;

    if (name.match(absURLRegEx)) {
      // defaultJSExtensions backwards compatibility
      if (this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js')
        name += '.js';
      return name;
    }

    // applyPaths implementation provided from ModuleLoader system.js source
    name = applyPaths(this.paths, name) || name;

    // defaultJSExtensions backwards compatibility
    if (this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js')
      name += '.js';

    // ./x, /x -> page-relative
    if (name[0] == '.' || name[0] == '/')
      return new URL(name, baseURIObj).href;
    // x -> baseURL-relative
    else
      return new URL(name, getBaseURLObj.call(this)).href;
  };
});

// percent encode just '#' in urls if using HTTP requests
var httpRequest = typeof XMLHttpRequest != 'undefined';
hook('locate', function(locate) {
  return function(load) {
    return Promise.resolve(locate.call(this, load))
    .then(function(address) {
      if (httpRequest)
        return address.replace(/#/g, '%23');
      return address;
    });
  };
});

/*
 * Fetch with authorization
 */
hook('fetch', function() {
  return function(load) {
    return new Promise(function(resolve, reject) {
      fetchTextFromURL(load.address, load.metadata.authorization, resolve, reject);
    });
  };
});

/*
  __useDefault

  When a module object looks like:
  newModule(
    __useDefault: true,
    default: 'some-module'
  })

  Then importing that module provides the 'some-module'
  result directly instead of the full module.

  Useful for eg module.exports = function() {}
*/
hook('import', function(systemImport) {
  return function(name, parentName, parentAddress) {
    if (parentName && parentName.name)
      warn.call(this, 'SystemJS.import(name, { name: parentName }) is deprecated for SystemJS.import(name, parentName), while importing ' + name + ' from ' + parentName.name);
    return systemImport.call(this, name, parentName, parentAddress).then(function(module) {
      return module.__useDefault ? module['default'] : module;
    });
  };
});

/*
 * Allow format: 'detect' meta to enable format detection
 */
hook('translate', function(systemTranslate) {
  return function(load) {
    if (load.metadata.format == 'detect')
      load.metadata.format = undefined;
    return systemTranslate.call(this, load);
  };
});

/*
 * JSON format support
 *
 * Supports loading JSON files as a module format itself
 *
 * Usage:
 *
 * SystemJS.config({
 *   meta: {
 *     '*.json': { format: 'json' }
 *   }
 * });
 *
 * Module is returned as if written:
 *
 * export default {JSON}
 *
 * No named exports are provided
 *
 * Files ending in ".json" are treated as json automatically by SystemJS
 */
hook('instantiate', function(instantiate) {
  return function(load) {
    if (load.metadata.format == 'json' && !this.builder) {
      var entry = load.metadata.entry = createEntry();
      entry.deps = [];
      entry.execute = function() {
        try {
          return JSON.parse(load.source);
        }
        catch(e) {
          throw new Error("Invalid JSON file " + load.name);
        }
      };
    }
  };
})

/*
 Extend config merging one deep only

  loader.config({
    some: 'random',
    config: 'here',
    deep: {
      config: { too: 'too' }
    }
  });

  <=>

  loader.some = 'random';
  loader.config = 'here'
  loader.deep = loader.deep || {};
  loader.deep.config = { too: 'too' };

  Normalizes meta and package configs allowing for:

  SystemJS.config({
    meta: {
      './index.js': {}
    }
  });

  To become

  SystemJS.meta['https://thissite.com/index.js'] = {};

  For easy normalization canonicalization with latest URL support.

*/
SystemJSLoader.prototype.env = 'development';

SystemJSLoader.prototype.config = function(cfg) {
  var loader = this;

  if ('warnings' in cfg)
    loader.warnings = cfg.warnings;

  // transpiler deprecation path
  if (cfg.transpilerRuntime === false)
    loader._loader.loadedTranspilerRuntime = true;

  // always configure baseURL first
  if (cfg.baseURL) {
    var hasConfig = false;
    function checkHasConfig(obj) {
      for (var p in obj)
        if (hasOwnProperty.call(obj, p))
          return true;
    }
    if (checkHasConfig(loader.packages) || checkHasConfig(loader.meta) || checkHasConfig(loader.depCache) || checkHasConfig(loader.bundles) || checkHasConfig(loader.packageConfigPaths))
      throw new TypeError('Incorrect configuration order. The baseURL must be configured with the first SystemJS.config call.');

    loader.baseURL = cfg.baseURL;

    // sanitize baseURL
    getBaseURLObj.call(loader);
  }

  if (cfg.defaultJSExtensions) {
    loader.defaultJSExtensions = cfg.defaultJSExtensions;
    warn.call(loader, 'The defaultJSExtensions configuration option is deprecated, use packages configuration instead.');
  }

  if (cfg.pluginFirst)
    loader.pluginFirst = cfg.pluginFirst;

  if (cfg.production)
    setProduction.call(loader, true);

  if (cfg.paths) {
    for (var p in cfg.paths)
      loader.paths[p] = cfg.paths[p];
  }

  if (cfg.map) {
    var objMaps = '';
    for (var p in cfg.map) {
      var v = cfg.map[p];

      // object map backwards-compat into packages configuration
      if (typeof v !== 'string') {
        objMaps += (objMaps.length ? ', ' : '') + '"' + p + '"';

        var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
        var prop = loader.decanonicalize(p);
        if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
          prop = prop.substr(0, prop.length - 3);

        // if a package main, revert it
        var pkgMatch = '';
        for (var pkg in loader.packages) {
          if (prop.substr(0, pkg.length) == pkg
              && (!prop[pkg.length] || prop[pkg.length] == '/')
              && pkgMatch.split('/').length < pkg.split('/').length)
            pkgMatch = pkg;
        }
        if (pkgMatch && loader.packages[pkgMatch].main)
          prop = prop.substr(0, prop.length - loader.packages[pkgMatch].main.length - 1);

        var pkg = loader.packages[prop] = loader.packages[prop] || {};
        pkg.map = v;
      }
      else {
        loader.map[p] = v;
      }
    }
    if (objMaps)
      warn.call(loader, 'The map configuration for ' + objMaps + ' uses object submaps, which is deprecated in global map.\nUpdate this to use package contextual map with configs like SystemJS.config({ packages: { "' + p + '": { map: {...} } } }).');
  }

  if (cfg.packageConfigPaths) {
    var packageConfigPaths = [];
    for (var i = 0; i < cfg.packageConfigPaths.length; i++) {
      var path = cfg.packageConfigPaths[i];
      var packageLength = Math.max(path.lastIndexOf('*') + 1, path.lastIndexOf('/'));
      var defaultJSExtension = loader.defaultJSExtensions && path.substr(packageLength - 3, 3) != '.js';
      var normalized = loader.decanonicalize(path.substr(0, packageLength));
      if (defaultJSExtension && normalized.substr(normalized.length - 3, 3) == '.js')
        normalized = normalized.substr(0, normalized.length - 3);
      packageConfigPaths[i] = normalized + path.substr(packageLength);
    }
    loader.packageConfigPaths = packageConfigPaths;
  }

  if (cfg.bundles) {
    for (var p in cfg.bundles) {
      var bundle = [];
      for (var i = 0; i < cfg.bundles[p].length; i++) {
        var defaultJSExtension = loader.defaultJSExtensions && cfg.bundles[p][i].substr(cfg.bundles[p][i].length - 3, 3) != '.js';
        var normalizedBundleDep = loader.decanonicalize(cfg.bundles[p][i]);
        if (defaultJSExtension && normalizedBundleDep.substr(normalizedBundleDep.length - 3, 3) == '.js')
          normalizedBundleDep = normalizedBundleDep.substr(0, normalizedBundleDep.length - 3);
        bundle.push(normalizedBundleDep);
      }
      loader.bundles[p] = bundle;
    }
  }

  if (cfg.packages) {
    for (var p in cfg.packages) {
      if (p.match(/^([^\/]+:)?\/\/$/))
        throw new TypeError('"' + p + '" is not a valid package name.');

      var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
      var prop = loader.decanonicalize(p);
      if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
        prop = prop.substr(0, prop.length - 3);

      // allow trailing slash in packages
      if (prop[prop.length - 1] == '/')
        prop = prop.substr(0, prop.length - 1);

      loader.packages[prop] = loader.packages[prop] || {};

      // meta backwards compatibility
      if (cfg.packages[p].modules) {
        warn.call(loader, 'Package ' + p + ' is configured with "modules", which is deprecated as it has been renamed to "meta".');
        cfg.packages[p].meta = cfg.packages[p].modules;
        delete cfg.packages[p].modules;
      }

      for (var q in cfg.packages[p])
        if (indexOf.call(packageProperties, q) == -1)
          warn.call(loader, '"' + q + '" is not a valid package configuration option in package ' + p);

      extendMeta(loader.packages[prop], cfg.packages[p]);
    }
  }

  for (var c in cfg) {
    var v = cfg[c];
    var normalizeProp = false;

    if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles' || c == 'paths' || c == 'warnings' || c == 'packageConfigPaths')
      continue;

    if (typeof v != 'object' || v instanceof Array) {
      loader[c] = v;
    }
    else {
      loader[c] = loader[c] || {};

      if (c == 'meta' || c == 'depCache')
        normalizeProp = true;

      for (var p in v) {
        // base-level wildcard meta does not normalize to retain catch-all quality
        if (c == 'meta' && p[0] == '*') {
          loader[c][p] = v[p];
        }
        else if (normalizeProp) {
          var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
          var prop = loader.decanonicalize(p);
          if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
            prop = prop.substr(0, prop.length - 3);
          loader[c][prop] = v[p];
        }
        else {
          loader[c][p] = v[p];
        }
      }
    }
  }
};<commit_msg>meta configuration to decanonicalize with extensions<commit_after>var absURLRegEx = /^[^\/]+:\/\//;

function readMemberExpression(p, value) {
  var pParts = p.split('.');
  while (pParts.length)
    value = value[pParts.shift()];
  return value;
}

var baseURLCache = {};
function getBaseURLObj() {
  if (baseURLCache[this.baseURL])
    return baseURLCache[this.baseURL];

  // normalize baseURL if not already
  if (this.baseURL[this.baseURL.length - 1] != '/')
    this.baseURL += '/';

  var baseURL = new URL(this.baseURL, baseURI);

  this.baseURL = baseURL.href;

  return (baseURLCache[this.baseURL] = baseURL);
}

function getMapMatch(map, name) {
  var bestMatch, bestMatchLength = 0;

  for (var p in map) {
    if (name.substr(0, p.length) == p && (name.length == p.length || name[p.length] == '/')) {
      var curMatchLength = p.split('/').length;
      if (curMatchLength <= bestMatchLength)
        continue;
      bestMatch = p;
      bestMatchLength = curMatchLength;
    }
  }

  return bestMatch;
}

function setProduction(isProduction) {
  this.set('@system-env', this.newModule({
    browser: isBrowser,
    node: !!this._nodeRequire,
    production: isProduction
  }));
}

var baseURIObj = new URL(baseURI);

hookConstructor(function(constructor) {
  return function() {
    constructor.call(this);

    // support baseURL
    this.baseURL = baseURI.substr(0, baseURI.lastIndexOf('/') + 1);

    // support map and paths
    this.map = {};
    this.paths = {};

    // global behaviour flags
    this.warnings = false;
    this.defaultJSExtensions = false;
    this.globalEvaluationScope = true;
    this.pluginFirst = false;

    // by default load ".json" files as json
    // leading * meta doesn't need normalization
    // NB add this in next breaking release
    // this.meta['*.json'] = { format: 'json' };

    // Default settings for globalEvaluationScope:
    // Disabled for WebWorker, Chrome Extensions and jsdom
    if (isWorker
        || isBrowser && window.chrome && window.chrome.extension
        || isBrowser && navigator.userAgent.match(/^Node\.js/))
      this.globalEvaluationScope = false;

    // support the empty module, as a concept
    this.set('@empty', this.newModule({}));

    setProduction.call(this, false);
  };
});

// include the node require since we're overriding it
if (typeof require != 'undefined' && typeof process != 'undefined' && !process.browser)
  SystemJSLoader.prototype._nodeRequire = require;

var nodeCoreModules = ['assert', 'buffer', 'child_process', 'cluster', 'console', 'constants',
    'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'module', 'net', 'os', 'path',
    'process', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'sys', 'timers',
    'tls', 'tty', 'url', 'util', 'vm', 'zlib'];

/*
  Core SystemJS Normalization

  If a name is relative, we apply URL normalization to the page
  If a name is an absolute URL, we leave it as-is

  Plain names (neither of the above) run through the map and paths
  normalization phases.

  The paths normalization phase applies last (paths extension), which
  defines the `decanonicalize` function and normalizes everything into
  a URL.
 */
hook('normalize', function(normalize) {
  return function(name, parentName) {
    // first run map config
    if (name[0] != '.' && name[0] != '/' && !name.match(absURLRegEx)) {
      var mapMatch = getMapMatch(this.map, name);
      if (mapMatch)
        name = this.map[mapMatch] + name.substr(mapMatch.length);
    }

    // dynamically load node-core modules when requiring `@node/fs` for example
    if (name.substr(0, 6) == '@node/' && nodeCoreModules.indexOf(name.substr(6)) != -1) {
      if (!this._nodeRequire)
        throw new TypeError('Error loading ' + name + '. Can only load node core modules in Node.');
      this.set(name, this.newModule(getESModule(this._nodeRequire(name.substr(6)))));
    }

    // relative URL-normalization
    if (name[0] == '.' || name[0] == '/') {
      if (parentName)
        name = new URL(name, parentName.replace(/#/g, '%05')).href.replace(/%05/g, '#');
      else
        name = new URL(name, baseURIObj).href;
    }

    // if the module is in the registry already, use that
    if (this.has(name))
      return name;

    if (name.match(absURLRegEx)) {
      // defaultJSExtensions backwards compatibility
      if (this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js')
        name += '.js';
      return name;
    }

    // applyPaths implementation provided from ModuleLoader system.js source
    name = applyPaths(this.paths, name) || name;

    // defaultJSExtensions backwards compatibility
    if (this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js')
      name += '.js';

    // ./x, /x -> page-relative
    if (name[0] == '.' || name[0] == '/')
      return new URL(name, baseURIObj).href;
    // x -> baseURL-relative
    else
      return new URL(name, getBaseURLObj.call(this)).href;
  };
});

// percent encode just '#' in urls if using HTTP requests
var httpRequest = typeof XMLHttpRequest != 'undefined';
hook('locate', function(locate) {
  return function(load) {
    return Promise.resolve(locate.call(this, load))
    .then(function(address) {
      if (httpRequest)
        return address.replace(/#/g, '%23');
      return address;
    });
  };
});

/*
 * Fetch with authorization
 */
hook('fetch', function() {
  return function(load) {
    return new Promise(function(resolve, reject) {
      fetchTextFromURL(load.address, load.metadata.authorization, resolve, reject);
    });
  };
});

/*
  __useDefault

  When a module object looks like:
  newModule(
    __useDefault: true,
    default: 'some-module'
  })

  Then importing that module provides the 'some-module'
  result directly instead of the full module.

  Useful for eg module.exports = function() {}
*/
hook('import', function(systemImport) {
  return function(name, parentName, parentAddress) {
    if (parentName && parentName.name)
      warn.call(this, 'SystemJS.import(name, { name: parentName }) is deprecated for SystemJS.import(name, parentName), while importing ' + name + ' from ' + parentName.name);
    return systemImport.call(this, name, parentName, parentAddress).then(function(module) {
      return module.__useDefault ? module['default'] : module;
    });
  };
});

/*
 * Allow format: 'detect' meta to enable format detection
 */
hook('translate', function(systemTranslate) {
  return function(load) {
    if (load.metadata.format == 'detect')
      load.metadata.format = undefined;
    return systemTranslate.call(this, load);
  };
});

/*
 * JSON format support
 *
 * Supports loading JSON files as a module format itself
 *
 * Usage:
 *
 * SystemJS.config({
 *   meta: {
 *     '*.json': { format: 'json' }
 *   }
 * });
 *
 * Module is returned as if written:
 *
 * export default {JSON}
 *
 * No named exports are provided
 *
 * Files ending in ".json" are treated as json automatically by SystemJS
 */
hook('instantiate', function(instantiate) {
  return function(load) {
    if (load.metadata.format == 'json' && !this.builder) {
      var entry = load.metadata.entry = createEntry();
      entry.deps = [];
      entry.execute = function() {
        try {
          return JSON.parse(load.source);
        }
        catch(e) {
          throw new Error("Invalid JSON file " + load.name);
        }
      };
    }
  };
})

/*
 Extend config merging one deep only

  loader.config({
    some: 'random',
    config: 'here',
    deep: {
      config: { too: 'too' }
    }
  });

  <=>

  loader.some = 'random';
  loader.config = 'here'
  loader.deep = loader.deep || {};
  loader.deep.config = { too: 'too' };

  Normalizes meta and package configs allowing for:

  SystemJS.config({
    meta: {
      './index.js': {}
    }
  });

  To become

  SystemJS.meta['https://thissite.com/index.js'] = {};

  For easy normalization canonicalization with latest URL support.

*/
SystemJSLoader.prototype.env = 'development';

SystemJSLoader.prototype.config = function(cfg) {
  var loader = this;

  if ('warnings' in cfg)
    loader.warnings = cfg.warnings;

  // transpiler deprecation path
  if (cfg.transpilerRuntime === false)
    loader._loader.loadedTranspilerRuntime = true;

  // always configure baseURL first
  if (cfg.baseURL) {
    var hasConfig = false;
    function checkHasConfig(obj) {
      for (var p in obj)
        if (hasOwnProperty.call(obj, p))
          return true;
    }
    if (checkHasConfig(loader.packages) || checkHasConfig(loader.meta) || checkHasConfig(loader.depCache) || checkHasConfig(loader.bundles) || checkHasConfig(loader.packageConfigPaths))
      throw new TypeError('Incorrect configuration order. The baseURL must be configured with the first SystemJS.config call.');

    loader.baseURL = cfg.baseURL;

    // sanitize baseURL
    getBaseURLObj.call(loader);
  }

  if (cfg.defaultJSExtensions) {
    loader.defaultJSExtensions = cfg.defaultJSExtensions;
    warn.call(loader, 'The defaultJSExtensions configuration option is deprecated, use packages configuration instead.');
  }

  if (cfg.pluginFirst)
    loader.pluginFirst = cfg.pluginFirst;

  if (cfg.production)
    setProduction.call(loader, true);

  if (cfg.paths) {
    for (var p in cfg.paths)
      loader.paths[p] = cfg.paths[p];
  }

  if (cfg.map) {
    var objMaps = '';
    for (var p in cfg.map) {
      var v = cfg.map[p];

      // object map backwards-compat into packages configuration
      if (typeof v !== 'string') {
        objMaps += (objMaps.length ? ', ' : '') + '"' + p + '"';

        var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
        var prop = loader.decanonicalize(p);
        if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
          prop = prop.substr(0, prop.length - 3);

        // if a package main, revert it
        var pkgMatch = '';
        for (var pkg in loader.packages) {
          if (prop.substr(0, pkg.length) == pkg
              && (!prop[pkg.length] || prop[pkg.length] == '/')
              && pkgMatch.split('/').length < pkg.split('/').length)
            pkgMatch = pkg;
        }
        if (pkgMatch && loader.packages[pkgMatch].main)
          prop = prop.substr(0, prop.length - loader.packages[pkgMatch].main.length - 1);

        var pkg = loader.packages[prop] = loader.packages[prop] || {};
        pkg.map = v;
      }
      else {
        loader.map[p] = v;
      }
    }
    if (objMaps)
      warn.call(loader, 'The map configuration for ' + objMaps + ' uses object submaps, which is deprecated in global map.\nUpdate this to use package contextual map with configs like SystemJS.config({ packages: { "' + p + '": { map: {...} } } }).');
  }

  if (cfg.packageConfigPaths) {
    var packageConfigPaths = [];
    for (var i = 0; i < cfg.packageConfigPaths.length; i++) {
      var path = cfg.packageConfigPaths[i];
      var packageLength = Math.max(path.lastIndexOf('*') + 1, path.lastIndexOf('/'));
      var defaultJSExtension = loader.defaultJSExtensions && path.substr(packageLength - 3, 3) != '.js';
      var normalized = loader.decanonicalize(path.substr(0, packageLength));
      if (defaultJSExtension && normalized.substr(normalized.length - 3, 3) == '.js')
        normalized = normalized.substr(0, normalized.length - 3);
      packageConfigPaths[i] = normalized + path.substr(packageLength);
    }
    loader.packageConfigPaths = packageConfigPaths;
  }

  if (cfg.bundles) {
    for (var p in cfg.bundles) {
      var bundle = [];
      for (var i = 0; i < cfg.bundles[p].length; i++) {
        var defaultJSExtension = loader.defaultJSExtensions && cfg.bundles[p][i].substr(cfg.bundles[p][i].length - 3, 3) != '.js';
        var normalizedBundleDep = loader.decanonicalize(cfg.bundles[p][i]);
        if (defaultJSExtension && normalizedBundleDep.substr(normalizedBundleDep.length - 3, 3) == '.js')
          normalizedBundleDep = normalizedBundleDep.substr(0, normalizedBundleDep.length - 3);
        bundle.push(normalizedBundleDep);
      }
      loader.bundles[p] = bundle;
    }
  }

  if (cfg.packages) {
    for (var p in cfg.packages) {
      if (p.match(/^([^\/]+:)?\/\/$/))
        throw new TypeError('"' + p + '" is not a valid package name.');

      var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
      var prop = loader.decanonicalize(p);
      if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
        prop = prop.substr(0, prop.length - 3);

      // allow trailing slash in packages
      if (prop[prop.length - 1] == '/')
        prop = prop.substr(0, prop.length - 1);

      loader.packages[prop] = loader.packages[prop] || {};

      // meta backwards compatibility
      if (cfg.packages[p].modules) {
        warn.call(loader, 'Package ' + p + ' is configured with "modules", which is deprecated as it has been renamed to "meta".');
        cfg.packages[p].meta = cfg.packages[p].modules;
        delete cfg.packages[p].modules;
      }

      for (var q in cfg.packages[p])
        if (indexOf.call(packageProperties, q) == -1)
          warn.call(loader, '"' + q + '" is not a valid package configuration option in package ' + p);

      extendMeta(loader.packages[prop], cfg.packages[p]);
    }
  }

  for (var c in cfg) {
    var v = cfg[c];

    if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles' || c == 'paths' || c == 'warnings' || c == 'packageConfigPaths')
      continue;

    if (typeof v != 'object' || v instanceof Array) {
      loader[c] = v;
    }
    else {
      loader[c] = loader[c] || {};

      for (var p in v) {
        // base-level wildcard meta does not normalize to retain catch-all quality
        if (c == 'meta' && p[0] == '*') {
          loader[c][p] = v[p];
        }
        else if (c == 'meta') {
          loader[c][loader.decanonicalize(p)] = v[0];
        }
        else if (c == 'depCache') {
          var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
          var prop = loader.decanonicalize(p);
          if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
            prop = prop.substr(0, prop.length - 3);
          loader[c][prop] = v[p];
        }
        else {
          loader[c][p] = v[p];
        }
      }
    }
  }
};<|endoftext|>


<commit_before>import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from '../../tests/helpers/start-app';

let container;

module('Acceptance | instance storage service', {
  beforeEach: function () {
    this.application = startApp();

    container = this.application.__container__;
  },

  afterEach: function () {
    container = null;
    Ember.run(this.application, 'destroy');
  }
});

test('properly sets and gets with . delimited key', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo.bar';
  const value = 'hello world';

  storageService.setItem(key, value);

  assert.equal(storageService.getItem(key), value, 'returned item should match input item.');
});

test('properly sets and gets string value', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo';
  const value = 'hello world';

  storageService.setItem(key, value);

  assert.equal(storageService.getItem(key), value, 'returned item should match input item.');
});

test('properly sets and gets object value', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo';
  const value = {hello: 'world'};

  storageService.setItem(key, value);

  assert.equal(storageService.getItem(key).hello, value.hello);
});

test('properly removes an item', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo';
  const value = 'hello world';

  storageService.setItem(key, value);

  storageService.removeItem(key);

  assert.equal(storageService.getItem(key), undefined);
});

test('properly clears', function (assert) {
  assert.expect(2);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key1 = 'key1';
  const value1 = 'value1';
  const key2 = 'key2';
  const value2 = 'value2';

  storageService.setItem(key1, value1);
  storageService.setItem(key2, value2);

  storageService.clear();

  assert.equal(storageService.getItem(key1), undefined, `${key1} should be cleared`);
  assert.equal(storageService.getItem(key2), undefined, `${key2} should be cleared`);
});

test('length', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');

  assert.equal(storageService.length(), 0);
});

test('key returns correct index', function (assert) {
  assert.expect(2);

  const storageService = container.lookup('storagekit/service:instance-storage');

  storageService.setItem('foo', 'bar');
  storageService.setItem('baz', 'qux');

  assert.equal(storageService.key(0), 'baz');
  assert.equal(storageService.key(1), 'foo');
});

test('#keys returns correct key set', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');

  storageService.setItem('foo', 'bar');
  storageService.setItem('baz', 'qux');

  assert.deepEqual(storageService.keys(), ['baz', 'foo']);
});

<commit_msg>simple formatting (remove extra line)<commit_after>import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from '../../tests/helpers/start-app';

let container;

module('Acceptance | instance storage service', {
  beforeEach: function () {
    this.application = startApp();

    container = this.application.__container__;
  },

  afterEach: function () {
    container = null;
    Ember.run(this.application, 'destroy');
  }
});

test('properly sets and gets with . delimited key', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo.bar';
  const value = 'hello world';

  storageService.setItem(key, value);

  assert.equal(storageService.getItem(key), value, 'returned item should match input item.');
});

test('properly sets and gets string value', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo';
  const value = 'hello world';

  storageService.setItem(key, value);

  assert.equal(storageService.getItem(key), value, 'returned item should match input item.');
});

test('properly sets and gets object value', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo';
  const value = {hello: 'world'};

  storageService.setItem(key, value);

  assert.equal(storageService.getItem(key).hello, value.hello);
});

test('properly removes an item', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key = 'foo';
  const value = 'hello world';

  storageService.setItem(key, value);

  storageService.removeItem(key);

  assert.equal(storageService.getItem(key), undefined);
});

test('properly clears', function (assert) {
  assert.expect(2);

  const storageService = container.lookup('storagekit/service:instance-storage');
  const key1 = 'key1';
  const value1 = 'value1';
  const key2 = 'key2';
  const value2 = 'value2';

  storageService.setItem(key1, value1);
  storageService.setItem(key2, value2);

  storageService.clear();

  assert.equal(storageService.getItem(key1), undefined, `${key1} should be cleared`);
  assert.equal(storageService.getItem(key2), undefined, `${key2} should be cleared`);
});

test('length', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');

  assert.equal(storageService.length(), 0);
});

test('key returns correct index', function (assert) {
  assert.expect(2);

  const storageService = container.lookup('storagekit/service:instance-storage');

  storageService.setItem('foo', 'bar');
  storageService.setItem('baz', 'qux');

  assert.equal(storageService.key(0), 'baz');
  assert.equal(storageService.key(1), 'foo');
});

test('#keys returns correct key set', function (assert) {
  assert.expect(1);

  const storageService = container.lookup('storagekit/service:instance-storage');

  storageService.setItem('foo', 'bar');
  storageService.setItem('baz', 'qux');

  assert.deepEqual(storageService.keys(), ['baz', 'foo']);
});
<|endoftext|>


<commit_before>/* @flow */

import eventsReducer from '../events';
import { mockedEvents } from '../../__mocks__/data/mockedEvents';
import moment from 'moment';

import type { EventsState, EventsStateData } from '../events';
import type { EventsData } from '../../types/apiData';
import type { Action } from '../../types/actions';
import type { Event } from '../../types/model';

describe('events reducer', () => {
  const initialState: EventsState = {
    data: {},
    dataFetched: false,
    isFetching: false,
    error: false
  };

  it('has initial empty state', () => {
    expect(eventsReducer(undefined, ({}: any))).toEqual(initialState);
  });

  it('adds fetched events', () => {
    const events: EventsData = mockedEvents;
    const action: Action = {
      type: 'EVENTS_FETCHING_DATA_SUCCESS',
      data: events
    };

    // Number of added events match
    expect(Object.keys(eventsReducer(undefined, action).data)).toHaveLength(
      mockedEvents.length
    );

    // Structure of data object (id as key)
    expect(eventsReducer(undefined, action).data[mockedEvents[0].id]).toEqual(
      mockedEvents[0]
    );

    expect(eventsReducer(undefined, action)).toMatchObject({
      dataFetched: true,
      isFetching: false,
      error: false
    });
  });

  it('filters past events', () => {
    jest.unmock('moment');
    const pastEvent: Event = {
      id: '1',
      name: 'Past event',
      description: null,
      url: 'https://example.org',
      start: moment().subtract(2, 'days').toISOString(),
      image: 'https://example.org'
    };
    const currentEvent: Event = {
      id: '2',
      name: 'Current event',
      description: null,
      url: 'https://example.org',
      start: moment().subtract(1, 'hours').toISOString(),
      end: moment().add(1, 'hours').toISOString(),
      image: 'https://example.org'
    };
    const futureEvent: Event = {
      id: '3',
      name: 'Future event',
      description: null,
      url: 'https://example.org',
      start: moment().add(2, 'days').toISOString(),
      image: 'https://example.org'
    };
    const action: Action = {
      type: 'persist/REHYDRATE',
      payload: {
        events: {
          data: {
            '1': pastEvent,
            '2': currentEvent,
            '3': futureEvent
          },
          dataFetched: false,
          isFetching: false,
          error: false
        },
        bookmarks: {}
      }
    };

    expect(eventsReducer(undefined, action)).toEqual({
      data: {
        '2': currentEvent,
        '3': futureEvent
      },
      dataFetched: false,
      isFetching: false,
      error: false
    });
  });
});
<commit_msg>♻ remove unused import<commit_after>/* @flow */

import eventsReducer from '../events';
import { mockedEvents } from '../../__mocks__/data/mockedEvents';
import moment from 'moment';

import type { EventsState } from '../events';
import type { EventsData } from '../../types/apiData';
import type { Action } from '../../types/actions';
import type { Event } from '../../types/model';

describe('events reducer', () => {
  const initialState: EventsState = {
    data: {},
    dataFetched: false,
    isFetching: false,
    error: false
  };

  it('has initial empty state', () => {
    expect(eventsReducer(undefined, ({}: any))).toEqual(initialState);
  });

  it('adds fetched events', () => {
    const events: EventsData = mockedEvents;
    const action: Action = {
      type: 'EVENTS_FETCHING_DATA_SUCCESS',
      data: events
    };

    // Number of added events match
    expect(Object.keys(eventsReducer(undefined, action).data)).toHaveLength(
      mockedEvents.length
    );

    // Structure of data object (id as key)
    expect(eventsReducer(undefined, action).data[mockedEvents[0].id]).toEqual(
      mockedEvents[0]
    );

    expect(eventsReducer(undefined, action)).toMatchObject({
      dataFetched: true,
      isFetching: false,
      error: false
    });
  });

  it('filters past events', () => {
    jest.unmock('moment');
    const pastEvent: Event = {
      id: '1',
      name: 'Past event',
      description: null,
      url: 'https://example.org',
      start: moment().subtract(2, 'days').toISOString(),
      image: 'https://example.org'
    };
    const currentEvent: Event = {
      id: '2',
      name: 'Current event',
      description: null,
      url: 'https://example.org',
      start: moment().subtract(1, 'hours').toISOString(),
      end: moment().add(1, 'hours').toISOString(),
      image: 'https://example.org'
    };
    const futureEvent: Event = {
      id: '3',
      name: 'Future event',
      description: null,
      url: 'https://example.org',
      start: moment().add(2, 'days').toISOString(),
      image: 'https://example.org'
    };
    const action: Action = {
      type: 'persist/REHYDRATE',
      payload: {
        events: {
          data: {
            '1': pastEvent,
            '2': currentEvent,
            '3': futureEvent
          },
          dataFetched: false,
          isFetching: false,
          error: false
        },
        bookmarks: {}
      }
    };

    expect(eventsReducer(undefined, action)).toEqual({
      data: {
        '2': currentEvent,
        '3': futureEvent
      },
      dataFetched: false,
      isFetching: false,
      error: false
    });
  });
});
<|endoftext|>


<commit_before>var tokenizerUtils = require('../tokenizer/utils');
var findIdentifierEnd = tokenizerUtils.findIdentifierEnd;
var findNumberEnd = tokenizerUtils.findNumberEnd;
var findDecimalNumberEnd = tokenizerUtils.findDecimalNumberEnd;
var isHex = tokenizerUtils.isHex;
var tokenizerConst = require('../tokenizer/const');
var SYMBOL_TYPE = tokenizerConst.SYMBOL_TYPE;
var IDENTIFIER = tokenizerConst.TYPE.Identifier;
var PLUSSIGN = tokenizerConst.TYPE.PlusSign;
var HYPHENMINUS = tokenizerConst.TYPE.HyphenMinus;
var NUMBERSIGN = tokenizerConst.TYPE.NumberSign;

var PERCENTAGE = {
    '%': true
};

// https://www.w3.org/TR/css-values-3/#lengths
var LENGTH = {
    // absolute length units
    'px': true,
    'mm': true,
    'cm': true,
    'in': true,
    'pt': true,
    'pc': true,
    'q': true,

    // relative length units
    'em': true,
    'ex': true,
    'ch': true,
    'rem': true,

    // viewport-percentage lengths
    'vh': true,
    'vw': true,
    'vmin': true,
    'vmax': true,
    'vm': true
};

var ANGLE = {
    'deg': true,
    'grad': true,
    'rad': true,
    'turn': true
};

var TIME = {
    's': true,
    'ms': true
};

var FREQUENCY = {
    'hz': true,
    'khz': true
};

// https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
var RESOLUTION = {
    'dpi': true,
    'dpcm': true,
    'dppx': true,
    'x': true      // https://github.com/w3c/csswg-drafts/issues/461
};

// https://drafts.csswg.org/css-grid/#fr-unit
var FLEX = {
    'fr': true
};

// https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
var DECIBEL = {
    'db': true
};

// https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
var SEMITONES = {
    'st': true
};

function consumeFunction(token, addTokenToMatch, getNextToken) {
    var length = 1;
    var cursor;

    do {
        cursor = getNextToken(length++);
    } while (cursor !== null && cursor.node !== token.node);

    if (cursor === null) {
        return false;
    }

    while (true) {
        // consume tokens until cursor
        if (addTokenToMatch() === cursor) {
            break;
        }
    }

    return true;
}

// TODO: implement
// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
// https://drafts.csswg.org/css-values/#calc-notation
function calc(token, addTokenToMatch, getNextToken) {
    if (token === null) {
        return false;
    }

    var name = token.value.toLowerCase();
    if (name !== 'calc(' &&
        name !== '-moz-calc(' &&
        name !== '-webkit-calc(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function attr(token, addTokenToMatch, getNextToken) {
    if (token === null || token.value.toLowerCase() !== 'attr(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function expression(token, addTokenToMatch, getNextToken) {
    if (token === null || token.value.toLowerCase() !== 'expression(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function url(token, addTokenToMatch, getNextToken) {
    if (token === null || token.value.toLowerCase() !== 'url(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function idSelector(token, addTokenToMatch) {
    if (token === null) {
        return false;
    }

    if (token.value.charCodeAt(0) !== NUMBERSIGN) {
        return false;
    }

    if (consumeIdentifier(token.value, 1) !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function isNumber(str) {
    return /^[-+]?(\d+|\d*\.\d+)([eE][-+]?\d+)?$/.test(str);
}

function consumeNumber(str, allowFraction) {
    var code = str.charCodeAt(0);

    return findNumberEnd(str, code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0, allowFraction);
}

function consumeIdentifier(str, offset) {
    var code = str.charCodeAt(offset);

    if (code < 0x80 && SYMBOL_TYPE[code] !== IDENTIFIER && code !== HYPHENMINUS) {
        return offset;
    }

    return findIdentifierEnd(str, offset + 1);
}

function astNode(type) {
    return function(token, addTokenToMatch) {
        if (token === null || token.node.type !== type) {
            return false;
        }

        addTokenToMatch();
        return true;
    };
}

function dimension(type) {
    return function(token, addTokenToMatch, getNextToken) {
        if (calc(token, addTokenToMatch, getNextToken)) {
            return true;
        }

        if (token === null) {
            return false;
        }

        var numberEnd = consumeNumber(token.value, true);
        if (numberEnd === 0) {
            return false;
        }

        if (type) {
            if (!type.hasOwnProperty(token.value.substr(numberEnd).toLowerCase())) {
                return false;
            }
        } else {
            var unitEnd = consumeIdentifier(token.value, numberEnd);
            if (unitEnd === numberEnd || unitEnd !== token.value.length) {
                return false;
            }
        }

        addTokenToMatch();
        return true;
    };
}

function zeroUnitlessDimension(type) {
    var isDimension = dimension(type);

    return function(token, addTokenToMatch, getNextToken) {
        if (isDimension(token, addTokenToMatch, getNextToken)) {
            return true;
        }

        if (token === null || Number(token.value) !== 0) {
            return false;
        }

        addTokenToMatch();
        return true;
    };
}

function number(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null) {
        return false;
    }

    var numberEnd = consumeNumber(token.value, true);
    if (numberEnd !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function numberZeroOne(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null || !isNumber(token.value)) {
        return false;
    }

    var value = Number(token.value);
    if (value < 0 || value > 1) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function numberOneOrGreater(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null || !isNumber(token.value)) {
        return false;
    }

    var value = Number(token.value);
    if (value < 1) {
        return false;
    }

    addTokenToMatch();
    return true;
}

// TODO: fail on 10e-2
function integer(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null) {
        return false;
    }

    var numberEnd = consumeNumber(token.value, false);
    if (numberEnd !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

// TODO: fail on 10e-2
function positiveInteger(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null) {
        return false;
    }

    var numberEnd = findDecimalNumberEnd(token.value, 0);
    if (numberEnd !== token.value.length || token.value.charCodeAt(0) === HYPHENMINUS) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function hexColor(token, addTokenToMatch) {
    if (token === null || token.value.charCodeAt(0) !== NUMBERSIGN) {
        return false;
    }

    var length = token.value.length - 1;

    // valid length is 3, 4, 6 and 8 (+1 for #)
    if (length !== 3 && length !== 4 && length !== 6 && length !== 8) {
        return false;
    }

    for (var i = 1; i < length; i++) {
        if (!isHex(token.value.charCodeAt(i))) {
            return false;
        }
    }

    addTokenToMatch();
    return true;
}

// https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
// https://drafts.csswg.org/css-values-4/#identifier-value
function customIdent(token, addTokenToMatch) {
    if (token === null) {
        return false;
    }

    var identEnd = consumeIdentifier(token.value, 0);
    if (identEnd !== token.value.length) {
        return false;
    }

    var name = token.value.toLowerCase();

    // § 3.2. Author-defined Identifiers: the <custom-ident> type
    // The CSS-wide keywords are not valid <custom-ident>s
    if (name === 'unset' || name === 'initial' || name === 'inherit') {
        return false;
    }

    // The default keyword is reserved and is also not a valid <custom-ident>
    if (name === 'default') {
        return false;
    }

    // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)

    addTokenToMatch();
    return true;
}

module.exports = {
    'angle': zeroUnitlessDimension(ANGLE),
    'attr()': attr,
    'custom-ident': customIdent,
    'decibel': dimension(DECIBEL),
    'dimension': dimension(),
    'frequency': dimension(FREQUENCY),
    'flex': dimension(FLEX),
    'hex-color': hexColor,
    'id-selector': idSelector, // element( <id-selector> )
    'ident': astNode('Identifier'),
    'integer': integer,
    'length': zeroUnitlessDimension(LENGTH),
    'number': number,
    'number-zero-one': numberZeroOne,
    'number-one-or-greater': numberOneOrGreater,
    'percentage': dimension(PERCENTAGE),
    'positive-integer': positiveInteger,
    'resolution': dimension(RESOLUTION),
    'semitones': dimension(SEMITONES),
    'string': astNode('String'),
    'time': dimension(TIME),
    'unicode-range': astNode('UnicodeRange'),
    'url': url,

    // old IE stuff
    'progid': astNode('Raw'),
    'expression': expression
};
<commit_msg>make <string> and <ident> generics checking indepence of AST node<commit_after>var tokenizerUtils = require('../tokenizer/utils');
var findIdentifierEnd = tokenizerUtils.findIdentifierEnd;
var findNumberEnd = tokenizerUtils.findNumberEnd;
var findDecimalNumberEnd = tokenizerUtils.findDecimalNumberEnd;
var findStringEnd = tokenizerUtils.findStringEnd;
var isHex = tokenizerUtils.isHex;
var tokenizerConst = require('../tokenizer/const');
var SYMBOL_TYPE = tokenizerConst.SYMBOL_TYPE;
var IDENTIFIER = tokenizerConst.TYPE.Identifier;
var PLUSSIGN = tokenizerConst.TYPE.PlusSign;
var HYPHENMINUS = tokenizerConst.TYPE.HyphenMinus;
var NUMBERSIGN = tokenizerConst.TYPE.NumberSign;
var APOSTROPHE = tokenizerConst.TYPE.Apostrophe;
var QUOTATIONMARK = tokenizerConst.TYPE.QuotationMark;

var PERCENTAGE = {
    '%': true
};

// https://www.w3.org/TR/css-values-3/#lengths
var LENGTH = {
    // absolute length units
    'px': true,
    'mm': true,
    'cm': true,
    'in': true,
    'pt': true,
    'pc': true,
    'q': true,

    // relative length units
    'em': true,
    'ex': true,
    'ch': true,
    'rem': true,

    // viewport-percentage lengths
    'vh': true,
    'vw': true,
    'vmin': true,
    'vmax': true,
    'vm': true
};

var ANGLE = {
    'deg': true,
    'grad': true,
    'rad': true,
    'turn': true
};

var TIME = {
    's': true,
    'ms': true
};

var FREQUENCY = {
    'hz': true,
    'khz': true
};

// https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
var RESOLUTION = {
    'dpi': true,
    'dpcm': true,
    'dppx': true,
    'x': true      // https://github.com/w3c/csswg-drafts/issues/461
};

// https://drafts.csswg.org/css-grid/#fr-unit
var FLEX = {
    'fr': true
};

// https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
var DECIBEL = {
    'db': true
};

// https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
var SEMITONES = {
    'st': true
};

function consumeFunction(token, addTokenToMatch, getNextToken) {
    var length = 1;
    var cursor;

    do {
        cursor = getNextToken(length++);
    } while (cursor !== null && cursor.node !== token.node);

    if (cursor === null) {
        return false;
    }

    while (true) {
        // consume tokens until cursor
        if (addTokenToMatch() === cursor) {
            break;
        }
    }

    return true;
}

// TODO: implement
// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
// https://drafts.csswg.org/css-values/#calc-notation
function calc(token, addTokenToMatch, getNextToken) {
    if (token === null) {
        return false;
    }

    var name = token.value.toLowerCase();
    if (name !== 'calc(' &&
        name !== '-moz-calc(' &&
        name !== '-webkit-calc(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function attr(token, addTokenToMatch, getNextToken) {
    if (token === null || token.value.toLowerCase() !== 'attr(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function expression(token, addTokenToMatch, getNextToken) {
    if (token === null || token.value.toLowerCase() !== 'expression(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function url(token, addTokenToMatch, getNextToken) {
    if (token === null || token.value.toLowerCase() !== 'url(') {
        return false;
    }

    return consumeFunction(token, addTokenToMatch, getNextToken);
}

function idSelector(token, addTokenToMatch) {
    if (token === null) {
        return false;
    }

    if (token.value.charCodeAt(0) !== NUMBERSIGN) {
        return false;
    }

    if (consumeIdentifier(token.value, 1) !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function isNumber(str) {
    return /^[-+]?(\d+|\d*\.\d+)([eE][-+]?\d+)?$/.test(str);
}

function consumeNumber(str, allowFraction) {
    var code = str.charCodeAt(0);

    return findNumberEnd(str, code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0, allowFraction);
}

function consumeIdentifier(str, offset) {
    var code = str.charCodeAt(offset);

    if (code < 0x80 && SYMBOL_TYPE[code] !== IDENTIFIER && code !== HYPHENMINUS) {
        return offset;
    }

    return findIdentifierEnd(str, offset + 1);
}

function ident(token, addTokenToMatch) {
    if (token === null) {
        return false;
    }

    if (consumeIdentifier(token.value, 0) !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function astNode(type) {
    return function(token, addTokenToMatch) {
        if (token === null || token.node.type !== type) {
            return false;
        }

        addTokenToMatch();
        return true;
    };
}

function string(token, addTokenToMatch) {
    if (token === null || token.value.length < 2) {
        return false;
    }

    var quote = token.value.charCodeAt(0);

    if (quote !== APOSTROPHE && quote !== QUOTATIONMARK) {
        return false;
    }

    if (findStringEnd(token.value, 1, quote) !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function dimension(type) {
    return function(token, addTokenToMatch, getNextToken) {
        if (calc(token, addTokenToMatch, getNextToken)) {
            return true;
        }

        if (token === null) {
            return false;
        }

        var numberEnd = consumeNumber(token.value, true);
        if (numberEnd === 0) {
            return false;
        }

        if (type) {
            if (!type.hasOwnProperty(token.value.substr(numberEnd).toLowerCase())) {
                return false;
            }
        } else {
            var unitEnd = consumeIdentifier(token.value, numberEnd);
            if (unitEnd === numberEnd || unitEnd !== token.value.length) {
                return false;
            }
        }

        addTokenToMatch();
        return true;
    };
}

function zeroUnitlessDimension(type) {
    var isDimension = dimension(type);

    return function(token, addTokenToMatch, getNextToken) {
        if (isDimension(token, addTokenToMatch, getNextToken)) {
            return true;
        }

        if (token === null || Number(token.value) !== 0) {
            return false;
        }

        addTokenToMatch();
        return true;
    };
}

function number(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null) {
        return false;
    }

    var numberEnd = consumeNumber(token.value, true);
    if (numberEnd !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function numberZeroOne(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null || !isNumber(token.value)) {
        return false;
    }

    var value = Number(token.value);
    if (value < 0 || value > 1) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function numberOneOrGreater(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null || !isNumber(token.value)) {
        return false;
    }

    var value = Number(token.value);
    if (value < 1) {
        return false;
    }

    addTokenToMatch();
    return true;
}

// TODO: fail on 10e-2
function integer(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null) {
        return false;
    }

    var numberEnd = consumeNumber(token.value, false);
    if (numberEnd !== token.value.length) {
        return false;
    }

    addTokenToMatch();
    return true;
}

// TODO: fail on 10e-2
function positiveInteger(token, addTokenToMatch, getNextToken) {
    if (calc(token, addTokenToMatch, getNextToken)) {
        return true;
    }

    if (token === null) {
        return false;
    }

    var numberEnd = findDecimalNumberEnd(token.value, 0);
    if (numberEnd !== token.value.length || token.value.charCodeAt(0) === HYPHENMINUS) {
        return false;
    }

    addTokenToMatch();
    return true;
}

function hexColor(token, addTokenToMatch) {
    if (token === null || token.value.charCodeAt(0) !== NUMBERSIGN) {
        return false;
    }

    var length = token.value.length - 1;

    // valid length is 3, 4, 6 and 8 (+1 for #)
    if (length !== 3 && length !== 4 && length !== 6 && length !== 8) {
        return false;
    }

    for (var i = 1; i < length; i++) {
        if (!isHex(token.value.charCodeAt(i))) {
            return false;
        }
    }

    addTokenToMatch();
    return true;
}

// https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
// https://drafts.csswg.org/css-values-4/#identifier-value
function customIdent(token, addTokenToMatch) {
    if (token === null) {
        return false;
    }

    var identEnd = consumeIdentifier(token.value, 0);
    if (identEnd !== token.value.length) {
        return false;
    }

    var name = token.value.toLowerCase();

    // § 3.2. Author-defined Identifiers: the <custom-ident> type
    // The CSS-wide keywords are not valid <custom-ident>s
    if (name === 'unset' || name === 'initial' || name === 'inherit') {
        return false;
    }

    // The default keyword is reserved and is also not a valid <custom-ident>
    if (name === 'default') {
        return false;
    }

    // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)

    addTokenToMatch();
    return true;
}

module.exports = {
    'angle': zeroUnitlessDimension(ANGLE),
    'attr()': attr,
    'custom-ident': customIdent,
    'decibel': dimension(DECIBEL),
    'dimension': dimension(),
    'frequency': dimension(FREQUENCY),
    'flex': dimension(FLEX),
    'hex-color': hexColor,
    'id-selector': idSelector, // element( <id-selector> )
    'ident': ident,
    'integer': integer,
    'length': zeroUnitlessDimension(LENGTH),
    'number': number,
    'number-zero-one': numberZeroOne,
    'number-one-or-greater': numberOneOrGreater,
    'percentage': dimension(PERCENTAGE),
    'positive-integer': positiveInteger,
    'resolution': dimension(RESOLUTION),
    'semitones': dimension(SEMITONES),
    'string': string,
    'time': dimension(TIME),
    'unicode-range': astNode('UnicodeRange'),
    'url': url,

    // old IE stuff
    'progid': astNode('Raw'),
    'expression': expression
};
<|endoftext|>


<commit_before>import _default from "ember-views/views/states/default";
import EmberError from "ember-metal/error";

import Ember from "ember-metal/core"; // Ember.assert
import { create } from "ember-metal/platform";
import merge from "ember-metal/merge";

/**
@module ember
@submodule ember-views
*/

var inBuffer = create(_default);

merge(inBuffer, {
  $: function(view, sel) {
    // if we don't have an element yet, someone calling this.$() is
    // trying to update an element that isn't in the DOM. Instead,
    // rerender the view to allow the render method to reflect the
    // changes.
    view.rerender();
    return Ember.$();
  },

  // when a view is rendered in a buffer, rerendering it simply
  // replaces the existing buffer with a new one
  rerender: function(view) {
    throw new EmberError("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.");
  },

  // when a view is rendered in a buffer, appending a child
  // view will render that view and append the resulting
  // buffer into its buffer.
  appendChild: function(view, childView, options) {
    var buffer = view.buffer;
    var _childViews = view._childViews;

    childView = view.createChildView(childView, options);
    if (!_childViews.length) { _childViews = view._childViews = _childViews.slice(); }
    _childViews.push(childView);

    if (!childView._morph) {
      buffer.pushChildView(childView);
    }

    view.propertyDidChange('childViews');

    return childView;
  },

  invokeObserver: function(target, observer) {
    observer.call(target);
  }
});

export default inBuffer;
<commit_msg>Import only jQuery instead of Ember in ember-views.<commit_after>import _default from "ember-views/views/states/default";
import EmberError from "ember-metal/error";

import jQuery from "ember-views/system/jquery";
import { create } from "ember-metal/platform";
import merge from "ember-metal/merge";

/**
@module ember
@submodule ember-views
*/

var inBuffer = create(_default);

merge(inBuffer, {
  $: function(view, sel) {
    // if we don't have an element yet, someone calling this.$() is
    // trying to update an element that isn't in the DOM. Instead,
    // rerender the view to allow the render method to reflect the
    // changes.
    view.rerender();
    return jQuery();
  },

  // when a view is rendered in a buffer, rerendering it simply
  // replaces the existing buffer with a new one
  rerender: function(view) {
    throw new EmberError("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.");
  },

  // when a view is rendered in a buffer, appending a child
  // view will render that view and append the resulting
  // buffer into its buffer.
  appendChild: function(view, childView, options) {
    var buffer = view.buffer;
    var _childViews = view._childViews;

    childView = view.createChildView(childView, options);
    if (!_childViews.length) { _childViews = view._childViews = _childViews.slice(); }
    _childViews.push(childView);

    if (!childView._morph) {
      buffer.pushChildView(childView);
    }

    view.propertyDidChange('childViews');

    return childView;
  },

  invokeObserver: function(target, observer) {
    observer.call(target);
  }
});

export default inBuffer;
<|endoftext|>


<commit_before>const debug = require('debug')('faktory-worker:connection-pool');
const Connection = require('./connection');
const sleep = require('./sleep');

/**
 * pools connections to the faktory server, ensuring that they're
 * connected before lending them
 * @private
 */
class ConnectionFactory {
  /**
   * @param {object} options
   * @param {string} options.host host to connect to
   * @param {string|number} port port to connect to host on
   * @param {function} handshake a function to perform the handshake for a connection
   *                             after it connects
   */
  constructor({ host, port, handshake }) {
    this.host = host;
    this.port = port;
    this.handshake = handshake;
    this.attempts = 0;
    this.onConnectionError = console.warn.bind(console);
  }

  /**
   * Creates a connection for the pool
   * connections are not added to the pool until the handshake (server greeting)
   * is complete and successful
   */
  async create() {
    debug('+1');
    const connection = new Connection(this.port, this.host);
    connection.on('error', this.onConnectionError);
    try {
      const greeting = await connection.open();
      await this.handshake(connection, greeting);
      this.attempts = 0;
    } catch (e) {
      this.attempts += 1;
      debug('attempts=%i', this.attempts);
      await sleep(130 * this.attempts * 2);
      throw e;
    }
    return connection;
  }

  /**
   * Destroys a connection from the pool
   */
  destroy(connection) {
    debug('-1');
    connection.removeListener('error', this.onConnectionError);
    return connection.close();
  }

  /**
   * Validates that a connection from the pool is ready
   */
  validate(connection) {
    return connection.connected;
  }
}

module.exports = ConnectionFactory;
<commit_msg>apply ceiling to connection backoff<commit_after>const debug = require('debug')('faktory-worker:connection-pool');
const Connection = require('./connection');
const sleep = require('./sleep');

/**
 * pools connections to the faktory server, ensuring that they're
 * connected before lending them
 * @private
 */
class ConnectionFactory {
  /**
   * @param {object} options
   * @param {string} options.host host to connect to
   * @param {string|number} port port to connect to host on
   * @param {function} handshake a function to perform the handshake for a connection
   *                             after it connects
   */
  constructor({ host, port, handshake }) {
    this.host = host;
    this.port = port;
    this.handshake = handshake;
    this.attempts = 0;
    this.onConnectionError = console.warn.bind(console);
  }

  /**
   * Creates a connection for the pool
   * connections are not added to the pool until the handshake (server greeting)
   * is complete and successful
   */
  async create() {
    debug('+1');
    const connection = new Connection(this.port, this.host);
    connection.on('error', this.onConnectionError);
    try {
      const greeting = await connection.open();
      await this.handshake(connection, greeting);
      this.attempts = 0;
    } catch (e) {
      this.attempts += 1;
      debug('attempts=%i', this.attempts);
      await sleep(200 * Math.min([this.attempts, 20]));
      throw e;
    }
    return connection;
  }

  /**
   * Destroys a connection from the pool
   */
  destroy(connection) {
    debug('-1');
    connection.removeListener('error', this.onConnectionError);
    return connection.close();
  }

  /**
   * Validates that a connection from the pool is ready
   */
  validate(connection) {
    return connection.connected;
  }
}

module.exports = ConnectionFactory;
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import Ember from 'ember';
import moment from 'moment';
import wait from 'ember-test-helpers/wait';

const { Object: EmberObject, RSVP, Service } = Ember;
const { Promise, resolve } = RSVP;

let ourEvent;
let course;
let session;
let sessionType;
let sessionDescription;
let offering;
let storeMock;
moduleForComponent('single-event', 'Integration | Component | ilios calendar single event', {
  integration: true,
  beforeEach() {
    window.Promise = Promise;
    const now = moment().hour(8).minute(0).second(0);

    course = EmberObject.create({
      id: 1,
      title: 'test course',
      sortedObjectives: resolve([]),
    });
    sessionType = EmberObject.create({
      id: 1,
      title: 'test type',
    });
    sessionDescription = EmberObject.create({
      id: 1,
      description: 'test description',
    });
    session = EmberObject.create({
      id: 1,
      title: 'test session',
      course: resolve(course),
      sessionType: resolve(sessionType),
      sessionDescription: resolve(sessionDescription),
      sortedObjectives: resolve([]),
    });
    offering = EmberObject.create({
      id: 1,
      session: resolve(session),
    });
    ourEvent = EmberObject.create({
      user: 1,
      courseExternalId: 'ext1',
      sessionTypeTitle: 'session type',
      name: 'test event',
      courseTitle: 'test course',
      startDate: now,
      endDate: now.clone().add(1, 'hour'),
      location: 'here',
      instructors: ['Great Teacher'],
      offering: 1,
    });

    storeMock = Service.extend({
      findRecord(what){
        if (what === 'offering') {
          return resolve(offering);
        }
      },
      query(what){
        if (['sessionLearningMaterial', 'courseLearningMaterial'].includes(what)) {
          return resolve([]);
        }
        throw new Error(`${what} isn't a valid query term`);
      },
    });
    this.register('service:store', storeMock);
  }
});

test('it renders', async function(assert) {
  assert.expect(6);
  this.set('event', ourEvent);
  this.render(hbs`{{single-event event=event}}`);
  await wait();

  assert.ok(this.$('.single-event-summary').text().includes('test course'), 'course title is displayed');
  assert.ok(this.$('.single-event-summary').text().includes('test session'), 'session title is displayed');
  assert.ok(this.$('.single-event-location').text().includes('here'), 'location is displayed');
  assert.ok(this.$('.single-event-instructors').text().includes('Taught By Great Teacher'), 'instructors are displayed');
  assert.ok(this.$('.single-event-session-is').text().includes('This session is "test type"'), 'session type is displayed');
  assert.ok(this.$('.single-event-summary').text().includes('test description'), 'session description is displayed');
});
<commit_msg>testing display of (some) learning materials with event details.<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import Ember from 'ember';
import moment from 'moment';
import wait from 'ember-test-helpers/wait';

const { Object: EmberObject, RSVP, Service } = Ember;
const { Promise, resolve } = RSVP;

let ourEvent;
let course;
let session;
let sessionType;
let sessionDescription;
let offering;
let storeMock;
let sessionLearningMaterial;
let learningMaterial;
moduleForComponent('single-event', 'Integration | Component | ilios calendar single event', {
  integration: true,
  beforeEach() {
    window.Promise = Promise;
    const now = moment().hour(8).minute(0).second(0);

    course = EmberObject.create({
      id: 1,
      title: 'test course',
      sortedObjectives: resolve([]),
    });
    sessionType = EmberObject.create({
      id: 1,
      title: 'test type',
    });
    sessionDescription = EmberObject.create({
      id: 1,
      description: 'test description',
    });
    session = EmberObject.create({
      id: 1,
      title: 'test session',
      course: resolve(course),
      sessionType: resolve(sessionType),
      sessionDescription: resolve(sessionDescription),
      sortedObjectives: resolve([]),
    });
    offering = EmberObject.create({
      id: 1,
      session: resolve(session),
    });
    ourEvent = EmberObject.create({
      user: 1,
      courseExternalId: 'ext1',
      sessionTypeTitle: 'session type',
      name: 'test event',
      courseTitle: 'test course',
      startDate: now,
      endDate: now.clone().add(1, 'hour'),
      location: 'here',
      instructors: ['Great Teacher'],
      offering: 1,
    });

    learningMaterial = EmberObject.create({
      title: 'Lecture Notes',
      description: 'Lecture Notes in PDF format',
      url: 'http://example.edu/notes.pdf',
      type: 'file',
      mimetype: 'application/pdf',
      filesize: 1000,
      citation: null
    });

    sessionLearningMaterial = EmberObject.create({
      learningMaterial: resolve(learningMaterial),
      required: true,
      notes: 'Lorem Ipsum',
      publicNotes: true,
    });

    storeMock = Service.extend({
      findRecord(what){
        if (what === 'offering') {
          return resolve(offering);
        }
      },
      query(what){
        if ('sessionLearningMaterial' === what) {
          return resolve([sessionLearningMaterial]);
        } else if ('courseLearningMaterial' === what) {
          return resolve([]);
        }
        throw new Error(`${what} isn't a valid query term`);
      },
    });
    this.register('service:store', storeMock);
  }
});

test('it renders', async function(assert) {
  assert.expect(9);
  this.set('event', ourEvent);
  this.render(hbs`{{single-event event=event}}`);
  await wait();

  assert.ok(this.$('.single-event-summary').text().includes('test course'), 'course title is displayed');
  assert.ok(this.$('.single-event-summary').text().includes('test session'), 'session title is displayed');
  assert.ok(this.$('.single-event-location').text().includes('here'), 'location is displayed');
  assert.ok(this.$('.single-event-instructors').text().includes('Taught By Great Teacher'), 'instructors are displayed');
  assert.ok(this.$('.single-event-session-is').text().includes('This session is "test type"'), 'session type is displayed');
  assert.ok(this.$('.single-event-summary').text().includes('test description'), 'session description is displayed');
  const $sessionLm = this.$('.single-event-learningmaterial-list:eq(0) .single-event-learningmaterial-item:eq(0)');
  assert.equal(this.$('.single-event-learningmaterial-item-notes', $sessionLm).text().trim(), sessionLearningMaterial.get('notes'));
  assert.equal(this.$('.single-event-learningmaterial-item-description', $sessionLm).text().trim(), learningMaterial.get('description'));
  assert.ok(this.$('.single-event-learningmaterial-item-title', $sessionLm).text().includes(learningMaterial.get('title')));
});
<|endoftext|>


<commit_before>/*
* Shader.js
* Parameters:
* use: GLOW.ShaderCompiledData
* except: object, holding data that should be overwritten in GLOW.ShaderCompiledData
* vertexShader: string, vertex shader code
* fragmentShader: string, fragment shader code
* data: attributes and uniforms
* elements: elements (array or UInt16Array)
*/

GLOW.Shader = (function() {

    "use strict"; "use restrict";

    // private data, functions and initializations here

    // constructor
    function shader(parameters) {
        this.id = GLOW.uniqueId();

        this.compiledData = parameters.use ?
            parameters.use.clone(parameters.except) :
            GLOW.Compiler.compile(parameters);

        this.attachData();
    }

    // methods
    shader.prototype.attachData = function() {
        var u, a;

        for (u in this.compiledData.uniforms) {
            if (this[u] === undefined) {
                this[u] = this.compiledData.uniforms[u].data;
            }
            else {
                console.warn("GLOW.Shader.attachUniformAndAttributeData: name collision on uniform " + u + ", not attaching for easy access. Please use Shader.uniforms." + u + ".data to access data.");
            }
        }

        for (a in this.compiledData.attributes) {
            if (this[a] === undefined) {
                this[a] = this.compiledData.attributes[a].data;
            }
            else {
                console.warn("GLOW.Shader.attachUniformAndAttributeData: name collision on attribute " + a + ", not attaching for easy access. Please use Shader.attributes." + a + ".data to access data.");
            }
        }
    };

    shader.prototype.draw = function() {
        var compiledData = this.compiledData;
        var cache = GLOW.currentContext.cache;

        if (!cache.programCached(compiledData.program)) {
            var diff = cache.setProgramHighestAttributeNumber(compiledData.program);
            if (diff) {
                // enable / disable attribute streams
                var highestAttrib = compiledData.program.highestAttributeNumber;
                var current = highestAttrib - diff + 1;

                if (diff > 0) {
                    for (; current <= highestAttrib; current++) {
                        GL.enableVertexAttribArray(current);
                    }
                }
                else {
                    for (; current >= highestAttrib; current--) {
                        GL.disableVertexAttribArray(current);
                    }
                }
            }
            GL.useProgram(compiledData.program);
        }

        for (var u in compiledData.uniforms) {
            if (!cache.uniformCached(compiledData.uniforms[u])) {
                compiledData.uniforms[u].load();
            }
        }

        for (var a in compiledData.attributes) {
            if (!cache.attributeCached(compiledData.attributes[a])) {
                compiledData.attributes[a].bind();
            }
        }

        compiledData.elements.draw();
    };

    shader.prototype.clone = function(except) {
        return new GLOW.Shader({ use: this.compiledData, except: except });
    };

    shader.prototype.dispose = function() {
        // TODO
    };

    return shader;
})();

<commit_msg>Attached uniforms, attributes, elements and program from .compiledData for easier access<commit_after>/*
* Shader.js
* Parameters:
* use: GLOW.ShaderCompiledData
* except: object, holding data that should be overwritten in GLOW.ShaderCompiledData
* vertexShader: string, vertex shader code
* fragmentShader: string, fragment shader code
* data: attributes and uniforms
* elements: elements (array or UInt16Array)
*/

GLOW.Shader = (function() {

    "use strict"; "use restrict";

    // private data, functions and initializations here

    // constructor
    function shader(parameters) {
        this.id = GLOW.uniqueId();

        this.compiledData = parameters.use ?
            parameters.use.clone(parameters.except) :
            GLOW.Compiler.compile(parameters);

        this.attachData();
    }

    // methods
    shader.prototype.attachData = function() {
        var u, a;

        this.uniforms = this.compiledData.uniforms;
        this.attributes = this.compiledData.attributes;
        this.elements = this.compiledData.elements;
        this.program = this.compiledData.program;

        for (u in this.compiledData.uniforms) {
            if (this[u] === undefined) {
                this[u] = this.compiledData.uniforms[u].data;
            }
            else {
                console.warn("GLOW.Shader.attachUniformAndAttributeData: name collision on uniform " + u + ", not attaching for easy access. Please use Shader.uniforms." + u + ".data to access data.");
            }
        }

        for (a in this.compiledData.attributes) {
            if (this[a] === undefined) {
                this[a] = this.compiledData.attributes[a].data;
            }
            else {
                console.warn("GLOW.Shader.attachUniformAndAttributeData: name collision on attribute " + a + ", not attaching for easy access. Please use Shader.attributes." + a + ".data to access data.");
            }
        }
    };

    shader.prototype.draw = function() {
        var compiledData = this.compiledData;
        var cache = GLOW.currentContext.cache;

        if (!cache.programCached(compiledData.program)) {
            var diff = cache.setProgramHighestAttributeNumber(compiledData.program);
            if (diff) {
                // enable / disable attribute streams
                var highestAttrib = compiledData.program.highestAttributeNumber;
                var current = highestAttrib - diff + 1;

                if (diff > 0) {
                    for (; current <= highestAttrib; current++) {
                        GL.enableVertexAttribArray(current);
                    }
                }
                else {
                    for (; current >= highestAttrib; current--) {
                        GL.disableVertexAttribArray(current);
                    }
                }
            }
            GL.useProgram(compiledData.program);
        }

        for (var u in compiledData.uniforms) {
            if (!cache.uniformCached(compiledData.uniforms[u])) {
                compiledData.uniforms[u].load();
            }
        }

        for (var a in compiledData.attributes) {
            if (!cache.attributeCached(compiledData.attributes[a])) {
                compiledData.attributes[a].bind();
            }
        }

        compiledData.elements.draw();
    };

    shader.prototype.clone = function(except) {
        return new GLOW.Shader({ use: this.compiledData, except: except });
    };

    shader.prototype.dispose = function() {
        // TODO
    };

    return shader;
})();

<|endoftext|>


<commit_before>var forAll,
  slice = [].slice;

forAll = function(signature, name, predicate) {
  var format, pp;
  pp = new jasmine.StringPrettyPrinter();
  format = function(values) {
    pp.format(value);
    return pp.string;
  };
  return it(name, function() {
    var failedBefore, failure, jscPredicate, localJasmine;
    failedBefore = false;
    localJasmine = this;
    JSC.clear();
    jscPredicate = (function(_this) {
      return function() {
        var value, verify;
        verify = arguments[0], value = 2 <= arguments.length ? slice.call(arguments, 1) : [];
        predicate.apply(null, value);
        return verify(_this.results().failedCount === 0);
      };
    })(this);
    JSC.claim(name, jscPredicate, signature);
    if (this.reps) {
      JSC.reps(this.reps);
    }
    failure = function(f) {
      var theReport;
      theReport = 'Failed: ' + f.name;
      if (!failedBefore) {
        console.log('First failure with arguments:');
        console.log(f.args);
        if (f.exception != null) {
          console.log('Exception: ' + f.exception);
        }
        localJasmine.fail(theReport);
      }
      return failedBefore = true;
    };
    JSC.on_fail(failure);
    JSC.on_lost(failure);
    return JSC.check(5000);
  });
};

// ---
// generated by coffee-script 1.9.2<commit_msg>reformatting; remove some wasteful postassigns<commit_after>
var forAll,
    slice = [].slice;

forAll = function(signature, name, predicate) {

  var pp     = new jasmine.StringPrettyPrinter(),
      format = function(values) {
        pp.format(value);
        return pp.string;
      };

  return it(name, function() {

    var failedBefore, failure, jscPredicate, localJasmine;

    failedBefore = false;
    localJasmine = this;

    JSC.clear();

    jscPredicate = (function(_this) {

      return function() {
        var value, verify;
        verify = arguments[0], value = 2 <= arguments.length ? slice.call(arguments, 1) : [];
        predicate.apply(null, value);
        return verify(_this.results().failedCount === 0);
      };

    })(this);

    JSC.claim(name, jscPredicate, signature);

    if (this.reps) { JSC.reps(this.reps); }

    failure = function(f) {
      var theReport;
      theReport = 'Failed: ' + f.name;
      if (!failedBefore) {
        console.log('First failure with arguments:');
        console.log(f.args);
        if (f.exception != null) {
          console.log('Exception: ' + f.exception);
        }
        localJasmine.fail(theReport);
      }
      return failedBefore = true;
    };

    JSC.on_fail(failure);
    JSC.on_lost(failure);

    return JSC.check(5000);

  });

};
<|endoftext|>


<commit_before>var CustomAsset = (function () {

    var CustomAsset = Fire.define('Fire.CustomAsset', Fire.Asset);

    return CustomAsset;
})();

Fire.CustomAsset = CustomAsset;
<commit_msg>update addCustomAssetMenu<commit_after>var CustomAsset = (function () {

    var CustomAsset = Fire.define('Fire.CustomAsset', Fire.Asset);

    return CustomAsset;
})();

Fire.CustomAsset = CustomAsset;

Fire.addCustomAssetMenu = Fire.addCustomAssetMenu || function (constructor, menuPath, name, priority) {
    // implement only available in editor
};

<|endoftext|>


<commit_before>// Copyright 2010 Steven Dee. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('jsprettify.prettifyStr');

goog.require('goog.array');
goog.require('jsprettify.entities');

/**
 * Prettifies strings by replacing ASCII shorthand with proper typographical
 * symbols.
 * @param {string} text Text to prettify.
 * @return {string} Prettified text.
 */
jsprettify.prettifyStr = function(text) {
  var e = jsprettify.entities;
  /**
   * This array holds entries consisting of patterns and replacements in the
   * order that they are to be applied. We need to preserve order, since e.g.
   * if -- were replaced before ---, disaster would ensue.
   * @type {Array.<{pattern: string, replace: string}>}
   */
  var subs = [
    {pattern: '\\.\\.\\.',         replace: e.hellip},
    {pattern: "(^|[\\s\"])'([^']*)'($|[\\s\".,;:?!])",
     replace: '$1' + e.lsquo + '$2' + e.rsquo + '$3'},
    {pattern: "'",                 replace: e.rsquo},
    {pattern: '"($|[\\s.,;:?!])',  replace: e.rdquo + '$1'},
    {pattern: '(^|[\\s-])"',       replace: '$1' + e.ldquo},
    {pattern: '---',               replace: e.emdash},
    {pattern: '--',                replace: e.endash}
  ];
  goog.array.forEach(subs, function(sub) {
    var pattern = new RegExp(sub.pattern, 'g');
    text = text.replace(pattern, sub.replace);
  });
  return text;
};
<commit_msg>Handle contiguous single quote pairs (fixes issue 17).<commit_after>// Copyright 2010 Steven Dee. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('jsprettify.prettifyStr');

goog.require('goog.array');
goog.require('jsprettify.entities');

/**
 * Prettifies strings by replacing ASCII shorthand with proper typographical
 * symbols.
 * @param {string} text Text to prettify.
 * @return {string} Prettified text.
 */
jsprettify.prettifyStr = function(text) {
  var e = jsprettify.entities;
  var pattern = new RegExp("(^|[\\s\"])'([^']*)'($|[\\s\".,;:?!])", 'g');
  var replace = '$1' + e.lsquo + '$2' + e.rsquo + '$3';
  text = text.replace(pattern, replace);
  // We need to run the regexp twice for cases like "'a' 'b'", where the space
  // character gets consumed by the first match (see
  // testPrettifiesContiguousSingleQuotePairs in prettify_str_test.html).
  text = text.replace(pattern, replace);
  /**
   * This array holds entries consisting of patterns and replacements in the
   * order that they are to be applied. We need to preserve order, since e.g.
   * if -- were replaced before ---, disaster would ensue.
   * @type {Array.<{pattern: string, replace: string}>}
   */
  var subs = [
    {pattern: '\\.\\.\\.',         replace: e.hellip},
    {pattern: "'",                 replace: e.rsquo},
    {pattern: '"($|[\\s.,;:?!])',  replace: e.rdquo + '$1'},
    {pattern: '(^|[\\s-])"',       replace: '$1' + e.ldquo},
    {pattern: '---',               replace: e.emdash},
    {pattern: '--',                replace: e.endash}
  ];
  goog.array.forEach(subs, function(sub) {
    var pattern = new RegExp(sub.pattern, 'g');
    text = text.replace(pattern, sub.replace);
  });
  return text;
};
<|endoftext|>


<commit_before>/*global define*/
/*jslint nomen: true*/
define(['jquery', 'underscore', 'oro/entity-field-select-util', 'oro/entity-field-view',
    'jquery-ui', 'jquery.select2'
    ], function ($, _, EntityFieldUtil, EntityFieldView) {
    'use strict';

    $.widget('oroentity.fieldChoice', {
        options: {
            entity: null,
            fields: [],
            util: {},
            select2: {
                collapsibleResults: true,
                dropdownAutoWidth: true
            }
        },

        _create: function () {
            this.entityFieldUtil = new EntityFieldUtil(this.element);

            this._on({
                change: function (e) {
                    if (e.added) {
                        this.element.trigger('changed', e.added.id);
                    }
                }
            });
        },

        _init: function () {
            $.extend(this.entityFieldUtil, this.options.util);
            this.options.fields = this.entityFieldUtil._convertData(this.options.fields, this.options.entity, null);
            this.element
                .data('entity', this.options.entity)
                .data('data', this.options.fields);

            this._processSelect2Options();

            this.element.select2($.extend({
                data: this.options.fields
            }, this.options.select2));
        },

        _setOption: function (key, value) {
            if ($.isPlainObject(value)) {
                $.extend(this.options[key], value);
            } else {
                this._super(key, value);
            }
            return this;
        },

        _getCreateOptions: function () {
            return $.extend(true, {}, this.options);
        },

        _processSelect2Options: function () {
            var template, entityFieldUtil,
                options = this.options.select2;

            if (options.formatSelectionTemplate) {
                entityFieldUtil = this.entityFieldUtil;
                template = _.template(options.formatSelectionTemplate);
                options.formatSelection = function (item) {
                    return item.id ? template(entityFieldUtil.splitFieldId(item.id)) : '';
                };
            }
        },

        getApplicableConditions: function (fieldId) {
            return EntityFieldView.prototype.getFieldApplicableConditions.call(this.entityFieldUtil, fieldId);
        },

        setValue: function (value) {
            this.element.select2('val', value, true);
        }
    });

    return $;
});
<commit_msg>BAP-3064: Adopt concept of Entity Edit View for Display Columns<commit_after>/*global define*/
/*jslint nomen: true*/
define(['jquery', 'underscore', 'oro/entity-field-select-util', 'oro/entity-field-view',
    'jquery-ui', 'jquery.select2'
    ], function ($, _, EntityFieldUtil, EntityFieldView) {
    'use strict';

    function filterFields(fields, exclude) {
        fields = _.filter(fields, function (item) {
            var result;
            if (item.children) {
                item.children = filterFields(item.children, exclude);
                result = !_.isEmpty(item.children);
            } else {
                result = !_.some(exclude, function (rule) {
                    var cut = _.pick(item, _.keys(rule));
                    return _.isEqual(cut, rule);
                });
            }
            return result;
        });
        return fields;
    }

    $.widget('oroentity.fieldChoice', {
        options: {
            entity: null,
            fields: [],
            util: {},
            select2: {
                collapsibleResults: true,
                dropdownAutoWidth: true
            },
            exclude: []
        },

        _create: function () {
            this.entityFieldUtil = new EntityFieldUtil(this.element);

            this._on({
                change: function (e) {
                    if (e.added) {
                        this.element.trigger('changed', e.added.id);
                    }
                }
            });
        },

        _init: function () {
            $.extend(this.entityFieldUtil, this.options.util);
            this.options.fields = this.entityFieldUtil._convertData(this.options.fields, this.options.entity, null);
            if (!_.isEmpty(this.options.exclude)) {
                this.options.fields = filterFields(this.options.fields, this.options.exclude);
            }
            this.element
                .data('entity', this.options.entity)
                .data('data', this.options.fields);

            this._processSelect2Options();

            this.element.select2($.extend({
                data: this.options.fields
            }, this.options.select2));
        },

        _setOption: function (key, value) {
            if ($.isPlainObject(value)) {
                $.extend(this.options[key], value);
            } else {
                this._super(key, value);
            }
            return this;
        },

        _getCreateOptions: function () {
            return $.extend(true, {}, this.options);
        },

        _processSelect2Options: function () {
            var template, entityFieldUtil,
                options = this.options.select2;

            if (options.formatSelectionTemplate) {
                entityFieldUtil = this.entityFieldUtil;
                template = _.template(options.formatSelectionTemplate);
                options.formatSelection = function (item) {
                    return item.id ? template(entityFieldUtil.splitFieldId(item.id)) : '';
                };
            }
        },

        getApplicableConditions: function (fieldId) {
            return EntityFieldView.prototype.getFieldApplicableConditions.call(this.entityFieldUtil, fieldId);
        },

        setValue: function (value) {
            this.element.select2('val', value, true);
        }
    });

    return $;
});
<|endoftext|>